Think·two-phase async
ᛉ
ZK Proofs
Verifiable compute
Generate ZK proofs of computation inside a TEE. Verified on-chain.
0x0000000000000000000000000000000000000806Explorer
Different layout! ZK uses
ExecutorRequest directly, NOT LongRunningRequest. NO pollIntervalBlocks, NO maxPollBlock, NO taskIdMarker. Wrong struct = silent revert.click 'auto' (capability = 5)
bytes — circuit-specific input encoding
≤ 500
min escrow: 0.1000 RITUALyou have: — RITUAL
Connect your wallet to submit a real transaction.
to: 0x0000000000000000000000000000000000000806chainId 1979 · two-phase · ExecutorRequest layout
Output
Click Validate to encode the 14-field ZK proof request.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {PrecompileConsumer} from "./utils/PrecompileConsumer.sol";
contract ZKVerifier is PrecompileConsumer {
address constant ZK = address(0x806);
address constant ASYNC_DELIVERY = 0x5A16214fF555848411544b005f7Ac063742f39F6;
event ZKRequested(bytes32 indexed jobId);
event ZKVerified(bytes32 indexed jobId, bytes proof);
/// @dev IMPORTANT: ZK extends ExecutorRequest layout — NOT LongRunningRequest.
/// No pollInterval / maxPollBlock / taskIdMarker fields. Wrong struct
/// shape = silent revert.
function requestProof(address executor, bytes calldata operationInput) external {
bytes memory encoded = abi.encode(
executor,
new bytes[](0), uint256(500), new bytes[](0), bytes(""),
false, // inputEncrypted
uint64(block.number + 1000), // maxProofBlock
address(this), this.onZKResultDelivered.selector,
uint256(300_000), uint256(1_000_000_000),
uint256(100_000_000), uint256(0),
operationInput
);
(bool ok, bytes memory result) = ZK.call(encoded);
require(ok, "zk call failed");
bytes32 jobId = abi.decode(result, (bytes32));
emit ZKRequested(jobId);
}
function onZKResultDelivered(bytes32 jobId, bytes calldata proof) external {
require(msg.sender == ASYNC_DELIVERY, "unauth");
// Proof verified by chain as part of settlement. If we got here,
// the proof is valid.
emit ZKVerified(jobId, proof);
}
}