¿Es posible agotar todos los fondos en una cuenta de Ethereum?

Tengo una cuenta de Ethereum cargada con Ethers y necesito gastarlos todos , dejando el saldo final de la cuenta exactamente en cero Weis . ¿Es eso posible?

Sé que usar el método eth_estimateGas()y multiplicar por gasPriceél calcula txCost, pero ¿realmente hay alguna garantía de que esta será la tarifa real de mi próxima transacción? La estimación del gas podría cambiar según https://github.com/ethereum/go-ethereum/issues/2395 y el precio del gas no es fijo ni predecible https://etherscan.io/charts/gasprice

¿Hay alguna forma de realizar una transacción sabiendo exactamente el saldo final del remitente antes de enviarla?

¿"Necesitas" dejar exactamente cero wei atrás? ¿Por qué?
Solo sumando una contabilidad fiduciaria que ha sido auditada a través de blockchain. Cuando un usuario realiza un pago, el saldo cae a cero.
Eso no parece que tendría que dejar un saldo de exactamente cero. Unos pocos cientos de gasolina, a los precios actuales de la gasolina, equivalen a una pequeña fracción de centavo.

Respuestas (1)

, si está transfiriendo a una cuenta de propiedad externa (EOA).

No , si está transfiriendo a una cuenta de contrato.

Puede especificar el gasPrice( x gas) que está dispuesto a pagar por su transacción y el minero decidirá si extrae su transacción.

Para un EOA, el gas siempre es 21000, por lo que puede especificar la tarifa exactamente.

Para una cuenta de contrato, estimateGas(...)no siempre devolverá el gas exacto requerido para ejecutar su transacción (consulte ¿Cuáles son las limitaciones para estimar Gas y cuándo su estimación sería considerablemente incorrecta? ), por lo que no puede especificar la tarifa exactamente.

De Gas y costos de transacción :

El límite de gas está ahí para protegerlo de la ejecución de un código defectuoso hasta que se agoten sus fondos. El producto de gasPrice y gas representa la cantidad máxima de Wei que está dispuesto a pagar por ejecutar la transacción. Los mineros utilizan lo que especificas como gasPrice para clasificar las transacciones para su inclusión en la cadena de bloques. Es el precio en Wei de una unidad de gas, en el que se cotizan las operaciones de VM.

Aquí hay un ejemplo:

> eth.gasPrice
20000000000

// Specify a lower gasPrice
> eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[2], gasPrice: 15000000000, value: web3.toWei(1, "ether")});
"0x9e53cb0268ae6b75303c46a20d869e2a6f95a93269a5c07bf5bf1f37ff6fea80"

La transacción es minada. El recibo de la transacción muestra el gas usado 21000:

> eth.getTransactionReceipt("0x9e53cb0268ae6b75303c46a20d869e2a6f95a93269a5c07bf5bf1f37ff6fea80");
{
  blockHash: "0xd0bd16c0a3064a5ee1d45762030080b1791d14ec80504f01c839577881696e60",
  blockNumber: 5706,
  contractAddress: "0x39236bc7d128340b345138d997854981eb4948e7",
  cumulativeGasUsed: 21000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 21000,
  logs: [],
  root: "86edc80b49786b7dc101c54f85659715661121a22e36dcfd90bf2c0961142493",
  to: null,
  transactionHash: "0x9e53cb0268ae6b75303c46a20d869e2a6f95a93269a5c07bf5bf1f37ff6fea80",
  transactionIndex: 0
}

Y el gasPrice es 15000000000 como se especifica en la transacción:

> eth.getTransaction("0x9e53cb0268ae6b75303c46a20d869e2a6f95a93269a5c07bf5bf1f37ff6fea80");
{
  blockHash: "0xd0bd16c0a3064a5ee1d45762030080b1791d14ec80504f01c839577881696e60",
  blockNumber: 5706,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gas: 90000,
  gasPrice: 15000000000,
  hash: "0x9e53cb0268ae6b75303c46a20d869e2a6f95a93269a5c07bf5bf1f37ff6fea80",
  input: "0x",
  nonce: 6,
  to: null,
  transactionIndex: 0,
  value: 1000000000000000000
}

Verifique la cuenta del minero en el bloque antes de la transacción extraída y en el bloque cuando se extrajo la transacción:

> web3.fromWei(eth.getBalance(eth.accounts[0], 5705),"ether")
28522.81130279    
> web3.fromWei(eth.getBalance(eth.accounts[0], 5706),"ether")
28527.81161779

Y aquí está la diferencia que muestra la recompensa minera de 5 ETH + las tarifas de transacción cobradas:

> web3.fromWei(eth.getBalance(eth.accounts[0], 5706).minus(eth.getBalance(eth.accounts[0], 5705)),"wei")
5000315000000000000

Y confirmando que las tarifas de transacción ganadas son gas x specified gasPrice:

> new BigNumber(21000).times(15000000000)
315000000000000



Y esto lleva a la siguiente pregunta, ¿qué sucede cuando especifica un valor gasPricesuperior al actual gasPrice?

Así que aquí está la misma información con el especificado gasPricemás alto que el actual gasPrice:

> eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[2], gasPrice: 25000000000, value: web3.toWei(1, "ether")});    
"0xcbd2a112c77baeca47550f49181fd2fcb05b3551b71f6180a30a55672c6aab3d"

El recibo de la transacción:

> eth.getTransactionReceipt("0xcbd2a112c77baeca47550f49181fd2fcb05b3551b71f6180a30a55672c6aab3d")
{
  blockHash: "0x58ba7819f778f482930e67a2914c0174aaf92bfb680b407fa9bcd55cfe5e4e80",
  blockNumber: 5808,
  contractAddress: "0xc5c9b0194bb6184db6a278f96525718a45d310a5",
  cumulativeGasUsed: 21000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 21000,
  logs: [],
  root: "68774aad53457e6cd4cd3b9344235e43a021366ff9763156224dbf07101b55af",
  to: null,
  transactionHash: "0xcbd2a112c77baeca47550f49181fd2fcb05b3551b71f6180a30a55672c6aab3d",
  transactionIndex: 0
}

Los detalles de la transacción:

> eth.getTransaction("0xcbd2a112c77baeca47550f49181fd2fcb05b3551b71f6180a30a55672c6aab3d")
{
  blockHash: "0x58ba7819f778f482930e67a2914c0174aaf92bfb680b407fa9bcd55cfe5e4e80",
  blockNumber: 5808,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gas: 90000,
  gasPrice: 25000000000,
  hash: "0xcbd2a112c77baeca47550f49181fd2fcb05b3551b71f6180a30a55672c6aab3d",
  input: "0x",
  nonce: 7,
  to: null,
  transactionIndex: 0,
  value: 1000000000000000000
}

El cambio en el saldo muestra que el minero utilizará su especificación gasPricey se embolsará las tarifas de transacción más altas:

> web3.fromWei(eth.getBalance(eth.accounts[0], 5808).minus(eth.getBalance(eth.accounts[0], 5807)),"wei")
5000525000000000000

Confirmando que la transacción utilizó su especificado gasPrice:

> new BigNumber(21000).times(25000000000)
525000000000000
Perfecta explicación, muchas gracias. Solo una duda: si eth.gasPrice es 20000000000, ¿cómo es posible que Ethereum acepte la primera transacción con un gasPrice más bajo: 15000000000?
En realidad, es posible enviar una cantidad exacta de gas a un contrato, en más de un sentido. Primero, dado que Ethereum es totalmente determinista, es posible, con bastante esfuerzo, saber exactamente cuánto gas usará una transacción en muchos casos. En segundo lugar, es posible construir un contrato que garantice el consumo de casi todo el gas que le envíe. Simplemente usa una llamada de bajo nivel para llevar a cabo el tx real, luego desperdicia el resto del gas. Esto puede hacer que te queden menos de 6 gasolina, que francamente no es nada.