Build your own marketplace in minutes

OpenSea provides a one-stop shop for creating your own customizable marketplace for your non-fungible token (NFT) project. Allow users to smoothly buy and sell your items, get custom stats and analytics, and earn revenue when your items get traded.


1. Structuring your smart contract

Leveraging the ERC721 standard to make your items instantly tradeable on OpenSea

​Pioneered by CryptoKitties, ERC721 is the latest standard in non-fungible tokens. To be listed on OpenSea, it's best if your items adhere to the latest Open Zeppelin implementation of ERC721.

*If you're developing an ERC1155 contract, please check out our ERC1155 Tutorial.

OpenSea Creature Sample Contract

We've created a very simple sample repository to get you started. The full code for the sample can be found on Github.

The sample code is a collectible called OpenSea Creatures. OpenSea Creatures are pretty basic: they each have a unique look, traits, and attributes. While one day we may add more of a game around these creatures, for the purpose of this example, the main thing you can do with a creature is own it. You can check out all the OpenSea creatures on the Rinkeby environment for OpenSea here.

Creature ERC721 contract

pragma solidity ^0.5.0;

import "./TradeableERC721Token.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

 * @title Creature
 * Creature - a contract for my non-fungible creatures.
contract Creature is TradeableERC721Token {
  constructor(address _proxyRegistryAddress) TradeableERC721Token("Creature", "OSC", _proxyRegistryAddress) public {  }

  function baseTokenURI() public view returns (string memory) {
    return "";

As you can see, the contract itself is pretty simple. It just inherits from TradeableERC721Token, which in turn inherits from the OpenZeppelin ERC721 contracts (which implement all of the necessary ERC721 methods). You'll probably have more logic in your game, but the important piece for OpenSea is the tokenURI method, which allows us to map the tokenId's in the Creature contract to some metadata off-chain about the contract. We'll learn more about this in the next section.

OpenSea Whitelisting (optional)

Additionally, the ERC721Tradable and ERC1155Tradable contracts whitelist the proxy accounts of OpenSea users so that they are automatically able to trade any item on OpenSea (without having to pay gas for an additional approval). On OpenSea, each user has a "proxy" account that they control, and is ultimately called by the exchange contracts to trade their items.

Note that this addition does not mean that OpenSea itself has access to the items, simply that the users can list them more easily if they wish to do so. It's entirely optional, but results in significantly less user friction. You can find this code in the overridden isApprovedForAll method, along with the factory mint methods.

Next we'll learn about how to structure that metadata so it can be picked up by OpenSea.

Deploying your contract

To deploy the Creature contract, simply check out the repo, get a free Alchemy API key, and deploy with Truffle:

yarn install
export ALCHEMY_KEY="<your_alchemy_project_id>"
export MNEMONIC="<metamask>"
export NETWORK="rinkeby"
truffle deploy --network rinkeby

If you're using Infura API already, you can also use the INFURA_KEY environment variable instead of ALCHEMY_KEY.

Quick tip

You only need to run the export lines above once in your shell session. We recommend that you put those lines into a .env file, apply it once using . .env, and avoid checking it in when committing your code. There's a sample .env file here.

Note that in order to deploy with Truffle and Infura, you'll need a "seed phrase" from a MetaMask account that is funded with Ether. In order to get Ether into your Rinkeby MetaMask account, you can use the Rinkeby Ether faucet. You'll need to post a message to one of your social profiles and paste the link to your post in the test faucet. In order to obtain your "seed phrase" from Metamask click "settings" and click "reveal seed words". Make sure you don't share your seed phrase for any accounts containing Mainnet tokens!

Minting your tokens

Next, we'll want to mint new assets to our newly-deployed ERC721 contracts! We'll mint these assets into an account that we control so that we can test the OpenSea auction flow for our items.

After deploying to the Rinkeby network, there will be a contract on Rinkeby that will be viewable on Rinkeby Etherscan. You can find the address of the deployed contract in the output of the deployment command and find it on Etherscan by hitting the URL:<contract_address>.

For example, here is a recently deployed contract. You should set this contract address and the address of your MetaMask account as environment variables when running the minting script:

export OWNER_ADDRESS="<my_address>"
export NFT_CONTRACT_ADDRESS="<deployed_contract_address>"
node scripts/mint.js

What's next?

At this point, we've deployed our first smart contract on the Rinkeby network and minted some new OpenSea creatures on our contract. You should be able to visit and view your new creatures as NFTs inside your wallet! More on that in section 3.

The default metadata for the creatures is provided by{token_id}, which is set here. Next, you'll need create your custom metadata API.

Updated 2 months ago

What's Next

Let's learn more about the metadata associated with each CryptoPuff.

2. Adding metadata

1. Structuring your smart contract

Leveraging the ERC721 standard to make your items instantly tradeable on OpenSea

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.