Skip to content

Secondary Royalties on OpenSea

Opensea is allowing the Contract Owner to set royalties on a whole token collection. That ownership is determined by querying a function called owner() in the smart contract.

If you ever wondered why you can't set secondary sales royalties on tokens minted by Mintable or Rarible its because you are not the contract owner - you are the token owner!

But here we're doing our own custom contract.

And the best part is: We don't have to write that functionality ourselves from scratch, because openzeppelin has everything already there. We just need to include it.

At the same time we can also add a mint functionality for the contract owner!

Ownable functionality

Let's add the ownable functionality first:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";


contract MinimalERC721 is ERC721, Ownable {
    constructor() ERC721("Minimal", "MIN") {}
}

If you do the same as before: deploy the token to the developer network and query the functions, then you see it now contains a "owner" function:

If you are logged into Opensea and you are the owner of the collection, then Opensea lets you set a secondary sales royalty.

We still cannot mint tokens. Let's add a minting functionality, so that the owner - and only the owner - can mint new tokens!

Mint tokens

To mint tokens we basically need two things:

  1. generate a unique token id for each token we mint
  2. somehow (potentially) limit who is allowed to mint tokens. In our example only the contract owner will be allowed to mint tokens.

Let's add the following functions to the contract:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MinimalERC721 is ERC721, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdTracker;
    constructor() ERC721("Minimal", "MIN") {}

    function mint(address _to) public onlyOwner {
        super._mint(_to, _tokenIdTracker.current());
        _tokenIdTracker.increment();        
    }
}

If you open the developer console again (truffle develop and then migrate --reset and then let token = await MinimalERC721.deployed()) then you see the functions which are available. You can mint tokens!

await token.mint(accounts[0]);

(await token.balanceOf(accounts[0])).toString()

Awesome, you can mint tokens. You are also your own contract owner. But how does Mintable and Rarible work?


Last update: March 28, 2022