Por qué algunas transacciones internas pueden tener éxito y otras fallan

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);

}

Respuestas (2)

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.

Los contratos precompilados también esperan que los parámetros de entrada sean válidos; de lo contrario, provocarán un error.
Gracias por su respuesta. ¿Me puede decir cómo especificar el gas en la transacción interna?
Puede usar algo como: 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.

address.sendtransfiere 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 payablefunción de respaldo, address.senddevolverá 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.sendfallar es que solo se envían 2300 gases junto con él. Un contrato inteligente que tiene una payablefunción de respaldo solo puede recibir Ether address.sendsi 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.calldevuelve falso si falló y truesi tuvo éxito.

¡Sin embargo!

address.calles una amenaza potencial para la seguridad. Podría introducir una vulnerabilidad de reingreso . Por eso se desaconseja su uso.

Gracias por su respuesta. ¿Me puede decir cómo especificar el gas en la transacción interna?