You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

以太坊主网EVM交易回滚问题咨询:Rinkeby正常的ERC721A合约主网调用失败

ERC721A Contract Reverts on Ethereum Mainnet (Works on Rinkeby)

Hey there, let’s troubleshoot why your mint transaction is getting reverted on mainnet even though it worked perfectly on Rinkeby. Let’s break down your setup and walk through the most likely fixes.

Your Contract Code

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/access/Ownable.sol";
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract Basic is ERC721A, Ownable {
 using Strings for uint256;
 string private BaseURI;

 constructor() ERC721A("NAME", "SYMBOL") {
 BaseURI = "ipfs://...";
 }

 function _startTokenId() internal view virtual override returns (uint256) {
 return 1;
 }

 function setBaseURI(string memory _uri) external onlyOwner {
 BaseURI = _uri;
 }

 function tokenURI(uint256 _tokenId) public view override returns (string memory) {
 require(_exists(_tokenId), "tokenURI : nonexistent token");
 return string(
 abi.encodePacked(
 BaseURI, "/", Strings.toString(_tokenId), ".json"
 )
 );
 }

 function mint(address _address, uint256 quantity) external onlyOwner {
 _mint(_address, quantity);
 }
}

Your Interaction Code

const Web3 = require("web3");
var contractInfo;
var owner_pk;
var owner_address;
var RPC;
const INV = {
 Ganache: 0,
 Rinkeby: 1,
 Mainnet: 2,
};
const TEST_INV = INV.Mainnet;
// ...省略其他环境配置
} else if (TEST_INV == INV.Mainnet) {
 contractInfo = require("./mainnet-info.js");
 owner_pk = "............";
 owner_address = "0x1D15A2D8d660bf24Bdf9ddec0F94Cfc5D6d5Ab39";
 RPC = "https://mainnet.infura.io/v3/.......";
}
const web3 = new Web3(new Web3.providers.HttpProvider(RPC));
var contract = new web3.eth.Contract(
 contractInfo.ABI,
 contractInfo.CONTRACT_ADDRESS
);

async function mint(_address, quantity) {
 var functionData = contract.methods.mint(_address, quantity).encodeABI();
 txCount = await web3.eth.getTransactionCount(owner_address, "latest");
 const ntx = {
 to: contractInfo.CONTRACT_ADDRESS,
 gas: 5500000,
 nonce: web3.utils.toHex(txCount),
 data: functionData,
 };
 const signedTx = await web3.eth.accounts.signTransaction(ntx, owner_pk);
 var transactionReceipt;
 web3.eth.sendSignedTransaction(
 signedTx.rawTransaction,
 function (error, hash) {
 if (!error) {
 console.log("The hash of your transaction is: ", hash);
 } else {
 console.log(
 "Something went wrong while submitting your transaction:",
 error
 );
 }
 }
 );
 console.log(`Transaction receipt: ${JSON.stringify(transactionReceipt)}`);
 return "complete";
}
mint("0x1D15A2D8d660bf24Bdf9ddec0F94Cfc5D6d5Ab39", 1);

Error Details

{
 "blockHash": "0xdf1035c5018127732b70ec545cf5ef8286768788173087de64156684a4ad30e2",
 "blockNumber": 15173679,
 "contractAddress": null,
 "cumulativeGasUsed": 2251524,
 "effectiveGasPrice": 62243679156,
 "from": "0x1d15a2d8d660bf24bdf9ddec0f94cfc5d6d5ab39",
 "gasUsed": 22384,
 "logs": [],
 "logsBloom": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
 "status": false,
 "to": "0xa9e27be51a8520b4d794c62cdac8263d2304da05",
 "transactionHash": "0x821f25e88c3ad9dbb55a8782690ca289c69cab0bae1f3412a4916f08a9d8ad0b",
 "transactionIndex": 51,
 "type": "0x0"
}

Key Account & Contract Info

  • Wallet Address: 0x1D15A2D8d660bf24Bdf9ddec0F94Cfc5D6d5Ab39
  • Contract Address: 0xa9e27Be51A8520B4d794c62cDac8263d2304dA05

Troubleshooting Steps

Let’s start with the most probable issues first, since your contract works flawlessly on Rinkeby:

1. Verify Contract Ownership

Your mint function uses the onlyOwner modifier—this is the #1 cause of reverts for owner-restricted functions. You need to confirm that the wallet address you’re using to sign transactions is actually the owner of the mainnet contract.

Run this quick check to confirm:

async function checkContractOwner() {
  const contractOwner = await contract.methods.owner().call();
  console.log("Contract Owner:", contractOwner);
  console.log("Your Wallet:", owner_address);
}
checkContractOwner();

If these addresses don’t match, you deployed the mainnet contract with a different wallet than the one you’re using now—this would immediately trigger a revert.

2. Retrieve the Exact Revert Reason

The biggest clue will be the specific error message the EVM returns. Modify your mint function to catch and parse this:

async function mint(_address, quantity) {
  try {
    const functionData = contract.methods.mint(_address, quantity).encodeABI();
    const txCount = await web3.eth.getTransactionCount(owner_address, "latest");
    const ntx = {
      to: contractInfo.CONTRACT_ADDRESS,
      gas: 5500000,
      nonce: web3.utils.toHex(txCount),
      data: functionData,
    };
    const signedTx = await web3.eth.accounts.signTransaction(ntx, owner_pk);
    const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
    console.log("Transaction Receipt:", receipt);
    return "complete";
  } catch (error) {
    console.error("Revert Error:", error.message);
    // Extract the exact revert reason if available
    if (error.data) {
      const revertReason = web3.eth.abi.decodeParameter('string', error.data.slice(138));
      console.error("Exact Revert Message:", revertReason);
    }
  }
}

This will print messages like Ownable: caller is not the owner which directly points to the problem.

3. Confirm Deployment Consistency

Double-check that you deployed the exact same contract to mainnet as you did on Rinkeby:

  • Ensure the Solidity compiler version matches (you’re using ^0.8.9—no accidental upgrades/downgrades)
  • Verify the ABI in mainnet-info.js matches the compiled mainnet contract (not the Rinkeby one)
  • Confirm the contract address in your config is correct (0xa9e27Be51A8520B4d794c62cDac8263d2304dA05)

4. Check for Nonce Conflicts

While your transaction was included in a block, it’s worth confirming the nonce you used was correct. Sometimes pending transactions can cause nonce mismatches—use web3.eth.getTransactionCount(owner_address, "pending") instead of "latest" to catch any pending transactions that might interfere.


My money’s on an ownership mismatch being the issue, but the exact revert reason will confirm it for sure. Let me know what you find!

内容的提问来源于stack exchange,提问作者Dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:22:48