I want to test the following contract.
The contract contracts/Token.sol is using ERC721 contract and Open Zeppelin architecture.
And I wrote the test code test/Token.js following but I ran the truffle test, the transaction was reverted, and said Error: Returned error: VM Exception while processing transaction: revert. await proxy.methods.mint().send({from: sender}) has some problem.
How do I test the ERC721 minting function?
Thank you!
contracts/Token.sol
pragma solidity ^0.5.8;
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/upgrades/contracts/Initializable.sol";
contract Token is Initializable, ERC721Full {
string public tokenName;
uint256 internal nextTokenId;
function mint() external {
uint256 tokenId = nextTokenId;
nextTokenId = nextTokenId.add(1);
super._mint(msg.sender, tokenId);
}
function initialize(string memory _tokenName) public {
tokenName = _tokenName;
nextTokenId = 0;
}
function setTokenURI(uint256 _tokenId, string calldata _message) external {
super._setTokenURI(_tokenId, _message);
}
}
test/Token.js
const { TestHelper } = require('@openzeppelin/cli');
const { Contracts, ZWeb3 } = require('@openzeppelin/upgrades');
ZWeb3.initialize(web3.currentProvider);
const ABNToken = Contracts.getFromLocal('ABNToken');
const tokenName = "start";
web3.eth.getAccounts(function(error, result) {
if (error) console.log("Couldn't get accounts")
sender = result[0]
})
require('chai').should();
contract('ABNToken', function () {
let proxy
beforeEach(async function () {
this.project = await TestHelper();
proxy = await this.project.createProxy(ABNToken);
proxy.options.from = sender;
await proxy.methods.initialize(tokenName).send({from: sender});
})
it('Initialize function test', async function () {
let tokenname = await proxy.methods.tokenName().call();
tokenname.should.eq(tokenName);
})
it('Mint function test', async function () {
console.log(proxy.methods)
await proxy.methods.mint().send({from: sender})
})
})
function mint(address to, uint256 tokenId) public onlyMinter returns (bool) {
_mint(to, tokenId);
return true;
}
So this is as far as i understand the interface of mint needing to params. To equals to recipient address and tokenId is uint256. So you only have one param in you call.
First test the method of the original interface:
mint( sender, unint265(1234)) … Using this should work. So may do this as the first test
Ok, you have made your own defintion of mint without params:
Rename you definition to something like createToken and then test it again. So this insures you don’t get wired when reading error messages.
Then if the first version works, but the second not, then you may start with createToken as a wapper around your the orignal mint interface.
But dependant what you like to archive with you project, there is probably no reason to write your own version of mint, because everything you like can be prepared in test/JavaScript environment.
Second advice, don’t start with ERC721 full when learning. Start with the base contract and go for there.
In case you are a beginner, I would not start with upgradable contracts in the first place. Just take the openZeppelin without it. This makes it easier to lean ERC721 stuff first, then It is a short way to include upgradabel stuff to it.
So may be strip this code down to the basics and go from there.
Hope this helps a little bit. I payed a lot of time starting with the same approach…
Just a quick answer here (on mobile)looks like nothing is being initialized- so the contract doesn’t even have any minters assigned, hence it won’t let you mint.
Look into the contracts that ERC721 inherits from, each one of them needs to be initialized. So for example have a look at one of m contracts:
Here I create an erc721 token, but I initialize all the contracts I inherit from in a initialize function.
My example is a little more than you need- but there is also a simple test in the file. Maybe that will set you in the right direction!