https://ropsten.etherscan.io/tx/0x8d5b9a6906b9f287c4b09333272f691a75655e470c128b78b3bc4a540c534190
In this transaction, I tried to send 10wei to 0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000001,
.....
0x0000000000000000000000000000000000000009
But the ethes sent to 0x0000000000000000000000000000000000000001 and several other accounts have failed, and the other part Ha sido exitoso. No sé por qué esto es así. Este es el código fuente del contrato.
function getThisBalance() payable returns(uint, uint){
for (uint i = 0; i < msg.value; i ++){
address(i).send(1);
}
return (i, msg.value);
}
La razón por la que su envío falla para ciertas direcciones (por ejemplo, address(1)
) es que esta dirección es en realidad un contrato (aunque no lo parezca en etherscan.io).
Estas direcciones son contratos compilados previamente (p. ej., el contrato de recuperación de ECDSA), así que tome gasolina adicional para enviar fondos. Puede pasar gas adicional al enviar el ETH para evitar esto, o usar un rango diferente de direcciones evitando contratos precompilados si las direcciones no son importantes para usted.
address.send
transfiere Ether a la cuenta especificada. Si esa cuenta es un contrato inteligente, se ejecuta su función de respaldo.
De forma predeterminada, la función alternativa de un contrato inteligente no es payable
. Eso significa que se revertirá cuando se le envíe Ether. Entonces, si una de sus direcciones es la de un contrato inteligente, que no tiene una payable
función de respaldo, address.send
devolverá falso y el éter no se enviará a ese contrato inteligente. Sin embargo, la transacción continuará ya que su código no hace nada con el valor de retorno de address.send
.
Otra razón para address.send
fallar es que solo se envían 2300 gases junto con él. Un contrato inteligente que tiene una payable
función de respaldo solo puede recibir Ether address.send
si la ejecución de la función de respaldo no cuesta más de 2300 de gas. Es posible emitir un evento con gas 2300, pero no mucho más que eso.
Para enviar más de 2300 gases a la función de reserva, puede utilizar address.call.value([wei])()
, que reenvía todo el gas, o address.call.value([wei]).gas([gas])()
. address.call
devuelve falso si falló y true
si tuvo éxito.
¡Sin embargo!
address.call
es una amenaza potencial para la seguridad. Podría introducir una vulnerabilidad de reingreso . Por eso se desaconseja su uso.
ismael
usuario17314
adam dossa
msg.sender.call.gas(2500000).value(amount)()
para especificar una mayor cantidad de gas. NB: la razón para no hacer esto es que permite que el contrato al que está enviando fondos vuelva a entrar en su contrato (ya que tiene el gas para hacerlo ahora). Para contratos conocidos precompilados esto no es necesariamente un problema, pero es peligroso cuando se envía ETH a contratos desconocidos.