OCP-0004: On-Chain Entity Registry
Abstract
This OCP extends the crown registry to non-token entity types. It adds two new SymbolType values (NFTCollection, Protocol), defines per-type verification method restrictions enforced on-chain, and establishes the Entity Type Requirements Matrix for future type additions.
Motivation
The Identity Gap
On-chain entities (protocols, NFT collections, DAOs, bridges) lack a standard for verified canonical identity. Each category is developing siloed standards (ERC-4824 for DAOs, ERC-8004 for AI agents) with no unifying layer. CAIP-19 provides asset addressing but not identity, metadata, or ownership verification.
Why OpenCrown
The crown system's architecture is already general-purpose — only the inputs are token-specific:
symbolTypeis stored asuint8— 256 possible types with no storage layout change neededverificationMethodis stored asuint8— 256 possible methods, same story- The heartbeat keeper accepts arbitrary scores; scoring methodology is off-chain
- The naming service resolves any crown symbol; entity type is irrelevant to resolution
- The anti-squatting mechanisms (soulbound, heartbeat decay, escalating fees) are entity-agnostic
This OCP extends the registry to additional entity types using the existing storage and verification infrastructure.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Spec 1: Entity Type Taxonomy
Expand the SymbolType enum to include new entity categories. Documentation SHOULD use "entity type" language going forward, while maintaining backwards compatibility in code by keeping the SymbolType name:
// Existing values (unchanged):
// 0: Native — L1/L2 gas token
// 1: Token — Fungible token (ERC-20, SPL)
// 2: Wrapped — Canonical wrapped version
// 3: Bridged — Cross-chain bridge version
// 4: Synthetic — Derivative/synthetic asset
// New values introduced by this OCP:
// 5: NFTCollection — NFT collection (ERC-721, ERC-1155)
// 6: Protocol — Protocol or DAO identity
Backwards compatibility: The symbolType field is stored as uint8 in the Crown struct. No storage layout change. No upgrade to existing data. Values 0-4 continue to function identically. The SymbolType enum in the interface contract gains two new members.
Future expansion: Values 7-255 are reserved for future entity types. New entity types MAY be added via governance proposal under this framework's Requirements Matrix (Spec 4), without requiring a separate OCP. Only changes to the framework itself require a new OCP.
Spec 2: NFT Collection Crowns (EntityType 5)
What it represents: Verified ownership or stewardship of an NFT collection's identity. The crown is for the collection as a whole, NOT for individual NFTs within it.
Crown struct usage:
| Field | Usage |
|---|---|
symbol |
Collection ticker/abbreviation (max 20 chars) |
chainId |
Chain where the collection contract is deployed |
tokenAddress |
The ERC-721 or ERC-1155 contract address |
symbolType |
5 (NFTCollection) |
Allowed verification methods:
| Method | Value | Rationale |
|---|---|---|
| Deployer | 0 | Wallet that deployed the collection contract |
| Owner | 1 | Ownable.owner() on the collection contract |
| MintAuthority | 2 | Program authority patterns relevant for Solana NFT collections |
| Foundation | 3 | Domain-verified organization attestation |
| Governance | 4 | DAO governance vote |
Disallowed verification methods for NFTCollection:
| Method | Value | Rationale |
|---|---|---|
| Majority | 5 | Majority holder verification is undefined for non-fungible collections |
Heartbeat scoring methodology (off-chain keeper):
| Score Component | Weight | Methodology |
|---|---|---|
timestampScore |
50% | Identical to fungible tokens — time since last update |
volumeScore |
30% | 30-day rolling on-chain activity: transfers, mints, and burns, normalized. NOT secondary market sales volume. |
holderScore |
20% | Unique wallets holding 1+ items from the collection over 30-day rolling window |
ERC-1155 gap: ERC-1155 contracts that host multiple distinct collections under a single contract address require a collection identifier to disambiguate which collection a crown represents. This capability is under active research and SHOULD be addressed in a future governance proposal. Until resolved, crowns for ERC-1155 contracts MUST represent the contract as a whole. Implementations SHOULD NOT mint NFTCollection crowns for multi-collection ERC-1155 contracts until the collection identifier mechanism is defined.
Anti-squatting: All existing mechanisms apply without modification.
Naming: Collection crowns resolve in the naming service identically to token crowns: collectionname.operator
Spec 3: Protocol Crowns (EntityType 6)
What it represents: Canonical verified identity for a protocol, DAO, or on-chain service. The crown establishes the entity's identity within the registry and naming service.
Crown struct usage:
| Field | Usage |
|---|---|
symbol |
Protocol name/abbreviation (max 20 chars) |
chainId |
Primary chain of the protocol (or chain where governance contract is deployed) |
tokenAddress |
The protocol's canonical administrative entry point (see below) |
symbolType |
6 (Protocol) |
Token address selection: tokenAddress MUST be set to the contract that serves as the protocol's canonical administrative entry point — specifically, the contract over which the claimant can demonstrate verified authority. This is typically the governance contract, admin multisig, or upgradeability proxy owner. When a protocol has multiple contracts, the claimant MUST specify the one whose ownership or control they can cryptographically prove. The verification proof MUST demonstrate authority over the specific address provided.
Allowed verification methods:
| Method | Value | Rationale |
|---|---|---|
| Deployer | 0 | Wallet that deployed the protocol's primary contract |
| Owner | 1 | Ownable.owner() on the primary contract |
| Foundation | 3 | Domain-verified organization attestation |
| Governance | 4 | DAO governance vote (most appropriate for protocol crowns) |
Disallowed verification methods for Protocol:
| Method | Value | Rationale |
|---|---|---|
| MintAuthority | 2 | Token-specific infrastructure |
| Majority | 5 | Protocols have no supply |
Heartbeat scoring methodology (off-chain keeper):
| Score Component | Weight | Methodology |
|---|---|---|
timestampScore |
50% | Identical — time since last update |
volumeScore |
30% | 30-day rolling on-chain transaction/interaction count, normalized |
holderScore |
20% | Unique interacting wallets over 30-day rolling window |
Special case — Self-referential protocol crown:
The OpenCrown protocol itself MAY hold a Protocol crown on each chain where it is deployed. This crown:
- Uses Governance verification (the DAO votes to mint its own crown per OCP-0002)
- Uses ecosystem health metrics for heartbeat:
volumeScore= crown claims in rolling period;holderScore= active crowns in registry
During Phases 1-2 (per OCP-0002 Spec 7), the governance multisig mints and manages the protocol crown via PROTOCOL_ADMIN_ROLE.
Naming: Protocol crowns resolve identically: protocolname.operator
Spec 4: Entity Type Requirements Matrix
Each entity type MUST define the following:
| Requirement | Description |
|---|---|
| Allowed verification methods | Which VerificationType values are valid for this entity type |
| Heartbeat scoring methodology | How volumeScore and holderScore are computed by the off-chain keeper |
| Anti-squatting adaptations | Any modifications to squatting protections, or confirmation that defaults apply |
| Naming conventions | How the entity type integrates with the naming service |
| Scope boundaries | What the crown represents and what it explicitly does NOT represent |
| Data source availability | Confirmation that data sources exist (or can be built) to feed the heartbeat keeper for this entity type |
Future governance proposals adding new entity types MUST include all six requirements. Proposals failing to address any requirement SHOULD be rejected during review. Changes to this framework itself (new requirements, modifications to the matrix) require a new OCP.
Spec 5: Governance Participation
All crown types participate in governance equally per OCP-0002. Governance eligibility is determined by heartbeat composite score (>= 40 = eligible to vote with weight 1.0), regardless of entity type. NFT Collection crowns and Protocol crowns have the same governance rights and weight as fungible token crowns.
Spec 6: Naming Collision Resolution
When multiple crowns share the same symbol across different entity types (e.g., a Token crown and a Protocol crown both using the same symbol), the naming service MUST resolve the bare name (symbol.operator) to the crown with the highest heartbeat composite score.
All crowns remain individually addressable by crown ID regardless of name resolution. Consumers requiring type-specific resolution SHOULD query by crown ID or filter by entity type via the API or SDK.
Scoped naming: Type-qualified names (e.g., symbol.type.operator) MAY be introduced via future governance proposal.
Contract Changes
This section describes the exact smart contract modifications required to implement this OCP. These changes would be presented in governance proposals for crown holder approval per OCP-0002.
Change 1: SymbolType Enum Extension
Contract: IOpenCrownRegistry.sol
Type: Interface modification (additive)
// BEFORE (current):
enum SymbolType {
Native, // 0
Token, // 1
Wrapped, // 2
Bridged, // 3
Synthetic // 4
}
// AFTER (proposed):
enum SymbolType {
Native, // 0
Token, // 1
Wrapped, // 2
Bridged, // 3
Synthetic, // 4
NFTCollection, // 5
Protocol // 6
}
Storage impact: None. The symbolType field in the Crown struct is already stored as uint8. Existing crowns with values 0-4 are unaffected.
ABI impact: The ABI changes to include new enum members. Consumers using raw uint8 values are unaffected. Consumers using enum names need updated ABIs.
Change 2: Verification Method Validation
Contract: OpenCrownRegistry.sol
Type: Logic modification in mintCrown()
Add validation that restricts verification methods by entity type:
// New internal function:
function _isValidVerificationForType(
uint8 symbolType,
uint8 verificationMethod
) internal pure returns (bool) {
// Types 0-4 (fungible): all verification methods allowed (backwards compatible)
if (symbolType <= 4) return true;
// Type 5 (NFTCollection): all methods except Majority
if (symbolType == 5) {
return verificationMethod != 5; // != Majority
}
// Type 6 (Protocol): all methods except MintAuthority and Majority
if (symbolType == 6) {
return verificationMethod != 2 // != MintAuthority
&& verificationMethod != 5; // != Majority
}
// Unknown types: reject until defined by governance proposal.
return false;
}
Called from: mintCrown() — reverts with InvalidVerificationForType(symbolType, verificationMethod) if validation fails.
Storage impact: None. Pure function, no state changes.
Change 3: New Error Type
Contract: IOpenCrownRegistry.sol
Type: Interface addition
error InvalidVerificationForType(uint8 symbolType, uint8 verificationMethod);
Change 4: New Event for Entity Type Tracking
Contract: IOpenCrownRegistry.sol
Type: Interface addition
// Emitted alongside CrownMinted when symbolType >= 5
event EntityCrownMinted(
uint256 indexed tokenId,
uint8 indexed symbolType,
string symbol,
uint64 chainId,
address tokenAddress
);
Implementations MUST emit EntityCrownMinted alongside CrownMinted when symbolType >= 5.
Rationale: While CrownMinted already includes all data, a separate indexed event by symbolType makes it efficient for indexers to filter entity-type crowns without scanning all crown events.
Summary of Changes
| Change | Contract | Type | Storage Impact | Breaking? |
|---|---|---|---|---|
| SymbolType enum extension | IOpenCrownRegistry | Additive | None | No (uint8) |
| Verification validation | OpenCrownRegistry | Logic | None | No |
| New error type | IOpenCrownRegistry | Additive | None | No |
| Entity event | IOpenCrownRegistry | Additive | None | No |
Upgrade path: Standard UUPS proxy upgrade. No storage migration required. All changes are additive or logic-only.
Rationale
Why Not Rename SymbolType to EntityType in Code
Backwards compatibility. External integrations, SDKs, indexers, and documentation all reference SymbolType. Renaming in code creates a breaking change with no functional benefit. Documentation and specifications SHOULD use "entity type" language going forward, with a note that the code-level name remains SymbolType.
Why NFT Collections But Not Individual NFTs
Crowns represent entity-level identity, not asset-level identity. An NFT collection is an entity (with a deployer, a community, a brand). An individual NFT is an asset within that entity. Registering individual NFTs would create massive squatting risk, minimal revenue upside, and scope creep toward marketplace functionality.
Why Verification Validation Is On-Chain
On-chain enforcement prevents operators from bypassing per-type verification restrictions. Off-chain validation would rely on operator integrity.
Why All Crown Types Have Equal Governance Weight
The heartbeat score already captures whether an entity is active and well-maintained. Introducing separate governance pools or type-weighted voting adds complexity without clear benefit — a healthy NFT collection crown and a healthy token crown both represent verified, active entities with equal stake in the registry's governance. Simplicity prevents governance gaming through type manipulation.
Why Heartbeat Uses Activity Not Sales
For non-fungible entity types (NFT collections, protocols), heartbeat scoring uses on-chain activity (transfers, mints, interactions) rather than secondary market sales volume. Sales volume is a marketplace metric that measures speculative interest. Activity measures genuine usage — the signal that matters for identity health. This also avoids dependency on off-chain marketplace data sources that may be unreliable or manipulable.
Why Entity Relationships Are Off-Chain First
On-chain relationships are expensive to store, hard to update, and create complex dependency graphs. Starting with off-chain (IPFS metadata + indexer) relationships allows the community to discover which relationships are actually valuable before committing to on-chain storage. The pattern follows the crown metadata model: content-addressed, owner-controlled, indexer-derived.
Backwards Compatibility
This OCP introduces no backwards incompatibilities:
- Existing crowns (types 0-4) function identically
- No storage layout changes
- No modification to existing verification or heartbeat logic
- The
SymbolTypeenum extension is additive - All new functionality is opt-in (only affects new crowns minted with types 5-6)
SDKs and indexers will need updates to recognize the new types, but unrecognized types already fall through gracefully (stored as raw uint8).
Security Considerations
Entity Type Validation
The _isValidVerificationForType function prevents minting crowns with inappropriate verification methods. For example, "Majority Holder" verification for an NFT collection could allow a whale to claim a crown that should belong to the collection creator. Restricting methods per type mitigates this.
Squatting on Protocol Names
Protocol names are higher-value targets than token names. The existing anti-squatting mechanisms (verification requirement, heartbeat decay, escalating fees) provide baseline protection. Additionally, protocol crowns typically require Governance verification (a DAO vote), which is the highest-friction verification method and the hardest to fake.
Naming Collision
When multiple entity types claim the same symbol, heartbeat-based resolution determines the bare name winner. This creates an incentive to maintain crown health, which is the desired behavior. Potential gaming (artificially inflating heartbeat to steal a name) is mitigated by the same anti-manipulation measures that protect heartbeat integrity for all crown types.
Future Entity Type Risk
New entity types introduced through future governance proposals could have unanticipated interactions with existing mechanisms. The Entity Type Requirements Matrix (Spec 4) ensures every new type explicitly addresses verification, heartbeat, anti-squatting, naming, scope, and data source availability — preventing under-specified types from entering the system.
Implementation Considerations
Off-Chain Keeper Changes
The heartbeat keeper requires new data source integrations:
- NFT collection data: On-chain activity metrics (transfers, mints, burns), unique holder counts (from on-chain indexing)
- Protocol data: Transaction counts, active users (from on-chain indexing or protocol-specific APIs)
These are keeper-side changes and do not affect the on-chain contracts.
SDK Updates
The SDK's SymbolType type union needs two new members: 'nft_collection' and 'protocol'. The VerificationMethod type MAY need filtering helpers per entity type. These are additive, non-breaking changes.
Operator UX
Reference operators will need adapted UI for NFT collection and protocol crown profiles — different display layouts, different metadata fields, different heartbeat visualizations. This is operator-level work outside the scope of this OCP.
Solana Program
The Solana program (programs/opencrown/) requires equivalent changes:
SymbolTypeenum extension in program state- Verification method validation per entity type in
mint_crowninstruction EntityCrownMintedequivalent event emission- These changes mirror the EVM contract changes and MUST maintain behavioral parity.
Future Direction: Entity Relationships
This OCP establishes entity identity. A natural next step is entity relationships — formal links between crowns that capture how entities relate to each other:
| Relationship | Description |
|---|---|
issuedBy |
This token/collection was created by this protocol (linked by crown IDs) |
governedBy |
This protocol is governed by this DAO (linked by crown IDs) |
bridgedFrom |
This bridged asset originates from this native asset (already partially captured by SymbolType 3) |
Entity relationships are NOT specified by this OCP. They SHOULD be recorded in crown metadata (IPFS) and indexed off-chain until the community identifies which relationships are valuable enough to warrant on-chain storage. A future governance proposal or OCP MAY formalize on-chain relationship primitives.
Copyright
Copyright and related rights waived via CC0.