在 EVM 兼容的区块链中,智能合约可以和其他已经部署的智能合约进行交互。本文讲解了如何在一个智能合约之中调用另一个合约的函数
智能合约是在区块链中被执行的一段程序,因为它们在区块链上执行,所以不依赖于任何的中心化服务器。目前最主流的智能合约编程语言是 Solidity。
在以太坊区块链中,智能合约可以和其他已经部署的智能合约进行交互。除了以太坊,其他 EVM 兼容的区块链(使用以太坊虚拟机执行智能合约的区块链)也都有这个特点。
以下是需要在一个智能合约中调用其他合约的一些场景:
有的时候,一个应用是由多个合约组成的。比如,我曾经创建过一个应用,它是由三个合约组成的并且彼此之间需要交互,但是我没法将它部署在以太坊的主网上,因为它们占的空间太大了,超出了区块限制。我不得不将这个应用重构为 5 个更小的智能合约,这样这个应用才可以被发布。
另一个有趣的应用场景是可升级的合约。区块链是不可更改的,这就意味着在智能合约部署以后,代码就不能被修改了。但是可以通过代理函数来指向其他合约来完成“升级”。
如果你想要改变逻辑,你可以给代理合约提供一个不同的目标合约地址,比如一个更新过的合约。还可以把逻辑和数据分到不同的智能合约中。这样,逻辑合约可以被代理合约升级或者替换,但是所有的数据还是存储在数据合约之中。
这个特性非常有用,因为它允许代码被重复利用,部署的合约可以被当成一个库来使用。因此,它还可以减少部署时的消耗,因为当合约可以被重复使用的时候,每次新的应用需要部署的合约就可能变少。
让我们使用 Remix 这个在线 IDE 来进行一些尝试。
创建一个文件,用来存储智能合约,你可以将多个智能合约存储在一个文件中!
你将要在这个文件中编写并且部署两个合约。 首先,定义 SPDX license 信息和编译器版本。复制并且粘贴这部分代码:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
第一个合约是“Counter”,合约中只有一个数字自增的函数。 复制并且粘贴这个例子:
contract Counter {
uint public number;
function increment() external {
number += 1;
}
}
Counter 合约有:
编译 Counter 合约
部署 Counter 合约
在下方找到部署好的合约,然后复制它的地址。就像下面这个地址:
0xd9145CCE52D386f254917e481eB44e9943F39138 你会看到如下图所示:
在左边工具栏的下方可以找到部署好的合约
打开 Counter 合约然后:
这个是最终结果: counter 合约的最终结果
现在我们第一个合约 Counter 已经部署了,让我们创建另一个合约来使用 Counter 合约中的 increment 函数。这个机制就像是依赖注入(Dependency Injection),调用者可以通过合约函数的签名和变量来初始化一个合约。
在 Contract.sol 文件的底部复制和粘贴以下的代码:
contract CounterCaller {
Counter public myCounter;
constructor(address counterAddress) {
myCounter = Counter(counterAddress);
}
function counterIncrement() external {
myCounter.increment();
}
}
CounterCaller 合约有:
myCounter
的变量,数据类型就是 Counter。这意味着我们已经将即将调用的合约作为一个数据类型,以便我们可以通过这个变量来获得合约的函数和变量。counterIncrement
函数会通过 myCounter
调用 increment
函数,这里的 myCounter
就像是指向 Counter 智能合约的“指针”。请看完整的 Contracts.sol 文件:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract Counter {
uint public number;
function increment() external {
number += 1;
}
}
contract CounterCaller {
Counter public myCounter;
constructor(address counterAddress) {
myCounter = Counter(counterAddress);
}
function counterIncrement() external {
myCounter.increment();
}
}
编译 CounterCaller 合约
现在,让我们来部署 CounterCaller 合约。在左边的工具栏中,点击按钮“Deploy and run transactions”。
部署 ContractCaller 合约。
在左边工具栏中找到 CounterCaller 合约,然后展开。
这个基础的例子演示了如何从在一个合约中调用另一个合约。
还有一些别的方式在不同的合约之间互相调用,只要你知道部署好的合约的地址,函数和公共变量,另一个合约就可以调用它。
在你知道了合约中能够调用另一个合约之后,你就可以:
您可以关注 Chainlink 预言机并且私信加入开发者社区,有大量关于智能合约的学习资料以及关于区块链的话题!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!