안녕하세요.
Ethereum Dapp개발을 위한 truffle 튜토리얼 중 pet-shop 튜토리얼을 통해 로컬 개발환경 구성과 실행 테스트, 명령어 실행은 물론이고 스마트 컨트랙트 개발, 테스트, 마이그레이션을 경험해 볼수 있습니다
또한 nodejs 를 이용해서 웹으로 web3 클라이언트로 블록체인과 통신하고 트렌젝션 처리를위해 웹 브라우져를 통해 Metamask를 구동하고 거래를 처리해 봄으로서 Dapp서비스 개발의 전체적인 흐름과 개발 방법을 경험해볼수 있는 좋은 예입니다
(먼저, 충실히 튜토리얼을 진행해보고 이후 기본 기능에서 점차적으로 확장해가면서 기능을 추가해 볼 계획입니다)
Pet Shop 튜토리얼의 대상
Pet Shop 튜토리얼 요건정의
Pet Shop 튜토리얼 아키텍처
4가지의 주요 기능으로 구성되며 순차적으로 하나씩 살펴 보겠습니다
튜토리얼 순서
(MacOS를 기준으로 작성합니다)
먼저 Truffle 설치 전에 아래 두가지를 설치합니다.
완료 후 Truffle을 설치합니다.
|
:~ dongsik$ sudo npm install -g truffle Password: /Users/dongsik/.nvm/versions/node/v6.9.5/bin/truffle -> /Users/dongsik/.nvm/versions/node/v6.9.5/lib/node_modules/truffle/build/cli.bundled.js + [email protected] updated 1 package in 4.603s :~ dongsik$ |
Truffle 설치 확인
Ganache 설치
스마트 계약의 배포, 어플리케이션 개발, 테스트 실행에 사용할 Ethereum 개발을 위한 Personal 블록체인
http://truffleframework.com/ganache 로 이동하여 “Download” 버튼을 클릭하고, Ganache를 다운로드 및 설치합니다.
설치 후 Ganache를 실행하면 로컬 RPC 서버가 구동되며 테스트를 위한 10개의 Account가 만들어집니다. 우측 상단의 설정에서 IP 및 포트를 지정 할 수 있습니다. (자세한 사용방법은 사이트를 참조하세요)
Truffle은 현재 디렉토리에서 초기화 되기 때문에 먼저 디렉토리를 하나 만들고 그 디렉토리로 이동합니다.
Pet-shop 튜토리얼을 위한 Truffle Box가 만들어져 있으며, 기본 프로젝트 구조와 사용자 인터페이스 코드가 포함되어 있습니다. Truffle Box를 풀려면 Truffle unbox 명령을 사용하면 됩니다.
생성된 기본 Truffle 디렉토리 구조 및 파일 설명
contracts / : 스마트 계약을 위한 Solidity 소스 파일을 포함합니다. 해당 디렉토리에 Migrations.sol이라는 중요한 계약이 있습니다. 이 계약에 대해서는 나중에 설명합니다.
Migrations / : Truffle은 스마트 컨트랙트 배포를 처리 하기 위해서 Migration시스템을 사용합니다. Migration은 변경 사항을 추적하는 추가적인 특별한 스마트 계약입니다.
test / : 스마트 컨트랙트의 JavaScript 및 Solidity 테스트를 모두 포함합니다.
truffle.js : Truffle 설정 파일
백-엔드 로직 및 스토리지 역할을하는 스마트 계약서를 작성하여 dapp을 시작해 봅니다.
첫 번째로, contracts > Adoption.sol 파일 추가 합니다.
심볼 (^)은 필요한 Solidity의 최소버전을 지정("표시된 버전 이상")하며, 명령문은 semicolons(;)로 끝납니다.
Address라는 고유한 데이터 타입, 즉 Ethereum의 주소이며 20 bytes의 값으로 저장됩니다.
Ethereum address의 배열. 배열은 하나의 유형(type)이 포함되며 고정 또는 가변 길이를 가질 수 있습니다. 이 경우 유형은 address 이며 배열의 크기는 16입니다.
또한 변수 adopters가 public임을 알 수 있습니다. Public 변수는 자동으로 getter 메소드가 가지지만, 이 경우 배열은 키가 필요하며 단일 값만 반환합니다. 나중에 UI에서 사용할 전체 배열을 반환하는 함수를 작성할 것입니다.
사용자가 입양(Adoption) 요청을 할 수 있도록 허용합니다.
Solidity에서는 함수 매개 변수와 출력 유형을 모두 지정 해야 합니다. 이 경우 petId (정수)를 가져 와서 정수를 반환합니다.
PetId가 adopters 배열 범위 내에 있는지 확인합니다. Solidity에있는 배열은 0부터 인덱싱되므로 ID 값은 0에서 15 사이 여야합니다. ID가 범위 내에 있는지 확인하기 위해 require () 문을 사용합니다.
ID가 범위 내에 있으면 우리는 adopters 배열에 호출 한 주소를 추가합니다. 이 함수를 호출 한 사람 또는 스마트 계약자의 주소는 msg.sender로 표시됩니다. 마지막으로, 제공된 애완 동물을 확인하고 반환합니다.
마지막으로, 확인을 하기 위해 전달했던 petId를 반환합니다.
위에서 언급 한 것처럼 배열 getter는 주어진 키에서 하나의 값만 반환합니다. UI에서는 모든 애완 동물의 입양 상태를 업데이트해야하지만, 16 개의 API 호출을 하는 것은 이상적이지 않습니다. 다음 단계는 전체 배열을 반환하는 함수를 작성하는 것입니다.
위에서 추가 한 adopt () 함수 다음, 스마트 계약에 getAdopters () 함수를 추가합니다.
adopters 들은 이미 선언 되었으므로 간단하게 반환 할 수 있습니다. 반환 유형 (이 경우, Adopters의 유형)을 Address [16]으로 지정해야합니다.
앞에서 간단한 Smart contract를 작성했습니다. 다음으로 컴파일 및 마이그레이션을 해보겠습니다
트러플은 내장 개발 콘솔(Truffle Develop) 가지고 있는데 개발용 블럭체인을 생성하고 이를통해 컨트랙트 배포(deploy)테스트를 해볼수 있습니다
또한 콘솔에서 직접 트러플의 명령들을 실행하는 기능도 가지고 있습니다
Solidity는 컴파일 언어 입니다. 즉, Ethereum Virtual Machine(EVM)에서 실행하기 위해 bytecode로 컴파일 해야 합니다
인간이 읽을수있는 Solidity코드를 EVM이 이해할수있는 무엇인가로 변환 번역 한다고 생각하면 됩니다
컴파일이 완료되면 .build/contracts 폴더아래 compile 정보를 담은 개별 json 파일이 생성됩니다.
성공적으로 Smart Contract가 Compile되면 이제 블록체인으로 migrate 합니다.
마이그레인션(Migration)은 응용 프로그램의 계약 상태를 변경하여 한 상태에서 다음 상태로 이동시키는 전개 스크립트입니다. 첫 번째 마이그레이션의 경우 새 코드를 배포하는 것이지만 시간이 지남에 따라 다른 마이그레이션은 데이터를 이동하거나 계약을 새로운 것으로 대체 할 수 있습니다.
migrations/ 폴더에 default로 1_initial_migration.js 파일이 존재합니다.
이 파일은 이후 스마트 계약의 마이그레이션을 관찰하기 위해 Migrations.sol 컨트랙트의 배포를 관리하며, 나중에 변경되지 않은 컨트랙트를 이중 마이그레이션하지 않도록 보장합니다. (1_initial_migration.js 내용)
이제 Adoption 컨트랙트에 대한 마이그레이션을 작성합니다
migrations/ 디렉토리에 2_deploy_contracts.js 파일을 생성
2_deploy_contracts.js에 아래 내용 입력
컨트랙트를 블록체인으로 Migration하기 전에 블록체인을 실행 해야 합니다. 컨트랙트를 Deploy, 어플리케이션 개발, 테스트 실행을 위해 Private 블록체인으로 Ganache를 사용 합니다.
(응용 프로그래밍에서 Ganache.app을 실행하면 됩니다.)
truffle.js파일에서 Ganache를 설정합니다. 이때 설정정보에 networks에 development 를 추가하면 로컬 Ganache에 연결됩니다.
이제 터미널에서 컨트랙트를 블록체인으로 migration 합니다
순서대로 실행중인 마이그레이션과 배포 된 각 계약의 블록 체인 주소를 볼 수 있습니다. (이때 주소가 다를 수 있습니다.)
Ganache를 통해 블록체인의 상태가 변경된 것을 확인합니다. 현재 블록이 이전에 0이었는데 블록이 4로 변경된것을 보여줍니다. 또한 첫 번째 계정의 원래 Ether는 100 이었지만 마이그레이션하는 데 드는 트랜잭션 비용으로 인해 이제는 더 낮습니다. 나중에 거래 비용(Transaction Costs)에 대해 자세히 이야기하겠습니다.
아래는 추가된 블록의 정보
트렌젝션의 처리 정보
이제 첫 번째 스마트 계약서를 작성하여 로컬로 실행중인 블록 체인에 배포했습니다. 이제 이 스마트 계약과 상호작용을 해 보겠습니다. (interact with)
Truffle은 스마트 계약 테스트의 경우 매우 유연합니다. 테스트는 JavaScript 또는 Solidity로 작성 될 수 있습니다. 이 튜토리얼에서는 Solidity에서 테스트를 작성합니다.
adopt() 함수를 테스트하기 위해 앞서 작성한 Adoption.sol 컨트랙트의 adopt()함수를 상기해보면 함수는 성공하면 입력된 petId를 리턴하는 것을 떠올려 보기 바랍니다. 테스트 케이스에서는 ID가 반환되었는지와 전달된 ID에 대해 adopt() 함수의 반환 값을 비교하여 올바른지 확인 할 수 있습니다.
앞서 언급한 public 변수가 자동 getter 메소드를 가진다는것을 기억한다면, 위의 입양 테스트에서 저장한 주소를 검색할 수 있습니다. 저장된 데이터는 테스트 기간 동안 지속되기 때문에 앞서 테스트한 Pet의 adopt(8)의 입양 정보는 다른 테스트를 통해 검색 가능 합니다.
배열은 주어진 단일 키에 대한 단일 값만 반환하기 때문에 전체 배열을 위한 자체 getter를 만듭니다.
전체 테스트 코드입니다.
이제 터미널로 돌아가서 test를 실행합니다.
"truffle test"를 사용하며, 모든 테스트가 통과 되면 아래와 같은 출력을 확인 할수 있습니다.
이제 스마트 계약서를 작성하여 로컬 테스트 블록체인에 배포하고 콘솔을 통해 상호 작용할 수 있다는 것을 확인 했으므로 Pete가 Pet Shop에서 사용할 수 있는 UI를 만들겠습니다.
이 Pet shop Truffle Box에는 src/ 디렉토리에 프론트 엔드 용 코드가 포함되어 있습니다.
이미 제공되는 앱의 구조에 Ethereum의 고유한 기능을 채워 넣음으로써 프런트 엔드 개발을 완료합니다.
1.텍스트 편집기로 /src/js/app.js 파일을 엽니다.
2.파일을 살펴보면, 어플리케이션을 관리하고 init()에서 pet 데이터를 로드한 다음 initWeb3() 함수를 호출하는 전역 App 객체가 있다는 것을 알 수 있습니다.
실제 js에서는 아래 load 함수가 가장 아래 있지만 흐름 설명을 위해 먼저 기술합니다.
init 함수
Web3 JavaScript 라이브러리는 Ethereum 블록체인과 상호작용합니다. 사용자 계정을 검색하고 transaction을 보내고 스마트 컨트랙트와 상호작용하는 등의 작업을 수행할 수 있습니다.
initWeb3 함수
이제 Dapp을 사용할 준비가 되었습니다.
브라우저에서 dapp과 상호작용하기 가장 쉬운 방법은 Chrome과 Firefox 모두를 위한 브라우저 확장 프로그램 인 MetaMask를 사용하는 것입니다.
1.브라우저에 MetaMask를 설치합니다.
2.한번 설치되면, 주소 표시줄 옆에 MetaMask fox 아이콘을 볼수 있습니다. 아이콘을 클릭하면 다음 화면이 나타납니다.
3.Privacy Notice를 수락하기위해서 Accept 버튼을 클릭합니다.
4.그러면 사용조건(Term of Use)가 나타나며, 읽은 다음 밑으로 스크롤링 하고 역시 Accept를 클릭합니다.
5.이제 초기 MetaMask 화면이 나타납니다. Import Existing DEN을 클릭합니다.
6.Wallet Seed 라고 표시된 박스에 Ganache에 표시된 mnemonic을 입력합니다.
아래에 비밀번호를 입력하고 OK를 클릭합니다.
7.이제 MetaMask를 Ganache가 만든 블록체인에 연결합니다. "Main Network"가 표시된 메뉴를 클릭하고 Custom RPC를 선택하십시오.
8."New RPC URL"상자에 http://127.0.0.1:8545를 입력하고 저장을 클릭합니다.
상단의 네트워크 이름이 “Private Network”으로 바뀝니다.
9.’Setting'옆에 있는 왼쪽 화살표를 클릭하여 페이지를 닫고 계정 페이지로 돌아갑니다.
Truffle Develp에 의해 생성된 각 계정에는 100 ether가 주어집니다.
첫 번째 계정에서는 계약 자체가 배포 될 때와 테스트가 실행될 때 일부 가스가 사용 되었기 때문에 약간 더 적습니다.
설정이 이제 완료 되었습니다.
이제 로컬 웹 서버를 시작하고 dapp를 사용할 수 있습니다. 정적 파일을 제공하기 위해 lite-server 라이브러리를 사용하고 있습니다. 이것은 pet-shop Truffle Box와 함께 제공되었지만 작동 방식을 살펴 보겠습니다.
1.텍스트 에디터로 bs-config.json 파일을 오픈 (프로젝트의 root 디렉토리에 있는) 하고 내용을 검사합니다.
lite-server에 우리의 기본 디렉토리에 포함시킬 파일을 알려줍니다.
웹 사이트 파일에는 ./src 디렉토리를, 컨트랙트 아티팩트에는 ./build/contracts 디렉토리를 추가합니다.
프로젝트의 루트 디렉토리에있는 package.json 파일의 scripts 객체에 dev 명령을 추가합니다.
1.로컬 웹 서버를 시작합니다.
dev 서버가 실행되고 dapp이 포함 된 새 브라우저 탭이 자동으로 열립니다.
2.dapp을 사용하기 위해 원하는 애완동물의 입양 버튼을 클릭합니다.
주) 크롬 브라우져에서 어떻게 다이렉트로 Metamask를 띄울수 있는지에 대한 질문에 대한 답입니다. Chrome 플러그인 Metamask는 브라우저에 전역 변수 web3을 삽입합니다. MetaMask가 설치되어 web3가 주입 된 브라우져 콘솔에서 web3을 타이핑하여 web3 객체를 볼 수 있습니다. MetaMask는 서버 측과 브라우저 인터페이스 간의 프록시입니다. 프로그램(Metamask)이 브라우저에로드 될 때만이 변수를 볼 수 있습니다.
아래글은 Metamask QnA에 올라온 글입니다.
3.MetaMask를 통해 트랜잭션을 승인하라는 메시지가 자동으로 표시됩니다. SUBMIT을 클릭하여 트랜잭션을 승인합니다.
4.채택 된 애완 동물의 변화 옆에있는 버튼이 "Success"이라고 표시됩니다. 애완 동물이 입양 되었으므로, 비 활성화됩니다.
그리고 MetaMask에서 트랜잭션이 나열된 것을 볼 수 있습니다 :
지금까지 Truffle 프레임워크를 이용해서 App을 만들고 Metamask를 통해서 스마트 컨트랙트와 상호작용(Interacting) 해보는 튜토리얼을 해봤습니다. 간단한 샘플이긴하지만, 많은 Dapp들이 가져야하는 어플리케이션의 구조를 잘 설명하고 있다고 생각됩니다. 이 패턴을 통해 여러가지 목적하는 어플리케이션을 블록체인으로 구현하는 기본이 될수 있을거라고 생각합니다.