Properties

Projects and editions have certain properties that can be used to effect how the media is rendered. Let's look at getting the properties of an edition from it's animation_url( An Opensea metadata convention to display live media )

There is a details about the tokenURI and on-chain properties at the bottom of this page if you want to dig deeper.

Animation_Url

Each edition of a project has an animation_url property in it's metadata. This url is how the edition is viewed.

https://arweave.net/h6P9YDHh2c6FpJ-W_ZLh0vxZuQ8wCwci3rDht7MSX6w/?id=1&address=0x07428b7a16bf805787d3c3546c9b40a10dbd3a57

breaking it down

They are quite long so lets break it down. The first section points to the arweave transaction of the media of the project.

   arweave gatway                   transaction id
┌────────┴────────┐ ┌─────────────────────┴────────────────────┐
https://arweave.net/h6P9YDHh2c6FpJ-W_ZLh0vxZuQ8wCwci3rDht7MSX6w/

The second section is a "query string". key-value pairs of a specific edition. In this example the edition number, the seed number and the project smart contract address.
   edition  seed            project smart contract address
     ┌┴┐    ┌┴┐      ┌───────────────────┴──────────────────────┐
  ?id=1&seed=5address=0x07428b7a16bf805787d3c3546c9b40a10dbd3a57

TIP

On a smart contract level the first section is stored on-chain. The second part is generated from the smart contract state when the tokenURI function is called.

Url Params

Using the URLSearchParams APIopen in new window we can read the properties of the animation_url and use them to effect how the edition is rendered.

// create a url with the window location
const url = new URL(window.location.href)

// get all the properties
const projectContractAddress = url.searchParams.get("address")
const editionNumber = url.searchParams.get("id")
const seed = url.searchParams.get("seed")

Test Locally

When developing locally simply add a query string to the end of the url

http://localhost:8080/?seed=5
js module

url-params.js

// create a url with the window location
const url = new URL(window.location.href)

// get all the properties
export const projectContractAddress = url.searchParams.get("address")
export const editionNumber = url.searchParams.get("id")
export const seed = url.searchParams.get("seed")

import like so

import { projectContractAddress, editionNumber, seed } from "./url-params.js"

learn about modules hereopen in new window

script tag

Insert into html <body> before your javascript. Adds olta object as a global varible

<script>
   // create a url with the window location
   const url = new URL(window.location.href)

   // all the properties in an object named olta
   var olta = {
      projectContractAddress: url.searchParams.get("address"),
      editionNumber: url.searchParams.get("id"),
      seed: url.searchParams.get("seed")
   }
</script>

Access the params like so

olta.projectContractAddress
olta.editionNumber
olta.seed

Reading the url parameters is the key to making each edition unique and is the starting point for making them dynamic.

TokenURI

The data that is stored on-chain is used to generate a base64 encoded url that when decoded results in a json metadata for that edition.

Metadata is generated when tokenURI or tokenURIOfVersion is called on the contract. It will look like this:

{
  "name":"Name Of Project 1/10",
  "description":"Description of the project",
  "image":"https://arweave.net/h6P9YDHh2c6FpJ-W_ZLh0vxZuQ8wCwci3rDht7MSX6w/thumbnail.jpg",
  "animation_url":"https://arweave.net/h6P9YDHh2c6FpJ-W_ZLh0vxZuQ8wCwci3rDht7MSX6w/?id=1&address=0x07428b7a16bf805787d3c3546c9b40a10dbd3a57",
  "media_version":"0.0.1",
  "patch_notes":"https://arweave.net/h6P9YDHh2c6FpJ-W_ZLh0vxZuQ8wCwci3rDht7MSX6w/patchnotes.txt",
  "properties":{
    "number":1,
    "name":"Testing Token"
  }
}

On-Chain

Project properties

Certian propertys are shared across all editions of a project and are stored on-chain in the project contract. This is predominantly to save gas when minting editions but also gives collectors the assurance that the metadata isn't going anywhere.

propertytypedescription
namestringthe name of the project
symbolstringthe name of the project slugifyed and capitlized
descriptionstringthe description of the project
editionSizeuint256The total number of editions for the project
royaltyBPSuint256The royalty amount for secondary sales that goes to the royaltyFundsRecipient
royaltyFundRecipientaddressdefaults to creator address, can be set by the creator to any other address

url properties

When a project is created the urls of the media content are stored as a version.

datadescription
imagea list of urls and there content hashes
animation_urla version label following the semantic labeling convention
patchnotesa version label following the semantic labeling convention

These url's can be updated by the project creator by calling addVersion on the project smart contract. Every version is stored on-chain and the last added version is considered the most up to date media.

Learn more about versions
Version

A version is simply a list of urls that point to the media content and a label.

datatypedescription
urls{url: string, sha256hash: bytes32}[]a list of urls and their content hashes
labeluint8[3]a version label following the semantic labeling convention

As well as the url we also store a sha256 hash of the content found on that url.This hash is used to verify the content as it is possible for the creator to update the url.

an example version:

{
   urls: [
      // image
      {
         url: "https://url-of-thumbnail.com",,
         sha256hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
      },
      // animation_url
      {
         url: "https://url-of-live-artwork.com",
         sha256hash: "0x0000000000000000000000000000000000000000000000000000000000000000"
      },
      // patchnotes
      {
         url: "https://url-of-patch-notes-text-file.com",
         sha256hash: "0x0000000000000000000000000000000000000000000000000000000000000000"
      },
   ],
   label: [0,0,1]
}

Edition properties

Each edition has certain propertys that make it unique.

propertytypedescription
editionNumberuint256The unique number of the edition
seeduint256A unique number that is chosen when edition is minted (only seeded projects)
owneraddressThe owner of this edition