MyToken Uncaught ReferenceError: MINTER_ROLE is not defined

I am learning Access Control and testing MyToken.sol
I use truffle console to test it and encountered error when testing hasRole() function. Please see below…

:computer: Environment

OpenZeppelin 3.x MyToken.sol & Access Control example code

Truffle v5.1.53 (core: 5.1.53)
Solidity - ^0.6.0 (solc-js)
Node v14.15.1
Web3.js v1.2.9

:memo:Details

I encountered error below…

truffle(development)> token=await MyToken.deployed()
undefined
truffle(development)> token.hasRole(MINTER_ROLE,accounts[1])
-- got messages below --
evalmachine.<anonymous>:0
token.hasRole(MINTER_ROLE,accounts[1])
              ^
Uncaught ReferenceError: MINTER_ROLE is not defined
    at evalmachine.<anonymous>:0:15
    at sigintHandlersWrap (vm.js:272:15)
    at Script.runInContext (vm.js:139:14)
    at runScript (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:251:1)
    at Console.interpret (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:266:1)
    at bound (domain.js:430:14)
    at REPLServer.runBound [as eval] (domain.js:443:12)
    at REPLServer.onLine (repl.js:817:10)
    at REPLServer.emit (events.js:315:20)
    at REPLServer.EventEmitter.emit (domain.js:486:12)

 truffle(development)> token.hasRole(token.MINTER_ROLE,accounts[1])
-- got messages below --
Uncaught TypeError: param.substring is not a function
    at evalmachine.<anonymous>:0:7
    at sigintHandlersWrap (vm.js:272:15)
    at Script.runInContext (vm.js:139:14)
    at runScript (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:251:1)
    at Console.interpret (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:266:1)
    at bound (domain.js:430:14)
    at REPLServer.runBound [as eval] (domain.js:443:12)
    at REPLServer.onLine (repl.js:817:10)
    at REPLServer.emit (events.js:315:20)
    at REPLServer.EventEmitter.emit (domain.js:486:12)
    at REPLServer.Interface._onLine (readline.js:337:10)
    at REPLServer.Interface._line (readline.js:666:8)
    at REPLServer.Interface._ttyWrite (readline.js:1010:14)
    at REPLServer.self._ttyWrite (repl.js:907:9)
    at ReadStream.onkeypress (readline.js:213:10)
    at ReadStream.emit (events.js:315:20)
    at ReadStream.EventEmitter.emit (domain.js:486:12)
    at emitKeys (internal/readline/utils.js:345:14)
    at emitKeys.next (<anonymous>)
    at ReadStream.onData (readline.js:1144:36)
    at ReadStream.emit (events.js:315:20)
    at ReadStream.EventEmitter.emit (domain.js:486:12)
    at addChunk (_stream_readable.js:309:12)
    at readableAddChunk (_stream_readable.js:284:9)
    at ReadStream.Readable.push (_stream_readable.js:223:10)
    at TTY.onStreamRead (internal/stream_base_commons.js:188:23)
    at TTY.callbackTrampoline (internal/async_hooks.js:129:14) {
  hijackedStack: 'TypeError: param.substring is not a function\n' +
    '    at ABICoder.formatParam (/usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/src/index.js:280:1)\n' +
    '    at /usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/src/index.js:117:1\n' +
    '    at Array.map (<anonymous>)\n' +
    '    at ABICoder.encodeParameters (/usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth-abi/src/index.js:105:1)\n' +
    '    at /usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/src/index.js:531:1\n' +
    '    at Array.map (<anonymous>)\n' +
    '    at Object._encodeMethodABI (/usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/src/index.js:530:10)\n' +
    '    at Object._processExecuteArguments (/usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/src/index.js:855:1)\n' +
    '    at Object._executeMethod (/usr/lib/node_modules/truffle/build/webpack:/node_modules/web3-eth/node_modules/web3-eth-contract/src/index.js:880:1)\n' +
    '    at /usr/lib/node_modules/truffle/build/webpack:/packages/contract/lib/execute.js:143:1\n' +
    '    at processTicksAndRejections (internal/process/task_queues.js:93:5)'
}

:1234: Code to reproduce

// contracts/MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20, AccessControl {
    // Create a new role identifier for the minter role
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(address minter) public ERC20("MyToken", "TKN") {
        // Grant the minter role to a specified account
        _setupRole(MINTER_ROLE, minter);
    }

    function mint(address to, uint256 amount) public {
        // Check that the calling account has the minter role
        require(hasRole(MINTER_ROLE, msg.sender), "Caller is not a minter");
        _mint(to, amount);
    }
}

// 2_deploy.js
const MyToken = artifacts.require("MyToken");
module.exports = async function (deployer) {
  await deployer.deploy(MyToken,'0xb7fgfgfggg......');
};
1 Like

Hi @qoopme,

When accessing the MINTER_ROLE externally, we need to use the getter for the MINTER_ROLE constant. The compiler automatically creates getter functions for all public state variables, (see: https://docs.soliditylang.org/en/latest/contracts.html#getter-functions).

So rather than token.MINTER_ROLE we need to use token.MINTER_ROLE().

You can try this out in the console and see the difference in the values.

I tried ....
truffle(development)> token.hasRole(token.MINTER_ROLE(),accounts[1])
got error

another tried and it works

truffle(development)> await token.hasRole(await token.MINTER_ROLE(), accounts[0])
'false'

Finally I can move on learning openzeppelin
Thanks very much !

1 Like

Hi @qoopme,

You could also have a look at: Create an ERC20 using Truffle, without writing Solidity for some of the interaction via the console.

Also the OpenZeppelin Learn guides: https://docs.openzeppelin.com/learn/

Feel free to create new topics to ask any questions.

1 Like