我们可使用web3.js调用estimateGas函数获得一个调用智能合约的Gas估计值 ,estimateGas调用将直接在节点的VM中执行,并未在区块链中确认,函数会返回估算使用的gas量
问题
调用智能合约方法gas
费给低了报
intrinsic gas too low
给高了也报错
metamask too high for low tansation
有时候还报
gas limit reached
方法
食用web3.eth.estimateGas获取需要的gas
web3.eth.estimateGas(callObject [, callback])
参数
callObject - The transaction object to send:
from: String -(optional) 发起交易的账户
to: String - 合约地址
value: Number|String|BigNumber - (optional)需要的value数量
gas: Number|String|BigNumber -(optional) 交易可能需要用到的gas,单位wei。未用完则返回
gasPrice: Number|String|BigNumber - (optional) gasPrice
data: String - 发送这笔交易的数据,见分解
nonce: Number - (optional) 用来重置pending的交易,需要和pending的交易有相同的nonce
其中参数`to` 和参数 `data`必填,其它选填 data
contractInstance.contractFunction.getData(param1, param2 ...);
运行
合约
contract TestEstimateGasContract{
uint256 public amount ;
function setAmount(uint256 _amount) payable public{
amount = _amount;
}
}
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
button{
width: 100%;
padding: 30px;
height: 100px;
margin: 30px;
}
</style>
</head>
<body>
<div><input id="amount" type="text"></div>
<div><input id="submit" type="submit" onclick="setAmount()">setAmount</button></div>
<script>
var abi = [
{
"constant": false,
"inputs": [
{
"name": "_amount",
"type": "uint256"
}
],
"name": "setAmount",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "amount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];
var contractAddress = '0x1d03de1f1e26b3cb8516f99a8ec1b6464e390a45';
var contractInstance = web3.cmt.contract(abi).at(contractAddress);
var gasPrice = '10000000000';
function setAmount(){
var amount = document.getElementById('amount').value;
alert('您填写的数字是:' + amount);
var feeData = contractInstance.setAmount.getData(amount);
web3.cmt.estimateGas({data:feeData, to: contractAddress},function (error, gas) {
if(!gas){
alert('请检查合约是否abi是否正确!')
return;
}
contractInstance.setAmount(amount,{gasPrice: gasPrice, gas: gas}, function(error, tx){
if(!error){
alert('set amount tx:' + tx);
var transactionTimer = setInterval(function () {
web3.cmt.getTransactionReceipt(tx, function (error, result) {
if (!error && result != null) {
console.log(result);
alert('set amount tx detail:' + JSON.stringify(result) + ';end');
clearInterval(transactionTimer);
} else if(!result && error != null){
console.log(error);
alert(JSON.stringify(error));
clearInterval(transactionTimer);
}
})
}, 5000);
}else{
alert(alert(JSON.stringify(err)));
console.log(err);
}
});
})
}
</script>
</body>
</html>
提醒
本示例食用 chrome + metamask + CMT Test Network
,可直接运行;如需在eth测试链上跑,请将合约代码部署到eth测试链,并将abi
和contractAddress
换成你自己的
版本控制
Version | Action | Time |
---|---|---|
1.0 | Init | 2018-11-17 |