# 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();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bitroot.gitbook.io/bitroot/developer-documentation/evm-with-foundry.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
