--- eip: 8028 title: Data Anchoring Token (DAT) description: A semi-fungible token for AI-native digital assets with usage rights and revenue sharing author: Timi (@nora-coder-dot) , Daniel Li (@daniel) discussions-to: https://ethereum-magicians.org/t/draft-erc-eip-data-anchoring-token-dat/25512 status: Draft type: Standards Track category: ERC created: 2025-09-12 --- ## Abstract The Data Anchoring Token (DAT) is a semi-fungible token (SFT) standard for AI-native digital assets. Each DAT represents a bundle of **ownership certificate**, **usage rights**, and **revenue share**, optimized for datasets, models, and agent/inference workflows. This ERC introduces a token primitive for AI workflows. A DAT belongs to an **asset class** (dataset/model/agent) and carries a **value** (usage quota), a **shareRatio** (revenue entitlement weight), and optional **expireAt**. DAT supports **partial value transfers** within the same class, **class-level approvals** for operator platforms, **usage metering events**, and on-chain **revenue settlement** in ETH or [ERC-20](./eip-20.md). It composes with existing ERCs (e.g., [ERC-3525](./eip-3525.md)-like semi-fungibility, [ERC-2981](./eip-2981.md) royalty signaling, [ERC-4907](./eip-4907.md)/[ERC-5006](./eip-5006.md) rental roles) while filling the missing **usage metering + deterministic settlement** gap. ## Motivation AI development faces three persistent challenges: - **Data sharing barriers.** Privacy, lack of standardized frameworks, and trust discourage contribution. - **Data quality and evaluation.** Public data is inconsistent; valuable datasets lack verifiable metrics and provenance. - **Revenue attribution.** Contributors rarely receive fair compensation in centralized AI ecosystems. Existing standards ([ERC-20](./eip-20.md)/[ERC-721](./eip-721.md)/[ERC-1155](./eip-1155.md)) do not natively support **usage-based access rights** or integrated **revenue sharing** tied to utilization. DAT provides a minimal, composable framework to standardize ownership, usage, and settlement for AI assets. ## Specification This section is **normative** unless stated otherwise. Keywords **MUST**, **SHOULD**, and **MAY** are as in RFC 2119. ### 1. Terminology - **Class** — category of homogeneous AI assets (dataset/model/agent). - **DAT token** — unique on-chain identity under a Class with semi-fungible **value** (quota) and **shareRatio** (economic weight). - **Value** — consumable quota (e.g., inference calls, tokens processed, steps). - **shareRatio** — non-negative integer weight for per-Class settlement. - **expireAt** — optional UNIX timestamp after which usage MUST be invalid. - **Operator** — approved address (e.g., AI platform/agent runner) allowed to act within a Class. ### 2. Conformance & Scope An implementation conforms to DAT if it exposes the required **events**, **views**, and **state-transition functions** and adheres to the semantics below. Optional extensions MAY include an [ERC-3525](./eip-3525.md) profile, [ERC-2981](./eip-2981.md) royalty views, and [ERC-20](./eip-20.md)–denominated settlement. ### 3. Storage Model (Minimum) Per-Class: - `metadataURI (string)` — off-chain metadata (IPFS/Arweave). - `integrityHash (bytes32)` — commitment for authenticity. - `unitDecimals (uint8)` — decimals for **Value** units. - `policyURI (string, OPTIONAL)` — machine-readable usage/licensing policy. - `totalShare (uint256)` — sum of active (non-expired) `shareRatio`. - `accRevenuePerShare[asset] (uint256)` — cumulative settlement index per asset, scaled by `1e18`. Per-Token: - `classId (uint256)` - `value (uint256)` - `shareRatio (uint16/uint32)` (**MUST** saturate on overflow) - `expireAt (uint64)` (`0` = no expiry) - `owner (address)` - `countedInShare (bool)` — whether included in `totalShare` - `rewardDebt[asset] (uint256)` — accounting index snapshot (scaled by `1e18`) ### 4. Events (Required) ```solidity event ClassCreated(uint256 indexed classId, string metadataURI, bytes32 integrityHash); event ClassPolicyUpdated(uint256 indexed classId, string policyURI); event MetadataUpdated(uint256 indexed classId, string metadataURI, bytes32 integrityHash); event Minted(uint256 indexed tokenId, uint256 indexed classId, address to, uint256 value, uint256 shareRatio, uint64 expireAt); event TransferToken(uint256 indexed tokenId, address indexed from, address indexed to); event ValueTransferred(uint256 indexed fromTokenId, uint256 indexed toTokenId, uint256 value); event Expired(uint256 indexed tokenId); event UsageRecorded(uint256 indexed tokenId, bytes32 metricType, uint256 amount, address actor); event RevenueSettled(uint256 indexed classId, address indexed asset, uint256 amount); event Claimed(uint256 indexed tokenId, address indexed to, address indexed asset, uint256 amount); event ApprovalForClass(address indexed owner, uint256 indexed classId, address indexed operator, bool approved); ``` Notes: `asset` is `address(0)` for native ETH or an [ERC-20](./eip-20.md) address; `metricType` is a `bytes32` label (e.g., `keccak256("inference_calls")`). ### 5. Read-Only Views (Required) ```solidity function getClassMeta(uint256 classId) external view returns (string memory metadataURI, bytes32 integrityHash, uint8 unitDecimals, string memory policyURI); function classOf(uint256 tokenId) external view returns (uint256); function valueOf(uint256 tokenId) external view returns (uint256); function shareRatioOf(uint256 tokenId) external view returns (uint256); function expireAtOf(uint256 tokenId) external view returns (uint64); function ownerOf(uint256 tokenId) external view returns (address); // Revenue accounting function pendingRevenue(uint256 tokenId, address asset) external view returns (uint256); ``` ### 6. State-Transition Functions (Required) #### 6.1 Class management ```solidity function createClass( string calldata metadataURI, bytes32 integrityHash, uint8 unitDecimals, string calldata policyURI ) external returns (uint256 classId); function updateClassMetadata(uint256 classId, string calldata metadataURI, bytes32 integrityHash) external; function updateClassPolicy(uint256 classId, string calldata policyURI) external; ``` - MUST emit `ClassCreated` / `MetadataUpdated` / `ClassPolicyUpdated`. - `integrityHash` SHOULD commit to the metadata payload (cf. [EIP-2477](./eip-2477.md)-like behavior). - Implementations MAY restrict creation/updates to an admin/DAO. #### 6.2 Minting & ownership ```solidity function mint( uint256 classId, address to, uint256 value, uint256 shareRatio, uint64 expireAt ) external returns (uint256 tokenId); function transferToken(uint256 tokenId, address to) external; ``` - MUST emit `Minted` and `TransferToken` when applicable. - If `shareRatio > 0`, the token participates in `totalShare` until expiry. #### 6.3 Approvals (Class-level) ```solidity function approveForClass(uint256 classId, address operator, bool approved) external; function isApprovedForClass(address owner, uint256 classId, address operator) external view returns (bool); ``` - Approved **Class operators** MAY act for the owner in **usage** and **value** ops within that Class. #### 6.4 Semi-fungible value transfer ```solidity function transferValue(uint256 fromTokenId, uint256 toTokenId, uint256 value) external; ``` Preconditions: - `classOf(fromTokenId) == classOf(toTokenId)` - Caller is `ownerOf(fromTokenId)` or an approved Class operator - `value > 0` and `valueOf(fromTokenId) >= value` - Both tokens non-expired (`expireAt == 0 || now <= expireAt`) Effects: - Decrement `value(fromTokenId)`, increment `value(toTokenId)`, emit `ValueTransferred`. #### 6.5 Usage metering ```solidity function recordUsage(uint256 tokenId, bytes32 metricType, uint256 amount) external; ``` Preconditions: - Caller is `ownerOf(tokenId)` or an approved Class operator - Token non-expired Effects: - Emit `UsageRecorded(tokenId, metricType, amount, msg.sender)` - **Hard-quota (RECOMMENDED):** if `amount > 0`, decrement `value(tokenId)`; revert on underflow - **Soft-quota (OPTIONAL profile):** no on-chain decrement; rely on events for off-chain reconciliation #### 6.6 Expiry A token with `expireAt != 0 && now > expireAt` is **expired** for usage/value ops. On first observation: - Set `countedInShare = false` and reduce Class `totalShare` by `shareRatio` - Emit `Expired(tokenId)` Expiry does **not** burn the token nor transfer ownership. #### 6.7 Settlement & claims ```solidity function settleRevenueETH(uint256 classId) external payable; function settleRevenueERC20(uint256 classId, address asset, uint256 amount) external; function claim(uint256 tokenId, address asset, address payable to) external returns (uint256 amountClaimed); ``` Semantics: - `settleRevenue*` increases `accRevenuePerShare[asset]` iff `totalShare > 0`; `asset = address(0)` for ETH - `pending = shareRatio(tokenId) * accRevenuePerShare[asset] / 1e18 - rewardDebt[tokenId][asset]` - `claim` transfers `pending` to `to`, updates `rewardDebt`, emits `Claimed` Pull-based claims reduce reentrancy risk and allow flexible custody. Batch claimers MAY exist off-spec. ### 7. Infrastructure Context (Informative) DAT is chain-level and infra-agnostic, but practical deployments include: - **iDAOs / Domain DAOs** — curate assets and gate `createClass/mint` - **Validation Quorums** — attest integrity/licensing; their attestations are referenced via `integrityHash`/`policyURI` or a proof registry - **Agent Runtimes** — approved Operators that execute AI workloads and call `recordUsage` - **Settlement Gateways** — route paid service fees into `settleRevenue*` for deterministic on-chain distribution ### 8. Profiles & Interoperability (Optional) - **[ERC-3525](./eip-3525.md) profile:** map `classId → slot`; DAT `value` ↔ 3525 `value`; reuse receiver/events where applicable - **[ERC-2981](./eip-2981.md) views:** discovery-only royalties; DAT settlement remains enforceable stream/claim - **[ERC-4907](./eip-4907.md)/[ERC-5006](./eip-5006.md):** reuse rental/user roles; DAT expiry is orthogonal - **[ERC-2477](./eip-2477.md)/[ERC-4906](./eip-4906.md):** integrity commitments and metadata update events - **[ERC-20](./eip-20.md) settlement adapter:** allowance-based transfers into `settleRevenueERC20` ### 9. Proof Registry (Optional Extension) ```solidity event ProofAdded(uint256 indexed tokenId, bytes32 proofType, string uri, bytes signature); function addProof( uint256 tokenId, bytes32 proofType, string calldata uri, bytes calldata signature ) external; ``` - `proofType` labels (e.g., `TEE_REPORT`, `ZK_ATTEST`) - `uri` SHOULD reference proof blob; `signature` SHOULD bind submitter authorization - Access MAY be restricted to owner/approved operator/DAO controller ### 10. Usage Policy (Optional, Class-level) A JSON at `policyURI` MAY define units & throttling, authorized operators, compliance constraints, and settlement assets/splits. The policy SHOULD be versioned and bound by `integrityHash` or metadata commitment. ### 11. Error Handling (Required) MUST revert on: - Value underflow / class mismatch in `transferValue` - Expired token usage - Unauthorized calls (neither owner nor approved Class operator) - Settlement when `totalShare == 0` SHOULD use descriptive revert strings. ### 12. Gas & Indexing Guidance (Informative) Prefer event-first design: indexers reconstruct usage totals from `UsageRecorded`. Keep `metricType` as `bytes32`. Consider batch settlement/claims for high-throughput Classes. ### 13. Non-Goals DAT does **not** standardize off-chain inference execution, cryptographic proof formats, or DAO governance mechanics. ### 14. End-to-End Workflows (Informative) **Dataset example** 1. iDAO validates dataset; quorum attests → `integrityHash` 2. `createClass(metadataURI, integrityHash, unitDecimals, policyURI)` 3. `mint(classId, user, value=1_000, shareRatio=500, expireAt=0)` 4. Operator calls `recordUsage(tokenId, "inference_calls", 50)` (hard-quota decrements `value`) 5. Fees routed via `settleRevenueETH/ERC20` 6. Holder `claim(tokenId, asset, to)` **Model/Agent example** 1. Publish model Class with operator allow-list in policy 2. Mint access tokens with `expireAt` (subscription) or limited `value` (quota) 3. Agent runtime (approved) records usage 4. Periodic settlement → holder claims ### 15. Minimal Interface (Consolidated) ```solidity interface IDATCore { // events event ClassCreated(uint256 indexed classId, string metadataURI, bytes32 integrityHash); event ClassPolicyUpdated(uint256 indexed classId, string policyURI); event MetadataUpdated(uint256 indexed classId, string metadataURI, bytes32 integrityHash); event Minted(uint256 indexed tokenId, uint256 indexed classId, address to, uint256 value, uint256 shareRatio, uint64 expireAt); event TransferToken(uint256 indexed tokenId, address indexed from, address indexed to); event ValueTransferred(uint256 indexed fromTokenId, uint256 indexed toTokenId, uint256 value); event Expired(uint256 indexed tokenId); event UsageRecorded(uint256 indexed tokenId, bytes32 metricType, uint256 amount, address actor); event RevenueSettled(uint256 indexed classId, address indexed asset, uint256 amount); event Claimed(uint256 indexed tokenId, address indexed to, address indexed asset, uint256 amount); event ApprovalForClass(address indexed owner, uint256 indexed classId, address indexed operator, bool approved); // views function getClassMeta(uint256 classId) external view returns (string memory, bytes32, uint8, string memory); function classOf(uint256 tokenId) external view returns (uint256); function valueOf(uint256 tokenId) external view returns (uint256); function shareRatioOf(uint256 tokenId) external view returns (uint256); function expireAtOf(uint256 tokenId) external view returns (uint64); function ownerOf(uint256 tokenId) external view returns (address); function pendingRevenue(uint256 tokenId, address asset) external view returns (uint256); // class mgmt function createClass(string calldata, bytes32, uint8, string calldata) external returns (uint256); function updateClassMetadata(uint256 classId, string calldata, bytes32) external; function updateClassPolicy(uint256 classId, string calldata) external; // mint & transfer function mint(uint256, address, uint256, uint256, uint64) external returns (uint256); function transferToken(uint256, address) external; // approvals function approveForClass(uint256, address, bool) external; function isApprovedForClass(address, uint256, address) external view returns (bool); // value & usage function transferValue(uint256, uint256, uint256) external; function recordUsage(uint256, bytes32, uint256) external; // settlement function settleRevenueETH(uint256 classId) external payable; function settleRevenueERC20(uint256 classId, address asset, uint256 amount) external; function claim(uint256 tokenId, address asset, address payable to) external returns (uint256); } ``` ## Rationale - **Semi-fungibility.** DAT adopts `id + value` with intra-Class transfers to model quotas; mapping to [ERC-3525](./eip-3525.md) (`classId → slot`) maximizes wallet/indexer compatibility. - **Usage metering.** A minimal `recordUsage` standardizes audit trails for calls/tokens/steps without heavy storage. - **Settlement.** Pull-based, per-Class settlement provides deterministic on-chain revenue distribution; [ERC-2981](./eip-2981.md) views can be exposed for marketplace discovery. - **Extensibility.** Roles/expiry can reuse [ERC-4907](./eip-4907.md)/[ERC-5006](./eip-5006.md); provenance via integrity commitments and optional proof registry. ## Backwards Compatibility DAT MAY be implemented as a profile over [ERC-3525](./eip-3525.md) while adding usage and settlement surfaces. It also composes with [ERC-2981](./eip-2981.md) (royalty views), [ERC-4907](./eip-4907.md)/[ERC-5006](./eip-5006.md) (rental roles), and [EIP-2477](./eip-2477.md)/[ERC-4906](./eip-4906.md) (metadata integrity/updates). ## Reference Implementation A reference implementation is available in the [assets/eip-8028](../assets/eip-8028) directory. The implementation includes: - Core DAT contract with all required interfaces - Example usage scenarios for datasets, models, and agents ## Security Considerations - **Operator abuse.** Restrict `recordUsage` to approved Class operators; rate-limit and log via events. - **Revenue manipulation.** Settlement index arithmetic MUST guard against overflows; claims are pull-based; [ERC-20](./eip-20.md) transfers MUST check return values. - **Expiry enforcement.** All usage/value ops MUST validate expiry. - **Proof spoofing.** If Proof Registry is used, bind submitter authorization and commitments; crypto verification remains application-level. - **Reentrancy.** Use checks-effects-interactions or reentrancy guards in `claim`. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).