How to Deploy Solidity Smart Contracts to the Ethereum Blockchain

This tutorial walks you through deploying Solidity smart contracts to the Ethereum blockchain using Web3, Infura, and the Truffle HD Wallet provider.

Introduction

Learning how to write your own Solidity contract deployment script is an important skill for developing applications on the Ethereum blockchain. Knowing how to deploy your smart contracts can deepen your understanding of existing deployment tools. It also frees you from relying on existing tools such as Truffle or Remix.

Setup

Before you begin you will need to have Node.js installed and have your compiled Solidity smart contracts stored somewhere in your project. If you are unsure how to compile your Solidity smart contracts check out my previous article here . You will also need an Infura api endpoint set up. To do this visit their website, create an Ethereum project, and follow through their steps to get set up. Infura’s api will allow us to deploy our contracts to the Ethereum blockchain or an Ethereum testnet. You will also need an Ethereum wallet that can interact with web3. I will be using metamask in this tutorial. The Metamask wallet allows us to send funds to smart contracts and pays for the gas required to deploy smart contracts. The next thing you have to do is install the necessary dependencies.

npm install --save @truffle/hdwallet-provider web3 dotenv

While the libraries are installing you can head over to your project and create a .env file in the top most folder. In this file we are going to store our Ethereum account secret and Infura api endpoint. IMPORTANT since we don’t want to share our account secret with anyone MAKE SURE to include the .env file in your .gitignore file if you are pushing your project to github. Next add your account secret and Infura api endpoint to the file like so.

# .env file
SECRET="this is your 12 word mnemonic pharse etc ... ..."
INFURA_API="https://your_infura_endpoint"

After you create your .env file you can head over to your project directory and create a deploy.js file. I created mine in the /ProjectName/ethereum/ directory.

Deploy Script

The first step in writing our deploy script is to import the necessary dependecies.

// This will allow our metamask wallet to interact with the Ethereum blockchain
const HDWalletProvider = require('@truffle/hdwallet-provider');
// This library allows us to interact with contracts on the Ethereum blockchain
const Web3 = require('web3');
// This is our compiled Solidity contract in JSON
const compiledGreeting = require('./build/Greeting.json');
// This library allows us to keep our account mnemonic phase and api endpoint secret
require('dotenv').config();

Next we are going to initialize our web3 instance with our selected wallet provider.

const provider = new HDWalletProvider(process.env.SECRET, process.env.INFURA_API);
const web3 = new Web3(provider);

process.env.SECRET tells the provider which account is interacting with the Ethereum blockchain, and the process.env.INFURA_API tells the provider where to send our interactions. For this tutorial we will be sending them to the Rinkeby Ethereum test network, since I do not want to spend real money until I am launching an application into production. Ethereum testnetworks allow us to use fake ether to test our applications. We then pass our provider variable to our Web3 constructor to get our instance of web3 that will allow us to interact with the Ethereum network (Rinkeby test network) from our account. Next we will define our deploy function that actually deploys our Solidity smart contracts to the Ethereum testnet.

const deploy = async () => {
    // Get the account(s) that we are deploying our smart contracts from
    const accounts = await web3.eth.getAccounts();
    console.log(`Attempting to deploy from account ${accounts[0]}`);
    const result = await new web3.eth.Contract(compiledGreeting.abi)
        .deploy({ data: compiledGreetomg.evm.bytecode.object })
        .send({ gas: '3000000', gasPrice: '100000000', from: accounts[0]});
    console.log(`Contract deployed to ${result.options.address }`);
    provider.engine.stop();
}
deploy();

The first line of the deploy function gets the accounts we have on Metamask. On the second line we create our contract and deploy it to the Rinkeby testnet. We pass in our contracts bytecode to deploy to tell the Ethereum network what code to run on the blockchain. We then send the maximum amount of gas we are willing to pay and the price in wei we will pay for each unit of gas. We also send the account that is deploying the contract. Finally, we tell our provider that we are done deploying the script, and then we actually call our deploy function on the last line. To run our script go to your root directory and enter the following command.

node ethereum/deploy.js

You can view the entire script below.

// Deploy our smart contracts to an ethereum network
// Currently deploying to ropsten
const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const compiledGreeting = require('./build/Greeting.json');
require('dotenv').config();

const provider = new HDWalletProvider(
    process.env.SECRET,
    process.env.INFURA_API
);

const web3 = new Web3(provider);

const deploy = async () => {
    const accounts = await web3.eth.getAccounts();
    console.log(`Attempting to deploy from account ${accounts[0]}`);
    const result = await new web3.eth.Contract(compiledGreeting.abi)
        .deploy({ data: compiledGreeting.evm.bytecode.object })
        .send({ gas: '3000000', gasPrice: '100000000, from: accounts[0]' });
    console.log(`Contract deployed to ${result.options.address}`);
    provider.engine.stop();
};
deploy();

Conclusion

In this tutorial I showd you how to write your own deploy script to deploy your Solidity smart contracts to the Ethereum blockchain. Hopefully this gave you some insight on how tools like truffle work under the hood.

If you have any suggestions for articles or feedback on this article let me know in the comments!