function _safeMint(address to, uint256 tokenId) internal virtual {
    _safeMint(to, tokenId, "");

 * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
 * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
function _safeMint(
    address to,
    uint256 tokenId,
    bytes memory _data
) internal virtual {
    _mint(to, tokenId);
        _checkOnERC721Received(address(0), to, tokenId, _data),
        "ERC721: transfer to non ERC721Receiver implementer"

 * @dev Mints `tokenId` and transfers it to `to`.
 * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
 * Requirements:
 * - `tokenId` must not exist.
 * - `to` cannot be the zero address.
 * Emits a {Transfer} event.
function _mint(address to, uint256 tokenId) internal virtual {
    require(to != address(0), "ERC721: mint to the zero address");
    require(!_exists(tokenId), "ERC721: token already minted");

    _beforeTokenTransfer(address(0), to, tokenId);

    _balances[to] += 1;
    _owners[tokenId] = to;

    emit Transfer(address(0), to, tokenId);

This is part of my code, I’m really struggling to find online examples that successfully utilise safe mint and are able to mint NFTs with it and set the correct token URI.

Most online mint scripts look like this:

   const API_URL = process.env.API_URL;
   const PUBLIC_KEY = process.env.PUBLIC_KEY;
   const PRIVATE_KEY = process.env.PRIVATE_KEY;

   const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
   const web3 = createAlchemyWeb3(API_URL);

   const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
   const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED";
   const nftContract = new web3.eth.Contract(contract.abi,contractAddress);

   async function mintNFT(tokenURI) {
   const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest');  

   //get latest nonce

  //the transaction
 const tx = {
   'from': PUBLIC_KEY,
   'to': contractAddress,
   'nonce': nonce,
   'gas': 500000,
   'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()


While their “mintNFT” function in the contract looks like:

function mintNFT(address recipient, string memory tokenURI)
        public onlyOwner
        returns (uint256)

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;

In the above code we tokenURI passed in the mintNFT function itself, I’m wondering how would safeMint be called in a script while also declaring the base token URI to ensure the nft is minted correctly.

I cant see anyway to pass a TokenURI in the mint function, so am unsure how to actually create the NFTs with their metadata.

1 Answer 1


I'd modify the mintNFT function in the contract

// *** Add _data parmeter
function mintNFT(address recipient, string memory tokenURI, bytes memory _data)
    public onlyOwner
    returns (uint256)

    uint256 newItemId = _tokenIds.current();

    // *** Move _setTokenUri before _safeMint
    _setTokenURI(newItemId, tokenURI);

    // *** Execute _safeMint at the end to follow 
    // *** Check-Effect-Interaction pattern
    _safeMint(recipient, newItemId, _data);

    return newItemId;
  • What goes in this data field of safe mint ? Commented Sep 21, 2022 at 4:43
  • @AmalnathSathyan It iis an extra parameter, it could be an empty string, or something you want to add to the particular token.
    – Ismael
    Commented Sep 21, 2022 at 5:01

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.