中文

From one piece of data to an asset

Protocol · · George (Engineer) · 23 min read

You delivered 100,000 labelled rows to an AI company. The agreement said that as long as the data got used, you would take a share of what it earned. You were optimistic about it, because you believed the data you were handing over was very good, and good data should pay well.

It did not turn out that way. Over the next six months your data was used only lightly, and each use touched only part of it, so what came back was far less than you had expected. You never found out why. Everything you knew came from that AI company, and all you could do was believe it.

Some time later you happened to read in a trade report that another company had your data too — and was not only using it, but passing it on to others and getting paid for it. This came as a surprise, because you had heard nothing about it, so you went back to the company you had signed with.

Their answer was airtight: that company’s data was “lawfully sourced”, and your contract carried “no third-party disclosure obligation”; as for the low returns, “settlement follows actual usage, and that is what the market pays”. You wanted to check any one of those sentences — how many times your data had actually been used, whether it had been licensed on, whether what that other company held was your batch — and you could not. The usage records were in their database, the licensing contracts were in their cabinet, and all you held were a few payment receipts.

Following the report a little further, you found that what the other company was selling was a 400,000-row dataset. If your 100,000 rows really were in there, they were mixed in with another 300,000 — and you could not pick your own out, let alone hold anyone to them.

At this point you cannot even tell which of the two happened: whether the company concealed a deal and kept the share owed to you, or whether the data leaked somewhere along the way and the other party never paid at all. The first is a breach of contract, the second is a loss of control, and they mean entirely different things — and you have no way to tell them apart.

You might think the answer is to find a more reputable company next time. And it is true that some platforms will give you a report — how many times it was used, what your cut is, laid out clearly. But the party issuing the report is the party that owes you the money: whether there were deals outside the report, whether your rows are still in the dataset, whether a grant was ever revoked — you have no way to check any of it independently of the platform. The per-row fingerprints, the membership table, the grant records have only ever lived in the platform’s own database. Contributions cannot be proved, ownership cannot be looked up, grants cannot be pulled back — that is decided by this way of keeping books, and it holds no matter who you sign with. Changing it takes a different set of bookkeeping rules, which is exactly what XnY Protocol sets out to do.

The key to the new rules is granularity. One overall attestation for a whole dataset is not enough — that only proves a batch of data existed at some moment; whether your rows are in it, and at what ratio the batch mixed in dilutes them, goes unrecorded. XnY Protocol keeps the books at the level of a single sample: every contribution has its own fingerprint, a dataset is a public aggregation of a batch of fingerprints, and how large a share you hold in a batch is publicly recorded, for anyone to check against.

Side by side: today a 400,000-row dataset is a black box and all you hold is a contract PDF saying the revenue is split by contribution; under XnY the same dataset is a public membership table with one row per sample carrying a cfId, a contributor DID and a weight, with your own rows picked out. Anyone can rehash the table and compare the result with the Merkle root published on chain, so changing any row makes the two roots stop matching. Your share is the sum of your weights over totalShares.
Figure 1 · The same 400,000-row dataset: a black box, or a public membership table with fingerprints and weights

Three conditions for data to be an asset

For data to become an asset that keeps earning, three things have to be solved at once.

Provable — what this asset is, and who owns it. It runs in two directions: backwards, where my contribution came from, who changed it, who reviewed it; forwards, which dataset it went into, and which revenue it corresponds to.

Ownable — ownership has to be a right that can be exercised, not a sentence in a contract. Exercisable means four things:

Accessible — the asset can move, but the data itself must not. Who can get the data, on what grounds, and how a grant is revoked — those three answers have to be guaranteed by mechanism, done as said, rather than promised in a clause.

Miss one and the whole thing fails: unprovable and there is nothing to title; unownable and there is nothing to trade; uncontrolled use and nobody dares release data at all. Look back at the opening and not one of the three holds, which is why the revenue split could only ever be a sentence in a contract.

XnY Protocol designs one mechanism for each of the three, and the next three sections take them in turn. The protocol objects those mechanisms use are explained where they first appear; only identity has to come first — it runs through all of them.

Identity: the DID

DID — short for Decentralized Identifier, a W3C standard. A contributor’s on-chain identity, written did:xny:<uuid> and stored on chain as a uint128. It is a pseudonymous identifier and carries no real-world identity. Every write in the protocol binds to a did rather than a wallet address — identity and signing wallet are decoupled, the wallet can change and the identity does not, a point that comes back when we get to claiming revenue.

What the blockchain is for in this protocol

The protocol “anchors on chain” every fact that needs to be publicly verifiable — every mechanism below does this. It is worth stopping first to be clear about why a chain, and what it actually provides.

Where this article says chain, it means a blockchain. In this protocol it is the ledger that belongs to no party. It provides three things:

That is exactly what the opening story was missing: the party issuing the report is no longer the party that owes you, because the ledger is in nobody’s hands.

Just as important is what the chain is not responsible for. It does not know whether the content of a row is correct — that is what review signatures are for; and it keeps no secrets — everything on chain is public and permanent. So there is a clear line between what belongs on chain and what does not:

Which means you can prove a piece of content has not been altered without showing it to anyone.

Immutability has its price too: what is written wrong cannot be erased, only corrected by appending. The protocol makes “correction by appending” a first-class citizen for that reason — the next section shows a kind of record (AMENDS) that does exactly this, keeping both the correction and the original on the books, so who changed what stays there to be looked up.

One rule runs through every entity: an on-chain object carries an id, usually a metadataHash and a metadataUri for its content, plus the few fields its own type needs. The content itself stays off chain; the hash is what the two sides match on, and checking integrity means fetching the content and recomputing it. What that split implies is unpacked in the storage section.

Finally, Figure 2 gives an overview of the protocol’s on-chain objects and their context — each object is unpacked below, where it first does some work.

An overview of the protocol's core objects: the DID is the identity and reaches the CF, the contribution fingerprint, as contributorDid and the DatasetVersion as assemblerDid; a batch of CFs is aggregated by weight into a DatasetVersion, whose datasetId is referenced by a Grant anchor. Frontier, Campaign and Task are context anchors — only taskId enters the CF, and none of the three take part in ownership, revenue or grants.
Figure 2 · The protocol’s core objects and its context anchors

Provable

Provable has two layers: the origin of a single contribution can be traced, and ownership across a dataset can be established. The first layer first.

Every contribution has its own fingerprint

The protocol does not define the workflow for “submit” and “review” — that is each platform’s own business. What it defines are two artifacts that can be signed and put on chain.

The first is a content fingerprint, called a CF in the protocol — short for Contribution Fingerprint. Every contribution is registered as one CF, and that CF is the anchor for it. A CF’s id is computed like this:

cfId = keccak256(metadataHash, contributorDid, taskId)          // no parent
cfId = keccak256(metadataHash, contributorDid, taskId, parentCf) // with a parent

Change one character of the content and metadataHash changes, and the cfId is entirely different — like pressing a thumbprint onto the content. Note what the formula deliberately leaves out: metadataUri. A contribution is defined by its content, not by where it is stored. A broken location can be repaired — the contract provides updateCFMetadataUri for it, callable only by the contributor themselves or an authorised reviewer — but the cfId never changes.

A CF also carries a taskId, pointing at a Task registered on chain — it takes part in computing the CF’s id and is part of the protocol. Above Task sit two further curation layers, Campaign and Frontier. For ownership and revenue those three are only context anchors: the chain attests that they exist and that their metadata is verifiable, but they take no part in any mechanism of ownership, revenue or grants — dataset assembly even crosses Frontiers, and one version may aggregate CFs from arbitrary tasks. This article does not unpack what those three layers mean for the business.

parentCf is the key to lineage. Every CF carries a kind, AtomicKind, of which there are four:

Annotation, correction, review — everything that happens afterwards hangs off the row it acts on, through parentCf. That is lineage in its minimal on-chain form: walk back up the parentCf chain to reach the origin; look up references in the other direction to reach what came after.

The second artifact is the review verdict. A reviewer signs a structured message — using EIP-712, Ethereum’s common standard for structured signatures, which signs the fields themselves rather than a run of free text, so every field is locked by the signature. The message carries eight fields:

The reviewer must be an identity already authorised on chain, and verification supports both ordinary wallets and contract wallets — the latter through the ERC-1271 standard interface. Once the signature is on chain, “who endorsed this row and what grade they gave it” stops being a line in a platform’s database and becomes a cryptographic fact anyone can verify.

One detail worth being clear about: submitting a CF is permissionless in the protocol — no authorisation needed, anyone can call it — and the chain itself does not verify at submission time that the caller controls that DID. So strictly speaking, what the on-chain anchor proves is that a binding of “this content × this identity × this time” was publicly recorded, and that nobody can change it afterwards; the endorsement that it really was that person’s work comes from the review signature, and from a plain fact — the real contributor holds the original content and an impostor does not. The protocol promises no more than that, but it is already enough to support verification: give someone a metadata document and a cfId, and verification takes three steps:

  1. hash the document;
  2. assemble the cfId per the formula;
  3. look up on chain that this id exists, and which DID and which task it is bound to.

All verification needs is that document and the public on-chain record; the whole process depends on no platform at all.

Top: a cfId is keccak256 over metadataHash, contributorDid, taskId and an optional parentCf; the formula deliberately omits metadataUri, so the location can change while the id does not. Bottom: lineage is a parentCf chain — a SAMPLE raw sample is referenced by a LABEL annotation, the LABEL by an AMENDS correction, the AMENDS by a VALIDATION review endorsement, each with its own cfId.
Figure 3 · How a cfId is built, and the parentCf lineage chain

Ownership lives on the dataset

There is a layering here that is easy to conflate and worth stating on its own: CF and Dataset are two layers, and ownership sits at the dataset layer, not on the single CF.

A CF does two jobs:

A single CF is not an asset: it is not held, not transferred, and nobody buys one annotation.

The dataset is the unit of the asset: it aggregates a batch of CFs into a whole that can be held, transferred, priced and exited. That layering is the most important step in the protocol’s design — put ownership on a single row and the grain is too fine for a trade to exist; put it on the dataset and “I hold 3% of this dataset” is measurable and transferable. Tracing keeps its per-row granularity, and the two layers each do their own job.

In the protocol a dataset version is uniquely identified by the triple (assemblerDid, manifestId, versionNumber), and three things are stored on chain: the Merkle root of the membership table, the total shares totalShares, and the URI pointing at the metadata.

Assembly happens like this: the assembler — the assemblerDid in that dataset triple — picks a batch of CFs and gives each one a weight, and the weights sum to a fixed totalShares. The full list of members and weights is published in the off-chain metadata, and the chain stores only that table’s Merkle root. So the black box with 300,000 rows mixed in, back at the opening, becomes a public membership table: whose each row is and what weight it carries are both in the table; the table’s integrity is guaranteed by the root on chain, and nobody can quietly change it afterwards. Your share is the sum of the weights of your rows divided by totalShares — arithmetic you can redo yourself.

Assembly changes nothing about the CFs themselves. A CF not picked into a dataset does not expire — its fingerprint, attribution and review signatures are all still on chain, it simply has no shares hanging off it for now, and it can be picked into a new version later all the same; a CF that is picked is not “consumed” either — it merely gains an association of “aggregated into X”, the source cfId can always be verified independently, and the same CF can go into other datasets. Assembly is itself permissionless: any user with a registered DID can publish a dataset version, and the protocol reserves that power for nobody.

Two kinds of “owning” have to be kept apart here. Once the assembler publishes a version, they are that dataset’s administrator in the protocol — the contract calls it the owner, and the grant issuance and revocation described later are executed by it; shareholders hold an economic interest — they take the revenue and can transfer it. Administration and revenue rights are separate from the moment of assembly: holders take no part in each grant decision, but neither are they locked in by an administrator who goes dark — assembly is permissionless, and anyone can reassemble the same batch of CFs into a new dataset version.

Verification is equally mechanical: rebuild the Merkle tree from the weight table in the metadata and compare it against the root on chain; any holder can take their leaf and proof to the contract to claim their shares, and the claim going through is itself proof that the shares are real.

Each row of the public off-chain weight table is a cfId, a contributor and a weight, and the weights sum to totalShares, here 10; the rows hash into four leaves, which hash pairwise into H12 and H34 and then into the root, and only the root and totalShares go on chain. Your leaves are L1 and L3, so your share is 3 plus 1 over 10, or 40 percent. The path from L1 to the root is highlighted, and L1's proof is just the two sibling hashes L2 and H34. Verify by rebuilding the whole tree from the weight table and comparing with the on-chain root, or take your own leaf and proof straight to the contract to claim.
Figure 4 · Weight table → Merkle tree → root on chain; a share is arithmetic anyone can redo

Ownable: making ownership exercisable

Shares are minted as ERC-1155 tokens — Ethereum’s multi-token standard, where each dataset version is one kind of token inside the same contract. The four things named earlier land here one by one.

Measurable was covered in the last section: a share is computed from the public weight table, and anyone can recompute it.

Transferable: shares transfer freely peer to peer, and who holds them right now is on chain to look up at any time. A transfer triggers a settlement hook — revenue is settled to the sender against their holding before the transfer, and the receiver accumulates from their new holding onward — so money already distributed to you is not clawed back because you sold the share.

Priceable: using the data costs money, and what the payment buys is an access grant. What the protocol requires is that pricing be possible at all; how high the price is and who it sells to it does not prescribe — that belongs to implementations and to the market, not to the protocol. What it underwrites is that the grant is a fact that can be looked up on chain and revoked.

Redeemable: when revenue arrives, the contract executes distribute(datasetId, token, amount), crediting each holder’s claimable balance against the holding snapshot at that moment. Two hard rules apply here:

  1. The denominator is fixed at totalShares, not “shares claimed so far” — claiming late costs you nothing, and claiming early buys you nothing.
  2. Who the revenue belongs to is decided by who holds the shares at the instant of distribute; transfer afterwards and the money already credited to you does not follow the shares to the buyer. That rule is there to prevent disputes: once shares are freely transferable, “whose money is this” needs exactly one answer. On claim, the money is paid to the DID’s current owner address — the books follow the identity, so lose a wallet, swap in another, and the claimable revenue is still there.

The platform fee is cut out at a fixed proportion at distribute time and withdrawn separately. The rate is a public parameter and can be zero; every fee taken is a visible outflow on chain — at reconciliation it is not a vague “operating cost” but a record that can be checked line by line.

The life of a share along a timeline — assemble, claim shares, distribute, transfer shares, claim revenue — with an example ledger beneath: you claim 4 of 10 shares; a 1,000 distribution credits you 400, because the denominator is fixed at totalShares, so claiming late costs nothing and claiming early gains nothing; you transfer 2 shares and the 400 stays with you, because revenue is settled to the sender before the transfer; you then claim and the 400 is paid to the DID's current owner address, even from a new wallet.
Figure 5 · The life of a share: sell the share, and the revenue already credited is still yours

Accessible: who gets to see the plaintext

Every mechanism so far deals with the ledger; access to the data is another matter. The raw data is not stored in the open, and who can fetch it is decided by a grant. As for whether that is enforced by access control or locked by encryption, that is an implementation choice — the protocol prescribes no means, only the conditions for letting data through.

A grant has two layers:

So “is it valid, has it been revoked” is an on-chain fact that anyone can check and nobody can deny, while “what the grant actually says” keeps the flexibility and privacy of being off chain. Each layer plays to its strength.

Before handing the data to a requester, the verifier must pass all five checks:

  1. the requester proves they control the DID in the credential;
  2. the credential’s signature is valid, and the issuer must be that dataset’s on-chain owner DID — otherwise anyone could self-sign a “grant”;
  3. the credential matches the digest the grantor kept when they approved it;
  4. requester and dataset match the on-chain anchor;
  5. the anchor is ACTIVE and not expired.

All five must pass before the data goes through; a valid anchor is only one necessary condition among them.

The owner in the second check is singular — the administrator assemblerDid from earlier: grants are issued and revoked by it. Shareholders’ revenue rights are unaffected, and the income each grant brings in is still split by share.

The protocol also supports revoking a grant, with the semantics that new access stops. The grantor can revoke at any time, the on-chain status flips to REVOKED, it takes effect immediately, and every access request after that is refused. But data already in someone else’s hands is not something the protocol can pull back — today we constrain redistribution with watermark tracing and licence terms.

Four lanes: the grantor, the dataset owner, issues a VC off chain and anchors it on chain with status ACTIVE, and hands the VC itself to the grantee; the requester presents the VC with DID authentication to the verifier, who runs five checks — the requester really controls the DID in the VC, the VC signature is valid and its issuer is the dataset owner DID, the VC matches the digest kept at approval, requester and dataset match the anchor, and the anchor is ACTIVE and unexpired — reading the anchor status on chain, and only when all five pass is the data released. The grantor can revoke at any time, the on-chain status flips to REVOKED, and later requests fail at check five.
Figure 6 · Grant and revocation: an off-chain VC plus an on-chain anchor, five checks before the data goes through

Data storage

Storage matters a great deal, because it is the shared foundation under all three of the above. The whole storage design is a hybrid, and the information about one row lives in three places:

The on-chain record points at the metadata, and the metadata in turn carries the hash and address of the data itself. Anyone can follow that trail to fetch the content, recompute the hash per the formula, compare it against the on-chain record, and so verify the data has not been altered. What can be fetched freely, of course, only goes as far as the metadata layer; the last step — fetching the data itself — goes through the grant channel described above, not by helping yourself.

On top of this design the protocol enforces only two hard rules:

  1. Content addressing: every address comes with a hash; fetched content must be re-hashed, and a mismatch must be refused. Who stores it does not matter — cloud storage, a decentralised network, whatever — because whether the content is right can be self-evident. The requirements on the address itself are only two: anyone must be able to fetch it remotely — not just the machine that stored it, so a local path does not count; and the content must be immutable — the same address always returns the same content.
  2. The location can be repaired, the identity does not change: a dead address can be updated, because id and address are decoupled. Migrating storage, adding replicas, switching providers — none of it touches any fact on chain.

Beyond those two — where it lives, how many replicas, how long it is retained, who pays — the protocol prescribes nothing. Those are engineering and economic questions for the implementer, and different implementations may answer them differently.

Coda

You ended the contract with that AI company, and this time you handed the data to a platform running on XnY Protocol.

The moment you submit, every row you contribute has its own fingerprint, bound to your DID, recorded on the ledger that belongs to no party. The reviewer’s verdict and signature go onto the ledger too — that this row is yours, who endorsed it, what grade it got, no longer depends on you keeping the evidence.

Later the data is assembled into a dataset, alongside 300,000 rows from other people. But this time the mixing is a public membership table: which rows are yours and what weight each carries is there for you to open and check whenever you want; your share is the sum of the weights of your rows divided by totalShares — arithmetic you can redo yourself.

The dataset sells. Every grant leaves an on-chain anchor — the digest of who it was granted to, the validity window, whether it was revoked — for anyone to look up. Next time you read that “another company has this data too”, one lookup tells you whether it was a proper grant or a leak: if there is an anchor, go reconcile; if there is not, take the fingerprints and the lineage and hold someone to account. The question you could not answer at the opening now has a test.

Each time revenue arrives, the contract credits your claimable balance against the holding at that moment, and you can read the number yourself; withdraw when you like, paid to the address behind your identity. The split is no longer a sentence in a contract PDF, it is deterministic logic executed by code.

And if this platform itself goes under one day? Your fingerprints, your shares and your claimable revenue are not in its database, they are on chain — bring in another operator and they are all still there. Every promise here holds without depending on any one company staying alive.

The protocol has its own clear limits, of course. It does not vouch for the quality of the data itself — reviewers’ signatures and the market answer that; nor is it the protocol’s business whether a dataset fetches a good price. What is genuinely still on the way is control over the plaintext: today the data itself is held in the operator’s storage, and letting the data’s owner hold the keys, with the operator never touching the plaintext, is the next step the protocol is working towards.


This post describes the XnY Protocol v2 spec. On-chain data and implementation progress: explorer.xny.ai; documentation: docs.xny.ai.

Related