-
Notifications
You must be signed in to change notification settings - Fork 371
CIP-0169? | Governance Metadata - On-Chain Effects #1101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ryun1
wants to merge
7
commits into
cardano-foundation:master
Choose a base branch
from
Ryun1:cip-governance-metadata-extension
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
fdbf43f
init draft for governance metadata extension
Ryun1 b283833
add reference to other issue
Ryun1 71cb9fa
clean up proposal, ready for pull request
Ryun1 8d6d99e
fix example
Ryun1 5dab320
add dicussion link to header
Ryun1 cd0697c
Update cip-governance-metadata-extension/README.md
Ryun1 b119207
Update cip-governance-metadata-extension/README.md
Ryun1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| --- | ||
| CIP: ? | ||
| Title: Governance Metadata - On-Chain Effects | ||
| Category: Metadata | ||
| Status: Proposed | ||
| Authors: | ||
| - Ryan Williams <[email protected]> | ||
| Implementors: | ||
| - Ryan Williams <[email protected]> | ||
| Discussions: | ||
| - https://github.com/cardano-foundation/CIPs/pull/1101 | ||
| Created: 2025-10-15 | ||
| 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 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 in **metadata replay attacks**. | ||
|
|
||
| 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). | ||
|
|
||
| ### Metadata Replay | ||
|
|
||
| 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, 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 | ||
|
|
||
| ## 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 | ||
Ryun1 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ##### 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 amount | ||
| } | ||
| ``` | ||
|
|
||
| **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 | ||
| } | ||
| ``` | ||
|
|
||
| ### Verification Process | ||
|
|
||
| Tools **SHOULD** implement the following verification when processing governance actions: | ||
|
|
||
| 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 | ||
|
|
||
| ### Examples | ||
|
|
||
| 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. | ||
| 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 | ||
|
|
||
| ## 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 | ||
30 changes: 30 additions & 0 deletions
30
cip-governance-metadata-extension/examples/parameter-change.jsonld
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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": [] | ||
| } |
28 changes: 28 additions & 0 deletions
28
cip-governance-metadata-extension/examples/treasury-withdrawal.jsonld
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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": { | ||
| "stake1uxsm9s75uhm20wxf6rsl9ga5chtw079fkrqa9cl55kmv0kqfk32j7": 100000000000 | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "authors": [] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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": [] | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.