Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Learn how to use SecretPath on EVM to encrypt payloads.
SecretPath seamlessly handles encrypted payloads on the EVM, which means EVM developers can use SecretPath to encrypt and decrypt messages cross-chain with little-to-no Rust experience required.
This tutorial explains how to upload your own Key-value store contract on Secret Network, which you can use to encrypt values on the EVM, as well as how to encrypt payloads and transmit them cross-chain. After this tutorial, you will have the tools you need to use SecretPath to encrypt messages on any EVM-compatible chain.
To get started, clone the SecretPath tutorials repository:
cd
into encrypted-payloads/evm-contract
Install the dependencies:
Create an env
file and add your:
EVM wallet private key
Infura API endpoint (Sepolia testnet)
See here for a properly configured example env file
Get sepolia tokens from faucet:
This tutorial is for Sepolia testnet, but there are 10+ chains currently configured that are also compatible by simply swapping out the SecretPath gateway address.
Now that your developer environment is properly configured, you're ready to encrypt your first payload with SecretPath!
cd
into encrypted-payloads/secret-contract
Compile the Secret Network key value store contract:
cd
into secret-contract/node
Install the dependencies:
Open the upload.js file and review the instantiate message at line 70:
gatewayAddress is the SecretPath gateway contract address for testnet
gatewayHash is the SecretPath gateway contract hash for testnet
gatewayKey is public key used for SecretPath encryption on Secret testnet
These three parameters remain constant and must be passed for every Secret Network contract that implements SecretPath. They can be found here for testnet.
To upload and instantiate the contract, run node upload
:
Upon successful upload, a contractHash
and address
will be returned:
Now that you have your key value store smart contract uploaded on Secret Network, let's use it to store encrypted messages. Most of the ECDH cryptography has been abstracted away so there are only a few values you need to change.
cd
into encrypted-payloads/evm-contract:
Open encrypt.js
in evm-contract/scripts and navigate to lines 43-49.
Update the routing_contract
and routing_code_hash
to the contract address and codehash
of the Secret Network smart contract that you instantiated:
publicClientAddress
is the gateway contract address for Sepolia, which is found in Secret's gateway contract docs here.
Next, update lines 73-77 with the EVM wallet address associated with the private key in your env file (myAddress)
, a key (any string
of your choosing), a value, (any string
of your choosing), and a viewing_key (any string
of your choosing).
value
is the the data that you want to encrypt, key
and viewing_key
are parameters you pass to encrypt the value.
Next, you are going to set the handle
variable to call the store_value
function inside of the Secret contract that you instantiated earlier. You do this with line 80, which corresponds to the store_value
function in the Secret contract:
Once you have decided upon these parameters, simply run encrypt.js:
Upon successful encryption, your payload hash will be returned:
Congrats, you have encrypted your first cross-chain payload with SecretPath!
To decrypt your encrypted payload, cd
into secret-contract/node
Open decrypt.js and update lines 8-9 with your key
and viewing-key:
Then run node decrypt:
Your decrypted payload will be returned:
Congrats! You have now used SecretPath to encrypt and decrypt cross-chain payloads! 🔥
SecretPath is a powerful addition to Secret Network’s cross-chain messaging capabilities. Along with IBC and Axelar GMP, and eventually to be joined by additional bridging technologies like Wormhole and Union, it enables groundbreaking new use-cases for Web3 applications by providing access to confidential computation. This facilitates novel applications such as private voting for DAOs, secure random number generation, confidential data access control via NFTs, encrypted DeFi order books, sealed-bid auctions, and storing encrypted data.
We also encourage developers to check out our grants program to get funding for building with SecretPath, and to join our Discord and Telegram to get involved with our community. You can also contact our team directly if you have any questions about building on Secret.
One of SecretPath's key features is the ability to use encrypted payloads to send over confidential messages to a Secret Smart contract.
SecretPath can seamlessly handle encrypted payloads, as the master gateway contract on Secret automatically decrypts the payload and hands the decrypted payload over to the target contract.
An extra encryption public key provided from the Secret Gateway Contract
A randomly created (ephemeral) encryption private key on the user side (independent of the user wallet's private key)
Combining both of these keys together via the ECDH Scheme yields our encryption key, which we use to encrypt the payload with ChaCha20-Poly1305.
As a first example for this, we have used SecretPath to encrypt a string
and subsequently store it in a Secret contract.
Contract Deployment: Participants initiate the process by deploying a Sealed Bid Contract to the Secret Network. This contract contains their auction items and encrypted bids, safeguarding the bid details from public exposure.
Contract Execution via Public Gateway:
The execution sequence begins when the Sealed Bid Contract is interacted with via the Ethereum Virtual Machine (EVM).
The SecretPath Public Gateway Smart Contract serves as the intermediary, facilitating communication between the EVM and Secret Network.
Secure Message Transmission:
Messages and transactions pass through the Public Gateway to the Private Gateway Smart Contract, utilizing ECDH to ensure that the data exchanged remains confidential and tamper-proof, maintaining the integrity of the sealed bid throughout the process.
Finalization:
Once the bidding period concludes, the Sealed Bid Contract processes the bids to determine the winner securely.
The outcome is then communicated back through the gateway contracts to the relevant parties on the EVM.
The encryption of the payload is done using the , an algorithm.
The key for this symmetric encryption is created by using the (ECDH) scheme, comprising of two components:
A first-price sealed-bid auction, also known as a "blind auction", is a type of auction in which all bidders simultaneously submit sealed bids so that no bidder knows the bid of any other participant. The highest bidder pays the price that was submitted. In this tutorial you will learn how to create a cross-chain sealed bid auction dApp with encrypted bids using.
See a live demo !
Learn how to use Secret Network smart contracts to encrypt and decrypt votes on Polygon testnet.
Learn how to use SecretPath to vote confidentially on the EVM
NOTE: These docs are currently in progress
SecretPath enables EVM developers to use Secret Network as a Confidential Computation Layer (CCL) for all EVM-compatible chains.
In this developer tutorial, you will learn how to use SecretPath to enable confidential voting on the EVM.
See a fullstack cross-chain voting demo here.
To get started, clone the examples repo:
Got improvements or suggestions on how to improve SecretVRF or this tutorial ? Please ask in the Secret Network Telegram or Discord.
For a detailed demonstration, you can watch our video tutorial available here:
After we've gone through an extensive example on how our example contract works, here's how to implement SecretVRF via SecretPath in your own contract in 4 easy steps:
First, import the ISecretVRF
interface into your Solidity Contract:
Second, set your gateway address to the Secret VRF Gateways that you can find EVM Testnet and EVM Mainnet. You only need to make sure that your contract knows the correct SecretVRF Gateway address, for example:
Now, we implement the function that calls the SecretVRF Gateway on EVM. Note that you have to pay an extra amount of your gas token as CallbackGas:
The callback gas is the amount of gas that you have to pay for the message coming on the way back. If you do pay less than the amount specified below, your Gateway TX will fail:
Since this check is dependent on the current block.basefee
of the block it is included in, it is recommended that you estimate the gas fee beforehand and add some extra overhead to it. An example of how this can be implemented in your frontend can be found in this example and here:
From here, the SecretVRF Gateway will take care of everything, just wait 1-2 blocks for Gateway to provide you the random number by getting it from the Secret Networks on chain VRF and do the callback.
The SecretVRF gateway contract will always call the contract that called the VRF contract (using msg.sender
) with the function selector bytes 0x38ba4614
, which is the function:
Now, the SecretVRF Gateway contract will verify the validity of the call and when all checks pass, it will call this function. In this case, we just emit a log as an example to finish our demo. Emitting a log is not obligatory and optional.
SecretVRF stands out in the competitive landscape of verifiable random functions (VRFs) by offering a significant cost and speed advantage over its principal competitors. Notably, it provides approximately a 4 times cost benefit, which is a massive saving for projects that rely on random number generation at scale. This economic efficiency is largely due to its optimized gas usage, which minimizes the on-chain transaction cost.
In addition to its cost benefits, SecretVRF is also twice as fast as its closest competitor. This speed improvement is critical for applications that require almost real-time randomness, such as gaming, lotteries, and various DeFi protocols.
To demonstrate, we have this small video here outlining all of the advantages of SecretVRF vs. its biggest competitor:
An example contract call using SecretVRF on Ethereum Sepolia which requests 20 random words is compared for its gas usage. Here, we use the example contracts provided in the documentation of Chainlink. In both cases, response time for Secret VRF is at around 1-2 blocks, so around 10s.
In total, we also do not need to pay in special LINK tokens and instead can just pay in the native gas token of the chain (here: Sepolia ETH), which saves you additional costs.
To summarize, SecretVRF's combination of cost efficiency, speed, and EVM chain compatibility makes it a compelling choice for developers and projects seeking reliable and economical verifiable random functions. Its technical innovations position it as a leader in the space, offering tangible benefits that can significantly enhance the performance and cost-effectiveness of a wide range of blockchain applications.
Learn how to use SecretPath on EVM to access on-chain verifiable random numbers.
Install the node dependencies:
Make sure your Infura API key is configured for Polygon Matic testnet 😎
Compile your Solidity smart contract:
Once the contract is compiled successfully, upload the contract to Polygon testnet:
Note the contract address:
Add the RandomnessReceiver
contract address to your env
file:
Now that you've uploaded your contract, it's time to set the SecretPath gateway address for Polygon Mumbai and then request on-chain verifiable random numbers!
Gateways are the on-chain smart contracts that handle the broadcasting, receipt, packaging, and verification of messages.
First, set the gateway address for Polygon Mumbai testnet. You can do this by executing set_gateway.js
:
Next, create an event listener so you can listen to when the random numbers that you request have been fulfilled.
Open a new terminal window and cd
into examples/EVM-snakepath-RNG:
Then, create the event listener by executing fulfill_randomness_event.js
:
Once you have configured how many random numbers you want to request, execute request_random.js
:
Upon successful execution, your terminal will log the following:
Navigate to your event listener terminal to see the returned random numbers:
Congrats! You've just used SecretPath to request your first verifiable on-chain random numbers! 🎉
If you don't see your random numbers returned, it means that our testnet relayer might have dropped the transaction. See below to learn how to relay your transaction manually.
To relay your random numbers manually, you can use Polygonscan and Secret.js!
After you execute request_random.js
and have a task_id
returned, you can now execute query_secret_network
for the given task_id.
The query will return info about your transaction for the given task_id
:
Once you have entered your transaction info, select "Write" to execute the transaction.
Congrats! You've just used SecretPath to request your first verifiable on-chain random numbers! 🎉
Secret VRF offers an innovative and cost-effective solution for EVM developers seeking access to verifiable random numbers. By following this guide, you've successfully set up your environment, deployed the RandomnessReceiver.sol
contract, and interacted with the SecretPath network to request and receive random numbers. Dive into the world of decentralized randomness with SecretPath, where security meets simplicity. 🌟
94k Gas with Secretpath:
300k+ Gas for Chainlink VRF with their example project:
55k gas with Secretpath:
200k+ gas for Chainlink VRF with their example project:
over SecretPath enables EVM developers to access on-chain verifiable random numbers at a fraction of the cost and block time of traditional RNG oracles such as ChainlinkVRF. With fewer than 100 lines of code, you will have access to an infinite supply of randomness.
See a fullstack cross-chain SecretVRF demo
To learn how SecretVRF works underneath the hood, refer to the docs . 🤓
To get started, clone the :
.
.
cd
into :
Update the env
file with your EVM wallet private key and API key.
This tutorial is for Polygon testnet,, but you can find a list of additional EVM gateway contract addresses .
Now it's time to request random numbers! Currently, request_random.js
is configured to request 3 random numbers, but you can update how many numbers you would like to request (up to 2000 for this example).
Open query_secret_network.js
and update the to your task_id
. Then execute query_secret_network.js
:
Now, open and then input the returned query info into the postExecution
field:
Coming soon 😎
Coming soon 😎
Coming soon 😎
Got improvements or suggestions on how to convert your ChainlinkVRF contract to SecretVRF ? Please ask in the Secret Network Telegram or Discord.
Converting from Chainlink VRF to Secret VRF is easier than you expect. Within four easy steps you can free your contract from bloat and use the lightweight and faster Secret VRF solution.
We start off with the example code from Chainlink from here:
In the first step, we remove the imports and the inheritance of the VRFConsumerBaseV2 and add our SecretVRF interface from this. There is no
to get to this:
Here, the behavior of the callbackGasLimit
is different than in ChainlinkVRF. The callback Gas limit is simply all of the gas that you need to pay in order to make callback, which includes the verification of the result as well. The callback gas is the amount of gas that you have to pay for the message coming on the way back. We recommend at least using 100_000+
in Callback gas to ensure that enough gas is available. In case you did not pay enough gas, the contract callback execution will fail.
Next, we can also simplify the constructor since we do not need to define any extra variables or subscriptionIds. Going from this:
to this
Next, we need to slightly adjust the behavior of the function rollDice(address roller)
function and how it calls the Request Randomness function within Secret VRF. Here, we need to use the Secet VRF gateway and call it directly instead.
Make sure to now mark this function as payable
!
Please make sure to actually prepay the right amount of callback gas directly as a value transfer into the contract. The callback gas is the amount of gas that you have to pay for the message coming on the way back. If you do pay less than the amount specified below, your Gateway TX will fail:
Since this check is dependent on the current block.basefee
of the block it is included in, it is recommended that you estimate the gas fee beforehand and add some extra overhead to it. An example of how this can be implemented in your frontend can be found in this example and here:
Lastly, we'll add a small check to ensure that we actually got an incoming call from the SecretVRF gateway contract. For this, remove the internal
and override
flags on the function and add the require:
That's all that you need to convert your contract from ChainlinkVRF to SecretVRF.
You will start by configuring your developer environment and then learn how to use SecretPath to enable cross-chain encryption and decryption, using Secret Network as a Confidential Computing Layer (CCL) for the EVM.
To get started, clone the SecretPath tutorials repository:
cd
into sealed-bid-auctions/sealed-bid-contract
Compile the contract
cd
into secret-contract/node:
Install the node dependencies
Set SecretPath parameters:
Upload and instantiate the contract:
Now that you've instantiated a sealed bid contract on Secret Network, it's time to create your first auction item with SecretPath!
cd
into sealed-bid-auctions/evm-contract
:
Install the dependencies
Configure env
Configure SecretPath
If you wanted to do this for mainnet, you would simply use the mainnet encryption key.
Now that you have all of your SecretPath code configured, execute the SecretPath Sepolia public gateway contract to send your auction item to the Secret contract:
Each auction item you create will have an associated ID; the first auction item has ID 1, the second has ID 2, and so on.
Upon successful execution, info about your SecretPath payload will be returned:
Note that the sealed bid contract is designed so that each auction item has an ascending index number starting with 1. So the first auction item you list is index 1, the second is index 2, and so on.
Once you have set your bid, execute the bid function:
Upon successful execution, info about your SecretPath payload will be returned. Now let's query your auction item and bids with secret.js.
cd
into sealed-bid-auctions/sealed-bid-contract/node
:
Make sure you have added your Sealed bid contract address and codehash to your env file, and then query the auction item with node query_auction
:
Note that you are querying with key 1, because the first auction item is stored at index 1, the second auction item is stored at index 2, and so on.
If your auction item was submitted successfully, it should be returned like so:
If the bidding is still open, it will return the message:
If the bidding is closed, it will return the highest bid:
Note that the end user of the application is not exposed to Secret Network and is only working directly in the EVM environment. However, the data is fully protected and cannot be viewed by anyone.
A first-price sealed-bid auction, also known as a "blind auction", is a type of auction in which all bidders simultaneously submit sealed bids so that no bidder knows the bid of any other participant. The highest bidder pays the price that was submitted. In this tutorial you will learn how to create a cross-chain sealed bid auction dApp with encrypted bids using.
See a live demo ! See the fullstack frontend code implementation .
your Sepolia wallet.
.
.
Update the with your Secret Network wallet mnemonic, and rename it ".env" instead of ".env.example"
Open upload.js and configure the SecretPath , , and :
gatewayAddress, gatewayHash, and gatewayPublicKey are needed for instantiating contracts that utilize SecretPath and can be found in the docs . You will always use these same 3 parameters for instantiating a SecretPath-compatible contract on testnet.
Upon successful upload and instantiation, add the contract codehash and address to your .
Configure the with your sealed bid auction contract address and codehash, and rename it ".env" instead of ".env.example".
Open and navigate to , the publicClientAddress
. This is the SecretPath gateway address for .
If you wanted to send messages on another chain, such as Base or Polygon, you would simply update this publicClientAddress with the corresponding address found.
Similarly, there is a SecretPath gateway encryption key, which is on This is used for ChaCha20-Poly1305 Payload encryption and can be found in the docs
Next, configure the auction to your liking (end_time
is the amount of minutes that the auction will be live for), and note the handle
variable, which is the function that is actually being called in the Secret contract that you deployed. You are executing the handle, which executes the in your sealed bid contract.
Now it's time to place an encrypted bid on your listed auction item. Open and adjust the that you want to bid as well as the of the auction item.
NOTE: end_time
is converted from minutes to Secret Network block height 😎
Now, query the by running node query_bid
:
This is programmed in the of the Sealed Bid contract and can be adjusted to your liking 😊
NOTE: Be sure to update the for subsequent auction item queries
Congrats! You deployed your very own sealed bid auction contract on Secret Network and used SecretPath to send cross-chain encrypted bids on Sepolia testnet. See the fullstack demo . You now have all of the tools you need to start building your own cross-chain SecretPath contracts on the EVM 🎉
If you have any questions or run into any issues, post them on the and somebody will assist you shortly.
Need help with using encrypted payloads with Snakepath or want to discuss use cases for your dApp? Please ask in the Secret Network Telegram or Discord.
First, install all of the the dependencies via NPM:
Next, import the following into your code:
In your vite.config.ts
in the project, you need to add the support for bigInt
into the esbuildOptions:
To start, we first define all of our variables that we need for the encryption, as well as the gateway information:
First, we define the Gateway address that is specific to each chain, which can you can look up here Supported Networks.
Second, you need to input the private contract that you are going to call, in our case the Secret VRF RNG contact on Secret Network. The code for this example contract can be found here in case you want to deploy it yourself.
Next, init the Ethereum client that you are using to call the contract with. Here, we init the chainId to use the Ethereum sepolia testnet and use ethers.js to retrieve the address.
Next, you generate ephermal keys and load in the public encryption key for the Secret Gateway that you can look up in Supported Networks. Then, use ECDH to create the encryption key:
Next, you define all of the information that you need for calling the private contract on Secret + add the callback information for the message on its way back.
We begin by defining the function that we are going to call on the private secret contract, here it's request_random
. Next, we add the parameters/calldata for this function, which is ("{ numWords: Number(numWords) }"
and convert it into a JSON string.
Next, we define the callback Information. In this case, we are using the gateway contract as an example callback. Here, you would typically put in your own custom callback address and callback selector in.
After defining the contract call and callback, we now construct the payload:
Next, we encrypt the payload using ChaCha20-Poly1305. Then, we hash the encrypted payload into a ciphertextHash
using Keccak256.
Next, we use Metamask to sign the ciphertextHash
using personal_sign
. Then, we recover the user_pubkey
from this signed message, which will be also passed into the Public Gateway.
Internally, Metamask takes the ciphertextHash
, preprends the "\x19Ethereum Signed Message:\n32"
string and then hashes it using Keccak256, which results the payloadHash
. Metamask actually signs the payloadHash
to get the signature. Keep this in mind when verifying the signature against the payloadHash
and NOT the ciphertextHash
.
The callback gas is the amount of gas that you have to pay for the message coming on the way back. If you do pay less than the amount specified below, your Gateway TX will fail:
Since this check is dependent on the current block.basefee
of the block it is included in, it is recommended that you estimate the gas fee beforehand and add some extra overhead to it. An example of how this can be implemented in your frontend can be found in this example and here:
Lastly, we pack all the information we collected during previous steps into an info
struct that we send into the Gateway contract. We the encode the function data. Finally, we set the tx_params. Please make sure to set an approiate gas amount for your contract call, here we used 150k gas. For the value of the TX, we send over the estimated callback gas that we calculated above.
Learn how to use Secret Network smart contracts to encrypt and decrypt votes on Polygon testnet.
In this tutorial you will learn how to encrypt and decrypt votes on the EVM with Secret Network smart contracts so that you can build confidential voting on any EVM chain of your choosing. You will be working with two smart contracts:
EVM smart contract deployed on Polygon testnet (voting contract)
Secret Network smart contract deployed on Secret testnet (decryption contract)
The EVM contract stores encrypted proposals and votes, and the Secret contract decrypts the stored votes and reveals them in a query.
See a live demo here, configured for Polygon testnet! (To use the demo, make sure Polygon testnet is added to your Metamask wallet)
You will start by configuring your developer environment and then learn how to generate cryptographic keys in a Secret Network smart contract which you will use to encrypt votes on the EVM.
To get started, clone the Secret Labs examples repo:
cd
into examples/evm-confidential-voting/polygon:
Install the node dependencies:
Update the env
file with your Secret Network wallet mnemonic, EVM wallet private key, and Infura API key:
Make sure your Infura API key is configured for Polygon Matic testnet 😎
Next, generate encryption keys for your EVM contract and automatically add them to your env
file by running create_keys.js
:
Now you are ready to upload the smart contracts! 🚀
cd
into examples/evm-confidential-voting/secret-network:
Compile the Secret Network smart contract:
If you are on a Mac and run into compilation error:
error occurred: Command “clang”
Make sure you have the latest version of Xcode installed and then update your clang path by running the following in your terminal:
cargo clean
AR=/opt/homebrew/opt/llvm/bin/llvm-ar CC=/opt/homebrew/opt/llvm/bin/clang cargo build --release --target wasm32-unknown-unknown
See here for instructions on updating your clang path.
cd
into examples/evm-confidential-voting/secret-network/node
Install the node dependencies:
Upload the Secret Network smart contract:
Upon successful upload a codeHash
and contract address
is returned:
Update the env
file with your codeHash
and contract address
:
Now that your Secret Network smart contract is instantiated, you can execute the contract to generate encryption keys as well as decrypt encrypted messages. To learn more about the encryption schema, see the EVM encryption docs here.
To create encryption keys, run node create_keys
:
After you generate your keys successfully, query your public key:
Which returns your public key as a string
:
Add the public_key to your env
file:
Now it's time to upload a Voting contract to the EVM, which you will use to store encrypted votes that can only be decrypted by your Secret Network smart contract.
cd
into examples/evm-confidential-voting/polygon:
Compile your Solidity smart contract:
Once the contract is compiled successfully, upload the contract to Polygon testnet:
Note the contract address:
Add the Polygon testnet contract address to your env
file:
Now that your Polygon smart contract is instantiated, you can execute the contract to create voting proposals as well as vote on existing proposals. You can review the solidity contract here.
To create a proposal, you must include a proposal description (a "yes" or "no" question) as well as a quorum number, which is the number of unique wallet addresses required to vote on the proposal before it closes.
For testing purposes, set quorum
to 1 unless you want to test with multiple wallet addresses
Open create_proposal.js
and update the proposal_description to a "yes" or "no" question of your choice:
Then run create_proposal.js
:
A transaction hash
will be returned upon successful execution:
You can query the proposal by running query_by_proposal_id
:
Be sure to update the proposalId
in query_by_proposal_id.js with the proposalId
you want to query!
Which returns your proposal:
Each time you create a proposal, the proposalId
is incremented by 1. Your first proposalId
is 1, your next proposalId
will be 2, and so on.
Now it's time to vote on the proposal you created. Open vote.js
and update your proposal answer to either "yes" or "no" in the msg object:
proposal.id
and proposal.description
will match the proposal info you input for getProposalById.
This means that each time you vote, you need to make sure you update the proposal_id
number that you pass to getProposalById()
so that it matches the proposal you want to vote on!
Once you have updated your vote
and proposalId
, execute the vote script:
Your encrypted data and transaction hash are returned upon successful execution:
Now it's time to decrypt your vote! First, query that the vote was successfully added to the proposal by running query_proposal_votes.js
:
Be sure to update the proposalId
with the proposal you want to query.
query_proposal_vote
returns your encrypted vote for the supplied proposalId
:
Run decrypt.js
to decrypt the vote:
In decrypt.js
, update the proposalId
with the proposal you want to query.
Which returns your decrypted vote:
Congrats! You have now deployed smart contracts on Polygon and Secret Network and implemented private cross-chain voting. If you have any questions or run into any issues, post them on the Secret Developer Discord and somebody will assist you shortly.