区块见闻 区块见闻
Ctrl+D收藏区块见闻
首页 > SHIB > 正文

VAL:探索以太坊合约委托调用(DelegateCall)_ALL

作者:

时间:

译文出自:登链翻译计划

译者:翻译小组

校对:Tiny熊

在本文中,我们看看如何调用另一个合约的函数,并更深入讨论delegatecall委托调用。

有时,需要在编写以太坊智能合约代码中,与其他合约进行交互。在Solidity中,有几种方法可以实现此目标:

如果知道目标合约的ABI,可以直接使用函数签名

假设已经部署了一个简单的合约,称为“Storage”,该合约允许用户保存val。

pragmasolidity^0

functionsetValue(uintv)public{val=v;}}

现在我们部署另一个称为“Machine”的合约,它是“Storage”合约的调用方。“Machine”引用“Storage”合约并更改其val。

pragmasolidity^0

functionsaveValue(uintx)publicreturns(bool){s

functiongetValue()publicviewreturns(uint){returns

}

在此案例中,我们知道Storage合约的ABI及其地址,以便我们可以使用该地址初始化现有的Storage合约,而ABI的作用是告诉我们如何调用Storage合约的函数。可以看到Machine合约调用了Storage

);describe('#saveValue()',()=>{it('shouldsuccessfullysavevalue',async()=>{awaitMachine

Aave即将在以太坊主网启动去中心化稳定币GHO:7月14日消息,Aave 关于在主网启动其去中心化稳定币 GHO的AIP提案已获得投票通过,该提案旨在通过 Aave V3 Facilitator 和 FlashMinter Facilitator 将 GHO 引入以太坊主网。该提案将在一天内在链上执行,GHO最早可能于7月15日在以太坊区块链上推出,以太坊上的 Aave V3 用户将能够使用抵押品来铸造 GHO。[2023/7/15 10:56:07]

);});});

测试通过了!

Contract:MachineAfterinitalize#saveValue()?shouldsuccessfullysavevalue(56ms)1passing(56ms)

如果不知道目标合约的ABI,请使用call或delegatecall

但是,如果调用者(在本例中为“Machine”合约)不知道目标合约的ABI,该怎么办?

其实,我们仍然可以使用call()和delegatecall()来调用目标合约的函数。

在解释以太坊Solidity的call()和delegatecall()之前,了解EVM如何保存合约变量对于了解call()和delegatecall()会有所帮助。

EVM如何将字段变量保存到存储

在以太坊中,有两种空间可以保存合约的字段变量。一个是“内存”,另一个是“存储”。而且,“foo”保存到存储意味着“foo”的值会永久记录到区块链状态中。

那么,单个合约中的如此多的变量又是怎样让彼此不重叠呢?EVM将插槽号分配给字段变量。

海南国际知识产权交易中心开业 将探索区块链技术相关落地应用:8月28日,海南国际知识产权交易中心正式开业,标志着海南自贸港在建设国际化知识产权交易场所、探索规范知识产权证券化等方面,迈出了重要一步。海南国知中心总经理赵军表示,海南国知中心将积极探索区块链技术在知识产权存证、交易中的落地应用,已建成的多链社区可实现知识产权上链、存证,并将继续搭建“IP多链联盟”。(新华网)[2020/8/28]

contractSample1{uint256first;//slot0uint256second;//slot1}

ImageforpostEVM使用插槽保存字段变量

因为first在Sample1合约中最先声明,所以分配了0个插槽。每个不同的变量都通过其插槽号来区分。

在EVM中,智能合约存储中具有2256个插槽,每个插槽可以保存32字节大小的数据。

如何调用智能合约函数

像Java,Python这样的通用编程代码一样,Solidity函数可以看作是一组命令。当我们说“函数被调用”时,这意味着我们将特定的上下文(如参数)注入到该组命令(函数)中,并且在此上下文中一个接一个地执行命令。

函数、命令组、地址空间可以通过其名称找到。

在以太坊函数中,调用可以用字节码表示,使用432*N个字节表达。这个字节码由两部分组成。

函数选择器:这是函数调用字节码的前4个字节。函数选择器是通过对目标函数的名称加上其参数类型(不包括空格)进行哈希取前4个字节得到,例如bytes4(keccak-256(“saveValue(uint)”))。基于此函数选择器,EVM可以决定应在合约中调用哪个函数。

安徽亳州:探索开展绿色食品、有机农产品区块链追溯应用:记者从安徽省亳州市民生办了解到,该市今年继续实施农产品质量安全追溯体系民生工程,新培育68个以上“三品一标”农产品和68个以上规模生产经营主体的农产品实现追溯,推动规模以上农产品生产经营单位入驻国家、省追溯管理信息平台和市智慧农业综合服务平台,探索开展绿色食品、有机农产品区块链追溯应用。(中安在线)[2020/6/28]

函数参数:将参数的每个值转换为固定长度为32bytes的十六进制字符串。如果有多个参数,则串联在一起。

如果用户将此432*N字节字节代码传递给交易的数据字段。EVM可以找到应执行的函数,然后将参数注入该函数。

用测试用例解释DelegateCall

上下文

当我们谈论智能合约函数的调用方式时,有一个“上下文”一词。实际上,“上下文”一词在软件中是很笼统的概念,其含义根据场合不同有所改变。

当我们谈论程序的执行时,我们可以说“上下文”是指执行时所有环境(如变量或状态)。例如,在执行程序“A”时,执行该程序的用户名是“zeroFruit”,则用户名“zeroFruit”可以是程序“A”的上下文。

在以太坊智能合约中,有很多上下文,其中一个代表性的事情是谁执行这个合约。你可能会在很多Solidity代码中看到msg

..

functionaddValuesWithCall(addresscalculator,uint256a,uint256b)publicreturns(uint256){(boolsuccess,bytesmemoryresult)=calculator

动态 | Opera与Ledger Capital合作探索区块链应用:据9月28日发布的一份新闻稿称,Opera已经与区块链咨询和金融服务公司Ledger Capital合作,探索可能的区块链应用。根据声明,这两家公司正在调查区块链的应用和用例,以及如何将该技术部署到Opera产品及其生态系统中。此前曾报道,Opera成为第一个包含内置加密货币钱包的主要web浏览器。Opera crypto wallet的产品负责人查尔斯?哈默尔(Charles Hamel)在评论这项举措时说:“用crypto钱包付款就像直接从手机发送数字现金一样……这为商家和内容创造者带来了新的可能性。”[2018/9/29]

}

下面是目标合约Calculator,它也有calculateResult和user。

pragmasolidity^0

}

测试addValuesWithCall

下面是addValuesWithCall的测试代码。需要测试的有:

由于上下文位于“Calculator”而非“Machine”上,因此add结果应保存到“Calculator”合约存储中

因此,Calculator的calculateResult应该为3,而user的地址应该设置为Machine的地址。

并且Machine的calculateResult应该为0,user为零地址。

describe('#addValuesWithCall()',()=>{letCalculator;beforeEach(async()=>{Calculator=awaitCalculatorFactory

受政府收紧供应链的压力推动 美国制药公司探索区块链技术应用:据华尔街日报消息,在联邦政府要求收紧药品供应链,并防止药物落入不法之手的压力下,制药公司正在加紧推动有前景但未被证实的区块链技术的落地应用。美源伯根和默克公司就计划扩大去年完成的一个测试项目,该项目旨在追溯医疗保健供应链中药物的所有权。[2018/6/7]

);it('shouldsuccessfullyaddvalueswithcall',async()=>{constresult=awaitMachine

);});

按预期通过了所有测试:

Contract:MachineAfterinitalize#addValuesWithCall()?shouldsuccessfullyaddvalueswithcall(116ms)1passing(116ms)

测试addValuesWithDelegateCall

下面是我们的addValuesWithCall测试代码。我们需要测试的有:

由于上下文位于“Machine”而非“Calculator”上,因此add结果应保存到“Machine”存储中。

因此,Calculator的calculateResult应该为0,而user的地址应为0地址。

而Machine的calculateResult应为3,而user的则为用户地址。

describe('#addValuesWithDelegateCall()',()=>{letCalculator;beforeEach(async()=>{Calculator=awaitCalculatorFactory

);it('shouldsuccessfullyaddvalueswithdelegatecall',async()=>{constresult=awaitMachine

);});

但是失败了!什么呢?“562046206989085878832492993516240920558397288279”来自哪里?

0passing(236ms)1failing1)Contract:MachineAfterinitalize#addValuesWithDelegateCall()shouldsuccessfullyaddvalueswithdelegatecall:AssertionError:expected'562046206989085878832492993516240920558397288279'toequal'3'expected-actual-5620462069890858788324929935162409205583972882793

如前所述,每个字段变量都有其自己的插槽。当我们委托调用Calculator时,上下文位于Machine上,但是插槽编号基于Calculator。

因此,由于Calculator用calculateResult覆盖了Storage地址,而user覆盖了calculateResult,因此测试失败。

基于此知识,我们可以找到“562046206989085875878832492993516240920558397288279”的来源。它是EOA的十进制版本。

Imageforpost“Calculator”合约字段变量将覆盖“Machine”合约字段变量

因此,要解决此问题,我们需要更改“Machine”字段变量的顺序。

contractMachine{uint256publiccalculateResult;addresspublicuser;Storagepublics;...}

最后,测试通过了!

Contract:MachineAfterinitalize#addValuesWithDelegateCall()?shouldsuccessfullyaddvalueswithdelegatecall(106ms)1passing(247ms)

总结一下

在本文中,我们已经看到了如何从合约中调用另一个合约的函数。

如果我们知道目标函数的ABI,就可以直接使用目标函数签名

如果我们不知道目标函数的ABI,可以使用call()或delegatecall()。但是在delegatecall()的情况下,我们需要关心字段变量的顺序。

源代码

如果你想自己进行测试,可以在此代码库中找到代码。

本翻译由CellNetwork赞助支持。

来源:https://medium.com/coinmonks/delegatecall-calling-another-contract-function-in-solidity-b579f804178c

参考资料

登链翻译计划:https://github.com/lbc-team/Pioneer

翻译小组:https://learnblockchain.cn/people/412

Tiny熊:https://learnblockchain.cn/people/15

ABI:https://learnblockchain.cn/docs/solidity/abi-spec.html

此代码库:https://github.com/zeroFruit/upgradable-contract/tree/feat/delegatecall

CellNetwork:https://www.cellnetwork.io/?utm_souce=learnblockchain

本文来源于非小号媒体平台:

登链社区

现已在非小号资讯平台发布105篇作品,

非小号开放平台欢迎币圈作者入驻

入驻指南:

/apply_guide/

本文网址:

/news/9569963.html

免责声明:

1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险

2.本文版权归属原作所有,仅代表作者本人观点,不代表非小号的观点或立场

上一篇:

币安为何推出第三条链?这对BNB意味着什么?

标签:ALLTORVALLATSwapAllTORNValkyrioplaton币怎么样

SHIB热门资讯
比特币:Loan Shifter 简介 — 让你的资产在不同的协议自由穿梭_makerdao下载

*译文出自:登链翻译计划 *译者:翻译小组 *校对:Tiny熊 你可能有多种原因想要更改当前头寸:也许你想将MakerDAO持有的ETH转换为USDC,或者你觉得ETH会有更高的表现.

BIT:阿根廷的Ripio收购了巴西第二大加密货币交易所_bitcoinfaith

阿根廷的Ripio已收购了巴西第二大加密货币交易所BitcoinCoco,以增加其在泡沫拉丁美洲的加密货币市场中的足迹。Ripio在2020年创下新高,突破了100万用户里程碑.

ETH:2020年几大山寨币的炒作活动比率指数_DrinkChain

本文跟踪了大家最喜欢的几种加密货币的炒作和价格走势。加密货币爱好者倾向于捍卫他们最喜爱的加密资产。看看XRP和LINK的支持者就知道了.

SET:比特币再破新高,回撤下行修复之后,币价涨势将再次展开攻势_Allbestico

前言:买卖遭损失时,切忌徒式加码,以谋求摊低成本消息面:金沙江创投朱啸虎:若民主党赢得美国参议院席位BTC将涨至5万美元金沙江创投董事总经理朱啸虎今日朋友圈表示.

INK:2021年比特币投资概览丨AAX新年特辑_XRP

目录 简介 第一章:新兴资产类别的诞生 比特币简介 比特币的重要性 第二章:比特币–具投资价值资产历史价格:2009-2019历史价格:2019-2021 交易量及流动性 供应及需求 第三章:未.

Gate.io:Gate.io“天天理财”第87期ETH锁仓理财明日开启,年化收益5%_Gatechain Token

Gate.io全新理财福利产品——“天天理财”已于10月12日正式上线,每天中午12点至少一场理财福利,赚主流币理财收益,天天理财天天乐!《BTC锁仓理财》于今日中午12点上线,目前进行中.