Developers Forum for XinFin XDC Network

Daniel Liu
Daniel Liu

Posted on

How to deploy smart contracts using Foundry on XDC Network !

What is Foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. Foundry consists of:

  • Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
  • Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
  • Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
  • Chisel: Fast, utilitarian, and verbose solidity REPL.

Projects Using Foundry

  • Art Gobblers - Contracts for Art Gobblers, the self-sustaining art factory, with custom ERC721 implementation with VRGDAs, GOO integration and differential fuzzing.
  • OpenSea Seaport - Seaport is a new marketplace protocol for safely and efficiently buying and selling NFTs.
  • Optimism Contracts Bedrock - This package contains the smart contracts that compose the on-chain component of Optimism's upcoming Bedrock upgrade.
  • MapleLoan - Set of contracts to facilitate on-chain Loans between Maple Finance Pools and institutional borrowers.
  • Cryptex Finance - Index token that tracks the total cryptocurrency market capitalization. (Optimism version uses Foundry tests).
  • Gov of Venice - Governance of Venice is a new paradigm in DAO governance, attempting to standardise the existence of functional groups within DAOs (Guilds) in terms of how they participate in the Governance process of different DAOs.
  • Beefy Finance - Official repo for strategies and vaults from the Beefy yield optimizer.
  • DeFi Hacks Reproduce - Foundry - Reproduce DeFi hack incidents using Foundry.
  • Tokenlon - Tokenlon is a decentralized exchange and payment settlement protocol.
  • Uniswap V3 Development Book - Development book about Uniswap V3 built using Foundry.
  • Uniswap Permit - Permit2 introduces a low-overhead, next generation token approval/meta-tx system to make token approvals easier, more secure, and more consistent across applications.

Installation

Linux and macOS

If you use Linux or macOS, you can install the latest release by using foundryup. This is the easiest option for Linux and macOS users. Open your terminal and type in the following commands:

curl -L https://foundry.paradigm.xyz | bash
source ${HOME}/.bashrc
foundryup
Enter fullscreen mode Exit fullscreen mode

Image description

Windows

We recommend using Windows Subsystem for Linux (WSL) on Windows. Or you can build from the source: get Rust and Cargo first, then install foundry use the below command

cargo install --git https://github.com/foundry-rs/foundry --profile local --locked foundry-cli anvil chisel
Enter fullscreen mode Exit fullscreen mode

Use Foundry

Initialize project

Start a new project which named hello_foundry with command forge init.

forge init hello_foundry
cd hello_foundry

# check out what forge generated for us
tree . -L 2
Enter fullscreen mode Exit fullscreen mode

Image description

Add openzeppelin-contracts

forge install Openzeppelin/openzeppelin-contracts
Enter fullscreen mode Exit fullscreen mode

Below is the output:

Installing openzeppelin-contracts in "/home/liudan/hello_foundry/lib/openzeppelin-contracts" (url: Some("https://github.com/Openzeppelin/openzeppelin-contracts"), tag: None)
    Installed openzeppelin-contracts v4.8.2
Enter fullscreen mode Exit fullscreen mode

Image description

Create a new contract

Create a file src/MyToken.sol with below codes:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;

import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import { ERC20Burnable } from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";

contract MyToken is ERC20, ERC20Burnable {
    constructor(string memory name, string memory symbol, uint256 initialSupply) ERC20(name, symbol) {
        _mint(msg.sender, initialSupply);
    }

    function mint(address to, uint256 amount) public {
        _mint(to, amount);
    }
}

Enter fullscreen mode Exit fullscreen mode

Compile contracts

Build the project with command forge build:

forge build
Enter fullscreen mode Exit fullscreen mode

Below is the output:

[⠊] Compiling...
[⠆] Installing solc version 0.8.19
[⠔] Successfully installed solc 0.8.19
[⠆] Compiling 28 files with 0.8.19
[⠒] Solc 0.8.19 finished in 2.21s
Compiler run successful
Enter fullscreen mode Exit fullscreen mode

Image description

Run tests

Run the tests with command forge test:

forge test
Enter fullscreen mode Exit fullscreen mode

Below is the output:

[⠰] Compiling...
No files changed, compilation skipped

Running 2 tests for test/Counter.t.sol:CounterTest
[PASS] testIncrement() (gas: 28334)
[PASS] testSetNumber(uint256) (runs: 256, μ: 27087, ~: 28409)
Test result: ok. 2 passed; 0 failed; finished in 9.84ms
Enter fullscreen mode Exit fullscreen mode

Image description

To print the gas report simply run: forge test --gas-report.

Deploy

Set environment variables

export XINFIN_RPC_URL="https://erpc.xinfin.network/"
export APOTHEM_RPC_URL="https://erpc.apothem.network/"
export PRIVATE_KEY=<YOUR_PRIVATE_KEY>
Enter fullscreen mode Exit fullscreen mode

Change YOUR_PRIVATE_KEY without 0x-prefix in the above command.

Deploy contract Counter

Deploy contracts Counter to testnet apothem with the command:

forge create --legacy --rpc-url ${APOTHEM_RPC_URL} \
--private-key ${PRIVATE_KEY} \
src/Counter.sol:Counter
Enter fullscreen mode Exit fullscreen mode

We must use the parameter --legacy because EIP-1559 not activated on XinFin blockchain. Below is the output:

[⠰] Compiling...
No files changed, compilation skipped
Deployer: 0xD4CE02705041F04135f1949Bc835c1Fe0885513c
Deployed to: 0x1aB1F3725Ff935d60AaC09Cc6C8075e61B6eDBF9
Transaction hash: 0xa685876f06dc5b73f6e2a5794a00ffc7b847b0d7a74c6f78b6e8a69b9be083da
Enter fullscreen mode Exit fullscreen mode

Image description

Deploy contract MyToken

Deploy contracts MyToken to testnet apothem with the command:

forge create --legacy --rpc-url ${APOTHEM_RPC_URL} \
--constructor-args "My Token" "MTK" 1000000000000000000000 \
--private-key ${PRIVATE_KEY} \
src/MyToken.sol:MyToken
Enter fullscreen mode Exit fullscreen mode

Below is the output:

[⠔] Compiling...
No files changed, compilation skipped
Deployer: 0xD4CE02705041F04135f1949Bc835c1Fe0885513c
Deployed to: 0xC793d9EE5DB38BBd077680A490e0fAB2B326f026
Transaction hash: 0x2ab002d0a01aa350ec8cf336b469110c2811aa40ae099dc57c829e8b58373943
Enter fullscreen mode Exit fullscreen mode

Image description

Verify contracts

Verify contract Counter

The contract Counter is very simple, just copy codes from file src/Counter.sol, below is the verify result:

https://explorer.apothem.network/address/xdc1ab1f3725ff935d60aac09cc6c8075e61b6edbf9#readContract

Verify contract MyToken

We need to flatten contract MyToken with command forge flatten first:

forge flatten --output src/MyToken.flatten.sol src/MyToken.sol
Enter fullscreen mode Exit fullscreen mode

Below is the output:

Flattened file written at src/MyToken.flatten.sol
Enter fullscreen mode Exit fullscreen mode

The copy codes from file src/MyToken.flatten.sol, below is the verify result:

https://explorer.apothem.network/address/xdcc793d9ee5db38bbd077680a490e0fab2b326f026#readContract

References

Discussion (0)