USDT.transfer self-destruct? 非标准ERC20问题和解决方案

0x00 问题 最近在做智能合约开发,需要转出合约里的 USDT。在以太坊网络里,USDT 是 ERC20 Token, 调用以下函数: 得到如下报错信息: 0x01 原因 为啥转出报错了呢,看看 Etherscan 合约源码1,发现猫腻: 没有返回值!!这不是标准的 ERC20。 标准 ERC20 会返回 bool 值,以区分是否转账成功。智能合约可以根据返回值,对错误做处理,这样的好处是,即使 Token 转移失败,仍然允许交易成功。 而 USDT 转移操作失败时,直接回退交易,没有返回值。 0x02 深入分析 一番搜索后,找到这篇文章2 讲的很详细,有兴趣的看看原文。 原来,ERC20 标准制定的时候就两种方案讨论了很久: 有返回值:返回 bool 是否成功,让合约去做异常处理 没有返回值: 失败时 revert 以确保安全性 现在,这两种都被认为服从 ERC20 标准,但前者更常见,很大一部分原因是 2017/3/17~2017/8/13 这段时间 OpenZeppelin 实现了前者3,之后才改为后者。 由于 Solidity 的函数选择器只由 函数名和入参决定,如: 也就是和函数返回值没关,所以两种实现的 transfer 函数调用都没问题。 第一种实现没有返回值,函数声明有返回 bool […]