Query and Submit evidence of validator misbehavior (equivocation)
x/evidence
module.
Precompile Address: 0x0000000000000000000000000000000000000807
Related Module: x/evidence
submitEvidence
evidence
import { ethers } from "ethers";
// ABI for the precompile
const precompileAbi = [
"function evidence(bytes32 evidenceHash) view returns (tuple(int64 height, int64 time, int64 power, string consensusAddress) evidence)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000807";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input: The hash of the evidence to query
const evidenceHash = "0x..."; // Placeholder for a 32-byte hash
async function getEvidence() {
try {
const ev = await contract.evidence(evidenceHash);
console.log("Evidence:", JSON.stringify(ev, null, 2));
} catch (error) {
console.error("Error fetching evidence:", error);
}
}
getEvidence();
getAllEvidence
import { ethers } from "ethers";
// ABI for the precompile
const precompileAbi = [
"function getAllEvidence(tuple(bytes key, uint64 offset, uint64 limit, bool count_total, bool reverse) pageRequest) view returns (tuple(int64 height, int64 time, int64 power, string consensusAddress)[] evidence, tuple(bytes next_key, uint64 total) page_response)"
];
// Provider and contract setup
const provider = new ethers.JsonRpcProvider("<RPC_URL>");
const precompileAddress = "0x0000000000000000000000000000000000000807";
const contract = new ethers.Contract(precompileAddress, precompileAbi, provider);
// Input for pagination
const pagination = {
key: "0x",
offset: 0,
limit: 10,
count_total: true,
reverse: false,
};
async function getAllEvidences() {
try {
const result = await contract.getAllEvidence(pagination);
console.log("All Evidence:", JSON.stringify(result.evidence, null, 2));
console.log("Pagination Response:", result.page_response);
} catch (error) {
console.error("Error fetching all evidence:", error);
}
}
getAllEvidences();
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.18;
import "../common/Types.sol";
/// @dev The IEvidence contract's address.
address constant EVIDENCE_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000807;
/// @dev The IEvidence contract's instance.
IEvidence constant EVIDENCE_CONTRACT = IEvidence(EVIDENCE_PRECOMPILE_ADDRESS);
/// @dev The Equivocation struct contains information about a validator's equivocation
struct Equivocation {
// height is the equivocation height
int64 height;
// time is the equivocation time
int64 time;
// power is the validator's power at the time of the equivocation
int64 power;
// consensusAddress is the validator's consensus address
string consensusAddress;
}
/// @author The Evmos Core Team
/// @title Evidence Precompile Contract
/// @dev The interface through which solidity contracts will interact with the x/evidence module
interface IEvidence {
/// @dev Event emitted when evidence is submitted
/// @param submitter The address of the submitter
/// @param hash The hash of the submitted evidence
event SubmitEvidence(address indexed submitter, bytes hash);
/// @dev Submit evidence of misbehavior (equivocation)
/// @param evidence The evidence of misbehavior
/// @return success True if the evidence was submitted successfully
function submitEvidence(Equivocation calldata evidence) external returns (bool success);
/// @dev Query evidence by hash
/// @param evidenceHash The hash of the evidence to query
/// @return evidence The equivocation evidence data
function evidence(bytes memory evidenceHash) external view returns (Equivocation memory evidence);
/// @dev Query all evidence with pagination
/// @param pageRequest Pagination request
/// @return evidence List of equivocation evidence
/// @return pageResponse Pagination response
function getAllEvidence(PageRequest calldata pageRequest)
external
view
returns (Equivocation[] memory evidence, PageResponse memory pageResponse);
}
{
"_format": "hh-sol-artifact-1",
"contractName": "IEvidence",
"sourceName": "solidity/precompiles/evidence/IEvidence.sol",
"abi": [
{ "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "submitter", "type": "address" }, { "indexed": false, "internalType": "bytes", "name": "hash", "type": "bytes" } ], "name": "SubmitEvidence", "type": "event" },
{ "inputs": [ { "internalType": "bytes", "name": "evidenceHash", "type": "bytes" } ], "name": "evidence", "outputs": [ { "components": [ { "internalType": "int64", "name": "height", "type": "int64" }, { "internalType": "int64", "name": "time", "type": "int64" }, { "internalType": "int64", "name": "power", "type": "int64" }, { "internalType": "string", "name": "consensusAddress", "type": "string" } ], "internalType": "struct Equivocation", "name": "evidence", "type": "tuple" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "components": [ { "internalType": "bytes", "name": "key", "type": "bytes" }, { "internalType": "uint64", "name": "offset", "type": "uint64" }, { "internalType": "uint64", "name": "limit", "type": "uint64" }, { "internalType": "bool", "name": "countTotal", "type": "bool" }, { "internalType": "bool", "name": "reverse", "type": "bool" } ], "internalType": "struct PageRequest", "name": "pageRequest", "type": "tuple" } ], "name": "getAllEvidence", "outputs": [ { "components": [ { "internalType": "int64", "name": "height", "type": "int64" }, { "internalType": "int64", "name": "time", "type": "int64" }, { "internalType": "int64", "name": "power", "type": "int64" }, { "internalType": "string", "name": "consensusAddress", "type": "string" } ], "internalType": "struct Equivocation[]", "name": "evidence", "type": "tuple[]" }, { "components": [ { "internalType": "bytes", "name": "nextKey", "type": "bytes" }, { "internalType": "uint64", "name": "total", "type": "uint64" } ], "internalType": "struct PageResponse", "name": "pageResponse", "type": "tuple" } ], "stateMutability": "view", "type": "function" },
{ "inputs": [ { "components": [ { "internalType": "int64", "name": "height", "type": "int64" }, { "internalType": "int64", "name": "time", "type": "int64" }, { "internalType": "int64", "name": "power", "type": "int64" }, { "internalType": "string", "name": "consensusAddress", "type": "string" } ], "internalType": "struct Equivocation", "name": "evidence", "type": "tuple" } ], "name": "submitEvidence", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }
]
}
Was this page helpful?