1

I don't have any programming language experience. But i'm interested to learn how to create my own ERC20 token and it was sucessfully deployed without any error using remix ethereum. But, once i'm trying to copy-pasteing another source code with more functions, then the supply become N/A, and this leads me to try using truffle and openzeppelin. Thousand of errors coming up during compiling but now everything works. Just when i tried to do

truffle migrate --reset

it shows this error message:

2_deploy_token.js
=================

Error:  *** Deployment Failed ***

"VrapzCoin" is an abstract contract or an interface and cannot be deployed.

   * Import abstractions into the '.sol' file that uses them instead of deploying them separately.
   * Contracts that inherit an abstraction must implement all its method signatures exactly.
   * A contract that only implements part of an inherited abstraction is also considered abstract.

    at Deployer._preFlightCheck (/usr/local/lib/node_modules/truffle/build/webpack:/packages/deployer/src/deployment.js:178:1)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at /usr/local/lib/node_modules/truffle/build/webpack:/packages/deployer/src/deployment.js:281:1
    at Migration._deploy (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/migration.js:70:1)
    at Migration._load (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/migration.js:57:1)
    at Migration.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/migration.js:167:1)
    at Object.runMigrations (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:148:1)
    at Object.runFrom (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:110:1)
    at Object.runAll (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:114:1)
    at Object.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:79:1)
    at runMigrations (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate.js:253:1)
    at /usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate.js:218:1
Truffle v5.1.20 (core: 5.1.20)
Node v13.12.0

and this is my VrapzCoin.sol looks like:

pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
//import "openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol"; //this one was already included on ERC20.sol
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";

contract VrapzCoin is ERC20, ERC20Detailed, ERC20Mintable {

}

And here's the rest:

ERC20.sol

pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./IERC20.sol";
///import "../../math/SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20Mintable}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20Basic {
  uint256 public totalSupply;
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

library SafeMath {

  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}


contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value > 0);
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  function balanceOf(address _owner) public view returns (uint256 balance) {
    return balances[_owner];
  }

}

contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) public view returns (uint256);
  function transferFrom(address from, address to, uint256 value) public returns (bool);
  function approve(address spender, uint256 value) public returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}



contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) internal allowed;


  function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    require(_value > 0);
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }

  function approve(address _spender, uint256 _value) public returns (bool) {
    require(_value > 0);
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint256) {
    return allowed[_owner][_spender];
  }

  function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
    require(_addedValue > 0);
    allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
    require(_subtractedValue > 0);
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

contract BurnableToken is BasicToken {

  event Burn(address indexed burner, uint256 value);

  function burn(uint256 _value) public {
    require(_value > 0);
    require(_value <= balances[msg.sender]);

    address burner = msg.sender;
    balances[burner] = balances[burner].sub(_value);
    totalSupply = totalSupply.sub(_value);
    emit Burn(burner, _value);
  }
}

ERC20Detailed.sol

pragma solidity ^0.5.0;

import "./IERC20.sol";

/**
 * @dev Optional functions from the ERC20 standard.
 */
contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
     * these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = 'VrapzCoin';
        _symbol = 'VRZ'';
        _decimals = 2;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }
}

ERC20Mintable.sol

pragma solidity ^0.5.0;

import "./ERC20.sol";
import "../../access/roles/MinterRole.sol";

/**
 * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},
 * which have permission to mint (create) new tokens as they see fit.
 *
 * At construction, the deployer of the contract is the only minter.
 */
contract ERC20Mintable is ERC20, MinterRole {
    /**
     * @dev See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the {MinterRole}.
     */
    function mint(address account, uint256 amount) public onlyMinter returns (bool) {
        mint(account, amount);
        return true;
    }
}

I've seen the step-by-step tutorial which the constructor should be added on my own .sol files which is VrapzCoin.sol, but here's i found it already on ERC20Detailed.sol. So, i set it right there to my own.

And this is my deploy_token.js looks like:


module.exports = function(deployer){

    deployer.deploy(VrapzCoin);
};

It's been my 3rd day to learn these stuffs. And i can't even make it.

I hope someone can point out where's the mistake ...

11
  • 4
    I'm voting to close this question as off-topic because the purpose here is to answer technical questions with some minimum knowledge and understanding of the person who's asking, not to teach from scratch the basics of one technology or another. Answering such questions will not really help that person understanding the basic concepts, nor will it contribute to this website, since various similar questions have already been answered here several times before. Apr 12 '20 at 11:54
  • 1
    I've read some tutorials and i'm not able to follow it that way. If you can't help just don't write anything or atleast give a referrence to all explanation so i can learn it myself. Imagine if everyone in this world with that mindset. Those who smart will get smarter and those who stupid will never be smart with your words. I've found few topics related but different circumstances. Just close it if this a trash topic then.
    – NOZR
    Apr 12 '20 at 12:10
  • 1
    If i didn't read some tutorials and etc, how do you think i can go this far? Nevermind you,re just too smart or maybe you're the smartest in this forum. @goodvibration, anyway thanks for your response.
    – NOZR
    Apr 12 '20 at 12:14
  • 1
    If i as smart as you're. I would just highlight the wrong syntax which is only "declared" but not yet "implemented" and then i'll add: "this is why it's an abstract contract because this function has been declared but not implemented yet".
    – NOZR
    Apr 12 '20 at 12:56
  • 1
    But let's just cut it here. Stop wasting your time. I'll just learn it myself. Thanks a lot for the response once again.
    – NOZR
    Apr 12 '20 at 12:57
3

ERC20Detailed's constructor receives three parameters to use ERC20Detailed you should pass those three parameters.

The problem is that VrapzCoin inherits from ERC20Detailed and never initializes it correctly.

Since those parameters are not used you can remove them, and the contract should compile

constructor() public {
    _name = 'VrapzCoin';
    _symbol = 'VRZ';
    _decimals = 2;
}

Note: Probably there's something else wrong in your setup since that should be a compiler error.

3
  • So, that those 3 parameters should be added to VrapzCoin.sol instead? I start figuring out where's my mistake. ERC20Detailed parameters should be added to deploy_token.js I think. When i compile the main contract it's successfully completed. Isn't that means there's no anything wrong with the setup? Anyway, thanks for the answer. Highly appreciated! But I'll try to restart all over again and make a basic one step-by-step before jumping to ERC20Detailed, ERC20Burnable, and etc.
    – NOZR
    Apr 13 '20 at 3:39
  • @NOZR I see two possible solutions: 1) remove the parameters from ERC20Detailed since they are not used (my suggestion above); 2) use those parameters instead of the hardcoded values, then you need to modify VrapzCoin constructor to pass those parametsr to ERC20Detailed. You do not need to modify deploy_token.js in both cases. A third solution is to add those parameters to VrapzCoin constructor and then pass them to ERC20Detailed (in this case you have to modify deplo_token.js).
    – Ismael
    Apr 13 '20 at 3:58
  • Alright. Thanks a lot, i really appreciate your help!
    – NOZR
    Apr 13 '20 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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