loopchain 입문 ( 소개, 설치, 개발환경구축 )
Contents I. loopchain 이란? II. III. IV. 설치 Tutorial SCORE(Smart Contract On Reliable Environment) 구축 Appendix. 본문서의내용은언제든지수정 / 삭제 / 업데이트가될수가있으니참고의목적으로사용하셔야합니다.
Contents I. loopchain 이란? 1) loopchain 주요특징 2) loopchain 기본구조 II. 설치 Tutorial 1) 설정가이드 2) Python 환경을구축하고 GitHub 프로젝트를 clone 하여설치 3) 제공되는 Docker 이미지를이용하여설치 Local computer 에서 RadioStation 과 2 개의 Peer 로 Blockchain network 구성 III. SCORE(Smart Contract On Reliable Environment) 구축 1) Local computer에서 SCORE 환경만들기 Tutorial 2) loopchain SCORE 개발에대한정보정리 IV. Appendix. 1) RESTful API 1 2 2) 설정 RadioStation - RESTful API Peer - RESTful API
I. loopchain 이란?
loopchain 주요특징 I. loopchain 이란? loopchain 은효율적인 Smart Contract 를기반으로실시간거래를지원할수있는고성능블록체인 5
loopchain 주요특징 I. loopchain 이란? 금융서비스에적용할수있고엔진부터응용까지전스택에서커스터마이징이가능한 Private Blockchain 6
SCORE (Smart Contract on Reliable Environment) I. loopchain 이란? SCORE 는 loopchain 에서지원하는 Smart Contract 을지칭하는것으로별도의 VM(Virtual Machine) 없이노드운영환경에서직접적으로실행되는고성능 Smart Contract 지원기능입니다. SCORE 는쉽게작성할수있어서높은개발생산성을가진 Smart Contract 입니다. SCORE 는블록체인프로세스와별도의프로세스로동작하면서다양한업무를개발할수있도록지원합니다. SCORE store 를통한등록, 배포및버전관리를제공합니다. 7
LFT algorithm I. loopchain 이란? LFT algorithm 은 BFT(Byzantine Fault Tolerance) 계열의알고리즘으로분기가없는빠른합의를지원합니다. BFT 계열합의알고리즘은머신의개수나, 지분을통하여투표를하여합의하는방식으로에너지낭비가없고즉각적인합의가가능하다는장점이있습니다. 기존 PBFT 를사용하는합의알고리즘에서발생하는통신오버헤드를 Piggybacking( 네트워크에서메시지를통합하여통신오버헤드를감소시키는방법 ) 을이용하여감소 Spinning( 리더를매번교체하는기법 ) 기법을이용하여일정한개수의블록생성시마다리더를교체하여비잔틴리더에발생할수있는서비스장애요소 ( 특정노드의트랜잭션을거부하는문제, 리더가매번시간초과시간에맞춰블록을생성하려는시도에대한피해 ) 를최소화 기존알고리즘들이가지고있는지나치게복잡한리더선정알고리즘을단순화 * 참고 : LFT 백서 8
Multi Channel I. loopchain 이란? Multi Channel 은하나의독립적인블록체인네트워크안에서업무별로채널이라는가상의네트워크를구성하여채널별로거래요청, 합의및 Smart Contract 를수행할수있는기능입니다. 하나의노드에서여러업무별당사자들만연결된다양한업무별채널을형성하기때문에채널별로무결성보장및합의가이루어집니다. 따라서거래데이터가실제거래당사자들만보유하게되어다양한규제에대응할수있습니다 9
Tiered Channel I. loopchain 이란? 블록체인네트워크에참여시인증과함께거래별로 PKI 기반인증을통해거래내역검증및보안이이뤄집니다. 인증된기관만참여시키며각참가자에게차등적권한을부여함으로서다양한엔터프라이즈업무환경에적합한시스템구현이가능합니다. 거래에참여하지않지만필요에따라거래내역을감사할수있는기능을특정노드에부여를하여감사만을위한노드생성이가능하므로금융시스템이요구하는 Compliance 기능을제공합니다. 다른권한을가진인증서배포. 블록체인참여자는정보확인및관리에대해서각각다른권한을가집니다. 검증노드, 트랜잭션생성노드등의특정노드생성가능합니다. Audit Service Audit 용 Certificate 발급 - Membership Manager 를통해 Audit 용인증서를발급받아감사노드에설정 - 향후감사가필요한거래에대해서는 Audit 용증적보관처리 10
Modular Architecture I. loopchain 이란? 모듈방식아키텍처를채택하여참여노드인증및합의알고리즘, Smart Contract 모듈등을필요한경우에추가및커스터마이징이가능합니다. 11
loopchain 기본구조 I. loopchain 이란? RadioStation Peer 들의인증을담당하고 Peer 들의목록을관리합니다. RadioStation 과 Peer 의접속 RadioStation 과 Peer 는시작할때에자신의인증서 / 개인키경로를입력합니다. Peer 들의인증서를설치시넣어주고설정파일에서이를읽어서처리하게하고있습니다. KMS(Key management system) 지원하는기능도 Enterprise 용으로지원합니다. Peer 블록생성, 블록관리, 트랜잭션생성, 조회, 원장조회등의기능을처리합니다.. Peer가생성될때에 RadioStation과연결한다. 시작할때에 RadioStation의접속정보 (IP:Port) 를가지고연결합니다. 가장먼저 RadioStation에연결되는 Peer가 Leader Peer가됩니다. 주의 : 최소 4개이상의 Peer가필요합니다. Leader Peer 일정시간마다 Transaction 들을모아 Block 을만들고보낸다음검증을 Peer 들에게받아서공표합니다.( 검증주기는설정가능합니다.) 다른 Peer 를 Subscription( 구독 ) 한다음에 Transaction / Block data 를동기화합니다. Leader Peer 의변경은등록된 Peer 의순서대로 Leader 권한을줍니다.(Round Robin). ( 주의 : block 생성개수기준은성능에따라서변경가능합니다.) 12
II. 설치 Tutorial
설정가이드 II. 설치 Tutorial <loopchain network 설정유의사항 > RadioStation 을제일먼저실행시키고 Peer 들을실행하셔야합니다. 모든 Peer 들은 N:N 으로연결됩니다. 따라서, 모든 Peer 들이서로 IP:Port 로연결할수있어야합니다. Multi Channel 설정 / SCORE 설정은설정파일을잘확인해주세요. 설정파일에오류가있으면찾기힘듭니다. 서로다른 Host 들에서띄울때는 LOOPCHAIN_HOST 설정을이용해서 RadioStation 이다른 Node 들에게 Peer 목록을띄울때, 외부서버들에서해당 Node 에접근할수있게해주세요. 최소노드수 : 제대로된 Blockchain network 를구성하기위해서 4 개이상의 Node 들을실행해야합니다. 예제에서 1 개혹은 2 개만띄운것은일종의예제로보시면됩니다. (Docker 사용시만 ) RadioStation 이나 Peer 에서외부 Host file 과연결을해주실폴더들이있습니다. 이설정이없으면 Docker container 가죽었을때에데이터를잃어버리실수가있습니다. "/storage": RadioStation, Peer 들의데이터를보관하는폴더 "/conf" : 설정파일들이담긴폴더 "/score" SCORE 를 zip 해서띄울때에, SCORE 파일이담긴 zip 파일의위치 14
설정가이드 II. 설치 Tutorial < 포트열기 > loopchain 을사용하기위해다음의 Port 가열려야합니다. Port 는설정에서변경이가능합니다. RadioStation 7102: grpc port 9002: RESTful port Peer 7100:gRPC port 9000: RESTful port < 설정파일 > 설정파일은 JSON 형식으로된파일입니다. 예를들어아래처럼만듭니다. "Variable 1":"Value1", "Variable 2":"Value2", "Variable 3":"Value3",... 특정한 JSON 파일을만들고그안에내용을작성하고 Peer 를아래와같이 -o option 을이용하여서해당파일을읽게해서 peer 를올립니다. $ python3 peer.py -o peer_conf.json... 이문서에서각종상황별로, 문제별로어떤옵션을가지고설정파일을만드는지정리하여서작성할것입니다. 자세한것은각상황별설정파일에서확인하시면됩니다. 15
GitHub 으로부터설치 - macos 기준 II. 설치 Tutorial macos 를기준으로먼저설명을하도록하겠습니다. 다른운영체제에서의설치방법에대해서는추후에추가될예정입니다. Python 설치 일반적으로 macos 에기본으로설치되어있는 Python 은 2.7.x 입니다. 따라서, Python 3.6 이상의버전으로설치를해야만합니다. 버전확인방법은다음과같습니다. $ python -V Python 2.7.10 맥에서가장쉽게 Python 3.6 이상의버전을설치하는방법은 Homebrew 를이용하는방법입니다. Homebrew 를설치하는것은매우간단합니다. 터미널에서다음의명령어를복사하여서붙여넣고실행하시면됩니다. 맥에기본적으로설치되어있는 ruby 를사용하여서 Homebrew 를설치하는것입니다. $ /usr/bin/ruby -e "$(curl -fssl https://raw.githubusercontent.com/homebrew/install/master/install) 설치중에비밀번호를입력하는부분이있는데, 컴퓨터비밀번호를입력하시면됩니다. 이제 python3 를 Homebrew 를이용해서설치합니다. 터미널에서 "brew install python3" 명령어를입력합니다 $ brew install python3 Updating Homebrew... ==> Auto-updated Homebrew! Updated 1 tap (homebrew/core)....( 중간생략 )... You can install Python packages with pip3 install <package> They will install into the site-package directory /usr/local/lib/python3.6/site-packages See: https://docs.brew.sh/homebrew-and-python ==> Summary! /usr/local/cellar/python/3.6.4_4: 4,615 files, 97.4MB $ 16
GitHub 으로부터설치 - macos 기준 II. 설치 Tutorial Python3 가설치완료가정상적으로되었는지버전을확인합니다. $ python3 -V Python 3.6.4 사용자환경구축 1. 먼저 GitHub 에공개되어있는 loopchain 프로젝트 (https://github.com/theloopkr/loopchain) 를 clone 합니다. 2. 프로젝트폴더로이동한다음에터미널창에서다음의명령어로사용자환경을구축합니다. $ virtualenv -p python3. # Create a virtual environment $ source bin/activate # Enter the virtual environment $ pip3 install -r requirements.txt # Install necessary packages in the virtual environment $./generate_code.sh # grpc generates codes necessary for communication 혹은, 프로젝트에포함되어있는스크립트를사용하는방법으로더쉽게설정할수도있습니다. $./setup.sh $ source bin/activate $./setup.sh $./generate_code.sh Unit Test 실행 설치가완료되면전체 Unit Test 를실행하여서정상작동여부를확인합니다. $./run_test.sh 17
GitHub 으로부터설치 II. 설치 Tutorial loopchain 실행 이전의 " 설정가이드 " 에서언급을하였듯이 RadioStation 을제일먼저실행시키고 Peer 들을실행합니다. 1. RadioStation 을실행합니다. $./radiostation.py # Execute RadioStation. RadioStation 을실행하면다음과같은로그를확인할수있습니다. 이로그의의미는로컬에서 9002 번포트로다른 Peer 들의연결을기다리고있다는의미입니다. 이제 RadioStation 서비스를성공적으로시작한것입니다. $./radiostation.py '2018-03-15 18:19:06,184 DEBUG Popen(['git', 'version'], cwd=/users/donghanlee/loopchain, universal_newlines=false, shell=none)' '2018-03-15 18:19:06,220 DEBUG Popen(['git', 'version'], cwd=/users/donghanlee/loopchain, universal_newlines=false, shell=none)' '2018-03-15 18:19:06,564 INFO RadioStation main got argv(list): []' '2018-03-15 18:19:06,565 INFO Set RadioStationService IP: 127.0.0.1' '2018-03-15 18:19:06,602 INFO (Broadcast Process) Start.' '2018-03-15 18:19:06,604 DEBUG (Broadcast Process) Status, param() audience(0)' '2018-03-15 18:19:07,599 DEBUG wait start broadcast process...' '2018-03-15 18:19:07,601 DEBUG Broadcast Process start("result": "success", "Audience": "0")' 2. 여러개의 Peer 들을실행합니다. 새로운터미널화면을열고 loopchain 프로젝트폴더로이동합니다. 그리고다음의명령어를입력하여서첫번째 peer 를실행합니다. $ source bin/activate # Open python virtual workspace. $./peer.py # Launch peer. 추가적인설정을 "configure.json" 파일에작성을하였고이를이용해서 peer 를실행시킨다면다음과같은명령어입력으로 peer 를실행할수있습니다. (configure.json 파일의위치는 loopchain 프로젝트안에있는 loopchain 폴더안에있습니다. ) $./peer.py -o./loopchain/configure.json 18
GitHub 으로부터설치 II. 설치 Tutorial 다음과같은로그를확인하실수있습니다.... '2017-07-20 16:05:13,480 DEBUG peer list update: 1:192.168.18.153:7100 PeerStatus.connected c3c5f2f0-6d19-11e7-875d- 14109fdb09f5 (<class 'str'>)' '2017-07-20 16:05:13,480 DEBUG peer_id: c3c5f2f0-6d19-11e7-875d-14109fdb09f5' '2017-07-20 16:05:13,480 DEBUG peer_self: <loopchain.baseservice.peer_list.peer object at 0x106249b00>' '2017-07-20 16:05:13,481 DEBUG peer_leader: <loopchain.baseservice.peer_list.peer object at 0x106249b00>' '2017-07-20 16:05:13,481 DEBUG Set Peer Type Block Generator!' '2017-07-20 16:05:13,481 INFO LOAD SCORE AND CONNECT TO SCORE SERVICE!' 두번째 peer 를동일한방법으로실행합니다. 이번에는 RadioStation 에연결하는다른포트를사용해야만합니다.( 동일한로컬컴퓨터에서실행되기때문에동일한포트는사용이안됩니다.) $ source bin/activate # Open python virtual workspace. $./peer.py -p 7101 # Launch peer with 7101 port 각 peer 는 RadioStation 에연결될때 7100 port 부터시작되는새로운포트를수신합니다. 새 peer 가연결될때마다 RadioStation 은기존 peer 목록을새 peer 에전달하고기존 peer 에새로운 peer 가추가되었음을알립니다. 3. 각 peer 들의상태체크 RESTful API 를이용하여서 RadioStation 및각 peer 의상태를확인할수있습니다. $ curl http://localhost:9002/api/v1/peer/list # Shows a list of peers that are currently configuring the blockchain network in Radiostation. $ curl http://localhost:9000/api/v1/status/peer # Shows the current status of peer0 $ curl http://localhost:9001/api/v1/status/peer # Shows the current status of peer1 4. 새로운 Transaction 생성 RESTful API 를사용하여서 peer0 에새로운 Transaction 을보냅니다. $ curl -H "Content-Type: application/json" -d '"data":"hello"' http://localhost:9000/api/v1/transactions "response_code": "0", "tx_hash": "71a3414d77dbdb34b92757ba75e51d9aa498f6a06609419cdf31327da4e9bf38", "more_info": "" $ 19
GitHub 으로부터설치 II. 설치 Tutorial 5. 새로생성된 Transaction 의 Height 를체크한다. $ curl http://localhost:9000/api/v1/blocks python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 404 100 404 0 0 32625 0 --:--:-- --:--:-- --:--:-- 33666 "response_code": 0, "block_hash": "33f84bc5c48339943ec802ecb65e11bdb003c3442e42b1a9581f32459f36f582", "block_data_json": "prev_block_hash": "af5570f5a1810b7af78caf4bc70a660f0df51e42baf91d4de5b2328de0e83dfc", "merkle_tree_root_hash": "71a3414d77dbdb34b92757ba75e51d9aa498f6a06609419cdf31327da4e9bf38", "time_stamp": "1521111197115569", "height": "1", "peer_id": "e54b340a-2824-11e8-bf1c-acde48001122" $ 20
Docker 를사용한설치 II. 설치 Tutorial Linux 에서 Docker 설치하기 Docker CE(Community Edition)X86-64, Docker EE(Enterprise edition) X86-64 를운용할수있는최신환경이면됩니다. Docker CE: 무료사용버전 Docker EE: 상용버전, 무료 Hosted Trial 사용가능. 각종 OS 들에대한지원추가제공. 모든상황에서방법이없으면 Docker 를 Binary 로부터설치할수있는방법이있습니다. (https://docs.docker.com/install/linux/docker-ce/binaries/) Platform Docker CE X86_64 Docker EE X86_64 Note CentOS O O CentOS 7이상. Installation Guide Devian O Stretch (stable) / Raspbian Stretch Jessie 8.0 (LTS) / Raspbian Jessie Wheezy 7.7 (LTS). Installation Guide Fedora O Fedora 24, 25 Installation Guide Windows Server 2016 O Installation Guide Oracle Linux O 7.3 이상. Installation Guide Red Hat Enterprise Linux O 64bit version Redhat Enterprise Linux 7 on an X86 or S390x. Installation Guide SUSE Linux Enterprise server O SUSE 12.x version (OpenSUSE 지원안함 ). Installation Guide Ubuntu O O EE : Xenial 16.04 (LTS) / Trusty 14.04 (LTS), CE : Zesty 17.04 / Xenial 16.04 (LTS) / Trusty 14.04 (LTS) Installation Guide 자세한정보는 Docker 홈페이지의 https://docs.docker.com/install/ 페이지를참조하여서설치하시면됩니다. 21
Docker 를사용한설치 II. 설치 Tutorial Windows / Mac 에서 Docker 설치하기 Docker 홈페이지의 https://docs.docker.com/install/ 페이지를참조하여서설치하시면됩니다. Docker 동작확인하기 "docker version" 명령어로 Docker 가정상설치되었는지확인합니다. 다음의화면을참고하셔서확인하십시오. $ docker version Client: Version: 17.12.0-ce API version: 1.35 Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:03:51 2017 OS/Arch: darwin/amd64 Server: Engine: Version: 17.12.0-ce API version: 1.35 (minimum version 1.12) Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:12:29 2017 OS/Arch: linux/amd64 Experimental: true TIP : Docker 사용자설정 Add the docker group if it doesn't already exist: $ sudo groupadd docker Add the connected user "$USER" to the docker group. Change the user name to match your preferred user if you do not want to use your current user: $ sudo gpasswd -a $USER docker Either do a "newgrp docker" or log out/in to activate the changes to groups. 22
Docker 를사용한설치 II. 설치 Tutorial loopchain Docker Image loopchain 의 Docker image 는다음의 3 종류가있습니다. looprs: RadioStation docker image looppeer: Peer docker image loopchain-fluentd: log 를저장하기위해서수정한 fluentd image Docker image 받기 아래화면과같이 docker pull 명령을이용하여서 Docker hub 로부터 loopchain docker image 들을다운받아옵니다. $ docker pull loopchain/looprs $ docker pull loopchain/looppeer $ docker pull loopchain/loopchain-fluentd 23
RadioStation 과 2 개의 Peer 로 Blockchain network 구성하기 II. 설치 Tutorial 목적 자신의컴퓨터상에서 Docker 를이용하여 RadioStation 과 Peer 2 개로구성된네트워크환경을구성하고정상적으로동작하는지테스트를합니다. 다음의그림과같은구조로네트워크가구성이됩니다. 디렉토리구성 이문서의내용을따라하게되면다음과같은디렉토리구성이만들어지게됩니다. 24
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 설정파일생성 1. 디렉토리생성 로그서버의설정파일폴더를생성하고로그를따로저장할폴더를생성합니다. 그리고, RadioStation 과 Peer 의설정파일을따로보관할폴더를만듭니다. $ mkdir -p fluentd/etc # 로그서버의설정파일폴더를생성. $ mkdir logs # 로그를따로저장할폴더를생성. $ mkdir conf # RadioStation과 Peer의설정파일을따로보관할폴더를생성. 2. log 서버의설정 log 서버의설정파일을작성하고설정파일위치로이동합니다. 이것은모든 log 들을파일로남기는설정입니다. 1) fluent.conf 을아래와같이만듭니다. <source> @type forward @id input1 port 24224 bind 0.0.0.0 </source> <match **> # Add your log tag to show in <>. @type copy <store> # Add your log tag to show in <>. @type file # Leave log file in path. path /logs/data.*.log symlink_path /logs/data.log time_slice_format %Y%m%d time_slice_wait 10m time_format %Y%m%dT%H%M%S%z compress gzip utc </store> </match> 2) 작성된 fluent.conf 를 fluentd/etc 디렉토리로이동합니다. $ mv fluent.conf./fluentd/etc 25
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 3. channel_manage_data.json 작성 이설정파일은 MultiChannel 을사용할때에설정하는파일입니다. 해당파일은 RadioStation 에서사용됩니다. 1) channel_manage_data.json 파일을아래와같이작성합니다. "channel1": "score_package": "loopchain/default" channel1 이라는 channel에서 loopchain/default라는 SCORE를이용합니다. loopchain/default는기본적으로각 peer들이가지고있는 SCORE 파일입니다. 2) 작성된 channel_manage_data.json를 /conf 디렉토리로이동합니다. $ mv channel_manage_data.json./conf 26
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 4. rs_conf.json 작성 이설정파일은 RadioStation 의설정들을담고있는파일입니다. 1) rs_conf.json 파일을아래와같이작성합니다. "CHANNEL_MANAGE_DATA_PATH": "/conf/channel_manage_data.json", "LOOPCHAIN_DEFAULT_CHANNEL": "channel1", "ENABLE_CHANNEL_AUTH": false CHANNEL_MANAGE_DATA_PATH: channel_manage_data.json 이어디에있는지지정해줍니다. LOOPCHAIN_DEFAULT_CHANNEL: RadioStation 에서 channel_manage_data.json 에서설정한 channel 중에별도로지정하지않고 request 가들어오면기본적으로사용할 channel 을정합니다. ENABLE_CHANNEL_AUTH: 정해진 Server 들만각 channel 별로들어올수있는제한을하는 Option 입니다.. 2) 작성된 rs_conf.json 를 /conf 디렉토리로이동합니다. $ mv rs_conf.json./conf 27
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 5. peer_conf0.json 작성 이설정파일은각 Peer 들의설정을담고있는파일입니다. 1) peer_conf0.json 파일을아래와같이작성합니다. "LOOPCHAIN_DEFAULT_CHANNEL": "channel1", "DEFAULT_SCORE_BRANCH": "master" LOOPCHAIN_DEFAULT_CHANNEL: 해당 peer 가 channel_manage_data.json 에서설정한 channel 중에별도로지정하지않고 request 가들어오면기본적으로사용할 channel 을정합니다. DEFAULT_SCORE_BRANCH: SCORE 를사용할때, 어떤 branch 의것을이용할지를정합니다. 기본값은 master 입니다. 참고로 SCORE 는 git repository 로원격 git repository 의것을 clone 해서쓰거나따로파일로읽어오게해야합니다. 2) 작성된 peer_conf0.json 를 /conf 디렉토리로이동합니다. $ mv peer_conf0.json./conf 28
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 5. peer_conf1.json 작성 이설정파일은각 Peer 들의설정을담고있는파일입니다. 1) peer_conf1.json 파일을아래와같이작성합니다. "LOOPCHAIN_DEFAULT_CHANNEL": "channel1", "DEFAULT_SCORE_BRANCH": "master" LOOPCHAIN_DEFAULT_CHANNEL: 해당 peer 가 channel_manage_data.json 에서설정한 channel 중에별도로지정하지않고 request 가들어오면기본적으로사용할 channel 을정합니다. DEFAULT_SCORE_BRANCH: SCORE 를사용할때, 어떤 branch 의것을이용할지를정합니다. 기본값은 master 입니다. 참고로 SCORE 는 git repository 로원격 git repository 의것을 clone 해서쓰거나따로파일로읽어오게해야합니다. 2) 작성된 peer_conf1.json 를 /conf 디렉토리로이동합니다. $ mv peer_conf1.json./conf 29
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial Docker Container 실행 Docker Container 를실행하는순서는다음과같습니다. 1. Log 서버를실행합니다. $ export TAG=latest # 환경변수를설정합니다. # Log server 컨테이너를실행합니다. $ docker run -d \ --name loop-logger \ --publish 24224:24224/tcp \ --volume $(pwd)/fluentd:/fluentd \ --volume $(pwd)/logs:/logs \ loopchain/loopchain-fluentd:$tag # Log server 컨테이너를정상적으로실행되었는지확인합니다. $ docker ps --filter name=loop-logger CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 268c79cd104b loopchain/loopchain-fluentd:latest "/bin/entrypoint.sh " 6 minutes ago Up 6 minutes 5140/tcp, 24284/tcp, 0.0.0.0:24224->24224/tcp loop-logger $ 30
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 2. RadioStation 을실행합니다. # RadioStation 에서이용할데이타저장공간을만듭니다. $ mkdir -p storagers # RadioStation 컨테이너를실행합니다. $ docker run -d --name radio_station \ -v $(pwd)/conf:/conf \ -v $(pwd)/storagers:/.storage \ -p 7102:7102 \ -p 9002:9002 \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ loopchain/looprs:$tag \ python3 radiostation.py -o /conf/rs_conf.json # RadioStation 컨테이너가정상적으로실행되었는지확인합니다. $ docker ps --filter name=radio_station CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 556b407669fc loopchain/looprs:latest "python3 radiostatio " About a minute ago Up About a minute 0.0.0.0:7102->7102/tcp, 7100-7101/tcp, 0.0.0.0:9002->9002/tcp radio_station $ 31
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 3. Peer 를순차적으로실행합니다.(peer0 실행 ) # Peer 0 번에서이용할데이타저장공간을만듭니다. $ mkdir -p storage0 # Peer0 컨테이너를실행합니다. $ docker run -d --name peer0 \ -v $(pwd)/conf:/conf \ -v $(pwd)/storage0:/.storage \ --link radio_station:radio_station \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ -p 7100:7100 -p 9000:9000 \ loopchain/looppeer:$tag \ python3 peer.py -o /conf/peer_conf0.json -p 7100 -r radio_station:7102 # Peer0 컨테이너가정상적으로실행되었는지확인합니다. $ docker ps --filter name=peer0 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f18c4e082a30 loopchain/looppeer:latest "python3 peer.py -o " 7 minutes ago Up 7 minutes 0.0.0.0:7100->7100/tcp, 0.0.0.0:9000->9000/tcp, 7101-7102/tcp peer0 $ 32
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 4. Peer 를순차적으로실행합니다.(peer1 실행 ) # Peer 1 번에서이용할데이타저장공간을만듭니다. $ mkdir -p storage1 # Peer1 컨테이너를실행합니다. $ docker run -d --name peer1 \ -v $(pwd)/conf:/conf \ -v $(pwd)/storage1:/.storage \ --link radio_station:radio_station \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ -p 7200:7200 -p 9100:9100 \ loopchain/looppeer:$tag \ python3 peer.py -o /conf/peer_conf1.json -p 7200 -r radio_station:7102 # Peer1 컨테이너가정상적으로실행되었는지확인합니다. $ $ docker ps --filter name=peer1 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c10d2938efee loopchain/looppeer:latest "python3 peer.py -o " 7 minutes ago Up 7 minutes 7100-7102/tcp, 0.0.0.0:7200->7200/tcp, 9000/tcp, 0.0.0.0:9100->9100/tcp peer1 $ 33
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 확인하기 제대로설치되고실행이되고있는지확인하는방법은다음과같습니다. 1. RadioStation 의 Channel1 에접속된 Peer 들의정보출력 curl http://localhost:9002/api/v1/peer/list?channel=channel1 python -m json.tool 명령어를입력합니다. 정상적으로동작하고있다면다음과비슷한메세지가출력이될것입니다. $ curl http://localhost:9002/api/v1/peer/list?channel=channel1 python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1573 100 1573 0 0 64583 0 --:--:-- --:--:-- --:--:-- 65541 "data": "connected_peer_count": 2, "connected_peer_list": [. ( 중간생략 ) ], "registered_peer_count": 2, "registered_peer_list": [. ( 중간생략 ) ], "response_code": 0 $ 34
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 2. Peer0 의상태정보를출력 curl http://localhost:9000/api/v1/status/peer?channel=channel1 python -m json.tool 명령어를입력합니다. 정상적으로동작하고있다면다음과비슷한메세지가출력이될것입니다. $ curl http://localhost:9000/api/v1/status/peer?channel=channel1 python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 264 100 264 0 0 19717 0 --:--:-- --:--:-- --:--:-- 20307 "audience_count": "0", "block_height": 0, "consensus": "siever", "leader_complaint": 1, "made_block_count": 0, "peer_id": "9f109b10-1b8b-11e8-9ab2-0242ac110004", "peer_target": "172.17.0.4:7100", "peer_type": "1", "status": "Service is online: 1", "total_tx": 0 $ 35
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 3. Peer1 의상태정보를출력 curl http://localhost:9100/api/v1/status/peer?channel=channel1 python -m json.tool 명령어를입력합니다. 정상적으로동작하고있다면다음과비슷한메세지가출력이될것입니다. $ curl http://localhost:9100/api/v1/status/peer?channel=channel1 python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 264 100 264 0 0 17546 0 --:--:-- --:--:-- --:--:-- 18857 "audience_count": "0", "block_height": 0, "consensus": "siever", "leader_complaint": 1, "made_block_count": 0, "peer_id": "c41c2488-2045-11e8-bae4-0242ac110005", "peer_target": "172.17.0.5:7200", "peer_type": "0", "status": "Service is online: 0", "total_tx": 0 $ 36
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 4. log 가저장되고있는지확인. 현재튜토리얼에서는 /logs 폴더에 RadioStation 과 Peer0 의로그가저장되고있습니다. 이를확인하기위해서 /logs 폴더안에파일들이생성되고있는지확인합니다. $ ls $(pwd)/logs/ data.b5669f50a57554db1a74bc2c19ddb6c16.log data.log time_slice_format %Y%m%d data.20180228_0.log.gz data.20180302_0.log.gz data.b5669f50a57554db1a74bc2c19ddb6c16.log.meta $ 37
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 실행스크립트작성 II. 설치 Tutorial 실제 loopchain 운영의편의를위해서위와같이매번명령어를직접입력하기보다는실행스크립트작성이필요합니다. 다음과같이총 3 개의실행스크립트를작성하고실행해보겠습니다. 1. 시작 - start.sh ( 새로운컨테이너실행 ) #!/usr/bin/env bash ############################################## # 환경변수등록 ############################################## export TAG=latest export CONF=$(pwd)/conf export LOGS=$(pwd)/logs export FLUENTD=$(pwd)/fluentd export STORAGE_RS=$(pwd)/storageRS export STORAGE_PEER_0=$(pwd)/storage0 ############################################## # 로그및데이터디렉토리생성 ############################################## if [! -d $LOGS ] then mkdir -p $LOGS fi if [! -d $STORAGE_RS ] then mkdir -p $STORAGE_RS fi if [! -d $STORAGE_PEER_0 ] then mkdir -p $STORAGE_PEER_0 fi ############################################## # 로그서버실행 ############################################## docker run -d \ --name loop-logger \ --publish 24224:24224/tcp \ --volume $FLUENTD:/fluentd \ --volume $LOGS:/logs \ loopchain/loopchain-fluentd:$tag ############################################## # Radio Station 실행 ############################################## docker run -d --name radio_station \ -v $CONF:/conf \ -v $STORAGE_RS/storageRS:/.storage \ -p 7102:7102 \ -p 9002:9002 \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ loopchain/looprs:$tag \ python3 radiostation.py -o /conf/rs_conf.json ############################################## # Peer0 실행 ############################################## docker run -d --name peer0 \ -v $(pwd)/conf:/conf \ -v $(pwd)/storage0:/.storage \ --link radio_station:radio_station \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ -p 7100:7100 -p 9000:9000 \ loopchain/looppeer:$tag \ python3 peer.py -o /conf/peer_conf0.json -p 7100 -r radio_station:7102 ############################################## # Peer1 실행 ############################################## docker run -d --name peer1 \ -v $(pwd)/conf:/conf \ -v $(pwd)/storage1:/.storage \ --link radio_station:radio_station \ --log-driver fluentd --log-opt fluentd-address=localhost:24224 \ -p 7200:7200 -p 9100:9100 \ loopchain/looppeer:$tag \ python3 peer.py -o /conf/peer_conf1.json -p 7200 -r radio_station:7102 38
RadioStation 과 2 개의 Peer 로 Blockchain Network 구성하기 II. 설치 Tutorial 2. 종료 - stop.sh ( 실행중인컨테이너를종료 ) #!/usr/bin/env bash docker stop $(docker ps -q --filter name=loop-logger --filter name=radio_station --filter name=peer0 --filter name=peer1) 3. 삭제 - delete.sh ( 종료된컨테이너를삭제 ) #!/usr/bin/env bash docker rm -f $(docker ps -aq --filter name=loop-logger --filter name=radio_station --filter name=peer0 --filter name=peer1) 39
III. SCORE 구축
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 목적 이 Tutorial 에서는사용자의컴퓨터에서 Docker 로 loopchain 을실행하면서 Github 에있는 SCORE 를사용하는것을실습하여봅니다. SCORE 저장소생성 1. GitHub 에서 SCORE sample 을 fork 해오기 Github 에서 SCORE Sample 프로젝트 (https://github.com/theloopkr/contract_sample) 를 fork 하여서 SCORE 개발환경을위한테스트용 SCORE 저장소를생성합니다. 41
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 2. SCORE 저장소와 SSH 통신을위해 SSH 키를생성하기 ssh-keygen 명령어를사용하셔서 id_tutorial 이라는이름으로생성합니다. 아래화면을참고하시고 GitHub 의자신의이메일주소로 SSH 키를생성하셔야합니다. 상세한내용은외부링크를참고해주세요. 만약 Sierra 10.12.2 혹은그이후의 macos 를사용하시는분들은링크의내용을참고하셔서추가적으로진행하셔야하는내용이있으니꼭확인하시고따라하십시오. $ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" Generating public/private rsa key pair. Enter file in which to save the key (/Users/user_id/.ssh/id_rsa): /Users/user_id/.ssh/id_tutorial... $ ls -la ~/.ssh/ grep id_tutorial -rw------- 1 donghanlee staff 1679 3 7 09:45 id_tutorial -rw-r--r-- 1 donghanlee staff 420 3 7 09:45 id_tutorial.pub 42
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 3. GitHub 에 Deployment key 를등록하기 앞서 Fork 한 SCORE 저장소에 SSH public key 내용을 ( 예 :id_tutorial.pub) 를등록합니다. 1) Public key 의내용을확인합니다. $ cat.ssh/id_tutorial.pub ssh-rsa...your_public_key... == your_email@example.com 2) Public key 의내용을아래처럼 Fork 한 SCORE package 의 deployment key 로등록합니다. 43
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 환경설정 Local computer 에서 RadioStation 과 2 개의 Peer 로 Blockchain network 구성하기내용을기반으로 SCORE 환경설정을하겠습니다. 해당파일과디렉토리를복사하여서다른디렉토리로만들고아래내용대로추가하거나수정합니다. 1. RadioStation 설정 - SCORE 저장소경로설정 channel_manage_data.json 을열어서 score_package 의값으로 your_github_id/contract_sample" 수정합니다. "channel1": "score_package": "your_github_id/contract_sample" 44
3. 변 Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 2. 시작스크립트인 start.sh 스크립트의 peer 부분을수정 1) 환경변수추가등록 export SSH_KEY_FOLDER=/Users/user_id/.ssh/id_tutorial 2) SSH key 경로설정 -v "$SSH_KEY_FOLDER:/root/.ssh/id_tutorial" 3) SCORE 저장소도메인설정 -e "DEFAULT_SCORE_HOST=github.com 변경된 start.sh 파일내용 ``` ############################################## # 환경변수등록 ############################################## export SSH_KEY_FOLDER=/Users/user_id/.ssh/id_tutorial ############################################## # Peer0 실행 ############################################## docker run -d --name peer0 \... -v $SSH_KEY_FOLDER:/root/.ssh/id_rsa \ -e "DEFAULT_SCORE_HOST=github.com" \... ############################################## # Peer1 실행 ############################################## docker run -d --name peer1 \... -v $SSH_KEY_FOLDER:/root/.ssh/id_rsa \ -e "DEFAULT_SCORE_HOST=github.com" \... ``` 45
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 환경설정확인 1. loopchain 도커컨테이너를모두실행 : start.sh $./start.sh 2. peer 목록조회 $ curl http://localhost:9002/api/v1/peer/list python -m json.tool "data": "connected_peer_count": 2, "connected_peer_list": [...,... ], "registered_peer_count": 2, "registered_peer_list": [...,... ], "response_code": 0 현재 Blockchain network 에연결된 Peer 들을보여줍니다. connected_peer_count 와 registered_peer_count 의값이같아야합니다. 46
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 3. Peer 상태조회 $ curl http://localhost:9000/api/v1/status/peer python -m json.tool "audience_count": "0", "block_height": 0, "consensus": "siever", "leader_complaint": 1, "made_block_count": 0, "peer_id": "d0060308-22b2-11e8-b58b-0242ac110004", "peer_target": "172.17.0.4:7100", "peer_type": "1", "status": "Service is online: 1", "total_tx": 0 Peer 의 block 들의높이, 상태, Tx 의갯수등을보여줍니다. 4. SCORE 버전조회 $ curl http://localhost:9000/api/v1/status/score python -m json.tool "all_version": [ "f58b8b3e955984a09674a1f74c493001678d706c", "b39064b358b84798f20f024fca066a113ec88b18", "99923ce139350cf8f37ef9f72fddf3f327da4d7a",.( 중간생략 ).. "e38140e76766f2e51f30858a0ee3c82a90b9c258", "af7c49743fecd315d4e4491751fbdae9b92dead7", "bcc0d0f05d1a219cd4ed47955a86b0e16d1b2778" ], "id": "your_github_id/contract_sample", "status": 0, "version": "f58b8b3e955984a09674a1f74c493001678d706c" 현재올라온 SCORE 의버전들을보여줍니다. SCORE 는내부에서 Git 으로버전을관리하기때문에 Git 상에서각버전의 SHA-1 hash 를보여줍니다 47
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 5. SCORE Transaction 생성 $ curl -H "Content-Type: application/json" -X POST -d '"jsonrpc":"2.0","method":"propose","params":"proposer":"realestateagent", "counterparties": ["leaseholder","jinho"], "content": "Theloop APT 101-3001, lease for 3 months from 3th April,2018", "quorum": "3"' http://localhost:9000/api/v1/transactions python -m json.tool "more_info": "", "response_code": "0", "tx_hash": "7bc856e972da62a6cba3deff71e74e848174fc1e28feaae66f58ff2447875f0a" 새로운 Transaction 을만들기위해서, 해당 SCORE 의 invoke() 아래구현된함수를부릅니다. 이를위해, 해당함수를부를수있는 json-rpc 2.0 형태의 JSON 을만들어부릅니다. 여기서는 propose 라는함수를불러본것입니다. 이결과로 Tx 의 Hash 값을되돌려줍니다. 6. SCORE Transaction 조회 - tx_hash 사용 (7bc856e972da62a6cba3deff71e74e848174fc1e28feaae66f58ff2447875f0a) $ curl http://localhost:9000/api/v1/transactions/result?hash=7bc856e972da62a6cba3deff71e74e848174fc1e28feaae66f58ff2447875f0a python -m json.tool "response": "code": 0, "jsonrpc": "2.0", "response_code": "0" 앞서만든 Tx 의 hash 를가지고결과를조회해봅니다. response_code 가 0 면정상입니다. 48
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 7. SCORE Transaction 실행결과조회 (Query) $ curl -H "Content-Type: application/json" -X POST -d '"jsonrpc": "2.0","channel":"channel1","method":"get_user_contracts","id":"11233","params":"user_id":"jinho"' http://localhost:9000/api/v1/query python -m json.tool "response": "code": 0, "id": "11233", "jsonrpc": "2.0", "response": "user_contracts": [ "approvers": [ "RealEstateAgent" ], "content": "Theloop APT 101-3001, lease for 3 months from 3th April,2018", "contract_id": 1, "counterparties": [ "leaseholder", "jinho" ], "proposer": "RealEstateAgent", "quorum": "3" ], "response_code": "0"] 만들어진 Transaction 을찾기위해서, 해당 SCORE 의 query() 아래구현된함수를부릅니다. 이를위해, 해당함수를부를수있는 json-rpc 2.0 형태의 JSON 을만들어부릅니다. 여기서는 user_contracts 라는함수를불러본것입니다. 49
Local computer 에서 SCORE 를불러오는 Tutorial III. SCORE 구축 8. peer 상태조회 (block_height, made_block_count,total_tx 변화확인 ) $ curl http://localhost:9000/api/v1/status/peer python -m json.tool "audience_count": "0", "block_height": 1, "consensus": "siever", "leader_complaint": 1, "made_block_count": 1, "peer_id": "d0060308-22b2-11e8-b58b-0242ac110004", "peer_target": "172.17.0.4:7100", "peer_type": "1", "status": "Service is online: 1", "total_tx": 1 앞서만든 Tx 로 total_tx 가증가된것을확인할수있습니다. 50
loopchain SCORE 개발에대한정보정리 III. SCORE 구축 SCORE 개발 SCORE의개발은 3단계로나뉘어집니다. 1. 비지니스모델타당성검증 2. 모델구현및 Unit Test 3. Integration Test 및모델배포 비지니스모델타당성검증 SCORE 안에서는다음과같은내용을통한비지니스모델은불가능합니다. 랜덤값에의존하는비지니스모델 : SCORE 안에서랜덤값을생성하거나, 실행하는모델은불가하나, 블록의해시혹은트랜잭션을이용한랜덤값이용은가능합니다. 외부의데이터에의존성이있는비지니스모델 : SCORE 안에서다른사이트를호출하거나, 외부의데이터를요구하는모델은아직불가능하나향후고려되고있습니다. 시간에따라행동하는혹은실행시간에따라내용이바뀌는모델 : 현재시간 ( 실행시간 ) 은사용불가능하며, 블록의시간혹은트랜잭션시간으로대체는가능합니다. 부동소수점처리불가 : CPU 에따라부동소수점표현방식이달라질수있으므로모든연산은정수단위에서처리해야합니다. 내부변수재사용금지 : 특정한변수를 Cache 해놓았다가쓰는것은금지되어야합니다. 51
loopchain SCORE 개발에대한정보정리 III. SCORE 구축 구현 SCORE 를작성하거나, 개발할때는 coverage 90% 이상을목표로개발하여야하며, 퍼포먼스도고려되어야합니다. 폴더및실행구조 / score / 회사명 ( 기관명 ) / 패키지명. ex) /score/loopchain/default/ deploy 폴더명은사용불가 원격 repository를사용하지않을경우다음과같이가능합니다. 회사명 ( 기관명 )_ 패키지명.zip 으로 repository 전체를압축하여 score에저장하여실행 패키지설명및실행에대한상세내용은 package.json 파일로정의하며, package.json 정의에대한내용은다른가이드에서설명합니다. 52
loopchain SCORE 개발에대한정보정리 III. SCORE 구축 Unit Test 모든테스트코드는 SCORE 의패키지루트에있어야하며, 차후 repository 등록전에실행됩니다. SCORE 와분리해서논리적인별도의 Module 을만들어서 Unit Test 를만들어서수행해야합니다. Integration Test RadioStation / Peer 를실행합니다. POST 로 /api/v1/transactions 로아래처럼데이터를보냅니다. "jsonrpc": "2.0", "id": 1, "method": "foo", "params": "param1":"value1... packages.json 에서얻은정의한함수의이름과데이터에맞춰 Transaction 을만들어준다. 형식은 JSON 2.0 RPC 방식에맞춰준다. Invoke / Query 모두같은방식으로호출된다. 함수이름으로구분한다. 53
loopchain SCORE 개발에대한정보정리 III. SCORE 구축 SCORE 배포및관리 <local develop folder를사용하는방법 > 1. configure_user.py 파일을추가합니다. (configure_default.py 와같은위치 ) ALLOW_LOAD_SCORE_IN_DEVELOP = 'allow' DEVELOP_SCORE_PACKAGE_ROOT = 'develop' DEFAULT_SCORE_PACKAGE = 'develop/[package]' 2. /score/develop/[package] 폴더를만듭니다. [package] 는원하는이름으로작성합니다. (sample 을사용하는경우 test_score 로합니다.) 3. /score/sample-test_score/* 파일을새로운폴더로복사합니다. 4. loopchain 네트워크를실행하여확인합니다. <zip 파일을사용하는방법 > 1. 임의의폴더에서 score 를작성합니다. ("local develop folder를사용하는방법 " 에서작성한 SCORE 복사하여도됩니다.) 2. package.json 의 "id" 값을 "[company_name]-[package]" 로수정합니다. 3. $ git init. 으로해당폴더를 local git repository 로설정합니다. 4. $ git add. 으로폴더의모든파일을 repository 에추가합니다. 5. $ git commmit -a 로 SCORE 파일들을 git 에 commit 합니다. 6. $ zip -r../[company_name]_[package].zip./ 으로 repository 를 zip 으로압축합니다. 7. zip 파일을 /score/ 아래에둡니다. (/score/[company_name]_[package].zip) 8. configure_user.py 파일을추가합니다. (configure_default.py 와같은위치 ) DEFAULT_SCORE_PACKAGE = '[company_name]/[package]' 9. loopchain 네트워크를실행하여확인합니다. 54
loopchain SCORE 개발에대한정보정리 III. SCORE 구축 <repository 를사용하는방법 > SCORE 의배포는특별히관리되는 repository 를사용할수있습니다. 차후다수의 repository 를검색하여, 순위별로배포하는방안도검토중입니다. remote repository 에서관리하지않는스코어는내부 repository 가포함된 zip 파일에서관리할수있습니다. peer 에서스코어의배포는다음의명령어를사용합니다. Docker 에서실행시 Local 에서실행시 참조 $ docker run -d $DOCKER_LOGDRIVE \ --name $PEER_NAME --link radio_station:radio_station \ -p $PORT:$PORT looppeer:$docker_tag \ python3 peer.py -c $DEPLOY_SCORE \ -r radio_station -d -p $PORT $ python3 peer.py -c $DEPLOY_SCORE -r radio_station -d -p $PORT DEPLOY_SCORE 는기관명 / 패키지명입니다. PEER_NAME 은 Peer 의이름을지칭합니다. PORT 는 radio_station 의위치 IP:PORT 로설정됩니다. 55
IV. Appendix.
RESTful API - RadioStation IV. Appendix. GET /api/v1/peer/list?channel=channel_name Radio Station 에등록 / 연결된 Peer 정보를가져온다 Response Body "registered_peer_count": "int: 등록된 Peer 의수 ", "connected_peer_count": "int: 연결된 Peer 의수 ", "registered_peer_list": " 등록된 Peer 의정보목록 " [ "order": "Radio Station 에등록된 Peer 에할당된고유순번 ", "peer_id": "Peer ID", "group_id": "Peer group 의 ID", "target": "Peer 의 IP: Port' 로이루어진문자열 ", "auth": "Peer 의 public key 정보 ( 인증서 )", "token": "Radio station 이 Peer 에게발급한토큰 ", "status_update_time": "Peer 의연결상태정보가업데이트된시간 ", "status": "int: Radio station 과 Peer 의연결상태. (unknown:0, connected:1, disconnected:2)", "peer_type": "grpc proto 에정의된 peer 타입의문자값 (peer:"0", leader:"1")", "..." ], "connected_peer_list": " 연결된 Peer 의정보목록 " [ "order": "Radio Station 에등록된 Peer 에할당된고유순번 ", "peer_id": "Peer ID", "group_id": "Peer group 의 ID", "target": "Peer 의 IP: Port' 로이루어진문자열 ", "auth": "Peer 의 public key 정보 ( 인증서 )", "token": "Radio station 이 Peer 에게발급한토큰 ", "status_update_time": "Peer 의연결상태정보가업데이트된시간 ", "status": "int: Radio station 과 Peer 의연결상태. (unknown:0, connected:1, disconnected:2)", "peer_type": "grpc proto 에정의된 peer 타입의문자값 (peer:"0", leader:"1")", "..." ]
RESTful API - RadioStation IV. Appendix. GET /api/v1/peer/leader?channel=channel_name Leader Peer 의정보를가져온다 Response Body "response_code": "int : RES_CODE", "data": "order": "Radio Station 에등록된 Peer 에할당된고유순번 ", "peer_id": "Peer ID", "group_id": "Peer group 의 ID", "target": "Peer 의 IP: Port' 로이루어진문자열 ", "auth": "Peer 의 public key 정보 ( 인증서 )", "token": "Radio station 이 Peer 에게발급한토큰 ", "status_update_time": "Peer 의연결상태정보가업데이트된시간 ", "status": "int: Radio station 과 Peer 의연결상태. (unknown:0, connected:1, disconnected:2)"
RESTful API - RadioStation IV. Appendix. GET /api/v1/peer/status?peer_id=peer 의 ID&group_id=Peer 의 group ID&channel=channel_name Parameter 로전달한 target 정보와일치하는 Peer 의상태정보를가져온다 Response Body "response_code": "int : RES_CODE", "data": "made_block_count": " 해당 Peer 가생성한 block 의수 ", "status": "Peer 의연결상태 ", "audience_count": " 해당 Peer 를 subscription 중인 Peer 의수 ", "consensus": " 합의방식 (none:0, default:1, siever:2)", "peer_id": "Peer 의 ID", "peer_type": "Leader Peer 여부 ", "block_height": "Blockchain 내에서생성된 Block 수 ", "total_tx": "int: Blockchain 내에서생성된 Transaction 수 ", "peer_target": "Peer 의 grpc target 정보 "
RESTful API - RadioStation IV. Appendix. GET /api/v1/conf loopchain 의모든 Configuration 목록을가져온다. Response Body "response_code": "int : RES_CODE", "data": [ "name": "Configuration 이름 ", "value": "String 타입의 Configuration 값 ", "type": "int : Configuration 값의데이터타입 (string:0, int:1, float:2)", "..." ]
RESTful API - RadioStation IV. Appendix. GET /api/v1/conf?name=configuration 이름 loopchain 의 Configuration 중특정값을 Configuration 이름기준으로가져온다. Response Body "response_code": "int : RES_CODE", "data": "name": "Configuration 이름 ", "value": "String 타입의 Configuration 값 ", "type": "int : Configuration 값의데이터타입 (string:0, int:1, float:2)"
RESTful API - RadioStation IV. Appendix. POST /api/v1/conf loopchain 의특정 Configuration 을설정한다. Request Body "response_code": "int : RES_CODE", "data": "name": "Configuration 이름 ", "value": "String 타입의 Configuration 값 ", "type": "int : Configuration 값의데이터타입 (string:0, int:1, float:2)" Content-Type : application/json Request-body : Raw 데이터로써, JSON 형태의데이터 Response Body "response_code": "int : RES_CODE", "message": "message"
RESTful API - RadioStation IV. Appendix. GET /api/v1/cert/list/ca CA 인증서를발급합니다. Response Body "response_code": "int : RES_CODE", "message": "message" GET /api/v1/cert/list/peer Peer 의인증서를발급합니다. Response Body "response_code": "int : RES_CODE", "message": "message"
RESTful API - RadioStation IV. Appendix. GET /api/v1/cert/issue/ca Radio station 이발급한 CA 인증서를가져옵니다. Response Body "response_code": "int : RES_CODE", "data": "cert_type": " 인증서타입 (signature:0, encryption:1, ca:2)", "subject": " 공개키주체정보 ", "issuer": " 발급주체정보 ", "serial_number": " 일련번호 ", "not_after": " 인증서만료일 ", "cert_pem": " 인증서 "
RESTful API - RadioStation IV. Appendix. GET /api/v1/cert/issue/peer Radio station 이발급한 Peer 인증서목록을가져옵니다. Response Body "response_code": "int : RES_CODE", "data": [ "cert_type": " 인증서타입 (signature:0, encryption:1, ca:2)", "subject": " 공개키주체정보 ", "issuer": " 발급주체정보 ", "serial_number": " 일련번호 ", "not_after": " 인증서만료일 ", "cert_pem": " 인증서 ", "..." ]
RESTful API - Peer IV. Appendix. GET /api/v1/status/peer?channel=channel name loopchain 의현재상태를가져옴 (block height, total tx 등 ) Response Body "status": "Service is online: 1", "audience_count": 0, "consensus": "siever", "peer_id": "ac997810-240b-11e7-b072-a45e60c5e043", "peer_type": "1"
RESTful API - Peer IV. Appendix. GET /api/v1/status/score?channel=channel name loopchain 의 SCORE 상태를가져옴 (Score version, 배포된버전, SCORE 아이디 ) Response Body "id": "score/certificate", "status": 0, "version": "5b95c851bb90219cacce8444b4667eed4af73935", "all_version": [ "5b95c851bb90219cacce8444b4667eed4af73935", "b40e09a84e2f25d91b10b7b8c89a3f3fbd9309a4", "67398e1c42929f85002dda25949743c8408a2556", "61819fefe9a403562815e94e889af6a74fc53715", "da54c689fb538342ae3190586af2e2cf2311ce96", "1b13778e65831f90761670bc9139fe5e13162db0", "29682ba50a586e534d52d647fb65f1a749d59036", "a222b096ef4a5c6f90c77736ac3914c39f55f2c5", "9c529558b9636e1d1aca6b2a8807f0ba3df474bf", "0c601c48e034dffa5b3a3f4336e15f285a45f3a9", "3447ef8db315a4addd499b620562576e10b3907d", "82f4f85786ef73e0d020244c1697c6918fca20ec", "81e7c40f5aab0546be6bb1398e8016f5a7e1a120", "a41b3e0dcaeca653e26f11b4c75e5c15766f761e", "5ead8aba390687a2b0768f60711a170c998e40aa", "d3924a4336fb7a2ed1d86f22d57c488b4be8432f", "d7d02cf9825ad879eb0e79f6f6ac1b81738e52aa", "7d590db788c0a81a7caeb938b8204a737d63dd71", "a62cf913ffdc8b497b1f6ecfd6d0d731d02506db", "5edd70fda15601035254c62157a6717b950e16ae", "084dc91f607ffe5a8d6cfa5f366a3706e8cd6b2b", "5bc674d2e5508165592f93a56bb24d7c46a679fc", "4701abc7c666f59559fea3d818687649f30708e7" ]
RESTful API - Peer IV. Appendix. POST /api/v1/query 스코어가실행된결과조회 Request Body POST /api/v1/query "jsonrpc": "2.0", "channel": "channel_name", "method": "get_name", "id": "test_query", "params": "id": "1", Content-Type : application/json Request-body : Raw 데이터로써, JSON형태의데이터 jsonrpc : 반드시 2.0으로설정 method : SCORE안에호출할 Function 이름 params : JSON으로구성된 SCORE안에호출할 Function의 parameters.
RESTful API - Peer IV. Appendix. Response Body "response_code": "int : RES_CODE", "response": "jsonrpc": "2.0", "code": 0, "response": "name": "godong", "id": "test_query" Content-Type : application/json response_code : Request-body : Raw 데이터로써, JSON 형태의데이터 jsonrpc : 반드시 2.0 으로설정. code : SCORE 안에서실행한결과. response : 결과로넘어오는 JSON body
RESTful API - Peer IV. Appendix. GET /api/v1/transactions?hash= 찾으려는트랜잭션해시 &channel=channel_name 트랜잭션해시로블록체인에저장된데이터를가져옴. Response Body "response_code" : "int : RES_CODE", "data" : " 트랜잭션생성시보낸데이터 ", "meta" : "peer_id" : " 트랜잭션을생성한피어아이디 ", "score_id" : " 실행한 SCORE id", "score_version" : " 실행한 SCORE version", "more_info" : " 추가정보 "
RESTful API - Peer IV. Appendix. GET /api/v1/transactions/result?hash= 찾으려는트랜잭션해시 &channel=channel_name Score 실행결과를 Transaction Hash 를통해가져옴 Response Body "response_code" : "int : RES_CODE", "response" : "code" : 0( 성공 ), 2( 아직 commit되지않음 ), 9000 Exception "message" : " 실패시실패메시지 "
RESTful API - Peer IV. Appendix. /api/v1/transactions 트랜잭션을생성하여 SCORE 를실행. Request Body "jsonrpc": "2.0", "channel": "channel_name", "method": "get_bid", # SCORE안에호출할 Function 이름 "id": "test_query", # 비동기응답시이용할예정. 현재는사용안함. "params": # JSON으로구성된 SCORE안에호출할 Function의 parameters. "name": "1", "identity": "2" Content-Type : application/json Request-body : Raw 데이터로써, JSON 형태의데이터 Response Body "response_code" : "int : RES_CODE", "tx_hash" : " 트랜잭션해시 ", "more_info" : " 추가정보 "
RESTful API - Peer IV. Appendix. /api/v1/transactions 트랜잭션을생성하여 SCORE 를실행. Request Body "jsonrpc": "2.0", "channel": "channel_name", "method": "get_bid", # SCORE안에호출할 Function 이름 "id": "test_query", # 비동기응답시이용할예정. 현재는사용안함. "params": # JSON으로구성된 SCORE안에호출할 Function의 parameters. "name": "1", "identity": "2" Content-Type : application/json Request-body : Raw 데이터로써, JSON 형태의데이터 Response Body "response_code" : "int : RES_CODE", "tx_hash" : " 트랜잭션해시 ", "more_info" : " 추가정보 "
RESTful API - Peer IV. Appendix. GET /api/v1/blocks?channel=channel name 마지막블록의 hash 데이터를가져온다. Response Body "response_code" : "int RES_CODE", "block_hash" : "block_hash", "block_data_json" : "block_data_json" GET /api/v1/blocks?channel=channel name&hash= 찾으려는블록해시 블록해시에알맞은블록에서헤더데이터로 filter 에있는데이터를가져오고 txfilter 에있는데이터를트랜잭션데이터에추가하여블록데이터를가져옵니다. Response Body "block_hash" : " 블록해시 ", "block_data_json" : "prev_block_hash" : " 이전블록해시 ", "merkle_tree_root_hash" : " 머클루트 ", "time_stamp" : " 블록생성시간 ", "height" : " 블록높이 ", "peer_id" : " 블록생성피어 id", "tx_data_json" : [ "tx_hash" : " 트랜잭션해시 ", "timestamp" : " 트랜잭션생성시간 ", "data_string" : " 트랜잭션에들어간데이터 ", "peer_id" : " 트랜잭션을생성한피어 " ]
설정 IV. Appendix. < Log level 설정하기 > LOOPCHAIN_LOG_LEVEL 을이용하세요. 아래중하나의 String 값을가지면됩니다. 기본값은 "DEBUG" 입니다. ( 제일많이모든로그를보여줍니다.) 옵션값 : CRITICAL,ERROR, WARNING, INFO, DEBUG ( 오른쪽에서왼쪽으로갈수로더많은로그를남김 ) < Peer 의외부 IP 설정 > LOOPCHAIN_HOST 에 IP 값을설정합니다. 기본적으로 Peer 는시작할때, 해당 Peer 가속한 Network 에서사설 IP(Private IP) 가지고다른 Peer 들과통신하려고합니다. 외부와통신하지않고내부 Network 로만동작하는경우에는문제가없습니다. 그러나상황에따라서공용 IP(Public IP) 를가지고통신하는것이나을수있습니다. 예를들어, Network 를구성하는 Node 들이기존인터넷망을이용하거나 VPN 을이용해서통신을하는경우, Peer 의 IP 는기존인터넷망이나 VPN 에서접근가능한 IP 여야합니다. 하지만, 안타깝게도 Docker 상에서는이런상황에서 IP 를가져올수가없습니다. 그래서 LOOPCHAIN_HOST 를이용해서다른 Peer 들과통신을하기위해사용할공용 IP 를지정할수있습니다. LOOPCHAIN_HOST:$ 현재 node 가보여주어야하는 IP
설정 IV. Appendix. <SCORE 불러오는 Repository URL 바꾸기 > DEFAULT_SCORE_HOST: 현재 Blockchain 서비스에서 SCORE 를가져오기위해사용할 Git repository 의 URL 을설정해주면됩니다. Docker 로 Peer 를실행할때의 DEFAULT_SCORE_HOST 옵션으로 SCORE 를가져올 Git service URL 을지정합니다. $ docker run -d --name peer0 \... -e "DEFAULT_SCORE_HOST=github.com" \...
설정 IV. Appendix. <Multichannel -1> Multichannel 을사용하기위해서는 SCORE 와 Peer 의정보에대해서알고있어야합니다. 1. `channel_manage_data.json` 을수정합니다. channel 의이름, channel 에서실행되는 SCORE 의이름그리고, channel 에 join 하는 peer 들의목록을작성합니다. "%CHANNEL_NAME1%": // 1st channel name "score_package": "your_score_package", // 이채널에서실행되는 SCORE의이름 "peers": [ "peer_target": "%IP%:%PORT%" // 채널에포함되는 peer의정보 & 리스트,... ], "%CHANNEL_NAME2%": // 2nd channel name "score_package": "your_score_package", // 이채널에서실행되는 SCORE의이름 "peers": [ "peer_target": ""%IP%:%PORT%" // 채널에포함되는 peer의정보 & 리스트,... ]
설정 IV. Appendix. <Multichannel -2> 예를들어서 wework_0, wework_1 채널이각각 SCORE score/code1, score/code2 을사용한다면다음과같이작성이될것입니다. "wework_0": "score_package": "score/code1", "peers": [ "peer_target": "~~~~",... ], "wework_1": "score_package": "score/code2", "peers": [ "peer_target": "~~~~",... ]
설정 IV. Appendix. <Multichannel -3> 2. 설정파일을사용하여서 RadioStation 을실행합니다. 추후에 Docker 로 blockchain 을로컬컴퓨터에서구현하는예제에서자세히다시설명이되겠지만다음과같은순서로 RadioStaion 이설정파일을읽으면서실행이됩니다. $./radiostation.py -o rs_config.json 1) RadioStaion 이실행될때가장먼저 rs_conf.json 설정파일이먼저로딩됩니다. rs_conf.json 파일에 channel_manage_data.json 파일의위치가있습니다. "CHANNEL_MANAGE_DATA_PATH" : "./channel_manage_data.json", "ENABLE_CHANNEL_AUTH" : true parameter는다음과같은의미가있습니다. CHANNEL_MANAGE_DATA_PATH: Multichannel 을위한환경설정파일의위치와이름 ENABLE_CHANNEL_AUTH true = channel에등록된채널만 join이가능하다. false= 어떤 peer도등록이가능하다. 따로 peer 목록이없는경우에사용. 2) channel_manage_data.json 파일에서 MultiChannel 에대한환경설정을읽어옵니다.
설정 IV. Appendix. <Multichannel -4> 3. Peer 를설정파일을이용하여서실행합니다. peer_config.json 파일이 peer 에서사용하는설정파일입니다. "LOOPCHAIN_DEFAULT_CHANNEL" : "wework_0", "DEFAULT_SCORE_BRANCH": "master" parameter 들은다음과같은의미가있습니다. LOOPCHAIN_DEFAULT_CHANNEL : 이 peer 에서사용하는기본채널 DEFAULT_SCORE_BRANCH : 사용하는 SCORE 의 Branch. 기본값은 master 입니다. 터미널에서다음과같은명령어로실행하면됩니다. $./peer.py -o peer_config.json
설정 IV. Appendix. <RESTful 응답의성능높이기 > USE_GUNICORN_HA_SERVER : 실제운영단계에들어가는 Node 가많은 RESTful API 에대한 Request 들을잘받을수있게 gunicorn web service 에서쓸지말지결정해주는변수입니다. 기본값은 False 입니다. 실제서비스에올릴때는반드시 True 로설정되어야합니다. <Network 가느릴경우조절해야하는것들 > 상황에따라서느린네트워크에운용을하게된다면여러가지네트워크속도에장애가있는지아닌지확인하고설정을바꿔야합니다. Case 1. RadioStaion 의 Hart beat 의시간조절 RadioStation 은리더장애를파악하기위해주기적으로 Peer 들에게 Heart Beat 를보내고허용된횟수만큼리더가응답이없을경우리더를교체하는과정을수행합니다. 그러나네트워크사정이설치되는환경에따라다를것이기때문에아래의변수들을 RadioStation 에서설정해주셔야합니다. SLEEP_SECONDS_IN_RADIOSTATION_HEARTBEAT : RadioStation 이 Peer 의 Status 를확인하는시간. 단위는 Second. 기본값은 30 초. NO_RESPONSE_COUNT_ALLOW_BY_HEARTBEAT: RadioStation 이 Status 확인이안되는 Leader 를교체할횟수. 기본값은 5 회. "SLEEP_SECONDS_IN_RADIOSTATION_HEARTBEAT" X "NO_RESPONSE_COUNT_ALLOW_BY_HEARTBEAT" 횟수만큼리더응답이없으면 RadioStation 이리더를교체합니다. Case 2. Peer 들의연결 Timeout 설정하기 네트워크상태에따라서아래변수들을수정해야할수있습니다. 보통의경우에는설정할필요가없지만네트워크가매우안좋은상황에는시도해볼수있습니다. GRPC_TIMEOUT: grpc 연결하는시간의 Timeout 한계치. 단위는 Second. GRPC_TIMEOUT_BROADCAST_RETRY: grpc 로 data 를 broadcasting 하는시간의 Timeout 한계치. 단위는 Second.
설정 IV. Appendix. <Hardware 성능의문제로 Block 에담기는 Tx 숫자를조절 > Blockchain 은검증된여러 Tx 들을담고있는 Block 들의연결입니다. 그러나 Hardware 와 Network 의제약으로이를조절해야할경우, 그리고 Tx 의크기가너무크게될때, 아래의변수들을수정해주십시오. 참고로한개의 Tx 안에담기는정보가 3MB 이하로쓰기를권장합니다. MAX_BLOCK_TX_NUM: 블록의담기는트랜잭션의최대개수 LEADER_BLOCK_CREATION_LIMIT: Leader 의 block 생성개수. 한 Leader 가이개수이상의 Block 을만들면다른 Peer 로 Leader 가변경. BLOCK_VOTE_TIMEOUT: Block 에대한투표응답을기다리는최대시간. 단위는 Seconds.
설정 IV. Appendix. <KeyLoad 설정방법 > <loopchain Key 구성요소 > loopchain 에서는보안통신, 트랜잭션서명등을위하여인증서와키옵션을설정해주어야합니다. loopchain 에서사용하는키는다음과같습니다. Channel 별서명키 ecdsa secp256k X.509 인증서, Public key <Channel 별서명키옵션설정 > loopchain 에서는트랜잭션생성및블록생성시각 Peer 를검증하기위하여공개키기반암호화알고리즘을통해인증서명을사용합니다. 이때사용하는알고리즘은 ecdsa secp256k 를사용하고인증서형태와 Public key 형태를지원합니다. loopchain Peer 는키를로드하기위해공개키의형태와 (cert, public key), 키세트로드방식, 키위치등을설정하여야합니다. json 형태로옵션을설정해야하며다음예제는키옵션별로세팅해야될세팅을설명합니다. Ex) channel1 = key_file 을통해 load 한다면아래와같이해준다. "CHANNEL_OPTION" : "channel1" : "load_cert" : false, "consensus_cert_use" : false, "tx_cert_use" : false, "key_load_type": 0, "public_path" : "public_key path", "private_path" : "private_key path", "private_password" : "private_key password"
설정 IV. Appendix. 각 Parameter들의내용들은다음과같습니다. load_cert :load할인증서의 type 이 cert 면 true, public key 면 false consensus_cert_use: block 및투표서명에사용할공개키타입 (true : cert, false : public key) tx_cert_use : Transaction서명및검증에사용할공개키타입 (true : cert, false : public key) key_load_type : 0 (File에서읽음 ) public_path : Public key가있는위치 private_path : Private key가있는위치 private_password : Private key의 Password.
Thank you