EVM Errors – Solving ‘Error: Transaction has Been Reverted by the EVM’ in Solidity

erc-20solidityweb3js

Could anyone point me at what is the problem here?

I tried to send ERC20 tokens by using ERC20 trasferFrom function.
I have executed a sendSignedTransaction and got an error as follows:

Error: Transaction has been reverted by the EVM:
{
  "blockHash": "0xf8c3f5d7552bce0c3191160af6bedd1dccdee15de1605301d225b54d84bc219c",
  "blockNumber": 5432016,
  "contractAddress": null,
  "cumulativeGasUsed": 576475,
  "from": "0xc17fe972be596e119d7e51270f1c7d3bda726db9",
  "gasUsed": 30631,
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "status": false,
  "to": "0x6c9ba85bb7d0acba49aa13e1882565efd823a4c9",
  "transactionHash": "0x338a60122583f3aff3c797dfd8fe5c25b8201ec1d1baff76af0a140dea20f8ce",
  "transactionIndex": 3
}
    at /Users/gemcutter/demo_peak/node_modules/web3-core-method/src/index.js:364:46
    at process._tickCallback (internal/process/next_tick.js:68:7)````

the execution code is as follows:

    var tx=myContract2.methods.transferFrom(from,to,amount)
    var encodedTx = tx.encodeABI();

    tx.estimateGas({to:to, data:encodedTx, from:approved}).then((gasAmount) => {
    console.log('app.js: estimated gas: ' + gasAmount.toString(10));

        web3.eth.getTransactionCount(from).then(_nonce => {
            nonce = web3.utils.toHex(_nonce);
            console.log('app.js: tx nonce: ' + nonce + ' at account[0]: ' + to);

            var tx = new ethTx({
                nonce: nonce,
                gasPrice: gasPrice,
                gasLimit: gasLimit,
                from: approved,
                to: contract2Addr,
                data: encodedTx
            },{chain: 'rinkeby' , hardfork: 'petersburg'});

            tx.sign(privKey);
            var signedRawTx = '0x' + tx.serialize().toString('hex');

            web3.eth.sendSignedTransaction(signedRawTx)
            .on('receipt', receipt => {
                console.log('app.js: signed tx receipt:\n' + JSON.stringify(receipt));
                console.log('Successfully transferred a token!');
            }).catch((err) => {
                console.log(err);
            });
        });
    }).then((result) => {
        console.log('Transfered tokens:'+JSON.stringify(result));
    }).catch((err) => {
        console.log('ERROR: app.js: Gas Estimate failed');
        console.log(err);
    });

The smart contract is as follows:

    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = balances[from].sub(tokens);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        emit Transfer(from, to, tokens);
        return true;
    }

The contract was successfully deployed.

I use following versions.
Truffle v5.0.3,
web3@1.0.0-beta.37,
node.js v10.16.0

I checked etherscan.io, but do not know how to deal with it.

Best Answer

Possible reason #1:

balances[from] = balances[from].sub(tokens);

This line would revert if balances[from] < tokens.


Possible reason #2:

allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);

This line would revert if allowed[from][msg.sender] < tokens.

In order to avoid that, you must first call approve(from,tokens).


Possible reason #3:

balances[to] = balances[to].add(tokens);

This line would revert if ~uint256(0) - balances[to] < tokens.


My guess is that your function-call reverts due to reason #2.