Skip to main content

Get Started

In this getting started guide, we'll show you how to build and deploy a full web3 application.

By the end, you'll have a project that allows you to mint NFTs into an ERC721A smart contract that you created!

If you prefer, you can create a fork our Replit to explore the code directly.

Build A Contract

Smart contracts are the foundational layer of any web3 application; they store the state and logic of your project on the blockchain. We provide a variety of ways for you to build and ship contracts, ranging from audited and gas-optimized prebuilt solutions, to a Solidity SDK that provides the building blocks to create your own.

Getting Started Contracts Comparison

In this section, we're going to show you how to build a contract from scratch using Solidity. If you want to explore the prebuilt contracts we have available, check out the prebuilt contracts section and join us back here when you're ready to build your application!

Creating A Project

First, we can use the CLI to create a new project with a smart contract inside, and Extensions installed for us.

npx thirdweb create --contract

Let's name our project contracts and select Hardhat as our framework.

Next, select the ERC721 Base contract as our starting point, which gives us an implementation of the ERC721A NFT standard that we can modify and extend.

thirdweb CLI select base contract

Open up the project in your text editor - let's see what's inside 👀.

Exploring the project

Inside the contracts folder, you'll find a Contract.sol file; this is our smart contract written in Solidity!

If we take a look at the code, you can see that our contract is inheriting the functionality of the ERC721Base, by:

  1. Importing the contract.
  2. Inheriting the contract, by declaring that our contract is ERC721Base.
  3. Implementing any required methods such as the constructor.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@thirdweb-dev/contracts/base/ERC721Base.sol";

contract Contract is ERC721Base {
string memory _name,
string memory _symbol,
address _royaltyRecipient,
uint128 _royaltyBps

This pattern lets us incorporate functionality from other contracts inside of ours, modify it, and add our own custom logic on top. For example, our contract currently implements all of the logic inside the ERC721Base.sol contract.

Adding Functionality

Base contracts work out of the box without any additional code required, but you might want to add additional functionality. Let's see how we can both override and extend the base contract.

Adding A Feature

Features are a great way to add individual pieces of functionality to your contract, such as Permissions.

You can follow the same pattern as we did with the base contract:

  1. Import it
import "@thirdweb-dev/contracts/extension/PermissionsEnumerable.sol";
  1. Inherit it
contract Contract is ERC721Base, PermissionsEnumerable {
// ...
  1. Implement it
contract Contract is ERC721Base, PermissionsEnumerable {
string memory _name,
string memory _symbol,
address _royaltyRecipient,
uint128 _royaltyBps
// Give the contract deployer the "admin" role when the contract is deployed.
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);

That's it! We can now restrict who can call certain functions on our contract.

Adding Custom Logic

Let's combine our new feature with some custom logic to create a new function that only the admin role can call.

Above the constructor, let's add a powerLevel mapping that stores a power level for each NFT.

// A mapping is a key-value store that lets us keep data in our contract.
// Here, the key is the token ID, and the value is the power level for that NFT.
mapping(uint256 => uint256) public powerLevel;

Next, let's add a function that lets the admin role set the power level of an NFT:

function setPowerLevel(uint256 _tokenId, uint256 _powerLevel) external onlyRole(DEFAULT_ADMIN_ROLE) {
powerLevel[_tokenId] = _powerLevel;

Great! Now the admin wallet (the contract deployer) can set the power level for any NFT.

Override An Inherited Method

Finally, let's see how we can override a method in the base contract.

Let's say we want to add a power level to the NFT when it's minted.

We can override the mintTo method from the base contract, and add our custom logic inside.

function mintTo(address _to, string memory _tokenURI) public virtual override {
// Grab the next token ID being minted using an inherited view.
uint256 tokenId = nextTokenIdToMint();

// Here, "super" refers to the base contract.
// We are saying "run the mintTo method from the base contract".
super.mintTo(_to, _tokenURI);

// *then* we can add our custom logic on top:
powerLevel[tokenId] = tokenId;


We're ready for liftoff! 🚀 Let's deploy our contract to the blockchain, by running:

npx thirdweb deploy

That's it! 🥳 This command does the following:

thirdweb CLI - thirdweb deploy

From the dashboard, we can see all of the Extensions that our contract implements.

For each extension, we unlock capabilities in the dashboard and the SDK. We'll learn more about that in the next section.

First, we need to enter the parameters for our contract:

  • _name: The name of our contract
  • _symbol: The symbol or "ticker" given to our contracts tokens
  • _royaltyRecipient: The wallet address that will receive the royalties from secondary sales
  • _royaltyBps: The basis points (bps) that will be given to the royalty recipient for each secondary sale, e.g. 500 = 5%

Finally, select the network you want to deploy to (we recommend the Goerli test network), and click "Deploy Now".

Deploying your contract using the thirdweb dashboard

Your Contract Dashboard

Welcome to your very own contract dashboard! 🎉

thirdweb dashboard contract deployed state

Here, you'll find all of the information you need to interact with and manage your contract, including:

  • Explorer: call any function on your contract, and view the results.
  • Events: a live-updating feed of all events emitted by your contract.

As well as tabs for each extension that your contract implements:

You just built and deployed your own NFT smart contract! 🥳

That's a huge accomplishment, and we're so proud of you! 🎉 Tag us below to let us know what you shipped!

Share on Twitter