Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 219 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| 0x0d32f061 | 39982168 | 5 days ago | IN | 0 ETH | 0.00000158 | ||||
| 0x0d32f061 | 39981883 | 5 days ago | IN | 0 ETH | 0.00000159 | ||||
| 0x0d32f061 | 39981318 | 5 days ago | IN | 0 ETH | 0.00000159 | ||||
| 0x0d32f061 | 38048644 | 50 days ago | IN | 0 ETH | 0.00000139 | ||||
| 0x0d32f061 | 37573572 | 61 days ago | IN | 0 ETH | 0.0000013 | ||||
| 0x0d32f061 | 37573518 | 61 days ago | IN | 0 ETH | 0.00000127 | ||||
| 0x0d32f061 | 37573501 | 61 days ago | IN | 0 ETH | 0.0000013 | ||||
| 0x0d32f061 | 37573425 | 61 days ago | IN | 0 ETH | 0.00000131 | ||||
| 0x0d32f061 | 37573417 | 61 days ago | IN | 0 ETH | 0.00000131 | ||||
| 0x0d32f061 | 37573406 | 61 days ago | IN | 0 ETH | 0.00000126 | ||||
| 0x0d32f061 | 37573400 | 61 days ago | IN | 0 ETH | 0.00000125 | ||||
| 0x0d32f061 | 37573385 | 61 days ago | IN | 0 ETH | 0.00000123 | ||||
| 0x0d32f061 | 37573383 | 61 days ago | IN | 0 ETH | 0.00000124 | ||||
| 0x0d32f061 | 37573365 | 61 days ago | IN | 0 ETH | 0.00000128 | ||||
| 0x0d32f061 | 37573329 | 61 days ago | IN | 0 ETH | 0.00000136 | ||||
| 0x0d32f061 | 37573132 | 61 days ago | IN | 0 ETH | 0.00000134 | ||||
| 0x0d32f061 | 37573114 | 61 days ago | IN | 0 ETH | 0.0000013 | ||||
| 0x0d32f061 | 37573096 | 61 days ago | IN | 0 ETH | 0.00000124 | ||||
| 0x0d32f061 | 37573077 | 61 days ago | IN | 0 ETH | 0.00000127 | ||||
| 0x0d32f061 | 37573059 | 61 days ago | IN | 0 ETH | 0.00000127 | ||||
| 0x0d32f061 | 37573041 | 61 days ago | IN | 0 ETH | 0.00000134 | ||||
| 0x0d32f061 | 37573022 | 61 days ago | IN | 0 ETH | 0.00000135 | ||||
| 0x0d32f061 | 37573003 | 61 days ago | IN | 0 ETH | 0.00000139 | ||||
| 0x0d32f061 | 37571024 | 61 days ago | IN | 0 ETH | 0.00000124 | ||||
| 0x0d32f061 | 37566326 | 61 days ago | IN | 0 ETH | 0.00000129 |
Loading...
Loading
Contract Name:
Groth16Verifier
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "./BN254.sol";
import "./IGroth16Bn254Verifier.sol";
/**
* @title Groth16Verifier
* @notice Generic Groth16 verifier over BN254 that reverts on malformed input and
* emits `ProofVerificationResult` with the verification outcome.
* @dev Follows the snarkjs/libsnark pairing equation:
* e(A,B) * e(-alpha1,beta2) * e(-vk_x,gamma2) * e(-C,delta2) == 1.
*/
contract Groth16Verifier is IGroth16Bn254Verifier {
using BN254 for BN254.G1Point;
using BN254 for BN254.G2Point;
/// @notice Scalar field modulus r (NOT the base field p).
uint256 private constant SNARK_SCALAR_FIELD =
21888242871839275222246405745257275088548364400416034343698204186575808495617;
/// @notice Custom errors for gas-efficient failures.
error InvalidICLength();
error InputOutOfBounds(); // public input >= r
/* ----------------------------- Verifier ----------------------------- */
/**
* @notice Verifies a Groth16 proof and reports the result via event and return value.
* @dev Reverts if IC length mismatches or public inputs >= scalar field.
* Point validation (coordinates, curve membership) is performed by EVM precompiles.
*/
function verifyProof(
bytes16 zkVerifyId,
bytes32 proofHash,
VerificationKey calldata vk,
Proof calldata proof,
uint256[] calldata publicInputs
) external returns (bool success) {
uint256 n = publicInputs.length;
if (vk.ic.length != n + 1) revert InvalidICLength();
// Validate public inputs < r (scalar field modulus)
// Note: Point coordinate validation is handled by EVM precompiles (ec_add, ec_mul, ec_pairing)
for (uint256 i = 0; i < n; ) {
if (publicInputs[i] >= SNARK_SCALAR_FIELD) revert InputOutOfBounds();
unchecked { ++i; }
}
// Build VK components
BN254.G1Point memory alpha1 = BN254.G1Point(vk.alpha1[0], vk.alpha1[1]);
BN254.G2Point memory beta2 = BN254.G2Point([vk.beta2[0][0], vk.beta2[0][1]], [vk.beta2[1][0], vk.beta2[1][1]]);
BN254.G2Point memory gamma2 = BN254.G2Point([vk.gamma2[0][0], vk.gamma2[0][1]], [vk.gamma2[1][0], vk.gamma2[1][1]]);
BN254.G2Point memory delta2 = BN254.G2Point([vk.delta2[0][0], vk.delta2[0][1]], [vk.delta2[1][0], vk.delta2[1][1]]);
// Build proof components
BN254.G1Point memory A = BN254.G1Point(proof.a[0], proof.a[1]);
BN254.G2Point memory B = BN254.G2Point([proof.b[0][0], proof.b[0][1]], [proof.b[1][0], proof.b[1][1]]);
BN254.G1Point memory C = BN254.G1Point(proof.c[0], proof.c[1]);
// vk_x = IC[0] + Σ_i IC[i+1] * publicInputs[i]
BN254.G1Point memory vk_x = BN254.G1Point(vk.ic[0][0], vk.ic[0][1]);
for (uint256 i = 0; i < n; ) {
BN254.G1Point memory ic = BN254.G1Point(vk.ic[i + 1][0], vk.ic[i + 1][1]);
vk_x.mulAccC(ic, publicInputs[i]);
unchecked { ++i; }
}
// Pairing product:
// e(A, B) * e(-alpha1, beta2) * e(-vk_x, gamma2) * e(-C, delta2) == 1
success = BN254.pairing4(
A, B,
alpha1.negate(), beta2,
vk_x.negate(), gamma2,
C.negate(), delta2
);
// Emit result and return success
emit ProofVerificationResult(zkVerifyId, proofHash, msg.sender, success);
return success;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
/**
* @title BN254
* @notice Minimal BN254 (alt_bn128) primitives backed by the EVM precompiles.
*/
library BN254 {
/// @notice Base field modulus p.
uint256 public constant FIELD_MODULUS =
0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47;
struct G1Point {
uint256 x;
uint256 y;
}
/// @dev G2 limbs are stored as [real, imaginary].
struct G2Point {
uint256[2] x;
uint256[2] y;
}
/* --------------------------- G1 operations --------------------------- */
function negate(G1Point memory p) internal pure returns (G1Point memory) {
if (p.x == 0 && p.y == 0) return G1Point(0, 0);
return G1Point(p.x, FIELD_MODULUS - p.y);
}
/// @notice G1 function to multiply a G1 value(x,y) to value in an address
/// @dev From snarkJS verifier template
function mulAccC(G1Point memory result, G1Point memory p, uint256 s)
internal
view
{
assembly {
let mIn := mload(0x40)
mstore(mIn, mload(p))
mstore(add(mIn, 32), mload(add(p, 32)))
mstore(add(mIn, 64), s)
let success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
mstore(add(mIn, 64), mload(result))
mstore(add(mIn, 96), mload(add(result, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, result, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
}
}
/* --------------------------- Pairing helpers ------------------------- */
function _writePair24(
uint256[24] memory dst,
uint256 o,
G1Point memory p1,
G2Point memory p2
) private pure {
dst[o + 0] = p1.x;
dst[o + 1] = p1.y;
dst[o + 2] = p2.x[1]; // X imaginary limb
dst[o + 3] = p2.x[0]; // X real limb
dst[o + 4] = p2.y[1]; // Y imaginary limb
dst[o + 5] = p2.y[0]; // Y real limb
}
/// @notice Pairing for 4 pairs (optimized for Groth16).
function pairing4(
G1Point memory a1,
G2Point memory a2,
G1Point memory b1,
G2Point memory b2,
G1Point memory c1,
G2Point memory c2,
G1Point memory d1,
G2Point memory d2
) internal view returns (bool) {
uint256[24] memory input;
_writePair24(input, 0, a1, a2);
_writePair24(input, 6, b1, b2);
_writePair24(input, 12, c1, c2);
_writePair24(input, 18, d1, d2);
uint256[1] memory out;
bool success;
assembly {
success := staticcall(gas(), 8, input, 0x300, out, 0x20)
}
if (!success) return false;
return out[0] != 0;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
/**
* @title IGroth16Bn254Verifier
* @notice Interface for Groth16 verifiers over BN254 that surface success via event and return value.
*/
interface IGroth16Bn254Verifier {
struct VerificationKey {
uint256[2] alpha1;
uint256[2][2] beta2;
uint256[2][2] gamma2;
uint256[2][2] delta2;
uint256[2][] ic;
}
struct Proof {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}
/// @notice Emitted after each verification attempt.
event ProofVerificationResult(
bytes16 indexed zkVerifyId,
bytes32 indexed proofHash,
address indexed requestor,
bool success
);
/**
* @notice Verifies a Groth16 proof and returns whether it succeeded.
* @dev Implementations should revert only for malformed input (length/field violations).
*/
function verifyProof(
bytes16 zkVerifyId,
bytes32 proofHash,
VerificationKey calldata vk,
Proof calldata proof,
uint256[] calldata publicInputs
) external returns (bool success);
}{
"remappings": [
"forge-std/=lib/forge-std/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": true
}Contract ABI
API[{"inputs":[],"name":"InputOutOfBounds","type":"error"},{"inputs":[],"name":"InvalidICLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes16","name":"zkVerifyId","type":"bytes16"},{"indexed":true,"internalType":"bytes32","name":"proofHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"requestor","type":"address"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"ProofVerificationResult","type":"event"},{"inputs":[{"internalType":"bytes16","name":"zkVerifyId","type":"bytes16"},{"internalType":"bytes32","name":"proofHash","type":"bytes32"},{"components":[{"internalType":"uint256[2]","name":"alpha1","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"beta2","type":"uint256[2][2]"},{"internalType":"uint256[2][2]","name":"gamma2","type":"uint256[2][2]"},{"internalType":"uint256[2][2]","name":"delta2","type":"uint256[2][2]"},{"internalType":"uint256[2][]","name":"ic","type":"uint256[2][]"}],"internalType":"struct IGroth16Bn254Verifier.VerificationKey","name":"vk","type":"tuple"},{"components":[{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"internalType":"struct IGroth16Bn254Verifier.Proof","name":"proof","type":"tuple"},{"internalType":"uint256[]","name":"publicInputs","type":"uint256[]"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080806040523461001657610790908161001b8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f803560e01c630d32f06114610025575f80fd5b346100c4576101803660031901126100c4576004356fffffffffffffffffffffffffffffffff19811681036100c75767ffffffffffffffff916044358381116100c7576100769036906004016100cb565b92610080366100de565b91610164359182116100c4576100c06100ae8686866100a236600489016100f0565b9390926024359061023a565b60405190151581529081906020820190565b0390f35b80fd5b5080fd5b90816101e09103126100da5790565b5f80fd5b6101009060631901126100da57606490565b9181601f840112156100da5782359167ffffffffffffffff83116100da576020808501948460051b0101116100da57565b903590601e19813603018212156100da570180359067ffffffffffffffff82116100da57602001918160061b360383136100da57565b634e487b7160e01b5f52601160045260245ffd5b906001820180921161017957565b610157565b634e487b7160e01b5f52603260045260245ffd5b91908110156101a25760051b0190565b61017e565b634e487b7160e01b5f52604160045260245ffd5b604051906040820182811067ffffffffffffffff8211176101db57604052565b6101a7565b60405190610300820182811067ffffffffffffffff8211176101db57604052565b604051906020820182811067ffffffffffffffff8211176101db57604052565b90156101a25790565b91908110156101a25760061b0190565b929594939190936101c08201966102518884610121565b905061025c8361016b565b03610540575f5b8281106104f357506102736101bb565b9183358352602084013560208401528861028b6101bb565b9160408601358352606086013560208401526102a56101bb565b6080870135815260a087013560208201526102be6101bb565b93845260208401526102ce6101bb565b9460c0870135865260e087013560208701526102e86101bb565b610100880135815261012088013560208201526103036101bb565b96875260208701526103136101bb565b97610140880135895261016088013560208a015261032f6101bb565b61018089013581526101a0890135602082015261034a6101bb565b998a5260208a015261035a6101bb565b9786358952602087013560208a01526103716101bb565b93604088013585526060880135602086015261038b6101bb565b6080890135815260a089013560208201526103a46101bb565b958652602086015260e06103b66101bb565b9860c08101358a52013560208901526103ef6103e96103db6103e16103db8a87610121565b90610221565b359885610121565b60200190565b356103f86101bb565b96875260208701525f5b81811061048b575050505061043698999a9b5061042a61042461043092610552565b93610552565b94610552565b9561062c565b916040517fc868c4ce3b3f615ef1d4b8508e065b8bbe61d75e45df10ae190575242e15c75c33936fffffffffffffffffffffffffffffffff191691806104858782919091602081019215159052565b0390a490565b8f906104ed826104c96103e96104c06104b86104a96001988b610121565b6104b28961016b565b9161022a565b359389610121565b6104b28761016b565b356104d26101bb565b91825260208201526104e5838689610192565b35908a6105d5565b01610402565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161051f828588610192565b35101561052e57600101610263565b60405163102cad1b60e01b8152600490fd5b60405163bb7a0e5760e01b8152600490fd5b5f602061055d6101bb565b8281520152805115806105c9575b6105b457602081519101517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47908103908111610179576105a96101bb565b918252602082015290565b506105bd6101bb565b5f81525f602082015290565b5060208101511561056b565b906020604051918051835201516020820152604081019283526107cf19906040816060816007865a01fa1561062457600660809260409585519052602085015160608401525a01fa1561062457565b5f805260205ff35b969392959491909561063c6101e0565b966103009889368a3780518952602090810151818a0152815101516040890152805151606089015260200180516106739060200190565b516080890152515160a0880152815160c088015260209182015160e088015280518201516101008801528051516101208801528101805182015161014088015251516101608701528251610180870152918201516101a086015280518201516101c08601528051516101e086015281018051820151610200860152515161022085015282516102408501529182015161026084015280518201516102808401528051516102a084015281018051909101516102c083015251516102e082015261073a610201565b80923660209083375a926008602094fa156107555751151590565b505f9056fea264697066735822122050ad4e6658718aee47ce805bb1e5e3d251fd7858dbc432f68f79f6ab7cfd63fb64736f6c63430008140033
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f803560e01c630d32f06114610025575f80fd5b346100c4576101803660031901126100c4576004356fffffffffffffffffffffffffffffffff19811681036100c75767ffffffffffffffff916044358381116100c7576100769036906004016100cb565b92610080366100de565b91610164359182116100c4576100c06100ae8686866100a236600489016100f0565b9390926024359061023a565b60405190151581529081906020820190565b0390f35b80fd5b5080fd5b90816101e09103126100da5790565b5f80fd5b6101009060631901126100da57606490565b9181601f840112156100da5782359167ffffffffffffffff83116100da576020808501948460051b0101116100da57565b903590601e19813603018212156100da570180359067ffffffffffffffff82116100da57602001918160061b360383136100da57565b634e487b7160e01b5f52601160045260245ffd5b906001820180921161017957565b610157565b634e487b7160e01b5f52603260045260245ffd5b91908110156101a25760051b0190565b61017e565b634e487b7160e01b5f52604160045260245ffd5b604051906040820182811067ffffffffffffffff8211176101db57604052565b6101a7565b60405190610300820182811067ffffffffffffffff8211176101db57604052565b604051906020820182811067ffffffffffffffff8211176101db57604052565b90156101a25790565b91908110156101a25760061b0190565b929594939190936101c08201966102518884610121565b905061025c8361016b565b03610540575f5b8281106104f357506102736101bb565b9183358352602084013560208401528861028b6101bb565b9160408601358352606086013560208401526102a56101bb565b6080870135815260a087013560208201526102be6101bb565b93845260208401526102ce6101bb565b9460c0870135865260e087013560208701526102e86101bb565b610100880135815261012088013560208201526103036101bb565b96875260208701526103136101bb565b97610140880135895261016088013560208a015261032f6101bb565b61018089013581526101a0890135602082015261034a6101bb565b998a5260208a015261035a6101bb565b9786358952602087013560208a01526103716101bb565b93604088013585526060880135602086015261038b6101bb565b6080890135815260a089013560208201526103a46101bb565b958652602086015260e06103b66101bb565b9860c08101358a52013560208901526103ef6103e96103db6103e16103db8a87610121565b90610221565b359885610121565b60200190565b356103f86101bb565b96875260208701525f5b81811061048b575050505061043698999a9b5061042a61042461043092610552565b93610552565b94610552565b9561062c565b916040517fc868c4ce3b3f615ef1d4b8508e065b8bbe61d75e45df10ae190575242e15c75c33936fffffffffffffffffffffffffffffffff191691806104858782919091602081019215159052565b0390a490565b8f906104ed826104c96103e96104c06104b86104a96001988b610121565b6104b28961016b565b9161022a565b359389610121565b6104b28761016b565b356104d26101bb565b91825260208201526104e5838689610192565b35908a6105d5565b01610402565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161051f828588610192565b35101561052e57600101610263565b60405163102cad1b60e01b8152600490fd5b60405163bb7a0e5760e01b8152600490fd5b5f602061055d6101bb565b8281520152805115806105c9575b6105b457602081519101517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47908103908111610179576105a96101bb565b918252602082015290565b506105bd6101bb565b5f81525f602082015290565b5060208101511561056b565b906020604051918051835201516020820152604081019283526107cf19906040816060816007865a01fa1561062457600660809260409585519052602085015160608401525a01fa1561062457565b5f805260205ff35b969392959491909561063c6101e0565b966103009889368a3780518952602090810151818a0152815101516040890152805151606089015260200180516106739060200190565b516080890152515160a0880152815160c088015260209182015160e088015280518201516101008801528051516101208801528101805182015161014088015251516101608701528251610180870152918201516101a086015280518201516101c08601528051516101e086015281018051820151610200860152515161022085015282516102408501529182015161026084015280518201516102808401528051516102a084015281018051909101516102c083015251516102e082015261073a610201565b80923660209083375a926008602094fa156107555751151590565b505f9056fea264697066735822122050ad4e6658718aee47ce805bb1e5e3d251fd7858dbc432f68f79f6ab7cfd63fb64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.