General Message Passing with Amplifier Example

This example shows the execution of a GMP call from the Ethereum Sepolia to the Avalanche Fuji testnets.

Prerequisites

You will need:

Helpful references

Send a GMP call between two chains

Execute the contract call on the source chain

Use callContract() to execute the contract call on Ethereum Sepolia, then locate the ContractCall event in the transaction details on QPscan, which should look something like this. Note the transaction hash and log index.

Verify messages at the source chain gateway

Once the transaction is finalized on the source chain, call verify_messages() at the source chain’s QPGateway:

QPd tx wasm execute QP18csycs4vm6varkp00apuqlsm7v4twg8jsljk8wfdd7cghr7g4rtsltrlkp '{"verify_messages":[{"cc_id":{"chain":"ethereum-sepolia","id":"0xeafbc1283699c49ba4f79ec43d8749f
d82ca4ee14c236787dd25a2f7d4932daa-60"},"destination_chain":"avalanche","destination_address":"0x79a35Fd62DbAa820D3025B3400eBcE17Cdd6C587","source_address":"0xA4f10f76B86E01B98daF66A3d02a65e14
adb0767","payload_hash":"64b8427717b2ce8573a0c37e03e30ec683c2fe57dcee4d426d22cf43c7692675"}]}' --from validator --gas auto --gas-adjustment 1.5

Wait for verification, which usually takes 1-3 blocks. Then call route_messages():

QPd tx wasm execute QP18csycs4vm6varkp00apuqlsm7v4twg8jsljk8wfdd7cghr7g4rtsltrlkp '{"route_messages":[{"cc_id":{"chain":"ethereum-sepolia","id":"0xeafbc1283699c49ba4f79ec43d8749fd
82ca4ee14c236787dd25a2f7d4932daa-60"},"destination_chain":"avalanche","destination_address":"0x79a35Fd62DbAa820D3025B3400eBcE17Cdd6C587","source_address":"0xA4f10f76B86E01B98daF66A3d02a65e14a
db0767","payload_hash":"64b8427717b2ce8573a0c37e03e30ec683c2fe57dcee4d426d22cf43c7692675"}]}' --from validator --gas auto --gas-adjustment 1.5

Call construct_proof() at the multisig-prover corresponding to the destination chain:

QPd tx wasm execute QP1qum2tr7hh4y7ruzew68c64myjec0dq2s2njf6waja5t0w879lutqv062tl '{"construct_proof":{"message_ids":[{"chain":"ethereum-sepolia","id":"0xeafbc1283699c49ba4f79ec43
d8749fd82ca4ee14c236787dd25a2f7d4932daa-60"}]}}' --from validator --gas auto --gas-adjustment 1.5

Note the multisig_session_id in the output:

{\"key\":\"multisig_session_id\",\"value\":\"1\"}

Retrieve the signed batch of messages

Wait for signing to complete, which usually takes 1-3 blocks. Then call get_proof():

QPd q wasm contract-state smart QP1qum2tr7hh4y7ruzew68c64myjec0dq2s2njf6waja5t0w879lutqv062tl '{"get_proof":{"multisig_session_id":"1"}}'

The output should look something like this:

data:
  data:
    commands:
    - id: c767e0ff9bcfcfa11d5346095b2c969fedb1c4a87bbf9fd0cb82578eda6fecc2
      params: 00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000079a35fd62dbaa820d3025b3400ebce17cdd6c58764b8427717b2ce8573a0c37e03e30ec683c2fe57dcee4d426d22cf43c769267500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010657468657265756d2d7365706f6c696100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30784134663130663736423836453031423938646146363641336430326136356531346164623037363700000000000000000000000000000000000000000000
      ty: approve_contract_call
    destination_chain_id: "43113"
  message_ids:
  - chain: ethereum-sepolia
    id: 0xeafbc1283699c49ba4f79ec43d8749fd82ca4ee14c236787dd25a2f7d4932daa-60
  multisig_session_id: "1"
  status:
    completed:
      execute_data: 09c5eabe000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000a869000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001c767e0ff9bcfcfa11d5346095b2c969fedb1c4a87bbf9fd0cb82578eda6fecc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000013617070726f7665436f6e747261637443616c6c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000079a35fd62dbaa820d3025b3400ebce17cdd6c58764b8427717b2ce8573a0c37e03e30ec683c2fe57dcee4d426d22cf43c769267500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010657468657265756d2d7365706f6c696100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307841346631306637364238364530314239386461463636413364303261363565313461646230373637000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000030000000000000000000000008054f16ad10c3bf57e178f7f9bc45ea89f84301a00000000000000000000000089a73afebb411c865074251e036d4c12eb99b7ba000000000000000000000000f330a7f2a738eefd5cf1a33211cd131a7e92fdd400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000415b0df0a1859262dbe806ba916432a688dddf8b31e82138d94d7a4d29ffd04a6f136d6286f02d337ca5632f0c739a4fea909b68c7fee60143bde385cb7c0623f61c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f5fb2289f995a4ec662cf4b83396ae3beaf004af77e9c60083637cd9596b28b30bf17949473dc6f2bb063bcba9e09ae9b267bb543b852fe43fa5fae6c01f81811b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004123d2d5f8f86b7f568f2503cb156e184c3a96d48c0b3ab8f096f83d31a4a03b057e7ef8b0ac0e36eef8354e0b0acab8475ac6f1801571e82c45ff8eeeaf1a0f9c1c00000000000000000000000000000000000000000000000000000000000000

Relay the execute data to the destination chain gateway

The execute data can be relayed to the destination chain’s QPGateway in a number of ways. Here’s how to do it with node.js using ethers:

> await wallet.sendTransaction({to: gatewayAddress, data: "0x"+executeData, gasLimit:ethers.BigNumber.from(5e+06)}).then((tx) => tx.wait())

Execute the contract

Fill in the appropriate values and execute the contract. The command_id can be found in the response to the get_proof query:

> await contract.execute(ethers.utils.arrayify(command_id),source_chain, source_address, ethers.utils.arrayify(payload)).then((tx) => tx.wait()
Edit this page