Hands-On Hardhat Part-2(계약서 작성, 테스트 및 배포)

에서 Hardhat으로 프로젝트 환경을 설정하는 방법에 대해 언급했습니다. 이 부분에서는 프로젝트 구조를 자세히 설명하고 테스트와 함께 첫 번째 계약을 작성하고 마지막으로 배포합니다.

자, VSCode를 열어봅시다.

우리 프로젝트의 구조를 보면 기본 계약으로 오는 계약이 있지만 필요하지 않으며 검토하지 않습니다. 계약서를 작성하겠습니다.



예를 들어 책을 나열하고 책의 이름, 저자, 가격 및 가용성과 같은 나열된 책에 대한 정보를 제공하는 BookStore가 있는 계약에 대해 생각해 봅시다.

계약 생성



그리고 VSCode로 돌아가 계약 디렉터리에서 이름이 지정된 BookStore.sol 파일을 만듭니다.



이제 BookStore.sol은 다음과 같아야 합니다.

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract BookStore {

    // Book's infos
    struct Book {
        string bookName;
        string bookAuthor;
        uint256 bookPrice;
        bool available;
    }

    // Books list
    Book[] public books;

    // Create a new book to add books list
    function createBook(
        string memory _name,
        string memory _author,
        uint256 _price,
        bool _available
    ) external {
        books.push(Book(_name, _author, _price, _available));
    }

    // Update book price by books list index
    function updateBookPrice(
        uint _index, 
        uint256 _newPrice
    ) external {
        books[_index].bookPrice = _newPrice;
    }

    // Update book avalibility by books list index
    function updateBookAvalibility(
        uint _index,
        bool _isAvaliable
    ) external {
        books[_index].available = _isAvaliable;
    }

    // Gell all books
    function getAllBooks() external view returns(Book[] memory) {
        return books;
    }
}


계약 테스트 작성



테스트 폴더에서 book-store-test.js라는 이름을 만듭니다.
프로젝트의 구조는 다음과 같습니다.



이 단계의 여러분, 이전 부분에서 고급 샘플 프로젝트를 선택했기 때문에 필요한 모든 라이브러리 또는 플러그인을 자동으로 추가했기 때문에 이 파일에서 chai 또는 다른 부분에 대해 혼란스러울 수 있습니다. 기본값으로 제공되기 때문입니다.

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("BookStore", function () {
  let BookStore, bookStore;

  before(async function () {
   /**
     * A ContractFactory in ethers.js is an abstraction used to deploy new smart contracts, 
     * so BookStore here is a factory for instances of our bookStore contract.
     */
    BookStore = await ethers.getContractFactory("BookStore");

    /**
     * Calling deploy() on a ContractFactory will start the deployment, 
     * and return a Promise that resolves to a Contract. 
     * This is the object that has a method for each of your smart contract functions.
     */
    bookStore = await BookStore.deploy();
    await bookStore.deployed();
  });

  it("should create a new book", async function () {
    await bookStore.createBook("1984", "George Orwell", 2, true);
    let books = await bookStore.getAllBooks();
    expect(books[0].bookName).to.equal("1984");
    expect(books[0].bookAuthor).to.equal("George Orwell");
    expect(books[0].bookPrice).to.equal(2);
    expect(books[0].available).to.equal(true);
  });

  it("should update book price", async function () {
    await bookStore.updateBookPrice(0, 4);
    let books = await bookStore.getAllBooks();
    expect(books[0].bookPrice).to.equal(4);
  });

  it("should update book availibity", async function () {
    await bookStore.updateBookAvalibility(0, false);
    let books = await bookStore.getAllBooks();
    expect(books[0].available).to.equal(false);
  });

  it("should return all books", async function () {
    await bookStore.createBook("Building a Second Brain", "Tiago Forte", 3, true );
    await bookStore.createBook("Last Summer on State Street", "Toya Wolfe", 1, true);
    await bookStore.createBook("Do Hard Things", "Steve Magness", 5, false);
    await bookStore.createBook("The Power of Discipline", "Daniel Walter", 6, true);
    await bookStore.createBook("Mindful Self-Discipline", "Giovanni Dienstmann", 2, false);
    let books = await bookStore.getAllBooks();
    expect(books.length).to.equal(6);
  });
});


테스트 시나리오를 작성한 후 터미널에서 테스트 작업을 실행하십시오.

npx hardhat test


이 시점에서 테스트 폴더를 지정하는 것을 잊지 마십시오. 예를 들어 테스트 파일은 테스트 폴더 안에 있으므로 지정해야 합니다.

npx hardhat test ./test/book-store-test.js




글쎄, 우리의 모든 테스트가 통과되었습니다.

계약 배포



자, 여러분, 지금까지 계약을 배포하는 데 모든 것이 훌륭합니다. 배포 스크립트를 작성해야 합니다. 스크립트 폴더를 열고 이름이 지정된 deployBookStore.js 파일을 만듭니다.



스크립트 파일은 다음과 같아야 합니다.

/**
 * We require the Hardhat Runtime Environment explicitly here.
 * This is optional but useful for running
 * the script in a standalone fashion through `node <script>`.
 * When running the script with `npx hardhat run <script>`
 * you'll find the Hardhat Runtime Environment's
 * members available in the global scope.
 * */
const hre = require("hardhat");

async function main() {
  /**
   * Hardhat always runs the compile task when running scripts
   * with its command line interface.
   * If this script is run directly using `node`
   * you may want to call compile
   * manually to make sure everything is compiled
   * await hre.run('compile');
   * */

  // We get the contract to deploy
  const BookStore = await hre.ethers.getContractFactory("BookStore");
  const bookStore = await BookStore.deploy();

  await bookStore.deployed();

  console.log("BookStore deployed to: ", bookStore.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;
});


스크립트 작성이 완료되면 터미널을 열고 이 명령줄을 작성하여 로컬 블록체인을 시작하십시오.

npx hardhat node


그런 다음 다른 터미널을 열고 스크립트 파일을 실행합니다.

npx hardhat run ./scripts/deployBookStore.js --network localhost




보시다시피 계약이 성공적으로 배포되었습니다.

그래서 Ropsten, Rinkeby 또는 Goerli와 같은 다른 네트워크에 계약을 배포하려는 경우 모든 작업을 완벽하게 수행했습니다. 이 시나리오를 수행하기 위해 Alchemy 및 Infura 옵션이 있습니다. 블록체인 API 및 노드 인프라입니다.

지금은 개발자가 테스트에서 확장된 배포에 이르기까지 블록체인 애플리케이션을 쉽게 수행할 수 있는 도구와 인프라를 제공하는 Infura를 사용할 것입니다.

환경을 설정하려면 Infura으로 이동하여 회원가입 후 새 프로젝트를 생성합니다.



그런 다음 프로젝트 세부 정보 페이지로 이동하여 Ropsten Network를 선택하고 엔드포인트를 복사합니다.



Infura API_KEY를 얻은 후에 개인 키도 필요합니다. Metamask 지갑을 열고 Ropsten 테스트 네트워크를 선택한 다음 세 개의 점을 클릭한 다음 계정 세부 정보를 클릭합니다.



그런 다음 개인 키 내보내기를 클릭하십시오.



개인 키를 얻은 후 VSCode로 돌아가서 hardhat.config.js 파일을 엽니다.

파일 코드는 다음과 같습니다.

require("dotenv").config();

require("@nomiclabs/hardhat-etherscan");
require("@nomiclabs/hardhat-waffle");
require("hardhat-gas-reporter");
require("solidity-coverage");

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

const API_URL = "https://ropsten.infura.io/v3/API_KEY";
const PRIVATE_KEY = "";
/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: "0.8.4",
  networks: {
    ropsten: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`],
    },
  },
};


이제 터미널을 열고 배포 작업을 실행하십시오.

npx hardhat run ./scripts/deployBookStore.js --network ropsten




계약을 확인하려면 https://ropsten.etherscan.io/에서 계약 주소를 검색하십시오.

첫 번째 계약을 작성, 테스트 및 배포한 것을 모두 축하합니다.

요약하면 HardHat으로 무엇을 할 수 있습니까?
  • 적용 범위(누락된 테스트 확인)
  • 가스 보고서(최적화 확인)
  • Dotenv(배포용 보안 키)
  • Localhost(로컬 테스트용 빠른 노드)
  • Solhint 통합(스타일 가이드 및 보안)
  • 스크립트(실행 중인 스크립트 컴파일 및 배포)
  • Typescript(버그 방지를 위해 정적으로 입력됨)
  • Etherscan 확인(IDE에서 워크플로 간소화)

  • 소셜 미디어에서 나와 연결: && &&Github

    좋은 웹페이지 즐겨찾기