> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hedera.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Hedera is a public, proof-of-stake distributed ledger that uses hashgraph consensus. Do not call it a blockchain.
> Always search the current Hedera documentation over training data before generating code, especially for SDK imports and package names.
> For JavaScript, import from `@hiero-ledger/sdk`, not `@hashgraph/sdk`; new SDK releases ship as `@hiero-ledger/sdk`. The Java SDK keeps the `com.hedera.hashgraph:sdk` Maven coordinates. Verify the exact import against the docs.
> Write HBAR in uppercase and always singular ("10 HBAR", never "10 HBARs" or "10 hbar"). Write tinybars in lowercase and plural.
> Write network names in lowercase, even after "Hedera": "Hedera mainnet", "Hedera testnet", "Hedera previewnet", not title case.
> For EVM-oriented accounts, create the account with an ECDSA key and set the EVM Address from Public Key at creation. This address is immutable and is not updated by key rotation. Do not use retired terms like "EVM alias" or "Account Number Alias".

# Configuring Foundry with Hedera Localnet/Testnet: A Step-by-Step Guide

> Configure Foundry to work with a local Solo network or Hedera Testnet through the JSON-RPC relay, covering foundry.toml, forge script deployment, cast, and Sourcify verification.

Developers building smart contracts on Hedera often use the **Hedera JSON-RPC Relay** to enable EVM tools like **Foundry**. In this post, we'll walk through how to set up Foundry against a local **Solo** network, allowing for local deployment, debugging, and testing of smart contracts without using testnet resources.

<Check>
  Not sure whether to run a local network, use Hashio, or set up a custom relay?
  Compare the options on the [JSON-RPC relay
  page](/evm/development/json-rpc#json-rpc-relay-options-for-the-hedera-network).
</Check>

<Info>
  You can take a look at the **complete code** in the [**Hedera-Code-Snippets
  repository**](https://github.com/hedera-dev/hedera-code-snippets/tree/main/tutorial-local-hardhat).
</Info>

This guide shows you how to configure Foundry to deploy, interact with, and test Solidity smart contracts on:

* Hedera Localnet (via Solo and its built-in JSON-RPC Relay)
* Hedera Testnet (via Hashio JSON-RPC Relay)

You’ll set up environment variables, configure `foundry.toml`, write a simple contract and a Foundry deployment script, and learn how to switch between Localnet and Testnet with a single flag.

If you’re looking for an end-to-end “Hello, ERC-20” tutorial, see: “[Getting started with Foundry](/evm/quickstart/deploy-with-foundry)” (deploy, interact, verify on Hashscan). This guide focuses on environment configuration and workflow for Localnet/Testnet.

***

## What you will accomplish

* Configure Foundry to talk to the Hedera JSON-RPC Relay (Localnet and Testnet)
* Deploy and interact with a sample contract using `forge script` and `cast`
* Verify contracts on Hashscan (Testnet)

***

## Prerequisites

* Foundry installed (forge, cast, anvil, chisel):
  * `curl -L https://foundry.paradigm.xyz | bash`
  * `foundryup`
* ECDSA account and private key
  * For Testnet: create/fund an account via the [Hedera Portal](https://portal.hedera.com/)
  * For Localnet: use one of the pre-funded accounts Solo generates (see Option A below)
* Basic Solidity / CLI familiarity

***

## Table of Contents

1. [Option A: Run Hedera Localnet](#option-a%3A-run-hedera-localnet-solo)
2. [Option B: Use Hedera Testnet](#option-b%3A-use-hedera-testnet-hashio)
3. [Step 1: Initialize a Foundry project](#step-1%3A-initialize-a-foundry-project)
4. [Step 2: Add environment variables](#step-2%3A-add-environment-variables)
5. [Step 3: Configure foundry](#step-3%3A-configure-foundry.toml)
6. [Step 4: Add a simple contract](#step-4%3A-add-a-simple-contract)
7. [Step 5: Update the deploy script](#step-5%3A-update-the-deploy-script)
8. [Step 6: Deploy the contract](#step-6%3A-deploy-the-contract)
9. [Step 7: Run tests](#step-7%3A-run-tests)
10. [Step 8: Verifying the contract on Hashscan](#step-8%3A-verifying-the-contract-on-hashscan)
11. [Interact using cast](#interact-using-cast)

***

## Option A: Run Hedera Localnet (Solo)

[Solo](https://solo.hiero.org/docs/) runs a full Hedera network on your machine: consensus node, mirror node, block node, JSON-RPC relay, and the Mirror Node Explorer. It requires Docker and Node.js 22 or later, and provisions `kubectl`, Helm, and `kind` for you at deploy time.

**Install the CLI and deploy a single-node network:**

```bash theme={null}
npm install -g @hiero-ledger/solo@latest
solo one-shot single deploy
```

The deploy command starts the whole stack and generates pre-funded ECDSA accounts. On Solo 0.63 and later, the endpoints are:

| Service | Endpoint |
| - | - |
| JSON-RPC relay | `http://localhost:37546` (chain ID `298`) |
| Mirror node REST API | `http://localhost:38081` |
| Mirror Node Explorer | `http://localhost:38080` |
| Consensus node gRPC | `localhost:35211` |

<Info>
  * Solo writes the generated accounts to `~/.solo/one-shot-<deployment-name>/accounts.json`. The default deployment name is `one-shot`, so the default path is `~/.solo/one-shot-one-shot/accounts.json`. Run `solo one-shot show deployment` to confirm yours.
  * Use an ECDSA key from the `createdAccounts` array: a private key of 64 hex characters with a `0x` prefix. Hedera ED25519 accounts do not work over the JSON-RPC relay.
  * These ports are defaults, not guarantees. If a port is taken, Solo forwards to the next free one and prints the assignments at the end of the deploy. Check them later with `solo deployment config ports --deployment <deployment-name>`.
  * Solo 0.62 and earlier use different defaults, including `http://localhost:7546` for the relay.
</Info>

Tear the network down when you are done:

```bash theme={null}
solo one-shot single destroy
```

See [Local Development](/native/local-dev/index) for prerequisites, verification steps, and troubleshooting.

***

## Option B: Use Hedera Testnet (Hashio)

Hashio is a community relay node suitable for development/testing:

* RPC URL: `https://testnet.hashio.io/api`

**Note**: For production, prefer a commercial-grade JSON-RPC relay or host your own Hiero JSON-RPC Relay.

***

## Step 1: Initialize a Foundry project

```bash theme={null}
forge init foundry-hello-world
cd foundry-hello-world
```

This creates `src`, `script`, `test`, and `lib`.

### Project Structure

The Foundry project initialization creates the following file structure:

```
foundry.toml
lib
└── forge-std
src
└── Counter.sol
script
└── Counter.s.sol
test
└── Counter.t.sol
```

Here's a quick overview of these files and directories:

* `foundry.toml`: You can configure Foundry's behavior using this file such as defining RPC URLs
* `src`: Serves as the default for storing your smart contract source code
* `script`: This is where you store Solidity scripts for deploying contracts and performing other on-chain operations
* `test`: Serves as the dedicated location for Solidity-based unit and integration tests for your smart contracts

***

## Step 2: Add environment variables

Create an `.env` for your RPC URL and private key.

```bash theme={null}
touch .env
```

Put the following into your environment file.

```bash .env theme={null}
HEDERA_RPC_URL=your-rpc-url
HEDERA_PRIVATE_KEY=0x-your-private-key
```

Now, let's also load these to the terminal:

```bash theme={null}
source .env
```

<Warning>
  Replace the `your-rpc-url` environment variable with:

  * For Testnet: `https://testnet.hashio.io/api`, or
  * For Localnet: `http://localhost:37546` (Solo 0.63 and later)

  Replace the `0x-your-private-key` environment variable with:

  * For Testnet: the **HEX Encoded Private Key** for your **ECDSA** **account** from the [Hedera Portal](https://portal.hedera.com/), or
  * For Localnet: an ECDSA private key from the `createdAccounts` array in `~/.solo/one-shot-<deployment-name>/accounts.json`, in the form `0x` followed by 64 hex characters
</Warning>

<Danger>
  ***Please note**:* *that Hashio is intended for development and testing
  purposes only. For production use cases, it's recommended to use
  commercial-grade JSON-RPC Relay or host your own instance of the* [*Hiero
  JSON-RPC Relay*](https://github.com/hiero-ledger/hiero-json-rpc-relay)*.*
</Danger>

***

## Step 3: Configure "foundry.toml"

Foundry uses the `foundry.toml` file for configuration. Open it and add profiles for the Hedera RPC endpoint.

```toml foundry.toml theme={null}
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings = [
  "forge-std/=lib/forge-std/src/"
]

# Add this section for Hedera Testnet
[rpc_endpoints]
hedera = "${HEDERA_RPC_URL}"
```

***

## Step 4: Add a simple contract

Use a tiny `Counter` contract to focus on configuration rather than external dependencies for this exercise.

Compile with:

```bash theme={null}
forge build
```

***

## Step 5: Update the deploy script

We are going to update our deploy script a little bit so we can use our private key instead of passing it as a flag every time:

```solidity script/Counter.s.sol theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

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

contract CounterScript is Script {
    Counter public counter;

    function run() external returns (address) {
        // Load the private key from the .env file
        uint256 deployerPrivateKey = vm.envUint("HEDERA_PRIVATE_KEY");

        // Start broadcasting transactions with the loaded private key
        vm.startBroadcast(deployerPrivateKey);

        // Deploy the contract
        counter = new Counter();

        // Stop broadcasting
        vm.stopBroadcast();

        console.log("Counter Contract deployed to:", address(counter));

        return address(counter);
    }
}
```

***

## Step 6: Deploy the contract

Now, execute the script to deploy your contract:

```bash theme={null}
forge script script/Counter.s.sol:CounterScript --rpc-url hedera --broadcast
```

After a few moments, you will see the address of your newly deployed contract:

```
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.

== Return ==
0: address 0x061A1DdE963792192eA823C2F57285111812630b

== Logs ==
  Counter Contract deployed to: 0x061A1DdE963792192eA823C2F57285111812630b

## Setting up 1 EVM.

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

Chain 296

Estimated gas price: 720.000000001 gwei

Estimated total gas used for script: 203856

Estimated amount required: 0.146776320000203856 ETH

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

##### 296
✅  [Success] Hash: 0x279d667c3a31bb0956449d819bdd4b99619a25b8387a0765f28c9407d158069b
Contract Address: 0x061A1DdE963792192eA823C2F57285111812630b
Block: 25089799
Paid: 0.0554489 ETH (163085 gas * 340 gwei)

✅ Sequence #1 on 296 | Total Paid: 0.0554489 ETH (163085 gas * avg 340 gwei)


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

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL
```

<Check>
  Note that Foundry hardcodes “ETH” in its summary. However, even if it says
  `ETH`, because we're connected to Hedera, the currency used is `HBAR`.
</Check>

Now, go ahead and update your `.env` values to point to another Hedera Network(Localnet or Testnet) and try again.

***

## Step 7: Run tests

You can also run the test suite that's included as part of `test/` directory:

```bash theme={null}
forge test
```

***

## Step 8: Verifying the Contract on Hashscan

Verifying your smart contract publishes its source code to [Sourcify](https://sourcify.dev), and HashScan picks up the verified status automatically.

<Info>
  Sourcify only verifies contracts on registered networks. Hedera Mainnet (chain ID `295`) and Testnet (chain ID `296`) are supported, but **Hedera Localnet is not**. Skip this step when working against Localnet and rerun verification once your contract is deployed on Testnet or Mainnet. Make sure to replace `<your-contract-address>` with the address you got after the deployment above.
</Info>

Run the following command, using the variables you set earlier.

```bash theme={null}
forge verify-contract <your-contract-address> src/Counter.sol:Counter \
    --chain-id 296 \
    --verifier sourcify \
    --verifier-url "https://sourcify.dev/server"
```

After running the command, you should see a success message.

```
Submitting verification for [Counter] "0x061A1DdE963792192eA823C2F57285111812630b".
Contract successfully verified
```

**Congratulations! 🎉 You have successfully deployed, interacted with, and verified a smart contract on the Hedera Testnet using Foundry. Feel free to reach out in** [**Discord**](https://hedera.com/discord)**!**

***

## Interact using cast

Set helpers:

```bash theme={null}
export CONTRACT_ADDRESS=<your-contract-address>
export MY_ADDRESS=$(cast wallet address $HEDERA_PRIVATE_KEY)
```

Read:

```bash theme={null}
cast call $CONTRACT_ADDRESS "number()(uint256)" --rpc-url hedera
```

Write:

```bash theme={null}
cast send $CONTRACT_ADDRESS "setNumber(uint256)" 42 \
  --private-key $HEDERA_PRIVATE_KEY \
  --rpc-url hedera

cast send $CONTRACT_ADDRESS "increment()" \
  --private-key $HEDERA_PRIVATE_KEY \
  --rpc-url hedera
```

Read again:

```bash theme={null}
cast call $CONTRACT_ADDRESS "number()(uint256)" --rpc-url hedera
```

You should get an output of `43` since the counter is at 43 now after having added 42 + 1.

***

## Further Learning & Next Steps

Want to take your local development setup even further? Here are some excellent tutorials to help you dive deeper into smart contract development on Hedera using Foundry:

1. [**How to Mint and Burn an ERC-721 Token (Part 1)**](/evm/tutorials/advanced/erc721-foundry/part1-mint-burn)\
   Learn how to create a basic ERC-721 NFT, mint it, and burn it on Hedera.
2. [How to Write Tests in Solidity (Part 2)](/evm/tutorials/advanced/erc721-foundry/part2-testing)\
   Learn how to start writing tests in Foundry using Solidity
3. [How to Fork the Hedera Network for Local Testing](/evm/development/forking)\
   Learn how to fork hedera network(testnet/mainnet) locally so you can start testing against the forked network

<Columns cols={2}>
  <Card title="Writer: Kiran, Developer Advocate" arrow>
    [GitHub](https://github.com/kpachhai) |
    [LinkedIn](https://www.linkedin.com/in/kiranpachhai/)
  </Card>

  <Card title="Editor: Luke, DevRel Engineer" arrow>
    [GitHub](https://github.com/LukeForrest-Hashgraph) |
    [X](https://x.com/_LukeForrest)
  </Card>

  <Card title="Editor: Krystal, Senior DX Engineer" arrow>
    [GitHub](https://github.com/theekrystallee) |
    [X](https://x.com/theekrystallee)
  </Card>
</Columns>
