Solidity極簡入門|第二十三講:Delegatecall
BlockBeats 律動財經 2022-08-25 20:30
我最近在重新學 solidity,鞏固一下細節,也寫一個「Solidity 極簡入門」,供小白們使用(編程大佬可以另找教程),每周更新 1-3 講。
所有代碼和教程開源在 github:github.com/AmazingAng/WTFSolidity
delegatecall
delegatecall 與 call 類似,是 solidity 中地址類型的低級成員函數。delegate 中是委託/代表的意思,那麼 delegatecall 委託了什麼?
當用戶 A 通過合約 B 來 call 合約 C 的時候,執行的是合約 C 的函數,語境 (Context,可以理解為包含變量和狀態的環境) 也是合約 C 的:msg.sender 是 B 的地址,並且如果函數改變一些狀態變量,產生的效果會作用於合約 C 的變量上。
而當用戶 A 通過合約 B 來 delegatecall 合約 C 的時候,執行的是合約 C 的函數,但是語境仍是合約 B 的:msg.sender 是 A 的地址,並且如果函數改變一些狀態變量,產生的效果會作用於合約 B 的變量上。
大家可以這樣理解:一個富商把它的資產(狀態變量)都交給一個 VC 代理(目標合約的函數)來打理。執行的是 VC 的函數,但是改變的是富商的狀態。
delegatecall 語法和 call 類似,也是:
其中二進制編碼利用結構化編碼函數 abi.encodeWithSignature 獲得:
函數簽名為"函數名(逗號分隔的參數類型)"。例如 abi.encodeWithSignature("f(uint256,address)", _x, _addr)。
和 call 不一樣,delegatecall 在調用合約時可以指定交易發送的 gas,但不能指定發送的 ETH 數額
注意:delegatecall 有安全隱患,使用時要保證當前合約和目標合約的狀態變量儲存結構相同,並且目標合約安全,不然會造成資產損失。
什麼情況下會用到 delegatecall?
目前 delegatecall 主要有兩個應用場景:
代理合約(Proxy Contract):將智能合約的儲存合約和邏輯合約分開:代理合約(Proxy Contract)儲存所有相關的變量,並且保存邏輯合約的地址;所有函數存在邏輯合約(Logic Contract)里,通過 delegatecall 執行。當升級時,只需要將代理合約指向新的邏輯合約即可。
EIP-2535 Diamonds(鑽石):鑽石是一個支持構建可在生產中擴展的模塊化智能合約系統的標準。鑽石是具有多個實施合約的代理合約。更多資訊請查看:鑽石標準簡介。
delegatecall 例子
調用結構:你(A)通過合約 B 調用目標合約 C。
被調用的合約 C
我們先寫一個簡單的目標合約 C:有兩個 public 變量:num 和 sender,分別是 uint256 和 address 類型;有一個函數,可以將 num 設定為傳入的_num,並且將 sender 設為 msg.sender。
發起調用的合約 B
首先,合約 B 必須和目標合約 C 的變量儲存布局必須相同,兩個變量,並且順序為 num 和 sender
接下來,我們分別用 call 和 delegatecall 來調用合約 C 的 setVars 函數,更好的理解它們的區別。
callSetVars 函數通過 call 來調用 setVars。它有兩個參數_addr 和_num,分別對應合約 C 的地址和 setVars 的參數。
而 delegatecallSetVars 函數通過 delegatecall 來調用 setVars。與上面的 callSetVars 函數相同,有兩個參數_addr 和_num,分別對應合約 C 的地址和 setVars 的參數。
運行結果
我們把合約 B 和 C 都部署好,然後調用合約 C 中的 callSetVars,傳入參數為合約 B 地址和 10。運行後,合約 C 中的狀態變量將被修改:num 被改為 10,sender 變為合約 B 的地址。
接下來,我們調用合約 C 中的 delegatecallSetVars,傳入參數為合約 B 地址和 100。由於是 delegatecall,語境為合約 B。在運行後,合約 B 中的狀態變量將被修改:num 被改為 100,sender 變為合約你的錢包地址。
總結
這一講我們介紹了 solidity 中的另一個低級函數 delegatecall。與 call 類似,它可以用來調用其他合約;不同點在於運行的語境,B call C,語境為 C;而 B delegatecall C,語境為 B。目前 delegatecall 最大的應用是代理合約和 EIP-2535 Diamonds(鑽石)。
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與虛擬貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 加入鉅亨買幣LINE官方帳號索取免費課程
- 掌握全球財經資訊點我下載APP
文章標籤
上一篇
下一篇