Document Anchoring for Tokenized Securities: Smart Contract Architecture

One registry, never overwritten: document anchoring for tokenized securities smart contract architecture, built for four EU regimes at once.

Gayathri

•

Sep 23, 2026

•

Document Anchoring for Tokenized Securities Smart Contract Architecture

A document registry looks like the simplest contract in the architecture: a hash, a URI, a timestamp. It is also the contract that four regimes read — the Prospectus Regulation, the Market Abuse Regulation, the ELTIF Regulation's own disclosure rules, and PRIIPs — and each of them means something different by "a new version was anchored." Scoped from any one of those regimes it is under-built for the other three.

This article covers DocumentRegistry as that multi-regime version model. The prospectus article already covers it from one angle — publication, validity, and the supplement gate — and the first section says exactly where the line between the two runs. The wider architecture is in the EU-Compliant Tokenized Securities: Smart Contract Architecture pillar; the covenants that bind to the versions anchored here are in the investor-covenants article.

1. The boundary with the prospectus article

Applies to every reader. Stated first so the two articles do not describe the same contract twice and disagree.

The prospectus article keeps the registry as the Prospectus Regulation's publication and validity mechanism: the ten-year accessibility duty under Article 21(7) and how it splits between hosting and proof; the supplement gate the subscription escrow reads before it opens a withdrawal window; and the anchor check on the subscription path that stops the contract selling against a withdrawn prospectus.

This article owns the version model those mechanisms sit on — what a version is, what the four regimes each do when one lands, why the history cannot be deleted, and how many registries to deploy. Where the prospectus article describes a registry function, this one explains why the function is shaped that way for regimes that have no withdrawal window at all.

2. The version hash is the product, not the document

Applies to every regime below. This is the single design decision the rest depends on.

The registry follows the ERC-1643 document-management pattern: the document stays off-chain, and the chain holds its hash and a hash of where it is hosted. Two things the pattern does not say are load-bearing here.

A document is a slot; versions accumulate underneath it. openDocument() creates a stable, issuer-chosen reference for "the prospectus for this offer" or "the key information document for this product." anchorVersion() pushes a version onto that slot and makes it current. Every version carries the fields that later checks read — and note how few there are:

struct Version {
    bytes32 versionHash;  // the document's own hash
    bytes32 uriHash;      // hash of where it is hosted
    uint64  anchoredAt;
    uint64  approvedAt;   // regulator's approval date; 0 = this regime has no ex-ante approval
}

Every delivery, consent and acknowledgement duty in the stack is discharged against a specific version. A retail investor was given that key information document; a fund investor acknowledged that ten-year warning. The covenant store satisfies its gate by comparing the investor's stored version hash against currentVersionHash() here. That single comparison is what makes a revision invalidate every outstanding acknowledgement the moment it is anchored — no sweep, no configuration, no chance to forget. A boolean anywhere in that path reintroduces the fail-open the design exists to remove.

Three reads serve the rest of the architecture. currentVersionHash() is what a covenant compares against. isCurrent() answers one question and only one — is this hash still the live version. documentStatus() is keyed by version hash rather than slot, because the contracts that call it are handed an artefact hash and not a slot name: it returns whether the hash exists and what approval date sits on it. Note that documentStatus() answers for superseded versions too, which is not an oversight: the escrow's window opener is asking about a supplement that may since have been supplemented again. Existence and currency are different questions and the contract keeps them on different functions.

3. Four regimes, one contract

Applies according to which regimes the instrument triggers. An open-ended retail fund is outside the Prospectus Regulation and still needs this contract.

The anchored document set is wider than a prospectus:

RegimeDocumentsRetention the regime sets
Prospectus RegulationProspectus, final terms, supplementsAt least ten years' electronic accessibility, Article 21(7)
Market Abuse RegulationDisclosed inside informationAt least five years on the issuer's website, Article 17
ELTIF RegulationThe fund's own prospectus (Article 23) and annual report (Article 24) — a disclosure regime distinct from the Prospectus Regulation, and not gated by open- or closed-ended status—
PRIIPsThe key information document, drawn up before the product reaches retail (Article 5), reviewed at least every 12 months and on material change (Article 10)—

Only the first row is a Prospectus Regulation duty. Twice in this design the open-ended-fund exclusion from that Regulation was read as switching off the registry. It switches off one regime's use of it. An open-ended retail fund owes a key information document, a long-term fund owes its own prospectus and annual report, and both anchor here. The subscription escrow's withdrawal windows genuinely drop out for such a fund; the registry does not.

The registry serves all four and models none of them — the slot carries no regime at all. A document's regime governs what the rest of the stack must do when a new version lands, which is an argument for putting it where that stack can act on it, not here. Section 4 works through why this contract is the wrong home for it.

4. The asymmetry — what a new version means in each regime

Applies to every version anchored after the first. This is the section that decides where regime knowledge lives.

The same call, anchorVersion(), has a different downstream statutory effect depending on which regime's document sits in the slot:

RegimeWhat anchoring a new version does
Prospectus supplementOpens a withdrawal window. Investors who already agreed to subscribe may withdraw within a minimum of three working days. The subscription escrow reads the registry before opening it, and refuses a hash that is not anchored and regulator-approved
Key information document revisionOpens no window. It invalidates every outstanding delivery acknowledgement instead. The next subscription needs a fresh one against the new hash
Disclosed inside informationNeither. The anchor is an integrity proof over the retention period; publication is the issuer's website
Fund prospectus and annual reportNeither. The anchor records that the document existed in that form on that date

That table is the most important thing in this article, and the registry encodes none of it — deliberately. Three reasons, in ascending order of weight.

A regime tag on the slot cannot enforce the asymmetry, because contracts cannot read events. 

Tagging each slot and emitting a different event per regime looks like it makes the difference operative. It does not: no event opens a withdrawal window. Opening one is a separate governance transaction against the escrow that somebody has to remember to send. A tag would buy an asymmetry documented on-chain and enforced nowhere — the most expensive kind of comment.

The one place the distinction does bite is offer configuration, not document metadata. 

The registry's status lookup is keyed by hash across every slot, so without a guard any approved hash — a key information document, a fund's annual report — could open an Article 23 window. That guard is real and necessary. It lives in the subscription escrow, as an allowlist of the slots holding this offer's prospectus lineage, because that is a fact about an offer. The escrow is deployed once per offer and never sits behind a proxy, which makes it the natural home for offer-specific configuration.

And a closed enumeration would make a new regulation force a redeployment of the one contract that cannot be redeployed. 

Serving a fifth regime would mean changing this contract — whose storage is the ten-year Article 21(7) evidence, which a fresh deployment cannot honestly restate. Coupling the document store to the regulatory taxonomy puts a migration nobody can perform on the critical path of every future rule change.

So the contract emits one generic VersionAnchored, carrying the superseded hash alongside the new one. An indexer that knows a slot holds key information documents can still answer which acknowledgements just died — v1 → v2 tells it that, "v2 is live" does not. The table above is a runbook fact and an indexer's classification. That is the right place for it.

5. No delete function — that is the retention control

Applies to every regime with a retention duty. Stated because the obvious implementation stores a date nothing enforces.

Two retention periods reach this contract — ten years under the Prospectus Regulation, five under the Market Abuse Regulation. The tempting build stores a retention date on each version. Nothing on-chain can enforce a duty owed by a file server, and a stored date no function reads is decoration.

We build the version history append-only, with no delete function. Superseding version one with version two marks version one non-current and removes nothing. The retention deadline is emitted, for the off-chain archive that actually holds the file, and never stored. On-chain, the guarantee is narrower and stronger: the hash you anchored is still provably the hash you anchored, for as long as the chain exists. Keeping the document reachable is the hosting arrangement's job; proving which document it was is the anchor's. That split is the whole of what makes the retention guarantee enforceable rather than recorded.

A caveat on what "append-only" is actually protecting, because it is easy to overclaim. 

The proof that a given hash was anchored on a given date lives in the event log, written into block history when the transaction was mined. Nothing later reaches back and changes that — not a delete function, not an upgrade, not a new implementation. So the audit answer to "was this the prospectus in force on 3 March 2027" is safe regardless of how the contract is deployed.

What the absence of a delete function protects is the live read: that versionAt() and isCurrent() still answer consistently with the log, today, for the contracts gating on them. That is the real exposure of putting this registry behind an upgradeable proxy — not the archive, but the answers the covenant store and the escrow act on, which would become governance-mutable. The upgrade mechanism is also an offer-document content item, so an upgradeable anchor is something the prospectus has to describe.

Worth stating plainly: that exposure is the same for every contract in the architecture. The case for deploying this one directly is narrower than the retention story suggests — one fewer moving part on the contract holding the evidence — and it is a reasonable default rather than a necessity.

6. The review cadence — why Article 10 stays off-chain

Applies where any investor is retail. Stated because the registry looks like the natural home for this duty and is not.

PRIIPs Article 10 requires the key information document to be reviewed at least every 12 months and on any material change, and revised where the review requires it. The registry holds no review state and enforces no cadence. A revision is anchored like any other version: the new hash supersedes the old, and every acknowledgement bound to the old one stops satisfying its gate, exactly as section 2 describes. That is the whole of the contract's involvement.

The duty is not modelled because it has two limbs and a contract can only see one. 

A clock catches at least every 12 months. Nothing on-chain can detect a material change in the underlying product — that limb is a human judgment about the world, and a contract has no access to the world.

That asymmetry is tolerable in a monitoring tool and corrosive in a control. A control that covers half a duty does not leave you half-covered; it leaves you covered on the easy half and quietly confident about the hard one. The compliance calendar entry gets closed because the contract "handles the review," and the material-change trigger — which needs a named owner and a link into the product-change process — never gets built. A registry that visibly does not cover Article 10 is safer than one that appears to.

So Article 10 is an off-chain duty with a named owner, and the deployment guide says so in those words. 

The same trade runs through the upgrade path elsewhere in this series: where the judgment is human, the control belongs in a reconciliation job someone owns, not in a require that can only read a calendar. The honest version of an on-chain control is one that refuses to imply coverage it does not have.

⚠️ The consequence is real and has to be staffed. A key information document that is never reviewed satisfies every on-chain read indefinitely. If you take this pattern, the review date and the material-change trigger go in the compliance calendar before the first retail subscription — not after.

7. Anchoring is a governance action, not an operational one

Applies to every version. The key that anchors decides who can open a statutory window.

Anchoring a supplement opens a withdrawal window on every subscription accepted before it. Anchoring a key information document invalidates every outstanding acknowledgement. Neither belongs on a daily-operations key. We build the registry's write path behind the same multisig and timelock as a contract upgrade, and nothing else can call it.

There are exactly two write functions, and that is the whole governance surface. 

openDocument() creates a slot; anchorVersion() pushes a version onto it. Nothing else writes at all — every fact a version carries is fixed at the moment it is anchored, and no later call can change it. That is the shape the next three points follow from.

The regulator's approval date is an argument to the anchor, not a later call. 

Article 23(1) puts the order plainly: the competent authority has up to five working days, and the supplement is published after it clears. A version sitting anchored-but-unapproved is not a state the Regulation contemplates, so the contract does not let you represent it — anchorVersion() takes approvedAt and there is no setter to change it afterwards.

Two consequences, both runbook rather than contract. A regime with no ex-ante approval passes zero — a key information document is not approved, a Market Abuse disclosure is not approved, and Article 8(5) final terms are filed, not approved. And the date is write-once: correcting a wrong one means anchoring a new version, which on a prospectus slot opens a withdrawal window on every subscription taken so far. A typo in that field is a refund event, not a patch. That is the price of collapsing two transactions into one, and it is the right side of the trade, because it puts the cost of the error where the error actually lands.

There is no way to anchor a document confidentially, and that is the Market Abuse answer rather than a gap in it. 

Under the protracted-process rules, intermediate steps stay confidential until the final event is disclosed. On a public ledger, any anchor at all — including a concealed one — publishes that something was anchored to that slot on that date, which for a document confidential precisely because it is undisclosed inside information is a statement that undisclosed inside information exists.

So the control is timing, not cryptography: anchor after the announcement. 

A document not anchored until the final event is disclosed has no confidentiality exposure to engineer around. The only thing an earlier anchor could add is a provable pre-announcement timestamp, and no regime here asks for one on-chain — Article 17(4) delayed disclosure is evidenced by the notification to the competent authority, and the Article 18 insider list carries its own dated record off-chain, where it has to live anyway because it is personal data.

The rule: confidentiality is a scheduling decision, not a contract feature. 

Before building a mechanism to anchor something you are not allowed to disclose, name the regime that requires a timestamp earlier than the disclosure itself. If none does, do not anchor it yet.

8. How many registries

Applies to any operator running more than one tokenized asset. Decide it on upgrade cost, not gas.

"Multi-regime" is not "multi-asset." Everything above is one contract serving four regimes for one instrument. Whether one registry serves many instruments — a namespaced registry, or one per asset — is a separate question, and the coupling that decides it is not engineering.

A material change to a disclosed contract's behavior, arising during an offer, needs a supplement filed before deployment — with up to five working days of regulatory approval and a withdrawal window on publication. A registry shared across several assets makes one upgrade to that registry a material change to several disclosed behaviors: several supplements, several approvals, several windows. Sharing is cheaper to build and materially more expensive to change, and the cost lands on the compliance calendar.

Our default is one registry per asset until the decision is taken deliberately. Merging later is cheap; splitting after issuance is a re-issuance.

9. What must never be anchored

Applies to every slot. Two rules, each with a regime behind it.

No document content, ever. The registry holds hashes and a hosting reference. The document is the archive's.

No personal data, in any form — and for the insider list that means no anchor at all, not a hashed one. The list carries names, dates of birth, home addresses and telephone numbers, precisely the category the right to erasure covers, and an immutable ledger cannot honor it. But the case against anchoring it does not rest on that. 

Nothing on-chain gates on insider status — being listed restricts no trade — so the anchor has no consumer and fails the test in section 2 outright. A qualified electronic timestamp gives the list a legal presumption of accuracy that a chain hash does not, which makes the anchor the weaker artefact in front of a regulator rather than the stronger one. And anchoring an event-based section publishes a timestamped signal that a new piece of inside information came into existence on that date. Keep the list off-chain, timestamped, and out of this contract.

If you're evaluating a registry-first architecture like this one for a live issuance, that's the kind of build an RWA tokenization development company like ours takes on end-to-end.

At a glance

ConcernOn-chainPartialOff-chain
Version modelSlot per document, versions beneath it; currentVersionHash(), isCurrent(), documentStatus()——
Prospectus — Art 21(7), Art 23Anchor, with the approval date as an argument to the anchor; supplement anchoring is what the escrow readsTen-year hostingFiling; materiality per change; getting approvedAt right first time — it is write-once
MAR — Art 17Anchor as integrity proof, after the announcement — on a public ledger any anchor publishes that something was anchored, which is itself the leakFive-year website hostingClassify the step as intermediate or final first, and schedule the anchor accordingly
MAR — Art 18 — insider listsNothing. No anchor, hashed or otherwise—List off-chain, qualified electronic timestamp; acknowledgments and ≥5-year retention
ELTIF — Arts 23–24Anchor—Annual report
PRIIPs — Art 5, Art 10Anchor only — a revision supersedes the old hash and invalidates acknowledgements bound to it. No review state of any kind: a clock reaches the 12-month limb and never the material-change limb, and half a control invites false confidence in the other halfKID productionThe whole Art 10 review — both limbs, named owner, compliance calendar
RetentionAppend-only, no delete function; deadline emitted, never storedThe archive—
GovernanceWrite path behind the upgrade multisig and timelockSalt reconciliation with a named owner—
InstancingPer asset by default—Decide on supplement cost before the second asset

This is engineering commentary on regulatory requirements, not legal advice. Which documents a specific instrument owes, and under which regime's retention rules, needs sign-off from counsel.

Gayathri

Gayathri

With a dedication to delivering organic content by simplifying complex concepts of Blockchain, and love to connect with your hearts and minds.

On This Page

Talk to InnBlockchain

Get a simple architecture and launch
structure for your ICO.