Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inscription metadata #2421

Merged
merged 14 commits into from
Oct 3, 2023
Merged

Inscription metadata #2421

merged 14 commits into from
Oct 3, 2023

Conversation

casey
Copy link
Collaborator

@casey casey commented Sep 4, 2023

Add metadata, based on #2053.

@elocremarc
Copy link
Contributor

elocremarc commented Sep 4, 2023

We should map keys to the Open Graph Protocol standard so metatags could also display on socials and SEO.
Example for /inscription page:

  <head>
    <meta property="og:foo">bar</meta>
    <meta property="og:this">that</meta>
    <meta property="og:title">dope title</meta>
    <meta property="og:image" content="/content/<inscriptionId>" />
  </head>

Edit: I think image needs the full path for images server would need to return origin

<meta property="og:image" content="https://ordinals.com/content/<inscriptionId>" />

This would work very well for image mime types without even encoding that tag. If say a HTML page wants SEO that one could specify an image. Will inscriptionId fit in the byte limit of this encoding?

src/inscription.rs Outdated Show resolved Hide resolved
@elocremarc
Copy link
Contributor

Needs a page ref on SUMMARY.md

 - [Inscriptions](inscriptions.md)
     - [Recursion](inscriptions/recursion.md)
     - [Metadata](inscriptions/metadata.md)

@Eoous
Copy link

Eoous commented Sep 5, 2023

Maybe we could support parse metadata in a file?

@uzyn
Copy link
Contributor

uzyn commented Sep 5, 2023

Would be great if we can align with OIP-01, a non-breaking metadata implementation.

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 1
  OP_PUSH "text/plain;charset=utf-8"
  OP_PUSH 0
  OP_PUSH "Hello, world!"
OP_ENDIF

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 1
  OP_PUSH "application/json;charset=utf-8"
  OP_PUSH 0
  OP_PUSH "{\"p\":\"oip-01\"}"
OP_ENDIF

It's been implemented by Sado SDK, Ordzaar, Ordlify.

Here's an example of a defined metadata using OIP-01: https://explorer.ordzaar.com/inscription/105758bb912665f5f803ec0f5268d2218b51978b16de05622c64c9faafd2d22ei0

While remaining fully backward-compatible, so it shows up fine on Ordinals.com https://ordinals.com/inscription/105758bb912665f5f803ec0f5268d2218b51978b16de05622c64c9faafd2d22ei0

It has a looser format, JSON vs named key-value pairs, for metadata than #2053, allowing for more flexible use cases such as: verifiable ordinal collection and file chunking.

Happy to discuss further on this.

@casey
Copy link
Collaborator Author

casey commented Sep 5, 2023

Needs a page ref on SUMMARY.md

 - [Inscriptions](inscriptions.md)
     - [Recursion](inscriptions/recursion.md)
     - [Metadata](inscriptions/metadata.md)

Good catch!

@casey
Copy link
Collaborator Author

casey commented Sep 5, 2023

Would be great if we can align with OIP-01, a non-breaking metadata implementation.

We considered something like this, but I see a few issues with using a different inscription on the same sat to contain metadata, but it seems inelegant to make the metadata its own inscription, when it isn't interesting on its own, and shouldn't be displayed as an inscription in its own right.

@kodemon
Copy link

kodemon commented Sep 6, 2023

metadata its own inscription, when it isn't interesting on its own, and shouldn't be displayed as an inscription in its own right

This makes sense to me, as having secondary inscriptions on sats being interpreted as unbound leaves inconsistent representation in the consumer layers (eg. one place may support OIP where as another may not) and represents them as bad/invalid inscriptions.

I think a single layer approach with OP codes may be a little limiting. Having meta data as a flexible object with ability to add nested separation of concern and lists through JSON is more beneficial than a key value pair approach.

So something like:

OP_5 meta # marker, when value "meta" next value OP_7 should be JSON
OP_7 json

So I definitely like an approach where we don't create two inscriptions on the same sat, but would miss having the ability to add a somewhat more complex meta object (unless there are some elegant solutions to this using the proposed approach). 🤔

@casey
Copy link
Collaborator Author

casey commented Sep 6, 2023

but would miss having the ability to add a somewhat more complex meta object

What specific metadata did you have in mind? From what I've observed, a simple key-value store covers the vast majority of use-cases, and has the advantage that it's attractive and simple to display.

@kodemon
Copy link

kodemon commented Sep 6, 2023

I was thinking in line of the meta presented in this example: https://ordinals.com/content/105758bb912665f5f803ec0f5268d2218b51978b16de05622c64c9faafd2d22ei1

So for example a trait key with a list of traits. or the creator with its own key value pair object. The one thing I could think of was doing:

OP_5 creator.name
OP_7 TheArtist

But for the traits list it may be a little more complicated 🤔

@Eoous
Copy link

Eoous commented Sep 6, 2023

a simple key-value store covers the vast majority of use-cases, and has the advantage that it's attractive and simple to display.

Many traits need nested key value pairs. In the scene, simple key-value pair could make no sense. Maybe json is a good way to store traits.

OP_5 json metadata

@uzyn
Copy link
Contributor

uzyn commented Sep 6, 2023

@casey

We considered something like this, but I see a few issues with using a different inscription on the same sat to contain metadata, but it seems inelegant to make the metadata its own inscription, when it isn't interesting on its own, and shouldn't be displayed as an inscription in its own right.

Agree on all the above. OIP-1 was designed, in order to not break existing support, based on a specific negative test case at the time of proposal (where trailing inscription is expected to be ignored). It seems to now no longer true, due to #2145

Trying to be as accommodating as possible to existing adopted social standards, e.g. https://www.oips.io/oip-02-verifiable-ordinal-collection utilizes OIP-1 but is proposed based on BRC-20.

I would adopt the model, but would highly recommend doing a more structured data in a similar style of BRC-20 for more extensibility.

@orkunkilic
Copy link

What do you think of supporting inner metadata with smth like this @casey:

 OP_5 just_key 
 OP_7 just_value
 OP_5 outer_key
 OP_7 
   OP_5 inner_key_and_outer_value
   OP_7 inner_value

We can limit inner depth with some const like 3? I am just brainstorming to have more flexible metadata structure while avoiding json.

@casey
Copy link
Collaborator Author

casey commented Sep 6, 2023

@kodemon

I was thinking in line of the meta presented in this example: https://ordinals.com/content/105758bb912665f5f803ec0f5268d2218b51978b16de05622c64c9faafd2d22ei1

There are some nested fields, but I feel like they could avoided and expressed as key-value pairs:

key value
Title Elemental
Description Azuki Elementals are a collection of 20,000 characters within the four domains of the Garden.
Hair Electrified Long - Black
Offhand Elemental Blade - Lightning
Eyes Enticing
Type Blue
Creator TheArtist [email protected]
Tips 1FFBzYT55auox4boSaQUYcsQ9LCaJJWhRw

@0xEclair

Many traits need nested key value pairs. In the scene, simple key-value pair could make no sense.

Examples of traits that need nested key value pairs would be great.

@orkunkilic

What do you think of supporting inner metadata with smth like this @casey:

In that case it would probably be better to use JSON, instead of rolling a new serialization format.

@uzyn

I would adopt the model, but would highly recommend doing a more structured data in a similar style of BRC-20 for more extensibility.

The purpose of the inscription metadata proposed here is to always for it to be human readable. My worry with structured data is that it won't be possible to display it to the user in an appealing format.

@Eoous
Copy link

Eoous commented Sep 6, 2023

There are some nested fields, but I feel like they could avoided and expressed as key-value pairs

Yeah. Normal key value pairs could be like this. But for developers, maybe they need to distinct types of keys(for display or for using in app). If only for display, it's no problem. I think metadata also needs more information to help developer to use them.

@kodemon
Copy link

kodemon commented Sep 7, 2023

The purpose of the inscription metadata proposed here is to always for it to be human readable. My worry with structured data is that it won't be possible to display it to the user in an appealing format.

I think this is probably where the mindset deviates as I am third party consumer of ord and shape the data it provides into product specific requirements. So for my use cases structured data is more important than ease of display as that is something I deal with during formatting.

So lets imagine the following object:

{
  "p": "super",
  "traits": [
    {
      "power": "anything",
      "strength": 10
    },
    ...
  ],
  ...other
}

The tricky part with this requirement is that its hard to flatten because the traits array may be dynamic, so if I flatten this it becomes hard to identify what is part of a trait and what is not. Where as when I am processing traits as part of my application I may have some internal logic specific for handling dynamic trait information.

So while I understand the appeal of human readable out of the box, as a third party developer relying on the data ord provides and the way that I personally prefer meta data to be presented I still think a flat key value pair representation is too limiting and I can see myself needing to hack around the limitation rather than just being able to use the data as is.

I would probably need to do something like

key value
p super
data { "traits": [ ... ], ... }

I think from a developers perspective consuming ord as a service, a structured meta object is more future proof.

For this specific issue I decided to be a little more vocal in my thoughts as it has a massive impact on the work I do with ord and we heavily rely on the ability add meta data to inscriptions 😅

@casey
Copy link
Collaborator Author

casey commented Sep 7, 2023

For this specific issue I decided to be a little more vocal in my thoughts as it has a massive impact on the work I do with ord and we heavily rely on the ability add meta data to inscriptions 😅

Your feedback is very welcome!

I think that, as much as I would like to constrain metadata to key-value pairs, it's a losing battle, so I changed the spec to use JSON instead. I've also included, as part of the spec examples of how ord will render JSON metadata as HTML on /inscription pages. Hopefully this will encourage inscribers to make their metadata legible, and to omit anything from metadata that isn't intended for human consumption.

@bruffstar
Copy link

It's great this was moved to a JSON setup. I think it would be really useful to have an endpoint where we get the metadata returned as JSON.

e.g. https://ordinals.com/inscription/<inscription-id>/metadata

This way, we can consume the JSON and display it any way we want.

@Psifour
Copy link
Contributor

Psifour commented Sep 8, 2023

To confirm, the plan for ord going forward is uncompressed UTF-8 JSON as a metadata format?
Despite all the excellent ways to encode data we have chosen one of the least data efficient ones to implement?

@casey
Copy link
Collaborator Author

casey commented Sep 8, 2023

To confirm, the plan for ord going forward is uncompressed UTF-8 JSON as a metadata format? Despite all the excellent ways to encode data we have chosen one of the least data efficient ones to implement?

I'm not set on this, but I don't think it's an entirely unreasonable choice. Yes, JSON is inefficient, however it is ubiquitous, and being human readable and writable is a huge advantage.

@stet
Copy link

stet commented Sep 10, 2023

human readable and writable is a huge advantage

I encourage use of efficient CBOR etc encoding. Not sure why it matters if metadata is immediately readable if it is rendered for consumer in appropriate format (which could be transformed to JSON if needed). Saving on bytes and bandwidth and energy efficiency are important considerations esp in context of Bitcoin onchain data store.

This is a great opportunity to be smart about the broad impact as opposed to a narrow focus on display of data.

I don't think people and software should be writing and inscribing raw JSON moving forward.

@kodemon
Copy link

kodemon commented Sep 10, 2023

I encourage use of efficient CBOR etc encoding. Not sure why it matters if metadata is immediately readable if it is rendered for consumer in appropriate format (which could be transformed to JSON if needed).

I agree with the take that readability should be a consumer level concern and not dictate its storage format in a way that is less efficient than it can be.

It would be interesting to hear some good ideas on an efficient and flexible solution for storing meta data on inscriptions. I don't have in depth knowledge on the topic of optimized encode/decode topics, and I am mostly concerned with the ability to consume the data stored to transform it into output that is used in product and/or protocol level decisions.

Copy link
Collaborator

@raphjaph raphjaph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Let's add special title and description display in another PR

@casey casey merged commit 26a755f into ordinals:master Oct 3, 2023
6 checks passed
@casey casey deleted the metadata branch October 3, 2023 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet