本文介绍了如何在Solidity中调用另一个智能合约的函数,通过部署两个合约(Counter.sol和Interface.sol)并演示它们之间的交互,展示了智能合约的复用性和交互方式。
重要通知
本指南包含对 Goerli 测试网的引用,该测试网已不再积极维护。虽然与该链相关的具体步骤可能不再适用,但整体流程可能对其他链仍然有效。我们建议你探索当前的替代方案来实现你的目标。如果你希望看到本指南的更新版本,请告知我们!
智能合约是以太坊网络中最受欢迎的功能。智能合约具有函数,有时需要被其他智能合约访问。在理解智能合约的交互之前,让我们先回顾一下智能合约的基础知识。
在本指南中,我们将学习智能合约,理解为什么我们希望从我们的智能合约中调用其他智能合约,并部署两个相互交互的独立合约。
智能合约是部署在区块链网络上的计算机代码,也称为应用程序。与任何其他应用程序一样,这些智能合约包含信息和条件或规则。主要区别在于,智能合约的函数可以被任何人、任何时间、任何原因执行。
在现实生活中,每当各方之间需要达成协议时,第三方会审查并验证它。例如,公证人会确保合同上双方的签名身份。这使得过程耗时且复杂。智能合约消除了对第三方的需求,使各方能够直接进行交易,从而实现了自动化并使过程更加安全。
智能合约使全球任何人都能进行交易,而无需担心信任问题和中间人。智能合约继承了区块链的许多属性,因为它们是设计并部署在区块链上的,不可变性就是其中之一,这意味着智能合约永远不能被更改,没有人可以破坏合约。
Solidity 是编写智能合约的标准语言,了解更多关于 Solidity,并编写你的第一个 Solidity 智能合约。
以下是智能合约的好处:
准确性 – 手动填写表格可能会导致一些错误,而使用自动化合约可以更快、更便宜且更准确。
信任 – 合约以编码格式部署并存储在区块链节点的网络上。它们永远不会丢失。
自治 – 使用智能合约,你就是达成协议的一方;无需依赖经纪人、律师或任何第三方中介。
速度 – 手动处理文档可能需要大量的文书工作并耗费时间。由于智能合约实际上只是计算机程序,它们可以自动化——这使得过程非常快速。
备份 – 想象一下,如果一家金融机构的数据中心崩溃,所有客户资产的数据都将丢失。在以太坊区块链上,网络上的每个人都有一个数据副本和智能合约。通过这种方式,数据被备份并且永远不会丢失。
节省 – 每当第三方参与协议时,都需要支付相当大的一笔费用作为服务费,但由于智能合约消除了对第三方的需求,交易成本降低了。
为什么合约需要与其他合约交互?
就像应用程序或计算机程序可以通过 API 访问其他应用程序的数据一样,智能合约可以利用已部署在区块链上的其他智能合约中的函数。这种可重用性可以节省区块链上的时间和空间,因为你不需要编写或复制粘贴函数,也不需要存储函数的副本。
我们将在 Goerli 测试网上部署我们的合约。要开始,你需要 Metamask 浏览器扩展来创建一个 ETH 钱包,并获取一些测试 ETH,你可以通过访问 QuickNode 多链水龙头 获取。你需要连接你的钱包或粘贴你的钱包地址,然后请求测试网资金。你还可以分享一条推文以获得 5 倍奖励!
现在为了实现我们的目标,我们将在 Solidity 中创建两个合约。
'Counter.sol' 将首先部署,这是一个简短的计数器递增脚本。
'Interface.sol' 我们将使用 Solidity 接口模式,并提供已部署合约 'Counter.sol' 的计数器函数签名。
前往 Ethereum Remix IDE 并创建一个新的 Solidity 文件 Counter.sol。
将以下代码粘贴到你的新 Solidity 脚本中:
pragma solidity ^0.6.8;
// SPDX-License-Identifier: MIT
contract Counter {
uint public count;
function increment() external {
count += 1;
}
}
上述代码的解释:
第 1 行:声明 Solidity 版本。
第 3 行:指定 SPDX 许可证 类型,这是在 Solidity ^0.6.8 之后新增的。每当智能合约的源代码向公众开放时,这些许可证可以帮助解决/避免版权问题。如果你不希望指定任何许可证类型,可以使用特殊值 UNLICENSED 或直接跳过整个注释(不会导致错误,只会出现警告)。
第 5 行:启动我们的合约,名为 Counter。
第 6 行:创建一个公共变量 count,类型为无符号整数,它将存储递增的值。
第 8-10 行:创建一个带有 external 修饰符的函数 increment,将 count 的值增加一。外部函数是合约接口的一部分,这意味着它们可以从其他合约和通过交易调用——这对于我们从另一个合约调用一个合约的目标至关重要。
编译智能合约并使用 Injected Web3 部署它,你可能还需要使用左侧菜单将编译器版本更改为 0.6.12。
现在我们已经部署了第一个合约,让我们创建另一个合约来使用 Counter.sol 合约的函数。
创建一个新的 Solidity 文件 Interface.sol,将以下代码粘贴到你的新 Solidity 脚本中:
pragma solidity ^0.6.0;
// SPDX-License-Identifier: MIT
interface ICounter {
function count() external view returns (uint);
function increment() external;
}
contract Interaction {
address counterAddr;
function setCounterAddr(address _counter) public payable {
counterAddr = _counter;
}
function getCount() external view returns (uint) {
return ICounter(counterAddr).count();
}
}
上述代码的解释:
第 1 行:声明 Solidity 版本。
第 3 行:指定 SPDX 许可证 类型,这是在 Solidity ^0.6.8 之后新增的。每当智能合约的源代码向公众开放时,这些许可证可以帮助解决/避免版权问题。如果你不希望指定任何许可证类型,可以使用特殊值 UNLICENSED 或直接跳过整个注释(不会导致错误,只会出现警告)。
第 5-8 行:创建一个 接口 ICounter,提供合约 Counter.sol 的函数签名,提供两个函数签名 count 和 increment。
第 10 行:启动我们的合约,名为 Interaction。
第 11 行:声明一个私有变量 `counterAddr` 来存储我们要调用函数的合约地址。
第 13-15 行:创建一个函数 setCounterAddr,它接受 `_counter` 作为参数。`_counter` 将是我们想要设置 `counterAddr` 的地址——它将被存储在链上。
第 17-19 行:声明 `getCount` 函数,这是我们最初开始这段旅程的原因,使用 `counterAddr` 地址实例化接口,并立即调用其上的 `count` 函数以从已部署的 `Counter.sol` 合约中获取计数。getCount 是一个视图类型的方法,并且具有外部状态,视图和纯方法(包括公共状态变量的 getter)可以在不进行交易的情况下调用。
编译智能合约并使用 Injected Web3 部署它。
注意:在部署之前,请确保从左侧菜单中选择 Contract 部分下的 Interaction。
现在你将在 Remix 的“已部署合约”部分下看到两个合约。从合约名称旁边的复制按钮复制已部署合约 COUNTER 的地址,展开 INTERACTION 合约,将地址粘贴到 setCounterAddr 按钮附近的输入框中,然后点击 setCounterAddr——这将把之前部署的智能合约的地址写入链上的变量 counterAddr。此交易将需要一些 gas。
现在让我们更新 COUNTER 合约中的 count 值,点击 increment;这将向链发送一个写请求,并需要一些 gas。然后点击 count。你必须看到 count 的值增加了一。
注意:你需要等待交易在区块链上确认(可能需要大约 45 秒左右),然后才能点击 count。
让我们检查一下 INTERFACE 合约是否可以获取更新后的 count 值,点击 INTERACTION 合约下的 getCount 按钮,你必须看到更新后的值。
注意:这假设上一部分的交易已确认。
使用接口允许用户使用已部署合约的功能。如果有人希望使用合约的函数,他们可以从其创建者那里获取该合约的接口,并将其集成到他们的合约中,而无需从头开始实现所有内容。
在这里,我们成功地看到了如何使用 Solidity 调用另一个智能合约的函数。
订阅我们的新闻通讯以获取更多关于以太坊的文章和指南。如果你有任何反馈,请随时通过Twitter与我们联系。你还可以在我们的Discord社区服务器上与我们聊天,那里有一些你会遇到的最酷的开发者 :)
- 原文链接: quicknode.com/guides/eth...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!