LogoLogo
Manifold for Developers
Manifold for Developers
  • Introduction
  • Shopify Merch Bridge
    • Overview
    • Tutorial
      • Step 1: Product Gate Setup
        • 1.1: Configure the Product
        • 1.2: Install Manifold Merch Bridge
        • 1.2: Create a New Product Gate
        • 1.3: Link a Product to the Gate
        • 1.4: Add Rules
      • Step 2: Store Theme Setup
        • 2.1 The Theme Editor
        • 2.2 Product Page Setup
        • 2.3 Cart Page Setup
    • Advanced Configuration
    • FAQ / Error Help
    • Reference
      • Product and Gate Configuration
        • Shopify Products
        • Product Gates
          • Gate Products
          • Rules
      • Custom Themes
      • Updating to the Latest Version
      • UI Configuration Options
      • Advanced Usage
      • Common Issues
  • Guides
    • Getting Started
    • HTML
    • React
    • NextJS
    • Vue
    • Wix
    • Squarespace
      • Simple Squarespace Site
      • Customised Squarespace Template
  • Resources
    • Apps
      • Grant Types
    • Widgets
      • Directory
      • Manifold CSS Variables
        • Scheme Utility Classes
        • List of Manifold CSS Variables
      • Connect Widget
        • Blockchain Interaction
        • Wallet Authentication
        • Data Client
          • NFT Information Retrieval
            • getNFT
            • getNFTsOfOwner
            • ownerHasNFT
            • getCollectors
          • Data Storage and Retrieval
        • Advanced Configuration
        • Customization & Styling
        • Automatic Error Handling
      • Campaign Widget
        • Campaign Creation
          • Questionnaire
        • Campaign Progress
        • Customization & Styling
      • Curation Widget
      • Marketplace Widgets
        • Widgets
          • Data Attributes
          • Layout Widgets
          • Card Widgets
          • Listing Widgets
        • Window Events
        • Troubleshooting
        • Customization & Styling
        • Version Change Notes
          • 3.2.1 - CSS Selector Changes
          • 3.1.1 - CSS Selector Changes
      • Claim Widgets
        • Widgets
          • Data Attributes
          • Complete Claim Widget
          • Buy Button Only Widget
          • Mint Count Widget
        • Troubleshooting
        • Customization & Styling
        • Version Change Notes
          • 1.7.0, 1.7.1 - CSS Selector Changes
      • Restricted Token Widget
        • Customization & Styling
      • Wallet Identity Widget
        • Customization & Styling
      • Subscription Widget
      • 6551 Display Widget
    • Manifold Ethereum Provider
  • Tools and APIs
    • Merkle Tree Tool
    • Snapshot Tool
    • Discord Tools
    • Server-Side Session Authentication
      • Signature Grant
      • Authorization Code Grant
  • Smart Contracts
    • Manifold Creator
      • Contracts
        • Creator Core
          • Common Functions
          • ERC721 Functions
          • ERC1155 Functions
        • Extensions
          • Extensions Functions
          • Extensions Examples
          • Extensions Deployment Guide
            • Dynamic NFT Extension
            • Lazy Mint Extension ERC1155
            • Lazy Mint Extension ERC721
        • Mint Permissions
          • Mint Permissions Functions
      • Prior Versions
        • 1.0.x
          • Creator Core
            • Common Functions
            • ERC721 Functions
            • ERC1155 Functions
          • Extensions
            • Extensions Functions
            • Extensions Examples
            • Extensions Deployment Guide
              • Dynamic NFT Extension
              • Lazy Mint Extension ERC1155
              • Lazy Mint Extension ERC721
          • Mint Permissions
            • Mint Permissions Functions
        • 2.0.x
          • Creator Core
            • Common Functions
            • ERC721 Functions
            • ERC1155 Functions
          • Extensions
            • Extensions Functions
            • Extensions Examples
            • Extensions Deployment Guide
              • Dynamic NFT Extension
              • Lazy Mint Extension ERC1155
              • Lazy Mint Extension ERC721
          • Mint Permissions
            • Mint Permissions Functions
    • Marketplace
      • Identity Verifier
    • Royalty Registry
  • Contact Us
Powered by GitBook
On this page
  • Intro
  • Contract
  • How to Deploy
  • FAQ

Was this helpful?

  1. Smart Contracts
  2. Manifold Creator
  3. Prior Versions
  4. 1.0.x
  5. Extensions
  6. Extensions Deployment Guide

Lazy Mint Extension ERC721

Intro

Another common ask is how to do lazy-minting with Manifold. If you're unfamiliar, lazy-minting is a technique by which minting costs are passed on to the buyer. This makes sense in many situations (especially collectible-style projects), but does not make sense in others. We'll take a look at the contract and how to deploy it here, but I would not suggest doing this for collections of less than, say, 20 tokens. The reason for this is that deploying an extension costs gas! And on a smaller scale, the savings from lazy-minting are less than the cost to deploy the contract.

Anyway, let's take a look. We'll do this with a contract that mints ERC721 tokens to your base contract.

Contract

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";
import "@manifoldxyz/creator-core-solidity/contracts/core/IERC721CreatorCore.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/ICreatorExtensionTokenURI.sol";

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

contract Tutorial3 is AdminControl, ICreatorExtensionTokenURI {

    using Strings for uint256;

    address private _creator;
    string private _baseURI;

    constructor(address creator) {
        _creator = creator;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(AdminControl, IERC165) returns (bool) {
        return interfaceId == type(ICreatorExtensionTokenURI).interfaceId || AdminControl.supportsInterface(interfaceId) || super.supportsInterface(interfaceId);
    }
    
    function mint() public {
      IERC721CreatorCore(_creator).mintExtension(msg.sender);
    }

    function setBaseURI(string memory baseURI) public adminRequired {
      _baseURI = baseURI;
    }

    function tokenURI(address creator, uint256 tokenId) external view override returns (string memory) {
        require(creator == _creator, "Invalid token");
        return string(abi.encodePacked(_baseURI, tokenId.toString()));
    }
}

Let's walk through the contract here before we think about deploying it.

The first function we have there is the constructor and this is called when we deploy the contract. At the time of deployment we must pass in the _creator (the address of your creator core contract). We have that so we can interact with it later when minting.

The supportsInterface function simply tells other contracts that are calling this one what functions it supports.

The mint function is where we allow other people to mint more tokens on this contract. You can see that it is pretty simple, it really just calls the mintExtension function to mint a token to the person who sent the transaction. Note that we do not specify a tokenURI here. This is because the core contract will hook back into this contracts tokenURI function later to get the URI.

The setBaseURI function lets us set the base for the tokenURI we want to return. It also lets us update this information at any time in the future.

The tokenURI function returns the base tokenURI concatenated with the tokenId. So in this case if your base tokenURI is https://arweave.net/abcd/ this will return https://arweave.net/abcd/1 for tokenId 1.

How to Deploy

You should be able to see your tokens on OpenSea TestNet. Here is the first of mine:

And here is the second

As you can see, these are token #1 and token #2 on the core contract. Notice the OpenSea URL which has the address of the core contract.

Congrats! You are done.

FAQ

Is this contract an EC721 contract?

No - but it helps you mint tokens on an ERC721 contract (your core contract)

What is the gas cost for deploying an extension like this?

This particular extension cost me 1,833,652 gas to deploy. At gas prices of 40 gwei, that would be about 0.07 ETH.

Last updated 2 years ago

Was this helpful?

Deploy core contract (using Manifold Studio is easiest) - example

Deploy the extension contract - example

Register the extension with #14 registerExtension on your base contract - example

Set the baseURI for your extension - example

Mint - example

Mint again - example

here
here
here
here
here
here
https://testnets.opensea.io/assets/0xe2c146396a37883ebd85b74f38e985e8d1ffc4f2/1
https://testnets.opensea.io/assets/0xe2c146396a37883ebd85b74f38e985e8d1ffc4f2/2