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.2 ^3 B; b8 n( f9 h$ [ s* W' ^
https://stackoverflow.com/a/37670490/7218912
/ l! A, K) D3 y T/ u/ s6 T
有时候确实有需要向智能合约转账:
但是大多数 smart contract 的 token 是不能转出的,只要合约里没写转出的逻辑,就不能转出。以太坊将智能合约看做是独立的个体,没人知道它的私钥,给不支持转出的智能合约转 token 就等于销毁了。' Q9 q A- E* U1 t; t
当我们要转账时,会转到交易方的地址,不会闲着没事给智能合约转 token。但是这种事情仍然会发生,不断有人给 EOSTokenContract 转 EOS(见下图),EOSTokenContract 账户下现在有 154,834 EOS,价值 $1,176,738.4(价格 $7.6)。类似的,QtumTokenContract 账户下现在有 22,293 QTUM,价值 $158,280.3(价格 $7.1)。
这些 token 都都都都销毁了 (⊙?⊙)
% d" ~+ w8 H5 w
Dexaran 认识到了这个问题,
Contracts that are not designed to work with tokens must reject incoming token transactions. Otherwise, each token becomes a potential token trap.
ERC20 token standard issues.(google docs), O/ C/ K# c" p {/ Y
; ~6 T5 d* q4 e3 `
并在 github 创建了一个 issue。5 | R' K0 j1 H; S5 [
tokenFallback 函数,当转账到不能转出的智能合约地址时,将自动取消。
contract ERC223 {
function transfer(address to, uint value, bytes data) {* a4 m4 @* |' b2 _ ?( O% g* L6 a5 W* m
uint codeLength;
assembly {
codeLength := extcodesize(_to)* f/ u# {- X. |6 o E5 p
}
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);9 F/ u8 `$ ^7 S5 j) ]
if(codeLength>0) {
// Require proper transaction handling.4 G( W* j. b9 k8 m+ ~; T. T4 a
ERC223Receiver receiver = ERC223Receiver(_to);
receiver.tokenFallback(msg.sender, _value, _data);, z0 y4 k( }. f
}5 e, P. E; ]+ K% B6 V
}7 U7 l* v, ~0 ]% B) F4 i
}1 ?, x/ B" Q5 T: H6 W+ T
【todo】:代码解释. y0 n" y7 A! T1 b
) Z) L1 g4 s s* F8 B
The biggest change is that ERC223 no longer allow token to be transferred to a contract that does not allow token to be withdrawn.
https://medium.com/cryptomover/what-are-erc20-and-erc223-tokens-307badcca5a