共计 3406 个字符,预计需要花费 9 分钟才能阅读完成。
智能合约是在区块链中被执行的一段程序,因为它们在区块链上执行,所以不依赖于任何的中心化服务器。目前最支流的智能合约编程语言是 Solidity。
在以太坊区块链中,智能合约能够和其余曾经部署的智能合约进行交互。除了以太坊,其余 EVM 兼容的区块链(应用以太坊虚拟机执行智能合约的区块链)也都有这个特点。
以下是须要在一个智能合约中调用其余合约的一些场景:
- 通证的铸造者和发行人,通过一个合约来调用通证的智能合约来发行它。
- 去中心化交易所(DEX)在进行通证交易的时候,始终都须要和其余智能合约相交互。
- 当你想通过 Chainlink Data Feed 取得一个通证价格的时候,你的智能合约也须要和资产的 aggregator 相交互,这里的 aggregator 也是一个智能合约。
- 当你应用 Chainlink VRF 的时候,你的合约须要给 VRF Coordinator 发送一个申请,Coordinator 才能够将随机数发送回你的智能合约。
-
在通过 Chainlink Keepers 自动化执行智能合约的时候,你须要创立 Keepers Upkeep,而 Upkeep 须要通过一个合约来查看和执行你部署的用户合约。
为什么要在一个合约中调用另外一个合约的函数?
有的时候,一个利用是由多个合约组成的。比方,我已经创立过一个利用,它是由三个合约组成的并且彼此之间须要交互,然而我没法将它部署在以太坊的主网上,因为它们占的空间太大了,超出了区块限度。我不得不将这个利用重构为 5 个更小的智能合约,这样这个利用才能够被公布。
另一个乏味的利用场景是可降级的合约。区块链是不可更改的,这就意味着在智能合约部署当前,代码就不能被批改了。然而能够通过代理函数来指向其余合约来实现“降级”。
如果你想要扭转逻辑,你能够给代理合约提供一个不同的指标合约地址,比方一个更新过的合约。还能够把逻辑和数据分到不同的智能合约中。这样,逻辑合约能够被代理合约降级或者替换,然而所有的数据还是存储在数据合约之中。
这个个性十分有用,因为它容许代码被反复利用,部署的合约能够被当成一个库来应用。因而,它还能够缩小部署时的耗费,因为当合约能够被重复使用的时候,每次新的利用须要部署的合约就可能变少。
Solidity 中调用另一个智能合约
让咱们应用 Remix 这个在线 IDE 来进行一些尝试。
创立你的第一个智能合约
创立一个文件,用来存储智能合约,你能够将多个智能合约存储在一个文件中!
- 在 Remix 中,点击右边工具栏的“File Explorers”。
- 点击“Create a new file”按钮。
- 给你的文件命名为 Contracts.sol
你将要在这个文件中编写并且部署两个合约。
首先,定义 SPDX license 信息和编译器版本。复制并且粘贴这部分代码:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
Counter 合约
第一个合约是“Counter”,合约中只有一个数字自增的函数。
复制并且粘贴这个例子:
contract Counter {
uint public number;
function increment() external {number += 1;}
}
Counter 合约有:
- 一个公共的变量 number,是一个无符号整型变量,这个变量会做自增。
- 一个函数 increment 给整型变量减少 1。它是一个 external 函数,所以它能够被其余合约发送的交易调用。
编译 Counter 合约
- 在右边工具栏中找到“Solidity compiler”按钮。
- 点击“Compile Contracts.sol”按钮
- Enable 主动编译(auto-compile)选项
- 看下有没有绿色的标记,如果有的话就阐明编译胜利了
部署 Counter 合约
- 在右边的工具栏,点击按钮“Deploy and run transactions”。
- 当初,咱们只有一个智能合约,所以“Counter”在“Contracts”下拉菜单中会被主动抉择。
- 点击“Deploy”按钮
在下方找到部署好的合约,而后复制它的地址。就像上面这个地址:
0xd9145CCE52D386f254917e481eB44e9943F39138
你会看到如下图所示:
在右边工具栏的下方能够找到部署好的合约
与 Counter 合约交互
关上 Counter 合约而后:
- 点击“number”按钮,而后查看它的值是不是 0。
- 点击“increment”按钮,发送一个交易来给数字减少 1。
- 再次点击“number”按钮,查看当初的值是不是 1。
这个是最终后果:
counter 合约的最终后果
CounterCaller 合约
当初咱们第一个合约 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。这意味着咱们曾经将行将调用的合约作为一个数据类型,以便咱们能够通过这个变量来取得合约的函数和变量。 - 构造函数,构造函数只有在部署的过程中才会被调用,它会应用之前部署的 Counter 合约的地址初始化 myCounter。
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 合约
- 如果你曾经 enable 来 auto-compile 选项,它就曾经实现了编译。
- 查看按钮旁边的绿色按钮,已确定是否曾经编译胜利。
- 或者,依据之前的步骤去编译 Counter 合约。
当初,让咱们来部署 CounterCaller 合约。在右边的工具栏中,点击按钮“Deploy and run transactions”。
- 在合约的下拉菜单中,抉择 CounterCaller。
- 在 Deploy 按钮旁边粘贴 Counter 合约的地址。
- 点击“Deploy”按钮。
部署 ContractCaller 合约。
与 CounterCaller 合约交互
在右边工具栏中找到 CounterCaller 合约,而后开展。
- 点击“myCounter”按钮而后查看 Counter 的地址。
- 点击“counterIncrement”按钮,发送交易来调用 Counter 合约中的 increment 函数。
- 在 Counter 合约中点击 number 按钮,验证数字是否减少了 1,当初应该曾经是 2 了。
这是最终的后果:
- 与 CounterCaller 合约交互。*
这个根底的例子演示了如何从在一个合约中调用另一个合约。
还有一些别的形式在不同的合约之间相互调用,只有你晓得部署好的合约的地址,函数和公共变量,另一个合约就能够调用它。
在你晓得了合约中可能调用另一个合约之后,你就能够:
- 将一个合约分成多个合约
- 设计简单的 dApp 的架构
- 实现代码的复用
- 创立工厂合约(一个能够创立别的合约的合约)
您能够关注 Chainlink 预言机并且私信退出开发者社区,有大量对于智能合约的学习材料以及对于区块链的话题!