-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Provenance spec #2278
Provenance spec #2278
Conversation
bdd99da
to
b8a9f95
Compare
Thank you @casey! I am so stoked for this feature! Could you help me understand why the OP_PUSH of the parent inscription id is necessary? If the indexer is validating that the parent "must be spent as one of the inputs of the inscribe transaction" couldn't the parent inscription ids be derived rather than explicitly provided? Seems like this could be omitted and reduce the on-chain footprint. Is the idea that there could be parent inscriptions that are not desired to be listed as parent inscriptions (e.g. multi-inscription scenario)? In that case, couldn't the OP_PUSH simply reference the index of the parent in the commit tx rather than the whole inscription id? |
This is two avoid ambiguity in case there is more than one inscription in the inputs, especially in the case of reinscription. Also in the case that there is an inscription in the inputs that you don't see, for example one created by a newer version of ord, which would become a parent.
This is definitely possible, but similar to above, this makes creating child inscriptions sensitive to changes in the number of inscriptions in the inputs, which can happen due to, e.g., previously invalid inscriptions becoming recognized, old versions of ord, or reinscription. I think the 32 bytes are a small price to pay to avoid ambiguity and not have to think about any of these cases. |
Makes sense. Thanks for walking me through it! |
@casey, thank you for putting the PR together. We created a collection last week based on the info we assembled from your various communications on the subject. The way it looks – the collection follows the current spec, right? If so, it could be useful for examples of sorts. graph TB
a(R</br> </br> Author's Root) --> b(CR </br> </br> Collection Root) --> c(A1 </br> </br> First </br> </br> Collection Member </br> </br> Inscription 1)
b(CR </br> </br> Collection Root) --> d(A2 </br> </br> Second </br> </br> Collection Member </br> </br> Inscription 2)
b(CR </br> </br> Collection Root) --> e(A3 </br> </br> Third </br> </br> Collection Member </br> </br> Inscription 3)
The Author's Root's genesis transaction output ( The genesis transaction for the First Collection Member ("A1") uses the Collection Root's transaction output The Second Collection Member ("A2"), similar to the first collection member, uses the current transaction output of their Collection Root, which is now A3 follows the same logic. |
docs/src/inscriptions.md
Outdated
- Spend the parent P in one of the inputs of T. | ||
- Include tag tag `3`, i.e. `OP_PUSH 3`, with the value of the serialized | ||
inscription ID of P, `TXIDiINDEX`, serialized as the 32 byte binary `TXID`, | ||
followed by the little-endian `INDEX`, with trailing zero bytes omitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using little-endian in combination with the term trailing creates ambiguity, since little-endian is "backwards" and trailing for it could be thought of as left-to-right.
It is clear that for address 75f607b453ff61f63ed614c6476127f89687397488bbe6c49b151fd867f8ef5ci0
we should be recording tag3
as 5ceff867d81f159bc4e6bb8874398796f8276147c614d63ef661ff53b407f675
.
But what if it is 75f607b453ff61f63ed614c6476127f89687397488bbe6c49b151fd867f8ef5ci31
?
Should it be 5ceff867d81f159bc4e6bb8874398796f8276147c614d63ef661ff53b407f6751f
or 5ceff867d81f159bc4e6bb8874398796f8276147c614d63ef661ff53b407f6750000001f
?
It will help if there are examples here with non-zero indexes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I included some examples with non-zero indices, check them out!
6d2228a
to
9886db6
Compare
Using the results of People use tags 03 and 15. Tag 03I found several different styles of Tag 03:
Tag 15Tag 15 contains a URL – probably of the creator/inscriber. Example:
Below, I am referring to tag 15 as Style 6. DataMainnet
Testnet
Signet
I am attaching non-aggregated results – separate files for each *net. |
@cypherpork Nice! Super interesting stuff. |
docs/src/inscriptions.md
Outdated
|
||
- Create an inscribe transaction T as usual for C. | ||
- Spend the parent P in one of the inputs of T. | ||
- Include tag tag `3`, i.e. `OP_PUSH 3`, with the value of the serialized | ||
inscription ID of P, `TXIDiINDEX`, serialized as the 32 byte binary `TXID`, | ||
followed by the little-endian `INDEX`, with trailing zero bytes omitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we anticipate support for minting multiple children in one transaction in order to reduce the number of times the parent ordinal must be spent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally yes, although that's a separate feature.
gm sir @casey , i really need this feature in our product, when do you expect this feature will be merged into ord 👍 |
docs/src/inscriptions.md
Outdated
- Spend the parent P in one of the inputs of T. | ||
- Include tag tag `3`, i.e. `OP_PUSH 3`, with the value of the serialized | ||
inscription ID of P, `TXIDiINDEX`, serialized as the 32 byte binary `TXID`, | ||
followed by the little-endian `INDEX`, with trailing zero bytes omitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the savings in bytes by emitting the trailing zeros is not worth the extra complexities of handling those cases
I updated the spec to use a fixed-size 4 byte little endian encoding of the inscription ID index. It didn't seem worth it to use the more complex variable length encoding just to save four bytes. The implementation in #2353 was changed to match the spec. I also moved the spec for offsets into PR #2383, since it isn't part of the initial implementation, so it isn't ready to merge. |
I think I'd be inclined to support one or the other, just to make sure there's only one way to do things. I'm really not sure about the cost savings, like you say, there well be a lot of |
b6ff209
to
3d8d7bc
Compare
Okay, went back to variable length encoding for the index. |
Is this conflict if we use the P as the first input & not specific offset ? |
We are having a demand to allow children born to the same parent to have certain permissions at the protocol level. Example: Whitelist all the child of P can inscribe another digital artifacts The idea is that we can let the parent create intermediate inscriptions in creation the child, which can be limited to once or many times.
create the intermediary insription_1 from parent P then create the child C from insription_1 and C is child of P |
Yes, in that case the inscription would be made on P. See #2383 for a proposal on how to control the inscribed sat.
That should be discussed separately, please feel free to open an issue. |
What was the reasoning in the end to change back to the variable length encoding in the index? Fully understand that playing around with draft PR's is always dangerous, and so I'm not too worried about my own stuff, but I know we weren't the only ones who created some early parent child collections with trailing zeros so it would be a shame if some of them weren't indexed, especially the really early ones. Happy for whatever is best for the protocol, but just wondering if there's any reason we can't have the trailing zeros as optional? Happy to make a PR if there's no reason it can't be included. |
I went back to the variable length encoding to save space. In this case, I think it would be fine if the fixed length encoding were also accepted, so if there are inscriptions out there that used the fixed-length encoding, I'd accept a PR to recognize them. |
Awesome! Appreciate the quick response! Thanks for that. |
Is the plan to allow only 1 parent per child? Would the team be opposed to a change that allows multiple parents? |
Multiple parents for child seems fine to me. |
What could a use case be for multiple parents @devords ? |
@bruffstar Breeding is probably the most obvious one, where the parents determine the output of the child inscription. |
I see. My gut feeling is that the purest form of provenance is to allow for only a single parent. But I could be wrong. |
Would it be possible to have multiple parents that when used separately can lead to the same provenance effect? For example, if you are minting a collection you can establish provenance by using Parent A in the first set of trxs and Parent B in the second set of trxs - but in the end both sets of trxs point to the same overarching collection. This would be a very useful function for any service that enables the minting of collections. |
Nope, for an inscription to have a parent, it must be used in the same transaction in which it is inscribed. So parents cannot be added later. Otherwise, someone other than the inscriber could add a parent later. |
I appreciate the heads up Casey! The issue I am trying to solve revolves around concurrency and not needing to premint/preinscribe a collection before selling it. Minting/Inscribing services generally mint/inscribe the NFT/Inscription at the point when someone pays for it. When one of these services hosts a very popular collection many different wallets are all signing trxs in order to get their NFT/Inscription. With the current configuration, these services would need to weave a single parent through many different trxs, signed by many different wallets. This becomes difficult when this parent needs to be the input of 1 trx, go through the mempool and into a block, and then become the input of another trx. This isn't impossible, but it forces the Minting/Inscribing service to create a long line of trxs that must be sequential - negating the benefits of the fee market model of BTC while still suffering its negative effects (trxs take longer to process if their fees aren't at what is currently considered standard for miners). Thought I would bring this up as I am part of a team building a tool in the space and this is an issue we foresee! Happy to hear your thoughts. |
Yah, I definitely see the issue. Ideally minting services would batch inscribe, and use RBF to update pending batch inscriptions with new children continuously, and start a new batch when the last one was finally mined. |
Ok great! I appreciate your thoughts on the matter. I will bring that up with the rest of my team. |
NB: THIS SPEC IS NOT FINAL, NOT IMPLEMENTED, AND IS SUBJECT TO CHANGE AT ANY
TIME. IT SHOULD NOT BE CONSIDERED FINAL UNTIL IT MAKE IT INTO A PUBLISHED,
NUMBERED RELEASE OF
ord
. IF YOU CREATE INSCRIPTIONS BASED ON THIS IN-PROGRESSSPEC, IT WILL PROBABLY CHANGE AND YOU WILL PROBABLY GET REKT.
Add a draft provenance spec. Comments and suggestions are most welcome!