Why Art Blocks Uses JavaScript in Its Smart Contract | by Nazar Ilamanov | Apr, 2022

Artwork Blocks is a platform for creating on-chain generative NFTs. However have you learnt what’s really saved on-chain vs off-chain? And why do they want JavaScript of their sensible contract?

We’ll discover out by breaking down the sensible contract of Artwork Blocks. We will even find out about how pictures are generated/rendered and the place Artwork Blocks will get the randomness wanted to generate them.

Right here is the define of this text

  • Background on ERC-721 — the NFT commonplace
  • Artwork Blocks contract supply code
  • Producing the artwork

First, slightly background on Artwork Blocks.

Artwork Blocks is a platform (actually only a sensible contract) the place you’ll be able to create generative NFTs. Artists submit scripts that may generate pictures. Artwork Blocks shops these scripts and when somebody desires to mint an NFT, it creates a novel hash. This hash is used as a seed to the picture era algorithm and the generated picture can be distinctive to the minter.

Listed below are some examples of generated pictures:

Standard Artwork Blocks collections: Ringers, Chromie Squiggle, Fidenza.

In an effort to perceive the Artwork Blocks sensible contract, we first must find out about ERC-721. ERC-721 is a normal used for implementing NFT sensible contracts. In an effort to be thought-about ERC-721 compliant, a contract must implement these capabilities:

  • title and image are NFT descriptors. For instance, for Artwork Blocks, they’re “Artwork Blocks” and “BLOCKS”.
  • tokenUri – path to token metadata (picture url, rarity attributes, and so on)
  • totalSupply – depend NFTs tracked by this contract
  • tokenByIndex – return tokenId of token at specified index. index is [0, totalSupply).
  • tokenOfOwnerByIndex – enumerate tokens of owner and return tokenId at index
  • balanceOf – number of NFTs owner has
  • ownerOf – owner of specified token
  • approve – allow someone else to manage (transfer, sell, etc) one’s token. Used by 3rd parties, like OpenSea, to manage tokens. (There is a similar function setApprovalForAll(address _operator, bool _approved) which is like approve but gives permission for all tokens rather than just one. Skipped for brevity)
  • transferFrom – transfer the token. The caller needs to be a pre-approved address.

All NFT smart contracts need to implement the ERC-721 standard. This allows third parties like OpenSea to interact with the NFT contracts in a standardized way (all contracts will have the same ownerOf function, for example). Check out my article on BoredApeYachtClub smart contract breakdown to learn more about the ERC-721 standard.

Let’s now learn about how Art Blocks implements this standard and creates generative NFTs.

The blockchain backend of Art Blocks consists of just one big smart contract called GenArt721Core.sol. This smart contract is broken down into 2 pieces:

  1. a contract implementing the ERC-721 standard
  2. the main contract GenArt721Core.sol responsible for storing the data needed to render NFTs

GenArt721Core.sol inherits from the ERC-721 contract. The source code can be found on Etherscan and Github.

Art Blocks also has 2 more lightweight contracts: GenArt721Minter (mints tokens and accepts payments) and Randomizer (generates pseudo-random numbers). But these won’t be covered in this article.

ERC-721 implementation

Art Blocks implements the ERC-721 interface using an off-the-shelf implementation by OpenZeppelin. OpenZeppelin is a library of implementations of the most common standards.

The implementation has no surprises. Everything you would expect from a standard implementation:

  • They use mappings to manage ownership of tokens:
  • Here is how ownership is transferred:
  • and how approvals are managed:
  • Although, not part of the ERC-721 standard, OpenZeppelin’s ERC-721 implementation includes mint and burn functions:
  • The implementation has a few more mappings to store additional information (the setter/getter functions for these mappings will be omitted for brevity):
  • Finally, here are the rest of the ERC-721 functions:
  • The one leftover function from the ERC-721 spec, tokenUri, will be explained later in the article.

The man contract extends the ERC-721 contract to add functionality specific to Art Blocks: “storing project info” and “generating NFTs”. Let’s start with the storing project info part.

Storing project info

Each NFT collection is considered to be a separate project (like Chromie Squiggle, Ringers, etc). The main contract defines a data structure for a Project:

NFTs for all projects are stored in one big smart contract — we don’t create a new contract for each collection. All the projects are stored in one big mapping, called projects, where the key is just the index of the project (0,1,2,…):

As you may have noticed from the above screenshot, the contract uses a few more data structures to keep track of everything:

Let me explain the last 4 lines:

  • tokenId is the ID of an NFT and projectId is the ID of the project. The contract keeps track of the 2-way mapping between the two.
  • hash is the keccak256 hash value of the combination of [1) index of NFT, 2) block number, 3) block hash of prev. block, 4) address of the minter, 5) random value from a randomizer contract]. We’ll get to the randomizer contract in a bit. The hash worth is computed in the course of the mint perform:

The undertaking parameters may be modified by artists through a bunch of setters comparable to these:

However as soon as the undertaking is locked, many variables can by no means be modified.

That’s it for the “storing undertaking data” performance. Let’s transfer on to the subsequent performance applied by the GenArt721Core.sol contract.

The entry level for producing the artwork is the tokenUri perform. It’s one of many capabilities within the ERC-721 commonplace and is meant to return the metadata (like pictures or attributes) of the NFT. Right here is the implementation of tokenUri:

It has many if situations, nevertheless it’s primarily simply establishing the metadata path conditionally. Tasks have the choice of storing the metadata on IPFS (as a picture or a JSON file) or, if the undertaking is dynamic, the metadata may be served from a conventional HTTP API. Many of the initiatives are dynamic so we are going to give attention to that case.

For instance, the Fidenza assortment (projectId=78) has the next metadata path:

You will get this data from Etherscan. Simply scroll right down to “tokenURI”. If we navigate to this HTTP path, we get this JSON file:

Discover that the JSON file has a bunch of various data for trait varieties and undertaking descriptions. It additionally has a hyperlink to the precise picture:

So, what do you actually personal while you purchase an NFT? On this case, you simply personal the tokenId. tokenUri perform then maps the tokenId to both IPFS or HTTP hyperlink relying on the undertaking settings. This hyperlink both factors to the picture instantly or to a JSON that has attributes and a nested hyperlink to the picture.

However how is the picture generated/rendered? Sadly, the picture isn’t generated on-chain. The sensible contract solely shops a JavaScript script wanted to render the picture. Artwork Blocks’ frontend then queries this script and generates the picture on-demand in its conventional backend, not the blockchain backend.

Why is the picture not generated/rendered on-chain? It’s as a result of the scripts have library dependencies. The scripts depend upon widespread JavaScript libraries comparable to p5.js and processing that are generally utilized by designers to create generative pictures. It could be very costly to place these dependency libraries on-chain and that’s why pictures are generated off-chain.

The directions to render pictures (the rendering scripts) are saved on-chain although. You may test the saved scripts for your self by navigating to projectScriptInfo on Etherscan. It will present you what library dependency the undertaking script wants and what number of scripts it has (if script is just too lengthy, will probably be damaged down into many items):

The precise scripts are in projectScriptByIndex:

The scripts are saved as plain strings within the Challenge information construction:

You would possibly surprise how the random patterns within the NFT collections are generated. When producing the photographs, the frontend doesn’t pull simply the scripts from the sensible contract. It additionally pulls the hash string. Bear in mind the hash string?

This hash may be learn off from the contract from the tokenIdToHash mapping. The hash string is used because the enter/seed in the course of the picture era course of. The hash string controls the parameters of the picture (for instance, how squiggly the Chromie Squiggle turns into).

Numerous data is mixed to provide the hash. One of many inputs is the deal with of the minter. This manner, the minter participates within the picture era course of and the NFT turns into distinctive to the minter. (If another person have been to mint the identical token underneath the identical actual situations, he would get a distinct picture as a result of his deal with can be totally different).

One other enter to the hash is the returnValue from a randomizerContract. It seems that this contract isn’t open-source (not verified on Etherscan) so we are able to’t see its code. But it surely’s most certainly a pseudo-random quantity generator that generates random numbers on-chain from sources such because the block variety of the final mint.

More Posts