> For the complete documentation index, see [llms.txt](https://bitroot.gitbook.io/bitroot/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bitroot.gitbook.io/bitroot/developer-documentation/evm-with-foundry.md).

# EVM with Foundry

### Bitroot EVM Smart Contract Development with Foundry <a href="#bitroot-evm-smart-contract-development-with-foundry" id="bitroot-evm-smart-contract-development-with-foundry"></a>

Since Bitroot is an EVM compatible chain, existing EVM tooling like [foundry forge ](https://book.getfoundry.sh/) or other could be re-used.

In this example we will be using [foundry tooling ](https://book.getfoundry.sh/).

Install the [foundry tooling ](https://book.getfoundry.sh/) by following this [Installation guide ](https://book.getfoundry.sh/getting-started/installation.html).

Create a new project following the [Creating New Project Guide ](https://book.getfoundry.sh/projects/creating-a-new-project).

Also make sure you have a wallet on Bitroot network.

Once project is created, tweak the contract code to the following, by adding a `getCounter` function:

```
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;
 
contract Counter {
    uint256 public number;
 
    function setNumber(uint256 newNumber) public {
        number = newNumber;
    }
 
    function increment() public {
        number++;
    }
 
    function getCount() public view returns (uint256) {
        return number;
    }
}
 
```

And the test code to the following:

```
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;
 
import {Test, console} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";
 
contract CounterTest is Test {
    Counter public counter;
 
    function setUp() public {
        counter = new Counter();
        counter.setNumber(0);
    }
 
    function test_Increment() public {
        counter.increment();
        assertEq(counter.number(), 1);
    }
 
    function testFuzz_SetNumber(uint256 x) public {
        counter.setNumber(x);
        assertEq(counter.number(), x);
    }
 
    function test_GetCount() public {
        uint256 initialCount = counter.getCount();
        counter.increment();
        assertEq(counter.getCount(), initialCount + 1);
    }
}

```

Run the tests with the following command:

```
$ forge test
```

If tests pass, deploy the contract to the Bitroot chain with the following command:

```
$ forge create --rpc-url $BITROOT_NODE_URI --mnemonic $MNEMONIC src/Counter.sol:Counter --broadcast
```

Where `$BITROOT_NODE_URI` is the URI of the Bitroot node and `$MNEMONIC` is the mnemonic of the account that will deploy the contract. If you run local Bitroot node, the address will be `http://localhost:8545` , otherwise you could grab a `evm_rpc` url from the [registry ](https://github.com/sei-protocol/chain-registry/blob/main/chains.json). If deployment is successful, you will get the EVM contract address in the output.

```
[⠒] Compiling...
No files changed, compilation skipped
Deployer: $0X_DEPLOYER_ADDRESS
Deployed to: $0X_CONTRACT_ADDRESS
Transaction hash: $0X_TX_HASH
```

Let’s use the `cast` command to query the contract:

```
$ cast call $0X_CONTRACT_ADDRESS "getCount()(uint256)" --rpc-url $BITROOT_NODE_URI
```

The command should return `0` as the initial value of the counter.

Now we can use the `cast` command to call the `increment` function:

```
$ cast send $0X_CONTRACT_ADDRESS "increment()" --mnemonic $MNEMONIC --rpc-url $BITROOT_NODE_URI
```

If command is successful, you will get the transaction hash and other info back.

Now let’s call the `getCount` function again and this case it should return `1`.

```
$ cast call $0X_CONTRACT_ADDRESS "getCount()(uint256)" --rpc-url $BITROOT_NODE_URI
```

Foundry generates the ABI for the contract in the `out` folder. You can use this ABI to interact with the contract from other tools like `ethers.js` or `web3.js`.

#### Calling contract using ethers.js <a href="#calling-contract-using-ethersjs" id="calling-contract-using-ethersjs"></a>

To call or query the contract from a frontend or a NodeJS script, you could use `ethers.js` like:

```
import { ethers } from 'ethers';
 
const privateKey = YOUR_PRIVATE_KEY;
const evmRpcEndpoint = YOUR_EVM_RPC_ENDPOINT;
const provider = new ethers.JsonRpcProvider(evmRpcEndpoint);
const signer = new ethers.Wallet(privateKey, provider);
 
if (!signer) {
    console.log('No signer found');
    return;
}
const abi = [
 {
      "type": "function",
      "name": "setNumber",
      "inputs": [
        {
          "name": "newNumber",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "outputs": [],
      "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "getCount",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "int256",
                "internalType": "int256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "increment",
        "inputs": [],
        "outputs": [],
        "stateMutability": "nonpayable"
    }
];
 
// Define the address of the deployed contract
const contractAddress = `0X_CONTRACT_ADDRESS`;
 
// Create a new instance of the ethers.js Contract object
const contract = new ethers.Contract(contractAddress, abi, signer);
 
// Call the contract's functions
async function getCount() {
    const count = await contract.getCount();
    console.log(count.toString());
}
 
async function increment() {
    const txResponse = await contract.increment();
    const mintedTx = await txResponse.wait();
    console.log(mintedTx);
}
 
await increment();
await getCount();
```
