AnteHandler
Dchain and other apps that use this AnteHandler decorator can specify fine-grained verifiable presentation requirements for individual messages in a transaction. Each required verifiable presentation is verified natively (in Go) before the messages are processed by the app.
For example, a cosmos.staking.v1beta1.MsgCreateValidator message can be gated so that it only passes if the
transaction also carries an SD-JWT presentation whose disclosed validator claim equals the validator address in the
message, derived from a credential issued by one of a set of trusted issuers. That requirement is configured in the
message's Route (see state). The AnteHandler decorator looks up the Route for the
message type, reads the presentation from the transaction's ExtensionOptions, and verifies it against the issuer's
public JWK and requirements - no smart contract is invoked.
AnteHandler verifying ExtensionOptions
The decorator is VcvExtensionOptionsDecorator (x/vcv/ante/ante.go). It is constructed with a list of VPVerifierI
keepers - the vcv keeper and any other module keeper (e.g. the x/notary keeper) that registers gated routes and reuses
the verification.
The decorator's flow on each transaction is:
- If the block height is
0(genesis), verification is skipped entirely. - It extracts the VP
ExtensionOptionsfrom the transaction. A VP extension option is anAnywhose type URL is the module'sExtensionOptionTypeUrl(/d.vcv.v1.VerifiablePresentation). - For every message it counts how many require verification by asking each keeper
IsMsgExtensionOptionsRequired(msg). The vcv keeper requires verification forcosmos.staking.v1beta1.MsgCreateValidatorandcosmos.gov.v1.MsgVote. - It asserts that the number of messages requiring verification equals the number of VP extension options provided; otherwise the transaction is rejected.
- For each message that requires verification it calls
VerifyMsgExtensionOptions(msg, vp)with the next VP extension option in order.
TxBody {
Messages [MsgCreateValidator, MsgSend, MsgVote]
ExtensionOptions[VP1, VP2]
}
In this example MsgSend does not require a presentation, so only two VP extension options are supplied - one for
MsgCreateValidator and one for MsgVote, matched in message order.
The ExtensionOptions value is the protobuf-encoded d.vcv.v1.VerifiablePresentation carrying a compact SD-JWT in its
presentation bytes:
message VerifiablePresentation { bytes presentation = 1; }
If no Route is registered for a message that a keeper considers "required", verification returns ErrRouteNotFound,
which the decorator tolerates - the message is allowed to pass. Any other verification error rejects the transaction.
Verification flow
VerifyMsgExtensionOptions (x/vcv/keeper/keeper_sdjwt_verify.go):
- Looks up the
Routebyproto.MessageName(msg). - Unmarshals the extension option bytes into a
VerifiablePresentationand reads the compact SD-JWT frompresentation. - Calls
sdjwt.Verify(token, {Now: ctx.BlockTime(), IssuerKeysResolver: route}). TheRouteitself acts as the issuer-key resolver, supplying the issuer's public JWK for signature verification. - For each of the issuer's
content_requirements, resolves the requirement'sCriterionagainst the disclosed claim and acompareTovalue taken from the message - forMsgCreateValidatorthe message's validator address (claimvalidator), and forMsgVotethe voter address (claimvoter).
Verification in the proposal pipeline
Beyond the AnteHandler, the vcv keeper also verifies VPs in the ABCI proposal pipeline: the proposer's VP
(MsgProcessProposal, comparing the proposer to the validator claim) and each validator's vote-extension VP
(ValidatorVoteExtension, comparing the validator consensus address to the validator claim). The same
VerifyVerifiablePresentation routine is used.
Implementation into app
The ExtensionOptions AnteHandler decorator is wired into the app's ante chain. In Dchain, see app/ante.go.