Open In App

How to Test a Smart Contract for Ethereum?

Last Updated : 27 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Public Blockchains like Ethereum are immutable, it is difficult to update the code of a smart contract once it has been deployed. To guarantee security, smart contracts must be tested before they are deployed to Mainnet. There are several strategies for testing contracts, but a test suite comprised of various tools and approaches is suitable for detecting both minor and significant security issues in contract code.

Smart Contract Testing

Smart contract testing is the process of ensuring that a smart contract’s code operates as intended. Testing is important for determining whether a certain smart contract meets standards for dependability, usability, and security. Approaches may differ, but most testing methods need to run a smart contract with a subset of the data it promises to handle. It is presumed that the contract is working properly if it gives correct outcomes for sample data. Most testing tools include resources for creating and executing test cases to determine if a contract’s execution matches the intended outcomes.

Importance of Testing a Smart Contract

Testing Smart Contracts is a critical and significant process in the development phase since it involves deploying it on the network every time and determining whether it works as expected or whether it needs some fine-tuning to enhance and satisfy its requirements.

  • Helps estimating gas fees: Gas Fees are the most important factor that you would need to consider. As deploying smart contracts on the Ethereum network would consume some block of space on the network, which would necessitate the payment of some gas fees in order to mine on the network. Gas Fees may seem to you a small amount but it’s worth a lot. You might not want to waste that, thus testing becomes an important task.
  • Helps to detect errors: Smart contracts frequently control high-value financial assets, tiny programming errors can, and frequently do, result in significant losses for users. However, detailed testing can assist you in detecting errors and loopholes in smart contract code early on and fixing them before publishing on Mainnet.

While it is feasible to update a contract if a bug is detected, upgrades are difficult and might cause issues if done incorrectly. Upgrading a contract undermines the idea of immutability and burdens users with new trust assumptions. A detailed method for testing your contract, on the other hand, mitigates smart contract security concerns and eliminates the need for sophisticated logic modifications after deployment.

Problems Due to Insufficient Smart Contracts Testing

Not testing smart contracts thoroughly can lead to various problems and vulnerabilities, including:

  1. Bugs and Errors: Smart contracts are written in code, and like any software, they can contain bugs and errors. Without proper testing, these issues may go unnoticed and lead to unexpected behaviour or security vulnerabilities.
  2. Security Vulnerabilities: Smart contracts can be susceptible to various security vulnerabilities, such as re-entrancy attacks, integer overflow/underflow, and unauthorized access. Testing helps identify and mitigate these vulnerabilities, ensuring the contract is robust and secure.
  3. Financial Loss: Smart contracts often involve financial transactions and the handling of digital assets. If a contract contains a bug or vulnerability, it may be exploited by malicious actors, resulting in financial loss or theft of assets.
  4. Inconsistencies and Logic Flaws: Testing helps identify inconsistencies and logic flaws in smart contracts. These issues may result in unexpected behaviour or contradictions within the contract’s logic, leading to undesirable outcomes or disputes.
  5. Contract Immutability: Smart contracts are typically immutable once deployed on the blockchain. Therefore, any bugs or vulnerabilities present in the contract cannot be easily rectified after deployment. Thorough testing before deployment is crucial to avoid permanent issues.
  6. Regulatory Compliance: Depending on the nature of the smart contract, it may need to comply with certain regulatory requirements. Testing ensures that the contract functions as intended adheres to relevant regulations and avoids any legal or compliance issues.
  7. User Experience Issues: Testing not only helps identify technical problems but also improves the overall user experience. Ensuring that the contract works seamlessly, provides clear instructions, and handles edge cases correctly enhances user satisfaction and reduces confusion.
  8. Reputation Damage: If a smart contract is deployed without proper testing and subsequently encounters issues, it can harm the reputation of the project or organization responsible for it. Users may lose trust in the contract and be hesitant to engage with it in the future.

Given the potential risks associated with smart contracts, thorough testing, including unit testing, integration testing, and security auditing, is crucial to identify and mitigate these problems before deployment.

Methods for Smart Contract Testing

Automated and manual testing approaches for Ethereum smart contracts can be coupled to develop a strong framework for contract analysis.

1. Automated Testing

Automated testing is a technology that automatically checks a smart contract’s code for execution issues. It is more efficient than manual testing methods due to scripts (i.e. writing different test cases) being used to evaluate contract features. Automated testing is particularly useful when tests are repetitive and time-consuming; difficult to carry out manually; susceptible to human error; or involve evaluating critical contract functions. However, automated testing can have downsides such as missing specific vulnerabilities and producing false positives, so it is important to combine automated and human testing for smart contracts.

2. Unit Testing

Unit testing examines contract functions independently and ensures that each component performs properly. If unit tests fail, they should be simple, quick to execute, and offer a clear indication of what went wrong. They may be used to ensure that functions return anticipated values, and that contract storage is appropriately updated after function execution. Running unit tests after making modifications to a contract’s codebase also guarantees that no errors are introduced.

Guidelines for unit testing smart contracts:

  • Understand your contracts’ business logic and workflow: Understanding a smart contract’s functionalities, user interactions, and operational workflow is crucial before writing unit tests. This knowledge enables the creation of effective tests, including happy path tests, to verify correct outputs for valid inputs. Additionally, it helps ensure that unit tests assess the contract’s execution against the defined requirements.
  • Evaluate all assumptions related to contract execution: Documenting assumptions, writing unit tests, and using assertions are essential for ensuring the reliability and security of smart contracts. Unit testing helps validate assumptions, protects against unexpected execution, and encourages consideration of potential security vulnerabilities. It is advised to go beyond positive tests and includes negative tests to check for failure with incorrect inputs. Unit testing frameworks provide the means to create and validate assertions, enabling thorough testing of smart contract capabilities and limitations.
  • Measure code coverage: Code coverage is a metric used in testing to measure the extent to which branches, lines, and statements of code are executed during test scenarios. It is crucial to aim for good code coverage to avoid “false negatives” where a contract passes all tests but still contains vulnerabilities. Achieving high code coverage provides confidence that all statements and functions in a smart contract have been adequately tested for accuracy and correctness.
  • Use well-developed testing frameworks: The choice of unit testing tools plays a vital role in ensuring the quality of your smart contract testing. An optimal testing framework is characterized by regular maintenance, valuable features such as logging and reporting capabilities, and a track record of extensive usage and auditing by fellow developers.
    Unit testing frameworks for Solidity smart contracts are available in various languages, with JavaScript, Python, and Rust being prominent examples. Some well-known unit testing frameworks for smart contracts include Truffle, Hardhat, and Ape, among others.

3. Integration Testing

While unit testing debugs contract operations in isolation, integration testing evaluates a smart contract’s components as a whole. Integration testing can identify problems caused by cross-contract calls or interactions between various functions inside the same smart contract. Integration tests, for example, can aid in determining if inheritance and dependency injection are functioning effectively.

  • If your contract has a modular design or interacts with other on-chain contracts during execution, integration testing is beneficial. To perform integration tests, fork the blockchain at a certain level (using a tool like Ganache or Hardhat) and simulate interactions between your contract and deployed contracts.
  • The split blockchain will function similarly to Mainnet, with accounts that have related statuses and balances. But it only acts as a sandboxed local development environment, meaning you won’t need real ETH for transactions, for example, nor will your changes affect the real Ethereum protocol.

4. Manual Testing

When it comes to smart contract testing, manual testing typically takes place in the later stages of the development cycle, following automated tests. This form of testing examines the smart contract as a fully integrated product, ensuring that it performs according to the specified technical requirements.

  • To assess how your smart contract behaves in a production environment, testing it on a local blockchain is a recommended approach. While automated testing in a local development environment can provide useful debugging insights, deploying on the main Ethereum chain can be costly in terms of gas fees and potential financial risks.
  • Utilizing a local blockchain, such as Ganache, Local Beacon Chains, or Hardhat, allows for interaction with the contract without significant overhead. Running contracts on a local blockchain is particularly beneficial for manual integration testing. Smart contracts offer composability, enabling integration with existing protocols. However, it is crucial to verify that these complex on-chain interactions yield accurate outcomes.
  • Another method of manual testing is deploying the contract on testnets. Testnets function similarly to the Ethereum Mainnet but utilize Ether with no real-world value. Deploying on a testnet enables users, including beta testers, to interact with the contract without risking actual funds. This form of testing evaluates the end-to-end flow of the application from a user’s perspective and allows testers to identify any issues related to the contract’s business logic and overall functionality.
    • After conducting tests on a local blockchain, deploying on a testnet is advantageous as it closely mimics the behaviour` of the Ethereum Virtual Machine. Many Ethereum-native projects choose to deploy dapps on testnets to evaluate the operation of smart contracts under real-world conditions. Some Examples of testnet are Goerli, Sepolia, etc.

Formal Verification and Smart Contract Testing

Testing can help validate a smart contract’s expected behaviour for certain data inputs, but it cannot provide definitive proof for inputs that were not included in the tests. Therefore, testing alone cannot ensure the complete “functional correctness” of a program, meaning it cannot guarantee that the program will behave as intended for all possible input values.

In contrast, formal verification is an approach that assesses the correctness of software by comparing a formal model of the program to a formal specification. The formal model represents the program mathematically, while the formal specification defines the program’s properties and logical assertions regarding its execution.

  • Unlike testing, formal verification can verify if a smart contract execution satisfies a formal specification for all possible executions, without the need for sample data.
  • This approach reduces the time spent on running numerous unit tests and is more effective at identifying hidden vulnerabilities.
  • It’s important to note that formal verification techniques vary in terms of their complexity and practical usefulness.

Testing Tools and Libraries

Here are some tools and libraries for Unit Testing smart contracts:

  • solidity-coverage: A code coverage tool specifically designed for Solidity smart contracts.
  • Waffle: A framework built on top of ethers.js that offers advanced features for smart contract development and testing.
  • Remix Tests: A tool integrated within the Remix IDE that allows you to write and run test cases for Solidity smart contracts.
  • OpenZeppelin Test Helpers: An assertion library that helps ensure your Ethereum smart contracts behave as expected.
  • Truffle Tests: An automated testing framework that simplifies the process of testing your contracts.
  • Brownie: A unit testing framework that uses Pytest, allowing you to write concise tests with minimal code for both small and large projects.
  • Foundry Tests: Foundry offers Forge, a fast and flexible Ethereum testing framework capable of executing unit tests, gas optimization checks, and contract fuzzing.
  • Hardhat Tests: A framework for testing smart contracts based on ethers.js, Mocha, and Chai.
  • ApeWorx: A Python-based development and testing framework specifically designed for smart contracts targeting the Ethereum Virtual Machine.

These tools and libraries provide various functionalities and options to streamline the testing process and ensure the reliability of your smart contracts.

How to Perform Unit Tests on Smart Contracts?

Unit Testing is the most crucial testing method to be carried out of every other testing method; There are many frameworks, tools, and libraries that help you in testing your application one of which is Hardhat. Hardhat helps in compiling and testing smart contracts at the very core. And also has its own built-in Hardhat Network (Local Ethereum Network design for development purposes). It also allows you to deploy contracts, run tests, and debugging of code.

Installing Hardhat

1. To install hardhat to the current project directory, run the following commands in your terminal.

npm init
npm install --save-dev hardhat

2. Next you need to set up your project in the current working directory in order to connect with the Hardhat development environment. For projects set up in the current directory, paste the below command in the command prompt by changing the directory to the current directory you want to set up your project.

npx hardhat

Select Create an empty hardhat.config.js with your keyboard and hit enter, once you’ve run the above command. hardhat.config.js file is important for a hardhat project.

Hardhat_ProjectCreate.jpg

Fig 1.1. Create Hardhat Project

3. Create three important folders in the working directory.

  • contracts: To create a smart contract.
  • scripts: To run deployment scripts.
  • tests: To run and test smart contracts using hardhat on the local blockchain, using JavaScript Framework ‘Mocha’.

Below is the expected folder structure:

FolderStructureTestingHardhat.jpg

Fig 1.2. Folder Structure

4. Other necessary installations (plugins) required, which help in developing a smart contract, testing, and creating an environment. To install it run this in your project working directory. Recommended for npm 7+ versions.

npm install --save-dev @nomicfoundation/hardhat-toolbox

For the npm 6 version or less, it might require installing a few more dependencies,

npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers

5. In case the above installation fails or shows errors like peer dependency conflict in the dependency tree, is most likely because of the npm version you have installed the error is most probably shown in the npm version above 7. Because npm version 7 and above treats peer dependency conflicts as errors. To tackle such a situation, install the npm version under 7.

OR

`npm install --leagacy-peer-deps`
`npm config set legacy-peer-deps true` to permanently resolve the error

6. Add the installed libraries/modules to hardhat.config.js file, add the ‘ require(“@nomicfoundation/hardhat-toolbox”); ‘ statement as shown below:

Javascript




require("@nomicfoundation/hardhat-toolbox");
module.exports = {
     solidity: "0.8.17",
 };


Contract Creation and Compile using Hardhat

Create any basic solidity smart contract under the contracts folder. For example:

Solidity




// SPDX-License-Identifier: UnLicensed
pragma solidity >=0.5.0 <0.9.0;
import "hardhat/console.sol";
contract Token{
    string public name  = "Hardhat Token";
    string public symbol  = "HHT";
    uint256 public totalSupply = 10000;
 
    address public owner;
 
    mapping (address => uint256) balances;
 
    constructor(){
        /* i.e the deployer will be the owner at first he can then transfer tokens to any
        other account addresses and he will have all the tokens in his wallet at first.*/
         
        balances[msg.sender] = totalSupply;
        owner = msg.sender;
    }
 
    function transfer(address to, uint256 amount) external {
        require(balances[msg.sender]>=amount, "Not enough tokens");
 
        console.log( "Transferring from %s to %s %s tokens",msg.sender,to,amount);
 
        balances[msg.sender] -= amount;
        balances[to] += amount;
 
    }
 
    function balanceOf(address account) external view returns (uint256) {
        return balances[account];
    }
     
}


Compile the smart contract to check if there are any errors or anomalies, using the hardhat compiler, use the following command,

npx hardhat compile

Testing of Smart Contract

Important terminologies to understand:

  • describe: A describe block is used for organizing test cases in logical groups of tests. For example, we want to group all the tests for a specific class.
  • it: Defining tests using its function.
  • beforeEach: Used for code reusability and reducing redundancy of code. Create a token.js file in the test directory( folder ).

Paste the below code into the token.js file:

Solidity




const { expect } = require("chai");
describe("Token contract", function () {
   it("Deployment should assign the total supply of tokens to the owner", async function () {
     const [owner] = await ethers.getSigners();
     const Token = await ethers.getContractFactory("Token");
     const hardhatToken = await Token.deploy();
     const ownerBalance = await hardhatToken.balanceOf(owner.address);
     expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);
   });
 });


In your command prompt or terminal run npx hardhat test, and the following output is expected:

 Token contract   
✓ Deployment should assign the total supply of tokens to the owner (654ms)
1 passing (663ms)

Which means the test has been passed.

 const [owner] = await ethers.getSigners();

In ethers.js, a Signer is an object that represents an Ethereum account. Transactions are sent to contracts and other accounts using this method. We’re obtaining a list of the accounts in the node we’re connected to, which is Hardhat Network in this case, and we’re just saving the first one. The global scope includes the ethers variable. If you prefer that your code be always explicit, you may add the following line at the top:

const { ethers } = require("hardhat");
const Token = await ethers.getContractFactory("Token");

A ContractFactory is used to create an instance of a token contract. Token here is just the instance.

const hardhatToken = await Token.deploy();

Calling the deploy() function on a ContractFactory instance will start the deployment process and returns a Promise. This object that gets created has a method for each of your smart contract functions.

const ownerBalance = await hardhatToken.balanceOf(owner.address);

After deploying the contract, contract methods on hardhatToken can be easily called. By calling the balanceOf() method we can extract the owner’s account balance.

It is important to understand that the account that deploys the token gets its entire supply. And by default instances are connected to the first signer.

expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);

Here it is IMPORTANT to note that the total supply and owner’s balance should be equal. Therefore to check this, we wrote the above code statement, which will tell you whether the contract is correctly deployed or not.
To do this we’re using Chai which is a popular JavaScript assertion library. These asserting functions are called “matchers“, and the ones we’re using here come from the @nomicfoundation/hardhat-chai-matchers plugin, which extends Chai with many matchers useful to test smart contracts.

Using a Different Account

To test your code by sending a transaction from an account (or Signer in ethers.js terminology) other than the default one, you can use the connect() method on your ethers.js Contract object to connect it to a different account, like this:

Javascript




const { expect } = require("chai");
 describe("Token contract", function () {
   // ...previous test...
    
   it("Should transfer tokens between accounts",async () => {
    
     // getSigners is used to get the account addresses and there balances.
     [owner,addr1,addr2] = await ethers.getSigners();
      
     // Creating instance of the contract.
     // getContractFactory is used to create instance of the contract.
     Token = await ethers.getContractFactory("Token");
      
     // Deploying the above instance over hardhat platform provided test local blockchain.
     hardhatToken = await Token.deploy();
      
     // Transfer 10 tokens from owner to addr1
     await hardhatToken.transfer(addr1.address,10);
      
     // extracting balance assigned to addr1 after deployment.
     const addr1Balance = await hardhatToken.balanceOf(addr1.address);
     expect(addr1Balance).to.equal(10);
      
     // Transfer 5 tokens from addr2 to addr1
     await hardhatToken.connect(addr1).transfer(addr2.address,5);
      
     // extracting balance assigned to addr2 after deployment.
     const addr2Balance = await hardhatToken.balanceOf(addr2.address);
     expect(addr2Balance).to.equal(5);
      
   }).timeout(50000);
 });


Full Test Suite

The below Code is the full test suite for Token.sol with other added information and the tests to be performed are structured in comprehended format.

Javascript




const {expect} = require("chai"); // Mocha-framework, chai-library
const { ethers } = require("hardhat");
 
 // basic syntax just to describe the contract name you can write any name over here.
describe("Token contract", function () {
   
    let Token;
    let hardhatToken;
    let owner;
    let addr1;
    let addr2;
    let addrs;
 
    /* beforeEach is a hook provided by mocha blockchain to attach common
     part before every describe function.*/
    /* common block to define, declare, intialize every common requirement such as to deploy,
    create an instance of blockchain.*/
    beforeEach(async () => {
        // getSigners is used to get the account addresses and there balances.
        [owner,addr1,addr2,...addrs] = await ethers.getSigners();
        
        // Creating instance of the contract.
        // getContractFactory is used to create instance of the contract.
        Token = await ethers.getContractFactory("Token");
        
        // Deploying the above instance over hardhat platform provided test local blockchain.
        hardhatToken = await Token.deploy();
    });
 
 
    describe('Deployment', () => {
        // it - is used to perform test over every function.
        // For testing every function we define 'it'.
        // Below 'it' checks if the deployment is done perfectly over a constructor call.
        it("Should set the right owner", async () => {
            expect(await hardhatToken.owner()).to.equal(owner.address);
        }).timeout(50000);
 
        it("Deployment should assign the total supply of tokens to the owner", async () => {
   
            /* Checking if the totalSupply is assigned to the owner and
            owner's balance has been credited.*/
            // extracting balance assigned to owner after deployment.
            const ownerBalance = await hardhatToken.balanceOf(owner.address);
         
            // Testing if( ownerBalance == totalSupply())
            /* if this doesn't happens to be true it will show 1 failing with
            AssertionError: Expected "10000" to be equal 10 */
            expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);
            
        }).timeout(50000);
    });
 
 
    describe('Transaction', () => {
        it("Should transfer tokens between accounts",async () => {
   
            // Transfer 10 tokens from owner to addr1
           await hardhatToken.transfer(addr1.address,10);
           // extracting balance assigned to addr1 after deployment.
           const addr1Balance = await hardhatToken.balanceOf(addr1.address);
           expect(addr1Balance).to.equal(10);
         
            // Transfer 5 tokens from addr2 to addr1
            await hardhatToken.connect(addr1).transfer(addr2.address,5);
            // extracting balance assigned to addr2 after deployment.
            const addr2Balance = await hardhatToken.balanceOf(addr2.address);
            expect(addr2Balance).to.equal(5);
 
        }).timeout(50000);
 
        it("Should fail if sender doesnot have enough tokens",async () => {
            
           const initialOwnerBalance = await hardhatToken.balanceOf(owner.address);
           await expect(hardhatToken.connect(addr1).transfer(owner.address,1)).to.be.revertedWith("Not enough tokens");
         
           expect(await hardhatToken.balanceOf(owner.address)).to.equal(initialOwnerBalance);
 
        }).timeout(50000);
 
 
        it("Should update balances after transfers",async () => {
   
           const initialOwnerBalance = await hardhatToken.balanceOf(owner.address);
           await hardhatToken.transfer(addr1.address,5);
           await hardhatToken.transfer(addr2.address,10);
           const finalOwnerBalance = await hardhatToken.balanceOf(owner.address);
           expect(finalOwnerBalance).to.equal(initialOwnerBalance-15);
           const addr1Balance = await hardhatToken.balanceOf(addr1.address);
           expect(addr1Balance).to.equal(5);
 
           const addr2Balance = await hardhatToken.balanceOf(addr2.address);
        
           expect(addr2Balance).to.equal(10);
 
        }).timeout(50000);
    });
 
   
});


Run npx hardhat test in your command prompt/ terminal. The output of npx hardhat test should look like this:

SmartContractTests_GFG.jpg

Fig 1.3. Results of the Tests Performed

Note : npx hardhat test would automatically compile the last updated code.

Debugging

Debugging of solidity smart contracts is possible by logging messages by calling console.log() from solidity code while running smart contracts and tests on Hardhat Network. Hardhat provides a console.sol module which makes it possible to log messages from solidity code. To do so, you just need to import hardhat/console.sol. This is how it should look like:

Solidity




pragma solidity >=0.5.0 <0.9.0;
import "hardhat/console.sol";
contract Token { //...
 
 }


Then you can simply add console.log to solidity functions similar to using it in Javascript. Here we are using it in the transfer() function.

Solidity




function transfer(address to, uint256 amount) external {
       require(balances[msg.sender]>=amount, "Not enough tokens");
 
       console.log( "Transferring from %s to %s %s tokens",msg.sender,to,amount);
 
       balances[msg.sender] -= amount;
       balances[to] += amount;
 
   }


Logging outputs will be reflected when you run your tests:

SmartContractDebug_GFG.jpg

Fig 1.4. Debugging the solidity code

Manual Testing: Deploying on Live Test Network & Local Hardhat Blockchain Environment

After your dApp is ready, you may want to deploy it onto a live network such that others can access an instance that’s not running locally on your system. The word ‘Live Network’ means it can be deployed on Ethereum’s “mainnet” which deals with money or “testnet” that do not require actual money. A few examples of testnet are Goerli and Sepolia. Sepolia is recommended.

Testing it on Local Blockchain

Create a deploy.js file inside the scripts folder and paste the following code into deploy.js:

Javascript




async function main() {
    const [deployer] = await ethers.getSigners();
   
    console.log("Deploying contracts with the account:", deployer.address);
   
    console.log("Account balance:", (await deployer.getBalance()).toString());
   
    const Token = await ethers.getContractFactory("Token");
    const token = await Token.deploy();
   
    console.log("Token address:", token.address);
  }
   
  main()
    .then(() => process.exit(0))
    .catch((error) => {
      console.error(error);
      process.exit(1);
    });


To connect to a specific Ethereum network, you can use the –network parameter when deploying, like this:

 npx hardhat run scripts/deploy.js --network <network-name>

Without using the –network parameter causes code to run against the embedded instance of the Hardhat network. Here the deployment gets lost when Hardhat finishes running, then to it is useful as it will help in testing that our deployment code works:

Output:

SmartContractDeploy.jpg

Fig 1.5. Deploying Smart on Contract Local Hardhat Network

Deploying to Test Networks

To deploy to testnet, simply add a network entry to your hardhat.config.js file and make the necessary changes as per the below code block. Using Goerli for this example, Sepolia or any other network is preferred as Goerli will be soon deprecating by the end of this year. In this example we will be using the Alchemy Web3 development platform in a similar way INFURA can also be used.

Javascript




require("@nomicfoundation/hardhat-toolbox");
 
/** @type import('hardhat/config').HardhatUserConfig */
 
const GOERLI_URL = "YOUR GOERLI URL WITH ALCHEMY API KEY";
const PRIVATE_KEY = "YOUR METAMASK ACCOUNT PRIVATE KEY";
module.exports = {
  solidity: "0.8.17",
  networks:{
    goerli:{
      url:GOERLI_URL,
      accounts:[PRIVATE_KEY],
    },
  }
};


Grab your API Key for Goerli or Sepolia network from Infura or Alchemy development platform. To deploy on Sepolia or Goerli, send some Sepolia or Goerli ether to the address that will be doing the deployment. A faucet, is a service that distributes testing-ETH for free, is a good place to receive testnet ether. After that run the below command on your command prompt of the current working directory.

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

You should see the deployed contract address if everything went fine.

How To Get the API Key from Alchemy?

1. Visit the Alchemy website – https://www.alchemy.com/

2. Login & Create your account.

3. Click on Create App on the dashboard.

ALCHEMY_Dashboard.jpg

Fig 2.1. Alchemy Dashboard

4. Make the necessary changes as below image, you can take any network suitable. Remember Selecting Ethereum Mainnet Deals with REAL ETHEREUM MONEY you may lose it if you have some, so be careful and just deploy it on Goerli or Sepolia testnets only.

ALCHEMY_CRA.jpg

Fig 2.2. Creating an App on Alchemy

5. An App will get created which can be seen on the dashboard, by clicking on the VIEW KEY, you can copy-paste that URL with the alchemy key embedded in the GOERLI_URL from the above code block.

ALCHEMY_CREATED.jpg

Fig 2.3. Getting the Goerli url with API Key

6. You can get the Metamask Private Key from Your Metamask account. First Make sure that you have enough goerli test ethers and that you are accessing the goerli test accounts and not from mainnet. You can get Goerli Test Ethers from ALCHEMY faucets. Then click on the 3 dots at the right corner of your Metamask account address and then click on the account details to get your private key.

Getting_METAMASK_pvtKey.jpg

Fig 2.4. Getting the Metamask Account

7. For Accessing the private key either scan the QR code or Click on the export private key.

ACCESSING_PvtKey.jpg

Fig 2.5. Accessing the Private Key



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads