230619_4주차

김강현·2023년 6월 19일
0

블체스-3기-TIL

목록 보기
12/12

월요일 (오전)

Tether 에서 usdt 가격은 항상 1달러 (stable coin)

유니스왑, 바이낸스를 통한 시장 프로세스

web3@1.9.0 버전 node 진행
(send가 가능한 버전)

hardhat 배포 실습

  1. etherscan 회원가입 및 api key 발급

  2. hardhat setting

> npm install --save-dev hardhat
> npm install --save -dev @nomicfoundation/hardhat-toolbox
> npx hardhat
  1. Lock.sol 변경
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
    uint public a;

    function getA() public view returns(uint) {
        return a;
    }

    function setA(uint _a) public {
        a = _a;
    }
}
  1. compile
    > npx hardhat compile

  2. deploy.js 변경

const hre = require("hardhat");

async function main() {
    //contract 변수로 설정
    const Contract_A = await hre.ethers.getContractFactory("Lock");
    //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;
});
  1. hardhat.config.js 변경
require("@nomicfoundation/hardhat-toolbox");

const PVK = "개인키"

module.exports = {
  solidity: "0.8.17",
  etherscan : {
    apiKey : "이더스캔 api 키",
  },
  networks : {
    goerli : {
      url : `https://goerli.infura.io/v3/infura api 키`,
      accounts : [PVK],
    }
  }
};
  1. 배포
// goerli
npx hardhat run --network goerli .\scripts\deploy.js

// etherscan verify & publishing

hardhat을 통해서 더 쉽게 verify & publishing이 가능하다.

npx hardhat verify --network goerli {컨트랙트 주소}

이런식으로 바로 업데이트

월요일 (오후)

Flatten 기능
import 되어있는 것들도 전부 한 파일에 담는 것.
(remix 에서는 우클릭 후 flatten 누르면 파일 생성됨)

hardhat 배포 실습 (constructor 있는)

npm install @openzeppelin/contracts

  1. erc20_3.sol 생성
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/token/ERC20/ERC20.sol';

contract ABCToken is ERC20("LikeLion", "LION") {
    constructor(uint totalSupply) {
        _mint(msg.sender, totalSupply);
    }

    function MintToken(uint a) public {
        _mint(address(this), a);
    }

    function decimals() public pure override returns(uint8) {
        return 0;
    }

    receive() external payable{}
}
  1. deploy_erc20_3.js 생성
// scripts 폴더의 deploy.js 파일 수정

const hre = require("hardhat");

async function main() {
  const LOCK = await hre.ethers.getContractFactory("ABCToken");
  const lock = await LOCK.deploy(1234);
  console.log("LOCK deployed to : ", lock);
  console.log("LOCK deployed to : ", lock.target);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
  1. 배포
> npx hardhat run --network goerli ./scripts/deploy_erc20_3.js
  1. verify & publishing
> npx hardhat verify --network goerli {컨트랙트 주소} {배포시 constructor input}

위 1234랑 같은 값을 넣어주어야, verify가 작동한다.

react 실습

  1. web3 goerli websocket 설정
const web3 = new Web3(
    "wss://goerli.infura.io/ws/v3/{apikey}"
);

const privateKey = '';
const account = web3.eth.accounts.privateKeyToAccount(privateKey).address;

해당 사이트에서 subscribe 사용법 확인 가능!
https://docs.web3js.org/guides/web3_upgrade_guide/x/subscribe_migration_guide

  1. subscribe event 추가
    전체 코드
import React from 'react';
import {useEffect, useState} from 'react';
import Web3 from 'web3';

function App() {
  const [blockNumber, setblockNumber] = useState();
  const [balance, setBalance] = useState();

  const web3 = new Web3("wss://goerli.infura.io/ws/v3/apiKey");

  const privateKey = '개인키';
  const account = web3.eth.accounts.privateKeyToAccount(privateKey).address;

  useEffect(()=> {
    async function getBlock() {
      const blockNumber = await web3.eth.getBlockNumber();
      setblockNumber(Number(blockNumber));
    }

    getBlock();
  })
  
  useEffect(()=> {
    async function subscribeBlock() {
      const subscription = await web3.eth.subscribe('newHeads');
      subscription.on('data', async blockhead => {
        console.log("Number of New Block : ", blockhead.number);
        setblockNumber(Number(blockhead.number));
      })
    }
    subscribeBlock();

    async function getBalance() {
      var balance = await web3.eth.getBalance(account);
      setBalance(Number(balance));
    }

    getBalance();
  })

  return (
    <div>
      <li>real time current block number is : {blockNumber} </li>
      <li>current Wallet : {account}</li>
      <li>current Balance : {balance}</li>
    </div>
  );
}

export default App;

dApp 구조

contract의 주소 접근 관련!!
https://ethereum.stackexchange.com/questions/268/ethereum-block-architecture

다양한 event listener 실습

window.ethereum.request({
        method: "eth_chainId",
      });
window.ethereum.on("chainChanged", () => {});
window.ethereum.on("accountsChanged", () => {});

화요일 (오전)

이쪽 진로 라인 정리 (feat. 민서 강사님)

이더 송금

<form onSubmit={sendTx}>
   <input type="text" name="address" placeholder="write address"></input>
   <input type="text" name="amount" placeholder="write amount"></input>
   <button type="submit">Send TX</button>
</form>
  async function sendTx(e) {
    e.preventDefault();
    const data = new FormData(e.target);
    console.log(typeof data.get("amount"));
    /*var a = Number(data.get("amount"));
    a = web3.utils.numberToHex(a);*/
    var a = web3.utils.numberToHex(Number(data.get("amount")));
    console.log(a, typeof a);

    await window.ethereum.request({
      method: "eth_sendTransaction",
      params: [{ from: account, to: data.get("address"), value: a }],
    });
  }

화요일 (오후)

컨트랙트 실습 (erc20)

import abi from "./abi.json";
...
var c_addr = "0xf7389e84220FF1165842e38C8e92772846e61A9d";
var contract = new web3.eth.Contract(abi, c_addr);
console.log("methods are : ", contract.methods);

토큰 balance를 관리할 useState 추가

const [tBalance, setTbalance] = useState();

토큰 balance 받아오기

  async function getTbalance() {
    if (account) {
      setTbalance(await contract.methods.balanceOf(account));
    } else {
      console.log("connect the wallet");
    }
  }

토큰 transfer

  async function sendErc(e) {
    e.preventDefault();
    const data = new FormData(e.target);
    var a = web3.utils.numberToHex(Number(data.get("amount_2")));

    await window.ethereum.request({
      method: "eth_sendTransaction",
      params: [
        {
          from: account,
          // to: data.get("address_2"), <- 함수 호출은 CA 한테 하는 거
          // to: data.get(c_addr), <- 실패
          to: c_addr,
          data: contract.methods.transfer(data.get("address_2"), a).encodeABI(),
        },
      ],
    });
  }

토큰 minting

<form onSubmit={minting}>
    <input type="text" name="amount_3" placeholder="write amount"></input>
    <button type="submit">Mint</button>
</form>
  async function minting(e) {
    e.preventDefault();
    const data = new FormData(e.target);
    var a = web3.utils.numberToHex(Number(data.get("amount_3")));

    await window.ethereum.request({
      method: "eth_sendTransaction",
      params: [
        {
          from: account,
          to: c_addr,
          data: contract.methods.MintToken(a).encodeABI(),
        },
      ],
    });
  }

minttoken payable 추가

contract addreess, abi 변경 필요

  async function payMinting(e) {
    e.preventDefault();
    const data = new FormData(e.target);
    var a = web3.utils.numberToHex(Number(data.get("amount_3")));
    var b = web3.utils.numberToHex(Number(data.get("amount_3"))*10000);

    await window.ethereum.request({
      method : "eth_sendTransaction",
      params : [{
        from : account,
        to : c_addr_2,
        value : b,
        data : contract2.methods.MintToken(a).encodeABI()
      }]
    })
  }

evm 동작 원리 구경

https://www.evm.codes/playground?fork=shanghai
이 사이트에서 stack, memory, storage 등 동작 프로세스 확인 가능

수/목 (typescript)

create react app

> npx create-react-app [directory] --template typescript

각종 자료형

FC (Function Component)

type, interface

type TCreature = {
  name: string;
  level: number;
};

interface ICreature {
  name: string;
  level: number;
}

const player: TCreature = {
  name: "Knight",
  level: 10,
};

const monster: ICreature = {
  name: "Skeleton",
  level: 8,
};

type, interface 확장

interface IHuman extends ICreature {
  age: number;
}

const c: IHuman[] = [
  {
    name: "Knight",
    level: 10,
    age: 10,
  },
];

props

props 변수들을 interface 로 지정해서, <> 안에 적어주면 된다.

interface BoxProps {
  color: string;
}

const Box: FC<BoxProps> = ({ color }) => {
  return (
    <div
      style={{
        backgroundColor: color,
        width: 400,
        height: 400,
        margin: 40,
      }}
    ></div>
  );
};
export interface BoxProps {
  color: Color;
  width: number;
  height?: number;
}

이런식으로 ? 를 붙혀주면 생략가능.

금 (오전)

CSR (Client Side Rendering)
SSR (Server Side Rendering)

SSG 라는 것도 있음 (Static Site Generation)

Next js

> npx create-next-app [폴더명]
(전부 yes로 설치)
typescript, eslint, src/, app router, alias(@)

profile
this too shall pass

0개의 댓글