譯文出自:登鏈翻譯計劃
譯者:翻譯小組
校對: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
Ava Labs宣布推出供傳統游戲開發商探索區塊鏈游戲集成的協作計劃Avalanche Arcad3:金色財經報道,Ava Labs今天宣布推出 Avalanche Arcad3,這是一個供傳統游戲開發商探索區塊鏈游戲集成的協作計劃。Ava Labs 表示,日本元宇宙和娛樂公司 Gree 和 Gumi 已加入 Arcad3,成為其最早的兩個合作伙伴,通過以太坊兼容鏈探索區塊鏈游戲。[2023/6/10 21:27:18]
);});});
測試通過了!
Contract:MachineAfterinitalize#saveValue()?shouldsuccessfullysavevalue(56ms)1passing(56ms)
如果不知道目標合約的ABI,請使用call或delegatecall
但是,如果調用者(在本例中為“Machine”合約)不知道目標合約的ABI,該怎么辦?
其實,我們仍然可以使用call()和delegatecall()來調用目標合約的函數。
在解釋以太坊Solidity的call()和delegatecall()之前,了解EVM如何保存合約變量對于了解call()和delegatecall()會有所幫助。
EVM如何將字段變量保存到存儲
在以太坊中,有兩種空間可以保存合約的字段變量。一個是“內存”,另一個是“存儲”。而且,“foo”保存到存儲意味著“foo”的值會永久記錄到區塊鏈狀態中。
那么,單個合約中的如此多的變量又是怎樣讓彼此不重疊呢?EVM將插槽號分配給字段變量。
BIS:9/10的央行正在探索數字貨幣:5月6日消息,根據國際清算銀行(BIS)進行的一項調查結果,全球十分之九的中央銀行正在探索中央銀行數字貨幣(CBDC)。調查還發現,與旨在供銀行使用的批發 CBDC 相比,更多的中央銀行正在開發或測試零售 CBDC 或旨在供消費者使用的數字貨幣。(coindesk)[2022/5/6 2:55:25]
contractSample1{uint256first;//slot0uint256second;//slot1}
ImageforpostEVM使用插槽保存字段變量
因為first在Sample1合約中最先聲明,所以分配了0個插槽。每個不同的變量都通過其插槽號來區分。
在EVM中,智能合約存儲中具有2256個插槽,每個插槽可以保存32字節大小的數據。
如何調用智能合約函數
像Java,Python這樣的通用編程代碼一樣,Solidity函數可以看作是一組命令。當我們說“函數被調用”時,這意味著我們將特定的上下文(如參數)注入到該組命令(函數)中,并且在此上下文中一個接一個地執行命令。
函數、命令組、地址空間可以通過其名稱找到。
在以太坊函數中,調用可以用字節碼表示,使用432*N個字節表達。這個字節碼由兩部分組成。
函數選擇器:這是函數調用字節碼的前4個字節。函數選擇器是通過對目標函數的名稱加上其參數類型(不包括空格)進行哈希取前4個字節得到,例如bytes4(keccak-256(“saveValue(uint)”))。基于此函數選擇器,EVM可以決定應在合約中調用哪個函數。
北京豐臺:提高加密等數字貨幣關鍵密碼技術研發,探索數字金融沙盒實驗:金色財經報道,北京市豐臺區人民政府印發《“十四五”時期豐臺區高精尖產業發展規劃》,在金融科技(數字金融)方面,支持中國人民銀行數字貨幣研究所加強技術研發投入,穩妥推進數字人民幣試點應用場景建設,提高對稱、非對稱密碼算法、認證和加密等數字貨幣關鍵密碼技術研發能力,支持數字貨幣及相關底層平臺軟硬件系統的架構設計和開發。加強區塊鏈等技術發展,研究網絡模型、分布式存儲、零知識證明、鏈上鏈下協同、監管科技等技術,以應用場景開放推動區塊鏈技術在更大規模的商業場景中落地。探索數字金融沙盒實驗等業務監管新模式。[2022/2/19 10:02:38]
函數參數:將參數的每個值轉換為固定長度為32bytes的十六進制字符串。如果有多個參數,則串聯在一起。
如果用戶將此432*N字節字節代碼傳遞給交易的數據字段。EVM可以找到應執行的函數,然后將參數注入該函數。
用測試用例解釋DelegateCall
上下文
當我們談論智能合約函數的調用方式時,有一個“上下文”一詞。實際上,“上下文”一詞在軟件中是很籠統的概念,其含義根據場合不同有所改變。
當我們談論程序的執行時,我們可以說“上下文”是指執行時所有環境(如變量或狀態)。例如,在執行程序“A”時,執行該程序的用戶名是“zeroFruit”,則用戶名“zeroFruit”可以是程序“A”的上下文。
在以太坊智能合約中,有很多上下文,其中一個代表性的事情是誰執行這個合約。你可能會在很多Solidity代碼中看到msg
聲音 | 重慶市委常委:充分利用重慶先行先試優勢,探索“區塊鏈+金融”:金色財經報道,昨日上午,2019中新金融峰會繼續舉行。在“中新金融科技合作展望暨江北嘴金融科技高峰對話”會中,重慶市委常委、兩江新區黨工委書記、管委會主任段成剛致辭。在“一個體系”建設中,段成剛提出,各方要充分用好重慶作為全國金融科技和金融標準化雙試點城市先行先試優勢,推動形成金融科技與多行業深度融合的發展體系,探索“區塊鏈+金融”,努力將金融科技港打造成為具有“一帶一路”特色和較大影響力的金融科技創新生態園。[2019/11/6]
..
functionaddValuesWithCall(addresscalculator,uint256a,uint256b)publicreturns(uint256){(boolsuccess,bytesmemoryresult)=calculator
}
下面是目標合約Calculator,它也有calculateResult和user。
pragmasolidity^0
}
測試addValuesWithCall
下面是addValuesWithCall的測試代碼。需要測試的有:
由于上下文位于“Calculator”而非“Machine”上,因此add結果應保存到“Calculator”合約存儲中
因此,Calculator的calculateResult應該為3,而user的地址應該設置為Machine的地址。
并且Machine的calculateResult應該為0,user為零地址。
動態 | 韓國主要衛星運營商探索區塊鏈技術:據韓國當地報紙EDaily報道,韓國最大的電信公司KT公司旗下的衛星運營商KT SAT正在探索區塊鏈技術。KT SAT已成立了一個工作組,負責解決包括區塊鏈在內的主要新興技術的使用問題,以擴大衛星行業現存的限制。名為KT SAT Eco Alliance的新計劃旨在匯集專注于物聯網(IoT)、網絡安全、5G以及區塊鏈等分布式賬本技術(DLT)的技術領域公司。[2018/11/24]
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:CALALLTORVALNautical CoinAlligatorkSTORE價格intervalue幣怎么買
尊敬的用戶: 因N8V項目官方將進行代幣切換,切換后的N8V代幣為ERC20通道的N8V。幣虎將支持N8V代幣切換,現已暫時關閉N8V的充提功能,并將于2021年1月5日18:00暫時關閉交易功.
1900/1/1 0:00:00昨天一天應該算是比特幣市場中比較黑暗的一天,全網在這一天爆倉金額價值累計超過98億元人民幣,根據市場研究機構提供的數據顯示,在最近的24小時內,共有107817人在比特幣的上漲行情中爆倉.
1900/1/1 0:00:00張瑞敏曾經說過,沒有成功的企業,只有時代的企業。區塊鏈的世界也是如此,區塊鏈也是隨著時代不斷發展,不斷淘汰的,而且我們發現,在區塊鏈的世界里,更新迭代來得更快一些.
1900/1/1 0:00:00尊敬的用戶: 平臺即日起啟動云平臺遷移工作,以下為相關注意事項:1.平臺將于2021年1月05日15:00將暫停交易和提幣功能,屆時將自動撤銷訂單.
1900/1/1 0:00:00最近先有硬件錢包?Ledger?泄露?27萬用戶信息,后有保險協議?NexusMutual?創始人HughKarp?遭黑客攻擊?37萬NXM代幣被盜.
1900/1/1 0:00:002021.1.2早間行情分析及操作思路: 行情回顧: 前幾日日幣策神給到的長線單多空指數拿到4000多點的空間!相信大家前幾天有所關注到拿到最高空,也是拿到低點的多單,對行情精準的判斷.
1900/1/1 0:00:00