A consumer contract receives a DataUpdate + SchnorrSignature in calldata, verifies it against the Molpha Verifier, and acts on the value in the same transaction.
Build the calldata
buildEvmVerifierArgs maps a gateway DataUpdateResult onto the on-chain structs with zero runtime dependency on ethers/viem:
gateway DataUpdateResult → IVerifier.DataUpdate
jobId, registryVersion, jobId, registryVersion,
signaturesRequired, signaturesRequired,
valuePacked, timestamp value, canonicalTimestamp
→ IVerifier.SchnorrSignature
s signature
commitmentAddr commitment
signersBitmap signersBitmap
Consumer contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.31;
import {IVerifier} from "molpha-core-contracts/interfaces/IVerifier.sol";
contract MyConsumer {
IVerifier public immutable verifier;
uint256 public constant MAX_STALENESS = 60; // seconds
constructor(address verifier_) {
verifier = IVerifier(verifier_);
}
function settle(
IVerifier.DataUpdate calldata update,
IVerifier.SchnorrSignature calldata sig
) external {
// 1. Cryptographic verification — MUST check the return value.
require(verifier.verify(update, sig), "Molpha: invalid signature");
// 2. Freshness — the verifier does not enforce staleness; the consumer does.
require(
block.timestamp - update.canonicalTimestamp <= MAX_STALENESS,
"Molpha: stale data"
);
// 3. Application logic using the verified value.
_useValue(update.value);
}
function _useValue(bytes32 value) internal { /* ... */ }
}
verify returns a boolean — it does not revert on a cryptographically invalid signature (structural violations revert; a bad signature returns false). Always require(...) the return value, or your contract will silently accept unverified data.
Consumer responsibilities
verify proves who signed what, not when you read it. Your contract must:
- Enforce freshness against
canonicalTimestamp — the verifier is stateless and has no replay window of its own.
- Prevent replay if your flow can be re-executed — the same valid payload verifies forever.
- Validate
jobId and signaturesRequired match the feed you intend to consume.
Gas
Representative execution gas from the repository benchmarks (forge test --match-test test_gas_verify -vv):
| Nodes | Threshold | Execution gas | Calldata gas | Est. total (with 21k base) |
|---|
| 5 | 3 | ~12,900 | ~1,920 | ~35,800 |
| 10 | 5 | ~16,900 | ~1,930 | ~39,800 |
| 20 | 8 | ~23,500 | ~1,950 | ~46,400 |
Full contract reference: EVM Verifier. Deployed addresses: Deployments.