Zum Hauptinhalt springen

RWA Metadata Storage

Status: Final

On-Chain Key-Value Metadata Storage for Compact Descriptors.

Abstract

Smart contracts often rely on off-chain JSON documents (e.g. for NFTs) or fixed functions (e.g. name(), symbol()) for metadata. This standard introduces a flexible on-chain key-value structure for metadata that must be durable, auditable, and optionally updateable. Use cases include document fingerprints, compliance references, and structured legal proofs. The KV structure works in parallel with existing standards to enhance trust, transparency, and auditability in tokenized systems.

Motivation

This CIP defines a standardized smart contract interface for storing compact key-value (KV) metadata on-chain. It supports sealed (immutable) and unsealed (updatable) entries. It is particularly useful for Real World Asset (RWA) tokenization and complements existing practices like CBC-20 metadata and off-chain NFT metadata URLs.

Specification

Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IOnChainMetadataKV {
function getMetadataValue(string calldata key) external view returns (string memory value);
function hasMetadataKey(string calldata key) external view returns (bool exists);
function isMetadataSealed(string calldata key) external view returns (bool sealed);

function listMetadataKeys() external view returns (string[] memory keys);
function getMetadataByIndex(uint256 index) external view returns (string memory key, string memory value);
function metadataCount() external view returns (uint256 total);

function setMetadataValue(string calldata key, string calldata value) external;
function sealMetadataKey(string calldata key) external;
}

Reference Implementation

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract OnChainMetadataKV is IOnChainMetadataKV {

struct Entry {
string value;
bool sealed;
bool exists;
}

mapping(string => Entry) private _entries;
string[] private _keys;

function setMetadataValue(string calldata key, string calldata value) external override {
Entry storage entry = _entries[key];

require(!entry.sealed, "Metadata key sealed");

if (!entry.exists) {
_keys.push(key);
entry.exists = true;
}

entry.value = value;
}

function sealMetadataKey(string calldata key) external override {
require(_entries[key].exists, "Key not found");
_entries[key].sealed = true;
}

function getMetadataValue(string calldata key) external view override returns (string memory) {
require(_entries[key].exists, "Key not found");
return _entries[key].value;
}

function hasMetadataKey(string calldata key) external view override returns (bool) {
return _entries[key].exists;
}

function isMetadataSealed(string calldata key) external view override returns (bool) {
require(_entries[key].exists, "Key not found");
return _entries[key].sealed;
}

function listMetadataKeys() external view override returns (string[] memory) {
return _keys;
}

function getMetadataByIndex(uint256 index) external view override returns (string memory, string memory) {
require(index < _keys.length, "Index out of bounds");

string memory key = _keys[index];
return (key, _entries[key].value);
}

function metadataCount() external view override returns (uint256) {
return _keys.length;
}
}

Real World Asset Use Case

RWA tokens frequently require referencing off-chain legal and regulatory artifacts, such as:

  • Investment prospectuses
  • Legal disclaimers
  • KYC provider certifications
  • Title deed hashes
  • Security identifiers (ISIN, CUSIP)

By using on-chain metadata KV:

  • Developers can store compact fingerprints or signed digests.
  • Legal auditors can verify presence and integrity on-chain.
  • Updates can be allowed when needed—but sealed once finalized.

RWA Ticker

The RWA ticker should be chosen according to the commodities being tokenized:

Examples:

RWAZCH5

Where:

  • RWA = Real World Asset prefix
  • ZC = Commodity (Corn)
  • H = Month code (March)
  • 5 = Year (2025)

Another example:

RWASWSG5

Where:

  • SWS = Sugar type
  • G = Month code (February)
  • 5 = Year (2025)

Keep tickers short, descriptive, and standardized.

Month Code Table

MonthCode
JanuaryF
FebruaryG
MarchH
AprilJ
MayK
JuneM
JulyN
AugustQ
SeptemberU
OctoberV
NovemberX
DecemberZ

Comparison Summary

MethodScopeLocationMutableStandard Use
name() / symbol()GlobalOn-chainNoIdentification (CBC-20/4626)
tokenURI()Per-tokenOff-chainYesNFT metadata (CBC-721/1155)
Metadata KV (this CIP)Key-definedOn-chainOptionalContextual metadata, docs, hashes

Rationale

The on-chain key-value metadata storage approach addresses the need for flexible, auditable, and optionally updateable metadata in smart contracts. This standard provides a middle ground between immutable on-chain data and mutable off-chain references.

This is particularly valuable for real-world asset tokenization, where legal and regulatory compliance requires both transparency and the ability to update information when necessary.

Backward Compatibility

This standard is designed to work alongside existing metadata approaches like:

  • CBC-20 name() / symbol()
  • CBC-721 tokenURI()

It adds additional metadata capability without breaking existing implementations.

Security Considerations

  • Mutable entries should be carefully permissioned.
  • Metadata keys should be sealed once finalized.
  • Consider role-based access control for setMetadataValue.
  • Consider versioned metadata keys such as:
PROSPECTUS_V1
PROSPECTUS_V2
LEGAL_HASH_V1

to preserve historical references.

Conclusion

The On-Chain Metadata KV standard provides a flexible and secure approach to managing metadata in smart contracts. Its adoption improves transparency, auditability, and compliance in tokenized systems, especially for Real World Asset (RWA) ecosystems.

References

Deployment Script

DeployOnChainKV.s.sol Solidity deployment script using the Foxar framework.

Test Suite

OnChainKV.t.sol Unit tests validating metadata setting, sealing, and retrieval.

Contract ABI

IOnChainMetadataKV.abi.json Interface ABI for integration with external tooling.

Copyright and related rights waived via CC0.

Tags:CBC