ยซ   2025/02   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Recent Posts
02-02 00:31

Today
Total

Recent Comments
๊ด€๋ฆฌ ๋ฉ”๋‰ด

์—ฐ์˜ ๊ธฐ๋ก ๐Ÿช

[Solidity+hardhat+JavaScript] ์Šค๋งˆํŠธ์ปจํŠธ๋ž™ ๋ฐฐํฌ ์‹ค์Šต ๋ณธ๋ฌธ

etc

[Solidity+hardhat+JavaScript] ์Šค๋งˆํŠธ์ปจํŠธ๋ž™ ๋ฐฐํฌ ์‹ค์Šต

kite707 2023. 4. 7. 19:40

์ด ๊ธ€์€ ์•„๋ž˜ ์˜์ƒ์„ ๋ณด๊ณ  ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋กํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

์˜์ƒ ๋ฐ”๋กœ๊ฐ€๊ธฐ


๋ชฉํ‘œ

ํŽ€๋”ฉ ํ”„๋กœ๊ทธ๋žจ์„ ๊ด€์žฅํ•˜๋Š” ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ ๋งŒ๋“ค๊ธฐ

  • ํ”„๋กœ์ ํŠธ์˜ ์˜ค๋„ˆ, ๋ชฉํ‘œ ๊ธˆ์•ก, ํ”„๋กœ์ ํŠธ์— ๊ธฐ๋ถ€ํ•œ ์‚ฌ๋žŒ๋“ค์˜ ๋ชฉ๋ก, ๊ทธ๋“ค์˜ ๊ตฌ๋งค๊ธˆ์•ก, ๊ธฐ๋ถ€๊ธˆ์˜ ๋ˆ„์  ์ด์•ก, ๋ฐ๋“œ๋ผ์ธ
  • ๋ฐ๋“œ๋ผ์ธ ๋„๋‹ฌ ์‹œ ๊ธฐ๋ถ€๊ธˆ ์ด์•ก>=๋ชฉํ‘œ๊ธˆ์•ก์ผ ๊ฒฝ์šฐ ๋ˆ์€ ํ”„๋กœ์ ํŠธ ์˜ค๋„ˆ์—๊ฒŒ ์ „๋‹ฌ -๊ธฐ๋ถ€๊ธˆ ์ด์•ก<๋ชฉํ‘œ๊ธˆ์•ก์ผ ๊ฒฝ์šฐ ๋ˆ์€ ๊ธฐ๋ถ€์ž๋“ค์—๊ฒŒ ํ™˜๋ถˆ

 

Contract ๋ฐฐํฌ

1. ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

npm install -D hardhat

npm install -D ethers

npm install -D --legacy-peer-deps @nomiclabs/hardhat-ethers

npm install -D --legacy-peer-deps @nomiclabs/hardhat-waffle

2. hardhat ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

npx hardhat

์œ„ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  create an empty hardhat.config.js๋ฅผ ์„ ํƒํ•œ ํ›„ hardhat.config.jsํŒŒ์ผ์˜ solidity๋ฒ„์ „์„ Fundraisign.sol ์ƒ๋‹จ  pragma solidity ๋ฒ„์ „์— ๋งž์ถฐ์ค˜์•ผ ํ•œ๋‹ค. ์ดํ›„ hardhat.config.js ํŒŒ์ผ์— require("@nomiclabs/hardhat-waffle") ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

 

 

  1. hardhat.config.js ํŒŒ์ผ์— require("@nomiclabs/hardhat-waffle") ์ถ”
  1. create an empty hardhat.config.js ์„ ํƒ
  2. hardhat.config.js ํŒŒ์ผ์˜ solidity ๋ฒ„์ „์„ Fundraising.sol ์ƒ๋‹จ pragma solidity ๋ฒ„์ „์— ๋งž์ถ”๊ธฐ
  3. hardhat.config.js ํŒŒ์ผ์— require("@nomiclabs/hardhat-waffle") ์ถ”๊ฐ€

 

3. ๋ธ”๋ก์ฒด์ธ ๊ณ„์ • ์ƒ์„ฑ

์ด์ œ ์ปจํŠธ๋ž™์„ ๋ฐฐํฌํ•˜๊ณ  ๊ธฐ๋ถ€๋œ ๋ˆ์„ ์ˆ˜๋ นํ•˜๊ธฐ ์œ„ํ•œ ๋ธ”๋ก์ฒด์ธ ๊ณ„์ •์„ ๋งŒ๋“ค์–ด๋ณด์ž. ์•„๋ž˜ ๋งํฌ๋ฅผ ๋ˆŒ๋Ÿฌ์„œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ ์ต์Šคํ…์…˜์„ ์ถ”๊ฐ€ํ•˜๋„๋ก ํ•˜์ž.

https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn

 

MetaMask

๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋”๋ฆฌ์›€ ์ง€๊ฐ‘

chrome.google.com

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ƒˆ ์ง€๊ฐ‘ ์ƒ์„ฑ์„ ๋ˆŒ๋Ÿฌ ์ง€๊ฐ‘์„ ์ƒ์„ฑํ•˜๊ณ , ์„ค์ •์— ๋“ค์–ด๊ฐ€ ํ…Œ์ŠคํŠธ๋„ท์ด ๋ณด์ด๋„๋ก ์„ค์ •์„ ํ•ด์ฃผ์ž.

์ง€๊ฐ‘์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋‹ˆ๋ชจ๋‹‰์ฝ”๋“œ๋Š” ์ž˜ ์ €์žฅํ•ด๋‘์–ด์•ผ ํ•œ๋‹ค. ์ ˆ๋Œ€ ์žƒ์–ด๋ฒ„๋ ค์„œ๋Š” ์•ˆ๋˜๋Š” ์ •๋ณด์ด๋‹ค.

 

3. ํ…Œ์ŠคํŠธ ์ด๋” ๋ฐ›๊ธฐ

์˜์ƒ์—์„œ๋Š” All that Node๋กœ ์ง„ํ–‰ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ์œผ๋กœ ์ธํ•ด ๋ง‰ํ˜€์„œ ์•„๋ž˜ ์‚ฌ์ดํŠธ์—์„œ ํ…Œ์ŠคํŠธ ์ด๋”๋ฅผ ์ˆ˜๋ นํ–ˆ๋‹ค.

https://goerlifaucet.com/

 

์œ„ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ง€๊ฐ‘์ฃผ์†Œ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

4. All that Node ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

All that Node ์ƒ๋‹จ์˜ dashboard - Create New Project๋ฅผ ํด๋ฆญํ•˜์ž.

๊ธฐ๋ณธ ์˜ต์…˜์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ์ด๋‹ค. checkout์„ ๋ˆ„๋ฅด๊ณ  create project๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด์ž. 

์ดํ›„ add protocol์„ ๋ˆ„๋ฅด๊ณ  Ethereum์„ ์„ ํƒํ•˜๋„๋ก ํ•˜์ž.

์ด์ œ Goerli RPC ๋ณต์‚ฌํ•ด hardhat.config.js์— ์ถ”๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ url์— Goerli RPC/API Key ํ˜•์‹์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

networks: {
    goerli: {
      url: "Goerli RPC ๋งํฌ/API Key",
    },
  },

5. HardHat์—์„œ ์ง€๊ฐ‘ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜๊ธฐ

ํ˜„์žฌ๋Š” MetaMask์—์„œ ์ง€๊ฐ‘์„ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค. HardHat์—์„œ๋„ ์ง€๊ฐ‘์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์ž.

MetaMask์—์„œ ๊ณ„์ • ์„ธ๋ถ€์ •๋ณด - ๋น„๊ณต๊ฐœ ํ‚ค ๋‚ด๋ณด๋‚ด๊ธฐ - ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ๊ณผ์ •์„ ๊ฑฐ์ณ private key๋ฅผ ์•Œ์•„๋‚ด๋„๋ก ํ•˜์ž.

์ดํ›„ accounts๋ถ€๋ถ„์— ์•Œ์•„๋‚ธ private key๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. ๋‹ค๋งŒ ์ด๊ฒƒ์€ ๋ณด์•ˆ์ƒ ์ข‹์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์ด๋‹ˆ .env์— ๊ฐ’์„ ์ €์žฅํ•ด์„œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

networks: {
    goerli: {
      url: "Goerli RPC ๋งํฌ/API Key",
      accounts: ["์•Œ์•„๋‚ธ private key"]
    },
  },

 

6. ๋ฐฐํฌ ์ฝ”๋“œ ์ž‘์„ฑ

์ด์ œ ์ž‘์„ฑํ•œ ์ปจํŠธ๋ž™ ์ฝ”๋“œ๋ฅผ ๋ฐฐํฌํ•ด๋ณด์ž. scriptsํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ์•ˆ์— deploy.js ์ƒ์„ฑํ•œ ๋’ค ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋„๋ก ํ•˜์ž.

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

async function main() {
  const Fundraising = await ethers.getContractFactory("Fundraising"); //Fundraising ์ปจํŠธ๋ž™์„ ๊ฐ€์ ธ์™€์„œ ์ปดํŒŒ์ผ ํ•œ๋‹ค.
  const contract = await Fundraising.deploy(100); //100์ด๋ผ๋Š” ์ธ์ž์™€ ํ•จ๊ป˜ ๋ฐฐํฌํ•œ๋‹ค. ํ•ด๋‹น ์ธ์ž๋Š” Fundraising ์ปจํŠธ๋ž™์— ์ „๋‹ฌ๋œ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ชฉํ‘œ๊ธˆ์•ก์„ ์˜๋ฏธํ•œ๋‹ค.
  console.log("Contract address is: ", contract.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

๊ทธ๋Ÿฐ ๋‹ค์Œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ปค๋งจ๋“œ์ฐฝ์— ์ž…๋ ฅํ•ด์ฃผ๋„๋ก ํ•˜์ž.

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

์„ฑ๊ณตํ•  ๊ฒฝ์šฐ ์ฝ˜์†” ์ฐฝ์— contract address๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์„ ๊ฒฝ์šฐ ์•„๋ž˜ ERRORS ๋ถ€๋ถ„์„ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•˜์ž. ์ด์ œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ๋ฅผ ํ†ตํ•ด Ether Scan์— ๋“ค์–ด๊ฐ€๋ฉด ๋ฐฐํฌ๋œ ์ปจํŠธ๋ž™์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Etherscan์—์„œ ๊ณ„์ • ๋ณด๊ธฐ๋ฅผ ํ†ตํ•ด ๋ฐฐํฌ๋œ ์ปจํŠธ๋ž™์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

7. ๋ฐฐํฌ๋œ ์ปจํŠธ๋ž™๊ณผ ์ƒํ˜ธ์ž‘์šฉ ํ•˜๊ธฐ

Ether Scan์—์„œ Contract Creation์„ ๋ˆŒ๋Ÿฌ ํ•ด๋‹น ์ปจํŠธ๋ž™ ์ƒ์„ธ ๋ณด๊ธฐ ํŽ˜์ด์ง€๋กœ ์ ‘๊ทผํ•œ ๋’ค, ํ•ด๋‹น ํŽ˜์ด์ง€ ์ƒ๋‹จ์˜ ์ปจํŠธ๋ž™ ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ•˜์ž.

๊ทธ๋ฆฌ๊ณ  ๋ฉ”ํƒ€๋งˆ์Šคํฌ๋ฅผ ํ†ตํ•ด ๋ณต์‚ฌํ•œ ์ปจํŠธ๋ž™ ์ฃผ์†Œ๋กœ 0.001Ether๋ฅผ ๋ณด๋‚ด์ฃผ๋„๋ก ํ•˜์ž. ์ฐธ๊ณ ๋กœ 1 Ether = 1,000,000,000,000,000,000 WEI ์ด๋‹ค.

๋‹ค์‹œ ์ปจํŠธ๋ž™ ์ƒ์„ธ ํŽ˜์ด์ง€๋ฅผ ๋ณด๋ฉด 0.001Ether๊ฐ€ ์ž˜ ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

8. ์ปจํŠธ๋ž™ ํ•จ์ˆ˜ ์‹คํ–‰ํ•˜๊ธฐ

hardhat.config.js์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. abi๊ฐ’์€ artifacts/contracts/Fundraising/Fundraising.json์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

task("check", "Check contract amounts", async () => {
  const [developer] = await ethers.getSigners();
  const contract = process.env.CONTRACT_ADDRESS;
  const abi = [
    'artifacts/contracts/Fundraising/Fundraising.json์˜ "abi":[]ํ•˜๊ณ  ๋‚˜์™€์žˆ๋Š” ๋ถ€๋ถ„',
  ];
  const fundraising = new ethers.Contract(contract, abi, developer);
  console.log(
    await fundraising.targetAmount(),
    await fundraising.raisedAmount()
  );
});

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๋ฐฉ๊ธˆ ์ž‘์„ฑํ•œ task๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž. 10์ง„์ˆ˜๋กœ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด parseInt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

npx hardhat check --network goerli
task("check", "Check contract amounts", async () => {
  const [developer] = await ethers.getSigners();
  const contract = process.env.CONTRACT_ADDRESS;
  const abi = [
    'artifacts/contracts/Fundraising/Fundraising.json์˜ "abi":[]ํ•˜๊ณ  ๋‚˜์™€์žˆ๋Š” ๋ถ€๋ถ„',
  ];
  const fundraising = new ethers.Contract(contract, abi, developer);

  //์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ์ˆ˜์ •๋œ ์ฝ”๋“œ
  targetAmount = await fundraising.targetAmount();
  raisedAmount = await fundraising.raisedAmount();
  console.log(parseInt(targetAmount), parseInt(raisedAmount));
});

 

๊ฐ’์ด 16์ง„์ˆ˜๋กœ ์ถœ๋ ฅ๋˜๋Š” ๋ชจ์Šต
๊ฐ’์ด 10์ง„์ˆ˜๋กœ ์ถœ๋ ฅ๋˜๋Š” ๋ชจ์Šต

 

ERRORS

  • Error: insufficient funds for intrinsic transaction cost
    ์ปจํŠธ๋ž™์„ ๋ฐฐํฌํ•˜๊ธฐ์— ํ…Œ์ŠคํŠธ ์ด๋”๊ฐ€ ๋ถ€์กฑํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ. ์•„๋ž˜ ์‚ฌ์ดํŠธ์—์„œ ํ…Œ์ŠคํŠธ์ด๋”๋ฅผ ๋ชจ์„ ์ˆ˜ ์žˆ๋‹ค.
    https://goerli-faucet.pk910.de/
  • Error: overflow [ See: https://links.ethers.org/v5-errors-NUMERIC_FAULT-overflow ]
    ์˜์ƒ์„ ๋ณด๊ณ  100000000000000000000๋ผ๋Š” ์ˆซ์ž์™€ ํ•จ๊ป˜ ๋ฐฐํฌํ–ˆ๋”๋‹ˆ ์•„๋ž˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. 100์œผ๋กœ ๊ณ ์ณ์ฃผ์—ˆ๋‹ค.
  • ProviderError: Too Many Requests error received from ethereum-goerli-rpc.allthatnode.com
    All that Node ์—์„œ ํ˜„์žฌ too many request๋ผ๋ฉฐ ํ…Œ์ŠคํŠธ ์ด๋”๋„ ๋ฐ›์„ ์ˆ˜ ์—†๋Š” ์ƒํƒœ์ธ๋ฐ ๋ง ๊ทธ๋Œ€๋กœ ๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ์ด ์™€์„œ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค. ์ž ์‹œ ๋’ค ์‹คํ–‰ํ•˜๋ฉด ์„ฑ๊ณตํ•œ๋‹ค. ์œ ์ € ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider')
    ์ด๋”๋ฆฌ์›€ ๋ฒ„์ „์„ 5.4์ดํ•˜๋กœ ๋‚ฎ์ถ”๋ฉด ํ•ด๊ฒฐ๋˜๋Š” ์˜ค๋ฅ˜์ด๋‹ค. package.json์—์„œ ์ด๋”๋ฆฌ์›€ ๋ฒ„์ „์„ 5.4๋กœ ์ž…๋ ฅํ•˜๊ณ  npm install์„ ํ•œ ๋’ค ๋‹ค์‹œ ์‹œ๋„ํ•ด๋ณด์ž.
    https://ethereum.stackexchange.com/questions/144451/typeerror-cannot-read-properties-of-undefined-reading-jsonrpcprovider

 

References