안녕하세요?

오늘은 지난 포스팅인 Hyperledger Fabric 개발환경 구성 에 이어 개발모드로 스마트 컨트랙(이하, 체인코드) 개발을 위한 환경 설명을 하겠습니다.

1. 사전 준비 사항

2. Fabric 소스 준비

체인코드 개발을 위해서는 개발 PC에 Fabric의 소스를 Golang 바이너리 설치 시 설정한 GOPATH 아래에 넣고 빌드하는 과정을 거칩니다.
다음의 명령어를 참조하여 GOPATH 하위에 디렉토리를 만들고 소스코드를 받습니다.

  • MacOS
$ mkdir -p $GOPATH/src/github.com/hyperledger
$ cd $GOPATH/src/github.com/hyperledger
$ git clone https://github.com/hyperledger/fabric.git
$ cd fabric
$ git checkout v0.6.1-preview
  • Windows
> mkdir %GOPATH%\src\github.com\hyperledger
> cd %GOPATH%\src\github.com\hyperledger
> git clone https://github.com/hyperledger/fabric.git
> cd fabric
> git checkout v0.6.1-preview

3. 체인코드 빌드 및 실행

소스를 모두 받았으면 우선 샘플 체인코드를 빌드하여 블록체인 네트워크 상에서의 동작을 확인 해보도록하겠습니다.
다음의 경로에서 체인코드를 빌드합니다.

  • MacOS
$ cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
$ go build
  • Windows
> cd %GOPATH%\src\github.com\hyperledger\fabric\examples\chaincode\go\chaincode_example02
> go build

위의 과정을 문제없이 완료하였으면 chaincode_example02 디렉토리 하위에 chaincode_example02 라는 이름으로 실행파일이 생성되었을 겁니다.(Windows는 chaincode_example02.exe )
개발모드에서는 이 실행파일을 몇 개의 환경변수와 함께 실행하기만 하면 블록체인 런타임에서 트랜잭션 테스트가 가능한 상태가 됩니다.

여기서 잠깐!!
개발모드와 운영모드의 차이점을 설명하면 아래 두 그림을 비교해 보면서 이해하시기 바랍니다.
먼저, 큰 차이점은 개발모드에서는 체인코드가 블록체인 런타임과 별도의 프로세스로 실행된다는 것입니다.

  • 운영모드에서는 체인코드를 디플로이하면 블록체인 네트워크에 있는 모든 피어들에게 복제가 되고 모든 피어들이 동일한 체인코드로 동작하게 되지만, 개발모드에서는 단일 피어에 체인코드가 붙어서 동작하는 구조입니다.
  • 그래서 체인코드 개발은 체인코드 실행 –> 테스트 –> 디버깅 –> 체인코드 빌드 –> 체인코드 실행의 순환적인 방법으로 이루어집니다.
개발모드 vs. 운영모드
  • 개발모드

  • 운영모드

그러면 실제로 블록체인 런타임에 체인코드를 실행해서 REST를 통해 테스트 해보도록 하겠습니다.
먼저, 지난 포스팅 Hyperledger Fabric 개발환경 구성을 참조하여 블럭체인 런타임을 실행시킵니다.

docker-compose up

체인코드 실행 전 Docker VM의 IP를 확인합니다.

docker-machine ls 

그리고 위에서 확인한 IP를 아래 명령어 중 CORE_PEER_ADDRESS의 값으로 입력하여 체인코드를 실행합니다.
체인코드를 실행 했을 때 에러없이 실행되며, 마지막에 “Received REGISTERED” 라는 메세지가 보이면 정상적으로 실행된 것입니다.

  • MacOS
$ cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
$ CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=192.168.99.100:7051 ./chaincode_example02

  • Windows
> cd %GOPATH%\src\github.com\hyperledger\fabric\examples\chaincode\go\chaincode_example02
> set CORE_CHAINCODE_ID_NAME=mycc
> set CORE_PEER_ADDRESS=192.168.99.100:7051
> chaincode_example01.exe

4. 테스트

지금까지 블록체인 런타임, 체인코드 실행을 모두 완료하였습니다. 이제부턴 REST Client를 통해 디플로이, 트랜잭션을 실행해 정상적으로 체인코드가 실행되는지 확인만 하면 됩니다.
테스트는 일반적인 REST Client로도 가능하며, 저는 POSTMAN을 통해 테스트 하도록 하겠습니다.

REST Endpoints

REST API들의 상세 설명은 다음에 따로 시간을 내어서 설명하도록 하겠습니다. 이번에는 테스트를 위해서 Registrar, Chaincode API만 사용을 합니다.

  • Block
    • GET /chain/blocks/{block-id}
  • Blockchain
    • GET /chain
  • Chaincode
    • POST /chaincode
  • Network
    • GET /network/peers
  • Registrar
    • POST /registrar
    • GET /registrar/{enrollmentID}
    • DELETE /registrar/{enrollmentID}
    • GET /registrar/{enrollmentID}/ecert
    • GET /registrar/{enrollmentID}/tcert
  • Transactions
    • GET /transactions/{UUID}

Hyperledger Fabric 개발환경 구성 에서 만들었던 docker-compose.yml 파일의 내용 중 CORE_SECURITY_ENABLED의 항목 true일 경우 반드시 사용자 등록 및 로그인 이 선행되어야지만 트랜잭션을 실행할 수 있습니다. 그리고 모든 API call에서 사용자 정보를 파라미터로 입력해야지만 정상적인 API call이 됩니다.

블록체인의 API를 사용하는 과정은 보안설정이 되어 있음을 가정하고
최초, 사용자 등록 및 로그인
이어서 체인코드 디플로이를 합니다.
체인코드 디플로이까지가 블록체인 런타음을 사용가능한 환경으로 준비하는 단계입니다.
다음으로 블록체인에 데이터를 입력하고 조화하는 동작인 “Invoke”, “Query” 동작을 필요에 따라 실행하게 됩니다.

사용자 등록 및 로그인

먼저, 사용자 등록 및 로그인을 해보겠습니다.
아래 내용에 있는 ID, PW는 사전에 정의되어 있는 유저이므로 동일한 유저로 테스트합니다.(유저 추가는 차후 설명하겠습니다.)

POST /registrar

{
  "enrollId": "admin",
  "enrollSecret": "Xurw3yU9zI0l"
}

체인코드 디플로이

블록체인의 런타임을 사용 가능한 상태로 만들어주기 위한 마지막 단계로 체인코드 디플로이 API를 호출합니다.
아래 파라미터 중 “secureContext”는 앞서 설명한 것과 같이 보안설정(CORE_SECURITY_ENABLED 항목을 true로 피어가 구동되었을 경우) 이 켜져 있는 경우 추가해야 하는 것입니다.

현재 버전의 Fabric에서는 블록을 관리하기위해서 Key-value 데이터베이스를 사용하고 있습니다.
그래서, 블록에 데이터 입력을 위해서는 Java의 HashMap등과 같이 Key – Value 쌍으로 입력을 하며,
값을 블록에서 조회하기 위해서는 Key 를 아용하여 값을 리턴 받습니다.
현재 샘플로 사용하는 체인코드는 최초 디플로이를 할때 총 4개의 argument를 받습니다. 아래와 같이 “a”, “100”, “b”, “200” 입니다.
체인코드의 로직으로 Key a 로 100의 값을 블록에 입력하고, 마찬가지로 Key b 로 200의 값을 넣습니다.

POST /chaincode

{
  "jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": 1,
    "chaincodeID":{
        "name": "mycc"
    },
    "ctorMsg": {
        "args":["init", "a", "100", "b", "200"]
    },
    "secureContext": "admin"
  },
  "id": 1
}

개발 모드에서 체인코드 디플로이는 “chaincodeID” 의 “name” 에 앞서 체인코드 실행시 입력한 “CORE_CHAINCODE_ID_NAME”의 값을 입력합니다.
또한, 개발모드에서 체인코드를 수정하였을 경우 3번 항목에서 설명한 체인코드 빌드부터 –> 체인코드 실행 –> 로그인 API 호출 –> 체인코드 디플로이를 호출하여야지만 기본 환경이 준비가 됩니다.
체인코드의 개발과정은 이 라이프사이클의 연속이라고 보시면 됩니다.

Invoke

지금부터는 블록체인에 데이터를 쓰고,조회하는 API를 설명합니다. 블록체인에 데이터를 쓰기위해서는 Invoke, 조회하기 위해서는 Query 를 호출합니다.
Invoke에서는 체인코드의 로직이 3개의 argument를 받아서 a 에 들어있는 값에 마지막 argument (여기에선 10) 을 빼고 블록에 입력, b 에 들어있는 값에 마지막 argument를 더해서 블록에 입력하라입니다.

POST /chaincode

{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
      "type": 1,
      "chaincodeID":{
          "name":"mycc"
      },
      "ctorMsg": {
         "args":["invoke", "a", "b", "10"]
      },
      "secureContext": "admin"
  },
  "id": 3
}

Query

위에서 Invoke가 정상적으로 호출이 되었다면 Qeury를 통해서 입력된 값을 확인합니다. 아래는 입력된 A 키의 값에 대해서 Query합니다.
Invoke가 정상적으로 되었다면 아래 그림에서와 같이 90의 값이 리턴되어야 합니다.(Invoke 의 로직 설명 참조바랍니다.)
Invoke의 로직 상 Invoke가 호출 될 수록 a 의 값은 10 만큼 작아지며, b의 값은 10 만큼 커집니다.(Invoke와 Query를 여러번 호출하면서 확인 해 보시기 바랍니다.)

POST /chaincode

{
  "jsonrpc": "2.0",
  "method": "query",
  "params": {
      "type": 1,
      "chaincodeID":{
          "name":"mycc"
      },
      "ctorMsg": {
         "args":["query", "a"]
      },
      "secureContext": "admin"
  },
  "id": 5
}

5. 정리하며

여기까지 모두 막힘없이 잘 진행이 되셨나요?
아직 체인코드를 개발하기 위한 인터페이스나 스펙에 대한 설명과, REST API 상세 설명은 하지 않았지만, 전반적인 체인코드 개발 사이클은 이해가 되었을 거라고 생각합니다.
개발을 위한 블록체인 런타임 구동은 단순히 멤버쉽 서비스와 VP가 하나씩 이루어진 환경( 사실은 체인코드 개발만을 위해서는 VP 하나만 있어도 상관없습니다.) 으로 충분한 환경이 되므로 가볍게 시작하실 수 있습니다.
다음으로 이어질 내용은 운영모드에서의 체인코드 디플로이와 테스트, 체인코드 인터페이스 상세, REST API 스펙 상세 등입니다.