다음과 같이 Hardhat 프로젝트를 생성할 수 있습니다. 'npx hardhat'을 실행하면 어떤 형태의 프로젝트를 생성할 지 선택하고, 프로젝트의 루트 경로를 설정하고, .gitignore 파일을 추가할 것인지, 샘플 프로젝트에 의존성 모듈을 설치할 것인지는 선택하면 필요한 파일들을 설치하게 됩니다.
$ mkdir greeter
$ cd greeter
$ npm install --save-dev hardhat
$ npx hardhat
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.13.0 👷
✔ What do you want to do? · Create a JavaScript project
✔ Hardhat project root: · /Users/trident/Projects/Solidity/hardhat-test
✔ Do you want to add a .gitignore? (Y/n) · y
✔ Do you want to install this sample project's dependencies with npm (hardhat @nomicfoundation/hardhat-toolbox)? (Y/n) · y
설치하고 난 후 디렉터리 구조는 다음과 같습니다. contracts에 스마트 컨트랙트가 위치하게 되고, scripts에는 배포 스크립트가 test에는 테스트 코드가 artifacts, cache에는 컴파일된 결과가 위치하게 됩니다. hardhat.config.js에 네트워크 연결 정보, 솔리디티 컴파일러 버전 정보 등을 설정합니다.
// SPDX-License-Identifier: UNLICENSEDpragmasolidity ^0.8.0;// Uncomment this line to use console.log// import "hardhat/console.sol";contract Lock {uintpublic unlockTime;addresspayablepublic owner;eventWithdrawal(uint amount, uint when);constructor(uint_unlockTime) payable {require( block.timestamp < _unlockTime,"Unlock time should be in the future" ); unlockTime = _unlockTime; owner =payable(msg.sender); }functionwithdraw() public {// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);require(block.timestamp >= unlockTime,"You can't withdraw yet");require(msg.sender == owner,"You aren't the owner");emitWithdrawal(address(this).balance, block.timestamp); owner.transfer(address(this).balance); }}
$ npx hardhat test
Lock
Deployment
✔ Should set the right unlockTime (2392ms)
✔ Should set the right owner
✔ Should receive and store the funds to lock
✔ Should fail if the unlockTime is not in the future (46ms)
Withdrawals
Validations
✔ Should revert with the right error if called too soon
✔ Should revert with the right error if called from another account
✔ Shouldn't fail if the unlockTime has arrived and the owner calls it
Events
✔ Should emit an event on withdrawals
Transfers
✔ Should transfer the funds to the owner
9 passing (3s)
스마트 컨트랙트의 배포는 기본적으로 제공되는 deploy.js를 사용합니다.
사전에 배포할 네트워크를 설정해야 하는데 아래와 같이 hardhat.config.js에 WEMIX3.0 테스트넷과 메인넷을 추가합니다. 배포에 사용할 계정 주소의 프라이빗 키를 저장한다면 쉽게 작업할 수 있어 테스트용 계정을 생성한 후 필요한 만큼의 WEMIX만 전송하여 사용하는 것이 좋습니다. MetaMask에서 프라이빗를키키 추출하는 방법은 여기서는 생략합니다.
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const hre = require("hardhat");
async function main() {
const currentTimestampInSeconds = Math.round(Date.now() / 1000);
const unlockTime = currentTimestampInSeconds + 60;
const lockedAmount = hre.ethers.utils.parseEther("0.001");
const Lock = await hre.ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
await lock.deployed();
console.log(
`Lock with ${ethers.utils.formatEther(
lockedAmount
)}ETH and unlock timestamp ${unlockTime} deployed to ${lock.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 run scripts/deploy.js --network wemix_testnet
Lock with 0.001ETH and unlock timestamp 1679558487 deployed to 0x813fbbbeF30f343da37332293546dc854CCecF