下面这段就是导致SMT被黑客攻击导致价值归零、以及各大交易所纷纷停止提币的核心代码
/*
* Proxy transfer SmartMesh token. When some users of the ethereum account has no ether,
* he or she can authorize the agent for broadcast transactions, and agents may charge agency fees
* @param _from
* @param _to
* @param _value
* @param feeSmt
* @param _v
* @param _r
* @param _s
*/
function transferProxy(address _from, address _to, uint256 _value, uint256 _feeSmt,
uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){
if(balances[_from] < _feeSmt + _value) revert();
uint256 nonce = nonces[_from];
bytes32 h = keccak256(_from,_to,_value,_feeSmt,nonce);
if(_from != ecrecover(h,_v,_r,_s)) revert();
if(balances[_to] + _value < balances[_to]
|| balances[msg.sender] + _feeSmt < balances[msg.sender]) revert();
balances[_to] += _value;
Transfer(_from, _to, _value);
balances[msg.sender] += _feeSmt;
Transfer(_from, msg.sender, _feeSmt);
balances[_from] -= _value + _feeSmt;
nonces[_from] = nonce + 1;
return true;
}
这是黑客利用漏洞完成SMT无限增发的合约调用
https://etherscan.io/tx/0x1abab4c8db9a30e703114528e31dee129a3a758f7f8abc3b6494aad3d304e43f
方法涉及的角色:
角色1 需要转SMT、但地址里面没有ETH的人 - 合约中的_from
角色2 帮助角色1来转SMT,并支付ETH的gas费用 - 合约中的msg.sender,也是调用这个合约的人
角色3 SMT接收方
方法的目的:
角色1想要转SMT给角色3,但自己又没有ETH来支付手续费,于是角色1找到有ETH的角色2说:我给你一些SMT当做手续费,你来通过调用transferProxy来把我的SMT转给角色3,因为你有ETH
方法的漏洞:
漏洞利用前几天导致BEC归零类似的uint256溢出,绕过了if的判断,所以解决这类问题还是需要使用SafeMath来做加减乘除。
EOS体系的解决方案:
1 关于转账手续费
虽然EOS主网还没有上,但根据EOS白皮书的说法,EOS体系转账是需要手续费的,但EOS允许收款人支付。这样角色1可以把中间人角色2排除,直接与角色3交易。
2 关于智能合约漏洞
当“势不可挡的应用程序”以不可预知的方式发挥作用时,使用EOS.IO软件的区块链允许区块生产者(超级节点)替换账户的代码,而不分叉整个区块链。这类似冻结账户的过程,这个代码的替换需要选出的15/21的区块生产者投票。
3 权限管理
proxyTransfer方法里的角色B获得角色授权进行资金操作的情况,在EOS中可以通过权限映射+多签名阈值来实现,虽然没有ETH上这么灵活,但从编程友好和安全的角度是有优势的。
以太坊的智能合约的灵活性是很高的,但也对智能合约开发者提出了很高的要求,而EOS有针对性对这些做了自己的结构设计。
网友评论