Невозможно вызвать контракт OpenZeppelin с AccessControl, установленным для функции mint, даже если у учетной записи есть права администратора.
Я взаимодействую с контрактом OpenZeppelin ERC-1155 этой формы: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol, который реализует
AccessControl
согласно этому документу: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol.
Я использую каску, и контракт развертывается на
ropsten
сеть с использованием моего. На стороне сервера я могу загрузить этот контракт и взаимодействовать с ним, используя мой. Следующий код успешно
mint
с помощью этой команды:
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();
Однако, когда я загружаю контракт в браузере, то же самое из моего
Metamask
кошелек, я получаю следующую ошибку:
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"
}
}
Это несмотря на то, что я могу подтвердить
PUBLIC_KEY
имеет
minter
доступ в браузере. Вот как я инициировал
web3
в браузере:
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();
}