# Foundry

## Using Foundry to Deploy To Phron <a href="#using-foundry-to-deploy-to-phron" id="using-foundry-to-deploy-to-phron"></a>

### Introduction <a href="#introduction" id="introduction"></a>

[Foundry](https://github.com/foundry-rs/foundry) is an Ethereum development environment written in Rust that helps developers manage dependencies, compile projects, run tests, deploy contracts, and interact with blockchains from the command line. Foundry can directly interact with Phron's Ethereum API so it can be used to deploy smart contracts into Phron.

Four tools make up Foundry:

* [**Forge**](https://book.getfoundry.sh/forge) - compiles, tests, and deploys contracts
* [**Cast**](https://book.getfoundry.sh/cast) - a command line interface for interacting with contracts
* [**Anvil**](https://book.getfoundry.sh/anvil) - a local TestNet node for development purposes that can fork preexisting networks
* [**Chisel**](https://book.getfoundry.sh/chisel) - a Solidity REPL for quickly testing Solidity snippets

This guide will cover how to use Foundry to compile, deploy, and debug Ethereum smart contracts on the Phron TestNet.

### Checking Prerequisites <a href="#checking-prerequisites" id="checking-prerequisites"></a>

To get started, you will need the following:

* Have an account with funds. You can get DEV tokens for testing on Phron once every 24 hours from the [Phron Faucet](https://faucet.phron.ai/)
* To test out the examples in this guide on Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers
* Have [Foundry installed](https://book.getfoundry.sh/getting-started/installation)

### Creating a Foundry Project <a href="#creating-a-foundry-project" id="creating-a-foundry-project"></a>

You will need to create a Foundry project if you don't already have one. You can create one by completing the following steps:

1. Install Foundry if you haven't already. If on Linux or MacOS, you can run these commands:

   ```bash
   curl -L https://foundry.paradigm.xyz | bash
   foundryup
   ```

   If on Windows, you'll have to install Rust and then build Foundry from source:

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs/ | sh
   cargo install --git https://github.com/foundry-rs/foundry foundry-cli anvil --bins --locked
   </code></pre>
2. Create the project, which will create a folder with three folders within it, and open it:

   ```bash
   forge init foundry && cd foundry
   ```

With the default project created, you should see three folders.

* `lib` - all of the project's dependencies in the form of git submodules
* `src` - where to put your smart contracts (with functionality)
* `test` - where to put the forge tests for your project, which are written in Solidity

In addition to these three folders, a git project will also be created along with a prewritten `.gitignore` file with relevant file types and folders ignored.

### The Source Folder <a href="#the-src-folder" id="the-src-folder"></a>

The `src` folder may already contain `Counter.sol`, a minimal Solidity contract. Feel free to delete it. To avoid errors, you should also delete the `Counter.s.sol` file in the `scripts` folder and the `Counter.t.sol` file in the `test` folder. In the following steps, you will be deploying an ERC-20 contract. In the contracts directory, you can create the `MyToken.sol` file:

```bash
cd src
touch MyToken.sol
```

Open the file and add the following contract to it:

```solidity
pragma solidity ^0.8.0;

// Import OpenZeppelin Contract
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// This ERC-20 contract mints the specified amount of tokens to the contract creator
contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MYTOK") {
        _mint(msg.sender, initialSupply);
    }
}
```

Before you attempt to compile, install OpenZeppelin contracts as a dependency. You may have to commit previous changes to git beforehand. By default, Foundry uses git submodules instead of npm packages, so the traditional npm import path and command are not used. Instead, use the name of OpenZeppelin's GitHub repository:

```bash
forge install OpenZeppelin/openzeppelin-contracts
```

### Compiling Solidity <a href="#compiling-solidity" id="compiling-solidity"></a>

Once all dependencies have been installed, you can compile the contract:

```bash
forge build
```

{% code overflow="wrap" %}

```bash
forge build[⠒] Compiling...[⠰] Compiling 30 files with 0.8.23[⠔] Solc 0.8.23 finished in 2.29sCompiler run successful!
```

{% endcode %}

After compilation, two folders will be created: `out` and `cache`. The ABI and bytecode for your contracts will be contained within the `out` folder. These two folders are already ignored by the `.gitignore` included in the default Foundry project initialization.

### Deploying the Contract <a href="#deploying-the-contract" id="deploying-the-contract"></a>

There are two primary ways to deploy contracts using Foundry. The first is the straightforward command `forge create`. There's also the more flexible and powerful option of foundry scripting, which runs simulations before any deployments. In the following sections, `forge create` and foundry scripting will both be covered.

#### Using Forge Create <a href="#using-forge-create" id="using-forge-create"></a>

Deploying the contract with `forge create` takes a single command, but you must include an RPC endpoint, a funded private key, and constructor arguments. `MyToken.sol` asks for an initial supply of tokens in its constructor, so each of the following commands includes 100 as a constructor argument. You can deploy the `MyToken.sol` contract using the following command for the correct network:

```bash
forge create --rpc-url INSERT_RPC_API_ENDPOINT \
--constructor-args 100 \
--private-key INSERT_YOUR_PRIVATE_KEY \
src/MyToken.sol:MyToken
```

After you've deployed the contract and a few seconds have passed, you should see the address in the terminal.

{% code overflow="wrap" %}

```bash
forge create --rpc-url https://testnet.phron.ai \ --constructor-args 100 \ --private-key INSERT_PRIVATE_KEY \ src/MyToken.sol:MyToken
[⠒] Compiling...No files changed, compilation skippedDeployer: 0x3B939FeaD1557C741Ff06492FD0127bd287A421eDeployed to: 0xc111402Aa1136ff6224106709ae51864512eC68fTransaction hash: 0xd77fc26aa296e81f35718b5878cda98e8371f6bf33b0f57e7d92997a36cf6465
```

{% endcode %}

Congratulations! Your contract is live! Save the address, as you will use it to interact with this contract instance in the next step.

#### Deploying via Solidity Scripting <a href="#deploying-via-solidity-scripting" id="deploying-via-solidity-scripting"></a>

Solidity scripting is a more powerful and flexible way to deploy contracts than [`forge create`](https://docs.moonbeam.network/builders/ethereum/dev-env/foundry/#deploying-the-contract). Writing a Solidity script is identical to writing a typical Solidity smart contract, though you won't ever deploy this contract.

You can tailor the behavior of `forge script` with various parameters. All components are optional except for local simulation, which is a required part of every run. The `forge script` command will attempt to execute all applicable steps in the following order:

1. **Local simulation** - simulate the transaction(s) in a local EVM
2. **Onchain simulation** - simulate the transaction(s) via the provided RPC URL
3. **Broadcasting** - when the `--broadcast` flag is provided, and simulations succeed, the transaction(s) are dispatched
4. **Verification** - API-based smart contract verification when the `--verify` flag and a valid API key are provided

Now, go ahead and write the script. In the script folder, create a file named `MyToken.s.sol`. Copy and paste the contents of the below file.

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import "../src/MyToken.sol";

contract MyScript is Script {
    function run() external {
        uint256 deployerPrivateKey = INSERT_PRIVATE_KEY;
        vm.startBroadcast(deployerPrivateKey);

        MyToken mytoken = new MyToken(1000000000);

        vm.stopBroadcast();
    }
}
```

{% hint style="warning" %}

### Remember

Remember never to store a production private key in a file, as shown above. This example is strictly for demonstration purposes.
{% endhint %}

Notice that even though the above script is not being deployed, it still requires all the typical formatting for a Solidity contract, such as the pragma statement.

You can deploy the `MyToken.sol` contract with the below command. Remember that it will execute all relevant steps in order. For this example, Foundry will first attempt a local simulation and a simulation against the provided RPC before deploying the contract. Foundry won't proceed with the deployment if any of the simulations fail.

{% code overflow="wrap" %}

```bash
forge script script/MyToken.s.sol --rpc-url https://testnet.phron.ai --broadcast
```

{% endcode %}

If your script's execution succeeds, your terminal should resemble the output below.

{% code overflow="wrap" %}

```bash
forge script script/MyToken.s.sol --rpc-url https://testnet.phron.ai --broadcast[⠒] Compiling...Script ran successfully.EIP-3855 is not supported in one or more of the RPCs used. Unsupported Chain IDs: 7744.Contracts deployed with a Solidity version equal or higher than 0.8.20 might not work properly.For more information, please see https://eips.ethereum.org/EIPS/eip-3855## Setting up 1 EVM.==========================
Chain 1287Estimated gas price: 3.25 gweiEstimated total gas used for script: 1346155Estimated amount required: 0.00437500375 ETH==========================
Finding wallets for all the necessary addresses...Sending transactions [0 - 0].⠁ [00:00:00] [#################################################] 1/1 txes (0.0s)Waiting for receipts. ⠉ [00:00:25] [#############################################] 1/1 receipts (0.0s)##### phron
✅ [Success]Hash: 0x95766ca2c8bc94171f9de783652d62468f004d686eb5ab82b3546774eee301bc Contract Address: 0x2A19aD12E9e8479207B78c39f5bCc848D386b9DABlock: 5881522Paid: 0.00309613125 ETH (990762 gas * 3.125 gwei)ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.Total Paid: 0.00309613125 ETH (990762 gas * avg 3.125 gwei)Transactions saved to: /Users/ubuntu-jammy/foundry/foundry/broadcast/MyToken.s.sol/1287/run-latest.jsonSensitive values saved to: /Users/ubuntu-jammy/foundry/foundry/cache/MyToken.s.sol/1287/run-latest.json
```

{% endcode %}

And that's it! For more information about Solidity scripting with Foundry, be sure to check out [Foundry's documentation site](https://book.getfoundry.sh/tutorials/solidity-scripting).

### Interacting with the Contract <a href="#interacting-with-the-contract" id="interacting-with-the-contract"></a>

Foundry includes cast, a CLI for performing Ethereum RPC calls.

Try to retrieve your token's name using Cast, where `INSERT_YOUR_CONTRACT_ADDRESS` is the address of the contract that you deployed in the previous section:

```bash
cast call INSERT_YOUR_CONTRACT_ADDRESS "name()" --rpc-url INSERT_RPC_API_ENDPOINT
```

You should get this data in hexadecimal format:

{% code overflow="wrap" %}

```bash
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000074d79546f6b656e00000000000000000000000000000000000000000000000000
```

{% endcode %}

This is far from readable, but you can use Cast to convert it into your desired format. In this case, the data is text, so you can convert it into ASCII characters to see "My Token":

{% code overflow="wrap" %}

```bash
cast --to-ascii 0x000000000000000000000000000000000000000000000000000000000000002000 000000000000000000000000000000000000000000000000000000000000074d7954 6f6b656e00000000000000000000000000000000000000000000000000
MyToken
```

{% endcode %}

{% code overflow="wrap" %}

```bash
cast --to-ascii 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000074d79546f6b656e00000000000000000000000000000000000000000000000000
```

{% endcode %}

You can also mutate data with cast as well. Try burning tokens by sending them to the zero address.

```bash
cast send --private-key INSERT_YOUR_PRIVATE_KEY \
--rpc-url INSERT_RPC_API_ENDPOINT \
--chain 7744 \
INSERT_YOUR_CONTRACT_ADDRESS \
"transfer(address,uint256)" 0x0000000000000000000000000000000000000001 1
```

The transaction will be signed by your Phron account and be broadcast to the network. The output should look similar to:

{% code overflow="wrap" %}

```bash
cast send --private-key INSERT_PRIVATE_KEY \ --rpc-url https://testnet.phron.ai \ --chain 7744 \ INSERT_CONTRACT_ADDRESS \ "transfer(address,uint256)" 0x0000000000000000000000000000000000000001 1

blockHash 0x6f99fac1bb49feccb7b0476e0ffcd3cef4c456aa9111e193ce11c7a1ab62314eblockNumber 5892860contractAddresscumulativeGasUsed 51332effectiveGasPrice 3125000000gasUsed 51332logs [{"address":"0xc111402aa1136ff6224106709ae51864512ec68f","topics":["0xddf252ad1be2c89b69 c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000003b939fead155 7c741ff06492fd0127bd287a421e", "0x0000000000000000000000000000000000000000000000000000000000000001"], "data":"0x0000000000000000000000000000000000000 000000000000000000000000001", "blockHash":"0x6f99fac1bb49feccb7b0476e0ffcd3cef4c4 56aa9111e193ce11c7a1ab62314e", "blockNumber":"0x59eafc", "transactionHash":"0xdd5f11be68d5 2967356ccf34b9a4b2632d0d5ac8932ff27e72c544320dec33e3", "transactionIndex":"0x0","logIndex":"0x0","transactionLogIndex":"0x0","removed":false}]logsBloom 0x000000000000000000000000000000000000000000000000000000000000000000000000000000004 00000000000000000000000000000000000000000040000000000000000000000000008000000000000 00000004000000000000000000000000000000000000000100000000000000000000000000000000001 00000010000000000000000000000000000000000000000000000000000000002000000040000000000 00000000000000000000000000000000000000000000000000000000002000000000000000000000000 00000000000000000000000000004000000000000000000000000000000000000000000000000000000 0001000000rootstatus 1transactionHash 0xdd5f11be68d52967356ccf34b9a4b2632d0d5ac8932ff27e72c544320dec33e3transactionIndex 0type 2
```

{% endcode %}

Congratulations, you have successfully deployed and interacted with a contract using Foundry!

### Forking with Anvil <a href="#forking-with-cast-anvil" id="forking-with-cast-anvil"></a>

As previously mentioned, [Anvil](https://book.getfoundry.sh/anvil) is a local TestNet node for development purposes that can fork preexisting networks. Forking Phron allows you to interact with live contracts deployed on the network.

There are some limitations to be aware of when forking with Anvil. Since Anvil is based on an EVM implementation, you cannot interact with any of the Phron precompiled contracts and their functions. Precompiles are a part of the Substrate implementation and therefore cannot be replicated in the simulated EVM environment. This prohibits you from interacting with cross-chain assets on Phron and Substrate-based functionality such as staking and governance.

To fork Phron, you will need to have your own endpoint and API key which you can get from one of the supported Endpoint Providers.

To fork Phron from the command line, you can run the following command from within your Foundry project directory:

```bash
anvil --fork-url INSERT_RPC_API_ENDPOINT
```

Your forked instance will have 10 development accounts that are pre-funded with 10,000 test tokens. The forked instance is available at `http://127.0.0.1:8545/`. The output in your terminal should resemble the following:

{% code overflow="wrap" %}

```bash
anvil --fork-url https://testnet.phron.ai

Available Accounts==================(0) "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" (10000.000000000000000000 ETH)(1) "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" (10000.000000000000000000 ETH)(2) "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" (10000.000000000000000000 ETH)(3) "0x90F79bf6EB2c4f870365E785982E1f101E93b906" (10000.000000000000000000 ETH)(4) "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" (10000.000000000000000000 ETH)(5) "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" (10000.000000000000000000 ETH)(6) "0x976EA74026E726554dB657fA54763abd0C3a0aa9" (10000.000000000000000000 ETH)(7) "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955" (10000.000000000000000000 ETH)(8) "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f" (10000.000000000000000000 ETH)(9) "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" (10000.000000000000000000 ETH)
Private Keys==================(0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80(1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d(2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a(3) 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6(4) 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a(5) 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba(6) 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e(7) 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356(8) 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97(9) 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
Wallet==================Mnemonic: test test test test test test test test test test test junkDerivation path: m/44'/60'/0'/0/
Fork==================Endpoint: https://testnet.phron.networkBlock number: 5892944Block hash: 0xc9579299f55d507c305d5357d4c1b9d9c550788ddb471b0231d8d0146e7144b7Chain ID: 7744
Base Fee==================125000000
Gas Limit==================30000000
Genesis Timestamp==================1705278817
Listening on 127.0.0.1:8545
```

{% endcode %}

To verify you have forked the network, you can query the latest block number:

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 
```

{% endcode %}

If you convert the `result` from [hex to decimal](https://www.rapidtables.com/convert/number/hex-to-decimal.html), you should get the latest block number from the time you forked the network. You can cross reference the block number using a block explorer.

From here you can deploy new contracts to your forked instance of Phron or interact with contracts already deployed. Building off of the previous example in this guide, you can make a call using Cast to check the balance of the minted MYTOK tokens in the account you deployed the contract with:

{% code overflow="wrap" %}

```bash
cast call INSERT_CONTRACT_ADDRESS  "balanceOf(address)(uint256)" INSERT_YOUR_ADDRESS --rpc-url http://localhost:8545
```

{% endcode %}

### Using Chisel <a href="#using-chisel" id="using-chisel"></a>

Chisel is a Solidity REPL or shell. It allows a developer to write Solidity directly in the console for testing small snippets of code, letting developers skip the project setup and contract deployment steps for what should be a quick process.

Since Chisel is mainly useful for quick testing, it can be used outside of a Foundry project. But, if executed within a Foundry project, it will keep the configurations within `foundry.toml` when running.

For this example, you will be testing out some of the features of `abi` within Solidity because it is complex enough to demonstrate how Chisel could be useful. To get started using Chisel, run the following in the command line to start the shell:

```bash
chisel
```

In the shell, you can write Solidity code as if it were running within a function:

```bash
bytes memory myData = abi.encode(100, true, "Develop on Phron");
```

Let's say you were interested in how `abi` encoded data because you're looking into how to most efficiently store data on the blockchain and thus save gas. To view how the `myData` is stored in memory, you can use the following command while in the Chisel shell:

```bash
!memdump
```

`memdump` will dump all of the data in your current session. You'll likely see something like this below. If you aren't good at reading hexadecimal or if you don't know how ABI encoding works, then you might not be able to find where the `myData` variable has been stored.

{% code overflow="wrap" %}

```bash
chisel
Welcome to Chisel! Type `!help` to show available commands. bytes memory myData = abi.encode(100, true, "Develop on Phron");
!memdump[0x00:0x20]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x20:0x40]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x40:0x60]: 0x0000000000000000000000000000000000000000000000000000000000000140[0x60:0x80]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x80:0xa0]: 0x00000000000000000000000000000000000000000000000000000000000000a0[0xa0:0xc0]: 0x0000000000000000000000000000000000000000000000000000000000000064[0xc0:0xe0]: 0x0000000000000000000000000000000000000000000000000000000000000001[0xe0:0x100]: 0x0000000000000000000000000000000000000000000000000000000000000060[0x100:0x120]: 0x0000000000000000000000000000000000000000000000000000000000000013[0x120:0x140]: 0x446576656c6f70206f6e204d6f6f6e6265616d00000000000000000000000000
```

{% endcode %}

Fortunately, Chisel lets you easily figure out where this information is stored. Using the `!rawstack` command, you can find the location in the stack where the value of a variable:

```bash
!rawstack myData
```

In this situation, since bytes is over 32 bytes in length, the memory pointer is displayed instead. But that's exactly what's needed since you already know the entirety of the stack from the `!memdump` command.

{% code overflow="wrap" %}

```bash
chisel
Welcome to Chisel! Type `!help` to show available commands. bytes memory myData = abi.encode(100, true, "Develop on Phron");
!memdump[0x00:0x20]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x20:0x40]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x40:0x60]: 0x0000000000000000000000000000000000000000000000000000000000000140[0x60:0x80]: 0x0000000000000000000000000000000000000000000000000000000000000000[0x80:0xa0]: 0x00000000000000000000000000000000000000000000000000000000000000a0[0xa0:0xc0]: 0x0000000000000000000000000000000000000000000000000000000000000064[0xc0:0xe0]: 0x0000000000000000000000000000000000000000000000000000000000000001[0xe0:0x100]: 0x0000000000000000000000000000000000000000000000000000000000000060[0x100:0x120]: 0x0000000000000000000000000000000000000000000000000000000000000013[0x120:0x140]: 0x446576656c6f70206f6e204d6f6f6e6265616d00000000000000000000000000 !rawstack myData
Type: bytes32 └ Data: 0x0000000000000000000000000000000000000000000000000000000000000080
```

{% endcode %}

The `!rawstack` command shows that the `myData` variable is stored at `0x80`, so when comparing this with the memory dump retrieved from the `!memdump` command, it looks like `myData` is stored like this:

```bash
[0x80:0xa0]: 0x00000000000000000000000000000000000000000000000000000000000000a0
[0xa0:0xc0]: 0x0000000000000000000000000000000000000000000000000000000000000064
[0xc0:0xe0]: 0x0000000000000000000000000000000000000000000000000000000000000001
[0xe0:0x100]: 0x0000000000000000000000000000000000000000000000000000000000000060
[0x100:0x120]: 0x0000000000000000000000000000000000000000000000000000000000000013
[0x120:0x140]: 0x446576656c6f70206f6e204d6f6f6e6265616d00000000000000000000000000
```

At first glance, this makes sense, since `0xa0` has a value of `0x64` which is equal to 100, and `0xc0` has a value of `0x01` which is equal to true. If you want to learn more about how ABI-encoding works, the [Solidity documentation for ABI is helpful](https://docs.soliditylang.org/en/v0.8.18/abi-spec.html). In this case, there are a lot of zeros in this method of data packing, so as a smart contract developer you might instead try to use structs or pack the data together more efficiently with bitwise code.

Since you're done with this code, you can clear the state of Chisel so that it doesn't mess with any future logic that you want to try out (while running the same instance of Chisel):

```bash
!clear
```

There's an even easier way to test with Chisel. When writing code that ends with a semicolon (`;`), Chisel will run it as a statement, storing its value in Chisel's runtime state. But if you only needed to see how the ABI-encoded data was represented, then you could get away with running the code as an expression. To try this out with the same `abi` example, write the following in the Chisel shell:

```bash
abi.encode(100, true, "Develop on Phron")
```

You should see something like the following:

{% code overflow="wrap" %}

```bash
!clearCleared session! abi.encode(100, true, "Develop on Phron")Type: dynamic bytes├ Hex (Memory):├─ Length ([0x00:0x20]): 0x00000000000000000000000000000000000000000000000000000000000000a0├─ Contents ([0x20:..]): 0x000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000134446576656c6f70206f6e204d6f6f6e6265616d00000000000000000000000000├ Hex (Tuple Encoded):├─ Pointer ([0x00:0x20]): 0x0000000000000000000000000000000000000000000000000000000000000020├─ Length ([0x20:0x40]): 0x00000000000000000000000000000000000000000000000000000000000000a0└─ Contents ([0x40:..]): 0x000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000134446576656c6f70206f6e204d6f6f6e6265616d00000000000000000000000000
```

{% endcode %}

While it doesn't display the data in the same way, you still get the contents of the data, and it also further breaks down how the information is coded, such as letting you know that the `0xa0` value defines the length of the data.

By default, when you leave the Chisel shell, none of the data is persisted. But you can instruct chisel to do so. For example, you can take the following steps to store a variable:

1. Store a `uint256` in Chisel

   ```bash
   uint256 myNumber = 101;
   ```
2. Store the session with `!save`. For this example, you can use the number `1` as a save ID

   ```bash
   !save 1
   ```
3. Quit the session<br>

   ```bash
   !quit
   ```

Then to view and interact with your stored Chisel states, you can take the following steps:

1. View a list of saved Chisel states

   ```bash
   chisel list
   ```
2. Load your stored states

   ```bash
   chisel load 1
   ```
3. View the `uint256` saved in Chisel from the previous set of steps

   ```bash
   !rawstack myNumber
   ```

{% code overflow="wrap" %}

```bash
uint256 myNumber = 101; !save 1 Saved session to cache with ID = 1 !quitchisel list⚒️ Chisel Sessions├─ "2024-01-15 01:17:34" - chisel-1.jsonchisel load 1Welcome to Chisel! Type `!help` to show available commands. !rawstack myNumberType: bytes32└ Data: 0x0000000000000000000000000000000000000000000000000000000000000065
```

{% endcode %}

You can even fork networks while using Chisel:

```
!fork https://testnet.phronscan.io
```

Then, for example, you can query the balance of one of Phron's collators:

```solidity
0x12E7BCCA9b1B15f33585b5fc898B967149BDb9a5.balance
```

{% code overflow="wrap" %}

```bash
!fork https://testnet.phron.networkSet fork URL to https://testnet.phronscan.io 0x12E7BCCA9b1B15f33585b5fc898B967149BDb9a5.balanceType: uint├ Hex: 0x000000000000000000000000000000000000000000000358affd3d76ebb78555└ Decimal: 15803094286802091476309
```

{% endcode %}

If you want to learn more about Chisel, download Foundry and refer to its [official reference page](https://book.getfoundry.sh/reference/chisel).

### Foundry With Hardhat <a href="#foundry-with-hardhat" id="foundry-with-hardhat"></a>

Often, there will be the case where a project that you wish to integrate with has all of its setup within Hardhat, making it an arduous task to convert the entirety of the project into Foundry. This additional work is avoidable by creating a hybrid project that uses both Hardhat and Foundry features together. This is possible with Hardhat's [hardhat-foundry plugin](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-foundry).

To convert your preexisting Foundry project to a hybrid project, you will essentially have to install a Hardhat project into the same folder:

```bash
npm init
npm install --save-dev hardhat @nomicfoundation/hardhat-foundry
npx hardhat init
```

For more information, please refer to our documentation on [Creating a Hardhat Project](https://docs.moonbeam.network/builders/ethereum/dev-env/hardhat/#creating-a-hardhat-project).

After initializing the new Hardhat project, a few new folders and files should appear: `contracts`, `hardhat.config.js`, `scripts`, and `test/Lock.js`. You'll need to make a few modifications to create a hybrid project:

1. Edit the `hardhat.config.js` file within your repository. Open it up, and at the top, add the following:

   ```bash
   require("@nomicfoundation/hardhat-foundry");
   ```

   After adding the `hardhat-foundry` plugin, the typical `contracts` folders for Hardhat will not work because now Hardhat expects all smart contracts to be stored within Foundry's `src` folder
2. Move all smart contracts within the `contracts` folder into the `src` folder, and then delete the `contracts` folder
3. Edit the `foundry.toml` file to ensure that dependencies installed via Git submodules and npm can be compiled by the Forge tool. Edit the `profile.default` to ensure that the `libs` entry has both `lib` and `node_modules`:

   ```javascript
   [profile.default]
   src = 'src'
   out = 'out'
   libs = ['lib', 'node_modules']
   solc = '0.8.20'
   evm_version = 'london'
   ```

Now both `forge build` and `npx hardhat compile` should work regardless of the dependencies.

Both `forge test` and `npx hardhat test` should now be able to access all smart contracts and dependencies. `forge test` will only test the Solidity tests, whereas `npx hardhat test` will only test the JavaScript tests. If you would like to use them in conjunction, then you can create a new script within your `package.json` file:

```json
"scripts": {
    "test": "npx hardhat test && forge test"
}
```

You can run this command with:

```bash
npm run test
```

Finally, while not necessary, it could be worthwhile to move all JavaScript scripts from the `scripts` folder into Foundry's `script` folder and delete the `scripts` folder so that you don't have two folders that serve the same purpose.

This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (<https://docs.Phron.ai/>). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.


---

# 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://docs.phron.ai/developers/build-with-phronai/smart-contracts-development/solidity-contracts/phron-toolkit/dev-environments/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.
