我仍然不明白“如果你把100 ERC20寄给一份合同,他们就会被困在那里,而这100 ERC20就永远失去了”。我真的不明白..。比如,合同上有地址和钱包,就像任何正常的指控一样。如果我们将ERC20发送到契约,为什么不使用传输方法--例如,将存储在智能契约中的令牌--转移到其他帐户地址。有人能给我举个例子吗?提前通知。
发布于 2019-03-23 21:44:37
一开始并不是特别明显。
合同可以很容易地接受和使用ERC20令牌进行交易。但是,合同不能在部署之前完成它设计不做的任何事情。虽然很容易说契约是一个地址,理论上它可以转发令牌,但在实践中,它可能不知道如何转发。契约不执行事先未编码的任意操作。
Open有CanReclaimTokens解决方案(https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.12.0/contracts/ownership/CanReclaimToken.sol),它接受一个简约的ERC20合同地址(因为随机令牌可能是任何东西),并允许接收合同的owner撤回。这是一种拯救的可能性,但只有在接收合同中包括了这一职能时:
XYZ令牌发送给contract FOO。FOO不知道这一点,但是它的地址在XYZ中有一个平衡。owner of FOO,有权从FOO中撤回XYZ。reclaimToken(address XYZ)来恢复搁浅的令牌。XYZ转发给爱丽丝。您可能会注意到,在任何情况下,这对Bob来说都不太理想。如果合同不能返回错误的令牌,那么Bob必须向Alice解释这一点。如果合同是分散的,并且没有一个骄傲的所有者,那么这个解决办法可能是不切实际的。如果合同确实具有恢复功能,那么Bob将承担可能不可取的服务责任。这都是假设爱丽丝能找到鲍勃。
我认为这么多(全部?)是合理的。挂线标记的情况是一种或另一种形式的运算符错误(或dev),因为如果合同不想要或不期望,向合同发送某种东西是没有意义的。默认情况下,这是一个无法恢复的错误。ERC223是一种预防性补救这种危险情况的尝试。
ERC223是ERC20,有一点额外的逻辑。它是向后兼容的,并通过以下方法来解决这个问题:
if(bytecode.length > 0),那么它就是一个契约。tokenFallback()函数(如果存在),或者调用常规回退函数。这给了接受者一个作出反应的机会。而不是不知道收据,现在调用接收合同。该怎么办..。嗯..。
如何拒绝(使用revert())意外类型的令牌?拒绝(通过revert())会将令牌返回给发送方,这可能是我们想要的。
你可以想象一个合同,它不期望任何形式的付款,也没有办法处理它。对于意外的乙醚,默认设置已经到位,因为如果附加了乙醚,则必须将函数标记为payable。并且,由solc创建并由EVM运行的默认回退函数(而不是payable)将拒绝所有其他如果以太被发送的函数。
tokenFallback()逻辑将这一思想扩展到令牌契约,并提出了一种标准化的处理方法。
考虑:
function tokenFallback(args ...) public {
revert("Don't send tokens here. This contract has no idea what to do with them.");
}它更充实了一点,在这里:https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.12.0/contracts/ownership/HasNoTokens.sol。
保护发送者的ERC223令牌。ERC20令牌只会到达,因为接收方无法拒绝它们。
希望能帮上忙。
https://ethereum.stackexchange.com/questions/68719
复制相似问题