Search code examples
ethereumsolidityopenzeppelin

totalsupply() is not a function openzeppelin contracts


I'm trying to import some contract files from open zeppelin so my solidity smart contracts can inherit their functionality, when trying to write chai tests that run on my smart contracts at compile time I get an error in my chai test.

  3 passing (2s)
  1 failing

  1) Contract: Color
       minting
         creates a new token:
     TypeError: contract.totalSupply is not a function

my contract importing the openzeppelin contracts

pragma solidity 0.8.7;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; //import base functionality
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; //import totalsupply()

contract color is ERC721 {
    string[] public colors;
    mapping(string => bool) _colorExists; //mappings are like json objects where value a is searched and its value is returned
    constructor() ERC721("Color", "COLOR") {
    }

    function mint(string memory _color) public{
      colors.push(_color);
      uint _id = colors.length -1;

      _mint(msg.sender,_id);
      _colorExists[_color] = true;
 
    }
}

and lastly my test file ( I have shortened it to show only the test giving me errors)

const { assert } = require('chai')
const Color = artifacts.require('./Color.sol')

require('chai')
.use(require('chai-as-promised'))
.should()

contract('Color', (accounts) =>{
    let FormControlStatic

    before(async ()=>{
        contract = 
        await Color.deployed()
    })
    
    describe('minting', async ()=>{
        
        it('creates a new token', async ()=>{
            const result = await contract.mint('#EC058E')
            console.log(result)
            const totalSupply = await contract.totalSupply()

            assert.equal(totalSupply,1)
            console.log(result)
        })
    })
})

also if we look at the file containing the function totalSupply() it is publicly scoped so it should be visible outside the function via import

I did some digging and imported the file that the actual function IS in from openzeppelin however it seems that I still get the same error, I tried compiling separately to see if recompiling after changing would resolve but it didn't

not sure if anyone else has gone through this recently or might have a solution also I'm importing the current version here https://www.npmjs.com/package/@openzeppelin/contracts

thanks!


Solution

  • Below is a complete implementation of the smart contract.

    As you mentioned in the question, it uses newer versions than the tutorial:

    • Solidity (0.8.0)
    • Open Zeppelin (4.3.2)
    pragma solidity ^0.8.0; // Note that this is using a newer version than in 
    
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
    
    
    contract Color is ERC721, ERC721Enumerable {
        string[] public colors;
        mapping(string => bool) _colorExists;
    
        constructor() ERC721("Color", "COLOR") public {
        }
    
        function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        override(ERC721, ERC721Enumerable)
        {
            super._beforeTokenTransfer(from, to, tokenId);
        }
    
        function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
        {
            return super.supportsInterface(interfaceId);
        }
    
    
        function mint(string memory _color) public {
            colors.push(_color);
            uint _id = colors.length - 1;
            _mint(msg.sender, _id);
            _colorExists[_color] = true;
        }
    }
    
    
    

    You can also take a look at OpenZeppelin's section about Extending Contracts to learn about overrides and super.