以太坊合约调用call、callcode和delegatecall的联系与区别

目录

1、调用者EthAlice

2、被调用者EthBob

3、部署合约

3.1 测试call()调用方式

3.2 测试callcode()调用方式

3.3 测试delegatecall()调用方式


在以太坊中,若需要合约与合约之间的调用,则可以使用call、callcode和delegatecall方法,它们之间的联系如下:

图1:三种调用方式 

 这里以合约EthAlice调用合约EthBob为例,进行说明,其执行流程如下:

 图2:合约间的调用流程(Alice调用Bob)

1、调用者EthAlice

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

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:(Bob)0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:32

图3:call()调用方式

 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:(Bob)0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:34

 图4:callcode()调用方式

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:(Bob)0xe981880Ac36360A1bF4F8F2a369877dbE29Aa8d4
value:36

图5:delegatecode()调用方式

    Alice通过delegatecall()方式,修改的是自身num:34–>36,
它不会修改Bob的num:32–>32;
    即delegatecall()方式,修改的是调用者自身的storage。
    Alice的msg.sender = 交易的发起者地址
    Bob的msg.sender = 调用者地址(Alice合约地址)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值