Hedera
  • Welcome to Hedera — let’s build the future
  • Getting Started
    • Environment Setup
    • Web2 Developers
      • Transfer HBAR
      • Create a Token
      • Create a Topic
    • EVM Developers
      • Deploy a Contract
  • Tutorials
    • Smart Contracts
      • How to Mint & Burn an ERC-721 Token Using Hardhat and Ethers (Part 1)
      • How to Set Access Control, a Token URI, Pause, and Transfer an ERC-721 Token Using Hardhat (Part 2)
      • How to Upgrade an ERC-721 Token with OpenZeppelin UUPS Proxies and Hardhat (Part 3)
      • How to Verify a Smart Contract on HashScan
      • Deploy a Smart Contract Using Remix
      • Deploy a Smart Contract Using Hardhat and Hiero JSON-RPC Relay
      • Deploy Your First Smart Contract
      • Deploy a Contract Using the Hedera Token Service
      • Send and Receive HBAR Using Solidity Smart Contracts
      • Deploy By Leveraging Ethereum Developer Tools On Hedera
      • Deploy a Subgraph Using The Graph and Hedera JSON-RPC Relay
      • Deploy Smart Contracts on Hedera Using Truffle
      • The Power of Native Hedera Tokens as ERC-20 Tokens: A step-by-step guide
      • HTS x EVM - Part 1: How to Mint NFTs
      • HTS x EVM - Part 2: KYC & Update
      • HTS x EVM - Part 3: How to Pause, Freeze, Wipe, and Delete NFTs
      • Hedera Smart Contracts Workshop
        • Setup
        • Solidity
        • Hedera SDK JS
        • Hardhat and EthersJs
        • Outro
      • Foundry
        • How to Setup Foundry and Write a Basic Unit Test
        • How to Deploy and Verify a Hedera Smart Contract with Foundry
        • How to Test A Solidity Event
        • How to Fork Testnet on Latest Block
    • Consensus
      • Submit Your First Message
      • Submit Message to Private Topic
      • Query Messages with Mirror Node
    • Tokens
      • Create and Transfer Your First NFT
      • Create and Transfer Your First Fungible Token
      • Create and Transfer an NFT using a Solidity Contract
      • Structure Your Token Metadata Using JSON Schema V2
      • Hedera Token Service - Part 1: How to Mint NFTs
      • Hedera Token Service - Part 2: KYC, Update, and Scheduled Transactions
      • Hedera Token Service - Part 3: How to Pause, Freeze, Wipe, and Delete NFTs
      • Create Your First Frictionless Airdrop Campaign
    • Local Node
      • How to Run Hedera Local Node in a Cloud Development Environment (CDE)
        • Run a Local Node in Gitpod
        • Run a Local Node in Codespaces
      • How to Set Up a Hedera Local Node
      • Set Up a Hedera Local Node using the NPM CLI
    • More Tutorials
      • Create and Fund Your Hedera Testnet Account
      • How to Create a Personal Access Token (API Key) on the Hedera Portal
      • How to Auto-Create Hedera Accounts with HBAR and Token Transfers
      • How to Configure a Mirror Node and Query Data
      • How to Generate a Random Number on Hedera
      • Get Started with the Hedera Consensus Service Fabric Plugin
        • Virtual Environment Setup
      • Schedule Your First Transaction
      • How to Connect to Hedera Networks Over RPC
        • Configuring Hashio RPC endpoints
        • Configuring Hiero JSON-RPC Relay endpoints
        • Configuring Validation Cloud RPC endpoints
      • JavaScript Testing
      • Create a Hedera DApp Integrated with WalletConnect
      • How to Connect MetaMask to Hedera
    • Demo Applications
    • Starter Projects
    • Building on Hedera (course)
  • Networks
    • Mainnet
      • Mainnet Accounts
      • Mainnet Consensus Nodes
        • Node Requirements
          • FAQ
      • Fees
        • Transaction Records
    • Testnets
      • Testnet Accounts
      • Testnet Consensus Nodes
    • Localnet
      • Single Node Configuration
      • Multinode Configuration
    • Network Explorers and Tools
    • Release Notes
      • Consensus Node
      • Hedera Mirror Node
  • Core Concepts
    • Accounts
      • Account Creation
      • Auto Account Creation
      • Account Properties
    • Keys and Signatures
    • Schedule Transaction
    • Smart Contracts
      • Understanding Hedera's EVM Differences and Compatibility
        • For EVM Developers Migrating to Hedera
          • Accounts, Signature Verification & Keys (ECDSA vs. ED25519)
          • JSON-RPC Relay and EVM Tooling
          • Token Management with Hedera Token Service
          • Decimal Handling (8 vs. 18 Decimals)
          • Handling HBAR Transfers in Contracts
        • For Hedera-Native Developers Adding Smart Contract Functionality
          • Integrating ED25519 Accounts and Advanced Features Into Smart Contracts
          • JSON-RPC Relay and State Queries
          • Extending Token Management with Smart Contracts
      • Creating Smart Contracts
      • Compiling Smart Contracts
      • System Smart Contracts
        • Hedera Account Service
        • Hedera Schedule Service
      • Gas and Fees
      • JSON-RPC Relay
      • Deploying Smart Contracts
      • Smart Contract Addresses
      • Verifying Smart Contracts
      • Smart Contract Traceability
      • Tokens Managed by Smart Contracts
        • ERC-20 (Fungible Tokens)
        • ERC-721 (Non-Fungible Token)
        • ERC-3643 Real World Assets (RWA)
        • ERC-1363 (Payable Tokens)
        • Hedera Token Service System Contract
      • Wrapped HBAR (WHBAR)
      • Smart Contract Rent
      • Smart Contract Security
      • EVM Archive Node Queries
    • Tokens
      • Tokenization on Hedera
      • Hedera Token Service (HTS) Native Tokenization
        • Token Types and ID Formats
        • Token Properties
        • Token Creation
        • Custom Fee Schedule
        • Token Airdrops
      • ERC/EVM-Compatible Tokenization
      • Hybrid (HTS + EVM ) Tokenization
    • Staking
      • Staking Program
      • Stake HBAR
    • Hashgraph Consensus Algorithm
      • Gossip About Gossip
      • Virtual Voting
    • Transactions and Queries
      • Transaction Properties
    • State and History
    • Mirror Nodes
      • Hedera Mirror Node
      • One Click Mirror Node Deployment
      • Run Your Own Mirror Node
        • Run Your Own Mirror Node with Google Cloud Storage (GCS)
        • Run Your Mirror Node with Amazon Web Services S3 (AWS)
  • Open Source Solutions and Integrations
    • AI Studio on Hedera
      • ElizaOS Plugin for Hedera
      • Hedera AI Agent Kit
      • MCP Server
      • OpenConvAI
    • AI Tools for Developers
      • Hedera Hivemind
      • Kapa AI
    • Asset Tokenization Studio (ATS)
      • Web User Interface (UI)
      • Frequently Asked Questions (FAQs)
    • HashioDAO
      • Governance Token DAO
      • NFT DAO
      • Multisig DAO
      • DAO Proposals
      • Local Environment Setup
    • Hedera CLI
    • Hedera Contract Builder
    • Hedera Custodians Library
      • How to use it
    • Hedera Developers Code Repository
    • Hedera Developer Playground
    • Hedera Wallet Snap By MetaMask
      • Hedera Wallet Snap Documentation
      • Tutorial: MetaMask Snaps – What Are They and How to Use Them
    • Interoperability and Bridging
      • LayerZero
    • NFT Studio
      • Airdrop List Verifier
      • Metadata Validator
      • NFT Rarity Inspector
      • NFT Token Holders List Builder
      • NFT Risk Calculator
      • Token Balance Snapshot
      • Hedera NFT SDK
    • Oracle Networks
      • Chainlink Oracles
      • Pyth Oracles
      • Supra Oracles
    • Stablecoin Studio
      • Core Concepts
      • Web UI Application
      • CLI Management
      • TypeScript SDK
    • Hedera Guardian
    • Hedera WalletConnect
  • SDKs & APIs
    • SDKs
      • Build Your Hedera Client
      • Set Up Your Local Network
      • Network Address Book
      • Keys
        • Generate a new key pair
        • Import an existing key
        • Create a key list
        • Create a threshold key
        • Generate a mnemonic phrase
        • Recover keys from a mnemonic phrase
      • HBAR
      • Specialized Types
      • Pseudorandom Number Generator
      • Transactions
        • Create a Batch Transaction
        • Transaction ID
        • Modify transaction fields
        • Create an unsigned transaction
        • Manually sign a transaction
        • Submit a transaction
        • Sign a multisignature transaction
        • Get a transaction receipt
        • Get a transaction record
      • Schedule Transaction
        • Schedule ID
        • Create a schedule transaction
        • Sign a scheduled transaction
        • Delete a schedule transaction
        • Get schedule info
        • Network Response Messages
      • Queries
      • General Network Response Messages
      • Accounts and HBAR
        • Create an account
        • Update an account
        • Transfer cryptocurrency
        • Approve an allowance
        • Delete an allowance
        • Delete an account
        • Get account balance
        • Get account info
        • Network Response Messages
      • Consensus Service
        • Create a topic
        • Update a topic
        • Submit a message
        • Delete a topic
        • Get topic messages
        • Get topic info
        • Network Response
      • Token Service
        • Token ID
        • NFT ID
        • Token types
        • Create a token
        • Custom token fees
        • Update a token
        • Update token custom fees
        • Update NFT metadata
        • Transfer tokens
        • Airdrop a token
        • Claim a token
        • Cancel a token
        • Reject a token
        • Delete a token
        • Mint a token
        • Burn a token
        • Freeze an account
        • Unfreeze an account
        • Enable KYC account flag
        • Disable KYC account flag
        • Associate tokens to an account
        • Dissociate tokens from an account
        • Pause a token
        • Unpause a token
        • Wipe a token
        • Atomic swaps
        • Get account token balance
        • Get token info
        • Get NFT info
        • Network Response Messages
      • File Service
        • Create a file
        • Append to a file
        • Update a file
        • Delete a file
        • Get file contents
        • Get file info
        • Network Response Messages
      • Smart Contract Service
        • Delegate Contract ID
        • Create a smart contract
        • Update a smart contract
        • Delete a smart contract
        • Call a smart contract function
        • Ethereum transaction
        • Get a smart contract function
        • Get smart contract bytecode
        • Get smart contract info
        • Hedera Service Solidity Libraries
        • Network Response Messages
      • Signature Provider
        • Provider
        • Signer
        • Wallet
        • Local Provider
    • Mirror Node REST API
      • Accounts
      • Balances
      • Blocks
      • Schedule Transactions
      • Smart Contracts
      • Tokens
      • Topics
      • Transactions
      • Network
    • Hedera Consensus Service gRPC API
    • Hedera APIs
      • Basic Types
        • AccountAmount
        • AccountID
        • ContractID
        • CryptoAllowance
        • CurrentAndNextFeeSchedule
        • FeeComponents
        • FeeData
        • FeeSchedule
        • FileID
        • Fraction
        • HederaFunctionality
        • Key
        • KeyList
        • NftAllowance
        • NftTransfer
        • NodeAddress
        • NodeAddressBook
        • RealmID
        • ScheduleID
        • SemanticVersion
        • ServicesConfigurationList
        • ServiceEndpoint
        • Setting
        • ShardID
        • Signature
        • SignatureList
        • SignatureMap
        • SignaturePair
        • SubType
        • TransferList
        • TransactionID
        • ThresholdKey
        • ThresholdSignature
        • TokenAllowance
        • TokenBalance
        • TokenBalances
        • TokenFreezeStatus
        • TokenPauseStatus
        • TokenID
        • TokenKycStatus
        • TokenRelationship
        • TokenTransferList
        • TokenType
        • TokenSupplyType
        • TopicID
        • TransactionFeeSchedule
      • Cryptocurrency Accounts
        • CryptoService
        • CryptApproveAllowance
        • CryptoDeleteAllowance
        • CryptoCreate
        • CryptoTransfer
        • CryptoUpdate
        • CryptoDelete
        • CryptoGetAccountBalance
        • CryptoGetAccountRecords
        • CryptoGetInfo
        • CryptoGetStakers
      • Consensus Service
        • Consensus Service
        • ConsensusCreateTopic
        • ConsensusUpdateTopic
        • ConsensusSubmitMessage
        • ConsensusDeleteTopic
        • ConsensusTopicInfo
        • ConsensusGetTopicInfo
      • Schedule Service
        • ScheduleService
        • SchedulableTransactionBody
        • ScheduleCreate
        • ScheduleDelete
        • ScheduleSign
        • ScheduleGetInfo
      • Token Service
        • TokenService
        • CustomFees
          • AssessedCustomFee
          • CustomFee
          • FractionalFee
          • FixedFee
          • RoyaltyFee
        • TokenCreate
        • TokenUpdate
        • TokenFeeScheduleUpdate
        • TokenDelete
        • TokenMint
        • TokenBurn
        • TokenFreezeAccount
        • TokenUnfreezeAccount
        • TokenGrantKyc
        • TokenRevokeKyc
        • TokenAssociate
        • TokenDissociate
        • TokenWipeAccount
        • TokenPause
        • TokenUnpause
        • TokenGetInfo
        • TokenGetNftInfo
        • TokenGetNftInfos
        • TokenGetAccountNftInfo
      • File Service
        • FileService
        • FileCreate
        • FileAppend
        • FileUpdate
        • FileDelete
        • FileGetContents
        • FileGetInfo
      • Smart Contracts
        • SmartContractService
        • ContractCall
        • ContractCallLocal
        • ContractCreate
        • ContractUpdate
        • ContractDelete
        • ContractGetByteCode
        • ContractGetInfo
        • ContractGetRecords
      • Miscellaneous
        • Duration
        • ExchangeRate
        • Freeze
        • FreezeType
        • GetByKey
        • GetBySolidityID
        • NetworkGetVersionInfo
        • NetworkService
        • Query
        • QueryHeader
        • Response
        • ResponseCode
        • ResponseHeader
        • SystemDelete
        • SystemUndelete
        • TimeStamp
        • Transaction
        • TransactionBody
        • TransactionContents
        • TransactionGetFastRecord
        • TransactionGetReceipt
        • TransactionGetRecord
        • TransactionReceipt
        • TransactionRecord
        • TransactionResponse
        • UncheckedSubmit
    • Hedera Status API
  • Support & Community
    • Glossary
    • Contributing to Hedera documentation
      • Contribution Guidelines
        • Creating Issues
        • Creating Pull Requests
        • Hedera Improvement Proposal (HIP)
        • Submit Demo Applications
      • Style Guide
        • Understanding different types of documentation
        • Use of HBAR and tinybars
        • Use of web2 and web3
        • Language and grammar
        • Formatting
        • Punctuation
        • GitBook Markdown Syntax
    • Discord
    • GitHub
    • Stack Overflow
    • Hedera Blog
    • Bug Bounty
    • Hedera Help
    • Documentation Survey
    • Meetups
    • Brand Guidelines
    • Status Page
Powered by GitBook
LogoLogo

INTRODUCTION

  • Fees
  • Core Concepts
  • Network Information

TOOLS

  • Bridge
  • Oracles
  • Explorers
  • Developer Portal & Faucet

RESOURCES

  • Status
  • Bug Bounty
  • Build on Hedera (course)
  • Documentation Survey
On this page
  • Prerequisites
  • Table of Contents
  • Step 1: Create and Compile the Solidity Contract
  • Step 2: Deploying the Smart Contract and Minting a Token
  • Step 3: Fixing Permissions, Redeploying, and Minting
  • Step 4: Pausing the Contract
  • Step 5: Transferring NFTs
  • Additional Resources

Was this helpful?

Edit on GitHub
  1. Tutorials
  2. Smart Contracts

How to Set Access Control, a Token URI, Pause, and Transfer an ERC-721 Token Using Hardhat (Part 2)

PreviousHow to Mint & Burn an ERC-721 Token Using Hardhat and Ethers (Part 1)NextHow to Upgrade an ERC-721 Token with OpenZeppelin UUPS Proxies and Hardhat (Part 3)

Last updated 12 days ago

Was this helpful?

In this tutorial, you'll learn how to create and manage an advanced ERC-721 token smart contract using Hardhat and OpenZeppelin. We'll cover deploying the contract, minting NFTs, pausing and unpausing the contract, and transferring tokens. You'll gain experience with (admin, minting, pausing roles), URI storage, and Pausable functionalities.

You can take a look at the complete code in the .


Prerequisites

  • ⚠️ Complete as we continue from this example.

  • Basic understanding of smart contracts.

  • Basic understanding of and JavaScript.

  • Basic understanding of and .

  • ECDSA account from the .


Table of Contents


Step 1: Create and Compile the Solidity Contract

Create a new Solidity file named erc-721-advanced.sol in your contracts directory, and paste this Solidity code:

erc-721-advanced.sol
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.22;

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {ERC721Pausable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";
import {ERC721URIStorage} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

contract MyTokenAdvanced is ERC721, ERC721URIStorage, ERC721Pausable, AccessControl {
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    uint256 private _nextTokenId;

    constructor(address defaultAdmin, address pauser, address minter)
        ERC721("MyTokenAdvanced", "MTK")
    {
        _grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
        _grantRole(PAUSER_ROLE, pauser);
        _grantRole(MINTER_ROLE, minter);
    }

    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    function safeMint(address to, string memory uri)
        public
        onlyRole(MINTER_ROLE)
        returns (uint256)
    {
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
        return tokenId;
    }

    // The following functions are overrides required by Solidity.

    function _update(address to, uint256 tokenId, address auth)
        internal
        override(ERC721, ERC721Pausable)
        returns (address)
    {
        return super._update(to, tokenId, auth);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721URIStorage, AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

The contract implements the ERC721URIStorage, ERC721Pausable, and AccessControl interfaces from OpenZeppelin. You can create the contract yourself using the OpenZeppelin Wizard and enable "Mintable," "Pausable," "URI Storage," and "Access Control -> Roles."

Compile your new contract:

npx hardhat compile

Step 2: Deploying the Smart Contract and Minting a Token

Create deploy-advanced.js in your scripts folder:

deploy-advanced.js
async function main() {
  const [deployer] = await ethers.getSigners();
  const MyTokenAdvanced = await ethers.getContractFactory("MyTokenAdvanced", deployer);
  
  // Third argument is the minting role set to an unknown address
  const contract = await MyTokenAdvanced.deploy(deployer.address, deployer.address, "0xc0ffee254729296a45a3885639AC7E10F9d54979");
  console.log("Contract deployed at:", contract.target);
}

main().catch(console.error);

Note that we are providing three arguments to the MyTokenAdvanced.deploy() function. When we look at the constructor of our smart contract, we can provide the admin, pauser, and minter roles.

constructor(address defaultAdmin, address pauser, address minter)

The deploy-advanced.js script sets the minter role to an unknown (random) address. This should prevent the deployer account from minting new tokens in the next step. First, let's run the deployer script:

npx hardhat run scripts/deploy-advanced.js --network testnet

Here's the output of the command:

Deploying contracts with the account: 0x7203b2B56CD700e4Df7C2868216e82bCCA225423
Contract deployed at: 0x28abF02031C65866c9D1F8fbc9c73e12A1a6A878

Copy the contract address of your newly deployed contract. Next, create mint-advanced.js in your scripts folder:

mint-advanced.js
async function main() {
  const [deployer] = await ethers.getSigners();
  const MyTokenAdvanced = await ethers.getContractFactory(
    "MyTokenAdvanced",
    deployer
  );

  // Connect to the deployed contract (REPLACE WITH YOUR CONTRACT ADDRESS)
  const contractAddress = "0x6F5F9Ed50140bb9C94246257241Ed5AA5d40A25d";
  const contract = await MyTokenAdvanced.attach(contractAddress);

  // Mint a token to ourselves
  const mintTx = await contract.safeMint(
    deployer.address,
    "https://myserver.com/8bitbeard/8bitbeard-tokens/tokens/1"
  );
  const receipt = await mintTx.wait();
  const mintedTokenId = receipt.logs[0].topics[3];
  console.log("Minted token ID:", mintedTokenId);

  // Check the balance of the token
  const balance = await contract.balanceOf(deployer.address);
  console.log("Balance:", balance.toString(), "NFTs");

  // Check the token URI
  const tokenURI = await contract.tokenURI(mintedTokenId);
  console.log("Token URI:", tokenURI);
}

main().catch(console.error);

This contract tries to mint a new token and sets the token URI to https://myserver.com/8bitbeard/8bitbeard-tokens/tokens/1 . This transaction will fail because our deployer account doesn't have the minter permission. Run the script:

npx hardhat run scripts/mint-advanced.js --network testnet

Notice minting fails due to incorrect permissions. Let's fix this in the next step.


Step 3: Fixing Permissions, Redeploying, and Minting

Update the minting role to your deployer account by modifying the following line of code in your deploy-advanced.js script:

deploy-advanced.js
const contract = await MyTokenAdvanced.deploy(deployer.address, deployer.address, deployer.address); // Deployer account gets all roles

Now that the deployer account has all the roles, redeploy the contract:

npx hardhat run scripts/deploy-advanced.js --network testnet

Don't forget to copy the new contract address and update the contractAddress variable in your mint-advanced.js script with this new address.

Next, execute the minting logic:

npx hardhat run scripts/mint-advanced.js --network testnet

The new token will be minted with token ID 0 and the corresponding token URI is printed to your terminal.


Step 4: Pausing the Contract

Create a new pause-advanced.js script and make sure to replace the contractAddress variable with your address:

pause-advanced.js
async function main() {
    const [deployer] = await ethers.getSigners();
    const MyTokenAdvanced = await ethers.getContractFactory("MyTokenAdvanced", deployer);
  
    // Connect to the deployed contract (REPLACE WITH YOUR CONTRACT ADDRESS)
    const contractAddress = "0x11828533C93F8A1e19623343308dFb4a811005dE";
    const contract = await MyTokenAdvanced.attach(contractAddress);
  
    // Pause the token
    const pauseTx = await contract.pause();
    await pauseTx.wait();
    console.log("Paused token");

    // Read the paused state
    const pausedState = await contract.paused();
    console.log("Contract paused state is:", pausedState);
}
  
main().catch(console.error);

The script calls the pause function on your contract. As we have the correct role, the token will be paused and its paused state will be printed to the terminal. Execute the script:

npx hardhat run scripts/pause-advanced.js --network testnet

The contract will return true when it is paused. Now, nobody can mint new tokens.

Pausing an ERC-721 contract temporarily disables critical functions, including minting, transferring, and burning tokens. While the contract is paused, users cannot perform these operations, making it particularly useful in emergency scenarios or maintenance periods. However, read operations such as checking token balances or URIs are still possible.


Step 5: Transferring NFTs

Create a transfer-advanced.js script to transfer an NFT to another address. Don't forget to replace the contractAddress with your smart contract address.

transfer-advanced.js
async function main() {
  const [deployer] = await ethers.getSigners();
  const MyTokenAdvanced = await ethers.getContractFactory(
    "MyTokenAdvanced",
    deployer
  );

  // Connect to the deployed contract (REPLACE WITH YOUR CONTRACT ADDRESS)
  const contractAddress = "0x11828533C93F8A1e19623343308dFb4a811005dE";
  const contract = await MyTokenAdvanced.attach(contractAddress);

  // Unpause the token
  const unpauseTx = await contract.unpause();
  await unpauseTx.wait();
  console.log("Unpaused token");

  // Read the paused state
  const pausedState = await contract.paused();
  console.log("Contract paused state is:", pausedState);

  // Transfer the token with ID 0
  const transferTx = await contract.transferFrom(
    deployer.address,
    "0x5FbDB2315678afecb367f032d93F642f64180aa3",
    0
  );

  await transferTx.wait();

  const balance = await contract.balanceOf("0x5FbDB2315678afecb367f032d93F642f64180aa3");
  console.log("Balance:", balance.toString(), "NFTs");
}

main().catch(console.error);

Execute the script to transfer the token:

npx hardhat run scripts/transfer-advanced.js --network testnet

If the balance for the 0x5FbDB2315678afecb367f032d93F642f64180aa3 account shows 1 , then you've successfully transferred the NFT and completed this tutorial! 🎉


Additional Resources

This script will first unpause your contract and then transfer the token to a random address 0x5FbDB2315678afecb367f032d93F642f64180aa3 using the on your contract. This function accepts the sender address, receiver address, and the token ID you want to transfer. Next, we check if the account has actually received the token by verifying its balance.

transferFrom function
OpenZeppelin ERC-721 Docs
Access Control Docs
Access Control
Hedera-Code-Snippets repository
tutorial part 1
Node.js
Hardhat EVM Development Tool
Ethers
Hedera Portal
Create and Compile the Solidity Contract
Deploying the Smart Contract and Minting a Token
Fixing Permissions, Redeploying, and Minting
Pausing the Contract
Pausing the Contract
Transferring NFTs

Writer: Michiel, Developer Relations Engineer

Editor: Luis, Sr Software Developer

Editor: Krystal, Technical Writer

|

|

GitHub
LinkedIn
GitHub
GitHub
X