谈谈fisco bcos智能合约中tx.origin和msg.sender的作用及使用场景

tx.origin (address):交易发送方(完整调用链上的原始发送方)由于是直接调用者,所以当处于 用户A->合约1->合约2 调用链下,若在合约2内使用msg.sender,得到的会是合约1的地址。如果想获取用户A,可以用tx.origin:交易的”始作俑者”,整个调用链的起点。

# 来来来看照: ![_20200929112734.jpg](https://img.learnblockchain.cn/attachments/2020/10/ugawfO4M5f880c0b1daa5.jpg) 有认识的吗? # 官方解释: msg.sender (address):消息发送方(当前调用) tx.origin (address):交易发送方(完整调用链上的原始发送方)由于是直接调用者,所以当处于 用户A->合约1->合约2 调用链下,若在合约2内使用msg.sender,得到的会是合约1的地址。如果想获取用户A,可以用tx.origin:交易的”始作俑者”,整个调用链的起点。 # []()[]()实践: 在下面的2个合约中,T4中去调用T3中的函数,当处于 用户A->合约1->合约2 调用链下,若在合约2内使用msg.sender,得到的会是合约1的地址。如果想获取用户A,可以用tx.origin:交易的”始作俑者”,整个调用链的起点。 把官方的解释带入实际的案例如下: 用户A:小米 ![0](https://img.learnblockchain.cn/2020/10/16_/638939244.png) 合约1:T4 ![0](https://img.learnblockchain.cn/2020/10/16_/954900221.png) 合约2:T3 ![0](https://img.learnblockchain.cn/2020/10/16_/5967041.png) ## []()[]()T3合约代码如下: pragma solidity >=0.4.0 contract T3 { // 为了演示去掉view,方便传入用户的address function select() public returns(address){ return tx.origin; } // 为了演示去掉view方便传入用户的address function select2() public returns(address){ return msg.sender; } } ## []()[]()T4合约代码如下: pragma solidity >=0.4.0 import "./T3.sol"; contract T4 { // 为了演示去掉view,方便传入用户的address function select() public returns(address){ T3 t3=new T3(); return t3.select(); } // 为了演示去掉view,方便传入用户的address function select2() public returns(address){ T3 t3=new T3(); return t3.select2(); } } # []()[]()测试结果: 先调用T4的select函数(tx.origin),如下图所示: ![0](https://img.learnblockchain.cn/2020/10/16_/340170477.png) 得到的是小米用户的公钥地址信息 ![0](https://img.learnblockchain.cn/2020/10/16_/5524321.png) 先调用T4的select2函数(msg.sender),如下图所示: ![0](https://img.learnblockchain.cn/2020/10/16_/192823220.png) 得到是T4的合约的地址 ![0](https://img.learnblockchain.cn/2020/10/16_/783081704.png) # []()[]()总结: 所以在有用户A->合约1->合约2 这种类似的调用链场景下做权限判断的时候一定要注意合理的选择使用tx.origin还是msg.sender。以防对合约的业务的逻辑造成影响。

来来来看照:

有认识的吗?

官方解释:

msg.sender (address):消息发送方(当前调用)

tx.origin (address):交易发送方(完整调用链上的原始发送方)由于是直接调用者,所以当处于 用户A->合约1->合约2 调用链下,若在合约2内使用msg.sender,得到的会是合约1的地址。如果想获取用户A,可以用tx.origin:交易的”始作俑者”,整个调用链的起点。

[]()[]()实践:

在下面的2个合约中,T4中去调用T3中的函数,当处于 用户A->合约1->合约2 调用链下,若在合约2内使用msg.sender,得到的会是合约1的地址。如果想获取用户A,可以用tx.origin:交易的”始作俑者”,整个调用链的起点。

把官方的解释带入实际的案例如下:

用户A:小米

合约1:T4

合约2:T3

[]()[]()T3合约代码如下:

pragma solidity >=0.4.0

contract T3 {

// 为了演示去掉view,方便传入用户的address

function select() public returns(address){

return tx.origin;

}

// 为了演示去掉view方便传入用户的address

function select2() public returns(address){

return msg.sender;

}

}

[]()[]()T4合约代码如下:

pragma solidity >=0.4.0

import "./T3.sol";

contract T4 {

// 为了演示去掉view,方便传入用户的address

function select() public returns(address){

T3 t3=new T3();

return t3.select();

}

// 为了演示去掉view,方便传入用户的address

function select2() public returns(address){

T3 t3=new T3();

return t3.select2();

}

}

[]()[]()测试结果:

先调用T4的select函数(tx.origin),如下图所示:

得到的是小米用户的公钥地址信息

先调用T4的select2函数(msg.sender),如下图所示:

得到是T4的合约的地址

[]()[]()总结:

所以在有用户A->合约1->合约2 这种类似的调用链场景下做权限判断的时候一定要注意合理的选择使用tx.origin还是msg.sender。以防对合约的业务的逻辑造成影响。

  • 发表于 2020-10-15 16:48
  • 阅读 ( 3997 )
  • 学分 ( 253 )
  • 分类:Solidity

评论