I compiled and migrated my solidity codes of erc20 token to development networks on truffle, and use it on truffle console.

truffle(development)> let instance = await XToken.deployed()
truffle(development)> let accountsArray = await web3.eth.getAccounts()
truffle(development)> instance.sendTxAndMessage(accountsArray[1], accountsArray[2], 60, "Hi!")

Then, I got error below:

Error: Returned error: VM Exception while processing transaction: revert
at XMLHttpRequest._onHttpResponseEnd (/Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request.js:318:1)
at XMLHttpRequest._setReadyState (/Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request.js:208:1)
at XMLHttpRequestEventTarget.dispatchEvent (/Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)
at XMLHttpRequest.request.onreadystatechange (/Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/web3/~/web3-providers-http/src/index.js:96:1)
at /Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/packages/truffle-provider/wrapper.js:112:1
at /Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/web3-eth/~/web3-core-requestmanager/src/index.js:140:1
at Object.ErrorResponse (/Users/user/.nodebrew/node/v10.9.0/lib/node_modules/truffle/build/webpack:/~/web3-eth/~/web3-core-helpers/src/errors.js:29:1)

So, does someone know how to handle this error?

Here is my solidiy code and truffle-config.js


pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol;

contract XToken is ERC20, Ownable {
    using SafeMath for uint8;
    using SafeMath for uint256;

    string public constant name = "XToken";
    string public constant symbol = "XTN";
    uint256 public constant decimals = 8;
    uint256 public _totalSupply = 5000000;

    mapping(address => uint) balances;
    mapping(address => string) public  receivedMessage;
    mapping(address => string) public  sentMessage;

    constructor (uint256 _initialSupply) public {
        balances[msg.sender] = _initialSupply;

    function airdrop(address _to, uint256 _value) public onlyOwner returns (bool) {
        transfer(_to, _value);
        return true;

    function sendTxAndMessage(address _from, address _to, uint256 _value, string memory _calldata) public returns (bool) {
        transferFrom(_from, _to, _value);
        sentMessage[_from] = _calldata;
        receivedMessage[_to] = _calldata;
        return true;

    function fetchReceivedMessage(address _to) public view returns (string memory) {
        return receivedMessage[_to];

    function fetchSentMessage(address _from) public view returns (string memory) {
        return sentMessage[_from];  



const HDWalletProvider = require('truffle-hdwallet-provider');

module.exports = {
  networks: {
    development: {
      host: "",     // Localhost (default: none)
      port: 7545,            // Standard Ethereum port (default: none)
      network_id: "*",       // Any network (default: none)

And also, my environment is: Truffle v5.0.5 (core: 5.0.5) Solidity v0.5.0 (solc-js) Node v10.9.0

Thanks in advance!

  • These are the reasons for the revert.require(value <= _balances[from]); require(value <= _allowed[from][msg.sender]); require(to != address(0)); Can you confirm these conditions? Mar 1, 2019 at 6:47
  • this could take a while to debug but if you want to message me, I will help you through every step of the way Mar 1, 2019 at 16:55
  • @Lucas Rodriguez Benitez where to msg you.
    – mzaidi
    Apr 17, 2021 at 23:00

1 Answer 1


The problem is with transferFrom, it is declared as external in ERC20.

When you execute sendTxAndMessage

     transferFrom(_from, _to, _value);

It is equivalent to an external call

     ERC20(address(this)).transferFrom(_from, _to, _value);

Then inside trasnferFrom you will have that msg.sender is the token address. So the call will fail if _from have not authorized it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.