페이지

2020년 12월 23일 수요일

몬티 홀 문제와 베이지안 추론

몬티 홀 문제와 베이지안 추론

몬티 홀 문제를 풀고 이에 대하여 베이지안 추론 방식으로 설명해 보고자 합니다.

문제 정의

세 개의 문이 있고 한 개의 문 뒤에는 자동차, 나머지 두 개의 문 뒤에는 염소가 있습니다. 각각의 문에는 1, 2, 3으로 번호가 붙어 있고 문이 닫힌 상태에서는 뒤에 무엇이 있는지 알 수 없습니다. 게임쇼 참여자가 1번을 선택하였습니다. 이어서 문 뒤에 무엇이 있는지 알고 있는 진행자는 3번 문을 열었고 그 뒤에는 염소가 있었습니다. 게임쇼 참여자에게 선택을 2번으로 바꿀 수 있는 기회가 주어집니다. 그렇다면 1번에 머무르는 것보다 2번으로 바꾸는 것이 우승할 확률을 더 높여줄까요?

문제 해결의 단서

  • 문 뒤에 무엇이 있는지 알고 있는 진행자는 2번 문과 3번 문 중 어느 하나를 무작위로 선택해서 여는 것이 아니라 자동차가 없는 문을 골라서 여는 것입니다. 진행자의 행위로 인해 2번 문 뒤에 자동차가 있을 확률이 더 높아졌다고 말할 수 있습니다.
  • 문 뒤에 무엇이 있는지 모르는 진행자가 2번 문과 3번 문 중에서 3번 문을 임의로 선택해서 열었는데 거기에 염소가 있다면 그것은 우연히 그렇게 된 것일 뿐입니다. 이 경우에는 2번 문 뒤에 자동차가 있을 확률을 더 높여주지 않으므로 1번 문을 선택한 게임쇼 참여자가 2번 문으로 바꿀 이유가 없습니다.

베이지안 추론

베이즈 정리

베이즈 정리는 아래의 식으로 표현됩니다.

  • P(CE)=P(EC)×P(C)P(E)P(C|E) = \frac{P(E|C)\times P(C)}{P(E)}

위의 식을 몬티 홀 문제에 적용하기 위하여 C와 E를 다음과 같이 정의합니다.

  • C: 2번 문 뒤에 자동차 존재 (2-car)
  • E: 3번 문 열기 (3-open)

3번 문 뒤에 염소가 있을 경우 2번 문 뒤에 자동차가 있을 확률을 아래와 같이 조건부확률로 표현할 수 있습니다.

  • P(2-car3-open)P(2\textnormal{-}car|3\textnormal{-}open)

이를 베이즈 정리에 따라 표현하면 아래와 같습니다.

  • P(2-car3-open)=P(3-open2-car)×P(2-car)P(3-open)P(2\textnormal{-}car|3\textnormal{-}open)=\frac { P(3\textnormal{-}open|2\textnormal{-}car)\times P(2\textnormal{-}car) }{ P(3\textnormal{-}open) }

확률 계산

3번 문을 열지 않은 상태에서 각각의 문 뒤에 자동차가 있을 확률

  • P(1-car)=13P(1\textnormal{-}car) = \frac{1}{3}
  • P(2-car)=13P(2\textnormal{-}car) = \frac{1}{3}
  • P(3-car)=13P(3\textnormal{-}car) = \frac{1}{3}

1번 문 뒤에 자동차가 있을 때 진행자가 3번 문을 열 확률

  • P(3-open1-car)=12P(3\textnormal{-}open|1\textnormal{-}car) = \frac{1}{2}

2번 문 뒤에 자동차가 있을 때 진행자가 3번 문을 열 확률

  • P(3-open2-car)=1P(3\textnormal{-}open|2\textnormal{-}car) = 1

3번 문 뒤에 자동차가 있을 때 진행자가 3번 문을 열 확률

  • P(3-open3-car)=0P(3\textnormal{-}open|3\textnormal{-}car) = 0

게임쇼 참여자가 1번 문을 선택했을 때 자동차가 어디에 있는지 알고 있는 진행자가 2번, 3번 문 중에서 3번 문을 열 확률

  • P(3-open)=P(3-open1-car)×P(1-car)+P(3-open2-car)×P(2-car)+P(3-open3-car)×P(3-car)=12×13+1×13+0×13=12P(3\textnormal{-}open) \\ \quad = P(3\textnormal{-}open|1\textnormal{-}car)\times P(1\textnormal{-}car) \\ \quad + P(3\textnormal{-}open|2\textnormal{-}car)\times P(2\textnormal{-}car) \\ \quad + P(3\textnormal{-}open|3\textnormal{-}car)\times P(3\textnormal{-}car) \\ \quad = \frac{1}{2}\times \frac{1}{3} + 1 \times \frac{1}{3} + 0\times \frac{1}{3} \\ \quad = \frac{1}{2}

3번 문을 열었을 때 2번 문 뒤에 자동차가 있을 확률

  • P(2-car3-open)=P(3-open2-car)×P(2-car)P(3-open)=1×1/31/2=23P(2\textnormal{-}car|3\textnormal{-}open) \\ \quad =\frac { P(3\textnormal{-}open|2\textnormal{-}car)\times P(2\textnormal{-}car) }{ P(3\textnormal{-}open) } \\ \quad = \frac{1\times 1/3}{1/2} \\ \quad = \frac{2}{3}

베이지안 추론 방식의 설명

3번 문을 열지 않은 상태에서 2번, 3번 문 중의 하나 뒤에 자동차가 있을 확률이 2/3인데, 3번 문 뒤에 자동차가 없다는 것을 알게 되었으므로 2번 문 뒤에 자동차가 있을 확률은 2/3가 됩니다.

이를 문제 정의 단원에서 제시한 내용과 확률 계산 단원에서 얻은 값을 사용하여 베이지안 추론 방식으로 설명할 수 있습니다.

  1. 기존 믿음(Prior)
    • 3번 문을 열지 않은 상태에서 2번 문 뒤에 자동차가 있을 확률은 1/3이고 2번, 3번 문 중의 하나 뒤에 자동차가 있을 확률은 2/3입니다.
  2. 새로운 증거(New Evidence)
    • 문 뒤에 무엇이 있는지 알고 있는 진행자가 3번 문을 열어서 염소가 있음을 보여주었습니다.
  3. 믿음 수정(Posterior)
    • 기존의 믿음, 그리고 새로운 증거를 고려하여 2번 문 뒤에 자동차가 있을 확률을 2/3로 수정합니다.

Written with StackEdit.

2020년 11월 28일 토요일

Excel VBA 사용하기

1. 개요

1.1. 목적

간단하고 짧은 비주얼 베이직 코드를 작성하여 엑셀 문서에 유용한 기능을 추가할 수 있음을 보여줍니다. 

1.2. 독자

  • 소프트웨어 개발자
  • 데이터 분석가

2. 준비

1) 엑셀 문서를 다음 형식의 파일로 저장합니다.

  • Excel 매크로 사용 통합 문서 (*.xlsm)

2) 엑셀 문서에서 파일 > 옵션 메뉴를 클릭합니다.

3) 리본 사용자 지정 탭에서 개발 도구 항목을 선택하고 확인 버튼을 클릭합니다.


4) 메뉴바에 개발 도구가 추가되었음을 확인합니다.


3. Hello, VBA! 예제

3.1. 매크로 추가

1) 엑셀 문서에서 보기 > 매크로 > 매크로 보기 메뉴를 클릭합니다.

2) 매크로 이름 입력창에 Hello를 입력하고 만들기 버튼을 클릭합니다.

3) 비주얼 베이직 편집기에서 아래 내용을 입력하고 저장합니다.

Sub Hello()
    MsgBox ("Hello, VBA!")
End Sub

3.2. 매크로 실행

1) 엑셀 문서에서 보기 > 매크로 > 매크로 보기 메뉴를 클릭합니다.

2) 매크로 이름 목록에서 Hello를 선택하고 실행 버튼을 클릭합니다.

3) 엑셀 문서에 다음과 같은 대화상자가 표시됨을 확인합니다.


4. 셀의 값을 읽고 쓰기 예제

4.1. 매크로 추가

1) 엑셀 문서에서 보기 > 매크로 > 매크로 보기 메뉴를 클릭합니다.

2) 매크로 이름 입력창에 ReadAndWriteExample을 입력하고 만들기 버튼을 클릭합니다.

3) 비주얼 베이직 편집기에서 아래 내용을 입력하고 저장합니다.

Sub ReadAndWriteExample()
    Dim Name As String
     
    Name = ActiveCell.Value
    Range("A10").Value = Name & " by Range"
    Cells(111).Value = Name & " by Cells"
End Sub

4.2. 매크로 실행

1) 엑셀 문서에서 하나의 셀을 선택하고 문자열을 입력합니다.

  • 예) "A9" 위치의 셀에 "Good"을 입력

2) 엑셀 문서에서 보기 > 매크로 > 매크로 보기 메뉴를 클릭합니다.

3) 매크로 이름 목록에서 ReadAndWriteExample을 선택하고 실행 버튼을 클릭합니다.

4) 엑셀 문서에 다음과 같은 내용이 표시됨을 확인합니다.


5. 참고 자료

  1. Getting started with VBA in Office
  2. How To Enable The Developer Tab
  3. VBA - Easy Excel
  4. VBA Articles - Excel Macro Mastery

2020년 5월 26일 화요일

Indy SDK Java 예제 빌드 및 실행

Indy SDK Java 예제 빌드 및 실행

아래 문서를 참고하여 Ubuntu에서 Indy SDK Java 예제를 빌드하고 실행하는 실습을 진행합니다.

1. 실습 환경

2. Java 빌드 프로그램 설치

  1. Java SDK를 설치합니다.

    $ sudo apt-get install openjdk-8-jdk
    
  2. Maven을 설치합니다.

    $ sudo apt-get install maven
    

3. Java 예제 빌드

  1. Indy SDK 소스를 다운로드합니다.

    $ cd $HOME
    $ git clone https://github.com/hyperledger/indy-sdk.git
    
  2. Java 예제를 빌드합니다.

    $ cd $HOME/indy-sdk/samples/java
    $ mvn package
    

4. 테스트

  1. Indy 노드 풀을 실행합니다.

    $ cd $HOME/indy-sdk
    $ docker build -f ci/indy-pool.dockerfile -t indy_pool .
    $ docker run -itd -p 9701-9708:9701-9708 indy_pool
    
  2. Java 예제를 실행합니다.

    $ mvn exec:java -Dexec.mainClass=Main
    

    정상적인 실행 결과는 아래와 같은 메시지를 출력합니다.

    Anoncreds sample -> started
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    Anoncreds sample -> completed
    Anoncreds Revocation sample -> started
    Anoncreds Revocation sample -> completed
    Ledger sample -> started
    Ledger sample -> completed
    Crypto sample -> started
    Crypto sample -> completed
    Endorser sample -> started
    Endorser sample -> completed
    

    Indy 노드 풀이 실행중이 아닐 경우 아래와 같은 TimeoutException 오류 메시지가 출력됩니다.

    Anoncreds sample -> started
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    [WARNING] 
    java.util.concurrent.ExecutionException: org.hyperledger.indy.sdk.ledger.TimeoutException: Timeout happens for ledger operation.
        at java.util.concurrent.CompletableFuture.reportGet (CompletableFuture.java:395)
        at java.util.concurrent.CompletableFuture.get (CompletableFuture.java:1999)
        at Anoncreds.demo (Anoncreds.java:27)
        at Main.main (Main.java:4)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke (Method.java:566)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282)
        at java.lang.Thread.run (Thread.java:834)
    Caused by: org.hyperledger.indy.sdk.ledger.TimeoutException: Timeout happens for ledger operation.
        at org.hyperledger.indy.sdk.IndyException.fromSdkError (IndyException.java:164)
        at org.hyperledger.indy.sdk.IndyJava$API.checkResult (IndyJava.java:92)
        at org.hyperledger.indy.sdk.pool.Pool.access$100 (Pool.java:20)
        at org.hyperledger.indy.sdk.pool.Pool$1.callback (Pool.java:52)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke (Method.java:566)
        at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback (CallbackReference.java:520)
        at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback (CallbackReference.java:551)
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    
  3. Indy 노드 풀 주소를 TEST_POOL_ID 환경변수에 지정하여 Java 예제를 실행할 수 있습니다.

    export TEST_POOL_IP=192.168.56.110
    $ mvn exec:java -Dexec.mainClass=Main
    

    이전에 다른 주소의 Indy 노드 풀에 접근하다가 실패한 적이 있다면 위와 같이 주소를 변경하여 실행할 때 아래와 같은 PoolLedgerConfigExistsException 오류 메시지가 발생할 수 있습니다.

    Anoncreds sample -> started
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    [WARNING] 
    java.util.concurrent.ExecutionException: org.hyperledger.indy.sdk.pool.PoolLedgerConfigExistsException: A pool ledger configuration already exists with the specified name.
        at java.util.concurrent.CompletableFuture.reportGet (CompletableFuture.java:395)
        at java.util.concurrent.CompletableFuture.get (CompletableFuture.java:1999)
        at utils.PoolUtils.createPoolLedgerConfig (PoolUtils.java:48)
        at Anoncreds.demo (Anoncreds.java:26)
        at Main.main (Main.java:4)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke (Method.java:566)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282)
        at java.lang.Thread.run (Thread.java:834)
    Caused by: org.hyperledger.indy.sdk.pool.PoolLedgerConfigExistsException: A pool ledger configuration already exists with the specified name.
        at org.hyperledger.indy.sdk.IndyException.fromSdkError (IndyException.java:162)
        at org.hyperledger.indy.sdk.IndyJava$API.checkResult (IndyJava.java:92)
        at org.hyperledger.indy.sdk.pool.Pool.access$400 (Pool.java:20)
        at org.hyperledger.indy.sdk.pool.Pool$2.callback (Pool.java:70)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke (Method.java:566)
        at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback (CallbackReference.java:520)
        at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback (CallbackReference.java:551)
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    

    이럴 경우에는 $HOME/.indy_client 폴더를 지우고 다시 실행합니다.

Written with StackEdit.

2020년 5월 22일 금요일

Indy SDK 빌드 및 설치

Indy SDK 빌드 및 설치

Indy SDK 바이너리 파일을 설치하려면 아래의 문서를 참고하여 libindy, libnullpay, libvcx, 그리고 indy-cli를 설치할 수 있습니다.

여기서는 아래 문서들을 참고하여 Ubuntu에서 Indy SDK 소스를 빌드하고 설치하는 과정을 실습합니다.

1. 실습 환경

2. C 빌드 프로그램 설치

  1. Make를 설치합니다.

    $ sudo apt-get install make
    
  2. C/C++ 컴파일러 및 링커를 설치합니다.

    $ sudo apt-get install g++
    

3. Rust 빌드 프로그램 설치

  1. 터미널에서 아래 명령을 실행합니다.

    $ curl https://sh.rustup.rs -sSf | sh
    

    위 명령은 다음 작업을 수행합니다.

    1. 설치 스크립트 다운로드
    2. 설치 스크립트 실행
      1. rustup을 설치
      2. rustup을 사용하여 최신 버전의 Rust를 설치
      3. Rust 실행 경로 $HOME/.cargo/bin를 환경변수 PATH에 추가

    설치에 성공하면 아래의 메시지가 출력됩니다.

    Rust is installed now. Great!
    
  2. 다시 로그인하면 Rust 실행 경로 $HOME/.cargo/bin가 환경변수 PATH에 포함되어 있을 것입니다.

  3. 설치한 Rust 컴파일러의 버전을 확인합니다.

    $ rustc --version
    rustc 1.43.1 (8d69840ab 2020-05-04)
    

4. Indy SDK 빌드 및 설치

  1. 필요한 라이브러리와 도구를 설치합니다.

    $ sudo apt-get update && \
    $ sudo apt-get install -y \
       build-essential \
       pkg-config \
       cmake \
       libssl-dev \
       libsqlite3-dev \
       libzmq3-dev \
       libncursesw5-dev
    
  2. libindy가 필요로 하는 libsodium은 apt 저장소에서 제공하지 않기 때문에 소스를 다운로드하여 빌드합니다.

    $ cd /tmp && \
      curl https://download.libsodium.org/libsodium/releases/old/unsupported/libsodium-1.0.14.tar.gz | tar -xz && \
       cd /tmp/libsodium-1.0.14 && \
       ./configure --disable-shared && \
       make && \
       sudo make install && \
       rm -rf /tmp/libsodium-1.0.14
    
  3. libindy 소스를 다운로드하여 빌드합니다.

    $ cd $HOME
    $ git clone https://github.com/hyperledger/indy-sdk.git
    $ cd ./indy-sdk/libindy
    $ cargo build
    

5. 테스트

5.1 Indy 노드 풀 실행

How to start local nodes pool with docker 문서를 참고하여 Indy 노드 풀을 로컬로 실행합니다.

  1. Docker로 Indy 풀을 빌드합니다.

    $ cd $HOME/indy-sdk
    $ docker build -f ci/indy-pool.dockerfile -t indy_pool .
    Sending build context to Docker daemon  4.832GB
    Step 1/22 : FROM ubuntu:16.04
     ---> 005d2078bdfa
    Step 2/22 : ARG uid=1000
     ---> Using cache
     ---> 8e4ce2fe34c7
    Step 3/22 : RUN apt-get update -y && apt-get install -y 	git 	wget 	python3.5 	python3-pip 	python-setuptools 	python3-nacl 	apt-transport-https 	ca-certificates 	supervisor
     ---> Using cache
     ---> c4db29f53a16
    Step 4/22 : RUN pip3 install -U 	pip==9.0.3 	setuptools
     ---> Using cache
     ---> 29699d8b1bcf
    Step 5/22 : RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CE7709D068DB5E88 || apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys CE7709D068DB5E88
     ---> Using cache
     ---> 5bc97b4e8591
    Step 6/22 : ARG indy_stream=master
     ---> Using cache
     ---> 847ea83573d3
    Step 7/22 : RUN echo "deb https://repo.sovrin.org/deb xenial $indy_stream" >> /etc/apt/sources.list
     ---> Using cache
     ---> c852d95dfaec
    Step 8/22 : RUN useradd -ms /bin/bash -u $uid indy
     ---> Using cache
     ---> 066abdcbb31e
    Step 9/22 : ARG indy_plenum_ver=1.12.1~dev989
     ---> Using cache
     ---> 321047b89616
    Step 10/22 : ARG indy_node_ver=1.12.1~dev1172
     ---> Using cache
     ---> 65a940e326d2
    Step 11/22 : ARG python3_indy_crypto_ver=0.4.5
     ---> Using cache
     ---> 2c012ba0ff4c
    Step 12/22 : ARG indy_crypto_ver=0.4.5
     ---> Using cache
     ---> c5e27ff6da07
    Step 13/22 : ARG python3_pyzmq_ver=18.1.0
     ---> Using cache
     ---> daf212ffee6f
    Step 14/22 : RUN apt-get update -y && apt-get install -y         python3-pyzmq=${python3_pyzmq_ver}         indy-plenum=${indy_plenum_ver}         indy-node=${indy_node_ver}         python3-indy-crypto=${python3_indy_crypto_ver}         libindy-crypto=${indy_crypto_ver}         vim
     ---> Using cache
     ---> dd09e2535e0e
    Step 15/22 : RUN echo "[supervisord]\nlogfile = /tmp/supervisord.log\nlogfile_maxbytes = 50MB\nlogfile_backups=10\nlogLevel = error\npidfile = /tmp/supervisord.pid\nnodaemon = true\nminfds = 1024\nminprocs = 200\numask = 022\nuser = indy\nidentifier = supervisor\ndirectory = /tmp\nnocleanup = true\nchildlogdir = /tmp\nstrip_ansi = false\n\n[program:node1]\ncommand=start_indy_node Node1 0.0.0.0 9701 0.0.0.0 9702\ndirectory=/home/indy\nstdout_logfile=/tmp/node1.log\nstderr_logfile=/tmp/node1.log\n\n[program:node2]\ncommand=start_indy_node Node2 0.0.0.0 9703 0.0.0.0 9704\ndirectory=/home/indy\nstdout_logfile=/tmp/node2.log\nstderr_logfile=/tmp/node2.log\n\n[program:node3]\ncommand=start_indy_node Node3 0.0.0.0 9705 0.0.0.0 9706\ndirectory=/home/indy\nstdout_logfile=/tmp/node3.log\nstderr_logfile=/tmp/node3.log\n\n[program:node4]\ncommand=start_indy_node Node4 0.0.0.0 9707 0.0.0.0 9708\ndirectory=/home/indy\nstdout_logfile=/tmp/node4.log\nstderr_logfile=/tmp/node4.log\n">> /etc/supervisord.conf
     ---> Using cache
     ---> a293cada0e77
    Step 16/22 : USER indy
     ---> Using cache
     ---> a80b0dfc3571
    Step 17/22 : RUN awk '{if (index($1, "NETWORK_NAME") != 0) {print("NETWORK_NAME = \"sandbox\"")} else print($0)}' /etc/indy/indy_config.py> /tmp/indy_config.py
     ---> Using cache
     ---> dcb46ff2da65
    Step 18/22 : RUN mv /tmp/indy_config.py /etc/indy/indy_config.py
     ---> Using cache
     ---> e540d82dfe32
    Step 19/22 : ARG pool_ip=127.0.0.1
     ---> Using cache
     ---> fd5c44727a33
    Step 20/22 : RUN generate_indy_pool_transactions --nodes 4 --clients 5 --nodeNum 1 2 3 4 --ips="$pool_ip,$pool_ip,$pool_ip,$pool_ip"
     ---> Running in 3290618d5b14
    Generating keys for provided seed b'000000000000000000000000000Node1'
    Init local keys for client-stack
    Public key is HXrfcFWDjWusENBoXhV8mARzq51f1npWYWaA1GzfeMDG
    Verification key is Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv
    Init local keys for node-stack
    Public key is HXrfcFWDjWusENBoXhV8mARzq51f1npWYWaA1GzfeMDG
    Verification key is Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv
    BLS Public key is 4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba
    Proof of possession for BLS key is RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1
    This node with name Node1 will use ports 9701 and 9702 for nodestack and clientstack respectively
    Generating keys for provided seed b'000000000000000000000000000Node2'
    Init local keys for client-stack
    Public key is Fsp2dyt7D2B4GA53hKnEmLym5Y75ExGFz2ZBzcQMNKsB
    Verification key is 8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb
    Init local keys for node-stack
    Public key is Fsp2dyt7D2B4GA53hKnEmLym5Y75ExGFz2ZBzcQMNKsB
    Verification key is 8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb
    BLS Public key is 37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk
    Proof of possession for BLS key is Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5
    This node with name Node2 will use ports 9703 and 9704 for nodestack and clientstack respectively
    Generating keys for provided seed b'000000000000000000000000000Node3'
    Init local keys for client-stack
    Public key is 6KTs7Q9Lng5uX6oWCkVifiJ6hSpkdHiRijAsXtAunnGN
    Verification key is DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya
    Init local keys for node-stack
    Public key is 6KTs7Q9Lng5uX6oWCkVifiJ6hSpkdHiRijAsXtAunnGN
    Verification key is DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya
    BLS Public key is 3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5
    Proof of possession for BLS key is QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh
    This node with name Node3 will use ports 9705 and 9706 for nodestack and clientstack respectively
    Generating keys for provided seed b'000000000000000000000000000Node4'
    Init local keys for client-stack
    Public key is ECUd5UfoYa2yUBkmxNkMbkfGKcZ8Voh5Mi3JzBwWEDpm
    Verification key is 4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA
    Init local keys for node-stack
    Public key is ECUd5UfoYa2yUBkmxNkMbkfGKcZ8Voh5Mi3JzBwWEDpm
    Verification key is 4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA
    BLS Public key is 2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw
    Proof of possession for BLS key is RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP
    This node with name Node4 will use ports 9707 and 9708 for nodestack and clientstack respectively
    BLS Public key is 4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba
    Proof of possession for BLS key is RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1
    BLS Public key is 37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk
    Proof of possession for BLS key is Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5
    BLS Public key is 3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5
    Proof of possession for BLS key is QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh
    BLS Public key is 2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw
    Proof of possession for BLS key is RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP
    Removing intermediate container 3290618d5b14
     ---> dc14f981b386
    Step 21/22 : EXPOSE 9701 9702 9703 9704 9705 9706 9707 9708
     ---> Running in 30903fff91f4
    Removing intermediate container 30903fff91f4
     ---> 86e1e83f19c2
    Step 22/22 : CMD ["/usr/bin/supervisord"]
     ---> Running in 7a8ade3e2407
    Removing intermediate container 7a8ade3e2407
     ---> ab8792faed23
    Successfully built ab8792faed23
    Successfully tagged indy_pool:latest
    
  2. Indy 풀을 실행합니다.

    $ docker run -itd -p 9701-9708:9701-9708 indy_pool
    e5f15ad2c43e39c5c8cf4c798445da395da0b268a32f0f8fc6f642a96adb9d18
    

5.2 테스트 시작

  1. 아래의 명령으로 테스트를 시작합니다.

    $ cd $HOME/indy-sdk/libindy
    $ RUST_TEST_THREADS=1 cargo test
    

    Indy 풀의 IP를 아래와 같이 환경변수 TEST_POOL_IP에 지정하여 실행할 수 있습니다.

    $ RUST_TEST_THREADS=1 TEST_POOL_IP=10.0.0.2 cargo test
    

5.3 Indy CLI 빌드

  1. indy-clilibindy에 의존하기 때문에 아래와 같이 libindy가 있는 위치를 지정하여 빌드합니다.

    $ cd $HOME/indy-sdk/cli/
    $ RUSTFLAGS=" -L ../libindy/target/debug" cargo build
    
  2. 환경변수 LD_LIBRARY_PATHlibindy가 있는 위치를 추가합니다.

    echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/indy-sdk/libindy/target/debug" >> ~/.bashrc
    sudo ldconfig
    source ~/.bashrc
    
  3. 아래 명령으로 indy-cli를 실행합니다.

    $ cd $HOME/indy-sdk/cli/target/debug
    $ ./indy-cli
    

Written with StackEdit.

국어 맞춤법 참고 자료

  제목 설명(인용) 출처 IT 글쓰기와 번역 노트 IT 기술 문서 및 서적을 집필/번역/교정하면서 얻은 경험/정보/지식을 공유합니다. 전뇌해커 [우리말 바루기] ‘대로’의 띄어쓰기 명사 뒤에서는 붙여 쓰고, 그 외에는 띄어 쓴다고 생각하면 쉽다. 다...