Ниже приведены тестовые примеры трюфелей в javascript, где я пытался добавить стоимость газа к балансу счета, чтобы подтвердить сумму транзакции, где сумма должна быть равна предыдущему балансу.
Но я не мог заставить его работать!
rcpt.cumulativeGasUsed, web3.eth.gasPrice, getBalance(accounts[1]) все верно, а арифметика нет, какие-то fromWei, toWei кунг-фу нужны?
Что я здесь делаю неправильно?
return instance.bailOut({ from: accounts[1] }).then(function (resp) {
var rcpt = web3.eth.getTransactionReceipt(resp.tx);
console.log("Sum: " + ((rcpt.cumulativeGasUsed * web3.eth.gasPrice) + web3.eth.getBalance(accounts[1]).toString(10)));
});
После множества экспериментов оказалось, что приведенный ниже метод работает нормально, но не может объяснить логику стоимости транзакции! Любая идея приветствуется.
В любом случае модульный тест проходит!!!
return contractInstance.withdraw({ value: web3.toWei(1, "ether"), gas: 1000000 }).then(function () {
var contractAddressBalance = web3.fromWei(web3.eth.getBalance(contractAddress).toString(10));
console.log("contractAddress balance after withdraw: " + contractAddressBalance);
return contractInstance.bailOut({ from: accounts[1] }).then(function (resp) {
var rcpt = web3.eth.getTransactionReceipt(resp.tx);
console.log("cumulativeGasUsed: " + rcpt.cumulativeGasUsed);
console.log("gasPrice: " + web3.eth.gasPrice);
var transactionCost = (rcpt.cumulativeGasUsed / 10000000); // How come this works???
console.log("transactionCost: " + transactionCost);
console.log("Account[1] balance after withdraw: " + web3.eth.getBalance(accounts[1]));
contractWalletAfter = web3.fromWei(web3.eth.getBalance(accounts[1]).add(web3.fromWei(rcpt.cumulativeGasUsed)));
assert.equal(((contractWalletAfter.minus(contractWalletBefore)).add(transactionCost)).valueOf(), 6, "6 wasn't in the contract wallet");
});
});
Примечание. Этот ответ действителен только для Truffle v4.
Я пробовал этот тест на примере MetaCoin из трюфеля (т.е. запускал truffle unbox metacoin
в пустой директории)
var MetaCoin = artifacts.require("./MetaCoin.sol");
contract('MetaCoin', function(accounts) {
it("Test gas", async () => {
const meta = await MetaCoin.deployed();
// Initial balance of the second account
const initial = await web3.eth.getBalance(accounts[1]);
console.log(`Initial: ${initial.toString()}`);
// Obtain gas used from the receipt
const receipt = await meta.sendCoin(accounts[2], 1, { from: accounts[1] });
const gasUsed = receipt.receipt.gasUsed;
console.log(`GasUsed: ${receipt.receipt.gasUsed}`);
// Obtain gasPrice from the transaction
const tx = await web3.eth.getTransaction(receipt.tx);
const gasPrice = tx.gasPrice;
console.log(`GasPrice: ${tx.gasPrice}`);
// Final balance
const final = await web3.eth.getBalance(accounts[1]);
console.log(`Final: ${final.toString()}`);
assert.equal(final.add(gasPrice.mul(gasUsed)).toString(), initial.toString(), "Must be equal");
});
});
Соответствующий вывод:
Contract: MetaCoin
Initial: 99971803600000000000
GasUsed: 23497
GasPrice: 100000000000
Final: 99969453900000000000
✓ Test gas (199ms)
1 passing (217ms)
Одно отличие состоит в том, что я читаю gasPrice из транзакции( getTransaction(hash).gasPrice
), а не из сети eth.gasPrice()
.
getTransaction(hash).gasPrice
100000000000 и eth.gasPrice()
20000000000 в моих тестах.Следующий код является тем же кодом, что и код Ismael , с изменениями для работы с Truffle v5, поскольку getBalance
тип возвращаемого значения, кроме того, gasUsed
и gasPrice
значения по умолчанию не являются BN:
var MetaCoin = artifacts.require("./MetaCoin.sol");
const { toBN } = web3.utils;
contract('MetaCoin', function(accounts) {
it("Test gas", async () => {
const meta = await MetaCoin.deployed();
// Initial balance of the second account
const initial = toBN(await web3.eth.getBalance(accounts[1]));
console.log(`Initial: ${initial.toString()}`);
// Obtain gas used from the receipt
const receipt = await meta.sendCoin(accounts[2], 1, { from: accounts[1] });
const gasUsed = toBN(receipt.receipt.gasUsed);
console.log(`GasUsed: ${receipt.receipt.gasUsed}`);
// Obtain gasPrice from the transaction
const tx = await web3.eth.getTransaction(receipt.tx);
const gasPrice = toBN(tx.gasPrice);
console.log(`GasPrice: ${tx.gasPrice}`);
// Final balance
const final = toBN(await web3.eth.getBalance(accounts[1]));
console.log(`Final: ${final.toString()}`);
assert.equal(final.add(gasPrice.mul(gasUsed)).toString(), initial.toString(), "Must be equal");
});
});
Исмаэль
gasUsed * gasPrice + value
. Если контракты делают перевод отправителю, который изменит окончательный баланс.Джимсон Джеймс
rcpt.cumulativeGasUsed * web3.eth.gasPrice
чтобы получить стоимость транзакции. Но это не сработало! Если у вас открыта консоль, вы можете быстро проверить то же самое с помощью Metacoin в тестовом примере с трюфелем. Похоже на какое-то волшебство с тестом на трюфели???