비계 Go Chaincode 프로젝트

Blockchain App Builder는 사양 파일에서 입력을 가져와 완전한 기능을 갖춘 비계 체인 코드 프로젝트를 생성합니다. 프로젝트에는 자동으로 생성된 클래스 및 함수, CRUD 메소드, SDK 메소드, 인수의 자동 검증, 마셜링/마셜링 해제 및 ORM(투명한 지속성 기능)이 포함됩니다.

체인코드 프로젝트가 Go 언어인 경우 스캐폴드 프로젝트에는 다음과 같은 세 가지 주요 파일이 포함됩니다.
  • main.go
  • <chaincodeName>.model.go
  • <chaincodeName>.controller.go
필요한 모든 라이브러리가 설치되고 패키지화됩니다.

model 하위 디렉토리의 <chaincodeName>.model.go 파일은 여러 자산 정의를 포함하며 controller 하위 디렉토리의 <chaincodeName>.controller.go 파일은 자산의 동작 및 CRUD 메소드를 포함합니다. model.gocontroller.go의 다양한 Go 구조 태그 및 패키지는 인수 자동 검증, 인수 마셜링/마셜링 해제, ORM(투명한 지속성 기능) 및 풍부한 쿼리 호출과 같은 기능을 지원합니다.

비계 프로젝트는 $GOPATH/src/example.com/<chaincodeName>에서 찾을 수 있습니다.

모델

자산 유형 등록 정보

기본적으로 모든 구조체에는 AssetType이라는 추가 속성이 있습니다. 이 속성은 이 유형의 자산만 인출하는 데 유용할 수 있습니다. 자산 생성 및 업데이트 중 이 속성에 대한 모든 변경사항이 무시됩니다. 기본적으로 등록정보 값은 <modelName>입니다.
type Supplier struct {
AssetType string 'json:"AssetType" default:"TestGoProject.Supplier"'

SupplierId            string      'json:"SupplierId" validate:"string,mandatory" id:"true'
RawMaterialAvailable  int         'json:"RawMaterialAvailable" validate:"int,min=0"'
License               string      'json:"License" validate:"string,min=10"'
ExpiryDate            date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
Active                bool	  'json:"Active" validate:"bool" default:"true"'
Metadata              interface{} 'json:"Metadata,omitempty"'
}

검증기

ID
id:"true"
이 검증기는 기본 자산을 고유하게 정의하는 속성을 식별합니다. 자산이 이 키의 값으로 저장됩니다. 이 검증기는 새 Go 프로젝트가 스캐폴딩될 때 자동으로 적용됩니다.
아래 스크린샷에서 "SupplierId"은 공급자 자산의 키이며 SupplierId 속성에 대한 태그 속성 id:"true"이 있습니다.
type Supplier struct {
    Supplierld              string        'json:"Supplierld" validate:"string,mandatory" id:"true"' 
    RawMaterialAvailable    int           'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string        'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date     'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool          'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{}   'json:"Metadata,omitempty"'   
}
파생됨
derived:"strategy,algorithm,format"
이 데코레이터는 다른 속성에서 파생된 속성을 정의하는 데 사용됩니다. 이 데코레이터에는 두 가지 필수 매개변수가 있습니다.
  • strategy: concat 또는 hash 값을 사용합니다. hash가 선택된 경우 추가 매개변수 algorithm가 필요합니다. 기본 알고리즘은 sha256이고 md5도 지원됩니다.
  • format: 전략에서 사용할 사양 문자열 및 값 배열을 사용합니다.
type Supplier struct{
   AssetType string 'json:"AssetType" final:"chaincode1.Supplier"'
   SupplierId   string  'json:"SupplierId" validate:"string" id:"true" mandatory:"true" derived:"strategy=hash,algorith=sha256,format=IND%1%2,License,Name"'
   Name         string  'json:"Name" validate:"string,min=2,max=4"'
   License      string  'json:"License" validate:"string,min=2,max=4"'
}
필수입니다
validate:"mandatory"
다음 속성은 필수로 표시되며 원장에 저장하는 동안 생략할 수 없습니다. 건너뛰면 오류가 발생합니다. 아래 예제에서 "SupplierId"에는 validate:"mandatory" 태그가 있습니다.
Type Supplier struct {
    Supplierld              string      'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable    int         'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string      'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool        'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{} 'json:"Metadata,omitempty"'
}
기본값
default:"<param>"
이는 다음 등록 정보에 기본값이 있을 수 있음을 나타냅니다. 기본 태그의 기본값은 원장에 저장하는 동안 속성을 건너뛸 때 사용됩니다. 아래 예제 속성에서 Active의 기본값은 default:"true" 태그로 제공된 true입니다.
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
유형 검증
검증 태그를 정의하여 속성에 대해 기본 실행 유형이 검증됩니다. 유형을 기반으로 하는 검증 태그는 다음과 같습니다.
  • 문자열: validate: "string"
  • 날짜: validate: "date"
  • 번호: validate: "int"
  • 부울: validate: "bool"
최소 검증기
validate:"min=<param>"
최소 검증기를 사용하여 숫자 및 문자열 유형의 속성에 대해 최소값을 설정할 수 있습니다.
int 유형의 경우: 예제에서 RawMaterialAvailable 속성의 최소값은 0이고 0보다 작은 값이 RawMaterialAvailable에 적용되면 오류가 반환됩니다.
유형 문자열의 경우: 문자열 유형의 경우 최소 검증자는 제공된 값을 사용하여 문자열의 길이를 확인합니다. 따라서 아래 예에서 License 등록 정보의 길이는 최소 10자여야 합니다.
예제:
Type Supplier struct {
    Supplierld             string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable   int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                string       'json:"License" validate:"string,min=10"'
    ExpiryDate             date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                 bool         'json:"Active" validate:"bool" default :"true"'
    Metadata               interface{}  'json:"Metadata,omitempty"'
}
최대 검증기
validate:"max=<param>"
최대 검증기를 사용하면 숫자 및 문자열 유형의 속성에 대해 최대값을 설정할 수 있습니다.
int 유형의 경우: 최소 검증기와 마찬가지로 int 유형의 경우 structfield에 대해 제공된 값이 검증기에 제공된 값보다 크면 오류가 반환됩니다.
유형 문자열: 최소 검증기와 마찬가지로 최대 검증기는 지정된 값의 문자열 길이도 확인합니다. 예제에서 Domain 속성의 최대값은 50이므로 Domain 속성의 문자열 길이가 50자를 초과하는 경우 오류 메시지가 반환됩니다.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
날짜 검증기입니다.
검증기 전:
validate:"before=<param>"
before 검증기는 매개변수에 지정된 값보다 작은 값을 가지도록 date 유형의 등록 정보를 검증합니다.
이 예에서 ExpiryDate 속성은 "2020-06-26" 앞에 있어야 하며, 그렇지 않으면 오류가 반환됩니다.
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
검증기 후:
validate:"after=<param>"
before 검증기는 매개변수에 지정된 값보다 큰 값을 가지도록 date 유형의 등록 정보를 검증합니다.
이 예에서 CompletionDate 속성은 "2020-06-26" 뒤에 있어야 하며, 그렇지 않으면 오류가 반환됩니다.
Type Supplier struct {
    Manufacturerld        string       'json:"Manufacturerld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,max=8"'
    ProductsAvailable     int          'json:"ProductsAvailable" validate:"int"'
    CompletionDate        date.Date    'json:"CompletionDate" validate:"date,after=2020-06-26"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
URL 검증기
validate:"url"
URL 검증기는 URL 문자열에 대한 속성을 검증합니다.
이 예에서 Domain 속성은 적합한 URL이어야 합니다.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
정규표 검증기
validate:"regexp=<param>"
정규식 검증기는 입력 정규식에 대한 속성을 검증합니다.
이 예에서 PhoneNumber 속성은 정규 표현식에 따라 이동 전화 번호를 검증합니다.
type Customer struct {
Customerld      string       'json:"Customerld" validate:"string,mandatory" id:"true"'
Name            string       'json:"Name" validate:"string,mandatory"'
ProductsBought  int          'json:"ProductsBought" validate:"int"'
OfferApplied    int          'json:"OfferApplied" validate :"int,nax=0"'
PhoneNumber     string       'json:"PhoneNumber" validate:"string,regexp=A\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"'
Received        bool         'json:"Received" validate:"bool"'
Metadata        interface{}  'json:"Metadata,omitempty"'
}
다중 검증자
하나의 속성을 여러 검증기에 적용할 수 있습니다.
이 예에서 Domain 속성은 문자열, URL, 최소 및 최대 문자열 길이에 대한 검증을 가집니다.
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}

ORM

투명한 지속성 기능 또는 단순화된 ORM은 컨텍스트(Ctx) 객체의 Model 클래스에 캡처됩니다. 모델이 다음 SDK 메소드 중 하나를 호출하는 경우 t.Ctx.Model를 사용하여 해당 메소드에 액세스합니다.

ORM을 구현하는 SDK 메소드는 다음과 같습니다.
  • Save - Hyperledger Fabric PutState 메소드를 호출합니다.
  • Get - Hyperledger Fabric GetState 메소드를 호출합니다.
  • Update - Hyperledger Fabric PutState 메소드를 호출합니다.
  • Delete - Hyperledger Fabric DeleteState 메소드를 호출합니다.
  • History - Hyperledger Fabric GetHistoryForKey 메소드를 호출합니다.
  • GetByRange - Hyperledger Fabric GetStateByRange 메소드를 호출합니다.
  • GetByRangeWithPagination - Hyperledger Fabric GetStateByRangeWithPagination 메소드를 호출합니다.

SDK 메소드

Go 체인코드는 모델 패키지와 함께 ORM(투명한 지속성 기능)을 구현합니다.

주:

버전 21.2.3부터 ORM 메소드에 액세스하는 방법이 변경되었습니다. ochain --version 명령을 실행하여 Blockchain App Builder의 버전을 확인합니다.

이전 릴리스에서는 ORM 메소드가 모델 패키지의 정적 메소드로 표시되었습니다. 이제 메소드가 트랜잭션 스텁을 보유하는 모델 수신기에 정의됩니다. 이러한 메소드를 호출하려면 컨트롤러의 트랜잭션 컨텍스트에서 보유하는 모델 수신기를 사용합니다. 이러한 메소드를 model.<method_name> 대신 t.Ctx.Model.<method_name>로 호출합니다.

다음 예에서는 이전 릴리스의 SaveGet 메소드 호출을 보여줍니다.

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := model.Get(id, &asset)
  return asset, err
}

다음 예에서는 버전 21.2.3 이상에서 SaveGet 메소드 호출을 보여 줍니다.

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return t.Ctx.Model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := t.Ctx.Model.Get(id, &asset)
  return asset, err
}

버전 21.2.3으로 업그레이드한 후 이전 버전의 Blockchain App Builder로 생성한 모든 체인코드 프로젝트에서 이와 같이 변경합니다. sync 명령을 사용하여 사양 파일과 소스 코드 간의 변경사항을 동기화하면 즉시 사용 가능한 메소드에 대한 변경사항이 컨트롤러에 자동으로 적용됩니다. 계속해서 충돌을 수동으로 해결해야 합니다.

모델 패키지를 통해 표시되는 ORM 메소드는 다음과 같습니다.

Get
지정된 ID를 기반으로 저장된 자산에 대한 원장을 질의합니다.
func Get(Id string, result ...interface{}) (interface{}, error)
매개변수:
  • ID - 원장에서 필요한 자산의 ID입니다.
  • result (interface{}) - 참조에 의해 전달되는 특정 유형의 빈 자산 객체입니다. 이 객체는 이 메소드의 결과를 포함합니다. 유형별 결과가 필요한 경우에만 사용됩니다.
  • asset (interface) - 참조로 전달되는 자산 객체가 비어 있습니다. 이 객체는 이 메소드의 결과를 포함합니다. 유형별 결과가 필요한 경우에만 사용됩니다.
반환값:
  • interface {} - 인터페이스는 map[string]interface{} 형식의 자산을 포함합니다. 이 맵에서 작업하기 전에 map[string]interface{} 유형의 획득한 인터페이스를 검증해야 합니다. 이 맵을 자산 객체로 변환하려면 유틸리티 API util.ConvertMaptoStruct를 사용할 수 있습니다(참조: 유틸리티 패키지).
  • error - 반환된 경우 오류를 포함하거나 nil입니다.
Update
원장에서 제공된 자산을 새 값으로 업데이트합니다.
func Update(args ...interface{}) (interface{}, error)
매개변수:
  • obj (interface) - 원장에서 업데이트해야 하는 객체가 이 API에 참조하여 새 값으로 전달됩니다. 입력 자산은 모델 사양에 언급된 구조 태그에 따라 검증 및 확인된 후 원장에 저장됩니다.
반환값:
  • interface{} - 저장된 자산이 인터페이스로 반환됩니다.
  • error - 반환된 경우 오류를 포함하거나 nil입니다.
Save
모든 구조 태그에서 검증한 후 자산을 원장에 저장합니다.
func Save(args ...interface{}) (interface{}, error)
매개변수:
  • obj/args[0] (interface{}) - 원장에 저장해야 하는 객체는 이 유틸리티 메소드에서 참조에 의해 전달됩니다.
  • metadata/args[1] (interface{}) - 이 매개변수는 선택사항입니다. 런타임 시 자산과 함께 원장에 메타데이터를 저장해야 하는 경우 쉽게 사용할 수 있도록 제공되었습니다. 이러한 요구 사항이 없으면 이 매개변수를 건너뛸 수 있습니다.
반환값:
  • interface {} - 자산이 인터페이스로 반환됩니다.
  • error - 반환된 경우 오류를 포함하거나 nil입니다.
Delete
원장에서 자산을 삭제합니다.
func Delete(Id string) (interface{}, error)
매개변수:
  • ID (string) - 원장에서 삭제해야 하는 자산의 ID입니다.
반환값:
  • interface {} - map[string]interface{} 형식으로 삭제 중인 자산을 포함합니다.
GetByRange
ID 범위별 자산 목록을 반환합니다.
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
매개변수:
  • startkey (string) - 필요한 객체 범위의 시작 ID입니다.
  • endkey (string) - 필요한 객체 범위의 끝입니다.
  • asset interface - (선택사항) 참조에 의해 전달되는 자산 배열이 비어 있습니다. 이 배열은 이 메소드의 결과를 포함합니다. 유형별 결과가 필요한 경우 사용됩니다.
반환값:
  • []map[string]interface{} - 이 배열에는 원장에서 가져온 자산 목록이 포함됩니다. 이 배열을 통해 반복되는 객체에 액세스하고 객체를 map[string]interface{}로 검증하고 유틸리티를 사용하여 자산 객체로 변환할 수 있습니다.
  • error - 반환된 경우 오류를 포함하거나 nil입니다.
GetByRangeWithPagination
GetByRangeWithPagination 메소드는 {chaincodeName}.model.ts의 구체적 Model 클래스에 의해 상속되는 OchainModel 클래스의 정적 메소드입니다.
그러면 페이지 크기 및 책갈피별로 필터링된 startIdendId 범위 사이의 자산 목록이 반환됩니다. 이 메소드는 내부적으로 Hyperledger Fabric GetStateByRangeWithPagination 메소드를 호출합니다.
modelName 매개변수를 제공하지 않으면 메소드는 Promise<Object [ ] >를 반환합니다. modelName 매개변수가 제공된 경우 이 메소드는 호출자 Model 유형으로 변환을 처리합니다. 다음 예에서 결과 배열의 유형은 Supplier입니다. 원장에서 반환된 자산이 Model 유형이 아닌 경우 목록에 포함되지 않습니다. 이 검사는 Model 클래스의 읽기 전용 assetType 등록 정보에 의해 수행됩니다.
페이지 크기 및 책갈피로 필터링된 startIdendId 범위 사이의 모든 자산을 반환하려면 일반 컨트롤러 메소드 getAssetsByRange를 사용합니다.
func (m *Model) GetByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string, asset ...interface{}) ([]map[string]interface{}, error) 
매개변수:
  • startkey : string - 범위의 시작 키입니다. 범위에 포함됩니다.
  • endkey : string - 범위의 종료 키입니다. 범위에서 제외됩니다.
  • pageSize : number - 질의의 페이지 크기입니다.
  • Bookmark : string - 질의의 책갈피입니다. 출력은 이 책갈피에서 시작됩니다.
  • asset interface - (선택사항) 참조에 의해 전달된 자산의 빈 배열입니다. 이 배열은 이 메소드의 결과를 포함합니다. 이 매개변수를 사용하여 유형별 결과를 얻을 수 있습니다.
반환값:
  • []map[string]interface{} - 원장에서 검색된 자산 목록을 포함하는 배열입니다. 이 배열을 반복하고 객체를 map[string]interface{}로 검증하고 자산 객체로의 변환 유틸리티를 사용하여 객체에 액세스할 수 있습니다.
  • error - 오류가 반환되면 오류를 포함하고, 그렇지 않으면 nil을 포함합니다.
GetHistoryById
지정된 ID의 자산 기록을 반환합니다.
func GetHistoryByID(Id string) ([]interface{}, error)
매개변수:
  • ID (string) - 내역이 필요한 자산의 ID입니다.
반환값:
  • []interface{} - 이 슬라이스에는 map[string]interface{} 슬라이스 형태로 원장에서 가져온 자산의 내역이 포함됩니다. 이 슬라이스를 반복하고 객체를 map[string]interface{}로 검증하고 유틸리티를 사용하여 자산 객체로 변환하는 방식으로 각 내역 요소에 액세스할 수 있습니다.
  • error - 관찰된 경우 오류를 포함합니다.
Query
질의 방법은 원장을 통해 SQL/Couch DB 질의를 실행합니다. 이 방법은 Oracle Blockchain Platform의 원격 배포에만 지원됩니다. 이 방법은 원장에서 SQL 질의를 실행하는 일반적인 방법입니다.
func Query(queryString string) ([]interface{}, error)
매개변수:
  • queryString (string) - 질의 문자열을 입력합니다.
반환값:
  • []interface{} - 질의 출력이 포함됩니다. 결과는 인터페이스 슬라이스 형식입니다. 슬라이스를 반복하고 요소를 적절한 유형으로 변환하여 사용해야 합니다.
  • error - 관찰된 경우 오류를 포함합니다.
QueryWithPagination
질의 방법은 페이지 크기 및 책갈피별로 필터링된 원장을 통해 SQL/Couch DB 질의를 실행합니다. 이 방법은 Oracle Blockchain Platform의 원격 배포에만 지원됩니다. 이 방법은 원장에서 SQL 질의를 실행하는 일반적인 방법입니다.
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
매개변수:
  • queryString (string) - 풍부한 SQL/Couch DB 쿼리.
  • pageSize : number - 질의의 페이지 크기입니다.
  • bookmark : string - 질의의 책갈피입니다. 출력은 이 책갈피에서 시작됩니다.
반환값:
  • []interface{} - 질의 출력이 포함됩니다. 결과는 인터페이스 슬라이스 형식입니다. 슬라이스를 반복하고 요소를 적절한 유형으로 변환하여 사용해야 합니다.
  • error - 관찰된 경우 오류를 포함합니다.
InvokeCrossChaincode
체인 코드에서 이 메소드를 사용하여 다른 체인 코드에서 함수를 호출할 수 있습니다. 두 체인코드는 동일한 피어에 설치되어야 합니다.
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
매개변수:
  • chaincodeName - 호출할 체인 코드의 이름입니다.
  • methodName - 체인 코드에서 호출할 메소드의 이름입니다.
  • arg - 호출 메소드의 인수입니다.
  • channelName - 호출할 체인 코드가 있는 채널입니다.
반환값:
  • interface{} - 세 개의 키가 포함된 map[string]interface{} 객체를 반환합니다.
    • isValid - 호출이 적합한 경우 true입니다.
    • payload - 교차 체인 코드 호출에 의해 JSON 객체로 반환된 출력입니다.
    • message - 체인 코드 간 호출에 의해 UTF-8 형식으로 반환된 메시지입니다.
반환 값 예제:
{
      "isValid": true,
      "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
      "payload": {
                  "AccountId": "oaccount~6b83b8ab931f99442897dd04cd7a2a55f808686f49052a40334afe3753fda4c4",
                  "AssetType": "oaccount",
                  "BapAccountVersion": 0,
                  "NoOfNfts": 0,
                  "OrgId": "appdev",
                  "TokenType": "nonfungible",
                  "UserId": "user2"
      }
}
InvokeChaincode
체인 코드에서 이 메소드를 사용하여 다른 체인 코드에서 함수를 호출할 수 있습니다. 두 체인코드는 동일한 피어에 설치되어야 합니다.
func InvokeChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
매개변수:
  • chaincodeName - 호출할 체인 코드의 이름입니다.
  • methodName - 체인 코드에서 호출할 메소드의 이름입니다.
  • arg - 호출 메소드의 인수입니다.
  • channelName - 호출할 체인 코드가 있는 채널입니다.
반환값:
  • interface{} - 세 개의 키가 포함된 map[string]interface{} 객체를 반환합니다.
    • isValid - 호출이 적합한 경우 true입니다.
    • payload - 체인 코드 간 호출에서 반환된 출력(UTF-8 형식)입니다.
    • message - 체인 코드 간 호출에 의해 UTF-8 형식으로 반환된 메시지입니다.
반환 값 예제:
{
    "isValid": true,
    "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
    "payload": "{\"AssetType\":\"oaccount\",\"AccountId\":\"oaccount~c6bd7f8dcc339bf7144ea2e1cf953f8c1df2f28482b87ad7895ac29e7613a58f\",\"UserId\":\"user1\",\"OrgId\":\"appdev\",\"TokenType\":\"nonfungible\",\"NoOfNfts\":0,\"BapAccountVersion\":0}"
} 

복합 키 메소드

GenerateCompositeKey
이 메소드는 indexName 및 인수에 제공된 속성을 기반으로 조합 키를 생성하고 반환합니다.
func GenerateCompositeKey(indexName string, attributes []string)
(string, error)
매개변수:
  • indexName (string) - 조합 키의 객체 유형입니다.
  • attrbutes ([]string) - 조합 키가 형성되어야 할 자산의 속성입니다.
반환값:
  • string - 조합 키 결과가 포함됩니다.
  • error - 관찰된 경우 오류를 포함합니다.
GetByCompositeKey
이 메소드는 매개변수에 제공된 키 및 열과 일치하는 자산을 반환합니다. index 매개변수는 stub 메소드 SplitCompositeKey의 배열에서 반환된 키의 인덱스를 나타냅니다.
내부적으로 이 메소드는 Hyperledger Fabric의 getStateByPartialCompositeKey, splitCompositeKeygetState를 호출합니다.
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
매개변수:
  • key (string) - 조합 키를 생성하는 중 제공된 객체 유형입니다.
  • column ([]string) - 조합 키를 사용하여 원장을 질의해야 하는 속성의 조각입니다.
  • index(int) - 속성의 인덱스입니다.
반환값:
  • Interface{} - 이 메소드의 결과인 자산 목록을 포함합니다.
  • error - 오류가 있는 경우 포함합니다.

스텁 방법

GetNetworkStub
이 방법은 Hyperledger Fabric chaincodeStub을 반환합니다.
GetNetworkStub 메소드를 호출하여 shim stub에 액세스할 수 있습니다. 이렇게 하면 자산과 직접 작업하는 고유한 구현을 작성하는 데 도움이 됩니다.
func GetNetworkStub() shim.ChaincodeStubInterface
매개변수:
  • 없음
반환값:
  • shim.ChaincodeStubInterface - Hyperledger Fabric 체인코드 스텁입니다.

기타 방법

  • GetTransactionId()
  • GetTransactionTimestamp()
  • GetChannelID()
  • GetCreator()
  • GetSignedProposal()
  • GetArgs()
  • GetStringArgs()
  • GetCreatorMspId()
  • GetId
GetTransactionId
현재 체인코드 호출 요청에 대한 트랜잭션 ID를 반환합니다. 트랜잭션 ID는 채널 범위 내에서 트랜잭션을 고유하게 식별합니다.
func GetTransactionId() string
매개변수:
  • 없음
반환값:
  • string - 필요한 트랜잭션 ID를 포함합니다.
GetTransactionTimestamp
트랜잭션이 생성된 시간 기록을 반환합니다. 이는 거래 ChannelHeader에서 가져오므로 클라이언트의 타임스탬프를 나타내며 모든 보증인 간에 동일한 값을 갖습니다.
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
매개변수:
  • 없음
반환값:
  • timestamp.Timestamp - 필요한 시간 기록을 포함합니다.
  • error - 오류가 있는 경우 포함합니다.
GetChannelID
처리할 체인 코드에 대한 제안의 채널 ID를 반환합니다.
func GetChannelID() string
매개변수:
  • 없음
반환값:
  • string - 필요한 채널 ID를 문자열로 포함합니다.
GetCreator
체인 코드 호출 제출자의 ID 객체를 반환합니다.
func GetCreator() ([]byte, error)
매개변수:
  • 없음
반환값:
  • []byte - 직렬화된 필수 ID 객체를 포함합니다.
  • error - 오류가 있는 경우 포함합니다.
GetSignedProposal
서명된 트랜잭션 제안의 완전히 디코딩된 객체를 반환합니다.
func GetSignedProposal() (*peer.SignedProposal, error)
매개변수:
  • 없음
반환값:
  • *peer.SignedProposal - 서명된 필수 제안 객체를 포함합니다.
  • error - 오류가 있는 경우 포함합니다.
GetArgs
인수를 체인코드 호출 요청의 문자열 배열로 반환합니다.
func GetArgs() [][]byte
매개변수:
  • 없음
반환값:
  • [][]byte - 전달된 인수를 포함합니다.
GetStringArgs
체인코드 Init 및 Invoke에 대한 인수를 문자열 배열로 반환합니다.
func GetStringArgs() []string
매개변수:
  • 없음
반환값:
  • []string - 필요한 인수를 문자열 배열로 포함합니다.
GetCreatorMspId
호출 ID의 MSP ID를 반환합니다.
func GetCreatorMspId() string
매개변수:
  • 없음
반환값:
  • string - 호출 ID의 MSP ID를 반환합니다.
GetId
자산의 파생 키가 ID인 경우 이 방법을 사용하여 파생 ID를 가져올 수 있습니다. 파생 키에 %t(시간 기록)이 포함된 경우 이 메소드는 오류를 반환합니다.
매개변수:
  • object - 객체에는 파생된 키가 종속된 모든 속성이 포함되어야 합니다.
반환값:
  • 파생된 키를 문자열로 반환합니다.
예제:
func (t *Controller) CustomGetterForSupplier(License string, Name string)(interface{}, error){
   var asset Supplier
   asset.License = License
   asset.Name = Name
   id,err := t.Ctx.Model.GetId(&asset)

   if err !=nil {
      return nil, fmt.Errorf("error in getting ID %v", err.Error())
   }
   return t.GetSupplierById(id)
}

유틸리티 패키지

유틸리티 패키지의 다음 메소드가 유용할 수 있습니다.

Util.CreateModel
제공된 JSON 문자열을 구문분석하고 제공된 유형의 자산 객체를 생성합니다.
func CreateModel(obj interface{}, inputString string) error
매개변수:
  • inputString (string) - 객체가 생성될 입력 JSON 문자열입니다.
  • obj (interface{}) - JSON 문자열에서 생성될 객체의 참조입니다. 이 객체는 검증기 태그에 따라 검증된 생성된 모델을 저장합니다.
반환값:
  • error - 자산을 생성하거나 검증하는 동안 발견된 모든 오류를 포함합니다.
util.ConvertMapToStruct
제공된 맵을 제공된 유형의 객체로 변환합니다.
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
매개변수:
  • inputMap (map[string](interface{})) - 자산 객체로 변환해야 하는 맵입니다.
  • resultStruct (interface{}) - 맵에서 생성해야 하는 필수 자산 객체의 참조입니다. 필요한 결과 자산 객체를 포함합니다.
반환값:
  • error - 자산을 생성하거나 검증하는 동안 발견된 모든 오류를 포함합니다.

토큰 SDK 방법은 블록체인 앱 빌더를 사용한 토큰화 지원에서 항목을 참조하십시오.

제어 장치

Controller.go 파일은 자산에 대한 CRUD 및 사용자정의 메소드를 구현합니다.

클래스, 함수 또는 파일을 원하는 만큼 만들 수 있지만 체인코드 구조체에 정의된 메서드만 외부에서 호출할 수 있으며 나머지 메서드는 숨겨집니다.

자동으로 생성된 메소드

입력 사양 파일에 설명된 대로 사양 파일에서 생성할 CRUD 메소드를 지정할 수 있습니다. 예를 들어, 모든 메소드를 생성하도록 선택한 경우 결과는 다음과 유사합니다.

//	
//Supplier
//	
func (t *ChainCode) CreateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputString)
    if err != nil {
        return nil, err   
    }
    return model.Save(&obj)
}

func (t *ChainCode) GetSupplierById(id string) (interface{}, error) {
    asset, err := model.Get(id) 
    return asset, err
}

func (t *ChainCode) UpdateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputstring)
    if err != nil {   
        return nil, err
    }
return model.Update(&obj)
}

func (t *ChainCode) DeleteSupplier(id string) (interface{}, error) { 
    return model.Delete(id)
}

func (t *ChainCode) GetSupplierHistoryById(id string) (interface{}, error) { 
    historyArray, err := model.GetHistoryByld(id) 
    return historyArray, err
}

func (t *ChainCode) GetSupplierByRange(startkey string, endKey string) (interface{}, error) { 
    assetArray, err := model.GetByRange(startkey, endKey) 
    return assetArray, err
}

사용자정의 방법

예제 사양 파일에서 생성된 사용자정의 메소드는 다음과 같습니다.

executeQuery는 SQL 서식 있는 질의를 호출하는 방법을 보여줍니다. 인수에 대한 검증자는 사양 파일에 지정된 인수의 유형에 따라 Blockchain App Builder에 의해 자동으로 추가됩니다.

업무 논리에 따라 기능을 구현할 수 있습니다. 사용자 메서드를 추가하는 경우 제어기 파일에 추가합니다. 컨트롤러 파일 대신 라이브러리에 사용자 정의 메소드를 추가하면 동기화 또는 체인코드 업그레이드 프로세스 중 라이브러리 폴더 내용이 업데이트될 때 변경사항이 손실됩니다.

//	
//Custom Methods
//			
/*
*	BDB sql rich queries can be executed in OBP CS/EE.
*	This method can be invoked only when connected to remote OBP CS/EE network.
*/
func (t *ChainCode) ExecuteQuery(inputQuery string) (interface{}, error) { 
    resultArray, err := model.Query(inputQuery) 
    return resultArray, err
}

func (t *ChainCode) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) {
    return nil, nil
}

func (t *ChainCode) GetRawMaterialFromSupplier(manufacturerId string, supplierId string, rawMaterialSupply int) (interface{} error) { 
    return nil, nil
}

Func (t *ChainCode) CreateProducts(manufacturerId string, rawMaterialConsumed int, productsCreated int) (interface{}, error) { 
    return nil, nil
}

func (t *ChainCode) SendProductsToDistribution() (interface{}, error) { 
    return nil, nil
}
Go 체인코드의 경우 모든 사용자 정의 메소드는 빈 인터페이스, 오류의 두 값을 반환해야 합니다. 예:
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) { 
    return nil, nil
}

초기화 메소드

사용자 정의 Init 메소드가 컨트롤러에 빈 정의와 함께 제공됩니다. Blockchain App Builder를 사용하여 배포 또는 업그레이드하는 경우 Init 메서드가 자동으로 호출됩니다. Hyperledger Fabric v1.4.7 플랫폼의 Oracle Blockchain Platform 콘솔에서 배포하거나 업그레이드하는 경우 Init 메소드도 자동으로 호출됩니다. Hyperledger Fabric v2.x 플랫폼의 Oracle Blockchain Platform 콘솔에서 배포하거나 업그레이드하는 경우 Init 메소드를 수동으로 호출해야 합니다. Postman과 같은 타사 도구를 사용하여 Init 메소드를 수동으로 호출할 수 있습니다.

type Controller struct {
}
func (t *Controller) Init(args string) (interface{}, error) 
    { return nil, nil
}

이 시점에서 응용 프로그램 상태를 초기화하려면 이 방법을 사용하면 됩니다.