From fdbf43fcd196b4b52039f9ab1c48df8a5f91e223 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 15 Oct 2025 14:42:46 +0100 Subject: [PATCH 1/9] init draft for governance metadata extension --- cip-governance-metadata-extension/README.md | 358 ++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 cip-governance-metadata-extension/README.md diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md new file mode 100644 index 0000000000..9626e92fdb --- /dev/null +++ b/cip-governance-metadata-extension/README.md @@ -0,0 +1,358 @@ +--- +CIP: ? +Title: Governance Metadata - On-Chain Effects +Category: Metadata +Status: Proposed +Authors: + - Ryan Williams +Implementors: + - Ryan Williams +Discussions: + - https://github.com/cardano-foundation/CIPs/pulls/? +Created: 2025-01-14 +License: CC-BY-4.0 +--- + +## Abstract + +This CIP extends [CIP-100 | Governance Metadata][CIP-100] to introduce a standardized `onChain` property. +The `onChain` property encapsulates the on-chain effects using [CIP-116 | Standard JSON encoding for Domain Types][CIP-116] standard encoding, +enabling verification that metadata content matches on-chain action and preventing metadata replay attacks. +This applies to all types of governance metadata, including governance actions, votes, DRep registrations/updates, and Constitutional Committee resignations. + +## Motivation: why is this CIP necessary? + +Without a standardized mechanism to bind metadata to specific on-chain effects, +there is a security vulnerability: **metadata replay attacks**. + +This vulnerability has been discussed via [CIPs Issue #970](https://github.com/cardano-foundation/CIPs/issues/970) by [Adam Dean](https://github.com/Crypto2099). + +### Attack Scenario + +A malicious actor could; + +1. Copy the metadata from a legitimate treasury withdrawal governance action +2. Modify only the destination address in the on-chain action +3. Submit this as a new governance action with the copied metadata + +From a voter's perspective, examining the metadata would show legitimate content (proper title, abstract, rationale, references, and author signatures). +However, the actual on-chain effect would send funds to a different address than described in the metadata. + +In high-volume voting environments such attacks could succeed if voters don't manually verify that the metadata matches the on-chain effects. + +### Other Author attacks + +- discuss attacks where multiple authors are collaborating before constructing on-chain part +- having an onChain property prevents someone from attaching the signed metadata to the wrong thing + +### Solution + +By including the on-chain effects within the signed metadata body using the `onChain` property. + +Metadata is bound to specific on-chain effects, +with author signature cryptographically locking it in. +This makes any metadata replay attacks, +where on-chain effects are edited automatically detectable. + +## Specification + +### The `onChain` Property + +The `onChain` property is a new **optional** property within the `body` object of [CIP-100][] governance metadata. + +#### JSON-LD Context + +The `onChain` property shall be defined in the JSON-LD `@context` as follows: + +```json +{ + "@context": { + "CIP116": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0116/README.md#", + "body": { + "@id": "CIP100:body", + "@context": { + "onChain": { + "@id": "CIPXXX:onChain" + } + } + } + } +} +``` + +> Note: `CIPXXX` represents this CIP's number once assigned. + +#### Structure + +The `onChain` property **MUST** conform to one of the [CIP-116][] Conway-era governance types. +The specific type is indicated by the `@type` field within the `onChain` object. + +> ⚠️ Note: any entry of anchor properties within the CIP116 objects must be removed as they constitute a circular dependency + +##### Supported Types + +**For Governance Actions:** + +The `onChain` property conforms to the [CIP-116][] `ProposalProcedure` type: + +```typescript +type OnChain = { + "@type": "ProposalProcedure"; + deposit: number; // Lovelace + returnAddr: Address; // CIP-116 Address type + govAction: GovAction; // CIP-116 GovAction type +} +``` + +Where `GovAction` is one of the [CIP-116][] Conway-era governance action types: + +- `InfoAction` +- `ParameterChange` +- `HardForkInitiation` +- `TreasuryWithdrawals` +- `NoConfidence` +- `UpdateCommittee` +- `NewConstitution` + +See [CIP-116 cardano-conway.json](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0116/cardano-conway.json) for complete type definitions. + +**For Votes:** + +The `onChain` property conforms to the [CIP-116][] `VotingProcedure` type: + +```typescript +type OnChain = { + "@type": "VotingProcedure"; + govActionId: { + txId: string; // Transaction ID (hex) + govActionIx: number; // Governance action index + }; + voter: Voter; // CIP-116 Voter type (DRep, SPO, or CC) + vote: Vote; // "yes" | "no" | "abstain" +} +``` + +**For DRep Registration:** + +The `onChain` property conforms to the [CIP-116][] DRep registration certificate structure: + +```typescript +type OnChain = { + "@type": "RegDRepCert"; + drepCredential: Credential; // CIP-116 Credential type + deposit: number; // Lovelace +} +``` + +**For DRep Update:** + +The `onChain` property conforms to the [CIP-116][] DRep update certificate structure: + +```typescript +type OnChain = { + "@type": "UpdateDRepCert"; + drepCredential: Credential; // CIP-116 Credential type +} +``` + +**For Committee Cold Credential Resignation:** + +The `onChain` property conforms to the [CIP-116][] committee resignation certificate structure: + +```typescript +type OnChain = { + "@type": "ResignCommitteeColdCert"; + committeeColdCredential: Credential; // CIP-116 Credential type +} +``` + +### Examples + +#### Treasury Withdrawal + +```json +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Fund Development Team", + "abstract": "Withdraw ₳100,000 to fund smart contract development team.", + "motivation": "The team has delivered milestones and requires funding for continued work.", + "rationale": "Funding will enable completion of the remaining project deliverables.", + "onChain": { + "@type": "ProposalProcedure", + "deposit": 100000000000, + "returnAddr": { + "network": "mainnet", + "paymentCred": null, + "stakeCred": { + "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" + } + }, + "govAction": { + "@type": "TreasuryWithdrawals", + "withdrawals": { + "stake1u8xj29v6qhja7zl0yk5u9q8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3h2g1f0e9d": 100000000000 + } + } + } + }, + "authors": [] +} +``` + +#### Protocol Parameter Change + +```json +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Increase Block Size to 96KB", + "abstract": "Update maxBlockBodySize parameter from 90112 to 98304 bytes.", + "motivation": "Current block size limits are constraining transaction throughput.", + "rationale": "Analysis shows network can safely handle larger blocks, improving user experience.", + "onChain": { + "@type": "ProposalProcedure", + "deposit": 100000000000, + "returnAddr": { + "network": "mainnet", + "paymentCred": null, + "stakeCred": { + "keyHash": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3" + } + }, + "govAction": { + "@type": "ParameterChange", + "protocolParamUpdate": { + "maxBlockBodySize": 98304 + }, + "policyHash": null, + "prevGovActionId": null + } + } + }, + "authors": [] +} +``` + +#### Vote on Governance Action + +```json +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Vote YES on Budget Proposal", + "abstract": "This metadata explains why I am voting YES on the 2025 budget proposal.", + "motivation": "The proposed budget aligns with community priorities and includes proper accountability measures.", + "rationale": "After reviewing the proposal details, the budget allocation is reasonable and the oversight mechanisms are sufficient.", + "onChain": { + "@type": "VotingProcedure", + "govActionId": { + "txId": "e14de8d9dc4f4ddf3fe9250a8a926e20f10e99b86bd0610b77d7a054981591ee", + "govActionIx": 0 + }, + "voter": { + "@type": "DRep", + "credential": { + "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" + } + }, + "vote": "yes", + } + }, + "authors": [] +} +``` + +#### DRep Registration + +```json +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "DRep Registration - Alice's Delegation Pool", + "abstract": "Registering as a DRep to represent community interests in governance.", + "motivation": "I want to actively participate in Cardano governance and represent the interests of delegators who trust my judgment.", + "rationale": "With 5 years of experience in the Cardano ecosystem and active participation in governance discussions, I am well-positioned to make informed voting decisions.", + "onChain": { + "@type": "RegDRepCert", + "drepCredential": { + "keyHash": "d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2" + }, + "deposit": 2000000, + } + }, + "authors": [] +} +``` + +### Verification Process + +Tools **SHOULD** implement the following verification when processing governance actions: + +1. **Parse On-Chain Data**: Extract the actual governance action from the blockchain +2. **Parse Metadata**: Retrieve and parse the governance action metadata +3. **Compare**: Verify that `body.onChain` matches the actual on-chain governance action +4. **Alert**: If mismatch detected, prominently warn users + +### Author Signatures + +When combined with [CIP-108][] author signatures, the `onChain` property is included in the signed `body` content. This means: + +1. Author signature covers the described on-chain effects +2. Any modification to `onChain` invalidates the signature +3. Metadata replay with different on-chain effects is detectable + +## Rationale + +### Why Extend CIP-100? + +[CIP-100][] provides the base structure for governance metadata. +This extension adds security-critical information while maintaining backward compatibility. + +### Why Use CIP-116 Encoding? + +[CIP-116][] provides standardized JSON encoding for Cardano domain types. + +### Why Optional? + +The `onChain` property is optional to maintain backward compatibility. + +This CIP is fully backward compatible: + +- **Existing Metadata**: Governance actions without `onChain` remain valid +- **Parsers**: Parsers ignoring `onChain` continue to work +- **Validators**: Validators not checking `onChain` continue to work + +However, **security-conscious voters and tools** should prefer governance actions that include `onChain` and show verification status. + +## Open Questions + +- How to handle `anchor` property inside of CIP116 objects in a nice way? + +## Path to Active + +### Acceptance Criteria + +This CIP is considered **Active** when: + +1. The specification is merged into the CIPs repository +2. At least two governance metadata authoring tools implement support +3. At least one verification tool implements on-chain comparison +4. Documentation and examples are available + +### Implementation Plan + +- todo + +## Copyright + +This CIP is licensed under [CC-BY-4.0][]. + +[CIP-100]: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md +[CIP-108]: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md +[CIP-116]: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0116/README.md +[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode From b2838338266e7061ccfce5c38068d6e5106a3000 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 15 Oct 2025 14:48:41 +0100 Subject: [PATCH 2/9] add reference to other issue --- cip-governance-metadata-extension/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index 9626e92fdb..168eab3fda 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -25,7 +25,7 @@ This applies to all types of governance metadata, including governance actions, Without a standardized mechanism to bind metadata to specific on-chain effects, there is a security vulnerability: **metadata replay attacks**. -This vulnerability has been discussed via [CIPs Issue #970](https://github.com/cardano-foundation/CIPs/issues/970) by [Adam Dean](https://github.com/Crypto2099). +This vulnerability has been discussed via [CIPs Issue #970](https://github.com/cardano-foundation/CIPs/issues/970) by [Adam Dean](https://github.com/Crypto2099) and further within [CIPs Issue #978](http://github.com/cardano-foundation/CIPs/issues/978). ### Attack Scenario From 71cb9fafff33adc29c4ab7db9ffedaa1cb75536b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 17 Oct 2025 15:41:39 +0100 Subject: [PATCH 3/9] clean up proposal, ready for pull request --- cip-governance-metadata-extension/README.md | 172 +++--------------- .../examples/parameter-change.jsonld | 30 +++ .../examples/treasury-withdrawal.jsonld | 28 +++ .../examples/vote.jsonld | 25 +++ 4 files changed, 104 insertions(+), 151 deletions(-) create mode 100644 cip-governance-metadata-extension/examples/parameter-change.jsonld create mode 100644 cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld create mode 100644 cip-governance-metadata-extension/examples/vote.jsonld diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index 168eab3fda..18e6be726d 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -9,7 +9,7 @@ Implementors: - Ryan Williams Discussions: - https://github.com/cardano-foundation/CIPs/pulls/? -Created: 2025-01-14 +Created: 2025-10-15 License: CC-BY-4.0 --- @@ -18,16 +18,16 @@ License: CC-BY-4.0 This CIP extends [CIP-100 | Governance Metadata][CIP-100] to introduce a standardized `onChain` property. The `onChain` property encapsulates the on-chain effects using [CIP-116 | Standard JSON encoding for Domain Types][CIP-116] standard encoding, enabling verification that metadata content matches on-chain action and preventing metadata replay attacks. -This applies to all types of governance metadata, including governance actions, votes, DRep registrations/updates, and Constitutional Committee resignations. +This can be applied to all types of governance metadata, including governance actions, votes, DRep registrations/updates, and Constitutional Committee resignations. ## Motivation: why is this CIP necessary? Without a standardized mechanism to bind metadata to specific on-chain effects, -there is a security vulnerability: **metadata replay attacks**. +there is a security vulnerability in **metadata replay attacks**. -This vulnerability has been discussed via [CIPs Issue #970](https://github.com/cardano-foundation/CIPs/issues/970) by [Adam Dean](https://github.com/Crypto2099) and further within [CIPs Issue #978](http://github.com/cardano-foundation/CIPs/issues/978). +This vulnerability has been discussed via [CIPs Issue #970](https://github.com/cardano-foundation/CIPs/issues/970) by [Crypto2099](https://github.com/Crypto2099) and further within [CIPs Issue #978](http://github.com/cardano-foundation/CIPs/issues/978) by [gitmachtl](https://github.com/gitmachtl). -### Attack Scenario +### Metadata Replay A malicious actor could; @@ -36,24 +36,16 @@ A malicious actor could; 3. Submit this as a new governance action with the copied metadata From a voter's perspective, examining the metadata would show legitimate content (proper title, abstract, rationale, references, and author signatures). -However, the actual on-chain effect would send funds to a different address than described in the metadata. +However, the actual on-chain effect would send funds to a different, malicious address. In high-volume voting environments such attacks could succeed if voters don't manually verify that the metadata matches the on-chain effects. +Relying on manual verification by voters is error prone and inefficient. ### Other Author attacks - discuss attacks where multiple authors are collaborating before constructing on-chain part - having an onChain property prevents someone from attaching the signed metadata to the wrong thing -### Solution - -By including the on-chain effects within the signed metadata body using the `onChain` property. - -Metadata is bound to specific on-chain effects, -with author signature cryptographically locking it in. -This makes any metadata replay attacks, -where on-chain effects are edited automatically detectable. - ## Specification ### The `onChain` Property @@ -140,7 +132,7 @@ The `onChain` property conforms to the [CIP-116][] DRep registration certificate type OnChain = { "@type": "RegDRepCert"; drepCredential: Credential; // CIP-116 Credential type - deposit: number; // Lovelace + deposit: number; // Lovelace amount } ``` @@ -166,148 +158,28 @@ type OnChain = { } ``` -### Examples - -#### Treasury Withdrawal - -```json -{ - "@context": "...", - "hashAlgorithm": "blake2b-256", - "body": { - "title": "Fund Development Team", - "abstract": "Withdraw ₳100,000 to fund smart contract development team.", - "motivation": "The team has delivered milestones and requires funding for continued work.", - "rationale": "Funding will enable completion of the remaining project deliverables.", - "onChain": { - "@type": "ProposalProcedure", - "deposit": 100000000000, - "returnAddr": { - "network": "mainnet", - "paymentCred": null, - "stakeCred": { - "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" - } - }, - "govAction": { - "@type": "TreasuryWithdrawals", - "withdrawals": { - "stake1u8xj29v6qhja7zl0yk5u9q8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3h2g1f0e9d": 100000000000 - } - } - } - }, - "authors": [] -} -``` - -#### Protocol Parameter Change - -```json -{ - "@context": "...", - "hashAlgorithm": "blake2b-256", - "body": { - "title": "Increase Block Size to 96KB", - "abstract": "Update maxBlockBodySize parameter from 90112 to 98304 bytes.", - "motivation": "Current block size limits are constraining transaction throughput.", - "rationale": "Analysis shows network can safely handle larger blocks, improving user experience.", - "onChain": { - "@type": "ProposalProcedure", - "deposit": 100000000000, - "returnAddr": { - "network": "mainnet", - "paymentCred": null, - "stakeCred": { - "keyHash": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3" - } - }, - "govAction": { - "@type": "ParameterChange", - "protocolParamUpdate": { - "maxBlockBodySize": 98304 - }, - "policyHash": null, - "prevGovActionId": null - } - } - }, - "authors": [] -} -``` - -#### Vote on Governance Action - -```json -{ - "@context": "...", - "hashAlgorithm": "blake2b-256", - "body": { - "title": "Vote YES on Budget Proposal", - "abstract": "This metadata explains why I am voting YES on the 2025 budget proposal.", - "motivation": "The proposed budget aligns with community priorities and includes proper accountability measures.", - "rationale": "After reviewing the proposal details, the budget allocation is reasonable and the oversight mechanisms are sufficient.", - "onChain": { - "@type": "VotingProcedure", - "govActionId": { - "txId": "e14de8d9dc4f4ddf3fe9250a8a926e20f10e99b86bd0610b77d7a054981591ee", - "govActionIx": 0 - }, - "voter": { - "@type": "DRep", - "credential": { - "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" - } - }, - "vote": "yes", - } - }, - "authors": [] -} -``` - -#### DRep Registration - -```json -{ - "@context": "...", - "hashAlgorithm": "blake2b-256", - "body": { - "title": "DRep Registration - Alice's Delegation Pool", - "abstract": "Registering as a DRep to represent community interests in governance.", - "motivation": "I want to actively participate in Cardano governance and represent the interests of delegators who trust my judgment.", - "rationale": "With 5 years of experience in the Cardano ecosystem and active participation in governance discussions, I am well-positioned to make informed voting decisions.", - "onChain": { - "@type": "RegDRepCert", - "drepCredential": { - "keyHash": "d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2" - }, - "deposit": 2000000, - } - }, - "authors": [] -} -``` - ### Verification Process Tools **SHOULD** implement the following verification when processing governance actions: -1. **Parse On-Chain Data**: Extract the actual governance action from the blockchain -2. **Parse Metadata**: Retrieve and parse the governance action metadata -3. **Compare**: Verify that `body.onChain` matches the actual on-chain governance action -4. **Alert**: If mismatch detected, prominently warn users - -### Author Signatures +1. **Parse On-Chain Data**: Extract the on-chain data which the metadata is attached to +2. **Parse Metadata**: Retrieve and parse the governance metadata +3. **Author Signature Check**: Validate the author signatures are all correct +4. **Compare**: Verify that `body.onChain` matches the actual on-chain effect +5. **Alert**: If there are invalid author signatures and/or the `onChain` does not match, warn the user -When combined with [CIP-108][] author signatures, the `onChain` property is included in the signed `body` content. This means: +### Examples -1. Author signature covers the described on-chain effects -2. Any modification to `onChain` invalidates the signature -3. Metadata replay with different on-chain effects is detectable +Please see [examples/](./examples/). ## Rationale +By including the on-chain effects within the signed metadata body using the `onChain` property. +Metadata is bound to specific on-chain effects, +with author signature cryptographically locking it in. +This makes any metadata replay attacks, machine detectable. +This allows governance tools to automatically verify this for voters. + ### Why Extend CIP-100? [CIP-100][] provides the base structure for governance metadata. @@ -327,8 +199,6 @@ This CIP is fully backward compatible: - **Parsers**: Parsers ignoring `onChain` continue to work - **Validators**: Validators not checking `onChain` continue to work -However, **security-conscious voters and tools** should prefer governance actions that include `onChain` and show verification status. - ## Open Questions - How to handle `anchor` property inside of CIP116 objects in a nice way? diff --git a/cip-governance-metadata-extension/examples/parameter-change.jsonld b/cip-governance-metadata-extension/examples/parameter-change.jsonld new file mode 100644 index 0000000000..d65c4b73d8 --- /dev/null +++ b/cip-governance-metadata-extension/examples/parameter-change.jsonld @@ -0,0 +1,30 @@ +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Increase Block Size to 96KB", + "abstract": "Update maxBlockBodySize parameter from 90112 to 98304 bytes.", + "motivation": "Current block size limits are constraining transaction throughput.", + "rationale": "Analysis shows network can safely handle larger blocks, improving user experience.", + "onChain": { + "@type": "ProposalProcedure", + "deposit": 100000000000, + "returnAddr": { + "network": "mainnet", + "paymentCred": null, + "stakeCred": { + "keyHash": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3" + } + }, + "govAction": { + "@type": "ParameterChange", + "protocolParamUpdate": { + "maxBlockBodySize": 98304 + }, + "policyHash": null, + "prevGovActionId": null + } + } + }, + "authors": [] +} \ No newline at end of file diff --git a/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld b/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld new file mode 100644 index 0000000000..2949fec2e0 --- /dev/null +++ b/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld @@ -0,0 +1,28 @@ +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Fund Development Team", + "abstract": "Withdraw ₳100,000 to fund smart contract development team.", + "motivation": "The team has delivered milestones and requires funding for continued work.", + "rationale": "Funding will enable completion of the remaining project deliverables.", + "onChain": { + "@type": "ProposalProcedure", + "deposit": 100000000000, + "returnAddr": { + "network": "mainnet", + "paymentCred": null, + "stakeCred": { + "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" + } + }, + "govAction": { + "@type": "TreasuryWithdrawals", + "withdrawals": { + "stake1u8xj29v6qhja7zl0yk5u9q8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3h2g1f0e9d": 100000000000 + } + } + } + }, + "authors": [] +} \ No newline at end of file diff --git a/cip-governance-metadata-extension/examples/vote.jsonld b/cip-governance-metadata-extension/examples/vote.jsonld new file mode 100644 index 0000000000..fef247a2c5 --- /dev/null +++ b/cip-governance-metadata-extension/examples/vote.jsonld @@ -0,0 +1,25 @@ +{ + "@context": "...", + "hashAlgorithm": "blake2b-256", + "body": { + "title": "Vote YES on Budget Proposal", + "abstract": "This metadata explains why I am voting YES on the 2025 budget proposal.", + "motivation": "The proposed budget aligns with community priorities and includes proper accountability measures.", + "rationale": "After reviewing the proposal details, the budget allocation is reasonable and the oversight mechanisms are sufficient.", + "onChain": { + "@type": "VotingProcedure", + "govActionId": { + "txId": "e14de8d9dc4f4ddf3fe9250a8a926e20f10e99b86bd0610b77d7a054981591ee", + "govActionIx": 0 + }, + "voter": { + "@type": "DRep", + "credential": { + "keyHash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" + } + }, + "vote": "yes" + } + }, + "authors": [] +} \ No newline at end of file From 8d6d99e79fe42bf03dc4bde47398ff16731454af Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 17 Oct 2025 15:45:52 +0100 Subject: [PATCH 4/9] fix example --- .../examples/treasury-withdrawal.jsonld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld b/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld index 2949fec2e0..0433a59371 100644 --- a/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld +++ b/cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld @@ -19,7 +19,7 @@ "govAction": { "@type": "TreasuryWithdrawals", "withdrawals": { - "stake1u8xj29v6qhja7zl0yk5u9q8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3h2g1f0e9d": 100000000000 + "stake1uxsm9s75uhm20wxf6rsl9ga5chtw079fkrqa9cl55kmv0kqfk32j7": 100000000000 } } } From 5dab320e4c9b08b3214fb7bb24c5f6ae050032e2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 17 Oct 2025 16:08:01 +0100 Subject: [PATCH 5/9] add dicussion link to header --- cip-governance-metadata-extension/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index 18e6be726d..d589df84c0 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -8,7 +8,7 @@ Authors: Implementors: - Ryan Williams Discussions: - - https://github.com/cardano-foundation/CIPs/pulls/? + - https://github.com/cardano-foundation/CIPs/pull/1101 Created: 2025-10-15 License: CC-BY-4.0 --- From cd0697cfcf250fb3420e8edda3880878c88bccff Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Oct 2025 09:22:24 +0100 Subject: [PATCH 6/9] Update cip-governance-metadata-extension/README.md Co-authored-by: Robert Phair --- cip-governance-metadata-extension/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index d589df84c0..9ef1ff8c6f 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -72,7 +72,8 @@ The `onChain` property shall be defined in the JSON-LD `@context` as follows: } ``` -> Note: `CIPXXX` represents this CIP's number once assigned. +> [!NOTE] +> `CIPXXX` represents this CIP's number once assigned. #### Structure From b119207ca6e6090bfcf6d778cdaf38ae2891112f Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Oct 2025 09:22:54 +0100 Subject: [PATCH 7/9] Update cip-governance-metadata-extension/README.md Co-authored-by: Robert Phair --- cip-governance-metadata-extension/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index 9ef1ff8c6f..ff7fa1a3ea 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -80,7 +80,8 @@ The `onChain` property shall be defined in the JSON-LD `@context` as follows: The `onChain` property **MUST** conform to one of the [CIP-116][] Conway-era governance types. The specific type is indicated by the `@type` field within the `onChain` object. -> ⚠️ Note: any entry of anchor properties within the CIP116 objects must be removed as they constitute a circular dependency +> [!WARNING] +> Any entry of anchor properties within the CIP116 objects must be removed as they constitute a circular dependency ##### Supported Types From 981340ad69fc925755285efcc1970110a2ee3c8a Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 24 Nov 2025 15:48:50 +0000 Subject: [PATCH 8/9] add common and update number --- cip-governance-metadata-extension/README.md | 6 ++-- .../cip169.common.jsonld | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 cip-governance-metadata-extension/cip169.common.jsonld diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index ff7fa1a3ea..e7c6707c80 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -1,5 +1,5 @@ --- -CIP: ? +CIP: 169 Title: Governance Metadata - On-Chain Effects Category: Metadata Status: Proposed @@ -64,7 +64,7 @@ The `onChain` property shall be defined in the JSON-LD `@context` as follows: "@id": "CIP100:body", "@context": { "onChain": { - "@id": "CIPXXX:onChain" + "@id": "CIP169:onChain" } } } @@ -73,7 +73,7 @@ The `onChain` property shall be defined in the JSON-LD `@context` as follows: ``` > [!NOTE] -> `CIPXXX` represents this CIP's number once assigned. +> This CIP uses `CIP169` as the namespace identifier. #### Structure diff --git a/cip-governance-metadata-extension/cip169.common.jsonld b/cip-governance-metadata-extension/cip169.common.jsonld new file mode 100644 index 0000000000..21d2c35043 --- /dev/null +++ b/cip-governance-metadata-extension/cip169.common.jsonld @@ -0,0 +1,33 @@ +{ + "@context": { + "CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + "CIP116": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0116/README.md#", + "CIP169": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0169/README.md#", + "hashAlgorithm": "CIP100:hashAlgorithm", + "body": { + "@id": "CIP100:body", + "@context": { + "onChain": { + "@id": "CIP169:onChain" + } + } + }, + "authors": { + "@id": "CIP100:authors", + "@container": "@set", + "@context": { + "did": "@id", + "name": "http://xmlns.com/foaf/0.1/name", + "witness": { + "@id": "CIP100:witness", + "@context": { + "witnessAlgorithm": "CIP100:witnessAlgorithm", + "publicKey": "CIP100:publicKey", + "signature": "CIP100:signature" + } + } + } + } + } +} + From 1aff5dc263815f901d6ecb28aaf5b88ec80c03b5 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 2 Dec 2025 12:17:49 +0000 Subject: [PATCH 9/9] remove confusing typescript definitions --- cip-governance-metadata-extension/README.md | 72 +++++++-------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/cip-governance-metadata-extension/README.md b/cip-governance-metadata-extension/README.md index e7c6707c80..c91ba211ad 100644 --- a/cip-governance-metadata-extension/README.md +++ b/cip-governance-metadata-extension/README.md @@ -81,22 +81,19 @@ The `onChain` property **MUST** conform to one of the [CIP-116][] Conway-era gov The specific type is indicated by the `@type` field within the `onChain` object. > [!WARNING] -> Any entry of anchor properties within the CIP116 objects must be removed as they constitute a circular dependency +> The `anchor` property **MUST** be omitted from all CIP-116 objects within the `onChain` property. +> The `anchor` property contains a URL and hash that points to the metadata document itself, creating a circular dependency. +> Since the `anchor` is not part of the actual on-chain effect (it's only a pointer to metadata), it is excluded from the `onChain` encoding. +> This applies to all CIP-116 types that include an `anchor` property, including: +> - `ProposalProcedure.anchor` +> - `VotingProcedure.anchor` (when present) +> - `Constitution.anchor` (when present in `NewConstitution` actions) ##### Supported Types **For Governance Actions:** -The `onChain` property conforms to the [CIP-116][] `ProposalProcedure` type: - -```typescript -type OnChain = { - "@type": "ProposalProcedure"; - deposit: number; // Lovelace - returnAddr: Address; // CIP-116 Address type - govAction: GovAction; // CIP-116 GovAction type -} -``` +The `onChain` property conforms to the [CIP-116][] `ProposalProcedure` type. Where `GovAction` is one of the [CIP-116][] Conway-era governance action types: @@ -112,53 +109,19 @@ See [CIP-116 cardano-conway.json](https://github.com/cardano-foundation/CIPs/blo **For Votes:** -The `onChain` property conforms to the [CIP-116][] `VotingProcedure` type: - -```typescript -type OnChain = { - "@type": "VotingProcedure"; - govActionId: { - txId: string; // Transaction ID (hex) - govActionIx: number; // Governance action index - }; - voter: Voter; // CIP-116 Voter type (DRep, SPO, or CC) - vote: Vote; // "yes" | "no" | "abstain" -} -``` +The `onChain` property conforms to the [CIP-116][] `VotingProcedure` type. **For DRep Registration:** -The `onChain` property conforms to the [CIP-116][] DRep registration certificate structure: - -```typescript -type OnChain = { - "@type": "RegDRepCert"; - drepCredential: Credential; // CIP-116 Credential type - deposit: number; // Lovelace amount -} -``` +The `onChain` property conforms to the [CIP-116][] DRep registration certificate structure. **For DRep Update:** -The `onChain` property conforms to the [CIP-116][] DRep update certificate structure: - -```typescript -type OnChain = { - "@type": "UpdateDRepCert"; - drepCredential: Credential; // CIP-116 Credential type -} -``` +The `onChain` property conforms to the [CIP-116][] DRep update certificate structure. **For Committee Cold Credential Resignation:** -The `onChain` property conforms to the [CIP-116][] committee resignation certificate structure: - -```typescript -type OnChain = { - "@type": "ResignCommitteeColdCert"; - committeeColdCredential: Credential; // CIP-116 Credential type -} -``` +The `onChain` property conforms to the [CIP-116][] committee resignation certificate structure. ### Verification Process @@ -191,6 +154,17 @@ This extension adds security-critical information while maintaining backward com [CIP-116][] provides standardized JSON encoding for Cardano domain types. +### Why Exclude the Anchor Property? + +The `anchor` property in CIP-116 governance types contains a URL and hash that points to the metadata document itself. +Including it in the `onChain` property would create a circular dependency: the metadata would contain an anchor pointing to itself. + +More importantly, the `anchor` is not part of the actual on-chain effect being verified. +The purpose of the `onChain` property is to encode the substantive on-chain effects (deposits, addresses, governance action parameters, etc.) that determine what the action actually does. +The `anchor` is merely a pointer to where metadata can be found, and is not relevant for verifying that the metadata matches the on-chain action. + +Therefore, the `anchor` property is explicitly excluded from the `onChain` encoding, while all other CIP-116 properties that represent actual on-chain effects are included. + ### Why Optional? The `onChain` property is optional to maintain backward compatibility.