solidity tx.origin和msg.sender那些事儿

这篇具有很好参考价值的文章主要介绍了solidity tx.origin和msg.sender那些事儿。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

        tx.origin与msg.sender是solidity中容易令人迷惑的两个变量,尤其是当我们直接调用合约时两者的值是相同的。为了更清晰的说明两者的关系我们需要构造合约间的链式调用,如下:

EOA -> Contract A -> Contract B -> Contract C

这里先说明结论:tx.origin始终保持是EOA,msg.sender是其直接调用者的地址。如:合约B中msg.sender的值为合约A的地址,合约C中msg.sender的值为合约B的地址。

        简单来说,前者是原始的交易发起者的外部地址(EOA),后者是方法的直接调用者(可以是EOA也可以是合约地址)。以下我们通过简单的合约示例来观察两者值的变化。

抽丝剥茧

下面通过合约直接调用、合约间调用和合约间链式调用的形式由浅入深逐步揭开tx.origin和msg.sender的神秘面纱。

直接调用

此处我们直接通过外部账户(EOA)来调用合约。

代码

contract AA {
    constructor() {
        console.log("Contract AA's address:", address(this));
    }

    fallback() external {
        console.log(
            "In AA fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }
}

上面代码中在构造函数中输出了合约地址,在fallback函数中输出了msg.sender和tx.origin的值。

执行

操作过程如下:

1. 部署合约;

2. 执行合约的fallback方法;

solidity tx.origin和msg.sender那些事儿,区块链,区块链,智能合约,开发语言,javascript,去中心化

由上面的执行结果(箭头1)我们可以看出,当直接调用合约时msg.sender和tx.origin的值是相同的。

注:我们构造了一个calldata参数来调用函数方法,该参数前4个字节标示要调用的方法。其计算方法是先对方法签名计算hash值(keccak256),然后截取hash的前四个字节(8个16进制字符),最后补0至32个字节。此处我们调用合约中的fallback方法,因此随机8个16进制数即可。

合约间调用

此处我们通过合约间调用来观察两者的值。

代码


contract AA {
    constructor() {
        console.log("Contract AA's address:", address(this));
    }

    fallback() external {
        console.log(
            "In AA fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }
    
    function remoteCall(address _instance) external {
        console.log(
            "In BB fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
        (bool sucess, ) = _instance.call(
            abi.encodeWithSignature("nonExistingFunction()")
        );
        require(sucess, "call error");
    }
}

contract BB {
    constructor() {
        console.log("Contract BB's address:", address(this));
    }

    fallback() external {
        console.log(
            "In BB fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }
}

以上代码合约AA中的remoteCall方法接受一个合约地址(在执行过程中我们输入合约BB的地址),用于调用其它合约的方法,此处我们调用的是合约中不存在的一个方法,因此目标合约的fallback方法会被触发。

执行

操作过程如下:

1. 部署合约AA;

2. 部署合约BB;

3. 以合约BB的地址为参数来调用合约AA的remoteCall方法;

solidity tx.origin和msg.sender那些事儿,区块链,区块链,智能合约,开发语言,javascript,去中心化

由上面执行结果我们可能看出,当合约AA调用合约BB中的方法时,合约B中的msg.sender为合约AA的地址。

合约间链式调用

代码

此处我们实现文章最开始描述的链式调用,即:

EOA -> Contract A -> Contract B -> Contract C


contract AA {
    constructor() {
        console.log("Contract AA's address:", address(this));
    }

    fallback() external {
        console.log(
            "In AA fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }
    

    function remoteCall(address _instance, address _instance2) external {
        console.log(
            "In AA fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );

        (bool sucess, ) = _instance.call(
            abi.encodeWithSignature("remoteCall(address)", _instance2)
        );
        require(sucess, "call error");
    }
}

contract BB {
    constructor() {
        console.log("Contract BB's address:", address(this));
    }

    fallback() external {
        console.log(
            "In BB fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }

    function remoteCall(address _instance) external {
        console.log(
            "In BB fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
        (bool sucess, ) = _instance.call(
            abi.encodeWithSignature("nonExistingFunction()")
        );
        require(sucess, "call error");
    }
}

contract CC {
    constructor() {
        console.log("Contract CC's address:", address(this));
    }

    fallback() external {
        console.log(
            "In CC fallback msg.sender:[%s] tx.origin:[%s] ",
            msg.sender,
            tx.origin
        );
    }
}

 上述代码中合约AA通过remoteCall方法接收两个地址,分别是合约BB、CC的地址,其中调用过程为:合约AA的remoteCall -> 合约BB的remoteCall -> 合约CC的fallback

执行

操作过程如下:

1. 部署合约AA;

2. 部署合约BB;

3. 部署合约CC;

4. 调用合约AA的remoteCall方法,其参数分别为合约BB地址、合约CC地址;

solidity tx.origin和msg.sender那些事儿,区块链,区块链,智能合约,开发语言,javascript,去中心化

由上图的执行过程,我们可以验证文章开头处的结论:tx.origin始终保持不变,其值是交易发起者的外部地址(EOA),msg.sender是其直接调用者的地址。文章来源地址https://www.toymoban.com/news/detail-777861.html

到了这里,关于solidity tx.origin和msg.sender那些事儿的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • solidity call和delegatecall的那些事儿

    call 是solidity中合约之间交互的一个底层调用,但官方建议该方法仅在发送以太坊时使用,合约接受转账必须定义receive或payable fallback(当调用合约中不存在的方法时,该方法被默认调用),而不建议用call来调用合约中存在的方法。关于receive和fallback的区别见下面示例合约Ca

    2024年02月03日
    浏览(28)
  • 边缘计算那些事儿—边缘智能技术

            边缘智能是边缘计算中一个非常重要的方向。它将边缘计算和人工智能算法结合起来,在边缘设备上就近处理目标检测、物体跟踪,识别等任务。这种处理方式可以降低时延,减少数据上送云端对回传网络的冲击,同时保证数据的隐私和安全性。但是,我们要面对一

    2023年04月22日
    浏览(35)
  • tx H5_1.0.19算法 tx算法 encrypt_msg 腾讯encrypt_msg算法mobile_save接口中的msg值算法。

    tx充值QB页面的mobile_save接口中的encrypt_msg值算法。 本帖学习研究探讨 目标网站地址 http://pay.qq.com/h5/ 版本 base_key_version=H5_1.0.21 encrypt_way=web_new_encrypt 目的是拿到最终的支付链接。 https://api.unipay.qq.com/v1/r/1450000490/mobile_save 可以看到 不管是QQ支付还是微信支付,最终的支付链接是

    2024年02月08日
    浏览(103)
  • 区块链2——Solidity智能合约开发

    区块链 索引目录 智能合约是一种以代码形式编写的自动执行合约,它们运行在区块链上。这些合约定义了在特定条件下发生的事件以及相应的行为。 1.1 智能合约结构 版本声明(Version Declaration): 智能合约通常以声明版本开始,指定合约应该使用的Solidity编译器版本。例如

    2024年02月05日
    浏览(54)
  • 区块链智能合约编程语言 Solidity

    上文介绍了区块链生态发展,我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。 Solidity 是以太坊开发人员使用的编程语言,用来编写智能合约,运行在以太坊虚拟机(EVM)上。 有开发经

    2024年02月12日
    浏览(45)
  • solidity开发 msg.value

    刚学完solidity的基础开发,想写一个众筹项目,在使用msg.value的时候,发现只要函数中使用到msg.value,就会自动转走账户的钱到该合约账户里。这让我非常疑惑,那怎么转出来呢?我写了一个demo来测试。 测试结果是:当我调用transfer()时,会扣除sender的eth,转到当前合约账户

    2024年02月11日
    浏览(35)
  • 【区块链实战】Solidity 智能合约如何给账户充值

    目录 一、实战场景 二、知识点 智能合约 智能合约函数 智能合约充值 payable 智能合约部署地址 智能合约的运行 合约 this 对象 三、菜鸟实战 四、运行结果 Solidity 智能合约如何给账户充值 1、充值金额 2、充值并查看结果

    2024年02月09日
    浏览(39)
  • 【区块链-智能合约工程师】第二篇:Solidity入门

    参考文章:一文速览2022十大智能合约开发工具 资料地址:WTF学院 HelloWorld remix:在线智能合约开发IDE(Integrated Development Environment,集成开发环境),可以在浏览器中快速部署测试智能合约。 合约HelloWorld: 事项 说明 代码所用的软件许可(license) 不写许可的话编译时会警告

    2024年02月09日
    浏览(44)
  • 区块链智能合约solidity的中的一些关键字

    目  录 pragma mapping msg对象 block对象 contract constructor struct 数据地址 地址类型 address payable revert 以下场景使用 revert() : require 以下场景使用 require() : assert 以下场景使用 assert(): 访问权限 internal public private external function returns return view pure constant event emit modifier pragma   

    2024年01月16日
    浏览(66)
  • 【区块链-智能合约工程师】第三篇:Solidity进阶(一)

    学习资料地址:WTF学院 库合约一般都是一些好用的函数合集(库函数),为了提升solidity代码的复用性和减少gas而存在。他和普通合约主要有以下几点不同: 不能存在状态变量 不能够继承或被继承 不能接收以太币 不可以被销毁 String库 String库合约是将uint256(大正整数)类型

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包