# Deploy on Zircuit

{% hint style="info" icon="triangle-exclamation" %}

## Note that [SLS](https://docs.zircuit.com/info/architecture/sls) is not enabled while we [focus](https://www.zircuit.com/blog/a-new-chapter-for-zircuit-from-l2-to-defi) on Zircuit Finance. Zircuit Finance does not rely on the Zircuit chain.

{% endhint %}

This tutorial will guide you through the complete process of setting up Foundry, creating a smart contract, and deploying it to the Zircuit testnet. Foundry is a powerful, fast, and portable toolkit for Ethereum application development written in Rust.

### Prerequisites

Before starting, ensure you have:

* A Unix-like operating system (macOS, Linux, or WSL on Windows)
* Git installed
* A wallet with some ETH on Zircuit
* Basic understanding of Solidity and blockchain concepts

### What is Foundry?

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development. It consists of:

* **Forge**: Ethereum testing framework (like Truffle, Hardhat)
* **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data
* **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network
* **Chisel**: Fast, utilitarian, and verbose Solidity REPL

{% stepper %}
{% step %}
**Set Up Foundry**

First, we'll install Foundry using the official installer script:

```bash
# Download and install Foundry
curl -L https://foundry.paradigm.xyz | bash

# Reload your shell configuration to make foundryup available
source ~/.zshrc  # for zsh users
# OR
source ~/.bashrc  # for bash users

# Install the latest version of Foundry tools
foundryup
```

**What this does:**

* Downloads the Foundry installer script
* Installs `foundryup`, the Foundry toolchain installer
* Updates your shell to recognize the new commands
* Installs or updates `forge`, `cast`, `anvil`, and `chisel`

**Verify installation:**

```bash
forge --version
```

{% endstep %}

{% step %}
**Create a New Counter Project**

Initialize a new Foundry project with the counter template:

```bash
# Create a new Foundry project called 'counter'
forge init counter

# Navigate into the project directory
cd counter
```

**What this creates:**

```
counter/
├── lib/               # Dependencies (like node_modules)
├── script/            # Deployment scripts
│   └── Counter.s.sol  # Deployment script
├── src/               # Smart contract source files
│   └── Counter.sol    # Main contract
├── test/              # Test files
│   └── Counter.t.sol  # Contract tests
└── foundry.toml       # Foundry configuration file
```

{% endstep %}

{% step %}
**Set Up Your Private Key for Deployment**

{% hint style="warning" %}
Never use your mainnet private key for testing. Always use a separate wallet for testnet development.
{% endhint %}

You need to securely store your private key for contract deployment:

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast wallet import mainnetKey --interactive
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast wallet import testnetKey --interactive
```

{% endtab %}
{% endtabs %}

**What this does:**

* Prompts you to enter your private key securely (won't display on screen)
* Encrypts and stores the key locally under the name "defaultKey"
* Requires a password to encrypt the stored key
  {% endstep %}

{% step %}
**Compile Your Smart Contract**

Compile all contracts in your project:

```bash
forge compile
```

**What this does:**

* Compiles all `.sol` files in the `src/` directory
* Generates ABI (Application Binary Interface) files
* Creates bytecode for deployment
* Checks for compilation errors and warnings
* Outputs artifacts to `out/` directory

**Expected output:**

```
[⠊] Compiling...
[⠃] Compiling 23 files with Solc 0.8.30
[⠊] Solc 0.8.30 finished in 889.13ms
Compiler run successful!
```

{% endstep %}

{% step %}
**Review the Contract and Deployment Script**

Let's examine the smart contract and deployment script in detail:

**src/Counter.sol**

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Counter {
    // State variable to store the counter value
    uint256 public number;

    // Function to set the counter to a specific value
    function setNumber(uint256 newNumber) public {
        number = newNumber;
    }

    // Function to increment the counter by 1
    function increment() public {
        number++;
    }
}
```

**Contract explanation:**

* `uint256 public number`: A public state variable that automatically generates a getter function
* `setNumber()`: Allows setting the counter to any value
* `increment()`: Increases the counter by 1
* All functions are `public`, meaning anyone can call them

{% code title="script/Counter.s.sol" %}

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

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

contract CounterScript is Script {
    Counter public counter;

    function setUp() public {}

    function run() public {
        // Start recording transactions for broadcast
        vm.startBroadcast();
        
        // Deploy the Counter contract
        counter = new Counter();
        
        // Stop recording transactions
        vm.stopBroadcast();
    }
}
```

{% endcode %}

**Deployment script explanation:**

* Inherits from `Script` to access deployment utilities
* `vm.startBroadcast()`: Begins recording transactions to broadcast to the network
* `new Counter()`: Deploys a new instance of the Counter contract
* `vm.stopBroadcast()`: Stops recording transactions
  {% endstep %}

{% step %}
**Deploy Your Smart Contract**

Customize your `foundry.toml` for different networks:

```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# Zircuit RPC configuration
[rpc_endpoints]
zircuit_mainnet = "https://mainnet.zircuit.com"
garfield_testnet = "https://garfield-testnet.zircuit.com"
```

Deploy the contract to Zircuit

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
forge script script/Counter.s.sol:CounterScript \
    --rpc-url zircuit_mainnet \
    --account mainnetKey \
    --broadcast
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
forge script script/Counter.s.sol:CounterScript \
    --rpc-url garfield_testnet \
    --account testnetKey \
    --broadcast
```

{% endtab %}
{% endtabs %}

**Command breakdown:**

* `forge script`: Command to run deployment scripts
* `script/Counter.s.sol:CounterScript`: Path to script file and contract name
* `--rpc-url`: The RPC endpoint
* `--account <key>`: Uses the imported private key
* `--broadcast`: Actually sends transactions to the network

**Expected output (Garfield Testnet):**

```
[⠊] Compiling...
No files changed, compilation skipped
Enter keystore password:
Script ran successfully.

## Setting up 1 EVM.

==========================

Chain 48898

Estimated gas price: 0.000000509 gwei

Estimated total gas used for script: 203856

Estimated amount required: 0.000000000103762704 ETH

==========================

##### 48898
✅  [Success] Hash: 0x59bf94e4055ee2c4a71b9e6a7b7589ad3a5831ac38717c5f0d488eb4ed365a77
Contract Address: 0x6E69d4f9bc6a3E2f67d2D86877800482A8cdca40
Block: 8549829
Paid: 0.000000000039987315 ETH (156813 gas * 0.000000255 gwei)

✅ Sequence #1 on 48898 | Total Paid: 0.000000000039987315 ETH (156813 gas * avg 0.000000255 gwei)
```

**Copy the Contract Address** from the output - you'll need it for the next step!
{% endstep %}

{% step %}
**Interact with Your Smart Contract**

Now that your contract is deployed, you can interact with it using `cast`.

**Execute a State-Changing Function**

To call the `increment()` function (which costs gas):

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast send <CONTRACT_ADDRESS> "increment()" \
    --rpc-url https://mainnet.zircuit.com \
    --account mainnetKey
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast send <CONTRACT_ADDRESS> "increment()" \
    --rpc-url https://garfield-testnet.zircuit.com \
    --account testnetKey
```

{% endtab %}
{% endtabs %}

**Replace `<CONTRACT_ADDRESS>` with your actual contract address from step 6.**

**What this does:**

* Sends a transaction to call the `increment()` function
* Uses your imported private key to sign the transaction
* Pays gas fees for the transaction

**Expected output (Garfield Testnet):**

```
blockHash            0x97162a12dc900daf598e18c7a026d0b7bea5b121fc20bd99600292b53ba8148b
blockNumber          8550305
contractAddress      
cumulativeGasUsed    91965
effectiveGasPrice    255
from                 0xbd9B49deFc88AC16D7fC0F7FE6Eb7E0F54F6317f
gasUsed              43482
...
```

**Read Contract State**

To read the current value of `number` (free, no gas required):

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast call <CONTRACT_ADDRESS> "number()" \
    --rpc-url https://mainnet.zircuit.com
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast call <CONTRACT_ADDRESS> "number()" \
    --rpc-url https://garfield-testnet.zircuit.com
```

{% endtab %}
{% endtabs %}

**Expected output:**

```
0x0000000000000000000000000000000000000000000000000000000000000001
```

This hexadecimal output represents the number `1`, showing that our increment worked!

**To convert hex to decimal:**

```bash
cast --to-dec 0x0000000000000000000000000000000000000000000000000000000000000001
# Output: 1
```

**Additional Interaction Examples**

Set the counter to a specific value:

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast send <CONTRACT_ADDRESS> "setNumber(uint256)" 42 \
    --rpc-url https://mainnet.zircuit.com \
    --account mainnetKey
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast send <CONTRACT_ADDRESS> "setNumber(uint256)" 42 \
    --rpc-url https://garfield-testnet.zircuit.com \
    --account testnetKey
```

{% endtab %}
{% endtabs %}

Check the balance of your deployer address:

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast balance <YOUR_WALLET_ADDRESS> \
    --rpc-url https://mainnet.zircuit.com
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast balance <YOUR_WALLET_ADDRESS> \
    --rpc-url https://garfield-testnet.zircuit.com
```

{% endtab %}
{% endtabs %}

Get transaction details:

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
cast tx <TRANSACTION_HASH> \
    --rpc-url https://mainnet.zircuit.com
```

{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
cast tx <TRANSACTION_HASH> \
    --rpc-url https://garfield-testnet.zircuit.com
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}
**Verifying Contracts**

After doing programmatic interactions with the smart contract, you can also verify the contract using `forge`.

{% tabs %}
{% tab title="Zircuit Mainnet" %}

```bash
forge verify-contract <CONTRACT_ADDRESS> <SOURCE_FILE>:<CONTRACT_NAME> \
--chain-id 48900 \
--verifier sourcify \
--verifier-url https://sourcify.dev/server
```

[https://explorer.zircuit.com/address](https://explorer.zircuit.com/address/)/\<CONTRACT\_ADDRESS>
{% endtab %}

{% tab title="Garfield Testnet" %}

```bash
forge verify-contract <CONTRACT_ADDRESS> <SOURCE_FILE>:<CONTRACT_NAME> \
--chain-id 48898 \
--verifier sourcify \
--verifier-url https://sourcify.dev/server
```

<https://explorer.garfield-testnet.zircuit.com/address>/\<CONTRACT\_ADDRESS>
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}
**Advanced Features**

**Running Tests**

Foundry includes a powerful testing framework:

```bash
# Run all tests
forge test

# Run tests with verbose output
forge test -vvv

# Run specific test
forge test --match-test testIncrement
```

**Code Coverage**

Generate test coverage reports:

```bash
forge coverage
```

**Gas Reporting**

Get detailed gas usage reports:

```bash
forge test --gas-report
```

**Gas Reporting**

Get detailed gas usage reports:

```bash
forge test --gas-report
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zircuit.com/build/start/deploy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
