data-book="docs" Foundry (EVM example) | The Root Network
Skip to content

2.34 Foundry (EVM example) ​
At a glance
What it isDeploy, verify and test a Solidity contract with forge. Futureverse’s EVM example for The Root Network, with its README and source.
Where it sitsPart II — Building · Chapter 2.34
CoversExamples · Procedure: · Testing: · Troubleshooting: · Source files
Sourcegithub.com/futureversecom/trn-examples/tree/main/examples/evm/use-forge

Deploy, verify and test a Solidity contract with forge. Reference: smart contract cookbook.

Copied from Futureverse’s futureversecom/trn-examples, deleted with its GitHub organisation, at commit 44c9e16 of 2024-10-31. Apache-2.0: license. Before you run it, read Running the examples.

Offline destinations

Some places this page points to did not answer when last checked:

  • github.com/futureversecom — organisation deleted (HTTP 404) (checked 2026-10-10)
  • porcini.rootnet.app — TLS certificate does not cover the host (checked 2026-10-10), named in code

The node source survives as the mirror https://github.com/marco-fv/trn-seed-public, and the organisation’s code examples are on this site as Code examples; its other repositories have no public copy.

This project showcases the deployment and verification of a basic smart contract on the TRN Porcini network using Foundry's forge CLI. It includes a sample contract, a corresponding test, and a deployment script.

IMPORTANT

Ensure the following ENV vars are available before running the examples

2.34.1 Examples ​

bash
# change your working directory to this example first
cd examples/substrate/use-forge

# export all required environments
export CALLER_PRIVATE_KEY=

pnpm forge:install

# deploy contract using `forge create`
pnpm forge:create

# deploy contract using `forge script`
pnpm forge:script

2.34.2 Procedure: ​

There are two methods to deploy contracts using Foundry:

  1. Using forge create

    Users can utilize the forge create command to deploy and verify a contract by specifying all the necessary parameters in the command. Here is an example:

    forge create \
        --rpc-url $PORCINI_RPC_URL \
        --private-key $DEPLOYER_PRIVATE_KEY \0
        --legacy \
        --optimize \
        --optimizer-runs 200 \
        --use <SOLIDITY_VERSION> \
        --verify \
        --verifier sourcify \
        path/to/<CONTRACT_NAME>.sol:<CONTRACT_NAME> \
        --constructor-args {if necessary}

    Note: You can check out the shell script example included in this repo: examples/evm/use-forge/script/use-forge-create.sh

    In this example, we set the --rpc-url to TRN Porcini and specify the --private-key using environment variables (see #5 of Prerequisites section).

    Pay special attention to the --legacy flag, as it is necessary for successful contract deployment on the TRN Porcini network. Failure to include this flag may result in errors (refer to the troubleshooting section for more information).

  2. Using forge script

    Users can also create a deployment script to automate the deployment process without having to provide the parameters each time. For detailed examples and information, refer to this repository (offline, checked 2026-10-10).

    However, note that there are known issues (explained further in the following section) when using forge script. If any errors occur during deployment, it is recommended to revert back to using forge create.

2.34.3 Testing: ​

This project includes a test script written in Solidity (see examples/evm/use-forge/test/Counter.t.sol file). To run the test, execute the following command in your terminal:

forge test

2.34.4 Troubleshooting: ​

  • Deserialization Error: invalid type: null, expected f64 at line 1 column 240.

    This error occurs when the --legacy flag is not used during contract deployment. Including this flag will resolve the issue.

  • Failed to get EIP-1559 fees

    This error also arises when the --legacy flag is missing. Adding the flag will resolve the problem.

  • Transaction Failure: 0x9cfe621bac130205088168a30470f0cbfdacb22ebb7ce5869a348a7552b7e8b8

    When this error occurs, the transaction has been executed on the chain but returns with an error. You can check the error code in the event broadcasted on the blockchain explorer, as shown in the example screenshot below.

    Possible errors: OutOfGas.

    Explorer event ethereum.Executed for an EVM transaction: its from and to addresses and transaction hash, exitReason Error, and the error OutOfGas

    One possible reason for this error is that the estimated gas is insufficient for the transaction. Increasing the `--gas-estimate-multiplier`` to 200 or higher may resolve the issue.

  • (code: -32603, message: submit transaction to pool failed: InvalidTransaction(InvalidTransaction::Custom(3)), data: None)

    The InvalidTransaction::Custom(3) means GasLimitTooLow in frontier. A higher gas limit is required to avoid this error.

    Note: While using forge script, sometimes raising gas limit still cannot solve this error. In this case a workaround is to switch to forge create

2.34.5 Source files ​

contracts/Counter.sol2.34.5.1 ​

solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

contract Counter {
    int256 count;

    constructor(int256 _count) {
        count = _count;
    }

    function increment() public {
        count += 1;
    }

    function decrement() public {
        count -= 1;
    }

    function getCount() public view returns (int256) {
        return count;
    }
}

script/Counter.s.sol2.34.5.2 ​

solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import "../contracts/Counter.sol";

import "forge-std/console.sol";
import "forge-std/Script.sol";

contract CounterScript is Script {
  function setUp() public {}

  function run() public {
    uint256 deployerPrivateKey = vm.envUint("CALLER_PRIVATE_KEY");

    vm.startBroadcast(deployerPrivateKey);
    new Counter(0);
    vm.stopBroadcast();
  }
}

script/use-forge-create.sh2.34.5.3 ​

bash
#!/usr/bin/env bash

forge create \
  --rpc-url "https://porcini.rootnet.app" \
  --private-key $CALLER_PRIVATE_KEY \
  --legacy \
  --verify \
  --verifier sourcify contracts/Counter.sol:Counter \
  --constructor-args 0

script/use-forge-script.sh2.34.5.4 ​

bash
#!/usr/bin/env bash

forge script \
  ./script/Counter.s.sol:CounterScript \
  --rpc-url "https://porcini.rootnet.app" \
  --private-key $CALLER_PRIVATE_KEY \
  --legacy \
  --broadcast \
  --verify \
  --verifier sourcify \
  -vvvv

test/Counter.t.sol2.34.5.5 ​

solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import "forge-std/Test.sol";
import "../contracts/Counter.sol";

contract CounterTest is Test {
    Counter counter;

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

    function testGetCount() public {
        int value = counter.getCount();
        assertEq(value, 0);
        emit log_int(value);
    }

    function testIncrement() public {
        counter.increment();
        int value = counter.getCount();
        assertEq(value, 1);
        emit log_int(value);
    }

    function testDecrement() public {
        counter.decrement();
        int value = counter.getCount();
        assertEq(value, -1);
        emit log_int(value);
    }
}

foundry.toml2.34.5.6 ​

toml
[profile.default]
src = 'contracts'
test = 'test'
out = 'forge-artifacts'
libs = ['lib']
solc = "0.8.17"

optimizer = true
optimizer-runs = 200
verbosity = 2

[rpc_endpoints]
porcini = "https://porcini.rootnet.app"

package.json2.34.5.7 ​

json
{
  "scripts": {
    "test": "forge test",
    "clean": "forge clean",
    "forge:install": "forge install foundry-rs/forge-std --no-commit --shallow",
    "forge:create": "./script/use-forge-create.sh",
    "forge:script": "./script/use-forge-script.sh",
    "forge:test": "forge test"
  }
}

remappings.txt2.34.5.8 ​

text
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
Source: futureversecom/trn-examples, examples/evm/use-forge (deleted) · commit 44c9e16, 2024-10-31 · Apache-2.0, license · part of Code examples

Associated docs

Where else you might go from here. Following one is optional — this chapter stands without them.

Back matter — read in order
See also — The whole of Back matter as one continuous page, reprinted from its chapters without change.
Code examples
See also — Futureverse’s code examples for The Root Network: scripts for the native API and the EVM, and two contract projects, each with its README and source.
Contents
See also — Every chapter in this book, each with the one line that tells you what you get by reading it.
Front matter — read in order
See also — The whole of Front matter as one continuous page, reprinted from its chapters without change.
Guides for the code examples
See also — How Futureverse’s TRN code examples get a test account: create one in MetaMask and fund it from the Porcini faucet.
How do I deploy a smart contract on The Root Network using hardhat?
See also — The code below is the minimum hardhat configuration to deploy smart contracts on The Root Network.
Index · A
See also — 609 index terms that start with A, each linked to the pages that define or use it.
Index · C
See also — 550 index terms that start with C, each linked to the pages that define or use it.

Curated independently and source-attributed. Not affiliated with Futureverse or TRN Labs. Sources

Curated independently and source-attributed. Not affiliated with Futureverse or TRN Labs.