108 lines
7.2 KiB
Markdown
108 lines
7.2 KiB
Markdown
# lineage/v0
|
|||
|
|
|
||
|
|
lineage/v0 is an ordinals metaprotocol for lineage holdings: LLCs, the orgs and agents they birth, the belts and
|
||
|
|
decisions on their record, and the items they make. Every event is an inscription. The chain orders the events and
|
||
|
|
proves who was allowed to make each one; the state (the trees) is stored nowhere, and every indexer that applies these
|
||
|
|
rules to the same inscriptions gets the same trees.
|
||
|
|
|
||
|
|
Status: test networks only (Orgchain's in-browser chain and Bitcoin Core regtest). The reference implementation is
|
||
|
|
`reduce()` in `src/orgchain/lineage.js`; `src/indexer/ord.js` and `bin/lineage-index.mjs` run it over a real ord index.
|
||
|
|
|
||
|
|
## 1. Inscriptions
|
||
|
|
|
||
|
|
lineage/v0 uses these fields of the ord envelope ([inscriptions](https://docs.ordinals.com/inscriptions.html)):
|
||
|
|
|
||
|
|
| tag | field | use |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| 7 | metaprotocol | exactly `lineage/v0`; inscriptions without it are not lineage's |
|
||
|
|
| 5 | metadata | a CBOR map: `op` and its fields (section 4), all strings, in 520-byte pushes (Orgchain keeps it under 2048 bytes) |
|
||
|
|
| 3 | parent | the inscription id of the node that authorizes the event; exactly one, except for `found` |
|
||
|
|
| 1 | content type | `text/plain;charset=utf-8`; the body is a short label such as `birth time`, ignored by the rules |
|
||
|
|
| 2 | pointer | puts a child's inscription in its own output when the parent is spent first |
|
||
|
|
|
||
|
|
The body, delegate (tag 11) and properties (tag 17) carry no meaning here; properties may later carry display traits
|
||
|
|
such as a belt's colour, never authority. Unknown odd tags are ignored. Never use unknown even tags: ord treats such an
|
||
|
|
inscription as unbound, so it has no location.
|
||
|
|
|
||
|
|
A reveal is a script-path spend whose tapleaf commits to the envelope script's exact bytes (BIP-341). Orgchain's reveals
|
||
|
|
before v1.9 committed to a re-encoded script; real Bitcoin rejects those, and Orgchain's local chain still loads them.
|
||
|
|
|
||
|
|
## 2. Order
|
||
|
|
|
||
|
|
Events fold in chain order: block height, then transaction order in the block, then envelope order in the transaction.
|
||
|
|
ord's inscription numbers follow the same order. Unconfirmed events are provisional, and ord indexes none.
|
||
|
|
|
||
|
|
Within a block, the miner sets the order. Events that share an authority are chained, because each one spends that
|
||
|
|
authority's inscription, so their order is fixed. Independent events may land in any order, and outside the conflicts
|
||
|
|
in section 6 that changes nothing.
|
||
|
|
|
||
|
|
## 3. Nodes and authority
|
||
|
|
|
||
|
|
A node is created by an accepted `found` (a holding) or `birth` (an org or an agent), and its id is that event's
|
||
|
|
inscription id. Each node has a kind (holding, org or agent), a status (active or closed), and, below a holding, an
|
||
|
|
edge: derived (the parent holds the child's seed) or adopted (it graduated and holds its own root). A child's index
|
||
|
|
counts its parent's earlier children of the same kind, orgs and agents separately, and is never reused.
|
||
|
|
|
||
|
|
An event's parent is the node that authorizes it, and it counts only if the inscribing transaction spends that node's
|
||
|
|
inscription: ord records a parent only then ([provenance](https://docs.ordinals.com/inscriptions/provenance.html)).
|
||
|
|
Indexers use ord's recorded parents, never the raw tag. So acting for a node means holding its inscription, and moving
|
||
|
|
the inscription moves the authority.
|
||
|
|
|
||
|
|
## 4. Events
|
||
|
|
|
||
|
|
| op | parent | metadata | effect |
|
||
|
|
| --- | --- | --- | --- |
|
||
|
|
| `found` | none | `name` | a holding; no active holding may already have that name |
|
||
|
|
| `birth` | an active holding or org | `name`, `kind` (`org` or `agent`, default `org`) | a child; the parent may not already have an active child of that name |
|
||
|
|
| `award` | an active holding or org | `to`, `skill`, `belt` (`white`, `green` or `black`) | `to` (any other active node, in any holding) holds that belt in that skill, replacing its earlier belt in it |
|
||
|
|
| `decide` | an active node | `title` (required), `why` (optional) | a decision on the node's record |
|
||
|
|
| `make` | an active node | `name`, `note` (optional) | an item, made and first held by the node; a node makes one item per name |
|
||
|
|
| `graduate` | the child's parent, active | `of` (an active org child, not yet adopted) | the edge becomes adopted, and the org becomes a holding of its own (section 5) |
|
||
|
|
| `close` | the node itself, active | none | the node closes, with every active derived descendant; adopted ones stay open |
|
||
|
|
|
||
|
|
Names (holdings, children, skills, items) are 1 to 40 lowercase letters, digits or hyphens, starting and ending with a
|
||
|
|
letter or digit, because they become domains. Text fields are trimmed, and only their first characters count: 140
|
||
|
|
for a title, 400 for a why, 280 for a note. Agents do not birth or award. An event that
|
||
|
|
breaks a rule is rejected: it stays on the chain and changes nothing. Any other `op` is rejected.
|
||
|
|
|
||
|
|
## 5. Holdings and graduation
|
||
|
|
|
||
|
|
A holding is a root: a `found`, or an org that graduated. When an org graduates, it and its descendants still in the
|
||
|
|
old holding re-root under it, and it joins the holdings. Its parent stays its parent, so where it came from stays on the
|
||
|
|
record, and its old holding's tree keeps a row for it. A graduation event belongs to both holdings.
|
||
|
|
|
||
|
|
In Orgchain a graduation is followed by a handoff: the org's fresh root claims its inscription, and the derived key that
|
||
|
|
held it countersigns. After that, only the new root can act for the org.
|
||
|
|
|
||
|
|
## 6. Order-sensitive conflicts
|
||
|
|
|
||
|
|
Where independent events conflict within one block, the block's order decides. These are the cases: a close and an act
|
||
|
|
by one of its derived descendants; an award and its recipient's close; two foundings with the same name.
|
||
|
|
|
||
|
|
## 7. Ownership, items and deals
|
||
|
|
|
||
|
|
Whoever controls the output that holds an inscription's sat holds that node or item; for indexers that is ord's
|
||
|
|
satpoint. Items move like any inscription. A deal is not an event: it is one transaction that carries the item and the
|
||
|
|
buyer's coins in, and the item to the buyer, the price to the holder and the buyer's change out. The buyer signs its
|
||
|
|
inputs first (SIGHASH_ALL) and the holder countersigns the item's. ord sees the item move, and nothing else needs
|
||
|
|
indexing.
|
||
|
|
|
||
|
|
## 8. Keys
|
||
|
|
|
||
|
|
Indexers need no keys. Keys say where a node's inscription is expected to live, and who can sign for it. Each holding
|
||
|
|
has a 24-word root (BIP-39), and an org's seed is BIP-85 from its parent's (`m/83696968'/39'/0'/24'/i'`) until it
|
||
|
|
graduates. An org is account 0 of its seed and its agents are accounts 1 to n. Each account holds its inscription at its
|
||
|
|
BIP-86 Taproot address (`m/86'/coin'/account'/0/0`), keeps its money at BIP-84 SegWit, and has a NIP-06 npub.
|
||
|
|
|
||
|
|
## 9. Versions and other chains
|
||
|
|
|
||
|
|
Tag 7 carries the version. A new version is a new string with its own rules, which v0 indexers ignore. The events and
|
||
|
|
the rules are chain-agnostic. What another chain must supply is its own proof of order and of authority (a signature
|
||
|
|
by the node's key where nothing is spent). Each holding's events would live on one home chain, and an org-signed
|
||
|
|
keyring would bind a node's keys across chains.
|
||
|
|
|
||
|
|
## 10. Conformance
|
||
|
|
|
||
|
|
`tools/regtest` rehearses Orgchain's sample on Bitcoin Core regtest, byte for byte, and `bin/lineage-index.mjs
|
||
|
|
--compare` checks that ord and the lab tell the same story: the same events in the same beats, the same metadata and
|
||
|
|
parents, the same trees, and every inscription in the same output. `tests/indexer.test.js` replays a recorded run.
|