1. 체인코드 구조
# go.mod 모듈을 사용해서 chaincode/chain1.go와 연결
하이퍼레저 패브릭(Hyperledger Fabric) v2.2 - 체인코드 go.mod 설정
0. Golang Package & Module 고랭의 패키지는 디렉토리의 개념으로 생각 다른패키지를 import하기 위해서 go.mod 모듈을 사용하여 패키지에 접근하는 방법을 소개한다. 1. 체인코드 디렉토리 구조 chaincode디
yoon1seok.tistory.com
2. 개발하고자 하는 체인코드 기능
기능을 추가하고 테스트하기 위해 test-network의 기본 smartcontract.go 활용해서 사용
- 생성시 최초 데이터 생성
- 특정 데이터 값 전체 조회
- 데이터 생성
- 단일조회
2-1. 생성시 최초 데이터 생성
생성하고자 하는 데이터 스키마 구조
// Asset describes basic details of what makes up a simple asset
type Asset struct {
User_id string `json:"ID"`
Pc_id string `json:"color"`
Date string `json:"size"`
Event string `json:"owner"`
SC string `json:"sc`
}
InitLedger 함수
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
// a := []list{data1,data2}
assets := []Asset{
{User_id: "sc-1-1", Pc_id: "PC-3504", Date: "03/11/2011 07:55:15", Event: "logon", SC: "1"},
{User_id: "sc-1-2", Pc_id: "PC-3504", Date: "03/11/2011 08:55:15", Event: "Device", SC: "1"},
{User_id: "sc-1-3", Pc_id: "PC-3504", Date: "03/11/2011 09:55:15", Event: "HTTP", SC: "1"},
{User_id: "sc-2-1", Pc_id: "PC-8844", Date: "03/11/2012 07:55:15", Event: "logon", SC: "2"},
{User_id: "sc-2-2", Pc_id: "PC-8844", Date: "03/11/2012 08:55:15", Event: "HTTP", SC: "2"},
{User_id: "sc-2-3", Pc_id: "PC-8844", Date: "03/11/2012 09:55:15", Event: "email", SC: "2"},
}
for _, asset := range assets {
assetJSON, err := json.Marshal(asset)
fmt.Println(assetJSON)
if err != nil {
return err
}
// Putstate(Key, Value)
err = ctx.GetStub().PutState(asset.User_id, assetJSON)
if err != nil {
return fmt.Errorf("failed to put to world state. %v", err)
}
}
return nil
}
shim package의 Putstate(Key, value)
2-2. 특정 데이터 값 전체 조회
GetAllAssets함수
sc_num을 매개변수로 받아 SC와 동일한 값을 조회해 반환
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface, sc_num string) ([]*Asset, error) {
// range query with empty string for startKey and endKey does an
// open-ended query of all assets in the chaincode namespace.
resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil {
return nil, err
}
defer resultsIterator.Close()
var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
var asset Asset
err = json.Unmarshal(queryResponse.Value, &asset)
if err != nil {
return nil, err
}
// asset.SC의 값이 매개변수 값과 같을경우 배열에 추가
if asset.SC == sc_num{
assets = append(assets, &asset)
}
}
return assets, nil
}
결과반환 명령어
peer chaincode query \
> -C mychannel \
> -n new5 \
> -c '{"Args":["GetAllAssets","1"]}'
SC '1' 반환
SC '2' 반환
2-3. 데이터 생성
CreateAsset함수
데이터 구조에 맞춰 원하는 데이터를 삽입
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, user_id string, pc_id string, date string, event string, sc string) error {
exists, err := s.AssetExists(ctx, user_id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("the asset %s already exists", user_id)
}
asset := Asset{
User_id: user_id,
Pc_id: pc_id,
Date: date,
Event: event,
SC: sc,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(user_id, assetJSON)
}
데이터 생성 명령어
# 체인코드 Invoke
peer chaincode invoke \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile $ORDERER_CA \
-C mychannel \
-n new \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
-c '{"function":"InitLedger","Args":["sc-3-1", "PC-9999", "05/11/2022 09:55:15", "Login", "3"]}'
2-4. 단일조회
ReadAsset함수
// ReadAsset returns the asset stored in the world state with given id.
func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, user_id string) (*Asset, error) {
assetJSON, err := ctx.GetStub().GetState(user_id)
if err != nil {
return nil, fmt.Errorf("failed to read from world state: %v", err)
}
if assetJSON == nil {
return nil, fmt.Errorf("the asset %s does not exist", user_id)
}
var asset Asset
err = json.Unmarshal(assetJSON, &asset)
if err != nil {
return nil, err
}
return &asset, nil
}
참고자료
1) shim Package Documents
https://pkg.go.dev/github.com/hyperledger/fabric-chaincode-go/shim#ChaincodeStub.GetState
shim package - github.com/hyperledger/fabric-chaincode-go/shim - Go Packages
Package shim provides APIs for the chaincode to access its state variables, transaction context and call other chaincodes. Constants func CreateCompositeKey(objectType string, attributes []string) (string, error) func Error(msg string) pb.Response func Get
pkg.go.dev
2) Contractapi Package Documents
contractapi package - github.com/hyperledger/fabric-contract-api-go/contractapi - Go Packages
Documentation ¶ View Source const SystemContractName = "org.hyperledger.fabric" SystemContractName the name of the system smart contract This section is empty. This section is empty. Contract defines functions for setting and getting before, after and unk
pkg.go.dev
'보안 및 블록체인 > 블록체인' 카테고리의 다른 글
하이퍼레저 패브릭(Hyperledger Fabric) v2.2 - #6 Hyperledger Explorer v1.1.8 구축(Docker기반) (0) | 2022.09.08 |
---|---|
하이퍼레저 패브릭(Hyperledger Fabric) v2.2 - #5 node.js Application구축 (0) | 2022.08.31 |
블록체인 보안이슈 및 위협요소 정리 51%공격 #2 (0) | 2022.08.16 |
블록체인 보안이슈 및 위협요소 정리 #1 - [블록체인] (0) | 2022.08.12 |
블록체인 암호화폐, 포크, 플랫폼코인 정리 - [블록체인] (1) | 2022.08.11 |