Можно ли исчерпать все средства на счете Ethereum?

У меня есть учетная запись Ethereum, загруженная эфирами, и мне нужно потратить их все , оставив окончательный баланс учетной записи ровно на нуле вейсов . Это возможно?

Я знаю, что использование метода eth_estimateGas()и умножение на gasPriceнего вычисляет txCost, но действительно ли есть гарантия, что это будет фактическая комиссия за мою следующую транзакцию? Оценка газа может измениться в соответствии с https://github.com/ethereum/go-ethereum/issues/2395 , а цена на газ не является фиксированной и предсказуемой https://etherscan.io/charts/gasprice.

Есть ли способ выполнить транзакцию, точно зная окончательный баланс отправителя до ее отправки?

Вам «нужно» оставить ровно ноль вэй? Почему?
Просто добавляю фиатную бухгалтерию, проверенную через блокчейн. Когда пользователь выполняет выплату, баланс падает до нуля.
Это не похоже на то, что он должен был бы оставить баланс точно равным нулю. Несколько сотен бензина при нынешних ценах на газ обойдутся в ничтожную долю пенни.

Ответы (1)

Да , если вы переходите на внешнюю учетную запись (EOA).

Нет , если вы переводите на контрактный счет.

Вы можете указать gasPrice( x gas), которую вы готовы заплатить за свою транзакцию, и майнер решит, стоит ли майнить вашу транзакцию.

Для EOA газ всегда 21000, так что можете точно указать комиссию.

Для контрактного счета estimateGas(...)не всегда будет возвращаться точное количество газа, необходимого для выполнения вашей транзакции (см. Каковы ограничения для оценки газа и когда его оценка может быть значительно неправильной? ), поэтому вы не можете точно указать комиссию.

От газа и транзакционных издержек :

Ограничение газа существует, чтобы защитить вас от запуска кода с ошибками, пока ваши средства не будут исчерпаны. Произведение gasPrice и gas представляет собой максимальную сумму Wei, которую вы готовы заплатить за выполнение транзакции. То, что вы указываете как gasPrice, используется майнерами для ранжирования транзакций для включения в блокчейн. Это цена в Wei за одну единицу газа, в которой оцениваются операции VM.

Вот пример:

> 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"

Транзакция заминирована. В квитанции об операции указан использованный газ 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
}

И gasPrice составляет 15000000000, как указано в транзакции:

> 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
}

Проверьте учетную запись майнера в блоке до добытой транзакции и в блоке, когда транзакция была добыта:

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

А вот разница, которая показывает вознаграждение за майнинг 5 ETH + сборы за транзакции:

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

И подтверждая, что заработанные комиссионные за транзакцию gas x specified gasPrice:

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



И это приводит к следующему вопросу: что происходит, когда вы указываете значение gasPriceвыше текущего gasPrice?

Итак, вот та же информация с указанным gasPriceвыше текущего gasPrice:

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

Квитанция о транзакции:

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

Детали сделки:

> 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
}

Изменение баланса показывает, что майнер будет использовать указанное вами gasPriceи присвоит себе более высокую комиссию за транзакцию:

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

Подтверждение того, что транзакция использовала указанный вами gasPrice:

> new BigNumber(21000).times(25000000000)
525000000000000
Отличное объяснение, большое спасибо. Просто сомнение: если eth.gasPrice равен 20000000000, как возможно, что Ethereum примет первую транзакцию с более низкой gasPrice: 15000000000?
На самом деле, отправить точное количество газа по контракту можно несколькими способами. Во-первых, поскольку Ethereum полностью детерминирован, можно, приложив немало усилий, точно знать, сколько газа будет использовать транзакция во многих случаях. Во-вторых, можно построить контракт, который гарантированно будет потреблять почти весь газ, который вы ему отправляете. Вы просто используете низкоуровневый вызов для фактической передачи, а затем тратите остальную часть газа. Это может привести к тому, что у вас останется менее 6 бензина, что, честно говоря, ничего.