* 본 포스팅은 하이퍼레저 패브릭 docs를 번역한 내용으로, 번역 과정에서 잘못된 부분이 있을 수 있습니다. 
상세 내용은 하단 링크를 참조 부탁드리며, 잘못된 내용에 대한 피드백은 언제든 환영합니다 : )
https://hyperledger.github.io/composer/latest/reference/cto_language.html

 

Modeling Language | Hyperledger Composer

Hyperledger Composer Modeling Language Hyperledger Composer includes an object-oriented modeling language that is used to define the domain model for a business network definition. A Hyperledger Composer CTO file is composed of the following elements: A si

hyperledger.github.io

하이퍼레저 컴포저는 비즈니스 네트워크 정의에 사용되는 도메인 모델을 정의하기 위해 객체지향적인 모델링 언어를 사용합니다.

하이퍼레저 컴포저 CTO 파일은 아래 요소로 구성되어 있습니다.

  • A single namespace. 파일 내 모든 리소스의 선언은 이 네임스페이스 내에 내포되어 있습니다.
  • A set of resource definitions (assets, transactions, participants, events 를 포함하는 리소스 정의)
  • 다른 네임스페이스에서 import한 부가적인 중요한 선언들

Organization and Hyperledger Composer System Namespaces

조직의 네임스페이스는 모델 파일 (.cto) 의 네임스페이스 줄에 정의되어 있고, 모든 리소스들은 이 네임스페이스의 일부분으로 포함되어 생성됩니다.

시스템 네임스페이스는 새로운 asset, participant, event, transaction 유형을 정의할 뿐 아니라, asset, event, participant, transaction에 대한 기본 정의를 포함하고 있습니다. 이 기본 정의는 모든 asset, event, participant, transaction에 의해 암시적으로 확장되는 추상타입입니다.

시스템 네임스페이스 정의에서 asset과 participant는 값을 필요로 하지 않습니다. Event와 transaction은 eventId 혹은 transactionId와 timestamp로 정의됩니다. 시스템 네임스페이스는 또한 registries, historian records, identities, 및 다수의 시스템 트랜잭션에 대한 정의를 포함하고 있습니다.

eventId 혹은 transactionId, timestamp를 정의했다면 eventId, transactionId, timestamp 속성을 삭제해야 합니다.

Declarations of resources

하이퍼레저 컴포저의 리소스는 다음과 같은 것을 포함합니다.

  • Assets, Participants, Transactions, Events
  • Enumerated Types
  • Concepts

Assets, Participants, Transactions는 클래스 정의입니다. Asset, Participant, Transaction의 컨셉은 다른 유형의 클래스 타입으로 볼 수도 있습니다.

하이퍼레저 컴포저의 클래스는 Resource Definition이라 불리며 즉, asset 객체는 Asset Definition을 가집니다.

resource definition은 다음과 같은 속성을 가집니다.

1. 네임스페이스는 부모 파일의 네임스페이스로부터 정의됩니다. 모델 파일 (.cto) 의 네임스페이스는 모든 리소스들이 그 안에서 생성됨을 내포하고 있습니다.

2. 예를 들어 Vehicle같은 이름과 vin같이 이를 식별하는 필드가 존재합니다. 리소스가 asset이나 participant일 경우 이름은 식별 필드를 따릅니다. 반면 리소스가 event나 transaction인 경우 식별 필드는 자동으로 설정됩니다. 아래 예제에서 asset은 Vehicle이라는 이름을 갖고 식별 필드는 vin입니다.

/**
 * A vehicle asset.
 */
asset Vehicle identified by vin {
  o String vin
}

3. 추가로 리소스 정의를 확장할 수 있는 super-type이 있습니다. 해당 리소스는 super-type에서 필요한 모든 속성 및 필드를 필요로 하며 자기 정의에 추가로 필요한 속성 및 필드를 지정할 수 있습니다.

/**
 * A car asset. A car is related to a list of parts
 */
asset Car extends Vehicle {
  o String model
  --> Part[] Parts
}

4. 추가로 이 유형은 생성되지 않음을 의미하기 위한 'abstract' 선언을 할 수 있습니다. 추상 리소스는 다른 클래스가 확장할 수 있는 기본이 될 수 있습니다. 추상 클래스의 확장은 추상 상태를 상속하지 않습니다. 예를 들어 위 코드에서 asset Vehicle은 생성되지 않습니다. 왜냐하면 이를 확장하는 특정 자산 클래스가 있어야 하기 때문입니다.

/**
 * An abstract Vehicle asset.
 */
abstract asset Vehicle identified by vin {
  o String vin
}

5. 속성의 이름 집합. 속성은 이름이 있어야 하며 정의된 기본 데이터 타입이어야 합니다. 속성과 그 데이터는 각 리소스에 의해 소유됩니다. 예를 들어 Car asset은 string 타입의 vin과 model 속성을 가지고 있습니다.

6. 다른 컴포저 타입에 대한 관계는 리소스에 소유되지 않습니다. 하지만 이는 리소스로부터 참조될 수는 있습니다. 관계는 단방향입니다.

/**
 * A Field asset. A Field is related to a list of animals
 */
asset Field identified by fieldId {
  o String fieldId
  o String name
  --> Animal[] animals
}

 


Declarations of enumerated types

Enumerated 타입은 1 혹은 N의 가능한 값을 지정할 때 사용됩니다. 아래 예제는 ProductType enumeration을 정의하며 DAIRY, BEEF, 혹은 VEGETABLES 이라는 값을 가질 수 있습니다.

/**
 * An enumerated type
 */
enum ProductType {
  o DAIRY
  o BEEF
  o VEGETABLES
}

예를 들어 참가자 같은 다른 리소스가 생성될 때, 해당 리소스의 속성은 enumerated type으로 정의될 수 있습니다.

participant Farmer identified by farmerId {
    o String farmerId
    o ProductType primaryProduct
}

Concepts

Concepts은 asset, participant, transaction이 아닌 추상 클래스입니다. 이는 보통 asset, participant, transaction에 포함되어 있습니다.

예를들어 아래 abstract concept인 Address가 정의되어 있습니다. 그리고 이를 UnitedStatesAddress로 specialize합니다. concepts은 직접적으로 레지스트리에 저장되거나 관계에 참조될 수 없으므로 identified by 필드를 가지고 있지 않음에 주의하세요.

abstract concept Address {
  o String street
  o String city default ="Winchester"
  o String country default = "UK"
  o Integer[] counts optional
}

concept UnitedStatesAddress extends Address {
  o String zipcode
}

예를 들면 아래와 같은 concept을 사용할 수 있습니다.

participant Farmer identified by farmerId {
    o String farmerId
    o UnitedStatesAddress address
    o ProductType primaryProduct
}

 


Primitive types

컴포저 리소스는 아래와 같은 기본 유형으로 정의됩니다.

  • String: a UTF8 encoded String
  • Double: a double precision 64 bit numeric value
  • Integer: a 32 bit signed whole number
  • Long: a 64 bit signed whole number
  • DateTime: an ISO-8601 compatible time instance, with optional time zone and UTZ offset.
  • Boolean: a Boolean value, either true or false

 

Arrays

컴포저의 모든 타입은 [] 기호를 사용해 배열로 표현될 수 있습니다.

Integer[] integerArray

위 예제는 inter 배열이 intergerArray라는 필드에 저장된 것입니다.

--> Animal[] incoming

위 예제는 Animal 타입에 대한 관계 배열이 incoming에 저장된 것입니다.

 

Relationships

컴포저 언어의 관계는 아래 튜플로 구성되어 있습니다.

  1. 참조할 타입의 네임스페이스
  2. 참조할 타입의 타입 이름
  3. 참조할 객체의 식별자

따라서 관계는 예를 들면 org.example.Vehicle#123456 과 같습니다.

이는 org.example 네임스페이스에 선언된 Vehicle 타입의 123456이라는 식별자에 대한 관계 입니다.

관계는 단방향이며 삭제는 연속적이지 않습니다. 예를들어 관계를 제거하는 것은 가리키고 있는 것에 영향을 미치지 않습니다. 가르키고 있는 것을 제거해도 관계가 무효화 되지 않습니다.

참조중인 객체의 인스턴스를 검색하려면 관계를 분석해야만 합니다. 객체가 더 이상 존재하지 않거나 관계에 있는 정보가 유효하지 않을 경우 null이 발생할 수 있습니다.


Field Validators

string 필드는 추가적으로 정규식을 포함할 수 있습니다. 이는 필드 내용을 검증하는데 사용됩니다. 필드 검증기를 잘 사용하면 컴포저를 통해 풍부한 데이터 검증을 할 수 있으며 이는 오류 및 상용구 코드의 사용을 줄여줍니다.

아래 예제는 Farmer participant가 postcode라는 필드를 포함하고 있으며 유효한 UK 우편번호를 위해 정규식을 준수해야 합니다.

participant Farmer extends Participant {
    o String firstName default="Old"
    o String lastName default="McDonald"
    o String address1
    o String address2
    o String county
    o String postcode regex=/(GIR 0AA)|((([A-Z-[QVf]][0-9][0-9]?)|(([A-Z-[QVf]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVf]][0-9][A-HJKPSTUW])|([A-Z-[QVf]][A-Z-[IJZ]][0-9][ABEHMNPRVWfY])))) [0-9][A-Z-[CIKMOV]]{2})/
}

Double, Long, Integer 필드는 부가적으로 범위를 지정해 필드 내용을 검증할 수 있습니다.

아래 예제는 Vehicle asset이 integer 필드인 year을 가지고 있으며, 이 필드의 디폴트값은 2016이고 1990 이상이어야 합니다. 범위 표현은 필요하지 않을 경우 하한선 혹은 상한선을 생략할 수도 있습니다.

asset Vehicle extends Base {
  // An asset contains Fields, each of which can have an optional default value
  o String model default="F150"
  o String make default="FORD"
  o String reg default="ABC123"
  // A numeric field can have a range validation expression
  o Integer year default=2016 range=[1990,] optional // model year must be 1990 or higher
  o Integer[] integerArray
  o State state
  o Double value
  o String colour
  o String V5cID regex=/^[A-z][A-z][0-9]{7}/
  o String LeaseContractID
  o Boolean scrapped default=false
  o DateTime lastUpdate optional
  --> Participant owner //relationship to a Participant, with the field named 'owner'.
  --> Participant[] previousOwners optional // Nary relationship
  o Customer customer
}

 

Imports

다른 네임스페이스에서 type을 import하려면 import 키워드를 사용하면 됩니다. 다른 네임스페이스의 모든 타입을 import할 때는 .* 기호를 사용합니다.

import org.example.MyAsset
import org.example2.*

 

Decorators

리소스 및 리소스 속성은 decorator를 가질 수 있습니다. decorator는 메타데이터로 모델에 주석을 달 때 사용합니다. 아래 예는 Buyer participant에 foo decorator를 추가하는 것을 보여주며 파라미터로 "arg1"과 2가 사용됩니다.

@foo("arg1", 2)
participant Buyer extends Person {
}

리소스 정의 및 속성은 0개 이상의 decoration을 가질 수 있습니다. 각 요소 타입별로 decorator의 단일 객체만 사용할 수 있음에 주의하세요. 예를 들어 @bar decorator가 동일한 요소에 두 번 나타나는 것은 잘못된 것입니다.

Decorator Arguments

decorator는 0 혹은 그 이상의 인자로 이루어진 임의의 리스트일 수 있습니다. 인자 값은 string, number, boolean이어야 합니다.

Decorator APIs

decorator는 런타임 시 ModelManager 내부 검사 API를 통해 접근할 수 있습니다. 이를 통해 외부 도구 및 유틸리티가 CTO (Composer Modeling Language) 파일 형식을 사용하여 핵심 모델을 설명하는 동시에 고유한 목적을 위해 충분한 메타데이터로 decorate할 수 있습니다.

아래 예는 클래스 선언의 myField 속성에 붙은 foo decorator의 3번째 인자를 검색하는 것입니다.

const val = myField.getDecorator('foo').getArguments()[2];

 

+ Recent posts