官方解釋:
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,以防對合約的業務的邏輯造成影響,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/172822.html
標籤:其他
下一篇:關于GO語言,這篇文章講的很明白
