以太坊智能合约互调用

本文介绍了如何在以太坊的智能合约中实现合约间的相互调用,包括重构大型应用以适应区块限制,以及通过代理合约进行可升级的智能合约设计。通过实例展示了在Solidity中使用RemixIDE进行合同部署和交互的过程。
摘要由CSDN通过智能技术生成

一、智能合约的相互调用和升级

有的时候,一个应用是由多个合约组成的。比如,我曾经创建过一个应用,它是由三个合约组成的并且彼此之间需要交互,但是我没法将它部署在以太坊的主网上,因为它们占的空间太大了,超出了区块限制。我不得不将这个应用重构为 5 个更小的智能合约,这样这个应用才可以被发布。

另一个有趣的应用场景是可升级的合约。区块链是不可更改的,这就意味着在智能合约部署以后,代码就不能被修改了。但是可以通过代理函数来指向其他合约来完成“升级”。

如果你想要改变逻辑,你可以给代理合约提供一个不同的目标合约地址,比如一个更新过的合约。还可以把逻辑和数据分到不同的智能合约中。这样,逻辑合约可以被代理合约升级或者替换,但是所有的数据还是存储在数据合约之中。

这个特性非常有用,因为它允许代码被重复利用,部署的合约可以被当成一个库来使用。因此,它还可以减少部署时的消耗,因为当合约可以被重复使用的时候,每次新的应用需要部署的合约就可能变少。

二、Solidity 中调用另一个智能合约

让我们使用 Remix 这个在线 IDE 来进行一些尝试。

方法一:同 sol 文件的智能合约调用

创建你的第一个智能合约

创建一个文件,用来存储智能合约,可以将多个智能合约存储在一个文件中!

  • 在 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 合约

  1. 在左边工具栏中找到“Solidity compiler”按钮。
  2. 点击“Compile Contracts.sol”按钮
  3. Enable 自动编译(auto-compile)选项
  4. 看下有没有绿色的标志,如果有的话就说明编译成功了

部署 Counter 合约

  1. 在左边的工具栏,点击按钮“Deploy and run transactions”。
  2. 现在,我们只有一个智能合约,所以“Counter”在“Contracts”下拉菜单中会被自动选择。
  3. 点击“Deploy”按钮

在下方找到部署好的合约,然后复制它的地址。就像下面这个地址:

0xa89b5892269303efFD663E5eb9758E75Bf260dF5

在这里插入图片描述

打开 Counter 合约然后:

  1. 点击“number”按钮,然后检查它的值是不是 0。
  2. 点击“increment”按钮,发送一个交易来给数字增加 1。
  3. 再次点击“number”按钮,检查现在的值是不是1。

这个是最终结果:

在这里插入图片描述

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 合约交互

在左边工具栏中找到 CounterCaller 合约,然后展开。

  • 点击“myCounter” 按钮然后查看 Counter 的地址。
  • 点击“counterIncrement”按钮,发送交易来调用 Counter 合约中的 increment 函数。
  • 在 Counter 合约中点击 number 按钮,验证数字是否增加了 1,现在应该已经是 2 了。
    这是最终的结果:
  • 在这里插入图片描述

方法二:不同 sol 文件的智能合约调用

Counter合约

Counter合约的内容不变,合约中只有一个数字自增的函数。

contract Counter {
    uint public number;
    function increment() external {
        number += 1;
    }
}

CounterCaller 合约

CounterCaller 合约需要增加一段Counter合约的定义

// SPDX-License-Identifier: MIT

pragma solidity 0.8.16;

contract CounterCaller {
    Counter public myCounter;

    constructor(address counterAddress) {
        myCounter = Counter(counterAddress);
    }

    function counterIncrement() external {
        myCounter.increment();
    }
}
contract Counter {
    function increment() external {}
}

三、总结

在你知道了合约中能够调用另一个合约之后,你就可以:

  • 将一个合约分成多个合约
  • 设计复杂的 dApp 的架构
  • 实现代码的复用
  • 创建工厂合约(一个可以创建别的合约的合约)
  • 消除24字节智能合约大小对代码实现的影响

附录

1、Web3j官方操作指南:https://docs.web3j.io/4.8.7/

2、solidity介绍文档:https://learnblockchain.cn/docs/solidity/

  • 33
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值