如何在智能合约中调用另一个合约的函数

智能合约是在区块链中被执行的一段程序,因为它们在区块链上执行,所以不依赖于任何的中心化服务器。目前最主流的智能合约编程语言是 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: MITpragma 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”按钮

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

0xd9145CCE52D386f254917e481eB44e9943F39138
你会看到如下图所示:

1-1.png
在左边工具栏的下方可以找到部署好的合约

与 Counter 合约交互

打开 Counter 合约然后:

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

这个是最终结果:
1-2.png
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 合约

  1. 如果你已经 enable 来 auto-compile 选项,它就已经完成了编译。
  2. 查看按钮旁边的绿色按钮,已确定是否已经编译成功。
  3. 或者,根据之前的步骤去编译 Counter 合约。

现在,让我们来部署 CounterCaller 合约。在左边的工具栏中,点击按钮“Deploy and run transactions”。

  1. 在合约的下拉菜单中,选择 CounterCaller。
  2. 在 Deploy 按钮旁边粘贴 Counter 合约的地址。
  3. 点击“Deploy”按钮。

1-3.png
部署 ContractCaller 合约。

与 CounterCaller 合约交互

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

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

1-4.png

  • 与 CounterCaller 合约交互。*

这个基础的例子演示了如何从在一个合约中调用另一个合约。

还有一些别的方式在不同的合约之间互相调用,只要你知道部署好的合约的地址,函数和公共变量,另一个合约就可以调用它。

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

  • 将一个合约分成多个合约
  • 设计复杂的 dApp 的架构
  • 实现代码的复用
  • 创建工厂合约(一个可以创建别的合约的合约)

您可以关注 Chainlink 预言机并且私信加入开发者社区,有大量关于智能合约的学习资料以及关于区块链的话题!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39290.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt是否会代替程序员

ChatGPT能否取代程序员? ChatGPT是一种非常普遍的人工智能(AI)系统,被广泛应用于自然语言处理领域。但是,这个问题是一个非常复杂的问题,需要经过认真的思考和辩论。ChatGPT能否取代程序员?这个…

GPT1、GPT2、GPT3、InstructGPT

GPT全称是 Generative Pre-Trained Transformer。顾名思义,GPT的目的就是通过Transformer为基础模型,使用预训练技术得到的通用的文本模型。目前已经公布论文的有文本预训练GPT-1、GPT-2、GPT-3,以及InstructGPT。ChatGPT和InstructGPT在模型…

python编程游戏代码tkinter,python编程游戏代码大全

python有趣的编程代码 class Point: row0 col0 def __init__(self, row, col): row col def copy(self): return Point(, )#初始框架import pygameimport random#初始化()W800H600ROW30COL40size(W,H)windowpygame.display.set_mode(size)pygame.display.set_cap…

python小游戏——推箱子代码开源

♥️作者:小刘在这里 ♥️每天分享云计算网络运维课堂笔记,努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的,绽放,愿所有的美好&#…

【C++小游戏】推箱子代码

注:本程序完全原创,如果有BUG,欢迎私信投诉。 Upd 2023/1/2 : 把代码扔到 LOJ 里格式化了一下,希望代码看起来没原来那么丑陋。 Upd 2023/3/3 : 修复了一个没有测试出来的 bug(箱子推进去后无法立即显示) …

怎么把知网的外文文献翻译成中文_知网查重中文译成英文可行吗?

把中文翻译成英文知网查重是能查出的,最新的版本增加了中英文互译、跨语言检测等功能。因此,中国知网不仅能查重英文论文,还能将中文翻译成英文的论文给查出来。所以说,中文译成英文不是一个好办法。那么,知网查重中文译成英文可行吗? 一、中国知网能否查重英文 目前市场…

开源大模型文档

开源大模型综述 排行榜1.LLaMA资源: 2.Chinese-LLaMA-Alpaca资源: 3.Alpaca资源: 4.Alpaca-LoRA5.Vicuna资源: 6.OpenChatKit资源: 7.GPT4ALL8.Raven RWKV资源: 9.OPT资源: 10.Flan-T5-XXL资源&…

5月份读书学习好文记录

学好C可以采取以下几个步骤: 掌握基本语法:C的语法对于初学者来说可能是一件比较难的事情,所以需要花时间掌握C的语言基础和语法规则,例如数据类型、流程控制、函数等。 学会面向对象编程(OOP):C是一种面向对象的编程…

多表关联出现重复数据原因

多表联合查询的时候,可能会产生多条重复数据,出现的原因: 1.可能是你用来进行 join的列,具有重复数据。 今天下午在写sql的时候,由于没有注意到该列的值并不是唯一的,所以导致查询出来的有N条重复数据 解决…

数据拼接出现重复

数据拼接出现重复 使用join方法拼接数据出现重复 使用join方法拼接数据出现重复 打印日期和星期,首先获取当前日期毫秒,再通过for循环将毫秒计算出下一日期 如要实现打印如下日期 代码如下 当28行和23行位置互换,就会发生一下情况 原因是…

wechat——解决重试三次产生消息重复的问题

通过上篇成功的接入开发者模式,与微信交互发送文本消息和模板消息,发现消息有的时候会重复发送,最多三次。查看微信公众平台文档发现:微信服务器在五秒内收不到响应会断掉链接,并且重新发起请求,总共重试三…

如何重复对好友发同一条信息

words"期末考试必过" import pyautogui #控制键盘鼠标 import pyperclip #控制电脑的复制截切版 import time #控制时间 time.sleep(5) #设置切换窗口时准备的时间 for i in words.split("/n")*99: #split("/n")把文章分成一句一句的 pr…

GP查询并删除重复数据问题

在数据库中做增删查改时,难免会因为误操作导致数据库中存在一些重复数据,那么如何定位这些重复数据并且删除呢?本文将介绍在Greenplum数据库中如何实现查询并删除重复数据的方法。 目录 PostgreSQL与Greenplum的关系GP查询重复数据1. row_nu…

C++ 查找字符串重复字符和只出现一次的字符

#include <iostream> #include <string>using namespace std;int main() {string temp "";cout << "请输入字符串&#xff1a;";getline(cin,temp);string str ""; //存放只出现一次的字符string str1 ""; //存…

chatgpt赋能python:Python排除字符串中重复字符

Python排除字符串中重复字符 在处理字符串数据时&#xff0c;我们经常需要对字符串中的重复字符进行处理&#xff0c;以便更好地对数据进行分析和处理。在Python编程领域中&#xff0c;有许多方法可以用于排除字符串中的重复字符&#xff0c;从而使数据更加清晰和有用。在本文…

拼音打字时不定时出现重复字母

问题自述&#xff1a; 家里面有一台备用机惠普15-R239TX&#xff0c;东西放久了发现键盘缝隙里面很脏&#xff0c;得空就拆机后彻底清理了一下。 自从上次清理过键盘后&#xff0c;在使用Q Q拼音打字时会不定时出现重字母的情况&#xff0c;重新下载最新版本&#xff0c;默认设…

CPM-Bee本地部署的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

3分钟部署私人chat-gpt教程

一、注册vercel账号 点击 Vercel 邮箱注册一个号&#xff0c;86的手机号也能注册。需要github账号和openai key 二、创建项目 1. 在首页新建项目 2. 登录你的github账号&#xff0c;然后创建一个仓库 导入第三方的仓库 输入&#xff1a;https://github.com/Yidadaa/ChatGPT…

注册AppStore开发者账号以及收款设置的流程详解(2019最新版)

最近和朋友倒腾了一个APP&#xff0c;想在App Store上架&#xff0c;因此就在注册个人开发者账号的过程中踩了不少坑。 申请App Store的开发者账号果然不是一件容易的事情&#xff0c;并且我发现在设置收款时尤其容易踩坑。期间&#xff0c;我也看了不少分享&#xff0c;但由于…

苹果 company开发者账号注册流程图解分享

苹果开发者账号的注册过程还是比较复杂的&#xff0c;周期拉了一个月&#xff08;漫长啊~~&#xff09;。和大家分享一下过程和细节&#xff0c;以免大家走了弯路。本文由萌虾米492405648编写蛮辛苦的要是对你有用是我最大的欣慰啦 一定要记住申请的过程中遇到问题致电苹果开发…