I am interacting with an OpenZeppelin ERC-1155 contract of this form: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol, which is implementing AccessControl
per this doc: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol.
I use hardhat, and the contract is deployed onto ropsten
network using my PUBLIC_KEY
. On the server side, I am able to load this contract and interact with it using my PUBLIC_KEY
. The following code successfully mint
with this command:
npx hardhat run scripts/index.js --network ropsten
function main(){
const accounts = await ethers.provider.listAccounts();
let [ PUBLIC_KEY ] = accounts;
const Contract1155 = await ethers.getContractFactory("ERC1155PresetMinterPauser");
const nft = await Contract1155.attach('...');
await nft.mint(PUBLIC_KEY,2,3453,'0x00');
await nft.mintBatch( PUBLIC_KEY, [1,2], [101,201], '0x00');
}
main();
However when I load the contract on the browser, with the same PUBLIC_KEY
from my Metamask
wallet, I get the following error:
index.js:50 Uncaught (in promise) Error: execution reverted: ERC1155PresetMinterPauser: must have minter role to mint
{
"originalError": {
"code": 3,
"data": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000038455243313135355072657365744d696e7465725061757365723a206d7573742068617665206d696e74657220726f6c6520746f206d696e740000000000000000",
"message": "execution reverted: ERC1155PresetMinterPauser: must have minter role to mint"
}
}
This is despite the fact that I can confirm PUBLIC_KEY
does have minter
access on the browser. Below is how I initiated web3
in the browser:
import Web3 from 'web3'
import detectEthereumProvider from '@metamask/detect-provider';
const Contract_115 = require('../../ERC1155PresetMinterPauser.json')
function maybe_mint(){
let ethereum = await detectEthereumProvider()
let web3 = new Web3(ethereum)
let abi = Contract_115.abi
let ropsten_address = '0x...';
const contract = new web3.eth.Contract(abi, ropsten_address);
// this is the same PUBLIC_KEY as the server side.
let accts = await web3.eth.getAccounts()
let PUBLIC_KEY = accts[0]
let MINTER = await contract.methods.MINTER_ROLE().call();
// this code says that `PUBLIC_KEY` does have minter privlidge
let pk_is_minter = await contract.methods.hasRole(MINTER,PUBLIC_KEY).call();
console.log('PUBLIC_KEY is minter: ', pk_is_minter) // returns true
// this fails with error: account does not have minter prilidge
const fn = contract.methods.mintBatch( PUBLIC_KEY, [1,2], [301,901], '0x00');
let gas = await fn.estimateGas();
}