Figment Datahub and Celo Network: Create an ERC1155 NFT on the Celo Network using Figment Datahub and Objects Stored on Filebase

Learn how to create a ERC1155 NFT on the Celo Network using Figment Datahub and objects stored on Filebase.

What is ERC1155?

ERC1155 is a novel token standard that aims to take the best from previous standards to create a fungibility-agnostic and gas-efficient token contract. ERC1155 draws ideas from all of ERC20, ERC721, and ERC777. ERC1155s are commonly used in NFT collectible projects, although they are not typically viewed as 'fine art' it is not unreasonable to use this token standard for such purposes.

What is Celo?

Celo is a global payment infrastructure platform for cryptocurrencies that targets mobile device end users.

What is Figment DataHub?

Figment DataHub is a platform that enables developers to create decentralized applications (dApps) using the powerful and unique features of blockchain technology without having to be experts on the wide variety of blockchain protocols.

Prerequisites:

This guide was written and tested using Ubuntu 20.04. Commands and workflow may vary depending on your operating system.

1. Login to your Figment Datahub console. Select ‘Create App’ to create a new Celo app.

2. Give your app a name, select ‘Staging’ for the environment, then select ‘Celo’ for the network.

Then use the ‘Create App’ button to create your new Celo app.

3. Once you’ve created your app, take note of the API key.

We will reference this API key later.

4. Next, we need a Filebase IPFS bucket.

To do this, navigate to console.filebase.com. If you don’t have an account already, sign up, then log in.

5. Select ‘Buckets’ from the left side bar menu, or navigate to console.filebase.com/buckets.

Select ‘Create Bucket’ in the top right corner to create a new bucket.

6. Enter a bucket name and choose the IPFS storage network to create the bucket.

Bucket names must be unique across all Filebase users, be between 3 and 63 characters long, and can contain only lowercase characters, numbers, and dashes.

7. Next, select the bucket from your list of buckets, then select ‘Upload’ in the top right corner to upload an image file.

8. Select an image to be uploaded.

Once uploaded, it will be listed in the bucket.

9. You can view the object’s IPFS CID in the CID column, or you can click on your uploaded object to display the metadata for the object, which includes the IPFS CID.

Choose the method you prefer, and take note of the IPFS CID.

10. Upload as many images as you’d like to use for your NFT collection and take note of the CID for each one.

11. Next, download and install S3FS-FUSE on a Linux or macOS system.

12. Set up Access Keys.

Set up a credentials file for S3FS at ${HOME}/.passwd-s3fs.

You will need to save your Filebase Access and Secret keys to this file and give it owner permissions. You can do so with the following commands:

echo ACCESS_KEY_ID:SECRET_ACCESS_KEY > ${HOME}/.passwd-s3fs

chmod 600 ${HOME}/.passwd-s3fs

ACCESS_KEY_ID is your Filebase Access key, and SECRET_ACCESS_KEY is your Filebase Secret key. For more information on Filebase access keys, see here.

13. Mount your bucket.

You can mount a Filebase IPFS bucket with the command:

s3fs mybucket /path/to/mountpoint -o passwd_file=${HOME}/.passwd-s3fs -o url=https://s3.filebase.com

  • mybucket: name of your Filebase bucket

  • /path/to/mountpoint

14. Now, navigate into the mounted Filebase bucket.

cd /path/to/mounted/bucket

15. Next, create a new folder to house your NFT collection scripts and navigate inside of it.

mkdir nftcollection

cd nftcollection

16. Initialize your npm workspace:

npm init

17. Then install the required npm dependencies:

npm install --save-dev hardhat

npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers web3 @celo/contractkit

18. Create a new Hardhat project with the following command:

npx hardhat

During the Hardhat initialization, select ‘Create a sample project’.

19. Next, install the OpenZeppelin ERC1155 library with the following command:

npm install @openzeppelin/contracts

touch contracts/NFTCollection.sol

This command also creates a new file called NFTCollection.sol

20. Open the NFTCollection.sol file and input the following content:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
contract NFTCollection is ERC1155 {
  // TODO
}

21. In this file, replace the // TODO text with the following:

uint256 public constant CLOUD = 0;
uint256 public constant BUTTON = 1;
uint256 public constant ROBOT = 2;

22. For each NFT ID, create a .json file with the naming scheme of {id}.json.

For example, for the CLOUD NFT with an ID of 0, we would create 0.json with the following content:

{
  "name": "Cloud",
  "description": "Filebase Cloud",
  "image": "https://ipfs.filebase.io/ipfs/{IPFS-CID}"
}

Replace the {CID} with the CID associated with the image uploaded to your Filebase bucket.

23. Next, add the following content into the NFTCollection.sol contract below the lines you created to list your NFT names and their values:

constructor() ERC1155("/local/path/to/json/files/{id}.json") {
    }
    
    //If you do not have a Cloud the contract will let you buy one
    function mintVillage() public{
        require(balanceOf(msg.sender,CLOUD) == 0,"you already have a Cloud ");
        _mint(msg.sender,CLOUD,1,"0x000");
    }
    
    //If you do not have a Button and have a Cloud the contract will let you buy the Button
    function mintMine() public{
        require(balanceOf(msg.sender,CLOUD) > 0,"you need to have a Cloud");
        require(balanceOf(msg.sender,BUTTON) == 0,"you already have a Button");
        _mint(msg.sender,BUTTON,1,"0x000");
    }
    
    //If you do not have a Robot and have a Cloud the contract will let you buy the Robot
    function mintFarm() public{
        require(balanceOf(msg.sender,CLOUD) > 0,"you need to have a Cloud");
        require(balanceOf(msg.sender,ROBOT) == 0,"you already have a Robot");
        _mint(msg.sender,ROBOT,1,"0x000");
    }

24. Next, open your hardhat.config.js file and set Solidity to the same version number that we set inside of our NFTCollection.sol contract:

module.exports = {
  solidity: "0.8.0",
};

25. Before you can compile, you need to delete the file contracts/Greeter.sol.

This file will interfere with the contract file we created when we compile it.

26. Compile your smart contract with the command:

npx hardhat compile

27. Now we need to create a Celo account to mint our contract on the Celo network.

Create a new file called celo_account.js with the following content:

const Web3 = require('web3')
const fs = require('fs')
const path = require('path')
const web3 = new Web3()
const privateKeyFile = path.join(__dirname, './.secret')

// Function getAccount will return the address of your account
const getAccount = () => {
    const secret = fs.readFileSync(privateKeyFile);
    const account = web3.eth.accounts.privateKeyToAccount(secret.toString())
    return account;
}

// Function setAccount will create new account and save the privateKey in .secret file 
const setAccount = () => {
    const newAccount = web3.eth.accounts.create()
    fs.writeFileSync(privateKeyFile, newAccount.privateKey, (err) => {
        if (err) {
            console.log(err);
        }
    })
    console.log(`Address ${newAccount.address}`)
}
module.exports = {
    getAccount,
    setAccount
}

28. In the hardhat.config.js file, enter the following lines to import the required Celo modules:

const fs = require('fs')
const path = require('path')
const privateKeyFile = path.join(__dirname, './.secret')
const Account = require('./celo_account');

Then under the existing tasks in that file, insert the following task:

task("celo-account", "Prints account address or create a new", async () => {
    fs.existsSync(privateKeyFile) ? console.log(`Address ${Account.getAccount().address}`) : Account.setAccount();
});

29. Next, create a file called celo_deploy.js.

In this file, insert the following code:

const Web3 = require('web3')
const ContractKit = require('@celo/contractkit')

const web3 = new Web3('https://celo-alfajores--rpc.datahub.figment.io/apikey/Datahub CELO API Key/')
const kit = ContractKit.newKitFromWeb3(web3)
const data = require('./artifacts/contracts/NFTCollection.sol/NFTCollection.json')
const Account = require('./celo_account');

async function NFTCollection() {
    const account = Account.getAccount()
    kit.connection.addAccount(account.privateKey) 
    let tx = await kit.connection.sendTransaction({
        from: account.address,
        data: data.bytecode
    })
     return tx.waitReceipt()
}
module.exports = {
    NFTCollection
}

Replace the DataHub CELO API Key with the Figment DataHub API key we took note of at the beginning of this tutorial.

30. Open the hardhat.config.js file again and add another task for deploying our contract:

const Deploy = require('./celo_deploy');

task("celo-deploy", "Prints account address or create a new", async () => {
    const tx = await Deploy.NFTCollection();
    console.log(tx);
    console.log(`save the contract address ${tx.contractAddress}`)
});

31. Run this celo-deploy script to deploy your contract:

npx hardhat celo-deploy

This will return your contract address.

From here, you can use this contract to interact with your NFT. You can use it in an application, such as a React App, that allows users to interact with your NFT collection through a user interface. Check out an example React App here.

Last updated