Solidity
ERC-20 transferFrom 實現的潛在缺陷……或者不是?
假設
transferFrom
函式以以下方式實現:function transferFrom (address _from, address _to, uint256 _value) public returns (bool success) { uint256 spenderAllowance = allowances [_from][msg.sender]; if (spenderAllowance < _value) return false; uint256 fromBalance = accounts [_from]; if (fromBalance < _value) return false; allowances [_from][msg.sender] = safeSub (spenderAllowance, _value); if (_value > 0 && _from != _to) { accounts [_from] = safeSub (fromBalance, _value); accounts [_to] = safeAdd (accounts [_to], _value); } Transfer (_from, _to, _value); return true; }
正如我所看到的,如果
_to
不同於msg.sender
將_to
獲得將從msg.sender
允許數量中刪除的所有令牌。實際上,這不應該是缺陷,因為沒有人會瘋狂到將他的允許金額發送給其他人,但它可以以不好的方式使用嗎?您對此有何看法?
transferFrom 流以某種方式定義為:
// Send `tokens` amount of tokens from address `from` to address `to` // The transferFrom method is used for a withdraw workflow, allowing contracts to send // tokens on your behalf, for example to "deposit" to a contract address and/or to charge // fees in sub-currencies; the command should fail unless the _from account has // deliberately authorized the sender of the message via some mechanism; we propose // these standardized APIs for approval: function transferFrom(address _from, address _to, uint tokens) public returns (bool success) { balances[_from] = balances[_from].sub(tokens); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(tokens); balances[_to] = balances[_to].add(tokens); Transfer(_from, _to, tokens); return true; }
如您所見,目的是允許任何先前批准的msg.sender (當然是**_from)將令牌從*_from*帳戶轉移到他想要的任何 _to帳戶。
Msg.sender將支付交易的津貼和gas。
所以沒有任何技巧的空間:msg.sender支付 gas 和津貼,_from花費一些批准的代幣,_to接收msg.sender 發送的代幣。
在我們無法擁有這種功能的情況下,msg.sender必須先將代幣轉移到他自己的賬戶(區塊鏈 n.1 上的交易),然後再將它們發送到*_to賬戶(區塊鏈 n.2 上的交易) . 所以msg.sender*支付了他的津貼和兩倍的氣體用於交易。
這可以通過 transferFrom 機制來避免,該機制只能使用區塊鏈交易來做到這一點,並且msg.sender執行起來更便宜。