# 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 %}
