# Lazy Mint Extension ERC1155

### 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 an ERC1155 contract, but something similar can be done with ERC721s.

### 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/IERC1155CreatorCore.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/ICreatorExtensionTokenURI.sol";

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

contract Tutorial2 is AdminControl, ICreatorExtensionTokenURI{

    address private _core;
    string private _baseURI;

    function initialize(address core) public adminRequired {
      _core = core;

      address[] memory to = new address[](1);
      to[0] = msg.sender;
      uint[] memory amounts = new uint[](1);
      amounts[0] = 1;
      string[] memory uris = new string[](1);
      uris[0] = "";

      IERC1155CreatorCore(_core).mintExtensionNew(to, amounts, uris);
    }

    function mint() public {
      address[] memory to = new address[](1);
      to[0] = msg.sender;
      uint[] memory tokenIds = new uint[](1);
      tokenIds[0] = 1;
      uint[] memory amounts = new uint[](1);
      amounts[0] = 1;

      IERC1155CreatorCore(_core).mintExtensionExisting(to, tokenIds, amounts);
    }

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

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

    function tokenURI(address core, uint256 tokenId) external view override returns (string memory) {
        require(core == _core, "Invalid token");
        return _baseURI;
    }
}

```

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

The first function we have there is called `initialize` and this is where we set ourselves up by minting the first copy of the token. In this case, we've hard-coded it to token #1. It is important to note that we're taking the assumption here that the extension will only be used for this token. When we call this function, we're saving the address of our *core* contract, and calling the `mintExtensionNew` function on it to mint the token.

The `mint` function is where we allow other people to mint more copies of this token. You can see that it is pretty simple, it prepares the input, and then calls `mintExtensionExisting` to mint another copy of an existing token (token #1 that we made in `initialize`).

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

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

The `tokenURI` function returns this URI. It is important to note that this *does not* follow the EIP-1155 spec (as the extension does not keep track of tokens itself, it only helps mint them). The base contract, of course, has the `uri` function specified by the spec.

### How to Deploy

1. Deploy your creator contract using Manifold Studio (in this example, you will want a 1155 contract)
2. Deploy the *extension* contract above using [remix](https://remix.ethereum.org/).
3. Register the extension with write as proxy function `#9: registerExtension` on your creator contract from step 1. You can access this function by visiting the etherscan page for your contract, then clicking `contract` -> `write as proxy`. You will want to enter the address from the extension contract from *step 2* in the `extension` parameter, and a blank space for the `baseURI` parameter.\
   ![](/files/j3K7w4rxJGPWvnYLZizk)
4. Set the baseURI for your extension with write function `#4. setBaseURI`. You can do this in via remix, or via the etherscan page for the extension contract.
5. Initialize the extension with write function `#2: initialize`. You can do this in via remix, or via the etherscan page for the extension contract.
6. Mint with write function `#3. mint`. You can do this in via remix, or via the etherscan page for the extension contract.

You should be able to see your token on OpenSea TestNet via:\
<https://testnets.opensea.io/assets/\\>\<CREATOR\_CONTRACT\_ADDRESS>/1

There are just a couple things to note here. The first is that this is token #1 on the *creator* contract. Notice the OpenSea URL which has the address of the *creator* contract. There are 2 tokens, and 2 owners. 1 of the tokens is owned by the wallet I called `initialize` with, and the other is owned by a wallet I called `mint` with.

### FAQ

**Is this contract an ERC1155 contract?**

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

**Can this deployed contract be re-used?**

Not in its current form. However, an extension can be written in such a way that it manages tokens for many different *core* contracts.

**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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.manifold.xyz/manifold-for-developers/smart-contracts/manifold-creator/contracts/extensions/extensions-deployment-guide/lazy-mint-extension-erc1155.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
