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 API 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 here
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.
property | type | description |
---|---|---|
name | string | the name of the project |
symbol | string | the name of the project slugifyed and capitlized |
description | string | the description of the project |
editionSize | uint256 | The total number of editions for the project |
royaltyBPS | uint256 | The royalty amount for secondary sales that goes to the royaltyFundsRecipient |
royaltyFundRecipient | address | defaults 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.
data | description |
---|---|
image | a list of urls and there content hashes |
animation_url | a version label following the semantic labeling convention |
patchnotes | a 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.
data | type | description |
---|---|---|
urls | {url: string, sha256hash: bytes32}[] | a list of urls and their content hashes |
label | uint8[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.
property | type | description |
---|---|---|
editionNumber | uint256 | The unique number of the edition |
seed | uint256 | A unique number that is chosen when edition is minted (only seeded projects) |
owner | address | The owner of this edition |