Environment
environment:Hardhat, solidity compiler version 0.8.1, ethers js, windows 10, node version 12.13.1, npm 7.8.0
Details
I am creating a mintable erc721 token that requires a new minter to verify a signature generated by an existing minter following this workshop repository https://github.com/OpenZeppelin/workshops/tree/master/06-nft-merkle-drop.
the test failed with the error “only_existing_minter” in the contract required check.
Code to reproduce
solidity code:
constructor()
ERC721("My NFT", "MyNFT")
EIP712("MYNFT", "1.0.0")
{}
function _hash(
address newArtist,
uint256 nonce
) public view returns (bytes32) {
return
_hashTypedDataV4(keccak256(abi.encode(
keccak256("Register(address newArtist,uint256 nonce)"),
newArtist,
nonce
)));
}
function _verify(bytes32 digest, bytes memory signature)
private
pure
returns (address)
{
return ECDSA.recover(digest, signature);
}
// serve as the verifyNewMinter function
// signature is generated by existing minter (wallet address of new minter and the nonce, usually 1 as the message object)
// msgSender is the new minter
function register(
bytes calldata signature
) external {
require(nonces[_msgSender()]==0, "user_exist");
address signer =
_verify(_hash(_msgSender(), nonces[_msgSender()]++), signature);
require(signer != address(0), "address_0");
require(isMinter[signer], "only_existing_minter");
_addMinter(_msgSender(), payable(signer));
}
javascript code:
const overrides = {
gasLimit: 9999999,
};
const domain = {
name: "MYNFT",
version: "1.0.0",
chainId: 1,
verifyingContract: myNft.address,
};
const types = {
Register: [
{ name: "newArtist", type: "address" },
{ name: "nonce", type: "uint256" },
],
};
const nonce = 1;
const values = { other1.address, nonce };
const signature = await other0._signTypedData(domain, types, values);
console.log("Signature: ", signature);
await myNft.connect(other1).register(signature, overrides);
// other0 is an existing minter