使用 Truffle 计算以太坊合约中的交易费用
Accounting for transaction fees in Ethereum contract using Truffle
我正在为以太坊使用 Truffle 测试框架 (v4.0.1)。我不明白为什么以下简单合约的交易费用加起来不等于 gasPrice*gasUsed
:
contract MinTest {
function run() public returns(bool) {
return true;
}
}
我使用的 mocha 测试是:
contract('Minimum Test', function (accounts) {
it("min test", function () {
var initial = web3.eth.getBalance(accounts[1]);
var final;
return MinTest.deployed().then(function(instance) {
return instance.run({from: accounts[1]});
}).then(function(result) {
final = web3.eth.getBalance(accounts[1]);
var gasPrice = new BigNumber(web3.eth.gasPrice);
var gasUsed = new BigNumber(result.receipt.gasUsed);
var gasCost = gasPrice.times(gasUsed);
console.log("gasPrice : " + gasPrice);
console.log("gasUsed : " + gasUsed);
console.log("gasCost : " + gasCost);
console.log("initial : " + initial);
console.log("initial-gasCost: " + initial.minus(gasCost));
console.log("final : " + final);
console.log("unaccounted : " + initial.minus(gasCost).minus(final));
});
});
});
上面的测试产生以下输出:
gasPrice : 20000000000
gasUsed : 21478
gasCost : 429560000000000
initial : 100000000000000000000
initial-gasCost: 99999570440000000000
final : 99997852200000000000
unaccounted : 1718240000000000
我预计调用合约的 MinTest.run
函数会导致 accounts[1]
被扣除正好等于 gasPrice*gasUsed
的金额,但事实并非如此这个例子。还有一个额外的1718240000000000
wei我记不起来了。为什么这里多了一个1718240000000000
wei?
web3.eth.gasPrice
不是您在交易调用中指定的价格。来自文档:
This property is read only and returns the current gas price. The gas
price is determined by the x latest blocks median gas price.
它是用来告诉你别人付的钱,所以你可以动态地确定"going rate"。如果您想随时间更改交易的汽油价格,则可以使用它。我猜 testrpc
只是将此设置为 20000000000。
另一方面,当您在事务调用中未指定 gasPrice
时,它默认为 10000000000。下面是更新的测试用例,其中传入 gasPrice
并输出(我测试用了 15 Gwei)。
contract('Minimum Test', function (accounts) {
it("min test", function () {
var initial = web3.eth.getBalance(accounts[1]);
var final;
var gasPrice = new BigNumber(15000000000);
return MinTest.deployed().then(function(instance) {
return instance.run({from: accounts[1], gasPrice: gasPrice});
}).then(function(result) {
final = web3.eth.getBalance(accounts[1]);
var gasUsed = new BigNumber(result.receipt.gasUsed);
var gasCost = gasPrice.times(gasUsed);
console.log("gasPrice : " + gasPrice);
console.log("gasUsed : " + gasUsed);
console.log("gasCost : " + gasCost);
console.log("initial : " + initial);
console.log("initial-gasCost: " + initial.minus(gasCost));
console.log("final : " + final);
console.log("unaccounted : " + initial.minus(gasCost).minus(final));
});
});
});
Contract: Minimum Test
gasPrice : 15000000000
gasUsed : 21431
gasCost : 321465000000000
initial : 100000000000000000000
initial-gasCost: 99999678535000000000
final : 99999678535000000000
unaccounted : 0
√ min test (773ms)
1 passing (922ms)
编辑 - web3js 文档确实说 gasPrice
的默认值应该是相同的:
gasPrice: Number|String|BigNumber - (optional, default:
To-Be-Determined) The price of gas for this transaction in wei,
defaults to the mean network gas price.
这可能是 Truffle 中的一个错误。无论如何,如果您传入自己的汽油价格,数字就会计算出来。
我正在为以太坊使用 Truffle 测试框架 (v4.0.1)。我不明白为什么以下简单合约的交易费用加起来不等于 gasPrice*gasUsed
:
contract MinTest {
function run() public returns(bool) {
return true;
}
}
我使用的 mocha 测试是:
contract('Minimum Test', function (accounts) {
it("min test", function () {
var initial = web3.eth.getBalance(accounts[1]);
var final;
return MinTest.deployed().then(function(instance) {
return instance.run({from: accounts[1]});
}).then(function(result) {
final = web3.eth.getBalance(accounts[1]);
var gasPrice = new BigNumber(web3.eth.gasPrice);
var gasUsed = new BigNumber(result.receipt.gasUsed);
var gasCost = gasPrice.times(gasUsed);
console.log("gasPrice : " + gasPrice);
console.log("gasUsed : " + gasUsed);
console.log("gasCost : " + gasCost);
console.log("initial : " + initial);
console.log("initial-gasCost: " + initial.minus(gasCost));
console.log("final : " + final);
console.log("unaccounted : " + initial.minus(gasCost).minus(final));
});
});
});
上面的测试产生以下输出:
gasPrice : 20000000000
gasUsed : 21478
gasCost : 429560000000000
initial : 100000000000000000000
initial-gasCost: 99999570440000000000
final : 99997852200000000000
unaccounted : 1718240000000000
我预计调用合约的 MinTest.run
函数会导致 accounts[1]
被扣除正好等于 gasPrice*gasUsed
的金额,但事实并非如此这个例子。还有一个额外的1718240000000000
wei我记不起来了。为什么这里多了一个1718240000000000
wei?
web3.eth.gasPrice
不是您在交易调用中指定的价格。来自文档:
This property is read only and returns the current gas price. The gas price is determined by the x latest blocks median gas price.
它是用来告诉你别人付的钱,所以你可以动态地确定"going rate"。如果您想随时间更改交易的汽油价格,则可以使用它。我猜 testrpc
只是将此设置为 20000000000。
另一方面,当您在事务调用中未指定 gasPrice
时,它默认为 10000000000。下面是更新的测试用例,其中传入 gasPrice
并输出(我测试用了 15 Gwei)。
contract('Minimum Test', function (accounts) {
it("min test", function () {
var initial = web3.eth.getBalance(accounts[1]);
var final;
var gasPrice = new BigNumber(15000000000);
return MinTest.deployed().then(function(instance) {
return instance.run({from: accounts[1], gasPrice: gasPrice});
}).then(function(result) {
final = web3.eth.getBalance(accounts[1]);
var gasUsed = new BigNumber(result.receipt.gasUsed);
var gasCost = gasPrice.times(gasUsed);
console.log("gasPrice : " + gasPrice);
console.log("gasUsed : " + gasUsed);
console.log("gasCost : " + gasCost);
console.log("initial : " + initial);
console.log("initial-gasCost: " + initial.minus(gasCost));
console.log("final : " + final);
console.log("unaccounted : " + initial.minus(gasCost).minus(final));
});
});
});
Contract: Minimum Test gasPrice : 15000000000 gasUsed : 21431 gasCost : 321465000000000 initial : 100000000000000000000 initial-gasCost: 99999678535000000000 final : 99999678535000000000 unaccounted : 0 √ min test (773ms) 1 passing (922ms)
编辑 - web3js 文档确实说 gasPrice
的默认值应该是相同的:
gasPrice: Number|String|BigNumber - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price.
这可能是 Truffle 中的一个错误。无论如何,如果您传入自己的汽油价格,数字就会计算出来。