Gas 的考虑
Gas在 [gas] 一节中有更详细的描述,在智能合约编程中是一个非常重要的考虑因素。gas是限制以太坊允许交易消耗的最大计算量的资源。如果在计算过程中超过了gas限制,则会发生以下一系列事件:
引发“out of gas”异常。
函数执行前的合约状态被恢复。
全部gas作为交易费用交给矿工,不予退还。
由于gas由创建该交易的用户支付,因此不鼓励用户调用gas成本高的函数。因此,程序员最大限度地减少合约函数的gas成本。为此,在构建智能合约时建议采用某些做法,以尽量减少函数调用的gas成本。
避免动态大小的数组
函数中任何动态大小的数组循环,对每个元素执行操作或搜索特定元素会引入使用过多gas的风险。在找到所需结果之前,或在对每个元素采取行动之前,合约可能会用尽gas。
避免调用其他合约
调用其他合约,尤其是在其函数的gas成本未知的情况下,会导致用尽gas的风险。避免使用未经过良好测试和广泛使用的库。库从其他程序员收到的审查越少,使用它的风险就越大。
估算gas成本
例如,如果你需要根据调用参数估计执行某种合约函数所需的gas,则可以使用以下过程;
var contract = web3.eth.contract(abi).at(address);
var gasEstimate = contract.myAweSomeMethod.estimateGas(arg1, arg2, {from: account});
gasEstimate 会告诉我们执行需要的gas单位。
为了获得网络的 gas价格 可以使用:
var gasPrice = web3.eth.getGasPrice();
然后估算 gas成本
var gasCostInEther = web3.fromWei((gasEstimate * gasPrice), 'ether');
让我们应用我们的天然气估算函数来估计我们的+Faucet+示例的天然气成本,使用此书代码库中的代码:
code/truffle/FaucetEvents
我们以开发模式启动truffle,并执行一个JavaScript文件+gas_estimates.js+,其中包含:
gas_estimates.js: Using the estimateGas function
var FaucetContract = artifacts.require("./Faucet.sol");
FaucetContract.web3.eth.getGasPrice(function(error, result) {
var gasPrice = Number(result);
console.log("Gas Price is " + gasPrice + " wei"); // "10000000000000"
// Get the contract instance
FaucetContract.deployed().then(function(FaucetContractInstance) {
// Use the keyword 'estimateGas' after the function name to get the gas estimation for this particular function (aprove)
FaucetContractInstance.send(web3.toWei(1, "ether"));
return FaucetContractInstance.withdraw.estimateGas(web3.toWei(0.1, "ether"));
}).then(function(result) {
var gas = Number(result);
console.log("gas estimation = " + gas + " units");
console.log("gas cost estimation = " + (gas * gasPrice) + " wei");
console.log("gas cost estimation = " + FaucetContract.web3.fromWei((gas * gasPrice), 'ether') + " ether");
});
});
truffle开发控制台显示:
$ truffle develop
truffle(develop)> exec gas_estimates.js
Using network 'develop'.
Gas Price is 20000000000 wei
gas estimation = 31397 units
gas cost estimation = 627940000000000 wei
gas cost estimation = 0.00062794 ether
建议你将函数的gas成本评估作为开发工作流程的一部分进行,以避免将合约部署到主网时出现意外。