1

Every time i submit my form from my frontend, MM opens up so i can pay my fee, i click confirm, the transaction fails with the error:

 {"blockHash":"0x837e462b489e65282e3a7c1b7f524cfc9c32bfa291c04940981323c9f1193606","blockNumber":"19613905","cumulativeGasUsed":"21070","from":"0x1d1874f9bcea4400a6a3ed85353bf19a764534e5","gasUsed":"21070","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0","to":"0x73ba4c37ce620ce4f7883ed4fcdf289c5448628b","transactionHash":"0x356fbf55537ab622ae6bac0e211a04276616b6806d64a158dfe0cc3631f6a554","transactionIndex":"0"}
    at get_transaction_error.ts:58:11
    at Generator.next (<anonymous>)
    at get_revert_reason.ts:94:2
    at new Promise (<anonymous>)
    at __awaiter29 (get_revert_reason.ts:94:2)
    at getTransactionError (get_transaction_error.ts:41:67)
    at rpc_method_wrappers.ts:630:28
    at Generator.next (<anonymous>)
    at fulfilled (get_transaction_error.ts:93:2)

I dont know how to solve this issue, I rewrote my backend multiple times and now i just started loosing hope... The project was supposed to enable user to upload an image and mint an NFT with it using piñata ipfs pinning service and I'm using a proprietary L2 blockchain to run the tx's. Here is my supper simple contract

pragma solidity ^0.8.18;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract SimpleNFT is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    event Minted(address indexed recipient, uint256 tokenId, string uri);

    constructor() ERC721("SimpleNFT", "SNFT") {}

    function mintNFT(
        address recipient,
        string memory uri
    ) external returns (uint256) {
        _tokenIds.increment();

        uint256 newNftTokenId = _tokenIds.current();
        _mint(recipient, newNftTokenId);
        _setTokenURI(newNftTokenId, uri);

        emit Minted(recipient, newNftTokenId, uri);

        return newNftTokenId;
    }
}

My frontend form that is supposed to be used to upload, mint and title the nfts: (i wont post the abi)


const contractAddress = "0x227d23545A2B53dEF6A9e68402482534Fd9cb961";

const Form = () => {
  const [file, setFile] = useState(null);
  const [imgURL, setImgURL] = useState(null);
  const [title1, setTitle1] = useState("");
  const [contract, setContract] = useState(null);

  useEffect(() => {
    const init = async () => {
      if (window.ethereum) {
        await window.ethereum.request({ method: "eth_requestAccounts" });
        web3 = new Web3(window.ethereum);
        const contractInstance = new web3.eth.Contract(abi, contractAddress);
        setContract(contractInstance);
      } else {
        console.error("Ethereum provider not found");
      }
    };
    init();
  }, []);

  const handleFileChange = (e) => {
    const selectedFile = e.target.files[0];
    console.log("Selected File:", selectedFile);
    setFile(selectedFile);
    const objectURL = URL.createObjectURL(selectedFile);
    setImgURL(objectURL);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    console.log("handleSubmit triggered");
    if (file) {
      try {
        const accounts = await web3.eth.getAccounts();
        console.log("File found, attempting to mint NFT...");
        const txReceipt = await contract.methods
          .mintNFT(accounts[0], title1)
          .send({ from: accounts[0], gas: 500000 });
        const formData = new FormData();
        formData.append("file", file);
        formData.append("title", title1);
        formData.append("address", accounts[0]);
        const response = await axios.post(
          "http://localhost:3000/api/mint",
          formData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        );
        console.log("Minting Response:", txReceipt);
        console.log("Minting Response:", response.data);
      } catch (error) {
        console.error("Error during minting process:", error);
      }
    } else {
      console.error("No file selected");
    }
  };

  return (
    <>
      <Header />
      <div className="nftbg">
        <div className="newnft">
          <p className="p1">CREATE</p>
          <p className="p2"> &nbsp;NEW NFT</p>
        </div>
        <form onSubmit={handleSubmit}>
          <section>
            <label htmlFor="file">Import file</label>
            <input
              type="file"
              name="file"
              id="file"
              onChange={handleFileChange}
            />
            <div className="photo_container">
              <img src={imgURL} alt="profile picture preview" />
            </div>
          </section>
          <section>
            <label htmlFor="title">NFT title</label>
            <input
              type="text"
              name="title1"
              id="title1"
              onChange={(e) => setTitle1(e.target.value)}
            />
          </section>
          <button type="submit" className="btn_NFT">
            <p className="btn_text_NFT">✨ Create Now ✨</p>
          </button>
        </form>
        <div className="bar">
          <p>Additional NFTs details</p>
          <div className="arrow"> </div>
        </div>
      </div>
    </>
  );
};

export default Form;

And my backend i use to upload a file to IPFS

const express = require("express");
const multer = require("multer");
const pinataSDK = require("@pinata/sdk");
const pinata = new pinataSDK(
  "ff6d3ff7737e8627277c",
  "462bb62848846981d6d23bcf21e527172d0d2d8bde7a71047d2c4b383dc88207"
);
const { Readable } = require("stream");
const cors = require("cors");
const app = express();
const upload = multer({ storage: multer.memoryStorage() });

app.use(cors());

function bufferToStream(buffer) {
  const readable = new Readable();
  readable.push(buffer);
  readable.push(null);
  return readable;
}

async function storeOnIPFS(fileBuffer) {
  console.log("Storing file on IPFS");
  try {
    const options = {
      pinataMetadata: {
        name: "MyNFTName",
      },
    };
    const result = await pinata.pinFileToIPFS(
      bufferToStream(fileBuffer),
      options
    );
    return result.IpfsHash;
  } catch (error) {
    console.error("IPFS Upload Error:", error);
    throw error;
  }
}

app.post("/api/mint", upload.single("file"), async (req, res) => {
  console.log("/api/mint route triggered");
  try {
    const fileBuffer = req.file.buffer;
    console.log("Received file buffer:", fileBuffer);

    const ipfsHash = await storeOnIPFS(fileBuffer);
    console.log(`File stored on IPFS with hash: ${ipfsHash}`);

    res.status(200).send({ message: "File stored on IPFS", ipfsHash });
  } catch (error) {
    console.error("Error in /api/mint route:", error);
    res.status(500).send("Internal Server Error");
  }
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000/");
});

I have put console logs literally wherever I can to solve it but it does not help. Please!!! I beg for help!

3
  • Can you please tell me what you are inputting as Title in your form? Plus if I am right, you didn't need a backend for this. You are, firstly minting the NFT through your front-end, and then minting again using your backend, using the same details Commented Sep 8, 2023 at 4:52
  • My title is supposed to be the input from my form labelled NFT Title... I made this backend as future proofing plus i dont know how to use multer any other way cuz this is how i learned it to work, What i discovered that when i extract the mint function from the backend as mint.js and call it, it works perfectly, but when i want to call it from the backend via my frontend through MM it suddenly does not work Commented Sep 8, 2023 at 9:50
  • you are right i call minting function twice, i fixed it now so i only call it in the frontend, but it did not change the fact that MM still rejects it with the same err Commented Sep 8, 2023 at 14:33

1 Answer 1

0

Okay i found the issue, the issue is i had to ditch web3.js and use ethers.js instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.