Comment on page

EVM Verifiable Randomness Tutorial

Learn how to use Secret VRF to send verifiable random numbers to EVM-compatible chains with Axelar GMP

Ethereum 🤝 SecretRNG

The ability to generate fair and verifiable random numbers on blockchain without compromising security or usability is critical for many decentralized applications. There have been attempts to solve this problem by various methods, such as using random data from external sources (the hash of a previous block, etc) or by using off-chain solutions, such as Chainlink’s VRF oracle, but these solutions are not optimal as they are either deterministic, rely on trusted parties, and/or require additional fees for gas and infrastructure. What is needed is a verifiable random number generator that exists on-chain, and is accessible across developer ecosystems, and this is now possible through the use of Secret Network Random Number Generator (RNG) + Axelar GMP.
In this tutorial, you will learn how to use Axelar GMP to send an array of verifiable random numbers from Secret to Polygon. Let's get started!


See here for prerequisites to follow along with this tutorial.

Upload ReceiveRandom.sol Contract to Polygon

In order to receive random numbers from a smart contract on Secret network, you must first upload and instantiate a smart contract on Polygon that can execute messages using Axelar GMP. We will be uploading the ReceiveRandom.sol contract to Polygon for this demo, which is designed to receive an array of bytes.
To upload the contract, we will use Remix Online IDE, which is a powerful toolset for developing, deploying, debugging, and testing Ethereum and EVM-compatible smart contracts.
First, navigate to Remix and create a new blank workspace:
Remix workspace
Next, create a new file called ReceiveRandom.sol and paste the solidity code. This will autofill your workspace with the necessary dependencies for your ReceiveRandom.sol contract 🤯
Now all that's left is to compile and upload the contract. Navigate to the Solidity compiler using the sidebar and click "Compile ReceiveRandom.sol". Then, navigate to "Deploy and run transactions." Toggle the Environment from "Remix VM (Shanghai)" to "Injected Provider - MetaMask" and make sure that in your MetaMask wallet you have currently selected Polygon testnet Mumbai network.
The constructor of ReceiveRandom.sol contains 3 variables that you must now input in order to instantiate the contract and link it to Axelar's Polygon gateway contract and gas receiver contract, as well as the Polygon chain name:
GATEWAY CONTRACT: "0xBF62ef1486468a6bd26Dd669C06db43dEd5B849B"
GASRECEIVER CONTRACT: "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6"
CHAINNAME: "Polygon"
Input these strings like so and then click "Transact":
ReceiveRandom.soll constructor
Upon successful instantiation, the contract address will be returned in the Remix terminal, which you can then view on Polygonscan. And the deployed contract can now be interacted with in the "Deployed Contracts" window:
Congrats, you've just deployed an Axelar GMP-compatible contract to Polygon testnet that can receive verifiable random numbers from a Secret Network smart contract 🎉

Upload a contract to Secret Network

Now that you've uploaded a GMP-compatible contract to Polygon, let's do the same on Secret Network so that the contracts can communicate with each other across the Cosmos!
First, clone this Secret Network examples repository:
git clone
Then, cd into the examples/EVM-GMP-RNG/secret_network/ folder
cd examples/EVM-GMP-RNG/secret_network/
and compile the contract by running make build-mainnet in your terminal.
make build-mainnet
If this is your first time working with a Secret contract, visit the Getting Started docs to properly configure your developer environment.
Now, cd into examples/EVM-GMP-RNG/secret_network/node
cd examples/EVM-GMP-RNG/secret_network/node
and then run npm install to install the package.json dependencies.
npm install
Create a .env file in examples/EVM-GMP-RNG/secret_network/node and add your wallet mnemonic in order to upload the contract:
.env config
You can then upload and instantiate the contract by running node index.js.
node index.js
Upon successful instantiation, a Secret contract address is returned that you can then use to send messages to Polygon:
Secret contract address upon successful instantation
Now let's execute the Secret RNG contract and send a random number to Polygon! 🚀

Send a Random Number from Secret to Polygon

To execute the SendMessageEvm transaction, which sends an array of random numbers from Secret Network to Polygon, navigate to the execute.js file in examples/EVM-GMP-RNG/secret_network/node and replace the contractAdress and contractCodeHash with your contract address and code hash, respectively.
cd examples/EVM-GMP-RNG/secret_network/node
Then, update destinationAddress to your Polygon contract address:
Next, in order to send a GMP message from Secret to Polygon, you need to include the correct IBC denom to pay for gas so that the message can be executed over IBC.
Learn how to get the correct AXL/Secret IBC denom here.
Once you have properly configured your execute.js file and procured the IBC denom needed to execute the transaction, all that's left is to run node execute.
node execute
The transaction should return a transactionHash as well as data about the IBC routing:
send_message_evm() transaction
And for good measure, view the transaction on Polygonscan to see that the array of random numbers was received!

Query the random number on Polygon and Secret

Now that you've successfully executed a cross-chain message from Secret to Polygon using Axelar GMP, let's query the message on Secret and Polygon.
Let's start by querying the array of random numbers now stored in the Secret contract to see if it matches the array of random numbers sent to the Polygon contract. Once the transaction has been executed successfully, you can use Secret.js to query the message:
// Query the contract for the stored message sent from Polygon
let get_stored_message = async () => {
let query = await secretjs.query.compute.queryContract({
contract_address: contractAddress,
query: {
get_stored_random: {},
code_hash: contractCodeHash,
To execute this query, navigate to the query.js file in examples/EVM-GMP-RNG/secret_network/node and replace the contractAdress and contractCodeHash with your contract address and code hash, respectively.
Then run node query.
node query
If the message was executed successfully, the query will return the array of random numbers:
random_bytes: [
43, 135, 165, 34, 220, 232, 231, 129,
32, 162, 83, 78, 74, 51, 90, 171,
10, 181, 184, 201, 246, 184, 175, 82,
248, 225, 111, 116, 36, 96, 114, 243
Great work! Now let's query the Polygon contract to see if the random numbers match!
To execute this query, cd into examples/EVM-GMP-RNG/polygon:
cd examples/EVM-GMP-RNG/polygon
Install the package.json dependencies:
npm install
Create a .env file in examples/EVM-GMP-RNG/polygon and add your Polygon testnet Infura API key and your Metamask private wallet key
Open ./scripts/queryRandom.js and replace the contractAddress with your Polygon contract address:
const contractAddress = "0x4396a9F3b1962bC7277fC44a78AA5c57e8966978";
Then execute the query by running npx hardhat run --network polygon ./scripts/queryRandom.js
npx hardhat run --network polygon ./scripts/queryRandom.js
Congrats! 🎉 The query should return an array of random numbers which matches the random numbers stored in the Secret Contract:
random integers: [
43, 135, 165, 34, 220, 232, 231, 129,
32, 162, 83, 78, 74, 51, 90, 171,
10, 181, 184, 201, 246, 184, 175, 82,
248, 225, 111, 116, 36, 96, 114, 243


This documentation has guided you through the process of deploying GMP-compatible contracts on both Polygon and Secret Network, illustrating how to send random numbers from Secret to Polygon. By following these steps, you have unlocked the potential for seamless interoperability and enhanced functionality in your blockchain applications.
If you run into any errors or questions, ping the #dev-issues channel on Secret Network's Discord and somebody will get back to you shortly 😊
Last modified 12d ago