译文出自:登链翻译计划
译者:翻译小组
校对: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
灰度 CFO:公司会定期评估Staking业务的发展,作为探索Staking的一部分:金色财经报道,Grayscale首席财务官Edward McGee在接受采访时表示,截至2022年8月,公司目前没有的任何投资进行质押,尽管我们目前没有在我们的任何投资工具中质押资产,但我们一直在积极探索质押适用的灰度产品的可能性。PoS 协议等创新技术可能具有变革性,但也存在必须仔细评估的风险。作为我们探索的一部分,我们的团队已经确定了在灰度产品结构中质押数字资产的一些关键风险和不确定性领域。
最重大的风险之一是税务处理和责任。被认为通过像我们的一种产品这样的投资工具从数字资产的质押中获得任何收益的投资者可能面临重大的税收影响。
还有一些技术和运营风险可能导致资产损失。目前,支持灰度产品的数字资产保存在一流的离线“冷”存储中。为了在我们的产品中安全可靠地质押数字资产,我们可能会聘请机构级组织来帮助监控和减轻新的或正在出现的风险。因此,我们会定期评估 Staking 业务的发展,作为我们探索产品 Staking 的一部分。[2022/8/15 12:26:29]
);});});
测试通过了!
Contract:MachineAfterinitalize#saveValue()?shouldsuccessfullysavevalue(56ms)1passing(56ms)
如果不知道目标合约的ABI,请使用call或delegatecall
但是,如果调用者(在本例中为“Machine”合约)不知道目标合约的ABI,该怎么办?
其实,我们仍然可以使用call()和delegatecall()来调用目标合约的函数。
高盛:探索如何确定比特币和其他加密资产的“基本面”:本周,高盛经济研究团队的Zach Pandl和Isabella Rosenberg发布报告,探索了如何确定加密资产的基本面问题。报告指出,将加密资产等同于黄金是确定其基本面的常见框架,但除此之外,加密货币价格也与其底层分布式网络的价值有关。报告使用区块链地址估算网络用户数量,并与货币市值进行比较,观察到:“市值与网络规模之间存在明显的相关性”,且相关性超过1。他们基于历史数据计算出的平均增长曲线接近价值=用户数的1.4次幂,这给出了一个利用基本面作为市值参考的基准比率。基于该推断,报告指出BTC的市值远大于基本面,其基于用户增量的价值(基本面)与市值相比存在严重偏差。过去几年,比特币市值较2018年平均水平上涨520%,但网络仅增长60-100%。报告认为这一偏差意味着要么比特币现在被高估,要么2018年被低估,要么兼而有之。但报告也指出,除基本面因素外,加密货币上涨还有众多其他因素,包括情绪,以及它作为一种快速致富的新方式的吸引力。但投机交易带来的网络活动增加并不能完全反应基本面的改善,因为平台并未获得更高的经济价值,要使加密货币网络具备可持续价值,活动需要由非投机性用例驱动,而目前此类用例十分缺乏。(雅虎财经)[2021/7/21 1:06:15]
在解释以太坊Solidity的call()和delegatecall()之前,了解EVM如何保存合约变量对于了解call()和delegatecall()会有所帮助。
EVM如何将字段变量保存到存储
在以太坊中,有两种空间可以保存合约的字段变量。一个是“内存”,另一个是“存储”。而且,“foo”保存到存储意味着“foo”的值会永久记录到区块链状态中。
欧洲央行正探索使用即时支付平台TIPS发行数字欧元:1月29日消息,当地时间周五,欧洲央行政策制定者、意大利央行行长Ignazio Visco表示,欧洲央行正在探索使用即时支付平台发行数字欧元的方法。Ignazio Visco称,如果数字欧元推出,那么它可以在意大利银行开发的欧洲即时支付结算基础设施TIPS上运行。目前正与欧洲央行一起进行试验,以探索使用TIPS作为引入数字欧元技术解决方案的可能性。(路透社)[2021/1/29 14:21:37]
那么,单个合约中的如此多的变量又是怎样让彼此不重叠呢?EVM将插槽号分配给字段变量。
contractSample1{uint256first;//slot0uint256second;//slot1}
ImageforpostEVM使用插槽保存字段变量
因为first在Sample1合约中最先声明,所以分配了0个插槽。每个不同的变量都通过其插槽号来区分。
在EVM中,智能合约存储中具有2256个插槽,每个插槽可以保存32字节大小的数据。
如何调用智能合约函数
像Java,Python这样的通用编程代码一样,Solidity函数可以看作是一组命令。当我们说“函数被调用”时,这意味着我们将特定的上下文(如参数)注入到该组命令(函数)中,并且在此上下文中一个接一个地执行命令。
函数、命令组、地址空间可以通过其名称找到。
在以太坊函数中,调用可以用字节码表示,使用432*N个字节表达。这个字节码由两部分组成。
函数选择器:这是函数调用字节码的前4个字节。函数选择器是通过对目标函数的名称加上其参数类型(不包括空格)进行哈希取前4个字节得到,例如bytes4(keccak-256(“saveValue(uint)”))。基于此函数选择器,EVM可以决定应在合约中调用哪个函数。
声音 | 金轮股份:正与腾讯金融云基于大宗商品区块链仓单项目做合作探索:11月25日,金轮股份在互动平台表示,公司正在与腾讯金融云基于大宗商品区块链仓单项目做合作探索。[2019/11/25]
函数参数:将参数的每个值转换为固定长度为32bytes的十六进制字符串。如果有多个参数,则串联在一起。
如果用户将此432*N字节字节代码传递给交易的数据字段。EVM可以找到应执行的函数,然后将参数注入该函数。
用测试用例解释DelegateCall
上下文
当我们谈论智能合约函数的调用方式时,有一个“上下文”一词。实际上,“上下文”一词在软件中是很笼统的概念,其含义根据场合不同有所改变。
当我们谈论程序的执行时,我们可以说“上下文”是指执行时所有环境(如变量或状态)。例如,在执行程序“A”时,执行该程序的用户名是“zeroFruit”,则用户名“zeroFruit”可以是程序“A”的上下文。
在以太坊智能合约中,有很多上下文,其中一个代表性的事情是谁执行这个合约。你可能会在很多Solidity代码中看到msg
..
functionaddValuesWithCall(addresscalculator,uint256a,uint256b)publicreturns(uint256){(boolsuccess,bytesmemoryresult)=calculator
}
下面是目标合约Calculator,它也有calculateResult和user。
声音 | 苏宁相关负责人:目前正在进一步探索区块链更多的应用场景:金色财经报道,苏宁相关负责人表示,目前正在进一步探索区块链更多的应用场景,如区块链应收账款、区块链票据、区块链物联网在物流中应用等,并着手进行系统开发。未来将在助力小微,为行业赋能,构建“金融+科技”生态圈,更好服务实体经济。[2019/10/31]
pragmasolidity^0
}
测试addValuesWithCall
下面是addValuesWithCall的测试代码。需要测试的有:
由于上下文位于“Calculator”而非“Machine”上,因此add结果应保存到“Calculator”合约存储中
因此,Calculator的calculateResult应该为3,而user的地址应该设置为Machine的地址。
并且Machine的calculateResult应该为0,user为零地址。
describe('#addValuesWithCall()',()=>{letCalculator;beforeEach(async()=>{Calculator=awaitCalculatorFactory
);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意味着什么?
摘要:在比特币存在的头?7?个月里,比特币创造者中本聪开采了多达?110?万枚比特币。这一财富目前价值超过?300?亿美元,但至今未被触及.
1900/1/1 0:00:00一、什么是ASwap?ASwap是AEX基于自动化做市商原理开发的流动性挖矿产品。ASwap由不同的流动池组成,每个流动池中存在两种数字货币.
1900/1/1 0:00:00亲爱的大币网(Dcoin)用户:"用信用卡购买数字货币"服务提供商Simplex最近因购买比特币的需求激增和行情剧变,发生流量问题,预计暂停Simplex服务。重开时间请参考最新公告.
1900/1/1 0:00:00?我一直有个感觉,很多事情都会经历由简入繁,再从繁归简的过程。人生如此,学习如此,投资亦是如此.
1900/1/1 0:00:00小币择时最重要的三个要素是什么?1.价格的短期周期。比如无论是0.3的dsd还是24的mph,事后看,宜分批搞一点。因为短期波动到了低位.
1900/1/1 0:00:00近年来,中央及各地方政府相继出台了多项纲领性文件,以加速推动我国区块链技术发展落地。据不完全统计,2020年以来,国家及地方层面共发布了179条区块链相关政策,政策内容包括产业培育、落地应用、行.
1900/1/1 0:00:00