kulkarohan / zdk

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cryptomedia Collections

"The creator community will be equally as important to this next crypto boom as the developer community was to the DeFi boom SS 2020. The goal of tools in the creator boom should be the same: maximize liquidity optimization for market suppliers and reward community. The suppliers aka market makers in this case, however, are the creators." - https://zora.co/blog/creative-composability

This hack is an attempt to get closer to that goal.

A common theme among recent conversations with middle-class / emerging artists is that many want their art in as many hands as possible.

Fractional.art helps this -- but long-term I think it'd be great to embed fractionalization (or something similar) into Zora's protocol itself.

After tinkering inside ourzora/core, I discovered a way to build similar functionality without touching the contracts at all, but through the ZDK.

First I'll show the complete minting process then explain the changes.

All Together!

import { Zora } from '@zoralabs/zdk'
import { Wallet } from 'ethers'
import {
  constructBidShares,
  constructCollectionData,
  constructCollectionMediaData,
  mintCollection,
  generateMetadata,
  sha256FromBuffer,
} from '@zoralabs/zdk'

const wallet = Wallet.createRandom()
const zora = new Zora(wallet, 4)

const contentHash = sha256FromBuffer(Buffer.from('testing zora collections ...'))
const collectionSupply = 4

const collectionData = constructCollectionData(contentHash, collectionSupply)

const metadataJSON = generateMetadata('zora-20210101', {
  version: 'zora-20210101',
  name: 'testing zora collections ...',
  description: collectionData['mediaTree'],
  mimeType: 'text/plain',
})

const metadataHash = sha256FromBuffer(Buffer.from(metadataJSON))
const metadataURI = 'https://ipfs.io/ipfs/QmaipCiN95UGEHRkxVWYmj8bcAYeyxL9LqjHACpvWzcHAt'
const contentURI = 'https://ipfs.io/ipfs/QmXxUwtS2HaCGpY3kKDs7ncy79pu92YZ1KtawQjmox6naf'

const collectionMediaData = constructCollectionMediaData(
  collectionData,
  contentURI,
  metadataURI,
  metadataHash
)

const bidShares = constructBidShares(
  10, // creator share
  90, // owner share
  0 // prevOwner share
)

mintCollection(collectionMediaData, bidShares, zora)

/** Rinkeby Transaction Hashes
 * 0x824e8147861840abc105023e2af161c5b72bfb39c8478541c2102704a2160161 (ZORA Token ID 3565)
 * 0x5af4b4214d6d29bd1ea4e8ea0d6def373a4f8cfcf4469ab2520c6a03f2422b32 (ZORA Token ID 3566)
 * 0x3e4d8cf7eb2e04cc2910267e3713d39503fa69e57a6b2dea0ddbbdd276fa0f09 (ZORA Token ID 3567)
 * 0xc4b9ef87a3d6a6a896f78808f25cae06f63b91b6991dba0715095c2ba9488913 (ZORA Token ID 3568)
 */

Some Notes

Collections invert fractionalization by allowing a creator to create "copies" of their NFT, instead of dividing it to pieces. Each "copy" still contains all the properties of cryptomedia.wtf, but what makes it a part of a collection is it points to a merkle tree proving its relation to the rest of the supply.

I see this is a building block towards a platform enabling creators to exercise features like "anyone who holds a piece of collection X will receive Y amounts of Z in the future" on Zora.

A few features/TODOs for this initial MVP:

  • A metadata scheme for collections to ensure the merkle tree is stored upon minting
  • Utility functions to verify an NFT's existence in a collection
  • Allow multiple content hashes so creators can create a collection of different NFTs (eg. Punks) natively on Zora

*ik you guys already use the term 'collection' but since its a cool term and this is just a mvp im rolling with it

Technical Details

CollectionData

A CollectionData type composed of four fields:

type CollectionData = {
  mediaSupply: number // Number of media files in collection
  mediaContentHashes: BytesLike[] // Content hashes of media in collection
  collectionHash: BytesLike // Root of collection's merkle tree
  mediaTree: string // JSON representation of collection's merkle tree
}

constructCollectionData

CollectionData is generated by the constructCollectionData function, which expects two parameters: contentHash and supply

This function utilizes three custom helper functions:

  • validateSupply ensures the number provided for supply is an integer
  • constructCollectionContentHashes uses the provided contentHash to generate unique content hashes for each media in the collection
  • constructCollectionTree uses the new content hashes to construct a merkle tree of the collection

Returns a populated CollectionData type

constructCollectionMediaData

Wraps constructMediaData by taking

  • a populated CollectionData type, and
  • existing ZDK properties tokenURI, metadataURI, and metadataHash

to construct MediaData for each media in a collection.

Returns an array of populated MediaData types

mintCollection

Wraps zora.mint by taking

  • a MediaData array returned by constructCollectionMediaData
  • BidShares returned by constructBidShares, and
  • an instance of Zora

and mints each media in a collection.

Feedback

hmu kulk#3357 on Discord

About

License:MIT License


Languages

Language:TypeScript 99.7%Language:JavaScript 0.3%