msg.sender和tx.origin的异同 / 学习智能合约#15

msg.sender和tx.origin的异同 / 学习智能合约#15

智能合约

如果你的智能合约逻辑简单,那么调用合约者就应该只用msg.sender,它表示调用者的身份。此时,你用tx.origin和用msg.sender是一样的,都是表示你在调用!但在很多技术文章中是不鼓励使用tx.origin,它可能会产生合约漏洞!

但是,如果你的智能合约逻辑稍显复杂,有几个功能部分,那么,相互之间的调用就比较麻烦了。今天也是在这块卡了好久,最后还是使用了tx.origin来解决了这个问题。

1
2
3
4
5
6
7
8
9
10
11
function transfer(address _to, uint256 _value) public override returns (bool success) {
require(_to != address(0));
require(balanceOf[msg.sender] >= _value);
require(balanceOf[ _to] + _value >= balanceOf[ _to]);

balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;

emit Transfer(msg.sender, _to, _value);
return true;
}

上面是典型的代币合约的转帐方法。如果是另一个合约要调用代币合约中的转帐是不会成功的!问题就出在msg.sender上。另一个合约要调用代币合约的转帐时msg.sender是指的合约地址,而不是当前的调用者!所以,一直会出现授权错误的提示。

改进下方法看看:

1
2
3
4
5
6
7
8
9
10
11
function transferFromOrigin(address _to, uint256 _value) public override returns (bool success) {
require(_to != address(0));
require(balanceOf[tx.origin] >= _value);
require(balanceOf[ _to] + _value >= balanceOf[ _to]);

balanceOf[tx.origin] -= _value;
balanceOf[_to] += _value;

emit Transfer(tx.origin, _to, _value);
return true;
}

就是将msg.sender替换成tx.origin,这样,就可以在另外的合约中调用代币合约中的转帐方法。但是技术高手们又认为这会出现漏洞攻击!我研究了半天,没太看明白,但是却是解决了我现在的问题,先用着吧。


This page is synchronized from the post: ‘msg.sender和tx.origin的异同 / 学习智能合约#15’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×