当前位置:网站首页>可升级合约的原理-DelegateCall
可升级合约的原理-DelegateCall
2022-07-02 09:38: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)。逻辑合约的方法在代理合约的上下文执行,并且修改的状态变量也是代理合约的。所以合约数据一直都在代理合约里,当逻辑合约升级时并不会影响合约原来已有的数据
有问题,或者建议请留言,谢谢。
边栏推荐
- tidb-dm报警DM_sync_process_exists_with_error排查
- TIPC introduction 1
- flink二開,實現了個 batch lookup join(附源碼)
- Wechat applet uses Baidu API to achieve plant recognition
- [in simple terms, play with FPGA learning 3 ----- basic grammar]
- [idea] use the plug-in to reverse generate code with one click
- Tick Data and Resampling
- SSRF
- PHP tea sales and shopping online store
- Skills of PLC recorder in quickly monitoring multiple PLC bits
猜你喜欢

Tick Data and Resampling

Wechat applet uses Baidu API to achieve plant recognition
![[in simple terms, play with FPGA learning 3 ----- basic grammar]](/img/f0/0204fa5197033877dc0758203253ae.png)
[in simple terms, play with FPGA learning 3 ----- basic grammar]

V2x SIM dataset (Shanghai Jiaotong University & New York University)

TIPC 寻址2

2022 love analysis · panoramic report of digital manufacturers of state-owned enterprises
![[cloud native] 2.5 kubernetes core practice (Part 2)](/img/87/826894d758392a0c7a60dd5fa09eef.png)
[cloud native] 2.5 kubernetes core practice (Part 2)

PLC-Recorder快速监控多个PLC位的技巧

Iii. Système de démarrage et d'horloge à puce

TIPC messaging3
随机推荐
ROS lacks catkin_ pkg
liftOver进行基因组坐标转换
Flick two open, realized a batch lookup join (with source code)
tqdm的多行显示与单行显示
[quick application] there are many words in the text component. How to solve the problem that the div style next to it will be stretched
Implementation of six singleton modes
The difference between SQL left join main table restrictions written after on and where
TDSQL|就业难?腾讯云数据库微认证来帮你
[AGC] how to solve the problem that the local display of event analysis data is inconsistent with that in AGC panel?
MySQL linked list data storage query sorting problem
Flink two Open, implement Batch Lookup join (attached source)
SSRF
MySQL比较运算符IN问题求解
sql left join 主表限制条件写在on后面和写在where后面的区别
TIPC Cluster5
Digital transformation takes the lead to resume production and work, and online and offline full integration rebuilds business logic
2022年4月17日五心红娘团队收获双份喜报
Iii. Système de démarrage et d'horloge à puce
程序员成长第六篇:如何选择公司?
C# 文件与文件夹操作