Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- CardMerkle
- Optimization enabled
- false
- Compiler version
- v0.8.28+commit.7893614a
- EVM Version
- Verified at
- 2026-08-20T06:38:38.330371Z
Constructor Arguments
contracts/lib/CardMerkle.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
/// @title CardMerkle — 52-leaf (padded to 64) keccak Merkle tree over deck values
/// @notice leaf(i) = keccak256(uint8 stage ‖ uint8 i ‖ 128-byte value);
/// padding leaves are bytes32(0). Mirrors web/js/merkle.mjs.
library CardMerkle {
uint256 internal constant DECK = 52;
uint256 internal constant TREE = 64;
uint256 internal constant DEPTH = 6;
uint256 internal constant VALUE_BYTES = 128;
/// @notice Compute the root of a full posted deck stage (calldata blob of
/// 52 × 128 bytes). `stage` ∈ 1..4 domain-separates the stages.
function computeRoot(bytes calldata deck, uint8 stage) public pure returns (bytes32) {
require(deck.length == DECK * VALUE_BYTES, "deck len");
bytes32[TREE] memory nodes;
for (uint256 i = 0; i < DECK; i++) {
nodes[i] = keccak256(
abi.encodePacked(stage, uint8(i), deck[i * VALUE_BYTES:(i + 1) * VALUE_BYTES])
);
}
// 12 zero padding leaves are bytes32(0) already
uint256 width = TREE;
while (width > 1) {
for (uint256 i = 0; i < width; i += 2) {
nodes[i / 2] = keccak256(abi.encodePacked(nodes[i], nodes[i + 1]));
}
width /= 2;
}
return nodes[0];
}
/// @notice Verify a single 128-byte value against a stored stage root.
function verify(
bytes32 root,
uint8 stage,
uint8 index,
bytes memory value,
bytes32[DEPTH] memory proof
) public pure returns (bool) {
if (index >= DECK || value.length != VALUE_BYTES) return false;
bytes32 h = keccak256(abi.encodePacked(stage, index, value));
uint256 idx = index;
for (uint256 d = 0; d < DEPTH; d++) {
h = idx & 1 == 1
? keccak256(abi.encodePacked(proof[d], h))
: keccak256(abi.encodePacked(h, proof[d]));
idx >>= 1;
}
return h == root;
}
}
Compiler Settings
{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":1,"enabled":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"computeRoot","inputs":[{"type":"bytes","name":"deck","internalType":"bytes"},{"type":"uint8","name":"stage","internalType":"uint8"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verify","inputs":[{"type":"bytes32","name":"root","internalType":"bytes32"},{"type":"uint8","name":"stage","internalType":"uint8"},{"type":"uint8","name":"index","internalType":"uint8"},{"type":"bytes","name":"value","internalType":"bytes"},{"type":"bytes32[6]","name":"proof","internalType":"bytes32[6]"}]}]
Contract Creation Code
0x608080604052346019576104f7908161001f823930815050f35b600080fdfe608080604052600436101561001357600080fd5b60003560e01c908163af0586a314610230575063b65c02d31461003557600080fd5b60403660031901126101fb576004356001600160401b0381116101fb57366023820112156101fb5760048101356001600160401b0381116101fb5736602482840101116101fb57610084610329565b611a008203610200579061080092604051936100a08186610339565b36853760f89290921b6001600160f81b0319169160005b60348110610160576040855b600182116100d75760209051604051908152f35b60005b8281106100ec57509060011c906100c3565b6100f681836104b0565b516001820180831161014a5761010c90846104b0565b51604051906020820192835260408201526040815261012c606082610339565b51902061013c8260011c846104b0565b5260028101809111156100da575b634e487b7160e01b600052601160045260246000fd5b8060071b908082046080148115171561014a57600181019182821161014a578260071b928084046080149015171561014a578281116101fb578483116101fb5780600193036101e76022604051838194602460208401978d895260ff60f81b8a60f81b1660218601528b01018484013781016000838201520301601f198101835282610339565b5190206101f482886104b0565b52016100b7565b600080fd5b60405162461bcd60e51b81526020600482015260086024820152673232b1b5903632b760c11b6044820152606490fd5b6101403660031901126101fb57610245610329565b906044359060ff821682036101fb576064356001600160401b0381116101fb57366023820112156101fb576004810135906001600160401b03821161031357610298601f8301601f191660200184610339565b81835236602483830101116101fb578160009260246020930183860137830101523660a312156101fb57604051906102d160c083610339565b819236610144116101fb576020946084945b610144861061030457506102fa9450600435610383565b6040519015158152f35b853581529486019486016102e3565b634e487b7160e01b600052604160045260246000fd5b6024359060ff821682036101fb57565b601f909101601f19168101906001600160401b0382119082101761031357604052565b90600681101561036d5760051b0190565b634e487b7160e01b600052603260045260246000fd5b939160ff811693603485108015906104a4575b6104995760405191602083019360ff60f81b9060f81b16845260ff60f81b9060f81b1660218301528181519160005b838110610481575050806103ec92602292016000838201520301601f198101835282610339565b519020919060005b60068110610403575050501490565b909192600190818086161460001461044f5761041f838561035c565b51906040519060208201928352604082015260408152610440606082610339565b5190205b93811c9291016103f4565b610459838561035c565b516040519060208201928352604082015260408152610479606082610339565b519020610444565b602082820181015160228784010152859350016103c5565b505050505050600090565b50608081511415610396565b90604081101561036d5760051b019056fea26469706673582212209ef41d97e5f0178d6e9421f08f6be3e46f2c46cc07e35ac9866c52e17ce4960264736f6c634300081c0033
Deployed ByteCode
0x608080604052600436101561001357600080fd5b60003560e01c908163af0586a314610230575063b65c02d31461003557600080fd5b60403660031901126101fb576004356001600160401b0381116101fb57366023820112156101fb5760048101356001600160401b0381116101fb5736602482840101116101fb57610084610329565b611a008203610200579061080092604051936100a08186610339565b36853760f89290921b6001600160f81b0319169160005b60348110610160576040855b600182116100d75760209051604051908152f35b60005b8281106100ec57509060011c906100c3565b6100f681836104b0565b516001820180831161014a5761010c90846104b0565b51604051906020820192835260408201526040815261012c606082610339565b51902061013c8260011c846104b0565b5260028101809111156100da575b634e487b7160e01b600052601160045260246000fd5b8060071b908082046080148115171561014a57600181019182821161014a578260071b928084046080149015171561014a578281116101fb578483116101fb5780600193036101e76022604051838194602460208401978d895260ff60f81b8a60f81b1660218601528b01018484013781016000838201520301601f198101835282610339565b5190206101f482886104b0565b52016100b7565b600080fd5b60405162461bcd60e51b81526020600482015260086024820152673232b1b5903632b760c11b6044820152606490fd5b6101403660031901126101fb57610245610329565b906044359060ff821682036101fb576064356001600160401b0381116101fb57366023820112156101fb576004810135906001600160401b03821161031357610298601f8301601f191660200184610339565b81835236602483830101116101fb578160009260246020930183860137830101523660a312156101fb57604051906102d160c083610339565b819236610144116101fb576020946084945b610144861061030457506102fa9450600435610383565b6040519015158152f35b853581529486019486016102e3565b634e487b7160e01b600052604160045260246000fd5b6024359060ff821682036101fb57565b601f909101601f19168101906001600160401b0382119082101761031357604052565b90600681101561036d5760051b0190565b634e487b7160e01b600052603260045260246000fd5b939160ff811693603485108015906104a4575b6104995760405191602083019360ff60f81b9060f81b16845260ff60f81b9060f81b1660218301528181519160005b838110610481575050806103ec92602292016000838201520301601f198101835282610339565b519020919060005b60068110610403575050501490565b909192600190818086161460001461044f5761041f838561035c565b51906040519060208201928352604082015260408152610440606082610339565b5190205b93811c9291016103f4565b610459838561035c565b516040519060208201928352604082015260408152610479606082610339565b519020610444565b602082820181015160228784010152859350016103c5565b505050505050600090565b50608081511415610396565b90604081101561036d5760051b019056fea26469706673582212209ef41d97e5f0178d6e9421f08f6be3e46f2c46cc07e35ac9866c52e17ce4960264736f6c634300081c0033