譯文出自:登鏈翻譯計劃
譯者:翻譯小組
校對: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
《河套深港科技創新合作區深圳園區發展規劃》發布:積極探索區塊鏈等技術在金融領域的規范應用:金色財經報道,國務院印發《河套深港科技創新合作區深圳園區發展規劃》,明確指出要規劃建設好河套深圳香港科技創新合作區。《規劃》指出香港和甚至將聯手打造國際一流科技創新平臺,聚焦區塊鏈與量子信息等前沿交叉領域,支持深港聯合國內外高校、科研院所在深圳園區共建卓越研究中心,積極探索區塊鏈等技術在金融領域的規范應用,加快建設深圳數據交易場所。[2023/9/4 13:17:09]
);});});
測試通過了!
Contract:MachineAfterinitalize#saveValue()?shouldsuccessfullysavevalue(56ms)1passing(56ms)
如果不知道目標合約的ABI,請使用call或delegatecall
但是,如果調用者(在本例中為“Machine”合約)不知道目標合約的ABI,該怎么辦?
其實,我們仍然可以使用call()和delegatecall()來調用目標合約的函數。
在解釋以太坊Solidity的call()和delegatecall()之前,了解EVM如何保存合約變量對于了解call()和delegatecall()會有所幫助。
EVM如何將字段變量保存到存儲
在以太坊中,有兩種空間可以保存合約的字段變量。一個是“內存”,另一個是“存儲”。而且,“foo”保存到存儲意味著“foo”的值會永久記錄到區塊鏈狀態中。
那么,單個合約中的如此多的變量又是怎樣讓彼此不重疊呢?EVM將插槽號分配給字段變量。
幣安首席執行官:幣安美國正在探索收購其他不良資產:金色財經報道,幣安首席執行官表示,幣安美國正在探索收購其他不良資產。(金十)[2022/12/20 21:55:13]
contractSample1{uint256first;//slot0uint256second;//slot1}
ImageforpostEVM使用插槽保存字段變量
因為first在Sample1合約中最先聲明,所以分配了0個插槽。每個不同的變量都通過其插槽號來區分。
在EVM中,智能合約存儲中具有2256個插槽,每個插槽可以保存32字節大小的數據。
如何調用智能合約函數
像Java,Python這樣的通用編程代碼一樣,Solidity函數可以看作是一組命令。當我們說“函數被調用”時,這意味著我們將特定的上下文(如參數)注入到該組命令(函數)中,并且在此上下文中一個接一個地執行命令。
函數、命令組、地址空間可以通過其名稱找到。
在以太坊函數中,調用可以用字節碼表示,使用432*N個字節表達。這個字節碼由兩部分組成。
函數選擇器:這是函數調用字節碼的前4個字節。函數選擇器是通過對目標函數的名稱加上其參數類型(不包括空格)進行哈希取前4個字節得到,例如bytes4(keccak-256(“saveValue(uint)”))。基于此函數選擇器,EVM可以決定應在合約中調用哪個函數。
函數參數:將參數的每個值轉換為固定長度為32bytes的十六進制字符串。如果有多個參數,則串聯在一起。
網易:具備探索元宇宙所需要的技術儲備:12月3日,網易星球在其官方公號表示,通過循序漸進地布局區塊鏈技術,網易已經在身份認證、價值認證等方面取得了一些成果,并展開了落地應用,具備了探索元宇宙所需要的技術儲備。[2021/12/3 12:49:11]
如果用戶將此432*N字節字節代碼傳遞給交易的數據字段。EVM可以找到應執行的函數,然后將參數注入該函數。
用測試用例解釋DelegateCall
上下文
當我們談論智能合約函數的調用方式時,有一個“上下文”一詞。實際上,“上下文”一詞在軟件中是很籠統的概念,其含義根據場合不同有所改變。
當我們談論程序的執行時,我們可以說“上下文”是指執行時所有環境(如變量或狀態)。例如,在執行程序“A”時,執行該程序的用戶名是“zeroFruit”,則用戶名“zeroFruit”可以是程序“A”的上下文。
在以太坊智能合約中,有很多上下文,其中一個代表性的事情是誰執行這個合約。你可能會在很多Solidity代碼中看到msg
..
functionaddValuesWithCall(addresscalculator,uint256a,uint256b)publicreturns(uint256){(boolsuccess,bytesmemoryresult)=calculator
}
下面是目標合約Calculator,它也有calculateResult和user。
pragmasolidity^0
聲音 | 工行相關人士:銀行區塊鏈技術應用領域和探索已越來越多:金色財經報道,工行相關人士表示,區塊鏈中對信息不可篡改的特征解決了信任問題,風險評估更準確,也有利于定價。該人士認為,從行業發展來看,銀行對于區塊鏈目前最多的應用領域在于供應鏈。通過供應鏈能夠在解決小微企業“融資難”和“融資貴”上起到重要作用。很多銀行在內部都有一個獨立的鏈,但是沒有放開實現跨鏈。這其中也涉及到一些信息隱私和客戶競爭問題。新技術的應用都有一個過程,至少現在銀行區塊鏈技術應用領域和探索是越來越多了。[2019/11/2]
}
測試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
動態 | 南方電網積極探索區塊鏈技術應用:據中國電力新聞網消息,南方電網公司始終堅持推進核心技術創新和商業模式創新,提早布局區塊鏈技術在能源領域的應用。在珠海,廣東電網公司珠海供電局開展了基于區塊鏈技術的綠證交易平臺試點示范。在深圳,南網電動汽車公司于今年1月31日開出全國首份充電電費區塊鏈電子發票,截至昨日,已累計開具5000余張。據了解,在國內外能源領域中,區塊鏈技術多用于解決可再生能源消納、電力分布式交易等問題。珠海供電局在支持能源消費革命的城市—園區雙級“互聯網+”智慧能源示范項目中建立的綠證交易平臺,正是將綠色證書交易與區塊鏈技術結合起來,實現分布式資源用戶、綠證購買商等不同主體身份的安全認證和綠證交易的高效運作。[2019/10/31]
);});
按預期通過了所有測試:
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意味著什么?
DeFi數據 1.DeFi總市值:225.13億美元市值前十幣種漲跌幅,金色財經制圖,數據來源Coingecko2.過去24小時去中心化交易所的交易量:28.6億美元交易量排名前十的DEX數據來.
1900/1/1 0:00:00最近市場上突然出現了一個去中心化合約交易平臺的項目,Bluecat,今天我們就來一起看看這個項目是什么樣的?去中心化合約交易平臺到底是什么?我們都知道目前的去中心化交易所的話.
1900/1/1 0:00:00算法穩定幣最近特別火爆,尤其是在SEC起訴Ripple之后——投資者們對監管趨嚴的擔憂又進一步加深,雖然本質上其實是對中心化機構的不信任.
1900/1/1 0:00:00央廣網北京1月2日消息據中央廣播電視總臺中國之聲《新聞縱橫》報道,繼深圳、蘇州陸續試點央行數字貨幣以來,近期,由央行主導的數字貨幣試點落地北京.
1900/1/1 0:00:00尊敬的用戶:HotcoinGlobal將于(GMT8)2021年1月10日12:00開放BIM充提業務,1月10日15:00開放BIM/USDT交易.
1900/1/1 0:00:00比特幣礦工發現北歐土地是一個獲利的機會來增加收入,這是因為電價暴跌的最便宜水平比其他任何知名的加密貨幣開采地都高.
1900/1/1 0:00:00