stacksgov / sips

Community-submitted Stacks Improvement Proposals (SIPs)
135 stars 81 forks source link

SIP-016 Metadata for Tokens #44

Closed friedger closed 2 years ago

friedger commented 3 years ago

This PR

friedger commented 3 years ago

I am looking for more real world examples like:

{
  "collection": "PoX Monks",
  "id": 1,
  "name": "PoX Monk 1",
  "image": "ipfs://ipfs/QmegB9FURt6Jz1kGbaQxNqhvoPk9G2b87rxUE1h9DLDbDF/PoX%20Monk%201.jpg",
  "attributes": [
    {
      "type": "body",
      "value": "buff monk"
    },
    {
      "type": "headwear",
      "value": "orange hat"
    }
  ]
}

Here we see additional properties: "collection" and "id", also "type" instead of "trait_type".

friedger commented 3 years ago

The SIP contains a JSON schema definition written in JSON. Makers of $65m NFT "First 5000 days" by Beeple mixed schema definition with schema values. Metadata should NOT look like this. While valid according to the sip, providing values in "description" fields is counter-intuitive.

{"title": "EVERYDAYS: THE FIRST 5000 DAYS", 
"name": "EVERYDAYS: THE FIRST 5000 DAYS", 
"type": "object", 
"imageUrl": "https://ipfsgateway.makersplace.com/ipfs/QmZ15eQX8FPjfrtdX3QYbrhZxJpbLpvDpsgb2p3VEH8Bqq", 
"description": "I made a picture from start to finish every single day from May 1st, 2007 - January 7th, 2021.  This is every motherfucking one of those pictures.", "attributes": [{"trait_type": "Creator", "value": "beeple"}], 
"properties": 
   {"name": {"type": "string", "description": "EVERYDAYS: THE FIRST 5000 DAYS"}, 
    "description": {"type": "string", "description": "I made a picture from start to finish every single day from May 1st, 2007 - January 7th, 2021.  This is every motherfucking one of those pictures."}, 
    "preview_media_file": {"type": "string", "description": "https://ipfsgateway.makersplace.com/ipfs/QmZ15eQX8FPjfrtdX3QYbrhZxJpbLpvDpsgb2p3VEH8Bqq"}, 
    "preview_media_file_type": {"type": "string", "description": "jpg"}, "created_at": {"type": "datetime", "description": "2021-02-16T00:07:31.674688+00:00"}, "total_supply": {"type": "int", "description": 1}, 
    "digital_media_signature_type": {"type": "string", "description": "SHA-256"},
    "digital_media_signature": {"type": "string", "description": "6314b55cc6ff34f67a18e1ccc977234b803f7a5497b94f1f994ac9d1b896a017"}, 
     "raw_media_file": {"type": "string", "description": "https://ipfsgateway.makersplace.com/ipfs/QmXkxpwAHCtDXbbZHUwqtFucG1RMS6T87vi1CdvadfL7qA"}}}
friedger commented 3 years ago

Example with extensive use of properties. Here trait definitions (that can be defined in attributes) and properties are mixed into the "properties" value.

{
"name": "foo",
"image": "bar",
"properties": {
  "making_of_video": {
     "display_type":  "uri",
     "trait_type": "string",
     "value": "protocol://identifier"
  },
  "video_md": {
   "display_type": "none",
   "trait_type": "xml", // string???
   "value": " <xs:element name="VIDEOMD" type="videoType"/>
        <xs:element name="VIDEOSRC" type="videoType"/>
        <xs:annotation>
        <xs:documentation>VIDEOMD: LC-AV Video Metadata Extension Schema. VIDEOMD contains technical ...
 </xs:documentation>
        </xs:annotation>
        <xs:complexType name="videoType">
        <xs:annotation>
        <xs:documentation>A complexType for encapsulating and organizing within a singleparent element ...
</xs:documentation>
        </xs:annotation>
     ..."
    },
 }
mardi00 commented 3 years ago

Hoi Axopoa here. For most of the NFT collections where the "source" is "hosted", a format like this would (maybe) be ok.

{
  "name": "PoX Monks",
  "description": "A unique collection of monks",
  "author": "Monks Studio",
  "version": 1,
  "date": 1631645313396,
  "items": [
    {
      "id": 1,
      "name": "PoX Monk 1",
      "source": "ipfs://ipfs/QmegB9FURt6Jz1kGbaQxNqhvoPk9G2b87rxUE1h9DLDbDF/PoX%20Monk%201.jpg",
      "attributes": [
        {
          "type": "body",
          "value": "buff monk"
        },
        {
          "type": "headwear",
          "value": "orange hat"
        }
      ]
    },
    {
      "id": 2,
      "name": "PoX Monk 2",
      "source": "ipfs://ipfs/QmegB9FURt6Jz1kGbaQxNqhvoPk9G2b87rxUE1h9DLDbDF/PoX%20Monk%201.jpg",
      "attributes": [
        {
          "type": "body",
          "value": "slim monk"
        },
        {
          "type": "headwear",
          "value": "blue hat"
        }
      ]
    }
  ]
}

Edit: Seems like I miss a lot of information. I will do my homework and come back

Jamil commented 3 years ago

For new collections, stxnft.com goes with a format that looks something like this:

{
  "collection": "StacksArmy",
  "name": "StacksArmy Captain #9",
  "image": "ipfs://ipfs/QmPPQBNKohiDYAnjKkdrQcf2LupqixFMEpyvnNWQXz7ozq/StacksArmy%20Captain%20%239.png",
  "attributes": [
    {
      "trait_type": "class",
      "value": "Captain"
    }
  ]
}

This is similar to the OpenSea metadata format, with the addition of the additional field collection.

This is because right now SIP-009 doesn't support "collection-level" metadata (ERC721Metadata for example, specifies name() and symbol() functions). I'm not terribly opinionated on whether this should be done at the contract level with an additional function to get the name/symbol, or whether it should be handled in get-token-uri as we do now.

To me, the OpenSea metadata format works just fine with this collection-level metadata caveat. I'd support either (a) an extension to SIP-009 allowing for NFT contracts to return a name and symbol (e.g., get-name and get-symbol functions which take no arguments), or (b) adopting a metadata format that is OpenSea + some field to specify the collection name.

friedger commented 3 years ago

Which properties should be required? This sip proposed "version", "name" and "image"

friedger commented 3 years ago

@MarvinJanssen This SIP tries to specifies metadata for any type of tokens. It should be applicable also for SIP-013 tokens (https://github.com/stacksgov/sips/pull/42). Does it make sense?

friedger commented 3 years ago

To me, the OpenSea metadata format works just fine with this collection-level metadata caveat. I'd support either (a) an extension to SIP-009 allowing for NFT contracts to return a name and symbol (e.g., get-name and get-symbol functions which take no arguments), or (b) adopting a metadata format that is OpenSea + some field to specify the collection name.

@Jamil I support b). I propose field "properties.collection".

MarvinJanssen commented 3 years ago

Thanks @friedger this is great. I think bringing in lots of real world examples makes sense (like you have been doing). We should tap into our friends in the EVM space and see what they are doing these days too. As long as there is a version field, mentioned in #42, then I think we can come up with anything.

Jamil commented 3 years ago

Which properties should be required? This sip proposed "version", "name" and "image"

On stxnft.com right now we'll render any metadata as long as name and image are provided.

However, are we going to require tokens which represent non-image data (e.g., bns, quotes) to have a corresponding render/image?

It'd certainly make things easier on my side but I'm not sure people will follow that for non-image NFTs.

friedger commented 3 years ago

This sip is mainly about sip compatible contracts, not about native assets, like bns.

BNS needs a wrapper!

It would be great to specify an algorithm to display tokens without image like identicon.

Non-image NFTs would still need some kind of image to represent on a marketplace assuming users use the marketplace with their eyes. We need to think about accessibility!

dantrevino commented 3 years ago

For new collections, stxnft.com goes with a format that looks something like this:

{
  "collection": "StacksArmy",
  "name": "StacksArmy Captain #9",
  "image": "ipfs://ipfs/QmPPQBNKohiDYAnjKkdrQcf2LupqixFMEpyvnNWQXz7ozq/StacksArmy%20Captain%20%239.png",
  "attributes": [
    {
      "trait_type": "class",
      "value": "Captain"
    }
  ]
}

This is similar to the OpenSea metadata format, with the addition of the additional field collection.

This is because right now SIP-009 doesn't support "collection-level" metadata (ERC721Metadata for example, specifies name() and symbol() functions). I'm not terribly opinionated on whether this should be done at the contract level with an additional function to get the name/symbol, or whether it should be handled in get-token-uri as we do now.

To me, the OpenSea metadata format works just fine with this collection-level metadata caveat. I'd support either (a) an extension to SIP-009 allowing for NFT contracts to return a name and symbol (e.g., get-name and get-symbol functions which take no arguments), or (b) adopting a metadata format that is OpenSea + some field to specify the collection name.

The specification for metadata should apply to individual NFTs ... for collection data, that should be included in attributes. ie. a "collection" is not an nft. Ie for Boom NFTs the metadata would look something like this below.

{
  "name": "Foo #101",
  "image": "ipfs://somerandomecid",
  "attributes": [
    { "collection_name":  "Foo Collection" },
    { "collection_size":  "10000" },
  ],
  "properties": {
    "prop_1": {
      "prop_type": "string",
      "display_type": "string",
     "value": "foo",
    },
    "prop_2": {
      "prop_type": "number",
      "display_type": "number",
      "value": 99,
    },
  },
    "localization": {
      "uri": "ipfs://somerandomcid/{locale}.json",
      "default": "en",
      "locales": ["en", "ar-eg", "de"]
  }
}

Further I suggest: name - required image - required, can be blank attributes: optional. Client may optionally display. properties: optional. Client may optionally display.

friedger commented 3 years ago

@dantrevino properties and attributes should be swapped, shouldn't it? At least that is how opensea defines it: https://docs.opensea.io/docs/metadata-standards#metadata-structure

attributes consists of trait_type, display_type and value.

properties can be anything.

dantrevino commented 2 years ago

@dantrevino properties and attributes should be swapped, shouldn't it? At least that is how opensea defines it: https://docs.opensea.io/docs/metadata-standards#metadata-structure

attributes consists of trait_type, display_type and value.

properties can be anything.

yup got that backwards

friedger commented 2 years ago

@Jamil Thank you for your review!

friedger commented 2 years ago

What is a good way to describe image_hash ?

zone117x commented 2 years ago

Thanks for initiating this SIP @friedger. Something I'd like to point out is that this SIP does not include requirements needed for implementing NFT metadata support in the current Stacks Blockchain API. See issue https://github.com/hirosystems/stacks-blockchain-api/issues/846

For example, the SIP does not include anything related to making the metadata easily (and at scale) accessible for a Stacks Node event observer such as the API. That would entail something like a print (AKA contract log event) requirement to output the NFT metadata URI (possibly more, like all mandatory properties of the metadata schema) on NFT mints. It also doesn't address a concern that has been brought up a few times around "refreshing" NFT metadata, for example, a metadata "reveal" sometime after an NFT is minted. That would likely also entail something like a contract log event to inform consumers to "re-resolve" the metadata for a given NFT.

These concerns may be out of scope for this SIP, but I figured it would be good to bring up in case anyone was planning on API support related to this SIP.

dcsan commented 2 years ago

@friedger re raw media - things like real world addresses, maybe thats too much feature creep? personally I'd like to nail digital assets first without adding the kitchen sink.

Did you see this example from the solana ecosystem just allowing files to be added. isn't this similar to the spec for files and folders for IPFS?

dcsan commented 2 years ago

one other comment, this might not be the place.. but when minting an NFT on a gas-cheap chain like STX, i'd like to add metadata to allow customization of NFTs, and keeping some of that data on-chain.

SIP009 sets out the transfer fn but it doesn't take any extra optional parameters.

so while this spec allows for richer metadata, i'm wondering where that metadata lives. For simple text metadata, we might want to look at eventually removing the need for external URLs and just exposing it directly from the contract (much like solidity allows for SVG data on-chain). Hence standardized functions for getting data in, and reading it back out, and also a very simple and type-limited version (no 'any') of the spec since Clarity is so strict on types.

dantrevino commented 2 years ago

Thx @friedger other than the any comment from @kyranjamie looks good

zone117x commented 2 years ago

@friedger you mentioned this PR supersedes https://github.com/stacksgov/sips/pull/18 -- is NFT class-level metadata intended to be out of scope? The previous PR specified a (get-nft-meta () ... ).

The API has some initial support for resolving and indexing NFT class metadata (similar to FT metadata), but it's disabled by default, and was pending ratification of the previous NFT metadata PR. See issue https://github.com/hirosystems/stacks-blockchain-api/issues/742

dantrevino commented 2 years ago

Actually @zone117x reminds of a good point ...

One thing that should be added to the SIP, imho, is that a protocol is not specified.

https://, ar://, ipfs://, sia://, etc, etc, as well as any future protocols should all be valid.

friedger commented 2 years ago

Section about uri schemes has been added @dantrevino

Metadata function have their own section now @zone117x As the metadata is not stored on-chain the api node is maybe not the right place to cache the meta data.

I have added more properties to make the metadata compatible with opensea. I even removed the requirement for a value of properties. I refused to add youtube_url because in a few years nobody knows what youtube was. I added a generic files property taken from metaplex (solana). @dcsan

dcsan commented 2 years ago

I came across this project which is one of the first "on chain" STX generative art projects I've seen: https://stxplates.xyz/

discussion: https://discord.com/channels/621759717756370964/877879077569171456/911219717610545193

This uses a 'bytes' field to expose some metadata from the contract, used for rendering the generative art.

Since clarity requires the exact string len, emitting metadata directly from the contract in the tokenURI seems very impractical. But this bytes field approach where the seed for the artwork is always the same length is very practical. This is similar to artblocks (docs link) which just passes in the last mint hash. It makes the artwork deterministic and reproducible which is critical for value - not just random each time.

The contract metadata for Plates is like below, but perhaps this bytes field (or seed maybe?) could go elsewhere in the final JSON hierarchy.

I think the process is a bit duplicative since the JSON metadata here is just stored in IPFS, not read in realtime from the contract. But all of the required data to render the artwork is inside the contract, and the json could be reconstructed, so buyers can be assured their art isn't going to vanish at some point

contract: https://explorer.stacks.co/txid/0x88ccc25f363d443316befe51b56ceac4a9b8a1c4283b3ce0ed70da93a53722ee?chain=mainnet

returns: (ok (some "ipfs://Qmd4zgFFhe85roe9e9zDVzP5GquaRAgbV7KaS524mMVQaz/624.json"))

so view it here: https://ipfs.io/ipfs/Qmd4zgFFhe85roe9e9zDVzP5GquaRAgbV7KaS524mMVQaz/624.json

gives

{
"external_url": "https://stxplates.xyz",
"image": "ipfs://QmNNfMNaH7wJkhhkfpyDyiLy5VEKbncoQ7oknv6ZGqSN1d/624.png",
"description": "STXPLATES is a collection of 10,000 randomly generated, unique, on-chain NFTS for the Stacks community. This is plate 44L5GHE6R",
"name": "44L5GHE6R",
"attributes": [
{
"trait_type": "Text",
"value": "44L5GHE6R"
},
{
"trait_type": "Text Color",
"value": "#F90F1B"
},
{
"trait_type": "Background Color",
"value": "#B5E3FC"
},
{
"trait_type": "Border Color",
"value": "#303649"
}
],
"artist": "@txp0st",
"collectionSize": 10000,
"index": 624,
"bytes": "666666666666666666666688888888888888888886688822888822882888886688282888282882888886682882882882882888886682222282222282888886688882888882882222286688888888888888888886682222288222282888286682888882888882888286682222882882282888286688888282888282222286682222888222282888286688888888888888888886682222288222282222886682888882888882888286682228882222882888286682888882888282222886682222288222882888286688888888888888888886666666666666666666666",
"collectionName": "STXPLATES"
}
friedger commented 2 years ago

This SIP has been moved to accepted by the author. Please take the next steps @jcnelson

friedger commented 2 years ago

The spec now includes a property sip that is the number of the sip that specifies the json schema for the meta data. In this case 16.

Property version has been removed.

MarvinJanssen commented 2 years ago

Not saying I am against the sip field in favour of version but I wonder if it may be too restrictive. (Still trying to think of scenarios.)

However, I like that it is nice and short. I'll bring it into the next draft for SIP013.

dantrevino commented 2 years ago

Not saying I am against the sip field in favour of version but I wonder if it may be too restrictive. (Still trying to think of scenarios.)

However, I like that it is nice and short. I'll bring it into the next draft for SIP013.

I think its more descriptive than 'version' ... the version really does refer to a sip, and the version would not change without a new sip ... for that reason, I think its actually more clear.

jcnelson commented 2 years ago

Hey @friedger @dantrevino, thanks for being patient -- I didn't see the original github notification from December. I left my initial feedback pass. Hope it's helpful!

jcnelson commented 2 years ago

Right now, the consideration advisory board for technical-track SIPs has no members besides myself [1]. That said, I'm happy to advance this to Recommended status on the board's behalf if there are no other objections or feedback. Once at least one mainnet contract is using this trait, the SIP can be transitioned to Activation-in-Progress. Feel free to add my email to the Signed-off: section in the preamble.

[1] I want to change this -- the governance group is happy to take new members. The list of all consideration advisory boards and their members can be found here: https://github.com/stacksgov/sips/tree/main/considerations

dcsan commented 2 years ago

seed | string | hex string represented the DNA of the NFT. The seed is usually stored on-chain, it might be contained in the metadata for convenience.

I would be tempted to make the seed a plain/not hex string, unless there's a real benefit in terms of gas or other on-chain storage for using hex. Some people might use it to just store a text message, like a title or a couple of words. As (hex) data the stacks API functions had problems automatically detecting types when returning as JSON, mixed with other fields, and also this required conversions before storing in a DB etc. Overall it makes things much more cumbersome. It reminds me of the days before unicode of all kinds of ugly encoding errors.

friedger commented 2 years ago

seed
I would be tempted to make the seed a plain/not hex string, unless there's a real benefit in terms of gas or other on-chain storage for using hex. Some people might use it to just store a text message, like a title or a couple of words. As (hex) data the stacks API functions had problems automatically detecting types when returning as JSON, mixed with other fields, and also this required conversions before storing in a DB etc. Overall it makes things much more cumbersome. It reminds me of the days before unicode of all kinds of ugly encoding errors.

My idea was to provide a well-defined machine processable field. If it is not useful, could you please provide a better description, maybe also a better name instead of seed? Maybe we want to define two different fields. @dcsan

If the API has a problem then we should fix the API not the standard :-)

dcsan commented 2 years ago

seed is fine as a name, i think its over-complex to have two fields for this too. the API is fine when it's reading just one data type but when it's a mixed struct it fails. But it's unavoidable that this also means the client has to encode data specially for this seeding, which is just extra potential for error, and in fact occurred for me. What worked in the test suite didn't work when run through (hiros) API contract functions.

So, i'd suggest to keep it simple so we can see and confirm what's getting posted in, and what we get out - as strings, without adding a double-dutch sandwich of encoding/decoding for little purpose, that (currently) mangles the data.

I think UTF8 would give a lot more options for content too, notwithstanding Terje's point. Even if it is a minefield internally at least it's relatively standard now.

friedger commented 2 years ago

@dcsan I replaced the description with something more general. The on-chain seed can use a different type.

friedger commented 2 years ago

@jcnelson The schema has been validated using JsonValidator. See https://github.com/Light-Labs/media-metadata-schemas The found errors has been fixed.

jcnelson commented 2 years ago

Just checking in. Is there a mainnet contract using this trait yet?

jcnelson commented 2 years ago

@friedger Feel free to advance the status of this SIP to Activation-in-Progress, per my earlier comment. I can't commit directly to your PR since it's in your repo.

Hero-Gamer commented 2 years ago

Hi all just wanna make sure this is captured officially.

During last Friday's weekly SIP call https://github.com/stacksgov/sips/issues/79#issuecomment-1212993156 I raised this point.

According to the activation criteria: "This SIP is activated if 10 contracts are deployed that follows this specification. This must happen before Bitcoin tip #750,000."

We are now at bitcoin block 749,565. 435 blocks left as of writing, which is approx. 3 days.

So I'm now working with the NFT marketplaces to fetch data to confirm 10 contracts have been deployed already. Will update all how it goes.

dantrevino commented 2 years ago

There's a miss here @friedger ... this is not a contract sip, its a metadata sip. @Hero-Gamer there is no way to look at a contract and determine if the metadata supports sip-016. The contract only has a link to metadata, but, for instance, the boom-300 "contract" was deployed 10 months ago, before the sip was complete, and initially we created nfts that were not sip-016 compliant. However, now it is deploying nfts that are sip-016 compliant. Same contract.

https://explorer.stacks.co/txid/SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boom-nft-300?chain=mainnet

both minted from the same contract: non-sip016 nft, created jan 17: https://bafkreie3abg3pp4573zkjmxcgaosifpyof5hi5gxelnqutnyhelihjqeqq.ipfs.nftstorage.link/ sip016 nft, created recently: https://bafkreicg63zfryk2cvrucztb5bztg4vh6hj2e65yxcr7nld2rtryobigcy.ipfs.nftstorage.link/

Jamil commented 2 years ago

Our Create Portal contracts are almost SIP-16 compliant but not quite, since we don't have the required "sip" field in the JSON. Working with our developers to add that for all future contracts, but not sure 10 contracts like this will be deployed by Wednesday. What is the process if this SIP does not meet the requirements by then, and we have to re-start?

dartman10 commented 2 years ago

I found these with "sip": 16 in metadata:

name contract metadata_url
Boombox [10th Edition] SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-32 https://cloudflare-ipfs.com/ipfs/bafkreigzei42ktazjl3b6ounitwazbmcz7zzn5vb7poevx2xoroau7ftnm
Boombox [12th Edition] - Bloombox by Grace Hye SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-36 ipfs://bafkreidowklqh7nub2dxrh2mj4tu46inqtapqfidqnwk5taown5w4li6pq
Boombox [13th Edition] SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-38 ipfs://bafkreibduyxkdcp3djswzjjoexoi6hcvk2suaoyri2uqpiuyxbhkh6bwxe
Boombox [14th Edition] - STX of Toys SPMS4E9RQ4GCGG68R6D15PKV01TYNCBPYZG1ZMFE.boomboxes-cycle-40 ipfs://bafkreieanobksr6qetgqupx7zpn2aebw742siwsqa4ef6i7aybxvnku2ze
Boombox [8th Edition] - Moonbox SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-28 https://cloudflare-ipfs.com/ipfs/bafkreic3emy7vy4azvm56sy3dwsuny4653uzi7ubb36ui63w424kagzfym
Boombox [8th Edition] - Moonbox SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-28-moonbox https://cloudflare-ipfs.com/ipfs/bafkreic3emy7vy4azvm56sy3dwsuny4653uzi7ubb36ui63w424kagzfym
Boombox [9th Edition] - Mushroom by Flower SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boomboxes-cycle-30 https://cloudflare-ipfs.com/ipfs/bafkreibszx62vqkce7pefr6xtcqvyec7lo5xdjy6c7r3dhfd5bkl3wyvku
jcnelson commented 2 years ago

Technically yes, you would need to restart in general since it indicates that the SIP doesn't have enough interest. But it seems that in this specific case, the only reason this SIP hasn't activated was due to a bug in the implementation (e.g. a missing sip field in the JSON), but there is otherwise sufficient interest. In this case, it would be fine by me to just combine the whole "withdraw, re-submit, accept, recommend, activation-in-progress" sequence into simply the act of increasing the activation-in-progress block height to whatever you need (a week?). The effect is the same either way; the SIP text wouldn't be changing and the activation-in-progress section only needs the steering committee's sign-off (which right now is just me).

So yeah, go ahead and change the block height and keep everything else as-is.

friedger commented 2 years ago

Here is another one: https://explorer.stacks.co/txid/SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boom-nft-300?chain=mainnet Makes it 8.

dartman10 commented 2 years ago

No. 9 - a new one deployed a few hours ago: SPQE8N8BHMT462W2XPK028GDM4RMQBSHAAY8D37G.crashpunks-punkettes https://explorer.stacks.co/txid/0x95c03cb957324a9983430b4419c4d4180d13ca5b067cda7e23d314df4f762443?chain=mainnet ipfs://QmcUiKLAeYbx78UZWoCuyKdm5GhZH6Jhto9yhKt1oPvWHY/

Hero-Gamer commented 2 years ago

153 bitcoin block time left, approx. 1 day. (current block time 749,847) Who else/where else can we ask to find the last contract required? almost there!

Jamil commented 2 years ago

The contract above (SPQE8N8BHMT462W2XPK028GDM4RMQBSHAAY8D37G.crashpunks-punkettes) was deployed with the Gamma Create Portal, which now has the sip field in the JSON.

The next contract deployed with the Gamma Portal will be the 10th :)

dartman10 commented 2 years ago

No. 10? This NFT has a dynamic metadata. The latest mint has a SIP-016 metadata, prior mints were not.

Latest mint with "sip": 16 :

Earlier mint example without "sip": 16:

Hero-Gamer commented 2 years ago

If all contracts checks out: Current Bitcoin block height: 749,876 https://mempool.space/block/0000000000000000000894d96480628dcd38fd9424750e9d2638aa75233e19f0

jcnelson commented 2 years ago

Awesome to see! I will take a look as soon as I am able, and if it all checks out, it will be my pleasure and honor to advance this to Ratified :tada:

jcnelson commented 2 years ago

Here is another one: https://explorer.stacks.co/txid/SP1QK1AZ24R132C0D84EEQ8Y2JDHARDR58R72E1ZW.boom-nft-300?chain=mainnet Makes it 8.

@friedger I'm not sure where to look for the metadata URL here? This appears to be a contract deploy from 6 months ago.

The rest look good to me.