Hyberledger Composer로 처음 해보는 블록체인 with 샘플코드

in blockchain •  7 years ago  (edited)

얼마전에 포스팅했던 글에서 이야기했듯이 현재 블록체인(!= 코인) 기술을 배워보는 중이다. 공부하고 있는 코세라의 블록체인 관련 강좌가 Hyberledger 라는 리눅스 파운데이션에서 만든 오픈소스 블록체인 솔루션을 사용하고 있는데, 3주차에 들어서면서 처음으로 예제코드를 동작시켜 보고 대충 감을 잡을 수 있는 기회가 있어서 공유해본다.

모델 파일, asset과 participant, 그리고 트랜잭션 모델을 정의한다. 잘 알려진바와 같이 블록체인이라는 자체의 개념은 open(public) ledger 다. ledger 즉 한국말로는 장부? 정도가 될 것 같은데, 그래서 장부에 뭔가가 기록될 때는 들어오는 것의 종류(돈, 물품, 등등) 즉 asset, 그리고 내가 A랑 거래를 해서 A가 나한테 뭘 준건지 아니면 내가 뭔가를 A한테 준건지를 기록할 수 있도록 거래에 참여한 사람, 즉 participant, 마지막으로 누가 누구한테 뭘 줬는지의 거래 자체를 정의할 수 있는 트랜잭션이 필요하다.

/**
 * Sample business network definition.
 */
namespace org.acme.sample

asset SampleAsset identified by assetId {
  o String assetId
  --> SampleParticipant owner
  o String value
}

participant SampleParticipant identified by participantId {
  o String participantId
  o String firstName
  o String lastName
}

transaction SampleTransaction {
  --> SampleAsset asset
  o String newValue
}

event SampleEvent {
  --> SampleAsset asset
  o String oldValue
  o String newValue
}

모델링을 하고 나면 그 다음에 필요한 것은 트랜잭션이 어떻게 처리되어야 하는지를 코딩한 트랜잭션 스크립트가 필요하다. 뭔가 길어 보이지만 코딩에 대한 경험이 조금이라도 있는 사람이라면 이 코드가 트랜잭션으로부터 넘겨받은 데이터 중 새로운 데이터값을 받아서 해당 에셋 레지스트리의 값을 업데이트하는 코드라는 걸 알 수 있다.

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Sample transaction processor function.
 * @param {org.acme.sample.SampleTransaction} tx The sample transaction instance.
 * @transaction
 */
function sampleTransaction(tx) {

    // Save the old value of the asset.
    var oldValue = tx.asset.value;

    // Update the asset with the new value.
    tx.asset.value = tx.newValue;

    // Get the asset registry for the asset.
    return getAssetRegistry('org.acme.sample.SampleAsset')
        .then(function (assetRegistry) {

            // Update the asset in the asset registry.
            return assetRegistry.update(tx.asset);

        })
        .then(function () {

            // Emit an event for the modified asset.
            var event = getFactory().newEvent('org.acme.sample', 'SampleEvent');
            event.asset = tx.asset;
            event.oldValue = oldValue;
            event.newValue = tx.newValue;
            emit(event);

        });

}

그 다음에 필요한 것은 바로 접근제어(access control)이다. 블록체인을 이용한 최초의 쓸만한(?) 레퍼런스인 비트코인은 '익명성' 이 특정이자 장점으로까지 내세워지고 있지만, 사실 블록체인 자체는 open ledger라는 걸 다시 한번 생각해 본다면 블록체인에 기록되는 트랜잭션은 사실 누가 누구와 무얼 거래하는지가 정확하게 기록이 되어야 하고 그래야 의미가 있다.
비트코인은 그 익명성 때문에 마약 혹은 무기거래상들이 대금결제시에 본인들의 신분을 숨기기 위한 결제수단으로 널리 사용되었었다는 건 잘 알려진 이야기다.

아무튼 그래서 participant에 대한 정부가 필요한 동시에 이 블록체인 '네트워크'에 접근하는 participant들이 무엇을 할 수 있고 무엇을 할 수 없는지를 컨트롤 할 필요성이 있다. 흔히 블록체인 하면 모든 것들이 블록체인 자체에 기록되고 누구나 그 거래내용을 볼 수 있다 라는 식으로 이야기가 되고 있지만 실제로는 거래 당사자들만이 해당 내용을 볼 수 있어야 하거나 아니면 특정 participant만 블록체인의 내용을 갱신할 수 있고 다른 participant들은 내용 보기만 가능하다던가 하는 권한조정이 필요하다.

즉 블록체인 자체에는 '모든 것들' 이 기록되지만 그렇다고 모두가 그걸 볼 수 있다거나 하는 이야기는 아니라는 것. A와 B가 주택 매매 거래를 했고 그게 만약 주택거래 데이터를 다루는 블럭체인 네트웤에 기록된다면 해당 매매와 전혀 상관없고 그 집의 주인이거나 채권자도 아닌 전혀 다른 C가 해당 트랜잭션을 볼 권리가 있어야 하는가? 볼 필요가 있을까?

/**
 * Sample access control list.
 */
rule EverybodyCanReadEverything {
    description: "Allow all participants read access to all resources"
    participant: "org.acme.sample.SampleParticipant"
    operation: READ
    resource: "org.acme.sample.*"
    action: ALLOW
}

rule EverybodyCanSubmitTransactions {
    description: "Allow all participants to submit transactions"
    participant: "org.acme.sample.SampleParticipant"
    operation: CREATE
    resource: "org.acme.sample.SampleTransaction"
    action: ALLOW
}

rule OwnerHasFullAccessToTheirAssets {
    description: "Allow all participants full access to their assets"
    participant(p): "org.acme.sample.SampleParticipant"
    operation: ALL
    resource(r): "org.acme.sample.SampleAsset"
    condition: (r.owner.getIdentifier() === p.getIdentifier())
    action: ALLOW
}

rule SystemACL {
  description:  "System ACL to permit all access"
  participant: "org.hyperledger.composer.system.Participant"
  operation: ALL
  resource: "org.hyperledger.composer.system.**"
  action: ALLOW
}

rule NetworkAdminUser {
    description: "Grant business network administrators full access to user resources"
    participant: "org.hyperledger.composer.system.NetworkAdmin"
    operation: ALL
    resource: "**"
    action: ALLOW
}

rule NetworkAdminSystem {
    description: "Grant business network administrators full access to system resources"
    participant: "org.hyperledger.composer.system.NetworkAdmin"
    operation: ALL
    resource: "org.hyperledger.composer.system.**"
    action: ALLOW
}

위의 코드를 대충 보면 억세스 컨트롤을 위한 룰을 여러가지 정의하는데, 어떤 participant를 위한​ 룰인지, 그리고 어떤 오퍼레이션에 대한 것인지(읽기/쓰기/삭제/전부? 등등), 그리고 어떤 리소스에 대한 것인지, 그리고 그걸 ALLOW한다는 내용. 예제 코드에는 나와 있지 않지만 액션에는 ALLOW 뿐만 아니라 DENY도 가능하다.

자 이렇게 하고 나면 위에서 정의했던 participant와 asset의 실제 데이터가 필요하다.
대략 다음과 같은 걸 participant registry에 등록하고 ( 처음 정의는 OOP에서 클래스 정의를, 그리고 이건 인스턴스를 생성한다고 생각하면 된다)

{
  "$class": "org.acme.sample.SampleParticipant",
  "participantId": "0828",
  "firstName": "Tobias",
  "lastName": "Hunter"
} 

그 다음에는 asset registry에다가 다음과 같은 SampleAsset을 생성한다

{
  "$class": "org.acme.sample.SampleAsset",
  "assetId": "assetId:1",
  "owner": "resource:org.acme.sample.SampleParticipant#0828",
  "value": "new value"
}

그리고 나서 트랜잭션을 실행시키려고 하면 다음과 같은 형태의 트랜잭션이 블록체인 네트웤에 전송될 거라는 JSON 포맷을 보여준다.

{
 "$class": "org.acme.sample.SampleTransaction",
 "asset": "resource:org.acme.sample.SampleAsset#assetId:1",
 "newValue": "new value",
}

실제로 실행이 되고 나면 처리된 트랜잭션들의 내용을 볼 수 있는데, 방금 막 실행된 트랜잭션을 살펴보면 위에서 봤던 class, asset, 그리고 newValue외에 트랜잭션 id와 트랜잭션이 실행된 시간의 타임스탬프가 추가된 것을 알 수 있다.

{
 "$class": "org.acme.sample.SampleTransaction",
 "asset": "resource:org.acme.sample.SampleAsset#assetId:1",
 "newValue": "new value",
 "transactionId": "a13dbf66-b1fb-416a-9fb3-eaa13940efc4",
 "timestamp": "2018-01-17T06:01:48.868Z"
}

뭔가 사람들이 블록체인이라고 이야기할 때 언뜻 뭔가 거창해 보이고 복잡할 것 같지만 실제로 이미 그런 개념들을 구현하고 추사화시킨 Hyperledger같은 블록체인 기술을 쓰면 사실상 코딩하는 입장에서는 그냥 데이터베이스 엔티티(혹은 OOP의 클래스/엔티티) 모델링해서 정의하고, 그것의 인스턴스를 만들어서 데이터베이스에 업데이트하는 일련의 것들과 크게 다르지 않아 보인다.

다만 블록체인 레이어에서 그 트랜잭션들을 모든 participant들이 동일하게 받아볼 수 있도록 트랜잭션을 관리하고 접근제어를 하고 그외 필요한 것들을 알아서 해 줄 터인데, 블록체인 기술의 장점을 취해서 실제 비즈니스 네트웤에 적용할 사람이라면 개념 정도만 이해하면 됐지 그 세세한 모든 것들을 다 알아야 할 필요는 없다. 마치 자동차 경주 선수가 운전만 잘하면 됐지 굳이 자동차의 엔진과 흡배기와 그 모든 것들을 다 알아야만 하는 것은 아니듯이 말이다.

자, 여기까지가 내 생애 최초의 블럭체인 관련 코딩 경험이다. 진도를 나가면서 또 공유할만하다 싶은 것들은 별도의 포스팅을 통해서 공유할 예정인데, 다만 이런 포스팅을 하면서 자그만 바램이 있다면 사람들이 블럭체인이라는 기술의 핵심이 정말로 무엇이고 뭘 하기 위한 것들인지, 그리고 비록 가상화폐(암호화폐, 버추얼 화폐, 코인, 기타 뭐라 부르든) 가 그 기반에 블록체인 기술을 쓰고는 있지만 사실 블록체인과 그 코인은 크게 상관이 없는 기술이라는 걸 이해하는데 도움이 되었으면 하는 것이다.

물론 코인을 주고받는 행위가 보내는 사람과 받는 사람이 있고(participant), 에셋이 있으며(비트코인 혹은 그 뭐든간에, 그리고 금액), 그리고 그것들의 거래내역인 트랜잭션이 있기 때문에 ledger(장부)에 기록되어 공유되는데 아주 적절한 use case이긴 하지만, 그 외에 또 코인을 채굴한다든지 해시를 쓴다든지 뭐 기타 등등의 것들은 사실 암호학이라든가 암호화폐쪽과 보다 더 밀접한 관계가 있는 내용이고 엄밀히 말한다면 블록체인 자체와는 아무런 상관이 없다.

그냥 '암호화폐' 라는 걸 사람들이 거래를 해야 하는데 그걸 중앙금융기관등을 이용하지 않고 서로 주고받았다는 걸 기록하기에 마침 적절한 블록체인 이라는 기술이 있어서 그 위에다가 암호화폐 거래의 트랜잭션을 태우고 있는 것. 그러니 어디가서 무식하게 "블록체인 = 코인" 이라는 이야기는 하지 말자. 블록체인상의 트랜잭션에는 어떤 에셋이든 올라갈 수 있다. 블록체인은 트랜스포트 레이어이고 코인은 그냥 그 위에서 옮겨다니는 payload일 뿐이다. ㅇㅋ?

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

좋은 글인데 이해하려면 공부가 더 필요한 흑
감사합니다!

어섭쇼 :D 스팀잇 계정오픈하셨군요 ㅎㅎ

지식 공유 감사합니다. 집에 가서 일독해 보겠습니다.

들러주셔서 감사합니다. :D