Developer Quickstart
Jovay is a cutting‑edge Layer 2 that delivers superior performance⚡ in throughput and latency while addressing critical security🔐 challenges. As an EVM‑equivalent Layer 2, Jovay remains fully compatible with the Ethereum ecosystem♻️.
🎯 What You’ll Accomplish
By the time you’re done, you’ll have:
🏅: Worked through the basic Solidity development on Jovay.
🥈: Worked through the ETH deposit and withdraw between Ethereum and Jovay.
🥉: Get familar with Jovay network and tooling.
🔧 Prerequisite
Here we assume that readers are already familiar with the concepts and usage of cryptocurrency. In order to successfully complete the tutorial, you need to be familiar with the usage of the following tools.
- 🛜 The Chrome explorer
- 💻 The Solidity programming language
- 🦊 The MetaMask wallet
- 🦔 The Remix development environment
💸 Get Funded on Jovay
In this section, we will introduce how to deposit ETH from Ethereum to Jovay. Users need to deposit ETH from Ethereum to Jovay so that they can use ETH to pay transaction fees in Jovay.
If you don't want to experience the complete deposit process from Sepolia to Jovay, you can just go to faucet for Jovay testnet and get funded. Finish the next part Add networks and then jump to next section Smart Contract on Jovay.
Add networks
Here we will use Ethereum testnet Sepolia and Jovay testnet.
Add Jovay
Add the Jovay testnet to your MetaMask. Refer to the MetaMask help document. The network information is as follows.
RPC URL: https://api.zan.top/public/jovay-testnet
Chain ID: 2019775
💡Tips: No need to setup the "Block explorer URL" part when you add network to metamask.

Figure 1: the Config of Jovay
Add Sepolia Add the Sepolia to your MetaMask. MetaMask presets the network Sepolia. You can find Sepolia in the test networks on the network selection page.

Figure 2: Preset Network
Drips from faucets🚰
Go to zan.top to get your Sepolia testnet tokens. After completing this step, you can see your account balance on MetaMask.
There are some other faucets if you can't receive tokens from zan.top faucet.
Review demo contract code
Click the link remix to review the demo contract code. On your remix, you would find three files for this tutorial:
☝️ IL1ETHBridge.sol: The contract interface of Jovay Token Bridge on Layer1.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
interface IL1ETHBridge {
/**
* The sender account transfers funds to TokenBridge to lock the assets;
* @param to_; L2 Receiver account address
* @param amount_; assert amount
* @param gasLimit_; gas limit on l2
* @param data_; none
*/
function deposit(address to_, uint256 amount_, uint256 gasLimit_, bytes memory data_) external payable;
struct L2MsgProof {
uint256 batchIndex;
bytes merkleProof;
}
function relayMsgWithProof(
uint256 value_,
uint256 nonce_,
bytes memory msg_,
L2MsgProof memory proof_
) external payable;
}
✌️ IL2ETHBridge.sol: The contract interface of Jovay Token Bridge on Layer2.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
interface IL2ETHBridge {
/**
* The sender account transfers to tokenbridge to lock the assets;
* @param to_ target address
* @param amount_ transfer amount
* @param gasLimit_ gas limit
* @param data_ data
*/
function withdraw(address to_, uint256 amount_, uint256 gasLimit_, bytes memory data_) external payable;
}
🤟 JovayExample.sol: A demo contract to show the experience of Solidity development on Jovay.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract JovayExample {
string private content = "welcome to Jovay";
function SetContent(string memory _new_content) public {
content = _new_content;
}
function GetContent() public view returns (string memory){
return content;
}
}
💡 tips: If you not familar with remix usage, please check out the help document.
Call contract to deposit
You need to send a transaction for calling the Token Bridge on Sepolia to trigger the crosschain deposit process, so here we go☄️.
Connect your remix to Sepolia with MetaMask.
Switch your MetaMask to network Sepolia.
Back to remix, click the button "
Deploy & run transactions
" on the left side bar. Then choose the "Environment
" and pick the "Injected Provider - MetaMask
".Compile the contract IL1ETHBridge.sol
Select the
IL1ETHBridge.sol
on file explorer of Remix. Then click the "Solidity compliers
" button and click the "Compile IL1ETHBridge.sol
" to get the compiled code ready.Attach the deployed Token Bridge contract.
The Token Bridge address on Sepolia is
0x940eFB877281884699176892B02A3db49f29CDE8
.Back to Remix "
Deploy & run transactions
", Fill in the Token Bridge address into the input box next to "At address
", then click "At address
". And you can see that the contract has been added under "Deployed Contracts
".Figure 3: Attach to TokenBridge Contract on Sepolia
Call function deposit
Like below, input the parameters and click the transact.
Figure 4: Dposit Function
Parameters describe here:
to_: The target address on Jovay to receive the deposited ETH. For example, your current MetaMask address.
amount_: Amount in wei to transfer to the deposit target. Ensure your Sepolia account has sufficient balance. For example
0.001 ether
(1000000000000000 wei
).gasLimit_: The gas limit to be used for the Jovay transfer transaction associated with L1. Must be greater than 1,200,000 to ensure sufficient gas on Jovay. Recommanded
1200000
.data: Message delivered with this deposit from Ethereum to Jovay. But here just input
0x
.value in transaction: The deposit ether value in transaction must cover the cost of the crosschain gas limit and the transfer amount. Now the price in Token Bridge is
0.001gwei
, if your gasLimit is1200000
and your amount isx
, the your value with transaction should greater or equal to valuex + 1200000 * 1e6
. For examplex
is0.001 ether
(1000000000000000 wei
) and value can be1001200000000000 wei
.Fill in your value into the input box above the function area, such as the one shown in the picture below:
Figure 5: Value for Transation
Click the transact button and MetaMask would sign and send your transaction to Sepolia.
After your deposit transaction is packaged on Sepolia, you would see its details on Jovay explorer. Search the deposit detail by your Sepolia transaction hash on Sepolia explorer.
Figure 6: Deposit Transaction on Sepolia
After Sepolia transaction finalized, your deposit would be relayed to Jovay testnet. This process may take up to 13~20 minutes. Once the deposit is confirmed on Jovay, an Jovay transaction hash will be displayed instead of a pending claim.
Figure 7: Finalize Deposit Transaction on Jovay
Check your balance on Jovay
Switch your MetaMask network to Jovay testnet. And you would find that the balance of your account changed.
Figure 8: Balance on Jovay
🧪 Smart Contract on Jovay
We encourage developers to deploy and test smart contracts on Jovay. This section will introduce how to deploy and invoke smart contracts compiled as native EVM bytecode on Jovay.
We're going to use remix to deploy a solidity demo smart contract and call it. And you can also use common development tools, such as foundry and hardhat, etc. Jovay is totally compatible with ethereum json rpc and its other standards.
Deploy contract
We provide a demo contract JovayExample.sol which you can found in the upper section 'Review demo contract code'. Also you can click share link again and go to Remix to see it.
Contract JovayExample only have one state variable called 'content
'. You can call the function 'SetContent
' to update it and function 'GetContent' to show it.
Before you start, switch your MetaMask to Jovay testnet and the Remix environment to MetaMask. Then on Remix, compile the contract and deploy it. In case you don't know how, Remix has a guide for users.
After deployment, you can find your deployed contract like below. You can search your contract address on Jovay explorer and get the details.

Figure 9: A Deployed Demo Contract
Interacting with deployed contract
Set the some string value in the input box. And click button transact to request the wallet to sign and send a transaction to Jovay testnet.

Figure 10: Call and Send Tx 🏎️
Copy the transaction hash which you can find it from Remix console like below. Then search transaction hash on Jovay explorer and you can have more details. The transaction is going to be confirmed in seconds.
Figure 11: Transaction Just Sent
After confirmation, your account balance will be reduced to pay the transaction fee. Checkout your MetaMask to see it. You will find Jovay is fast⚡️ and cheap💸.
Then call the GetContent function to check the content value. You should get the updated value which set by sent transaction.

Figure 12: New Content
Now you understand that the smart contract development on Jovay is same as on Ethereum, and more smooth on Jovay☄️.
🔙 How to Withdraw
The ETH token you hold on Jovay can be withdrawn back to Ethereum. In this section, we are going to describe it now.
To withdraw ETH from Jovay testnet to Sepolia, you need to invoke withdraw on the ETH Bridge contract on Jovay, and then invoke relayMsgWithProof
on the ETH Bridge contract on Sepolia.
Start a withdraw on Jovay
We provide the code IL2ETHBridge.sol of Token Bridge contract interface on Jovay which you can found in the upper section 'Review demo contract code'. Also you can click share link again and go to Remix to see it.
Before you start, switch your MetaMask to Jovay testnet and the Remix environment to MetaMask. Then on Remix, compile the contract interface IL2ETHBridge
and attach the bridge address. The ETH bridge address on Jovay testnet is 0xD278bC7189d2ed65c005c345A0e8a387f15b7a3A
.
After attached, you can find a ETH bridge contract instance like below.

Figure 13: Withdraw Function of L2ETHBridge
According to the following parameter definition, call the function withdraw with your own parameters.
to_: The address to receive the withdrawn ETH on Sepolia.
amount_: The amount of ETH to transfer to the withdrawal target address. Please ensure that sufficient balance remains to cover both the gas cost of this withdrawal transaction and the associated L1 transaction on Sepolia. For example
0.0001 ether
(100000000000000 wei
) .gasLimit_: The gas limit for the L1 transfer transaction associated with the L2 withdrawal. For example
1130000
.data_: Message delivered with this withdraw from Jovay to Ethereum. Just input 0x.
value in transaction: The withdraw ether value in transaction must cover the cost of the crosschain gas limit and the transfer amount. Now the price in Token Bridge is
0.001gwei
, if your gasLimit is 1130000 and your amount isx
, the your value with transaction should greater or equal to valuex + 1130000 * 1e6
. For examplex
is0.0001 ether
(100000000000000 wei
) and value can be101130000000000 wei
.Fill in your value into the input box above the function area, such as the one shown in the picture below:
Figure 14: Value for Transation
After sending the withdraw transaction on Jovay, wait for the next batch (less than 1 hour) to rollup to Sepolia. Search withdraw transaction hash on Jovay explorer to view the details.
Figure 15: Withdraw Transaction on Jovay
Once the rollup batch is finalized on L1, the Proof field will display a hex value. At that point, you can proceed to finalize the withdraw on Sepolia.
The proof mentioned here is generated by the merkle tree of the cross-chain messages, which is different from the proof provided by the prover during the rollup process.
Figure 16: Proof of Your Withdraw
Finalize the withdraw on Ethereum
Finalizing a withdrawal on Sepolia triggers the Bridge contract to transfer ETH to the target address, based on the L2 message produced by the Jovay withdraw
transaction.
The following steps can only be executed after the Jovay withdraw
transaction has been finalized on Sepolia. Enter the withdraw
transaction hash on the Jovay Explorer to navigate to the transaction details page, where the finalization status will be displayed. Then you can find the proof we described and assume that you already have the proof from the transaction detail page.
We provide the code IL1ETHBridge.sol of Token Bridge contract interface on Ethereum which you can found in the upper section 'Review demo contract code'. Also you can click share link again and go to Remix to see it.
Before you start, switch your MetaMask to Sepolia and the Remix environment to MetaMask. Then on Remix, compile the contract interface IL1ETHBridge
and attach the bridge address. The ETH bridge address on Sepolia is 0x940eFB877281884699176892B02A3db49f29CDE8
.
After attached, you can find a ETH bridge contract instance like below.

Figure 17: The Parameter of Finalize Withdraw Transaction
According to the following parameter definition, call the function relayMsgWithProof with your own parameters.
value_: the amout which you have withdrawn from Jovay, must equal to the amount you have configured in Start a withdraw on Jovay.
nonce_: the nonce of the L2Msg generated by your withdrawal transaction; you can retrieve this value from the withdrawal transaction's details page in Jovay Explorer. On the transaction details page of the Jovay explorer, click
Logs
to find the second eventSentMsg
. The nonce of this message is shown as below.Figure 18: Nonce for withdraw Msg
msg_: the L2Msg generated by your withdrawal transaction. On the transaction details page of the Jovay explorer, click
Logs
to find the second eventSentMsg
. The original message can be found in themsg
field ofEvent Params
. The message content on the browser page is in Base64 format. You need to convert it to Hex format for easy use in calling the contract. Don't forget the prefix0x
.Figure 19: The content of Withdraw Msg
proof_: A solidity struct and contains two fields described below. Note that this parameter must be passed in as a tuple using square brackets. The first element is
batchIndex
and the second ismerkleProof
. For example,[25,"0xbafd...a5be"]
, replace0xbafd...a5be
with your real merkleProof.batchIndex_: The index of the batch that includes the block which the withdrawal transaction is located, used to determine the Merkle Root of the L2Msg Tree. To get the batch index, click the Block Number link. You can find the batch index on the block details page. Here it is 25.
Figure 20: The Block of Withdraw Transaction
Figure 21: The Batch Index of Withdraw Transaction
merkleProof: The SPV proof corresponding to the Layer 2 message generated by the withdrawal transaction. You can also retrieve it from the withdrawal transaction's details page in Jovay Explorer, as shown in the figure above. Don't forget the prefix
0x
.Figure 22: Proof Is Ready
Get parameters ready, change MetaMask connect to Sepolia and then click button transact to request the wallet to sign and send a transaction to call the contract.

Figure 23: An Example of Finalize Withdraw Parameter
Wait the transaction confirmed on Sepolia, you can search the transaction on etherscan.io.
Figure 24: The Ether Amount Withdrawal
By sending this transaction to Sepolia, the relayMsgWithProof
method on the Sepolia ETH Bridge Contract is invoked to complete withdrawal proof validation, resulting in the specified ETH amount being successfully withdrawn to your account. Check your Sepolia account balance on MetaMask.