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.