Ethereum Smart Contract Development

Overview

Smart contract development frameworks make it easy to develop, test, and deploy smart contracts on EVM-based blockchains.

The following guide contains:

  1. Deploy your contract by using Hardhat
  2. Deploy your contract by using Truffle
  3. Deploy your contract by using Brownie
  4. Deploy your contract by using Foundry

Using Hardhat

Installing Hardhat

You can skip this section if you already have Hardhat installed or follow that Hardhat Installation guide on the Hardhat website for all details.

We provide you with a very basic process here for convenience:

  1. Install the Hardhat package.
npm install --save-dev hardhat
  1. Initialize a new Hardhat project using the following Hardhat command.
    This creates a basic project for you to set up directories and configuration files.
npx hardhat
  1. After executing the Hardhat command, this menu appears:
888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

👷 Welcome to Hardhat v2.10.1 👷‍

? What do you want to do? … 
❯ Create a JavaScript project
  Create a TypeScript project
  Create an empty hardhat.config.js
  1. In this menu, select Create a JavaScript project and select Enter.
  • Select the current directory as your project base.
  • Type Y when asked to add a .gitignore file.
  • Type Y when asked to install this sample project’s dependencies with npm.

After you complete these steps, you'll have a new Hardhat project.

Hardhat integration

The Fireblocks Hardhat Plugin helps seamlessly integrate Fireblocks into your Hardhat development stack.

You can use it to deploy contracts, sign messages, and send transactions.

Installation

npm install @fireblocks/hardhat-fireblocks

Import the plugin into your hardhat.config.js or hardhat.config.ts file:

require("@fireblocks/hardhat-fireblocks");
const { ApiBaseUrl } = require("@fireblocks/fireblocks-web3-provider");
import "@fireblocks/hardhat-fireblocks";
import { ApiBaseUrl } from "@fireblocks/fireblocks-web3-provider";

Configuration

This plugin extends the HttpNetworkUserConfig object with an optional fireblocks field.

This is an example of how to set this up in your Hardhat configuration file:

module.exports = {
  solidity: "0.8.17",
  networks: {
    goerli: {
      url: "https://rpc.ankr.com/eth_goerli",
      fireblocks: {
        apiBaseUrl: ApiBaseUrl.Sandbox, // If using a sandbox workspace
        privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
        apiKey: process.env.FIREBLOCKS_API_KEY,
        vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
      }
    },
  },
};

If you are not using a Sandbox environment, but rather a regular one, just comment the apiBaseUrl line.

Delete the Lock.sol file that came with your Hardhat boilerplate template:

rm contracts/Lock.sol

Deploy Contract

Now that you have a Hardhat project set up, create your smart contract contracts/hello.sol in the project folder and then deploy it to the Goerli Ethereum Testnet.

Step 1: Create and compile the Solidity file

pragma solidity ^0.8.17;

contract HelloWorld {
    string public greet = "Hello World!";
}

Run the following command to compile it:

npx hardhat compile

Step 2: Update the deployment script

Replace the contents of the deploy.js script with the following basic contract deployment flow:

const hre = require("hardhat");

async function main() {
  const factory = await hre.ethers.getContractFactory("HelloWorld");
  const contract = await factory.deploy();

  await contract.deployed();

  console.log("contract deployed to:", contract.address);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Step 3: Deploy smart contract

Deploy your contract to the Ethereum Goerli Testnet:

npx hardhat run --network goerli scripts/deploy.js

Or:

HARDHAT_NETWORK=goerli node scripts/deploy.js

This should take a couple of minutes to run if everything was configured correctly.

Once the deploy script has finished running, you will see this message if the contract was deployed successfully:

contract deployed to: <contract_address>

Using Truffle

Use the Fireblocks Web3 Provider to seamlessly work with Truffle on top of Fireblocks.

Installation

npm install -g truffle
npm install @fireblocks/fireblocks-web3-provider

Configuration

Step 1:

Set the environment variables

Step 2:

Initialize an example Truffle NFT project:

truffle unbox nft-box

Step 3:

Edit the truffle-config.js file:

require('dotenv').config();
const { FireblocksWeb3Provider, ChainId } = require("@fireblocks/fireblocks-web3-provider");

module.exports = {
  networks: {
    goerli: {
      provider: () => new FireblocksWeb3Provider({
        privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
        apiKey: process.env.FIREBLOCKS_API_KEY,
        vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
        chainId: ChainId.GOERLI,
      }),
      network_id: ChainId.GOERLI,
    },
  },
  compilers: {
    solc: {
      version: "0.8.13"
    }
  },
};

Usage:

truffle migrate --network goerli

Using Brownie

Use the Fireblocks JSON-RPC to seamlessly work with Brownie on top of Fireblocks.

Installation

Step 1 - Brownie installation:

Please follow the Brownie official documentation for installation

Step 2 - Install Fireblocks JSON RPC server:

npm install -g @fireblocks/fireblocks-json-rpc

Setup

Step 1 - Create a new example Brownie project:

brownie bake token
cd token

Step 2 - set environment variables:

Set the environment variables

Step 3 - Add Fireblocks Goerli network to Brownie:

brownie networks add Fireblocks fireblocks-goerli name="Goerli (Fireblocks)" chainid=5 host='http://127.0.0.1:8545/${FIREBLOCKS_API_KEY}' timeout=600

Step 4 - Configure brownie-config.yaml file:

Add dotenv: .env parameter to the config yaml file.

Example:

# exclude SafeMath when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
reports:
  exclude_contracts:
    - SafeMath
dotenv: .env

Usage:

fireblocks-json-rpc -- brownie run --network fireblocks-goerli scripts/token.py

Using Foundry

Installing Foundry

You can skip this section if you already have Foundry installed or follow that Foundry Installation guide , Foundry New Project guide on the Foundry website for all details.

We provide you with a very basic process here for convenience:

curl -L https://foundry.paradigm.xyz | bash
foundryup
forge init hello_foundry
cd hello_foundry
forge build
forge test

After you complete these steps, you'll have a new Foundry project.

Foundry integration

The Fireblocks Local JSON-RPC helps seamlessly integrate Fireblocks into your Foundry development stack.

You can use it to deploy contracts, sign messages, and send transactions.

Installation

npm install -g @fireblocks/fireblocks-json-rpc

Configuration

Configuration can be set via command line flags or environment variables.

Command line flags:

  • Ignore apiBaseUrl if you are not using a sandbox environment
fireblocks-json-rpc --apiKey <key> --privateKey <path_or_contents> --chainId <chainId> --apiBaseUrl https://sandbox-api.fireblocks.io

Environment variables:

  • Ignore FIREBLOCKS_API_BASE_URL if you are not using a sandbox environment
FIREBLOCKS_API_KEY=<key> \
FIREBLOCKS_API_PRIVATE_KEY_PATH=<path_or_contents> \
FIREBLOCKS_CHAIN_ID=<chainId> \
FIREBLOCKS_API_BASE_URL=https://sandbox-api.fireblocks.io
fireblocks-json-rpc

Delete the files that came with your Foundry boilerplate template:

rm test/Counter.t.sol script/Counter.s.sol src/Counter.sol

Deploy Contract - Using 'forge script'

Now that you have a Foundry project set up, create your smart contract src/Hello.sol in the project folder and then deploy it to the Goerli Ethereum Testnet.

Step 1: Create and compile the Solidity file

pragma solidity ^0.8.17;

contract HelloWorld {
    string public greet = "Hello World!";
}

Run the following command to compile it:

forge build

Step 2: Create the deployment script

Create a deployment script script/Hello.s.sol :

pragma solidity ^0.8.17;

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

contract MyScript is Script {
    function run() external {
        vm.startBroadcast();

        HelloWorld hello = new HelloWorld();

        vm.stopBroadcast();
    }
}

Step 3: Deploy smart contract

Deploy your contract to the Ethereum Goerli Testnet (It is recommended to use the --slow parameter in your forge script command, specifically when the script is processing few transactions sequentially):

FIREBLOCKS_API_KEY=12345678-1234-1234-1234-123456789abc \ 
FIREBLOCKS_API_PRIVATE_KEY_PATH=/path/to/secret.key \ 
FIREBLOCKS_CHAIN_ID=5 \
fireblocks-json-rpc --http -- \ 
forge script script/Hello.s.sol:MyScript \
--sender <sender_address> --slow --broadcast --unlocked --rpc-url {} 
  • sender_address can be found in your Fireblocks workspace, through Fireblocks API, or using the JSON RPC directly.
    Get address of vault account 0:
FIREBLOCKS_API_KEY=12345678-1234-1234-1234-123456789abc \ 
FIREBLOCKS_API_PRIVATE_KEY_PATH=/path/to/secret.key \ 
FIREBLOCKS_CHAIN_ID=5 \
fireblocks-json-rpc --http --vaultAccountIds 0 -- curl {} \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"method":"eth_accounts","id":1,"jsonrpc":"2.0"}'

This should take a couple of minutes to run if everything was configured correctly.