当前位置:网站首页>可昇級合約的原理-DelegateCall
可昇級合約的原理-DelegateCall
2022-07-02 11:35:00 【灬倪先森_】
可昇級合約的原理-DelegateCall
在介紹DelegateCall
時,我們需要帶上Call
方法一起介紹,並做對比。
先說概念吧!
DelegateCall:有一種特殊類型的消息調用,被稱為 委托調用(delegatecall)
。它和一般的消息調用(call
)的區別在於,目標地址的代碼將在發起調用的合約的上下文中執行,並且 msg.sender
和 msg.value
不變。 這意味著一個合約可以在運行時從另外一個地址動態加載代碼。
我不喜歡一上來就講概念,畢竟太難理解。還是上代碼演示吧
演示環境
Remix IDE:Remix是基於瀏覽器的 IDE,集成了編譯器和 Solidity 運行時環境,不需要服務端組件,支持網頁在線編寫、部署和測試智能合約。
本章主要是讓大家快速了解DelegateCall的特性,所以選擇基於Remix來演示。
編碼
我們在contracts
目錄下新建delegatecall.sol
文件,並接下來把下面演示代碼粘貼進delegatecall.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract A {
address public msgsender;
function callFunc() public {
msgsender = msg.sender;
}
}
contract B {
address public msgsender;
address public a;
constructor(address _a) {
a = _a;
}
function call_a_call() public{
// isOk 用來接收調用是否成功
(bool isOk,bytes memory result) = a.call(abi.encodeWithSignature("callFunc()"));
// 如果失敗,報异常
require(isOk,"call faild");
}
function delegatecall_a_delegatecall() public{
(bool isOk,bytes memory result) = a.delegatecall(abi.encodeWithSignature("callFunc()"));
require(isOk,"call faild");
}
}
我們在這裏定義兩個合約A
和B
A
合約有一個msgsender
狀態變量和callFunc()
方法
B
合約有兩個狀態變量msgsender
和a
,msgsender
是為了驗證我們的實驗結果,a
是存放合約A
的實例引用,並且定義了兩個方法,分別用來演示用B
合約通過call
和delegatecall
兩種方式調用A
合約的callFunc()
然後我們按Ctrl + s
快捷鍵,這裏會保存合約代碼,編譯器會自動幫我們編譯
合約部署
點擊下面的按鈕跳轉到部署與調試
頁面
先部署合約A
,再部署合約B
,因為B
中的狀態變量a
引用了A
的地址
- 部署合約
A
- 部署合約
B
部署合約B
時需要傳入A
的地址
合約交互
我們先點擊>
按鈕展開我們的合約,並點擊A
合約和B
合約的msgsender
按鈕查詢(點擊按鈕會自動調用msgsender
的查詢方法)當前狀態變量的值,這裏我們可以看到都為0
接下來我們點擊B
合約delegatecall_a_delegatecall
按鈕(調用delegatecall_a_delegatecall
方法),然後再次點擊A
合約和B
合約的msgsender
按鈕查詢
奇怪的事情發生了!!!A
合約的msgsender
沒有值,但是B
合約的msgsender
變成了我自己的地址0x5B38Da6a....
好了,我們可以結合上面的實驗結果,再來理解文章開頭的所說的概念
目標地址A
合約的代碼將在發起調用的B
合約的上下文
中執行,並且 msg.sender
和 msg.value
不變。上下文
就是運行環境,就包括了合約裏的狀態變量
,所以當合約執行callFunc()
的內容時,callFunc()
方法是在B
合約裏執行的,修改的是B
合約的狀態變量,而A
合約的msgsender
卻沒有變化。
如果B
合約的兩個狀態變量msgsender
和a
在代碼中互換比特置,就是另一個故事了,這裏涉及到另一個概念《合約數據存儲布局》
接下來我們點擊B
合約call_a_call
按鈕,然後再次點擊A
合約和B
合約的msgsender
按鈕查詢
現在A
合約的msgsender
有值了,B
合約的msgsender
值沒有變化。
當調用B
合約call_a_call
方法時,B
合約的狀態變量沒有發生變化,A
合約的msgsender
有值了,這說明callFunc()
方法是在A
合約的上下文
環境中執行的,這裏上下文
發生了變化。
並且我們發現A
合約的msgsender
變成了B
合約的地址,這說明在調用的過程中msg.sender
和 msg.value
發生了變化,msg.sender
不再是我自己0x5B38Da6a....
而是B
合約的地址
總結
會顧我們前面寫的可昇級合約,當對代理合約
發起調用時,代理合約
與邏輯合約
交互就是用的委托調用(DelegateCall)
。邏輯合約
的方法在代理合約
的上下文執行,並且修改的狀態變量
也是代理合約
的。所以合約數據一直都在代理合約
裏,當邏輯合約
昇級時並不會影響合約原來已有的數據
有問題,或者建議請留言,謝謝。
边栏推荐
- The difference between SQL left join main table restrictions written after on and where
- TIPC 寻址2
- Functional interfaces and method references
- Solve the problem of data blank in the quick sliding page of the uniapp list
- Introduction to interface debugging tools
- Verilog and VHDL signed and unsigned number correlation operations
- 通过券商经理的开户二维码开股票账户安全吗?还是去证券公司开户安全?
- 三.芯片啟動和時鐘系統
- Skills of PLC recorder in quickly monitoring multiple PLC bits
- What are the software product management systems? Inventory of 12 best product management tools
猜你喜欢
Always report errors when connecting to MySQL database
数字化转型挂帅复产复工,线上线下全融合重建商业逻辑
How does the whole network display IP ownership?
PHP tea sales and shopping online store
2022 love analysis · panoramic report of digital manufacturers of state-owned enterprises
tidb-dm报警DM_sync_process_exists_with_error排查
Webauthn - official development document
解决uniapp列表快速滑动页面数据空白问题
Openmldb meetup No.4 meeting minutes
enumrate的start属性的坑
随机推荐
2022年4月17日五心红娘团队收获双份喜报
TIPC协议
Jenkins installation
enumrate的start属性的坑
STM32 single chip microcomputer programming learning
念念不忘,必有回响 | 悬镜诚邀您参与OpenSCA用户有奖调研
CTF record
Resources reads 2D texture and converts it to PNG format
高德根据轨迹画线
Array splitting (regular thinking
接口调试工具概论
MySQL linked list data storage query sorting problem
Some things configured from ros1 to ros2
[play with FPGA learning 4 in simple terms ----- talk about state machine design]
Always report errors when connecting to MySQL database
From the perspective of attack surface, see the practice of zero trust scheme of Xinchuang
C#多维数组的属性获取方法及操作注意
由粒子加速器产生的反中子形成的白洞
八大排序汇总
Native method merge word