Skip to main content

Deploy now: from nothing to a verified contract on Gnosis Chain

Job: deploy and verify a contract on Gnosis Chain mainnet. Time: about 45 minutes. Chains: Chiado testnet, then Gnosis mainnet.

Prerequisites: a terminal on macOS or Linux, Git, a free Blockscout API key for verifying on mainnet, and a small amount of xDai on Gnosis Chain for the mainnet step. Around one xDai is far more than you need.

This guide takes you from an empty directory to a contract on Gnosis Chain mainnet whose source anyone can read on the block explorer. You rehearse every step on Chiado first, where nothing costs real money, then repeat it on mainnet.

Why mainnet matters here. Gnosis EEZ goes live by hard-forking the state of Gnosis Chain mainnet. A contract you deploy on mainnet today is on Gnosis EEZ at the same address the moment the fork activates. A contract on Chiado is not. Chiado is for rehearsal, and it gets its own fork for testing before mainnet.

Every step ends in something you can see. If a step does not produce the result described, stop there. The next step will not work.

Install Foundry​

Foundry is the toolchain you will use to compile, test, deploy and verify. Install it, or run foundryup to update an existing install:

curl -L https://foundry.paradigm.xyz | bash

Open a new terminal and run the installer it placed on your path:

foundryup

Check it worked:

forge --version

You should see a version string. You now have three commands: forge builds, tests and deploys, cast reads and writes single calls, and anvil runs a local node.

Create the project​

Make a new Foundry project and move into it:

forge init gnosis-launch
cd gnosis-launch

Confirm it compiles:

forge build

You should see Compiler run successful.

Write the contract​

Replace src/Counter.sol with a contract that records who deployed it and counts how many times it has been incremented. It is small on purpose: the point of this guide is the deployment loop, not the contract.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Counter {
address public immutable deployer;
uint256 public count;

event Incremented(address indexed by, uint256 newCount);

constructor() {
deployer = msg.sender;
}

function increment() external {
count += 1;
emit Incremented(msg.sender, count);
}
}

Test it locally​

Replace test/Counter.t.sol with a test that checks both pieces of state:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Test} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";

contract CounterTest is Test {
Counter counter;

function setUp() public {
counter = new Counter();
}

function test_RecordsDeployer() public view {
assertEq(counter.deployer(), address(this));
}

function test_Increments() public {
counter.increment();
counter.increment();
assertEq(counter.count(), 2);
}
}

Delete script/Counter.s.sol, which the template created for the old contract, then run the tests:

rm script/Counter.s.sol
forge test

You should see two tests passing. Nothing has touched a network yet.

Rehearse on Chiado​

Create a testnet account​

Generate an account and store it encrypted in Foundry's keystore, so no private key ends up in your shell history:

cast wallet new

Copy the private key it prints, then import it under the name chiado-dev:

cast wallet import chiado-dev --interactive

Paste the key, choose a password, and confirm it is stored:

cast wallet list

Fund it from the faucet​

Request test xDai for the address at the Chiado faucet, then check it arrived:

cast balance <TESTNET_ADDRESS> --rpc-url https://rpc.chiadochain.net

Anything above zero is enough. If it prints 0, wait a few seconds and try again.

Deploy and verify​

Deploy:

forge create src/Counter.sol:Counter \
--rpc-url https://rpc.chiadochain.net \
--account chiado-dev \
--broadcast

Enter your keystore password. Foundry prints the deployer, the new contract address and the transaction hash. Then verify the source on Blockscout, replacing <CONTRACT> with the address it printed:

forge verify-contract <CONTRACT> src/Counter.sol:Counter \
--chain 10200 \
--verifier blockscout \
--verifier-url https://gnosis-chiado.blockscout.com/api/

On success it prints Contract successfully verified. Open https://gnosis-chiado.blockscout.com/address/<CONTRACT> and check the code tab shows your Solidity source.

If both commands worked, the mainnet steps below will work the same way. The differences are the account, the RPC URL, the chain ID, and the explorer: Chiado uses Blockscout, and mainnet uses Gnosisscan.

Deploy to Gnosis Chain mainnet​

Create a separate mainnet account​

Do not reuse the testnet key. Generate a fresh one and import it under a different name:

cast wallet new
cast wallet import gnosis-deployer --interactive
warning

This account will hold real funds. Keep the private key out of chat windows, files you might commit, and shared machines. For a production deployment, Foundry also accepts --ledger or --trezor in place of --account, so the key never leaves a hardware wallet.

Fund it with xDai​

xDai is the gas token on Gnosis Chain. A deployment like this one costs a fraction of a cent. Get xDai to your new address in either of two ways:

Check it arrived:

cast balance <MAINNET_ADDRESS> --ether --rpc-url https://rpc.gnosischain.com

Deploy​

forge create src/Counter.sol:Counter \
--rpc-url https://rpc.gnosischain.com \
--account gnosis-deployer \
--broadcast

Copy the contract address it prints. From here <CONTRACT> means the mainnet address.

Verify​

Mainnet verification goes to Gnosisscan, the Gnosis Chain explorer, which is run by Blockscout. Get a free API key from the Blockscout developer portal and put it in your environment rather than on the command line:

export BLOCKSCOUT_API_KEY=<YOUR_KEY>

Then verify:

forge verify-contract <CONTRACT> src/Counter.sol:Counter \
--chain 100 \
--verifier blockscout \
--verifier-url https://gnosisscan.io/api/ \
--verifier-api-key $BLOCKSCOUT_API_KEY

On success it prints Contract successfully verified. Open https://gnosisscan.io/address/<CONTRACT>. The Contract tab shows your source with a verified tick, and Read Contract and Write Contract are available.

If you would rather not create a Blockscout account, Sourcify verifies Gnosis Chain contracts with no key. Swap the last three flags for --verifier sourcify. The source is then published on Sourcify rather than shown on Gnosisscan.

Read it back​

Change the state once:

cast send <CONTRACT> "increment()" \
--rpc-url https://rpc.gnosischain.com \
--account gnosis-deployer

The receipt shows a status of 1 (success). Read the count and the deployer:

cast call <CONTRACT> "count()(uint256)" --rpc-url https://rpc.gnosischain.com
cast call <CONTRACT> "deployer()(address)" --rpc-url https://rpc.gnosischain.com

The first prints 1. The second prints your mainnet deployer address.

If you use the Gnosis EEZ MCP server, your agent can make the same read with the chain_read_contract tool:

{
"address": "<CONTRACT>",
"abi_fragment": "function count() view returns (uint256)",
"function": "count",
"chain_id": 100
}

What happens at the fork​

Nothing you need to do. When Gnosis EEZ activates, this contract keeps:

TodayAfter the fork
Address<CONTRACT><CONTRACT>
Storagecount is 1count is 1
Verified sourceOn GnosisscanOn Gnosisscan
Gas tokenxDaixDai
Your keys and toolinggnosis-deployer, FoundryUnchanged

What changes is around it: blocks every 2 seconds, proven and settled on Ethereum (an interim proving setup at genesis, then real-time ZK proofs), and the ability to call Ethereum mainnet contracts in the same transaction. Gnosis Chain now and Gnosis EEZ has the full comparison.

Register as a launch partner​

You now have a verified contract on the chain that becomes Gnosis EEZ. Two steps make it count:

  1. Register the deployment in the ecosystem directory. Addresses are checked before they are listed, and the listing is what developers and agents see through the Gnosis EEZ MCP server.
  2. Book a call with the ecosystem team to confirm the partnership and get access to the Chiado fork when it opens.

Next steps​