如今以太坊上已经部署了超过 7万个ERC20 Token智能合约,基于 ERC20 合约的 DAPP 正在迅速发展,包括去中心化交易所、资产托管、钱包等应用。但是 安比(SECBIT)实验室 不断发现有大量 ERC20 Token 合约没有遵守 EIP20 规范,这些非标准合约将会对 DAPP 的生态造成严重影响。特别是自从今年4月17日,以太坊的智能合约语言编译器 Solidity 升级至 0.4.22 版本后,编译产生的合约代码将会无法兼容一些非标准的智能合约,这会对 DAPP 的开发带来很大的困扰。这个问题首当其冲地影响去中心化交易所(DEX),一些非标准 Token
可能无法正常完成交易/转账,另外一些针对 ERC20 Token 的 DAPP 也会受到影响。根据 安比(SECBIT)实验室不完全统计,存在这种不兼容问题的 ERC20 合约至少 2603份。但时至今日,这个问题并没有引起各方足够的重视。
5月10日,以太坊 Solidity 社区收到以下一个Issue(Enforcing ABI length checks for return data from calls can be breaking)提到了编译器升级后对非标准 Token 合约的影响。
问题解决方案直达:https://github.com/sec-bit/badERC20Fix/
问题描述
根据 Issue 中的描述信息可知,该问题是由ERC20 Token合约中 transfer() 函数未严格按照EIP20规范的实现所引起的。在以太坊官方的 EIP20 Token合约规范文档中,对各个接口和 Event 的实现都明确的做了规定。
每个函数都应包含返回值,其中transfer()函数应返回一个bool值。但是大量实际部署的Token合约,并没有严格按照 EIP20 规范来实现,如下列一段知名Token合约(市值63Billion USD)的代码所示,transfer函数没有返回值。
Token合约中,没有返回值的transfer()函数,并不符合EIP20合约规范。对于普通账户直接调用transfer()函数进行转账的场景不会有任何影响。但若外部合约按照EIP20规范的ABI解析去调用transfer()函数,在solidity编译器升级至0.4.22版本以前,合约调用也不会出现异常。但当合约升级至0.4.22后,transfer函数调用将发生revert。