Let’s have a deeper understanding of how estimateGas in web3.js calculates the amount of gas consumed by smart contracts

We can use the estimateGas function of the web3.js framework to obtain the estimated Gas value of an Ethereum smart contract by executing a message call or transaction that is executed directly in the node's VM and not confirmed in the blockchain , the function returns the estimated amount of gas used.

function call:

web3.eth.estimateGas (callObject [, callback])

parameter:

In web3.eth.sendTransaction, parameters are mostly optional.

1. Object - Transaction object to send:

  • fromString - The account address to transfer to. By default the web3.eth.defaultAccount property is used.
  • toString - (optional) destination address, undefined for the transaction that created the contract.
  • valueNumber|String|BigNumber - (Optional) The value transferred for the transaction in Wei, or the fund if it is a contract creation transaction.
  • gasNumber|String|BigNumber - (optional, default: pending) amount of gas to use for the transaction (unused gas is refunded).
  • gasPriceNumber|String|BigNumber - (optional, default: pending) The gas price for this transaction in wei, defaults to the average network gas price.
  • dataString - (optional) Either a byte string containing data associated with the message, or initialization code that creates a contract transaction.
  • nonceNumber - (optional) a random integer. This allows overwriting your own pending transactions using the same nonce.

2.Function - (optional) If a callback is passed, the HTTP request will become asynchronous. Detailed instructions are here in  this note  .

return value: 

Numeric: The gas value to use to simulate calls/transactions.

A simple example:
var result = web3.eth.estimateGas ({
    to: "0xc4abd0339eb8d57087278718986382264244252f", 
    data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
});
console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015"
 

You may encounter an error in the estimateGas method in the web3js library. The error I get most of the time is this: "Required gas exceeds allowable value or always transaction fails".

The first thing to check is whether the next transaction is valid. For example, if you are estimating the gasAmount to send a certain amount of tokens to another address, there are two main things to check:

1. Whether there is enough ether in the sending address.
2. Whether there are enough tokens/tokens in the sending address.
These may seem obvious to check, but it's still possible to make the low-level mistake of thinking that the method estimates Gas is only used to compute estimates, when it's not. If the actual conditions set by the parameters are wrong, it will throw an error when running the method without actually executing any code .

A code snippet to evaluate the gas required to send a token:

tokenContract.methods.transfer(recipientAddress,numtokens)
 .estimateGas({from:tokenHolderAddress},function(gasAmount){
 console.log(gasAmount);
 });

The official website is here https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethestimategas.

You can also enter https://ethereum.github.io/browser-solidity in the address bar of your browser, and then copy your contract directly to get the estimated value.

An example of the default in this code is the code for proposal voting as follows:

pragma solidity ^ 0.4 . 0 ;
contract Ballot {

    struct Voter {
        uint weight;
        bool voted;
        uint8 vote;
        address delegate;
    }
    struct Proposal {
        uint voteCount;
    }

    address chairperson;
    mapping(address => Voter) voters;
    Proposal[] proposals;

    /// Create a new ballot with $(_numProposals) different proposals. //Create a new ballot contract for different proposals 
    function Ballot(uint8 _numProposals) public {
        chairperson = msg.sender;
        voters[chairperson].weight = 1;
        proposals.length = _numProposals;
    }

    /// Give $(toVoter) the right to vote on this ballot.//Grant the right to vote
     /// May only be called by $(chairperson). //Can only be called by the chairperson 
    function giveRightToVote(address toVoter) public {
         if (msg.sender != chairperson || voters[toVoter].voted) return ;
        voters[toVoter].weight = 1;
    }

    /// Delegate your vote to the voter $(to).//Delegate your vote 
    function delegate (address to) public {
        Voter storage sender = voters[msg.sender]; // assigns reference  指定参数
        if (sender.voted) return;
        while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
            to = voters[to].delegate;
        if (to == msg.sender) return;
        sender.voted = true;
        sender.delegate = to;
        Voter storage delegateTo = voters[to];
        if (delegateTo.voted)
            proposals[delegateTo.vote].voteCount += sender.weight;
        else
            delegateTo.weight += sender.weight;
    }

    /// Give a single vote to proposal $(toProposal). //Vote for a proposal 
    function vote(uint8 toProposal) public {
        Voter storage sender = voters[msg.sender];
        if (sender.voted || toProposal >= proposals.length) return;
        sender.voted = true;
        sender.vote = toProposal;
        proposals[toProposal].voteCount += sender.weight;
    }

    function winningProposal() public constant returns (uint8 _winningProposal) {
        uint256 winningVoteCount = 0;
        for (uint8 prop = 0; prop < proposals.length; prop++)
            if (proposals[prop].voteCount > winningVoteCount) {
                winningVoteCount = proposals[prop].voteCount;
                _winningProposal = prop;
            }
    }
}

 You can try it under run.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326530584&siteId=291194637