6

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

 3 years ago
source link: https://learnblockchain.cn/article/1585
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

来来来看照:

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:小米

219abf7d2b3b33a34303e9ed55506101.png

合约1:T4

9b4f120d4770a20be3defd76828da6b9.png

合约2:T3

6c046cb4a66ef69a6de198b31f91bfec.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),如下图所示:

72c75b1bfb56b3c7a1bc48878cb107c9.png

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

84fcd00470e17894afed6216c6f18ab1.png

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

6818cf66b3616a5e03e317998b888505.png

得到是T4的合约的地址

f59e43675373232b7a2ad37be8ba803c.png

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

来来来看照:

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:小米

219abf7d2b3b33a34303e9ed55506101.png

合约1:T4

9b4f120d4770a20be3defd76828da6b9.png

合约2:T3

6c046cb4a66ef69a6de198b31f91bfec.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),如下图所示:

72c75b1bfb56b3c7a1bc48878cb107c9.png

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

84fcd00470e17894afed6216c6f18ab1.png

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

6818cf66b3616a5e03e317998b888505.png

得到是T4的合约的地址

f59e43675373232b7a2ad37be8ba803c.png

[]()[]()总结:

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

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 16小时前
  • 阅读 ( 7 )
  • 学分 ( 0 )
  • 分类:Solidity

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK