今天在技术群里跟大家做技术交流,发现还是有很多人还是对以太坊的智能合约调用关系不是很清楚。所以我打算专门写一篇博文来说一下这个问题。
直接上代码:
contract Wallet{
ERC20Token public token;
constructor(address _token) public{
token = ERC20Token(_token);
}
event Event_TransferToken(address _addr,uint256 _value);
function TransferToken(address _addr,uint256 _value) external
{
token.transfer(_addr ,_value);
emit Event_TransferToken(_addr ,_value);
}
}
如代码上所示,这个合约内有一个Token对象,合约初始化的时候传入一个ERC20 Token的地址来实例化这个token对象,还有一个TransferToken方法,传入你要转出的的token数量和地址,然后TransferToken方法会调用token.transfer方法转出token。
很多人认为当我们自己去调用Wallet合约的TransferToken方法,这个时候msg.sender是我们自己,所以当执行token.transfer语句的时候很多人也会觉得相对于token对象而言msg.sender还是我们自己,这个时候转出的token是我们自己账户上的token。
但是这个想法大错特错。
调用TransferToken方法的时候,msg.sender却是是我们自己,但是在这个方法体内又执行了token.transfer,但是这个语句并不是我们自己去调用的,而是这个Wallet合约调用的,我们只是跟Wallet合约交互,跟token合约交互的是Wallet,所以在执行token.transfer语句的时候,token合约接收到的msg.sender是Wallet,所以转出的token是从Wallet的账户地址转出来的。