譯文出自:登鏈翻譯計劃
譯者:翻譯小組
校對: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
阿聯酋自由區 RAK DAO 將探索運營比特幣全節點和閃電節點:金色財經報道,迪拜加密律師 Irina Heaver 稱,一旦 Ras AI Khaimah Digital Assets Oasis(RAK DAO)找到合適的合作伙伴,它將探索通過比特幣和其他穩定幣等加密支付用戶企業注冊、辦公室租金和其他服務,RAK DAO 還將探索運營比特幣全節點和閃電節點,以支持加密支付計劃。
RAK DAO 是一個新的元宇宙、區塊鏈、實用代幣、數字錢包、NFT、DAO、DApp 和其他 Web3 相關服務的數字和虛擬資產服務提供商的專用自由區,將促進受監管和不受監管的活動。[2023/3/3 12:40:48]
);});});
測試通過了!
Contract:MachineAfterinitalize#saveValue()?shouldsuccessfullysavevalue(56ms)1passing(56ms)
如果不知道目標合約的ABI,請使用call或delegatecall
但是,如果調用者(在本例中為“Machine”合約)不知道目標合約的ABI,該怎么辦?
其實,我們仍然可以使用call()和delegatecall()來調用目標合約的函數。
在解釋以太坊Solidity的call()和delegatecall()之前,了解EVM如何保存合約變量對于了解call()和delegatecall()會有所幫助。
EVM如何將字段變量保存到存儲
在以太坊中,有兩種空間可以保存合約的字段變量。一個是“內存”,另一個是“存儲”。而且,“foo”保存到存儲意味著“foo”的值會永久記錄到區塊鏈狀態中。
雄安新區探索數字人民幣硬錢包物物支付創新場景:近日,在雄安新區黨工委管委會、中國人民銀行石家莊中心支行的指導與支持下,中國銀行、中國電信和國家電網率先在雄安新區將數字人民幣硬錢包應用于新能源汽車充電場景,探索實現物物支付新技術落地。(中國雄安官網)[2021/3/19 19:01:05]
那么,單個合約中的如此多的變量又是怎樣讓彼此不重疊呢?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可以決定應在合約中調用哪個函數。
動態 | 塔塔集團等七家礦業集團與世界經濟論壇合作,探索建立原材料采購區塊鏈平臺:據Economictimes消息,包括印度最大的集團公司塔塔集團在內的七家礦業和金屬公司已與世界經濟論壇(WEF)合作,探索建立原材料采購區塊鏈平臺。WEF表示,該平臺將解決物料追蹤和碳排放量報告的透明度問題。此次合作將致力于試驗,設計和部署區塊鏈解決方案,以確保準確的原材料采購數據。[2019/10/25]
函數參數:將參數的每個值轉換為固定長度為32bytes的十六進制字符串。如果有多個參數,則串聯在一起。
如果用戶將此432*N字節字節代碼傳遞給交易的數據字段。EVM可以找到應執行的函數,然后將參數注入該函數。
用測試用例解釋DelegateCall
上下文
當我們談論智能合約函數的調用方式時,有一個“上下文”一詞。實際上,“上下文”一詞在軟件中是很籠統的概念,其含義根據場合不同有所改變。
當我們談論程序的執行時,我們可以說“上下文”是指執行時所有環境(如變量或狀態)。例如,在執行程序“A”時,執行該程序的用戶名是“zeroFruit”,則用戶名“zeroFruit”可以是程序“A”的上下文。
在以太坊智能合約中,有很多上下文,其中一個代表性的事情是誰執行這個合約。你可能會在很多Solidity代碼中看到msg
..
functionaddValuesWithCall(addresscalculator,uint256a,uint256b)publicreturns(uint256){(boolsuccess,bytesmemoryresult)=calculator
動態 | 頭部 OTC 機構攜 50 余家加密貨幣交易商探索建立 OTC 白名單框架:據鏈聞消息,包括 Jump Trading、Galaxy Digital、Cumberland 等頭部加密貨幣場外交易(OTC)機構在內的行業自律組織 CORA 在芝加哥召開會議,討論實施加密貨幣場外交易「白名單」框架,希望促進交易新標準的形成,從而擴大交易市場,吸引來自華爾街的專業交易者加入。CORA 的成員包括 Jump Trading、Galaxy Digital、Cumberland 等 50 家知名場外交易機構,這些機構 1 月底曾在渣打銀行資深人士林豪倫于新加坡組建的圓桌會議上聯合成立了加密貨幣衍生品交易所 Liquidity Offset Network,以增加交易量并降低交易成本,最早可能于 7 月獲得監管部門批準。[2019/5/14]
}
下面是目標合約Calculator,它也有calculateResult和user。
pragmasolidity^0
}
測試addValuesWithCall
下面是addValuesWithCall的測試代碼。需要測試的有:
由于上下文位于“Calculator”而非“Machine”上,因此add結果應保存到“Calculator”合約存儲中
因此,Calculator的calculateResult應該為3,而user的地址應該設置為Machine的地址。
并且Machine的calculateResult應該為0,user為零地址。
聲音 | Twitter首席執行官:Twitter正在探索區塊鏈的潛在應用:據Cointelegraph 9月7日消息,Twitter首席執行官杰克·多爾西(Jack Dorsey)在國會委員會作證時表示,該公司正在探索區塊鏈技術的潛在應用。杰克·多爾西在出席國會關于Twitter透明度和問責制的聽證會上回答了有關問題。當被問及區塊鏈技術對公司可能有哪些潛在應用,多西表示,區塊鏈可以用來打擊錯誤信息和騙局。[2018/9/7]
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意味著什么?
Tags:CALALLTORLATGrayscale Bitcoin Trust tokenized stock FTXminifootball幣燃燒嗎RAPTORjubilations
尊敬的用戶: WBF即將在開放區上線SKT/USDT交易對,具體上線時間請關注官方公告。 項目介紹: Vast是由新加坡資深基金會Profund發起,其核心技術團隊在美國區塊鏈行業從業七年以上,
1900/1/1 0:00:00親愛的BKEXer:??BKEXGlobal已完成SPA智能合約的置換,現已恢復SPA/USDT交易對交易功能和SPA充提功能,并不再支持SPA舊幣的充幣和提幣業務.
1900/1/1 0:00:00Gate.io今日已經根據用戶FIL6持倉情況完成FIL分發,總計約1.3萬枚,用戶可在賬戶賬單明細中查看詳情.
1900/1/1 0:00:00伴隨著比特幣漲勢,加密貨幣以太坊周一繼續創下歷史新高,幣價升破1100美元,24小時內漲幅超過30%。在比特幣的帶動下,分析師預計,機構將在2021年開始購買以太坊.
1900/1/1 0:00:00鏈聞消息,去中心化期貨交易所Futureswap發布V2測試版,增加了預言機中繼器網絡以實時報價,也在高效交易以及更高的資本效率等方面進行了更新,另外.
1900/1/1 0:00:00親愛的BitMax用戶:為支持Nsure.Network(NSURE)?的生態建設,BitMax現已開通NSURE代幣的Staking存幣生息服務.
1900/1/1 0:00:00