I am working on a Solidity contract that allows users to mint NFTs with custom information about agricultural batches (such as name, company information, variety, etc.) and an image that they can select themselves. However, I am currently stuck and need help to achieve this functionality. My current code only allows users to mint NFTs without any input of the custom information or image selection.

Here's the existing code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/[email protected]/security/Pausable.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";
import "@openzeppelin/[email protected]/utils/Counters.sol";

contract Farmer is ERC721, ERC721Enumerable, Pausable, Ownable {

    // ==== 1. Property Variables ==== //

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

        // Struttura per contenere le informazioni del lotto agricolo
    struct Batch {
        string Name;
        string CompanyInformation;
        string Variety;
        uint256 number;
        uint256 quantity;
        string certification;
        uint256 dateOfCreation;
        uint256 dateOfProduction;

    uint256 public MINT_PRICE = 0.01 ether;
    uint256 public MAX_SUPPLY = 500;

    bool public publicMintOpen = false;
    bool public allowListMintOpen = false;

    mapping(address => bool) public allowList;

    // ==== 2. Lifecycle Function ==== //

    constructor() ERC721("Farmer", "FRM") {
        // Start token ID from 1.
    function withdraw() public onlyOwner(){
        require(address(this).balance > 0, "Balance is zero!" );

    // ==== 3. Pauseable Functions ==== // 

    function pause() public onlyOwner {

    function unpause() public onlyOwner {

    // Function to modify the mint windows
    function editMintWindows (
        bool _publicMintOpen,
        bool _allowListMintOpen
    ) external onlyOwner {
        publicMintOpen = _publicMintOpen;
        allowListMintOpen = _allowListMintOpen;
    // Adding publicMint and allowListMint variables
    // Require only the whitelisted addresses to MINT
    function allowListMint() public payable{
        require(allowListMintOpen, "AllowList Mint is OVER!");
        require(allowList[msg.sender], "You are not eligible to mint!");
        require(msg.value == 0.001 ether, "Not enough ether sent!");

    // ==== 4. Minting Functions ==== //
    // ==== 5. Make it payable ==== //
    // ==== 6. Add a limited supply ==== //
    function publicMint() public payable{
        require(publicMintOpen, "Public Mint OVER!");
        // Check if supply is minted out
        // Check that ether value is correct
        require(msg.value >= MINT_PRICE, "Not enough ether sent!");

    function internalMint() internal {
        require(totalSupply() < MAX_SUPPLY, "MINTING IS OVER!");
        uint256 tokenId = _tokenIdCounter.current();
        _safeMint(msg.sender, tokenId);

    // Function to get the balance of the contract
    function withdraw(address _addr) external onlyOwner{
        uint256 balance = address(this).balance;

    // Populating the AllowList
    function setAllowList(address[] calldata addresses) external onlyOwner{
        for(uint256 i = 0; i < addresses.length; i++){
        allowList[addresses[i]] = true;
    // ==== 6. Other Function ==== // 
    function _baseURI() internal pure override returns (string memory) {
        return "ipfs://FarmerBaseURI/";

    function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
        override(ERC721, ERC721Enumerable)
        super._beforeTokenTransfer(from, to, tokenId, batchSize);

    // The following functions are overrides required by Solidity.

    function supportsInterface(bytes4 interfaceId)
        override(ERC721, ERC721Enumerable)
        returns (bool)
        return super.supportsInterface(interfaceId);

My goal is to have the user input the custom information (the properties in the "Batch" struct) and select an image when minting the NFT, which should then be visible in the NFT's JSON metadata.

How can I modify the code to accept user input for the custom information and image selection while minting the NFT? Any help or guidance would be greatly appreciated!


1 Answer 1


You can't pass the image to the solidity.

For other things just declare some parameters, whatever is needed, in the mint function that users should pass while minting the NFT. For the image you can define the functionality of uploading the image to IPFS through backend libraries and after uploading it, pass the URI to the mint function so that it can update the URI of the respective token ID.

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.