'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 1:[1]
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
.
Solution 2:[2]
We must extend IERC721Enumerable
contracts, and, implements its virtual functions.
contract Color is ERC721, IERC721Enumerable { // We must extends IERC721Enumerable
string[] public colors;
mapping(string => bool) _colorExists;
constructor() ERC721("Color", "COLOR") {}
function mint(string memory _color) public {
colors.push(_color);
uint256 _id = colors.length - 1;
// _mint(msg.sender,_id);
_colorExists[_color] = true;
}
// And must override below three functions
function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
// You need update this logic.
// ...
return 3;
}
function totalSupply() external view override returns (uint256) {
// You need update this logic.
// ...
return 1;
}
function tokenByIndex(uint256 index) external view override returns (uint256) {
// You need update this logic.
// ...
return 5;
}
}
Then, we can call totalSupply()
method
Solution 3:[3]
You can follow these following steps to continue the tutorial.
- First create a new contract file with ERC721Enumerable:
./node_modules/.bin/truffle-flattener ./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol > contracts/ERC721Enumerable.sol
- Second replace old ERC721 with new ERC721Enumerable:
import "./ERC721Enumerable.sol";
contract Color is ERC721Enumerable {
//
}
- Delete old ERC721Full.sol files under the contracts folder.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 |