There is no way in solidity to check if an address is a contract. One of the goals of Ethereum is for humans and smart contracts to both be treated equally.
https://stackoverflow.com/a/37670490/7218912, z. C& p3 Z5 I6 w: a, Q9 d3 p
有时候确实有需要向智能合约转账:1 f8 s6 ~( X6 j$ v& A0 l1 T. j& ^1 B
但是大多数 smart contract 的 token 是不能转出的,只要合约里没写转出的逻辑,就不能转出。以太坊将智能合约看做是独立的个体,没人知道它的私钥,给不支持转出的智能合约转 token 就等于销毁了。
当我们要转账时,会转到交易方的地址,不会闲着没事给智能合约转 token。但是这种事情仍然会发生,不断有人给 EOSTokenContract 转 EOS(见下图),EOSTokenContract 账户下现在有 154,834 EOS,价值 $1,176,738.4(价格 $7.6)。类似的,QtumTokenContract 账户下现在有 22,293 QTUM,价值 $158,280.3(价格 $7.1)。
这些 token 都都都都销毁了 (⊙?⊙)& P: `5 s# W2 x- F5 s# T4 \
% Y7 q1 s& Q! |
Dexaran 认识到了这个问题,! h& \/ T k: B6 c% ~
Contracts that are not designed to work with tokens must reject incoming token transactions. Otherwise, each token becomes a potential token trap.: Z9 y6 {4 y1 [" B; x
ERC20 token standard issues.(google docs)
并在 github 创建了一个 issue。
tokenFallback 函数,当转账到不能转出的智能合约地址时,将自动取消。' D# h! C4 V: L' ?) G) o2 Z3 k
contract ERC223 {, L/ u+ Z* B9 @6 d: H
function transfer(address to, uint value, bytes data) {
uint codeLength;
assembly {) @) ?& N; @' Z
codeLength := extcodesize(_to)
}
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);, S; Q0 i1 X/ T0 Z4 i" d- h
if(codeLength>0) {
// Require proper transaction handling.
ERC223Receiver receiver = ERC223Receiver(_to);) g* W0 ^% d4 [* B2 R m
receiver.tokenFallback(msg.sender, _value, _data);
}
}9 L2 A" c' P; W# U% ~
}+ d/ Y4 Q7 r5 _/ j1 l$ k/ B
【todo】:代码解释
The biggest change is that ERC223 no longer allow token to be transferred to a contract that does not allow token to be withdrawn.* h" p8 f1 i- e! h: F2 t$ |* h. m
https://medium.com/cryptomover/what-are-erc20-and-erc223-tokens-307badcca5a