새 폴더 생성 후
(터미널에서 실행)
npm init // 엔터 계속 하면 package.json
npm install --save-dev hardhat
npx hardhat
// Create an empty ~~~ 선택 ->Create an empty hardhat.config.js
npm install --save-dev @nomicfoundation/hardhat-toolbox
폴더 구성
|artifacts //abi생성되는 폴더
|cache
|contracts //A.sol
|node_modules
|scripts //deploy.js
|hardhat.config.js
|package-lock.json
|package.json
contracts/A.sol 파일
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Simple {
uint a;
function getA() public view returns(uint) {
return a;
}
function setA(uint _a) public {
a = _a;
}
}
실행 파일 작성 후 컴파일 명령어 실행
(터미널에서 실행)
npx hardhat compile
문제 없이 컴파일이 완료되면
|artifacts
|cache
파일이 생성됨 __artifacts안에 컨트랙트이름.json 파일이 생김(abi가 있는 파일)
이제 베포용 파일 생성하자
scripts/deploy.js 파일
const hre = require("hardhat");
async function main() {
//contract 변수로 설정
const Contract_A = await hre.ethers.getContractFactory("Simple");
//contract를 deploy하고
const contract_a = await Contract_A.deploy();
await contract_a.deployed();
console.log("Address : ", contract_a.address);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
생성 후
hardhat.config.js 파일
/** @type import('hardhat/config').HardhatUserConfig */
require("@nomiclabs/hardhat-ethers"); //추가하기
module.exports = {
solidity: "0.8.17",
};
(터미널에서)
npx hardhat run scripts/deploy.js
로 베포하면 계속 똑같은 주소로 결과가 나온다.
이건 제대로 베포된것이 아니고 주소만 나오는 상황(이더리움에서 논스는 거래를 일으킨 숫자임,
논스가 0이라서 위에 명령어는 몇번을 실행하던 주소만드는 환경값이 똑같으니까 주소값이 같게 나옴. 로컬에서 베포할떄는 거래가 추가되면서 다른값이 나옴)
split terminal로 오른쪽에 터미널을 추가 후
(오른쪽 터미널)
npx hardhat node
실행 하면 주소 20개정도가 쭉 나옴
이제 기존 터미널에서 베포 명령어를 실행
(기존 터미널에서)
npx hardhat run --network localhost scripts/deploy.js
이제 테스트넷에 베포를 하자. 하드헷은 기본적으로 provider를 alchemy로 한다.(infura도 상관없음)
hardhat.config.js 파일
/** @type import('hardhat/config').HardhatUserConfig */
require("@nomiclabs/hardhat-ethers");
const PVK = "지갑 개인키";
module.exports = {
solidity: "0.8.17",
networks: {
goerli: {
url: `https://eth-goerli.g.alchemy.com/v2/알케미 API-key`,
accounts: [PVK],
},
},
};
작성 후 터미널에서 베포 명령어 실행
npx hardhat run --network goerli scripts/deploy.js
실행 후 나오는 컨트랙트 주소 메모해두기
hardhat 특징은 verify를 터미널에서 간단히 실행할수 있다. 우선 verify를 하기 전 해둘것이
- etherscan 가입
- 내 계정정보에서 API Key Usage
- API Key 복사
그 후
hardhat.config.js 파일
/** @type import('hardhat/config').HardhatUserConfig */
require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-etherscan"); //추가
const PVK = "지갑 개인키";
module.exports = {
solidity: "0.8.17",
etherscan: {
apiKey: "위에 복사한 etherScan API Key",
},
networks: {
goerli: {
url: `https://eth-goerli.g.alchemy.com/v2/알케미 API-key`,
accounts: [PVK],
},
},
};
작성 후 터미널에서 명령어 실행
(터미널에서)
npx hardhat help //어떤 명령어 들이 있는지 보는것
npx hardhat verify --network goerli "아까 베포한 contract address"
이제 베포한 Contract를 동작시킬건데 터미널에서 작동하는 법과 vscode로 세팅 후 작동 하는것. 두가지 방법으로 실행
(터미널에서)
npx hardhat --network goerli console //네트워크 접속
const provider = new ethers.providers.AlchemyProvider(network="goerli", "알케미 API-key") //프로바이더 설정
const PVK = "지갑 개인키"
const signer = new ethers.Wallet(PVK, provider) //계정 등록
let addr = "베포한 컨트랙트주소"
let ABI = ~~~ (복붙할때 vscode에서 복사 후 복사한 abi를 웹 검색창에 붙여놓은 후 다시 복사하면 일렬로 이쁘게 복사됨)
const contract = new ethers.Contract(addr, ABI, signer) //컨트랙트 등록
contract.estimateGas.getA().then(console.log) //아까 베포한 contract의 getA라는 함수 실행
contract.address //컨트랙트 주소
contract.getA().then(console.log)
contract.setA(15).then(console.log)
await contract.getA().then(console.log)
contract.setA(25, {gasPrice : 5500000000}).then(console.log) //가스프라이스 설정해서 거래
먼저 .env 파일을 만들어 개인키, 알케미 api 키 등 을 따로 관리하자.
.env 파일
ABI = [ { "inputs": [], "name": "getA", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "_a", "type": "uint256" } ], "name": "setA", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ]
C_Addr = "컨트랙트 주소"
Alchemy_KEY = "알케미 API-key"
PVK = "지갑 개인키"
작성 후 interact.js 만들고
interact.js 파일
require("dotenv").config(); // dotenv 불러오기
const ethers = require("ethers"); // ethers 불러오기
const provider = new ethers.providers.AlchemyProvider(network = "goerli",process.env.Alchemy_KEY);
const signer = new ethers.Wallet(process.env.PVK, provider);
let ABI = process.env.ABI;
let addr = process.env.C_Addr;
const contract = new ethers.Contract(addr, ABI, signer);
//밑에는 실행 할 함수들 작성
contract.getA().then(console.log);
contract.setA(25, {gasPrice : 5500000000}).then(console.log);
(터미널에서)
node interact.js
이번에는 우리가 직접 테스트넷으로 송금하는 작업이다. 이번에도 터미널에서 실행 하는법과 vscode로 세팅해서 하는법으로 둘다 작업해본다.(세팅 환경은 위에와 동일한 환경임)
send.js 파일 생성 후
send.js 파일
require("dotenv").config(); //dotenv불러오기
const ethers = require("ethers"); //ethers 불러오기
const provider = new ethers.providers.AlchemyProvider(
(network = "goerli"),
process.env.Alchemy_KEY
);
const signer = new ethers.Wallet(process.env.PVK, provider);
async function send() {
const tx = {
to: "보낼 지갑 주소",
value: ethers.utils.parseEther("0.003"), //보낼 금액
};
const Txreciept = await signer.sendTransaction(tx);
console.log(Txreciept);
}
send();
작성 후 터미널에서 node send.js 실행
(터미널에서)
node send.js
(터미널에서)
const provider = new ethers.providers.AlchemyProvider(network="goerli", "API KEY")
const PVK = "your private key"
const signer = new ethers.Wallet(PVK, provider)
await signer.sendTransaction({to : "RECEIVER ADDRESS", value:ethers.utils.parseEther('0.05')})
모든 작업들 후 이더스캔(goerli 테스트넷)에서 확인해보면 된다.