Example: Verify Simple Event

Here is an example of simple receipt proof verification. Source code on GitHub.
On the source chain, anyone can submit a transaction to emit a SendNumber event with the sender address and the provided number.
contract PostNumber {
event SendNumber(address from, uint256 number);
function sendNumber(uint256 number) external {
emit SendNumber(msg.sender, number);
On the destination chain, one can submit the ZK proof (generated by the Brevis proofing system) of the source chain event to the verifier contract to validate and decode the event info.
contract VerifyNumberEvent {
IReceiptVerifier public receiptVerifier;
mapping(uint64 => address) public srcContract;
bytes32 constant eventTopic = keccak256(bytes("SendNumber(address,uint256)"));
event VerifiedNumber(uint64 blknum, address from, uint256 number);
IReceiptVerifier _receiptVerifier,
uint64 _senderChainId,
address _senderContract
) {
receiptVerifier = _receiptVerifier;
srcContract[_senderChainId] = _senderContract;
function submitNumberReceiptProof(
bytes calldata _receipt,
bytes calldata _proof,
bytes calldata _auxiBlkVerifyInfo
) external {
// retrieve verified event
IReceiptVerifier.ReceiptInfo memory receiptInfo = receiptVerifier
.verifyReceipt(_receipt, _proof, _auxiBlkVerifyInfo);
IReceiptVerifier.LogInfo memory log = receiptInfo.logs[0];
// compare expected and verified values
require(receiptInfo.success, "tx failed");
require(log.addr == srcContract[receiptInfo.chainId], "invalid src contract");
require(log.topics[0] == eventTopic, "invalid event");
// decode event data
address from = address(bytes20(BytesLib.slice(, 12, 20)));
uint256 number = uint256(bytes32(BytesLib.slice(, 32, 32)));
emit VerifiedNumber(receiptInfo.blkNum, from, number);