? ? 在以太坊中,若需要合約與合約之間的呼叫,則可以使用call、callcode和delegatecall方法,它們之間的聯系如下:
| 呼叫方式 | 修改storage | 呼叫者的msg.sender | 被呼叫的msg.sender | 執行的背景關系 | 推薦 |
|---|---|---|---|---|---|
| call | 修改被呼叫者的合約storage | 交易的發起者地址 | 呼叫者地址 | 在被呼叫者里 | 是 |
| callcode | 修改呼叫者的合約storage | 呼叫者地址 | 呼叫者地址 | 在呼叫者里 | 否 |
| delegatecall | 修改呼叫者的合約storage | 交易的發起者地址 | 呼叫者地址 | 在呼叫者里 | 是 |
? ? 這里以合約EthAlice呼叫合約EthBob為例,進行說明,其執行流程如下:
1、呼叫者EthAlice
? ? //ehtAlice.sol
pragma solidity ^0.4.18;
contract EthAlice {
uint public num;
address public addr;
function callSetNum(address ads, uint value) public returns(uint) {
require(ads.call(bytes4(keccak256("SetNum(uint256)")), value));
return value;
}
function callcodeSetNum(address ads, uint value) public returns(uint) {
require(ads.callcode(bytes4(keccak256("SetNum(uint256)")), value));
return value;
}
function delegatecallSetNum(address ads, uint value) public returns(uint) {
require(ads.delegatecall(bytes4(keccak256("SetNum(uint256)")), value));
return value;
}
}
2、被呼叫者EthBob
? ? //ethBob.sol
pragma solidity ^0.4.18;
contract EthBob {
uint public num;
address public addr;
event sendAddr(address);
function SetNum(uint _num) public {
num = _num;
addr = msg.sender;
emit sendAddr(msg.sender);
}
}
3、部署合約
? ? 在MetaMask里選擇一個Rinkeby測驗網賬戶,比如0x6026DfB9816D22F65F1011639B207B1c3A2C2e84
,然后在Remix上部署EthAlice和EthBob合約,得到如下:
? ? EthAlice合約地址:0xeb0282Dcd268afCFeAFA84ea2260edC2c7747381
? ? EthBob合約地址:0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
3.1 測驗call()呼叫方式
? ? 在Remix里的部署頁面里,點開ETHALICE --> callSetNum 輸入如下2個引數:
ads:0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:32
? ? 如圖(2) 所示:
? ? Alice通過call()方式,修改的是Bob的num:0–>32,
而不是自身的num:0–>0;
? ? 即call()方式,修改的是被呼叫者的storage,
? ? Alice的msg.sender = 交易的發起者地址
? ? Bob的msg.sender = 呼叫者地址(Alice合約地址)
3.2 測驗callcode()呼叫方式
? ? 在Remix里的部署頁面里,點開ETHALICE --> callcodeSetNum 輸入如下2個引數:
ads:0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:34
? ? 如圖(3) 所示:
? ? Alice通過callcode()方式,修改的是自身num:32–>34,
它不會修改Bob的num:32–>32;
? ? 即callcode()方式,修改的是呼叫者自身的storage,
? ? Alice的msg.sender = 呼叫者地址(Alice合約地址)
? ? Bob的msg.sender = 呼叫者地址(Alice合約地址)
3.3 測驗delegatecall()呼叫方式
? ? 在Remix里的部署頁面里,點開ETHALICE --> delegatecallSetNum 輸入如下2個引數:
ads:0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:36
? ? 如圖(4) 所示:
? ? Alice通過delegatecall()方式,修改的是自身num:34–>36,
它不會修改Bob的num:32–>32;
? ? 即delegatecall()方式,修改的是呼叫者自身的storage,
? ? Alice的msg.sender = 交易的發起者地址
? ? Bob的msg.sender = 呼叫者地址(Alice合約地址)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/265977.html
標籤:區塊鏈
上一篇:最新礦池排行,礦池算力,礦池挖礦,礦池推薦,魚池,星火礦池,蜜蜂礦池
下一篇:區塊鏈學習資料大全
