How The ImmutableX NFT Contract Works
Toggle full transcript
Hello and welcome to chapter two of the Create Configure and Sell NFT collections on ImmutableX course.
In this chapter we're going to cover how to create NFTs on ImmutableX. This first lesson covers how the ImmutableX NFT contract works.
This chapter centres around a series of practical labs where we will interact with some source code to mint our first NFT
on ImmutableX. In this lesson, we're going to read through the Solidity code that makes up the smart contract that sits behind an immutable x NFT.
In order to mint an NFT on ImmutableX the Solidity smart contract of your NFT asset needs to implement two interfaces.
The first is the one that you can see here on the screen. IMintable. IMintable, as you can see, is a fairly simple interface.
It has a single method mintFor that takes an address, a quantity, and a series of bytes.
Now this mintFor method is what ImmutableX calls when it is minting an NFT the first time that it is withdrawn
from ImmutableX to Ethereum. The second interface that your contract needs to extend is
the Ownable interface, which is exposed by Open Zeppelin. And this just indicates that the token can actually be owned by someone.
Now, ImmutableX provide us the mental abstract class to make it easier to create an immutable X compatible contract.
You can see that the IMintable class here extends the owner and IMintable interfaces. Now, before we dive into the detail about what this Mintable class does,
let's have a look at a simple implementation of an NFT that extends this abstract class.
And here it is here, our asset class. And you can see that our asset class extends ERC-721 that again we're getting from Open Zeppelin and the IMintable abstract base
class provided by ImmutableX. By extending these two base classes, we're able to have a fairly simple
30 line Solidity file that creates an IMX compatible NFT. There's three methods here that we needed to implement.
One of them is the constructor which calls into the constructors of both ERC-721 and IMintable. It's up to you what you put in your constructor as long as you can call these
underlying constructors underneath. In this case, we take the address of the owner that we want to own
the NFT that's being minted. The name and symbol of that NFT and a base. Hooray. The other important one here is there's an address being cast in that denotes the
IMX layer one smart contract. This then gets passed into the IMintable base class and we'll talk in a second
about what that actually does. The other two methods are the mintFor method and the baseUri method. The mintFor method is an abstract method exposed by the IMintable
base class and the baseUri method is an abstract method exposed by the ERC-721 base class.
Mintfor is called by the IMintable Base class and will see the circumstances under which that gets cold. And essentially what we're doing here is we're just allocating to the safe Mint
method that's provided by ERC-721. The way this works is the Mintable base class handles the implementation
of when ImmutableX calls our contract to mint an NFT, when that NFTs first being withdrawn to Layer 1 from ImmutableX.
And so in this case, given we're implementing the ERC-721, which is proxying that call through to the 721 code.
Additionally, we just need to implement how the ERC-721 contract can figure out what the baseUri is for this smart contract.
In this case, the implementation is simple and we simply pass it in at the point in time that we construct this particular NFT through the constructor
and then pass that through. But equally, you can do more complex implementations if you want to. So we've covered our assets so far here.
This is the most basic implementation, but you can add other things if you want to. The real magic then is what happens in mint or bought or sold.
So let's have a look at that. Now, the key thing here that needs to be implemented is from the IMintable interface we had that meant for method.
That's the signature that IMX Smart contract is expecting for the moment in time when it needs to mint an NFT when it's being withdrawn to layer one.
And we can see here that there's an implementation of that meant for method. It takes the three parameters that we talked about before a user address,
a quantity and the Minting blob. And in this implementation, there's a few things going on here. Firstly, because we are meeting an NFT, if the quantity is greater than one, then we
actually throw an error. Secondly, we take this minting blob and we actually call this split command here.
Now this is provided in the utils slash Minting dot sole file. And essentially what it does is it allows for a
byte string that looks something like this token ID colon blueprint, where a blueprint can be any string that you want to pass through. This is simply the way that ImmutableX encodes this information.
Acknowledging that whenever you meet an NFT on ImmutableX, there will be an integer token ID and there will be a blueprint string that had been passed through
to the ImmutableX call. And we'll see that later on in the lapse in this chapter. Understanding the actual implementation of this method is left as an exercise to the
watcher. So once we've split out from our Minting blob byte array into the separate token ID and by
the right blueprint, we can then call our _mintFor method. And this is what we looked at in our asset.sol File.
So this is a abstract method that is left for you to implement. And in our basic implementation here, we simply, as we said before, delegate
to ERC-721. And in fact, in this case, we're ignoring that memory byte string. But if you wanted to, you could actually use it.
The other thing then that we do is we actually store that blueprint against that token ID, and that's stored in this blueprints property,
which you can see up here is a mapping from 256 bit unsigned integer to a byte string. And then we simply emit this AssetMinted event which is defined up here.
Now, in this case, we're not actually using this blueprint at all. But again, if you want to do more advanced use cases, then you can start using the
blueprint within your contract. The last thing that we need to cover here is this only owner or IMX method, which we're actually applying here as part of
the Mint for. This is really important because what it does is essentially delegates access
so that the IMX smart contract on Layer 1 has the permission to call this mintFor method on our behalf.
So if we come back to the constructor of this Mintable class. We can see that there's two addresses past in: the owner and the IMX address.
So if we go back to our asset.sol we can see we passed through an owner that we took in the constructor and an IMX address that we also
took in the constructor. The IMX address is a fixed address depending on the network that you're talking to. And if you go to the official IMX Contracts GitHub site
and scroll down on the Readme, you can actually find the official contract address for both the Goerli network and
mainnet as well. Thanks for joining me for this description of the ImmutableX compatible NFT Smart Contract. Now that we've done this, let's start diving into the labs,
which you can join me for in the next lesson.