Example: Verify Simple TX

Here is an example of simple transaction proof verification. Source code on GitHub.
On the source chain, anyone can submit a sendNumber transaction to the contract.
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 transaction to the verifier contract to validate and decode the transaction info.
contract VerifyNumberTx {
ITxVerifier public txVerifier;
mapping(uint64 => address) public srcContract;
bytes4 constant funcSelector = bytes4(keccak256(bytes("sendNumber(uint256)")));
event VerifiedNumber(uint64 blknum, address from, uint256 number);
ITxVerifier _txVerifier,
uint64 _senderChainId,
address _senderContract
) {
txVerifier = _txVerifier;
srcContract[_senderChainId] = _senderContract;
function submitNumberTxProof(
bytes calldata _tx,
bytes calldata _proof,
bytes calldata _auxiBlkVerifyInfo
) external {
ITxVerifier.TxInfo memory txInfo = txVerifier.verifyTx(
require( == srcContract[txInfo.chainId], "invalid source contract");
uint256 number = decodeCalldata(;
emit VerifiedNumber(txInfo.chainId, txInfo.blkNum, txInfo.from, number);
function decodeCalldata(
bytes memory _data
) private pure returns (uint256 number) {
bytes4 method;
assembly {
method := mload(add(_data, 32))
require(method == funcSelector, "wrong method");
bytes memory argdata = BytesLib.slice(_data, 4, _data.length - 4);
number = abi.decode(argdata, (uint256));