Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
DnssecP256Verifier
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import "./interfaces/IAlgorithm.sol";
/// @notice Minimal interface for our verifier so other contracts can call it uniformly.
interface IDnssecP256Verifier {
function verify(bytes calldata proofBundle, bytes calldata question)
external
view
returns (bool ok, bytes memory canonicalRrset);
}
/// @notice Proof bundle structures matching `server.mjs`'s `PROOF_BUNDLE_SCHEMA`.
contract DnssecP256Verifier is IDnssecP256Verifier {
IAlgorithm public algorithm;
event AlgorithmUpdated(address indexed algorithm);
struct TrustAnchor {
bytes mode;
bytes zoneNameWire;
uint16 keyTag;
uint8 algorithm;
uint16 dnskeyFlags;
}
struct Question {
bytes qnameWire;
uint16 qtype;
uint16 qclass;
}
struct TimePolicy {
bytes policy;
uint64 validationTime;
uint64 clockSkewSeconds;
bool requireInceptionLeNowPlusSkew;
bool requireNowMinusSkewLeExpiration;
}
struct RRSIG {
uint16 typeCovered;
uint8 algorithm;
uint8 labels;
uint32 originalTTL;
uint32 expiration;
uint32 inception;
uint16 keyTag;
bytes signerNameWire;
bytes signature;
}
struct DNSKEY {
uint16 flags;
uint8 protocol;
uint8 algorithm;
bytes publicKey;
}
struct DNSSECProof {
bytes nameWire;
bytes rrsetBytes;
bytes signedDataBytes;
RRSIG rrsig;
DNSKEY dnskey;
}
struct ProofBundle {
bytes version;
bytes profile;
bytes signatureFormat;
TrustAnchor trustAnchor;
Question question;
TimePolicy time;
DNSSECProof dnskeyProof;
DNSSECProof answerProof;
}
struct RootAnchor {
uint256 publicKeyX;
uint256 publicKeyY;
uint16 keyTag;
uint256 validFrom;
}
mapping(bytes => RootAnchor) public pinnedAnchors;
address public owner;
error InvalidProofBundle();
error Unauthorized();
error InvalidZoneName();
error AlgorithmNotSet();
error InvalidSignature(string context);
error InvalidProofStructure(string reason);
error EmptyProofField(string field);
error InvalidSignatureFormat(bytes actual);
modifier onlyOwner() {
if (msg.sender != owner) revert Unauthorized();
_;
}
event TrustAnchorSet(bytes indexed zoneNameWire, uint16 keyTag, uint256 validFrom);
event TrustAnchorCleared(bytes indexed zoneNameWire);
event OwnerUpdated(address indexed previousOwner, address indexed newOwner);
/// @dev Sets deployer as owner.
constructor() {
owner = msg.sender;
}
/// @dev Transfers ownership.
function transferOwnership(address newOwner) external onlyOwner {
emit OwnerUpdated(owner, newOwner);
owner = newOwner;
}
function setAlgorithm(IAlgorithm algorithm_) external onlyOwner {
algorithm = algorithm_;
emit AlgorithmUpdated(address(algorithm_));
}
/// @dev Stores a pinned trust anchor for the given zone.
function setPinnedTrustAnchor(
bytes calldata zoneNameWire,
uint256 publicKeyX,
uint256 publicKeyY,
uint16 keyTag
) external onlyOwner {
if (zoneNameWire.length == 0) revert InvalidZoneName();
pinnedAnchors[zoneNameWire] = RootAnchor({
publicKeyX: publicKeyX,
publicKeyY: publicKeyY,
keyTag: keyTag,
validFrom: block.timestamp
});
emit TrustAnchorSet(zoneNameWire, keyTag, block.timestamp);
}
/// @dev Clears a pinned trust anchor.
function clearPinnedTrustAnchor(bytes calldata zoneNameWire) external onlyOwner {
delete pinnedAnchors[zoneNameWire];
emit TrustAnchorCleared(zoneNameWire);
}
function getPinnedAnchor(bytes memory zoneNameWire)
internal
view
returns (RootAnchor memory anchor)
{
anchor = pinnedAnchors[zoneNameWire];
if (anchor.keyTag == 0) revert InvalidZoneName();
}
function verify(bytes calldata proofBundle, bytes calldata question)
external
view
override
returns (bool ok, bytes memory canonicalRrset)
{
ProofBundle memory proof = decodeProofBundle(proofBundle);
Question memory decodedQuestion = question.length > 0
? decodeQuestion(question)
: proof.question;
validateProofStructure(proof);
RootAnchor memory anchor = validateTrustAnchor(proof.trustAnchor);
verifyDNSKEYProof(proof, anchor);
verifyAnswerProof(proof);
validateTimeWindows(proof);
validateQuestion(proof, decodedQuestion);
ok = true;
canonicalRrset = proof.answerProof.rrsetBytes;
}
function decodeProofBundle(bytes calldata encoded)
internal
pure
returns (ProofBundle memory proof)
{
(
bytes memory version,
bytes memory profile,
bytes memory signatureFormat,
TrustAnchor memory trustAnchor,
Question memory question,
TimePolicy memory time,
DNSSECProof memory dnskeyProof,
DNSSECProof memory answerProof
) = abi.decode(
encoded,
(
bytes,
bytes,
bytes,
TrustAnchor,
Question,
TimePolicy,
DNSSECProof,
DNSSECProof
)
);
proof = ProofBundle({
version: version,
profile: profile,
signatureFormat: signatureFormat,
trustAnchor: trustAnchor,
question: question,
time: time,
dnskeyProof: dnskeyProof,
answerProof: answerProof
});
}
function decodeQuestion(bytes calldata encoded)
internal
pure
returns (Question memory question)
{
(question.qnameWire, question.qtype, question.qclass) = abi.decode(
encoded,
(bytes, uint16, uint16)
);
}
function validateProofStructure(ProofBundle memory proof) internal pure {
if (proof.version.length == 0) revert EmptyProofField("version");
if (proof.profile.length == 0) revert EmptyProofField("profile");
if (proof.signatureFormat.length == 0) revert EmptyProofField("signatureFormat");
if (keccak256(proof.signatureFormat) != keccak256(bytes("p256_r_s_64"))) {
revert InvalidSignatureFormat(proof.signatureFormat);
}
if (proof.trustAnchor.zoneNameWire.length == 0) revert EmptyProofField("trustAnchor.zoneNameWire");
if (proof.question.qnameWire.length == 0) revert EmptyProofField("question.qnameWire");
if (proof.time.policy.length == 0) revert EmptyProofField("time.policy");
ensureProofNotEmpty(proof.dnskeyProof, "dnskeyProof");
ensureProofNotEmpty(proof.answerProof, "answerProof");
}
function ensureProofNotEmpty(DNSSECProof memory proof, string memory label) internal pure {
if (proof.nameWire.length == 0) revert InvalidProofStructure(label);
if (proof.rrsig.signature.length != 64) revert InvalidProofStructure(label);
if (proof.rrsig.signerNameWire.length == 0) revert InvalidProofStructure(label);
if (proof.rrsetBytes.length == 0) revert InvalidProofStructure(label);
if (proof.signedDataBytes.length == 0) revert InvalidProofStructure(label);
if (proof.dnskey.publicKey.length != 64) revert InvalidProofStructure(label);
}
function validateTrustAnchor(TrustAnchor memory proofAnchor)
internal
view
returns (RootAnchor memory anchor)
{
require(
keccak256(proofAnchor.mode) ==
keccak256(bytes("pinned_zone_ksk")),
"unsupported trust anchor mode"
);
anchor = getPinnedAnchor(proofAnchor.zoneNameWire);
require(anchor.keyTag == proofAnchor.keyTag, "key tag mismatch");
require(proofAnchor.algorithm == 13, "trust anchor must be Algo 13");
}
function verifyDNSKEYProof(ProofBundle memory proof, RootAnchor memory anchor)
internal
view
{
ensureAlgorithmSet();
require(proof.dnskeyProof.rrsig.algorithm == 13, "DNSKEY rrsig algo must be 13");
require(proof.dnskeyProof.dnskey.algorithm == 13, "DNSKEY must be algo 13");
bytes memory key = abi.encodePacked(
bytes32(anchor.publicKeyX),
bytes32(anchor.publicKeyY)
);
bool valid = algorithm.verify(
key,
proof.dnskeyProof.signedDataBytes,
proof.dnskeyProof.rrsig.signature
);
if (!valid) revert InvalidSignature("dnskey");
}
function verifyAnswerProof(ProofBundle memory proof) internal view {
ensureAlgorithmSet();
require(proof.answerProof.rrsig.algorithm == 13, "answer rrsig algo must be 13");
require(proof.answerProof.dnskey.algorithm == 13, "DNSKEY must be algo 13");
require(proof.answerProof.dnskey.publicKey.length == 64, "invalid dnskey key length");
bool valid = algorithm.verify(
proof.answerProof.dnskey.publicKey,
proof.answerProof.signedDataBytes,
proof.answerProof.rrsig.signature
);
if (!valid) revert InvalidSignature("answer");
}
function validateTimeWindows(ProofBundle memory proof) internal view {
uint64 nowTs = uint64(block.timestamp);
checkRrsigTime(proof.time, proof.dnskeyProof.rrsig, nowTs);
checkRrsigTime(proof.time, proof.answerProof.rrsig, nowTs);
}
function checkRrsigTime(
TimePolicy memory policy,
RRSIG memory rrsig,
uint64 nowTs
) internal pure {
uint64 skew = policy.clockSkewSeconds;
if (policy.requireInceptionLeNowPlusSkew) {
require(rrsig.inception <= nowTs + skew, "inception too late");
}
if (policy.requireNowMinusSkewLeExpiration) {
require(nowTs <= rrsig.expiration + skew, "signature expired");
}
}
function validateQuestion(ProofBundle memory proof, Question memory question)
internal
pure
{
require(question.qclass == 1, "only IN class supported");
require(
proof.answerProof.rrsig.typeCovered == question.qtype,
"qtype mismatch"
);
require(
keccak256(proof.answerProof.nameWire) == keccak256(question.qnameWire),
"qname mismatch"
);
}
function ensureAlgorithmSet() internal view {
if (address(algorithm) == address(0)) revert AlgorithmNotSet();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
interface IAlgorithm {
function verify(
bytes calldata key,
bytes calldata data,
bytes calldata signature
) external view returns (bool);
}{
"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": "cancun",
"viaIR": false
}Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlgorithmNotSet","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"EmptyProofField","type":"error"},{"inputs":[],"name":"InvalidProofBundle","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"InvalidProofStructure","type":"error"},{"inputs":[{"internalType":"string","name":"context","type":"string"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"bytes","name":"actual","type":"bytes"}],"name":"InvalidSignatureFormat","type":"error"},{"inputs":[],"name":"InvalidZoneName","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"algorithm","type":"address"}],"name":"AlgorithmUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"zoneNameWire","type":"bytes"}],"name":"TrustAnchorCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"zoneNameWire","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"keyTag","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"validFrom","type":"uint256"}],"name":"TrustAnchorSet","type":"event"},{"inputs":[],"name":"algorithm","outputs":[{"internalType":"contract IAlgorithm","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"zoneNameWire","type":"bytes"}],"name":"clearPinnedTrustAnchor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"pinnedAnchors","outputs":[{"internalType":"uint256","name":"publicKeyX","type":"uint256"},{"internalType":"uint256","name":"publicKeyY","type":"uint256"},{"internalType":"uint16","name":"keyTag","type":"uint16"},{"internalType":"uint256","name":"validFrom","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAlgorithm","name":"algorithm_","type":"address"}],"name":"setAlgorithm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"zoneNameWire","type":"bytes"},{"internalType":"uint256","name":"publicKeyX","type":"uint256"},{"internalType":"uint256","name":"publicKeyY","type":"uint256"},{"internalType":"uint16","name":"keyTag","type":"uint16"}],"name":"setPinnedTrustAnchor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"proofBundle","type":"bytes"},{"internalType":"bytes","name":"question","type":"bytes"}],"name":"verify","outputs":[{"internalType":"bool","name":"ok","type":"bool"},{"internalType":"bytes","name":"canonicalRrset","type":"bytes"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052348015600e575f80fd5b50600280546001600160a01b03191633179055611c868061002e5f395ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063e4a02f4a11610058578063e4a02f4a146100f3578063e58e620014610168578063f2fde38b1461017b578063f7e83aee1461018e575f80fd5b80631afb1354146100895780632e58ca461461009e5780638da5cb5b146100cd578063acd76e85146100e0575b5f80fd5b61009c610097366004611298565b6101af565b005b5f546100b0906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6002546100b0906001600160a01b031681565b61009c6100ee36600461130f565b610220565b61013e610101366004611458565b80516020818301810180516001808352938301929094019190912092905281549082015460028301546003909301549192909161ffff9091169084565b6040516100c49493929190938452602084019290925261ffff166040830152606082015260800190565b61009c610176366004611491565b61033e565b61009c610189366004611298565b6103e7565b6101a161019c3660046114cf565b61046c565b6040516100c4929190611567565b6002546001600160a01b031633146101d9576040516282b42960e81b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f9dfddf144470eb2821fe3daf0548360f61ec36aaad15652541696d97c6c3e0d791a250565b6002546001600160a01b0316331461024a576040516282b42960e81b815260040160405180910390fd5b5f84900361026b57604051636e1ef7bf60e01b815260040160405180910390fd5b60405180608001604052808481526020018381526020018261ffff16815260200142815250600186866040516102a2929190611581565b9081526040805160209281900383018120845181559284015160018401559083015160028301805461ffff191661ffff9092169190911790556060909201516003909101556102f49086908690611581565b6040805191829003822061ffff84168352426020840152917fa290c5c52baa6dfd5e53ab00d828105df047f6cb6890146fb13e303cf38c674d910160405180910390a25050505050565b6002546001600160a01b03163314610368576040516282b42960e81b815260040160405180910390fd5b6001828260405161037a929190611581565b9081526040519081900360200181205f8082556001820181905560028201805461ffff191690556003909101556103b49083908390611581565b604051908190038120907fd54c0ff02cddc44364d014fc0b12360c04535d619668a4599131c56646d43a4f905f90a25050565b6002546001600160a01b03163314610411576040516282b42960e81b815260040160405180910390fd5b6002546040516001600160a01b038084169216907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b5f60605f61047a87876104ef565b90505f8461048c578160800151610496565b6104968686610553565b90506104a182610594565b5f6104af8360600151610818565b90506104bb838261099c565b6104c483610b54565b6104cd83610d3a565b6104d78383610d6b565b505060e0015160200151600197909650945050505050565b6104f7611112565b5f8080808080808061050b8a8c018c6119e7565b60408051610100810182529889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201529b9a5050505050505050505050565b604080516060808201835281525f602082018190529181019190915261057b82840184611b41565b61ffff9081166040850152166020830152815292915050565b8051515f036105d55760405163d096ee8f60e01b81526020600482015260076024820152663b32b939b4b7b760c91b60448201526064015b60405180910390fd5b8060200151515f036106145760405163d096ee8f60e01b815260206004820152600760248201526670726f66696c6560c81b60448201526064016105cc565b8060400151515f0361065b5760405163d096ee8f60e01b815260206004820152600f60248201526e1cda59db985d1d5c99519bdc9b585d608a1b60448201526064016105cc565b604080518082018252600b81526a1c0c8d4d97dc97dcd7cd8d60aa1b6020918201529082015180519101207f1e3354a422078e975eb25e06aae069a209a2fd820017b91689ffaa65102b69d2146106cb57806040015160405163085ec74b60e11b81526004016105cc9190611b9a565b806060015160200151515f036107245760405163d096ee8f60e01b815260206004820152601860248201527f7472757374416e63686f722e7a6f6e654e616d6557697265000000000000000060448201526064016105cc565b608081015151515f0361076f5760405163d096ee8f60e01b81526020600482015260126024820152717175657374696f6e2e716e616d655769726560701b60448201526064016105cc565b60a081015151515f036107b35760405163d096ee8f60e01b815260206004820152600b60248201526a74696d652e706f6c69637960a81b60448201526064016105cc565b6107e48160c001516040518060400160405280600b81526020016a323739b5b2bca83937b7b360a91b815250610e70565b6108158160e001516040518060400160405280600b81526020016a30b739bbb2b9283937b7b360a91b815250610e70565b50565b61084360405180608001604052805f81526020015f81526020015f61ffff1681526020015f81525090565b60408051808201909152600f81526e70696e6e65645f7a6f6e655f6b736b60881b602091820152825180519101207fcb4a3c0966fa452790be050c7dece1a63eeb8df882f5fc6e87f73005b44d273b146108df5760405162461bcd60e51b815260206004820152601d60248201527f756e737570706f7274656420747275737420616e63686f72206d6f646500000060448201526064016105cc565b6108ec8260200151610f66565b9050816040015161ffff16816040015161ffff16146109405760405162461bcd60e51b815260206004820152601060248201526f0d6caf240e8c2ce40dad2e6dac2e8c6d60831b60448201526064016105cc565b816060015160ff16600d146109975760405162461bcd60e51b815260206004820152601c60248201527f747275737420616e63686f72206d75737420626520416c676f2031330000000060448201526064016105cc565b919050565b6109a4611003565b8160c00151606001516020015160ff16600d14610a035760405162461bcd60e51b815260206004820152601c60248201527f444e534b455920727273696720616c676f206d7573742062652031330000000060448201526064016105cc565b8160c00151608001516040015160ff16600d14610a5b5760405162461bcd60e51b8152602060048201526016602482015275444e534b4559206d75737420626520616c676f20313360501b60448201526064016105cc565b80516020808301516040515f93610a7e9390929101918252602082015260400190565b60408051601f198184030181528282525f805460c088015193840151606090940151610100015163de8f50a160e01b865292955090936001600160a01b039091169263de8f50a192610ad69287929190600401611bac565b602060405180830381865afa158015610af1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b159190611bee565b905080610b4e5760405163151a7bff60e11b8152602060048201526006602482015265646e736b657960d01b60448201526064016105cc565b50505050565b610b5c611003565b8060e00151606001516020015160ff16600d14610bbb5760405162461bcd60e51b815260206004820152601c60248201527f616e7377657220727273696720616c676f206d7573742062652031330000000060448201526064016105cc565b8060e00151608001516040015160ff16600d14610c135760405162461bcd60e51b8152602060048201526016602482015275444e534b4559206d75737420626520616c676f20313360501b60448201526064016105cc565b8060e00151608001516060015151604014610c705760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420646e736b6579206b6579206c656e6774680000000000000060448201526064016105cc565b5f805460e0830151608081015160609081015160408084015192909301516101000151925163de8f50a160e01b81526001600160a01b039094169363de8f50a193610cbe9391600401611bac565b602060405180830381865afa158015610cd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611bee565b905080610d365760405163151a7bff60e11b815260206004820152600660248201526530b739bbb2b960d11b60448201526064016105cc565b5050565b60a081015160c0820151606001514291610d54918361102d565b610d368260a001518360e00151606001518361102d565b806040015161ffff16600114610dc35760405162461bcd60e51b815260206004820152601760248201527f6f6e6c7920494e20636c61737320737570706f7274656400000000000000000060448201526064016105cc565b806020015161ffff168260e00151606001515f015161ffff1614610e1a5760405162461bcd60e51b815260206004820152600e60248201526d0e2e8f2e0ca40dad2e6dac2e8c6d60931b60448201526064016105cc565b8051805160209182012060e084015151805192019190912014610d365760405162461bcd60e51b815260206004820152600e60248201526d0e2dcc2daca40dad2e6dac2e8c6d60931b60448201526064016105cc565b8151515f03610e94578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160600151610100015151604014610ec1578060405163083cd6ab60e41b81526004016105cc9190611b9a565b816060015160e00151515f03610eec578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160200151515f03610f13578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160400151515f03610f3a578060405163083cd6ab60e41b81526004016105cc9190611b9a565b81608001516060015151604014610d36578060405163083cd6ab60e41b81526004016105cc9190611b9a565b610f9160405180608001604052805f81526020015f81526020015f61ffff1681526020015f81525090565b600182604051610fa19190611c09565b90815260408051918290036020908101832060808401835280548452600181015491840191909152600281015461ffff169183018290526003015460608301529091505f0361099757604051636e1ef7bf60e01b815260040160405180910390fd5b5f546001600160a01b031661102b576040516337abcd1d60e01b815260040160405180910390fd5b565b604083015160608401511561109d576110468183611c1f565b6001600160401b03168360a0015163ffffffff16111561109d5760405162461bcd60e51b8152602060048201526012602482015271696e63657074696f6e20746f6f206c61746560701b60448201526064016105cc565b836080015115610b4e5780836080015163ffffffff166110bd9190611c1f565b6001600160401b0316826001600160401b03161115610b4e5760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b60448201526064016105cc565b60405180610100016040528060608152602001606081526020016060815260200161116d6040518060a0016040528060608152602001606081526020015f61ffff1681526020015f60ff1681526020015f61ffff1681525090565b815260408051606080820183528082525f602080840182905283850182905280860193909352835160a081018552828152928301819052828401819052828201819052608083015291830152016111c26111d4565b81526020016111cf6111d4565b905290565b6040518060a0016040528060608152602001606081526020016060815260200161125c6040518061012001604052805f61ffff1681526020015f60ff1681526020015f60ff1681526020015f63ffffffff1681526020015f63ffffffff1681526020015f63ffffffff1681526020015f61ffff16815260200160608152602001606081525090565b8152604080516080810182525f80825260208281018290529282015260608082015291015290565b6001600160a01b0381168114610815575f80fd5b5f602082840312156112a8575f80fd5b81356112b381611284565b9392505050565b5f8083601f8401126112ca575f80fd5b5081356001600160401b038111156112e0575f80fd5b6020830191508360208285010111156112f7575f80fd5b9250929050565b803561ffff81168114610997575f80fd5b5f805f805f60808688031215611323575f80fd5b85356001600160401b03811115611338575f80fd5b611344888289016112ba565b9096509450506020860135925060408601359150611364606087016112fe565b90509295509295909350565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b03811182821017156113a6576113a6611370565b60405290565b60405161012081016001600160401b03811182821017156113a6576113a6611370565b5f82601f8301126113de575f80fd5b81356001600160401b038111156113f7576113f7611370565b604051601f8201601f19908116603f011681016001600160401b038111828210171561142557611425611370565b60405281815283820160200185101561143c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215611468575f80fd5b81356001600160401b0381111561147d575f80fd5b611489848285016113cf565b949350505050565b5f80602083850312156114a2575f80fd5b82356001600160401b038111156114b7575f80fd5b6114c3858286016112ba565b90969095509350505050565b5f805f80604085870312156114e2575f80fd5b84356001600160401b038111156114f7575f80fd5b611503878288016112ba565b90955093505060208501356001600160401b03811115611521575f80fd5b61152d878288016112ba565b95989497509550505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201525f6114896040830184611539565b818382375f9101908152919050565b803560ff81168114610997575f80fd5b5f60a082840312156115b0575f80fd5b6115b8611384565b905081356001600160401b038111156115cf575f80fd5b6115db848285016113cf565b82525060208201356001600160401b038111156115f6575f80fd5b611602848285016113cf565b602083015250611614604083016112fe565b604082015261162560608301611590565b6060820152611636608083016112fe565b608082015292915050565b5f60608284031215611651575f80fd5b604051606081016001600160401b038111828210171561167357611673611370565b60405290508082356001600160401b0381111561168e575f80fd5b61169a858286016113cf565b8252506116a9602084016112fe565b60208201526116ba604084016112fe565b60408201525092915050565b80356001600160401b0381168114610997575f80fd5b8015158114610815575f80fd5b5f60a082840312156116f9575f80fd5b611701611384565b905081356001600160401b03811115611718575f80fd5b611724848285016113cf565b825250611733602083016116c6565b6020820152611744604083016116c6565b60408201526060820135611757816116dc565b60608201526080820135611636816116dc565b803563ffffffff81168114610997575f80fd5b5f610120828403121561178e575f80fd5b6117966113ac565b90506117a1826112fe565b81526117af60208301611590565b60208201526117c060408301611590565b60408201526117d16060830161176a565b60608201526117e26080830161176a565b60808201526117f360a0830161176a565b60a082015261180460c083016112fe565b60c082015260e08201356001600160401b03811115611821575f80fd5b61182d848285016113cf565b60e0830152506101008201356001600160401b0381111561184c575f80fd5b611858848285016113cf565b6101008301525092915050565b5f60808284031215611875575f80fd5b604051608081016001600160401b038111828210171561189757611897611370565b6040529050806118a6836112fe565b81526118b460208401611590565b60208201526118c560408401611590565b604082015260608301356001600160401b038111156118e2575f80fd5b6118ee858286016113cf565b6060830152505092915050565b5f60a0828403121561190b575f80fd5b611913611384565b905081356001600160401b0381111561192a575f80fd5b611936848285016113cf565b82525060208201356001600160401b03811115611951575f80fd5b61195d848285016113cf565b60208301525060408201356001600160401b0381111561197b575f80fd5b611987848285016113cf565b60408301525060608201356001600160401b038111156119a5575f80fd5b6119b18482850161177d565b60608301525060808201356001600160401b038111156119cf575f80fd5b6119db84828501611865565b60808301525092915050565b5f805f805f805f80610100898b0312156119ff575f80fd5b88356001600160401b03811115611a14575f80fd5b611a208b828c016113cf565b98505060208901356001600160401b03811115611a3b575f80fd5b611a478b828c016113cf565b97505060408901356001600160401b03811115611a62575f80fd5b611a6e8b828c016113cf565b96505060608901356001600160401b03811115611a89575f80fd5b611a958b828c016115a0565b95505060808901356001600160401b03811115611ab0575f80fd5b611abc8b828c01611641565b94505060a08901356001600160401b03811115611ad7575f80fd5b611ae38b828c016116e9565b93505060c08901356001600160401b03811115611afe575f80fd5b611b0a8b828c016118fb565b92505060e08901356001600160401b03811115611b25575f80fd5b611b318b828c016118fb565b9150509295985092959890939650565b5f805f60608486031215611b53575f80fd5b83356001600160401b03811115611b68575f80fd5b611b74868287016113cf565b935050611b83602085016112fe565b9150611b91604085016112fe565b90509250925092565b602081525f6112b36020830184611539565b606081525f611bbe6060830186611539565b8281036020840152611bd08186611539565b90508281036040840152611be48185611539565b9695505050505050565b5f60208284031215611bfe575f80fd5b81516112b3816116dc565b5f82518060208501845e5f920191825250919050565b6001600160401b038181168382160190811115611c4a57634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220a89c168aa94530c692fea6f259214c3814b2d4ce21751e025d94a047f813b4fd64736f6c634300081a0033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063e4a02f4a11610058578063e4a02f4a146100f3578063e58e620014610168578063f2fde38b1461017b578063f7e83aee1461018e575f80fd5b80631afb1354146100895780632e58ca461461009e5780638da5cb5b146100cd578063acd76e85146100e0575b5f80fd5b61009c610097366004611298565b6101af565b005b5f546100b0906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6002546100b0906001600160a01b031681565b61009c6100ee36600461130f565b610220565b61013e610101366004611458565b80516020818301810180516001808352938301929094019190912092905281549082015460028301546003909301549192909161ffff9091169084565b6040516100c49493929190938452602084019290925261ffff166040830152606082015260800190565b61009c610176366004611491565b61033e565b61009c610189366004611298565b6103e7565b6101a161019c3660046114cf565b61046c565b6040516100c4929190611567565b6002546001600160a01b031633146101d9576040516282b42960e81b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f9dfddf144470eb2821fe3daf0548360f61ec36aaad15652541696d97c6c3e0d791a250565b6002546001600160a01b0316331461024a576040516282b42960e81b815260040160405180910390fd5b5f84900361026b57604051636e1ef7bf60e01b815260040160405180910390fd5b60405180608001604052808481526020018381526020018261ffff16815260200142815250600186866040516102a2929190611581565b9081526040805160209281900383018120845181559284015160018401559083015160028301805461ffff191661ffff9092169190911790556060909201516003909101556102f49086908690611581565b6040805191829003822061ffff84168352426020840152917fa290c5c52baa6dfd5e53ab00d828105df047f6cb6890146fb13e303cf38c674d910160405180910390a25050505050565b6002546001600160a01b03163314610368576040516282b42960e81b815260040160405180910390fd5b6001828260405161037a929190611581565b9081526040519081900360200181205f8082556001820181905560028201805461ffff191690556003909101556103b49083908390611581565b604051908190038120907fd54c0ff02cddc44364d014fc0b12360c04535d619668a4599131c56646d43a4f905f90a25050565b6002546001600160a01b03163314610411576040516282b42960e81b815260040160405180910390fd5b6002546040516001600160a01b038084169216907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b5f60605f61047a87876104ef565b90505f8461048c578160800151610496565b6104968686610553565b90506104a182610594565b5f6104af8360600151610818565b90506104bb838261099c565b6104c483610b54565b6104cd83610d3a565b6104d78383610d6b565b505060e0015160200151600197909650945050505050565b6104f7611112565b5f8080808080808061050b8a8c018c6119e7565b60408051610100810182529889526020890197909752958701949094526060860192909252608085015260a084015260c083015260e08201529b9a5050505050505050505050565b604080516060808201835281525f602082018190529181019190915261057b82840184611b41565b61ffff9081166040850152166020830152815292915050565b8051515f036105d55760405163d096ee8f60e01b81526020600482015260076024820152663b32b939b4b7b760c91b60448201526064015b60405180910390fd5b8060200151515f036106145760405163d096ee8f60e01b815260206004820152600760248201526670726f66696c6560c81b60448201526064016105cc565b8060400151515f0361065b5760405163d096ee8f60e01b815260206004820152600f60248201526e1cda59db985d1d5c99519bdc9b585d608a1b60448201526064016105cc565b604080518082018252600b81526a1c0c8d4d97dc97dcd7cd8d60aa1b6020918201529082015180519101207f1e3354a422078e975eb25e06aae069a209a2fd820017b91689ffaa65102b69d2146106cb57806040015160405163085ec74b60e11b81526004016105cc9190611b9a565b806060015160200151515f036107245760405163d096ee8f60e01b815260206004820152601860248201527f7472757374416e63686f722e7a6f6e654e616d6557697265000000000000000060448201526064016105cc565b608081015151515f0361076f5760405163d096ee8f60e01b81526020600482015260126024820152717175657374696f6e2e716e616d655769726560701b60448201526064016105cc565b60a081015151515f036107b35760405163d096ee8f60e01b815260206004820152600b60248201526a74696d652e706f6c69637960a81b60448201526064016105cc565b6107e48160c001516040518060400160405280600b81526020016a323739b5b2bca83937b7b360a91b815250610e70565b6108158160e001516040518060400160405280600b81526020016a30b739bbb2b9283937b7b360a91b815250610e70565b50565b61084360405180608001604052805f81526020015f81526020015f61ffff1681526020015f81525090565b60408051808201909152600f81526e70696e6e65645f7a6f6e655f6b736b60881b602091820152825180519101207fcb4a3c0966fa452790be050c7dece1a63eeb8df882f5fc6e87f73005b44d273b146108df5760405162461bcd60e51b815260206004820152601d60248201527f756e737570706f7274656420747275737420616e63686f72206d6f646500000060448201526064016105cc565b6108ec8260200151610f66565b9050816040015161ffff16816040015161ffff16146109405760405162461bcd60e51b815260206004820152601060248201526f0d6caf240e8c2ce40dad2e6dac2e8c6d60831b60448201526064016105cc565b816060015160ff16600d146109975760405162461bcd60e51b815260206004820152601c60248201527f747275737420616e63686f72206d75737420626520416c676f2031330000000060448201526064016105cc565b919050565b6109a4611003565b8160c00151606001516020015160ff16600d14610a035760405162461bcd60e51b815260206004820152601c60248201527f444e534b455920727273696720616c676f206d7573742062652031330000000060448201526064016105cc565b8160c00151608001516040015160ff16600d14610a5b5760405162461bcd60e51b8152602060048201526016602482015275444e534b4559206d75737420626520616c676f20313360501b60448201526064016105cc565b80516020808301516040515f93610a7e9390929101918252602082015260400190565b60408051601f198184030181528282525f805460c088015193840151606090940151610100015163de8f50a160e01b865292955090936001600160a01b039091169263de8f50a192610ad69287929190600401611bac565b602060405180830381865afa158015610af1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b159190611bee565b905080610b4e5760405163151a7bff60e11b8152602060048201526006602482015265646e736b657960d01b60448201526064016105cc565b50505050565b610b5c611003565b8060e00151606001516020015160ff16600d14610bbb5760405162461bcd60e51b815260206004820152601c60248201527f616e7377657220727273696720616c676f206d7573742062652031330000000060448201526064016105cc565b8060e00151608001516040015160ff16600d14610c135760405162461bcd60e51b8152602060048201526016602482015275444e534b4559206d75737420626520616c676f20313360501b60448201526064016105cc565b8060e00151608001516060015151604014610c705760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420646e736b6579206b6579206c656e6774680000000000000060448201526064016105cc565b5f805460e0830151608081015160609081015160408084015192909301516101000151925163de8f50a160e01b81526001600160a01b039094169363de8f50a193610cbe9391600401611bac565b602060405180830381865afa158015610cd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611bee565b905080610d365760405163151a7bff60e11b815260206004820152600660248201526530b739bbb2b960d11b60448201526064016105cc565b5050565b60a081015160c0820151606001514291610d54918361102d565b610d368260a001518360e00151606001518361102d565b806040015161ffff16600114610dc35760405162461bcd60e51b815260206004820152601760248201527f6f6e6c7920494e20636c61737320737570706f7274656400000000000000000060448201526064016105cc565b806020015161ffff168260e00151606001515f015161ffff1614610e1a5760405162461bcd60e51b815260206004820152600e60248201526d0e2e8f2e0ca40dad2e6dac2e8c6d60931b60448201526064016105cc565b8051805160209182012060e084015151805192019190912014610d365760405162461bcd60e51b815260206004820152600e60248201526d0e2dcc2daca40dad2e6dac2e8c6d60931b60448201526064016105cc565b8151515f03610e94578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160600151610100015151604014610ec1578060405163083cd6ab60e41b81526004016105cc9190611b9a565b816060015160e00151515f03610eec578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160200151515f03610f13578060405163083cd6ab60e41b81526004016105cc9190611b9a565b8160400151515f03610f3a578060405163083cd6ab60e41b81526004016105cc9190611b9a565b81608001516060015151604014610d36578060405163083cd6ab60e41b81526004016105cc9190611b9a565b610f9160405180608001604052805f81526020015f81526020015f61ffff1681526020015f81525090565b600182604051610fa19190611c09565b90815260408051918290036020908101832060808401835280548452600181015491840191909152600281015461ffff169183018290526003015460608301529091505f0361099757604051636e1ef7bf60e01b815260040160405180910390fd5b5f546001600160a01b031661102b576040516337abcd1d60e01b815260040160405180910390fd5b565b604083015160608401511561109d576110468183611c1f565b6001600160401b03168360a0015163ffffffff16111561109d5760405162461bcd60e51b8152602060048201526012602482015271696e63657074696f6e20746f6f206c61746560701b60448201526064016105cc565b836080015115610b4e5780836080015163ffffffff166110bd9190611c1f565b6001600160401b0316826001600160401b03161115610b4e5760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b60448201526064016105cc565b60405180610100016040528060608152602001606081526020016060815260200161116d6040518060a0016040528060608152602001606081526020015f61ffff1681526020015f60ff1681526020015f61ffff1681525090565b815260408051606080820183528082525f602080840182905283850182905280860193909352835160a081018552828152928301819052828401819052828201819052608083015291830152016111c26111d4565b81526020016111cf6111d4565b905290565b6040518060a0016040528060608152602001606081526020016060815260200161125c6040518061012001604052805f61ffff1681526020015f60ff1681526020015f60ff1681526020015f63ffffffff1681526020015f63ffffffff1681526020015f63ffffffff1681526020015f61ffff16815260200160608152602001606081525090565b8152604080516080810182525f80825260208281018290529282015260608082015291015290565b6001600160a01b0381168114610815575f80fd5b5f602082840312156112a8575f80fd5b81356112b381611284565b9392505050565b5f8083601f8401126112ca575f80fd5b5081356001600160401b038111156112e0575f80fd5b6020830191508360208285010111156112f7575f80fd5b9250929050565b803561ffff81168114610997575f80fd5b5f805f805f60808688031215611323575f80fd5b85356001600160401b03811115611338575f80fd5b611344888289016112ba565b9096509450506020860135925060408601359150611364606087016112fe565b90509295509295909350565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b03811182821017156113a6576113a6611370565b60405290565b60405161012081016001600160401b03811182821017156113a6576113a6611370565b5f82601f8301126113de575f80fd5b81356001600160401b038111156113f7576113f7611370565b604051601f8201601f19908116603f011681016001600160401b038111828210171561142557611425611370565b60405281815283820160200185101561143c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215611468575f80fd5b81356001600160401b0381111561147d575f80fd5b611489848285016113cf565b949350505050565b5f80602083850312156114a2575f80fd5b82356001600160401b038111156114b7575f80fd5b6114c3858286016112ba565b90969095509350505050565b5f805f80604085870312156114e2575f80fd5b84356001600160401b038111156114f7575f80fd5b611503878288016112ba565b90955093505060208501356001600160401b03811115611521575f80fd5b61152d878288016112ba565b95989497509550505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201525f6114896040830184611539565b818382375f9101908152919050565b803560ff81168114610997575f80fd5b5f60a082840312156115b0575f80fd5b6115b8611384565b905081356001600160401b038111156115cf575f80fd5b6115db848285016113cf565b82525060208201356001600160401b038111156115f6575f80fd5b611602848285016113cf565b602083015250611614604083016112fe565b604082015261162560608301611590565b6060820152611636608083016112fe565b608082015292915050565b5f60608284031215611651575f80fd5b604051606081016001600160401b038111828210171561167357611673611370565b60405290508082356001600160401b0381111561168e575f80fd5b61169a858286016113cf565b8252506116a9602084016112fe565b60208201526116ba604084016112fe565b60408201525092915050565b80356001600160401b0381168114610997575f80fd5b8015158114610815575f80fd5b5f60a082840312156116f9575f80fd5b611701611384565b905081356001600160401b03811115611718575f80fd5b611724848285016113cf565b825250611733602083016116c6565b6020820152611744604083016116c6565b60408201526060820135611757816116dc565b60608201526080820135611636816116dc565b803563ffffffff81168114610997575f80fd5b5f610120828403121561178e575f80fd5b6117966113ac565b90506117a1826112fe565b81526117af60208301611590565b60208201526117c060408301611590565b60408201526117d16060830161176a565b60608201526117e26080830161176a565b60808201526117f360a0830161176a565b60a082015261180460c083016112fe565b60c082015260e08201356001600160401b03811115611821575f80fd5b61182d848285016113cf565b60e0830152506101008201356001600160401b0381111561184c575f80fd5b611858848285016113cf565b6101008301525092915050565b5f60808284031215611875575f80fd5b604051608081016001600160401b038111828210171561189757611897611370565b6040529050806118a6836112fe565b81526118b460208401611590565b60208201526118c560408401611590565b604082015260608301356001600160401b038111156118e2575f80fd5b6118ee858286016113cf565b6060830152505092915050565b5f60a0828403121561190b575f80fd5b611913611384565b905081356001600160401b0381111561192a575f80fd5b611936848285016113cf565b82525060208201356001600160401b03811115611951575f80fd5b61195d848285016113cf565b60208301525060408201356001600160401b0381111561197b575f80fd5b611987848285016113cf565b60408301525060608201356001600160401b038111156119a5575f80fd5b6119b18482850161177d565b60608301525060808201356001600160401b038111156119cf575f80fd5b6119db84828501611865565b60808301525092915050565b5f805f805f805f80610100898b0312156119ff575f80fd5b88356001600160401b03811115611a14575f80fd5b611a208b828c016113cf565b98505060208901356001600160401b03811115611a3b575f80fd5b611a478b828c016113cf565b97505060408901356001600160401b03811115611a62575f80fd5b611a6e8b828c016113cf565b96505060608901356001600160401b03811115611a89575f80fd5b611a958b828c016115a0565b95505060808901356001600160401b03811115611ab0575f80fd5b611abc8b828c01611641565b94505060a08901356001600160401b03811115611ad7575f80fd5b611ae38b828c016116e9565b93505060c08901356001600160401b03811115611afe575f80fd5b611b0a8b828c016118fb565b92505060e08901356001600160401b03811115611b25575f80fd5b611b318b828c016118fb565b9150509295985092959890939650565b5f805f60608486031215611b53575f80fd5b83356001600160401b03811115611b68575f80fd5b611b74868287016113cf565b935050611b83602085016112fe565b9150611b91604085016112fe565b90509250925092565b602081525f6112b36020830184611539565b606081525f611bbe6060830186611539565b8281036020840152611bd08186611539565b90508281036040840152611be48185611539565b9695505050505050565b5f60208284031215611bfe575f80fd5b81516112b3816116dc565b5f82518060208501845e5f920191825250919050565b6001600160401b038181168382160190811115611c4a57634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220a89c168aa94530c692fea6f259214c3814b2d4ce21751e025d94a047f813b4fd64736f6c634300081a0033
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.