Deploy a contract with Foundry or Hardhat

Deploy Hello.sol on an EVM network with Foundry or Hardhat 2, verify the chain ID, and check the transaction receipt and contract response.

Select the network

Follow the target chain's integration guide (accessed via Supported Chains) to create network.mjs and export RPC_URL and CHAIN_ID. Chain guides read the chain ID and method policy from GET /v1/chains and explain the gas token, whether a separate broadcasting RPC is required, and chain-specific deployment settings.

Choose one tool below. Both deploy the same small contract without constructor arguments.

Fund the deployer with the selected network’s native gas token. Set DEPLOYER_PRIVATE_KEY securely in your local environment; never commit it. The following commands broadcast a transaction and spend gas.

Create Hello.sol with no constructor arguments:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Hello {
    event Ping(address indexed sender);
    function ping() external { emit Ping(msg.sender); }
    function hello() external pure returns (string memory) {
        return "hello";
    }
}

Foundry

In an initialized Foundry project, place the contract at src/Hello.sol and use this foundry.toml:

[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"
evm_version = "paris"

[rpc_endpoints]
target = "${RPC_URL}"
: "${RPC_URL:?Set RPC_URL}" "${CHAIN_ID:?Set CHAIN_ID}" "${DEPLOYER_PRIVATE_KEY:?Set deployer key}"
test "$(cast chain-id --rpc-url "$RPC_URL")" = "$CHAIN_ID" || exit 1
forge build
forge create src/Hello.sol:Hello --rpc-url target \
  --chain "$CHAIN_ID" --private-key "$DEPLOYER_PRIVATE_KEY" --broadcast

Keep the transaction hash and deployed address. Use cast receipt "$TX_HASH" --rpc-url "$RPC_URL" to inspect inclusion and status, then cast call "$CONTRACT_ADDRESS" "hello()(string)" --rpc-url "$RPC_URL" to read the contract. Set these two variables from the deployment output.

Hardhat 2 with ethers 6

In a separate CommonJS project (npm init -y), install npm install --save-dev hardhat@2 @nomicfoundation/hardhat-ethers@3 ethers@6. Place the same contract at contracts/Hello.sol. Save this as hardhat.config.cjs:

require('@nomicfoundation/hardhat-ethers');
const { RPC_URL, CHAIN_ID, DEPLOYER_PRIVATE_KEY } = process.env;
if (!RPC_URL || !/^[1-9][0-9]*$/.test(CHAIN_ID ?? '') || !DEPLOYER_PRIVATE_KEY) {
  throw new Error('Set RPC_URL, CHAIN_ID and DEPLOYER_PRIVATE_KEY');
}
module.exports = {
  solidity: { version: '0.8.24', settings: { evmVersion: 'paris' } },
  networks: {
    target: { url: RPC_URL, chainId: Number(CHAIN_ID), accounts: [DEPLOYER_PRIVATE_KEY] },
  },
};

Create the scripts directory and save as scripts/deploy.cjs:

const { ethers } = require('hardhat');
async function main() {
  const contract = await ethers.deployContract('Hello');
  console.log(contract.deploymentTransaction().hash);
  await contract.waitForDeployment();
  console.log(await contract.getAddress());
}
main().catch(error => { console.error(error); process.exitCode = 1; });
npx hardhat compile
npx hardhat run scripts/deploy.cjs --network target

The network’s chainId is checked against the RPC. See the Hardhat 2 network settings and Foundry settings (accessed: 2026-10-07).

Read events

Set LOG_ADDRESS to the deployed address. Follow the event reading method in the target chain's guide (WebSocket subscription or HTTP chunked polling, depending on the chain's ws field in /v1/chains) to read Ping events after calling ping().

Last updated:

On this page