DEV Community

Gabriel Rossi Lopes
Gabriel Rossi Lopes

Posted on • Originally published at Medium

Effortless Smart Contract Deployments

In the rapidly evolving world of blockchain technology, automating the deployment of smart contracts has become essential for developers striving to optimize their workflows. In this article, I’ll guide you through the step-by-step process of creating a GitHub Action that simplifies deploying smart contracts to the Sepolia test network. By harnessing the power of GitHub Actions, you can achieve a deployment process that is not only efficient but also secure.

Throughout this tutorial, you will learn how to set up a seamless workflow for your smart contract deployments. We’ll cover everything from obtaining Sepolia ETH using faucets to acquiring an Infura API key for accessing the RPC URL. Additionally, I’ll show you how to configure Etherscan API keys to display deployment data directly in your job logs. To ensure the security of your sensitive information, we’ll utilize GitHub Actions secrets to safely store your keys and URLs.

Deployment diagram

By the end of this article, you’ll have a comprehensive understanding of how to automate smart contract deployments, ultimately making your development process faster, more reliable, and easier to manage.

Fueling Our Wallet: Acquiring Sepolia ETH

GETBLOCK faucet claim form

GETBLOCK faucet claim form

First, we need to obtain some Sepolia ETH to cover the gas fees for our deployments. To do this, I used two reliable faucets: Google Cloud and GetBlock. It’s important to note that most faucets require you to have a small amount of Ether in your mainnet wallet at the address from which you are requesting Sepolia ETH. This is to verify that you are a legitimate user and to prevent abuse of the faucet service.

Connecting to the Network: Acquiring an Infura API Key

When deploying smart contracts on the blockchain, establishing a reliable connection to the network is crucial. One of the most straightforward and effective ways to achieve this is by using Infura’s RPC (Remote Procedure Call) URL. Here’s why Infura stands out as an excellent choice:

Simplicity: Infura offers a user-friendly interface that enables developers to easily obtain an RPC URL. This eliminates the need to set up and maintain your own Ethereum node, a process that can be both complex and time-consuming. Instead, you can focus on writing and deploying your smart contracts without the added overhead.

Reliability: As a trusted service, Infura provides high availability and uptime. You can connect to the Ethereum network without worrying about node downtime or maintenance issues, ensuring that your deployments run smoothly and consistently.

Scalability: Whether you’re deploying a single contract or managing multiple projects, Infura can accommodate varying loads. Its robust infrastructure is designed to handle numerous requests, allowing your applications to grow without encountering bottlenecks.

Quick Setup: After creating an Infura account and generating your API key, you’ll receive an RPC URL that can be easily integrated into your deployment scripts. This quick setup process saves valuable time and lets you dive straight into development.

Comprehensive Documentation: Infura provides detailed documentation and support, making it easier for developers of all experience levels to get started. This resource is invaluable, especially when you encounter challenges along the way.

At this point, navigate to the Infura dashboard to grab your API key in preparation for the next phase. Next, it’s time to securely store our essential and confidential information.

Working with secrets

Create secrets for the following: ETHERSCAN_API_KEY, PRIVATE_KEY, and TESTNET_RPC_URL. The RPC URL should be treated as a secret, formatted as https://sepolia.infura.io/v3/YOUR_API_KEY. If you’re unfamiliar with using secrets in GitHub Actions, be sure to check out the official documentation.

Foundry Deploy Action: Automating Smart Contract Deployment

This custom GitHub Action, is designed to automate the process of deploying smart contracts using the Foundry framework. Here’s a breakdown of how it works and the key steps involved:

Checkout the Codebase:

The first step uses the actions/checkout@v4 to clone the repository and its submodules into the GitHub Actions runner. This ensures that all relevant files, including any submodules, are available for the deployment process.

Install Foundry:

Foundry, a powerful development toolkit for Ethereum smart contracts, is installed using the foundry-rs/foundry-toolchain@v1 action. The version: nightly parameter ensures that the latest nightly version of Foundry is used, providing access to the latest features and updates.

Set Up Environment Variables:

In this step, environment variables needed for deployment are set up. This includes:

FOUNDRY_ETH_RPC_URL: The RPC URL for interacting with the blockchain.

PRIVATE_KEY: The private key of the deployer account.

CHAIN_ID: The ID of the blockchain network (e.g., Sepolia or Ethereum Mainnet).

ETHERSCAN_API_KEY: The API key used to verify the contract on Etherscan.

These values are securely passed from the workflow’s input parameters and stored as environment variables for the remainder of the job.

Compile Smart Contracts:

The forge build command is executed to compile the smart contracts. This is done within the working directory specified by the user (project_dir), which defaults to the root directory if not provided. Compilation ensures that all smart contracts are properly prepared before deployment.

Deploy Smart Contracts:

In this final step, the forge script command is used to deploy the smart contracts to the specified network. The deployment is broadcasted and verified using:

— broadcast: To send the deployment transaction to the blockchain.

— verify: To verify the contract on Etherscan using the provided API key.

This step also uses the environment variables for the RPC URL, private key, chain ID, and Etherscan API key to ensure secure and accurate deployment.

Input Parameters:

This action requires several input parameters to function correctly:

rpc-url: The RPC URL for connecting to the blockchain network (e.g., Infura).

private-key: The private key for the deployer’s wallet, used to sign transactions.

chain-id: The ID of the target blockchain network (e.g., 1 for Ethereum Mainnet or 11155111 for Sepolia).

etherscan-api-key: API key for Etherscan, enabling contract verification after deployment.

deploy-script: The path to the deployment script, which contains the logic for deploying the contract.

project_dir (optional): The directory containing the Foundry project. It defaults to the root directory (“.”) if not provided.

name: "Foundry Deploy Action"
description: "A custom action to deploy smart contracts using Foundry"
author: "Gabriel Rossi Lopes"
runs:
  using: "composite" 
  steps:

    - uses: actions/checkout@v4
      with:
        submodules: recursive

    - name: Install Foundry
      uses: foundry-rs/foundry-toolchain@v1
      with:
        version: nightly

    - name: Set up Environment Variables
      run: |
        echo "FOUNDRY_ETH_RPC_URL=$RPC_URL" >> $GITHUB_ENV
        echo "PRIVATE_KEY=$PRIVATE_KEY" >> $GITHUB_ENV
        echo "CHAIN_ID=$CHAIN_ID" >> $GITHUB_ENV
        echo "ETHERSCAN_API_KEY=$ETHERSCAN_API_KEY" >> $GITHUB_ENV
      env:
        RPC_URL: ${{ inputs.rpc-url }}
        PRIVATE_KEY: ${{ inputs.private-key }}
        CHAIN_ID: ${{ inputs.chain-id }}
        ETHERSCAN_API_KEY: ${{ inputs.etherscan-api-key }}
      shell: bash

    - name: Compile contracts
      run: forge build
      shell: bash
      working-directory: ${{ inputs.project_dir }}

    - name: Deploy contracts
      run: forge script ${{ inputs.deploy-script }} --broadcast --verify --rpc-url $FOUNDRY_ETH_RPC_URL --private-key $PRIVATE_KEY --chain-id $CHAIN_ID --etherscan-api-key $ETHERSCAN_API_KEY
      shell: bash
      working-directory: ${{ inputs.project_dir }}

inputs:
  rpc-url:
    description: "The RPC URL for the net"
    required: true
  private-key:
    description: "The private key for the deployer account"
    required: true
  chain-id:
    description: "The Chain ID for the network"
    required: true
  etherscan-api-key:
    description: "API key for etherscan"
    required: true
  deploy-script:
    description: "The path to the deploy script"
    required: true
  project_dir:
    description: "The directory containing the Foundry project (defaults to the root directory if not provided)."
    required: false
    default: "." 
Enter fullscreen mode Exit fullscreen mode

Example Usage:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Foundry Deploy Action
        uses: grossiwm/foundry-deploy-action@latest
        with:
          rpc-url: ${{ secrets.RPC_URL }}
          private-key: ${{ secrets.PRIVATE_KEY }}
          chain-id: 1 # Replace with your desired chain ID
          etherscan-api-key: ${{ secrets.ETHERSCAN_API_KEY }}
          deploy-script: "path/to/your/deploy_script.sol"
Enter fullscreen mode Exit fullscreen mode

This example demonstrates how to pass the necessary secrets and configuration options to the action for a secure and streamlined deployment process.

For a clearer understanding of the concepts discussed in this article, I encourage you to check out my GitHub Action repository, also the same action published in the marketplace. Additionally, you can find an example project that demonstrates the deployment process in action here. These resources will provide valuable insights and help solidify your understanding.

Top comments (0)