4일차-[ERC20]스마트컨트랙트 토큰 발행, 전송 & 지갑 만들기

스마트 컨트랙트 문법을 먼저 살펴보고, Besu나 Ganache로 스마트 컨트랙트 활용 실습(ERC20형식)과 MetaMask같은 지갑을 만드는 실습을 소개한다. 그리고 동작 원리를 살펴보자.

ERC20 방식은 우리가 토큰의 주인이며 마음대로 생성할 수 있고, 다른 이에게 줄 수 있다.

참고: 투자의 목적이 있다면 1차적으로 해당 코인의 github를 검색해서 업데이트가 자주 되는지 확인


실습전 개념 보충 설명

  • 암호화폐 - 코인과 토큰을 이쁘게 부르는 방법
  • 가상화폐 - 코인과 토큰을 이쁘게 부르는 방법
  • 코인 - 본인의 자체적인 플랫폼을 가지고 있는 블록체인에서 발행하는 가상(암호)화폐를 코인이라 한다 (ex. Eos, bitcoin, ethereum)
  • 토큰 - 자체적인 플랫폼 없이 특정 플랫폼에 종속되어서 코인을 생성하는 형태
  • 스테이블 코인 - $1 = (정해진) 코인의 가치를 가지도록 하겠다는 것. 변동성을 줄인다는 것.
    • 실제로 있는 개념이다. (핸드폰 마일리지, 게임 캐시 재화, 현대백화점 포인트)
    • 만원 = 1포인트 (머지포인트 사태)
  • CBDC (중앙은행) - 2022년 까지 중국에서 가상화폐
    • 토근 or 코인 -> 발행 주체와 관리를 국가에서 해준다. 1000원 = 1코인
    • 이 또한 실제 있는 개념. (지역화폐, 경기도 지역화폐, 전라도 지역화폐, 경상도 지역화폐, 광주시 지역화폐, 전북 지역화폐)
    • 다만, 코로나 때문에 아직이다.
  • Ganache를 켠 순간부터 가상 서버가 돌아가는 것. Besu에서 node 동작 시키면 가상 서버 돌아가는 것
    • 이때, Metamask 로 접근해야 Metamask 에서 정상 출력


이번 실습은 복잡하다.

그래도 지갑을 만들어서 스마트 컨트랙트에서 하던 구동을 개인이 직접 코드를 작성해서 똑같이 구동이 가능하단 점을 알 수 있을 것이다.

deploy(배포)가 된 건 체인에 created된 느낌이고 이때 생성된 주소가 deploy스마트 컨트랙트 주소이다.
=> 해당 주소(deploy된 스마트 컨트랙트 주소)를 사용하면 발행한 토큰을 Metamask 에서 가져올 수 있다.



스마트 컨트랙트 문법



변수/데이터 타입

  • Arraylist와 유사
  • Unit, Address가 생소한 데이터 타입

스마트 컨트랙트 문법1



함수

  • view를 많이 사용

스마트 컨트랙트 문법2



함수의 호출 범위 (가시성)

최종 함수 호출 형태

스마트 컨트랙트 문법3

스마트 컨트랙트 문법4



생성자

스마트 컨트랙트 문법5

스마트 컨트랙트 문법6



함수 변경자

  • 생성자랑 같이 실행된다고 보면 된다.

스마트 컨트랙트 문법7



예외 처리, 이벤트

  • 예외처리 예시는 위의 require(msg.sender == owner);
  • 이벤트 예시function { ~~~ event (log1, "테스트") }

스마트 컨트랙트 문법8



address 타입의 자료형

스마트 컨트랙트 문법9



조건문, 반복문

  • 조건문 : if, if else, else
  • 반복문 : for



상속

  • is 키워드 사용
  • public, internal 일 때 사용 가능



Remix 활용 - 이더리움 IDE

getter, setter 테스트

  • Remix(=IDE) 에서 start coding 클릭 및 ` solidity` 스마트 컨트랙트 언어를 사용할 것이다.

Remix로 solidity 테스트


예시

  • 첫 줄에 라이센스 부분 입력해줘야 오류가 안뜰 가능성이 높다.
  • 다음 줄은 solidity 버전을 몇을 사용하는지 입력한 것이다.
  • contract 에는 파일명과 같은 이름으로 생성한다.
  • 코드 내용은 자바의 getter, setter 함수 만드는것과 같다.

Remix로 solidity 테스트2


Deploy

  • 컴파일은 간단하니까 생략
  • Deploy를 통해 테스트 -> deploy 만 해도 GAS(수수료) 발생 확인 가능하다.
  • 한번 수정이 돼서 컴파일한 “스마트 컨트랙트는 주소”가 달라진다는 것을 꼭 기억
    • “스마트 컨트랙트 주소”는 아래 그림 속 왼쪽 아래에 Deployed Contracts 아래 FIRST… 주소 복사할 수 있다.
    • 예시로 public을 private으로 수정 후 다시 컴파일 및 Deploy를 하니 주소가 달라졌다.
      • 0xd9145CCE52D386f254917e481eB44e9943F39138 가
        0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3 로 변경
    • 그리고 여기서 만든 함수들이 IDE에서 버튼처럼 사용할 수 있게 되어있다.
      • 예로 postInt, getInt 등 이런 함수들 버튼으로 제공 (아래 사진엔 안보이고 뒤에 찾아보면 있음)

Remix로 solidity 테스트3



ganache 활용

  • 이전에 Ganache 사용한 프로젝트로 접근하도록 세팅하겠다.
  • ENVIRONMENT를 Ganache로 잡아주고, ACCOUNT에 우리가 요청할 주소를 입력
    • 참고로 0xccF… 주소 사용했고 Ganache에서 Public Key 주소다. Metamask에서 계정을 가져올때 사용하는 키는 Ganache에서 Private Key
  • Deploy하면 트랜잭션 create가 되고, 함수 버튼 클릭해서 요청하면 call로 잘 넘어간다.
    • 참고로 이때는 스마트 컨트랙트 주소가 생긴다.
  • 참고로 deploy나 함수 사용(postInt같은)은 전부 가스 요금이 붙지만 getInt 와 같은 함수들은 붙지 않으며 트랜잭션 횟수로도 추가되지 않는다.

Remix와 ganache


Deploy 이후 call을 해보겠다. -> postString 버튼 클릭

Remix와 ganache2


아래 그림 속 TX DATA가 우리가 보낸 값 “ganache” 이라고 보면 된다.

sender 쪽이 앞에서 적었던 주소이고, to contract 는 deploy되어 created된 스마트 컨트랙트 주소이고, 상단은 블록 트랜잭션 해시 값 이다.

오른쪽에 CONTRACT CREATION이 아닌 CONTRACT CALL 인 것을 보면 postString 버튼을 눌러 call 을 한 상태의 데이터임을 알 수 있다. (CREATION이 였으면 처음 Deploy 상태의 데이터)

Remix와 ganache3



besu 활용

우선 besu를 node 4개다 실행해준다. ganache 대신 가상 서버를 구동하는 느낌이다.

그후 metamask와 연동할 주소를 복사해서 ENVIRONMENT와 ACCOUNT를 적절히 작성한다.

besu는 지갑확인은 metamask로 확인하고 hash값 날린 데이터 확인은 postman로 확인했는데,
ganache는 이것을 ganache하나로 다 볼수 있는 것이었다. (지갑+데이터 전부 확인 가능)

물론, ganache도 지갑을 metamask로 확인 가능하다.


Account2 (0x829…주소)의 지갑 확인

Remix와 metamask와 besu


Remix에 Metamask 환경으로 세팅 및 위 주소로 스마트컨트랙트 테스트

Remix와 metamask와 besu2


Deploy로 Creation한 결과 지갑을 확인해보면 가스(수수료)가 빠진 걸 알 수 있다.

Remix와 metamask와 besu3


postInt 버튼을 클릭했을시 수수료가 빠지는 모습도 볼 수 있다.

Remix와 metamask와 besu4


마지막으로 postman에서 해시값 보낸것을 확인 가능하다. (사진생략)
ganache에서 TX DATA로 보이던 부분처럼 말이다.



testnet 활용

과정은 생략

  • testnet도 가능
    • 마찬가지로 ENVIRONMENT를 metamask로 설정 하면 된다.
  • etherscan에서도 확인가능



토큰 발행 실습 - ERC20 규칙

ERC20 방식은 우리가 토큰의 주인이며 마음대로 생성할 수 있고, 다른 이에게 줄 수 있다.

위에서 한 것은 테스트로 코드를 짜본 것일 뿐이다. 이번엔 ERC20 규칙을 살려서 실습을 진행한다.

  • ERC20 규칙 참고
  • 해당 문서의 Methods 부분 코드 가져와 remix에 작성
    • 그러나, 코드 작성하기 매우 힘드니까 깃허브에 제공하는 코드를 사용하겠다.
    • 깃허브 에서 아래 코드들만 가져와 remix에 작성

토큰 발행 실습

추가로 ERC20.sol과 IERC20Metadata.sol 의 윗부분 코드인 import에 경로를 ./으로 수정(동일한곳에 파일 생성했음)

코드에 컴파일 버전도 0.8.0이면 맞춰서 컴파일하면 에러 없이 잘 될 것이다.


계속 코드를 수정하자면…

// ERC20.sol
constructor(string memory name_, string memory symbol_) {
_name = name_; // 토큰 이름
_symbol = symbol_; // 토큰 심볼
_mint(msg.sender, mint_); // 누구(msg.sender)한테 줄건지, 양은 얼마나 할지
} // mint를 추가함

function decimals() public view virtual override returns (uint8) {
	return 1;
} // return을 18에서 1로 수정함.(소수점 표현)



테스트로 Deploy 할 때는 CONTRACT를 ERC20.sol으로 하면 토큰을 잘 발행하게 된다.

  • 아래처럼 하면 1000 st토큰을 얻을 수 있다.

토큰 발행 실습2



Ganache에서 테스트

Ganache에다가도 테스트해 볼 수 있고, 지갑은 Metamask로 확인 해보겠다.

Ganache -> 0.19ff… 주소를 가진 719 ETH 가 있다.

토큰 발행 실습3


Remix -> Ganache 연결 및 주소도 위 0.19ff… 주소를 설정하고 seo 토큰 발행 (이때 가스 발생)

토큰 발행 실습4

토큰 발행 실습5


Metamask -> 아래 그림은 단순히 가스(수수료) 사용하여 719->718 ETH 된 모습

  • 네트워크를 Ganache로 맞추고, 계정은 Ganache의 private key로 가져오면 끝
  • 내역보면 변경내역이 나오며, 토큰을 보고싶으면 토큰 가져오기에서 Remix의 Deployed Contracts에 있는 주소 복사해서 가져오면 생성된 토큰 확인도 가능

토큰 발행 실습6


토큰 가져오기는 이런식으로 생겼고 주소에는 스마트 컨트랙트 주소를 사용한다. (아래 주소는 위와 관련X)

metamask



Besu에서 테스트

위 작업을 Besu에서도 해보겠다. 서버 다시 구동하자 node1~4


Remix IDE -> Metamask 환경 연결에 0x829… 주소의 계정에 seo 토큰 발행 (가스 발생)

  • 아마 100JW 토큰이 10JW 토큰으로 보이는듯 하다.

토큰 발행 실습7


Metamask -> 가스 사용된 모습, 토큰 내역은 스마트컨트랙트 주소를 가져와야 추가 된다.

토큰 발행 실습8


함수사용 : increaseAllowance -> 함수 사용에도 가스 발생

  • 위에서 생성한 스마트컨트랙트에서 increaseAllowance 함수를 사용하는 모습
  • 0x4684… 주소로 10JW (실제론 1JW인듯?) 토큰을 추가한다.

토큰 발행 실습9


Metamask -> 함수 사용으로 가스 사용된 모습 (소수점자리가 9961 -> 9959)

토큰 발행 실습10


위 사진에서 내역만 보고, 토큰은 안 보여줬는데 토큰은 Metamask에서 토큰 가져오기 하면 볼 수 있다.
주소는 Deployed Contracts에 있는 주소 사용

  • 이 주소는 deploy된 스마트 컨트랙트의 주소이다. 0x8C8…
  • 이를 가져온 후 다시 Account2 계정을 확인해보면 9JW 토큰이 확인 된다.
    • 아마도 앞에서 100JW 에서 10JW를 0x4684… 주소로 줘서 90JW로(9JW)로 나온듯 하다.

image-20220721150331863

토큰 발행 실습11


JW 새로 생성한 토큰 전송 또한 문제없다. -> 위에서 함수 사용할 때 아래 주소로 토큰을 추가했었다.

토큰 발행 실습12



지갑 만들기 실습

여기선 besu과정만 나타낼 것이고, 혹시나 ganache가 궁금하다면 여기 과정과 같게 하되,
port 주소와, private key, public key 이런 부분들만 잘 수정하면 된다.

  • Nodejs를 사용할 것이기 때문에 안 깔려있으면 설치 Node.js

  • 바탕화면에 wallet_practice 폴더 생성 및 bash로 npm init 명령어 실행
    • package.json 생성
  • 하드코딩을 시작한다. 모든 스마트 컨트랙트 정보들 사용하기위해



package.json의 의존성(dependecise) 수정

  • 수정 후 bash에 npm install 명령어 실행 - lock파일 생성되면 ok
{
  "name": "wallet_practice",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.3",
    "web3": "^1.7.1",
    "body-parser": "^1.19.0",
    "ethereumjs-tx": "^1.3.7"
  }
}



html 작성

send.html 코드 작성

<form action="/send" method="post">
  address : <input type="text" name="address" /><br/>
  value : <input type="text" name="value" /><br/>
  submit : <input type="submit"/>
</form>


deploy.html 코드 작성

<form action="/deploy" method="post">
  token_name: <input type="text" name="tn" /><br/>
  token_symbol: <input type="text" name="ts" /><br/>
  total_supply : <input type="text" name="supply" /><br/>
  submit : <input type="submit"/>
</form>


balance.html 코드 작성

<form action="/balance" method="post">
  address : <input type="text" name="address" /><br/>
  submit : <input type="submit"/>
</form>



server.js 코드 작성

deploy와 send와 balance 를 진행해보겠다.


1) deploy

  • 블록체인과 연동하는 것을 중점으로 볼것
  • deploy하면 또 배포할 필요 없고, 얻은 contractAddress만 잘 사용하면 됨.

지갑 실습1

지갑 실습2

지갑 실습3

지갑 실습4


토큰 가져올때는 Remix에서

  • 지갑 실습5 이부분 복사해서 토큰 가져온것


이 주소는 deploy된 스마트 컨트랙트의 주소이다.

  • metamask로 확인하기 위해 토큰 가져오는 건 아래 사진 드래그한 주소를 잘 사용
  • 아래는 deploy 결과
  • 토큰을 가져오는 거지 계정 가져오는 게 아님. 햇갈리지 말것. 계정은 그냥 있는 계정 활용

지갑 실습6

지갑 실습7


2) send

  • 위에서 얻은 주소를 적용
    • 위에 드래그한 contractAddress를 의미한다.
  • form 쪽에 send할 땐 보내고 싶은곳 주소 적으면 된다.
    • public key(private key인가..? 햇갈림)를 보내면 됨. 여기선 Account1 계정의 주소를 보냈음

지갑 실습8


Metamask 계정1 확인 -> 본인은 aa라는 토큰 1000 을 보냄

지갑 실습9


3) balance

  • 잔고확인은 더 쉬운 이유가 이미 올라가 있는 블록체인에서 가져오는 거기 때문에 더 간단

  • form에 주소만 적어주면 된다. 이 또한 Public Key(private key인지 햇갈림)를 작성한다.

지갑 실습10


계정1 의 1000 aa 토큰의 잔고 표시

지갑 실습11



개념 보충설명

  • 참고 : JavaScript안에 Nodejs이고, Nodejs안에 Express, react가 포함된다.


전체적인 구조

전체 구조


Metamask 동작 원리

  • UI 자리를 Metamask가 하는것이다.

Metamask 동작 원리


Ganache 동작 원리

  • Metamask같은 UI 동작을 할 수 있는게 없어서 Remix(IDE)를 사용
  • 그렇지만, Ganache는 Metamask처럼 지갑 기능은 들고 있다.

Ganache 동작 원리


besu활용 돌아간 동작원리

  • besu로 했을 때 아래 그림 형태로 돌아갔던 것이다.
  • Metamask로 전송 가능했고 Remix ID로도 전송 가능했다는 점 기억
    Ganache는 전송하는 UI도 없고 불가했다는 점 기억

besu 동작 원리

댓글남기기