I've heavily piggy-backed off of OpenZeppelin's NFT contract to create a custom contract. I don't want to go into too much details around what the contract does.
The issue that I'm having is with deployment and contract calls.
I'm able to deploy the contract to both Ganache and HardHat's localhost. After which I can make contract calls with no problems.
The issue comes up when I try to deploy to Polygon.
Here's a link to the most recent contract I deployed. https://polygonscan.com/address/0x04b4bA0CCd2970780d12605Db30bBC234D2734BA
It seems to be empty?
I then try and run a contract function batchSafeMint
. Which, again, works completely fine on localhost and ganache. On Polygon, it seems to be working fine as well.
function batchSafeMint(address[] memory receivers, string[] memory uris) public radicalWalletOnly {
uint num_receivers = receivers.length;
for (uint i = 0; i < num_receivers; i++) {
if (receivers[i] != deployer && receivers[i] != vendor) {
if (balanceOf(receivers[i]) > maxPerks) {
continue;
}
}
uint256 tokenId = _nextTokenId++;
_safeMint(receivers[i], tokenId);
_setTokenURI(tokenId, uris[i]);
}
}
After this call I try calling the token uri function tokenURI
which then returns 2023-12-18T23:39:45.156Z error: Error: could not decode result data (value="0x", info={ "method": "tokenURI", "signature": "tokenURI(uint256)" }, code=BAD_DATA, version=6.9.0)
I'm not sure what I'm doing wrong here. After Googling around, seems like most people who hit this issue was due to selecting the wrong network. I double checked that the network on the ethers objects was all set to Polygon. I also set the environment variable HARDHAT_NETWORK to polygon.
I'm calling the scripts to deploy, mint, etc... with HardHat's run command.
Here' the deploy function
require('dotenv').config()
const { getOwner } = require('./helpers/getContractOwner')
const getTxOptions = require('./helpers/getTxOptions')
const logger = require('../../lib/logger')
const deployPerk = async (hre, contractName, contractSymbol, contractReward, baseUri, vendorAddress) => {
logger.info(`contract name: ${contractName}`)
logger.info(`contract symbol: ${contractSymbol}`)
logger.info(`contract reward: ${contractReward}`)
logger.info(`baseUri: ${baseUri}`)
logger.info(`vendor address: ${vendorAddress}`)
try {
const owner = await getOwner(hre)
const contract = await hre.ethers.deployContract(
'Perks', [vendorAddress, contractName, contractSymbol, baseUri, contractReward], owner)
const contractAddress = contract.target
const txHash = contract.deploymentTransaction().hash
return { contractAddress, txHash, rType: 'deploy-perk' }
} catch (error) {
logger.error(error.toString())
return { contractAddress: null, txHash: null, rType: 'deploy-perk', error: error.toString() }
}
}
module.exports = deployPerk
And the batchSafeMint script...
require('dotenv').config()
const getTxOptions = require('./helpers/getTxOptions')
const { getOwner, getContract } = require('./helpers/getContractOwner')
const logger = require('../../lib/logger')
const mintPerks = async (hre, contractAddress, toAddresses, uris) => {
logger.info(`contractAddress: ${contractAddress}`)
logger.info(`toAddresses: ${JSON.stringify(toAddresses)}`)
logger.info(`uris: ${JSON.stringify(uris)}`)
try {
const owner = await getOwner(hre)
const contract = await getContract(hre, contractAddress, owner)
const txOptions = await getTxOptions(10000000)
txOptions.nonce = await hre.ethers.provider.getTransactionCount(owner.address)
let tx = await contract.connect(owner).batchSafeMint(toAddresses, uris, txOptions)
const txHash = tx.hash
// let tx = await contract.tokenURI(0)
// console.log(tx)
// let wtx = await tx.wait()
// console.log(wtx)
return { txHash, rType: 'mint-perks' }
} catch (error) {
logger.error(error.toString())
return { txHash: null, rType: 'mint-perks', error: error.toString() }
}
}
module.exports = mintPerks
and this is how I'm getting the contract for contract calls
const getContract = async (hre, contractAddress, owner) => {
try {
const contractABI = await JSON.parse(fs.readFileSync(path.join(dirname, `/factory/artifacts/contracts/Perks.sol/Perks.json`), 'utf-8'))
// console.log(contractABI.abi)
const contract = await new hre.ethers.Contract(contractAddress, contractABI.abi, owner)
// const contract = await hre.ethers.getContract(hre, contractAddress, owner)
// console.log(owner)
// const contract = await hre.ethers.getContractAt(contractABI.abi, contractAddress, owner)
return contract
} catch (error) {
logger.error(error.toString())
return null
}
}
Any ideas around this would be much appreciated!