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

in STEEM CN/中文6 years ago

智能合约

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

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

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是指的合约地址,而不是当前的调用者!所以,一直会出现授权错误的提示。

改进下方法看看:

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,这样,就可以在另外的合约中调用代币合约中的转帐方法。但是技术高手们又认为这会出现漏洞攻击!我研究了半天,没太看明白,但是却是解决了我现在的问题,先用着吧。

Coin Marketplace

STEEM 0.05
TRX 0.32
JST 0.078
BTC 66831.29
ETH 1826.86
USDT 1.00
SBD 0.42