Build Decentralized Bank

탈중앙화된 은행 시스템 만들기

Decentralized Bank System

본 실습은 dapp university의 https://www.youtube.com/watch?v=xWFba_9QYmc 영상을 참고해서 작성하였다. 해당 영상은 코드 작성 위주라 자세한 내용이 빠져있는데, 이 문서에서는 조금 더 자세히 다루도록 한다.

평점

난이도 Beginner - 2

구현 할 것

준비

  • truffle 설치

$ npm install --g truffle@5.1.39
  • Ganache 설치

참고 문서

Web3: https://web3js.readthedocs.io/en/v1.3.4/ Truffle: https://www.trufflesuite.com/docs/truffle/overview Ganache: https://www.trufflesuite.com/ganache

Environment Setting & Token Contract

Step #1

작업 디렉토리를 만들고 truffle init을 수행한다.

Truffle은 개발자들이 편하게 smart contract를 개발할 수 있도록 도와주는 프레임워크이다.

세개의 디렉토리와 truffle-config.js 파일이 생성된다.

  • contract/ : smart contract 코드인 .sol(solidity)파일이 위치하는 곳

  • migration/ : migration을 위한 javascript 코드가 위치하는 곳

  • test/ : smart contract를 테스트하기 위한 javascript 혹은 solidity 코드가 위치하는 곳

  • truffle-config.js : truffle 관련 설정하는 파일

각각에 대한 자세한 내용은 Truffle 문서를 참고하자.

먼저 truffle-config.js 파일을 열어서 다음 부분을 uncomment하고 수정한다.

Step #2 토큰 컨트랙트 생성

은행에서 이자로 배포할 토큰은 ERC20 규약을 따르도록 할 것이다. Openzeppelin 라이브러리를 이용해서 이를 처리하도록 한다. 이에 대한 문서는 아래 링크에 있다.

먼저 openzeppelin library를 설치한다. 해당 라이브러리에는 ERC20토큰에 대한 인터페이스가 정의되어 있다. 이를 import하여 상속받아 사용할 것이다.

새로 생성할 토큰에 대한 solidity 파일을 contract/ 밑에 생성하고(contract/Token.sol) 아래 내용을 입력한다.

Solidity 개발 관습에 맞게 주석을 달아 두었다. 토큰을 위한 코드는 생각보다 간단하다. 이제 truffle로 해당 코드를 컴파일해보자. truffle-config.js 에 따로 설정하지 않았다면 컴파일 결과물은 build/contracts 에 생성된다.

Step #3 Test our token contract

Token 컨트랙트가 컴파일 되었으니, 문제 없이 동작하는 지 테스트해보도록 한다. 컨트랙트는 한번 배포되면 수정할 수 없으니 다른 프로그래밍에 비해 test과정이 특히 중요하다.

Truffle의 test과정에서 Ganache를 이용하는 것이 좋다. Ganache는 이더리움 로컬 네트워크를 생성하고 100ETH를 가진 10개의 account를 제공해준다.

Ganache

Test를 진행할 때 사용할 수 있는 여러 assertion module이 있는 데, 이 중 CryptoZombies 튜토리얼에서 쓰였던 chai를 이용할 것 이다. chai는 아래와 같이 다운로드할 수 있다.

이제 test/ 폴더에 test.js 파일과 helpers/time.js helpers/utils.js 를 생성한다.

먼저 test.js 파일에 아래 내용을 입력한다. 설명은 주석을 참고하자.

다음은 utils.js 파일이다. 자주 사용하는 기능을 따로 구현한 것이다.

Truffle로 테스트를 수행한다. 자동으로 test/ 에 있는 코드를 실행하여 테스트한다.

Step #4 Token migration

컴파일된 토큰 컨트랙트를 Ganache가 만들어준 로컬 네트워크에 deploy하자. 이를 migration이라고 한다.

migrations/ 폴더에 1로 시작하는 js파일이 있다. Truffle에서 기본 템플릿으로 제공하는 거라 사실 뭔지 자게하게 모르겠다. migrations/ 폴더의 파일은 숫자 prefixed 파일명을 사용해야 하는데, Truffle이 이 숫자 순서대로 실행시키기 때문이다. Token을 배포하기 위한 2_deploy.js 파일을 생성하고 아래 내용을 붙혀넣는다.

Ganache가 동작하고 있는지 확인하고 아래 커맨드를 입력한다.

성공적으로 수행되면 2개의 deployment가 수행되었다고 출력된다.

Decentralized Bank(DeBank) Contract

Step #5 DeBank Contract 작성

이제 예금, 출금, 대출, 상환 등의 기능을 가진 DeBank contract에 대해 코드를 작성할 것이다. 우선 컨트랙트의 기본 뼈대부터 입력한다.

위 코드에서 payable 제어자(modifier)는 함수가 ETH를 받을 수 있게 한다. 즉, payable 제어자가 붙은 함수를 실행할 때 ETH를 동봉해서 실행할 수 있다.

Deposit함수를 작성하자. 아래 내용을 알맞은 위치에 붙혀넣는다.

Withdraw 함수도 아래와 같이 작성한다. (역시 주석 참고)

block.timestamp와 now는 같다. (now 가 block.timestamp의 alias) now는 deprecated이므로 block.timestamp를 사용하자.

Step #6 DeBank Testing

Test 파일은 로직만 잘 작성하면 되므로 자세한 설명은 생략하고 한번 읽어 보길 바란다. 전체 코드는 아래와 같다.

Truffle로 테스트를 진행한다.

Step #7 Deploy DeBank

Deploy 코드를 업데이트한다. 2_deploy.js 파일을 업데이트한다.

다시 처음상태부터 migrate하기 위해 --reset 옵션을 추가한다.

Frontend 구현

Step #8 Create React App

백엔드로 사용할 블록체인 구현이 완료되었으니 (DeBank의 borrow, payOff는 추후에 추가 구현) 이제 React를 이용해서 프론트엔드 구현한다. 프로젝트 루트 디렉토리에서 아래 커맨드를 입력하여 react 환경을 구성한다.

client 디렉토리로 이동해서 실행해본다.

Step #9 Install dependency & Metamask

필요한 모듈을 설치한다.

브라우저에서 web3 어플리케이션을 사용하기 위해 Metamask 확장 프로그램 설치가 필요하다.

Metamask

확장 프로그램을 설치하면 브라우저 오른쪽 위에 해당아이콘이 생성된다.

Step #10 Metamask setting

Metamask 계정을 생성한 후 테스트 용도로 쓰기 위해서 Ganache network를 등록해주어야 한다. Etereum mainnet을 클릭하고 Custom RPC를 선택한다.

아래와 같이 입력해서 Ganache Test Network를 설정한다. (포트번호가 7545일수도 있다.)

다음으로 Ganache에 생성되어 있는 10개의 test 계정 중 1개를 import한다. 프로필 사진 같은 것을 누르고 Import Account를 누르고 Ganache에서 열쇠 모양 아이콘을 클릭한 후 private key를 복사해 붙혀넣는다.

Import한 Account를 개발하고 있는 웹 사이트에 conntect 시킨다. 옵션 아이콘을 누르고 connected sites를 누르고 확인을 계속 누르면 된다.

Step #11 React Skeleton code

React 작성에 대한 가이드는 아니니 React 코드에 대한 설명은 생략한다. 아래는 UI를 보여주는 React 템ㅍ플릿 코드이다. 이제 Metamask를 연결해 web3 어플리케이션으로 만들고, deposit과 withdraw함수를 구현해서 이더리움 네트워크(여기서는 Ganache local network)와 상호작용을 해볼것이다.

Step #12 Connect to blockchain (Become a web3 app)

아래 코드는 Metamask, Blockchain backend와 연동하는 부분이다. 컨트랙트와 계정에 대한 정보를 웹으로 가져올 수 있다.

계좌가 연동되어 계좌 주소와 잔고가 출력된다.

Step #13 Interact with smart contract

Smart contract의 함수는 contract 객체의 methods.<function>.call() 혹은 methods.<function>.send() 를 호출는 것으로 실행한다.

call() 과 send()는 함수 실행이 state를 변화시키느냐에 따라 구분되어 사용된다. 예를 들어 deposit과 withdraw는 contract 내부에 저장되는 잔고(state)를 변화시키므로 send()함수를 사용해야한다.

Deposit, Withdraw 함수는 아래와 같다.

이제 3 ETH를 예금해보자.

confirm을 누르면 계좌에서 3 ETH가 빠져나간 것을 확인할 수 있다.

시간이 조금 흐른 후에 Withdraw를 진행해보자.

Deposit했던 ETH가 다시 들어왔다. 그런데 이자로 받은 토큰은 어떻게 확인할까? 토큰을 Metamask에 추가해주어야 지갑에서 확인 가능하다. 토큰 컨트랙트 주소를 복사해서 Metamask의 Assets - Add Token에 붙혀넣는다. Token.json 파일에서 확인 가능하다.

"address"

아주 잠깐 예금했기때문에 매우 적지만 이자가 DEBT 토큰으로 계좌에 들어온 것을 확인할 수 있다.

Source code on Github

참고: https://www.youtube.com/watch?v=xWFba_9QYmc

Last update: 2021/04/25

Last updated

Was this helpful?