DAPP develop edible estimateGas

我们可使用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测试链,并将abicontractAddress换成你自己的

版本控制

Version Action Time
1.0 Init 2018-11-17