Create your own
Lesson illustration

Dynamic NFTs: Responding to On-Chain Events

Hello! Welcome back to our course.

In our last lesson, we built a fully functional auction system, adding a dynamic price discovery mechanism to our NFT marketplace. This completed our exploration of the core mechanics of NFT trading. Now, we'll shift our focus from how NFTs are traded to what they can be.

So far, the NFTs we've worked with have been static—their metadata and appearance are set at minting and never change. In this lesson, we'll explore one of the most creative and powerful evolutions in the space: dynamic NFTs.

Learning Outcome: By the end of this 60-minute lesson, you will be able to implement a dynamic NFT that changes its metadata based on on-chain state or external events.

We will uncover the core mechanism that makes NFTs dynamic, learn how to generate and store NFT images entirely on-chain using SVGs, and then use oracles to make our NFT react to real-world data.

1. The Core Mechanism: A Dynamic tokenURI

The key to a dynamic NFT (dNFT) lies in the tokenURI function, which is part of the ERC-721 metadata standard.

  • For a static NFT, tokenURI typically returns a fixed string, usually a URL pointing to a JSON file on IPFS (e.g., ipfs://.../1.json).
  • For a dynamic NFT, we override the tokenURI function to construct the JSON metadata on the fly, directly within the smart contract.

This means the function can read the contract's current state—or data from other contracts—and generate different metadata based on those values. The most powerful way to achieve this is by generating the image itself on-chain.

Let's explore how to generate both the JSON metadata and the image (as an SVG) completely on-chain.

How to store NFT metadata and SVG image completely on-chain (ERC721/ERC1155)

This video from Artur Chmaro provides an excellent technical breakdown of how to construct NFT metadata and an SVG image entirely within a Solidity smart contract. This is a foundational technique for creating dNFTs.

Watch the following segments to understand the end-to-end process of on-chain metadata generation: Storing Attributes On-Chain (1:48 - 3:22): See how NFT attributes are stored in a struct. Generating OpenSea-Compatible Metadata (3:22 - 4:35): Understand the structure of the JSON metadata that marketplaces expect. Encoding with Base64 and On-Chain SVG (4:35 - 7:17): This is the core of the technique. Pay close attention to how a raw SVG string is embedded in the contract and how the final JSON is encoded into a data URI. Implementing tokenURI (7:17 - 8:58): See how all the pieces are assembled in the tokenURI function to return the final, self-contained metadata.

To summarize the process shown in the video:

  1. Store Attributes: The NFT's traits (like speed, attack, etc.) are stored in a struct and mapped to each tokenId.
  2. Generate SVG: A function generates an SVG image as a string. Critically, this function can take the NFT's attributes as parameters to change the SVG's colors, shapes, or text.
  3. Construct JSON: The tokenURI function builds a JSON string that conforms to the metadata standard. It includes the name, description, and attributes.
  4. Encode and Return: The SVG string is embedded within the JSON's image field. The entire JSON object is then Base64 encoded and returned as a Data URI, which looks like this: data:application/json;base64,eyJuYW1lIjog....

This makes the NFT entirely self-contained and permanent. Its metadata and image live on the blockchain and depend on no external services like IPFS or a private server.

2. Sourcing External Data with Oracles

Now that we can generate metadata based on on-chain state, the next question is: how do we get real-world data onto the chain to trigger changes?

Blockchains are deterministic, isolated environments. A smart contract cannot make an API call to a weather service or a stock exchange. This is where oracles come in. Oracles are services that fetch external data and securely post it on the blockchain, making it available for smart contracts to read.

Chainlink is the most widely used decentralized oracle network. Let's see how it's used to create a dNFT.

Generating Dynamic NFTs On-chain using SVGs & Chainlink with Patrick Collins

In this video, Patrick Collins from Chainlink explains the concept of dNFTs and demonstrates one that changes based on the price of Ethereum, fetched via a Chainlink Price Feed.

Watch these segments to connect the on-chain SVG technique with external data: Dynamic NFT Demo (18:02 - 20:21): See a concrete example of a dNFT that displays a thumbs-up or thumbs-down SVG based on whether the ETH price is above a certain threshold. How Chainlink Data Feeds Work (20:21 - 25:21): This is a crucial conceptual overview. Understand how decentralized oracle networks provide secure and reliable data to smart contracts. Use Cases and Trade-offs (43:42 - 50:45): This discussion provides important context on why you might choose an on-chain vs. off-chain (IPFS) metadata strategy, touching on gas costs, permanence, and utility (especially in gaming).

The key takeaway is the overall architecture:

  1. A Chainlink Data Feed (an on-chain contract) is continuously updated with the latest asset price by a decentralized network of oracles.
  2. Our NFT contract's tokenURI function reads the price from the Data Feed contract.
  3. Based on the price, our function conditionally includes one SVG string or another in the generated metadata.

This creates an NFT that automatically reflects real-world market conditions.

3. Practical Implementation: A Multi-Dynamic NFT

Let's put theory into practice by examining a contract that combines multiple dynamic elements. The following tutorial from Chainlink provides the code for an NFT that changes in two ways:

  1. Its background color changes based on a verifiably random number from Chainlink VRF (Verifiable Random Function).
  2. It displays an emoji that changes based on the price movement of ETH from Chainlink Price Feeds.

Furthermore, it uses Chainlink Automation (also known as Keepers) to automatically call a function on our contract at regular intervals, triggering the updates. This makes the NFT truly autonomous.

How to Create a Dynamic NFT—Tutorial [<1 Hour]

This Chainlink blog post provides a complete smart contract and walkthrough for creating a dNFT. We will focus on understanding the contract's logic, as it's a perfect example of our learning outcome.

Read the Solidity code for the SuperDynamicNFT contract provided in Step 4, section F of the article. You don't need to follow the deployment steps, just focus on understanding the code's structure and logic.

Let's break down the key parts of the SuperDynamicNFT contract you just reviewed:

  • State Variables:

    • priceFeed: An interface to the Chainlink Price Feed contract.
    • COORDINATOR: An interface to the Chainlink VRF coordinator contract.
    • fillColor, ethIndicator: State variables that store the current dynamic properties of the NFT.
  • Automation Trigger (requestRandomWords):

    • This public function is designed to be called by Chainlink Automation on a schedule (e.g., every 2 minutes).
    • Its only job is to request a random number from the VRF service.
  • VRF Callback (fulfillRandomWords):

    • This is the function that the Chainlink VRF service calls back into once it has generated a secure random number.
    • Inside this function, the real work happens:
      1. It receives the randomWords.
      2. It calls updateFillColor() to generate a new hex color from the random number.
      3. It calls updateETHPrice() to get the latest ETH price and determine the correct emoji (😀, 😔, or 😑).
  • Metadata Generation (tokenURI):

    • This function reads the fillColor and ethIndicator state variables.
    • It constructs an SVG string, injecting these variables directly into the SVG code to set the rectangle's fill color and the emoji text.
    • Finally, it Base64-encodes everything and returns the complete data URI, just as we saw in the first video.

This architecture is a powerful and common pattern: Automation -> Oracle Request -> Callback -> State Update -> Dynamic tokenURI.

4. Alternative Architectures: Off-Chain Data with On-Chain Pointers

While on-chain SVGs are great for relatively simple and geometric images, they can become very gas-expensive for complex art. An alternative pattern is to store metadata off-chain but manage it through on-chain logic.

The Dynamic NFT with Chainlink automation tutorial from Tableland (resource dfeea) demonstrates such a pattern.

  • Storage: NFT metadata attributes are stored in tables in Tableland, a decentralized SQL database. The image pointers (IPFS CIDs) are stored in these tables.
  • Dynamic Trigger: Chainlink Automation calls a function (growFlower) in the contract on a schedule.
  • State Update: Instead of updating a state variable, the growFlower function executes a SQL UPDATE statement on the Tableland database, changing the NFT's "stage."
  • Metadata Retrieval: The tokenURI function returns a URL that executes a SQL SELECT ... JOIN query against the Tableland gateway, which fetches the current metadata for that token ID.

This approach separates the logic (on-chain contract) from the data (off-chain but decentralized database), offering a different set of trade-offs in terms of gas cost, complexity, and data availability.

Conclusion

Congratulations! You have now mastered the concepts and techniques for creating NFTs that are alive, evolving, and connected to the world around them. This is a significant step beyond static collectibles and opens up a vast design space for innovative Web3 applications.

Key Takeaways:

  • Dynamic tokenURI: The core of a dNFT is a tokenURI function that programmatically constructs metadata based on current state.
  • On-Chain SVGs: Generating SVG images and Base64 encoding them into a data URI is a powerful method for creating fully on-chain, permanent, and dynamic NFTs.
  • Oracles for External Data: Services like Chainlink are essential for bridging the gap between the deterministic blockchain and real-world data, enabling NFTs to react to events like price changes or random outcomes.
  • Automation for Autonomy: Using a service like Chainlink Automation allows dNFTs to update themselves without requiring manual transactions, creating truly autonomous on-chain agents.
  • Architectural Trade-offs: You understand the difference between fully on-chain metadata (like SVGs) and hybrid approaches (like Tableland) and their respective trade-offs.

Next Steps:

This lesson concludes our deep dive into the world of NFTs. We've built marketplaces, auction systems, and now dynamic, evolving tokens. The next logical step is to move our creations from the local development environment and testnets to a production environment where users can interact with them.

In our next lesson, we will begin a new module on the multi-chain ecosystem by learning how to deploy and verify a contract to an Ethereum Layer 2 network (e.g., Arbitrum, Optimism), a critical skill for launching scalable, low-cost applications.

Can't find a good explanation? Sign up and we'll make it for you

Sign up