solidity高阶 -- 调用接口合约
在区块链开发中,Solidity 是一种广泛使用的智能合约编程语言,而接口合约(Interface)是 Solidity 中一个非常重要的概念。它为智能合约之间的交互提供了一种标准化的方式,使得合约之间的调用更加灵活、安全且易于管理。本文将深入探讨 Solidity 中接口合约的概念、作用以及具体的实现示例。
注意:使用继承时请确保代码的正确性,以防丢失个人财产,在这里友情提示您,不要复制来源不明的solidity代码并进行部署。本文为自己梳理总结,如有不足还请指出,感谢包容。
学习更多solidity知识请访问 Github -- solidity基础 ,更多实例在 Smart contract
二、接口合约的作用
(一)抽象化合约交互
接口合约将合约的调用逻辑与实现细节分离,使得合约之间的交互更加抽象化。开发者只需要关注接口的定义,而无需关心目标合约的具体实现。这种抽象化的方式使得合约之间的耦合度降低,提高了代码的可维护性和可扩展性。
例如,假设我们有一个 Counter 合约,它实现了 ICounter 接口。其他合约可以通过 ICounter 接口调用 Counter 合约的函数,而无需知道 Counter 合约的具体实现细节。
(二)提高代码复用性
接口合约可以被多个合约实现,从而实现代码的复用。多个合约可以共享同一个接口定义,而每个合约可以根据自己的需求实现接口中的函数。这种方式避免了重复编写类似的函数逻辑,提高了开发效率。
(三)增强安全性
接口合约提供了一种明确的调用规范,使得合约之间的交互更加安全。通过接口合约,调用方可以明确知道目标合约提供的函数签名和返回值类型,从而避免因调用错误而导致的安全问题。同时,接口合约还可以限制调用方对目标合约的访问权限,进一步增强合约的安全性。
三、接口合约的实现示例
为了更好地理解接口合约的作用,我们通过一个具体的示例来展示如何使用接口合约。
(一)定义接口合约
首先,我们定义一个接口合约 ICounter,它包含两个函数:count() 和 inc()。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;interface ICounter {function count() external view returns (uint);function inc() external;
}
(二)实现接口合约
接下来,我们定义一个 Counter 合约,它实现了 ICounter 接口。Counter 合约包含一个状态变量 count,以及两个函数:inc() 和 dec()。其中,inc() 函数用于增加 count 的值,dec() 函数用于减少 count 的值。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;contract Counter {uint public count;function inc() external {count += 1;}function dec() external {count -= 1;}
}
(三)调用接口合约
最后,我们定义一个 CallInterface 合约,它通过 ICounter 接口调用 Counter 合约的函数。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;contract CallInterface {uint public count;function examples(address _counter) external {ICounter(_counter).inc();count = ICounter(_counter).count();}
}
在 CallInterface 合约中,examples() 函数接收一个合约地址 _counter,并通过 ICounter(_counter) 将该地址转换为 ICounter 类型。然后,调用 ICounter 接口的 inc() 函数来增加 Counter 合约的 count 值,并通过 count() 函数获取当前的 count 值,将其存储在 CallInterface 合约的 count 状态变量中。
四、接口合约与抽象合约的区别
在 Solidity 中,除了接口合约,还有一种类似的合约类型——抽象合约。抽象合约和接口合约有一些相似之处,但也有明显的区别。
(一)定义方式
-
接口合约:以关键字
interface开始,函数声明必须是external类型,不能包含状态变量。 -
抽象合约:以关键字
contract开始,可以包含external或internal函数,也可以包含状态变量。
(二)实现方式
-
接口合约:接口合约中的函数必须由实现合约提供具体实现,且不能包含任何逻辑。
-
抽象合约:抽象合约中的函数可以是抽象函数(没有实现),也可以是具体实现的函数。实现合约可以选择实现抽象函数,也可以直接继承抽象合约中的具体实现。
(三)使用场景
-
接口合约:主要用于定义合约之间的交互规范,使得合约之间的调用更加标准化和抽象化。
-
抽象合约:主要用于提供一组通用的函数和状态变量,供其他合约继承和扩展。抽象合约可以包含部分实现逻辑,使得继承合约可以复用这些逻辑。
五、关键注意事项
-
严格签名匹配:包括参数类型、返回值、可见性(external必须严格一致)
-
版本兼容:需使用相同Solidity编译器版本
-
限制特性:
-
不能包含构造函数
-
不能定义状态变量
-
不能继承其他合约
-
-
返回处理:view函数通过返回值获取数据,非view函数通过事件监听状态变化
六、典型应用场景
-
代币交互:ERC20标准接口
-
预言机调用:数据请求标准化
-
可升级合约:通过接口指向不同实现
-
合约检测:通过接口判断合约功能支持性
七、开发实践建议
-
接口命名使用"I"前缀(如
ICounter) -
为每个功能模块定义独立接口
-
使用TypeChain等工具自动生成TypeScript类型定义
-
结合require语句进行接口支持检测:
require(Counter(_counter).supportsInterface(type(ICounter).interfaceId),"Unsupported interface" );
八、本文代码总结
接口合约ICounter// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;contract Counter {uint public count;function inc() external {count += 1;}function dec() external {count -= 1;}}
//调用接口合约// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;interface ICounter {function count() external view returns (uint);function inc() external;
}
//interface开头,名字大写,完成了接口调用的方法
//调用了两个合约的函数contract CallInterface {uint public count;function examples(address _counter) external {ICounter(_counter).inc();count = ICounter(_counter).count();}
}
//调用inc这个方法
// count = ICounter(_counter).count();
结语
接口合约如同智能合约世界的通信协议,通过定义清晰的交互边界,极大地提升了合约系统的可维护性和扩展性。当您下次需要实现跨合约调用时,不妨先设计好接口规范——这如同为合约间的对话制定语法规则,将使您的DApp架构更加优雅稳健。
通过文中的Counter示例实践可以发现,接口合约将功能声明与具体实现分离,既保证了核心逻辑的安全性,又为后续功能扩展保留了充足的灵活性。这正是区块链智能合约开发中"合约优先"设计理念的生动体现。
相关文章:
solidity高阶 -- 调用接口合约
在区块链开发中,Solidity 是一种广泛使用的智能合约编程语言,而接口合约(Interface)是 Solidity 中一个非常重要的概念。它为智能合约之间的交互提供了一种标准化的方式,使得合约之间的调用更加灵活、安全且易于管理。…...
若依框架使用(低级)
克隆源码 浏览器搜索若依,选择 RuoYi-Vue RuoYi-Vue RuoYi-Vue 重要的事情说三遍,进入gitee 下面这个页面(注意红色框起来的部分) 进入Gitee进行下载 我下载的是最新的springboot3 下载好后我们可以选择一个文件夹࿰…...
找不到 MSVCP120.dll
msvcr120.dll msvcr120.dll 是 Microsoft Visual C Redistributable 的一部分,属于 Visual Studio 2013(VC 12.0)的运行时组件。它的重要性取决于你运行的应用程序是否需要它。 重要性 依赖库:如果某个程序是用 Visual Studio 2…...
AI软件栈:LLVM分析(三)
LLVM IR 文章目录 CFG线性IR 主要采用CFG与线性IR组合描述 CFG *关键在于基本块(Basic Block)的定义 线性IR *关键来自于SSA,单静态赋值...
openwebui入门
1 简介 Open WebUI(网址是openwebui.com)是一个高度可扩展、功能强大且用户友好的自托管Web用户界面,专为完全离线操作设计,编程语言是python。它支持对接Ollama和OpenAI兼容的API的大模型。 Open WebUI在架构上是一种中…...
Spark--如何理解RDD
1、概念 rdd是对数据集的逻辑表示,本身并不存储数据,只是封装了计算逻辑,并构建执行计划,通过保存血缘关系来记录rdd的执行过程和历史(当一个rdd需要重算时,系统会根据血缘关系追溯到最初的数据源ÿ…...
CTFSHOW-WEB入门-PHP特性89-100
题目:web 89 题目:解题思路:这道题目涉及了两个函数:preg_match()和intval()简要介绍一下两个函数 preg_match()用于对字符串进行正则表达式的匹配࿰…...
[250204] Mistral Small 3:小巧、快速、强大 | asdf 0.16.0 发布:Golang 重写带来性能飞跃
目录 Mistral AI 发布开源模型 Mistral Small 3:小巧、快速、强大asdf 0.16.0 版本发布:Golang 重写带来性能飞跃! Mistral AI 发布开源模型 Mistral Small 3:小巧、快速、强大 法国人工智能初创公司 Mistral AI 发布了最新的开源…...
PySpark学习笔记5-SparkSQL
sparkSql的数据抽象有两种。 一类是data set适用于java和Scala 一类是data frame适用于java,Scala,python 将r d d转换为data frame #方式一 df spark.createDataFrame(rdd,schema[name,age]) #方式二 schema Structtype(). add(id,integertype(),nu…...
windows版的docker如何使用宿主机的GPU
windows版的docker使用宿主机的GPU的命令 命令如下 docker run -it --nethost --gpus all --name 容器名 -e NVIDIA_DRIVER_CAPABILITIEScompute,utility -e NVIDIA_VISIBLE_DEVICESall 镜像名效果 (transformer) rootdocker-desktop:/# python Python 3.9.0 (default, Nov 15 …...
Python爬虫:1药城店铺爬虫(完整代码)
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…...
代码随想录算法训练营打卡第55天:并查集相关问题;
Java并查集的模板 //并查集模板 class DisJoint{private int[] father;public DisJoint(int N) {father new int[N];for (int i 0; i < N; i){father[i] i;}}public int find(int n) {return n father[n] ? n : (father[n] find(father[n]));}public void join (int …...
K8S学习笔记-------1.安装部署K8S集群环境
1.修改为root权限 #sudo su 2.修改主机名 #hostnamectl set-hostname k8s-master01 3.查看网络地址 sudo nano /etc/netplan/01-netcfg.yaml4.使网络配置修改生效 sudo netplan apply5.修改UUID(某些虚拟机系统,需要设置才能生成UUID)#…...
云原生周刊:K8s引领潮流
开源项目推荐 KWOK KWOK(Kubernetes WithOut Kubelet)是一个开源项目,旨在提供一个轻量级的 K8s 集群模拟环境,允许用户在不依赖真实节点的情况下,本地模拟整个 K8s 集群。它通过模拟 Kubelet 和其他集群组件的行为&…...
C_位运算符及其在单片机寄存器的操作
C语言的位运算符用于直接操作二进制位,本篇简单结束各个位运算符的作业及其在操作寄存器的应用场景。 一、位运算符的简单说明 1、按位与运算符(&) 功能:按位与运算符对两个操作数的每一位执行与操作。如果两个对应的二进制…...
【算法篇】贪心算法
目录 贪心算法 贪心算法实际应用 一,零钱找回问题 二,活动选择问题 三,分数背包问题 将数组和减半的最小操作次数 最大数 贪心算法 贪心算法,是一种在每一步选择中都采取当前状态下的最优策略,期望得到全局最优…...
Selenium 浏览器操作与使用技巧——详细解析(Java版)
目录 一、浏览器及窗口操作 二、键盘与鼠标操作 三、勾选复选框 四、多层框架/窗口定位 五、操作下拉框 六、上传文件操作 七、处理弹窗与 alert 八、处理动态元素 九、使用 Selenium 进行网站监控 前言 Selenium 是一款非常强大的 Web 自动化测试工具,能够…...
ioDraw桌面版 v3.4.0发布!AI文生图,AI图生图,手绘风格一键转换!
流程图功能升级 AI 文生图: 用户现在能输入文字描述,让软件自动生成对应的流程图画面,减少了手动绘图的工作量,提高创作效率,比如输入 “项目开发流程”,软件可能就会生成包含需求分析、设计、开发、测试…...
深入理解Node.js_架构与最佳实践
1. 引言 1.1 什么是Node.js Node.js简介:Node.js是一个基于Chrome V8引擎的JavaScript运行时,用于构建快速、可扩展的网络应用。Node.js的历史背景和发展:Node.js最初由Ryan Dahl在2009年发布,旨在解决I/O密集型应用的性能问题。随着时间的推移,Node.js社区不断壮大,提供…...
安装和卸载RabbitMQ
我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/SUWXdDb0UoCV86xP6b3c7qtMn6b 使用Ubuntu环境进行安装 一、安装Erlang 在安装RabbitMQ之前,我们需要先安装Erlang,RabbitMQ需要Erlang的语言支持 #安装Erlang sudo apt-get install erlang 在安装的过程中,会弹出一段信息,此…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
