Hyperledger fabci の Smart Contract(スマートコントラクト)を調査

Hyperledger Fabric

前回Commercial Paperを動かしていて、スマコンの詳しい説明がなかったが以下に詳しく記載されているページを発見。

Smart Contract Processing

fabcarに比べて俄然複雑になっているのでこちらで確認する。

Contract class – コントラクトクラス

スマコンの本体であるコントラクトクラス。
fabric-contract-apiのContractを継承する。

const { Contract, Context } = require('fabric-contract-api');

class CommercialPaperContract extends Contract {...}

コンストラクタに以下のような形で、コントラクト名を入れる。この名前は重要で色々なところでこの文字列で参照される。

constructor() {
    super('org.papernet.commercialpaper');
}

Transaction definition – トランザクション定義

issueの定義は以下

async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {...}

以下のようなパラメータで呼び出す

Txn = issue
Issuer = MagnetoCorp
Paper = 00001
Issue time = 31 May 2020 09:00:00 EST
Maturity date = 30 November 2020
Face value = 5M USD

ctx は重要で transaction の 様々な情報を保持する。

Context

コントラクトクラスで以下のように指定すると、独自のContextを設定できる。

createContext() {
  return new CommercialPaperContext()
}

以下のようなものが独自のcontext。PaperListをcontextに追加している。
PaperListは全ての PaperNetのcommercial papersを保存や検索できる。

class CommercialPaperContext extends Context {

  constructor() {
    super();
    // All papers are held in a list of papers
    this.paperList = new PaperList(this);
}

Transaction logic – トランザクションロジック

以下のようなコード。
await ctx.paperList.addPaper(paper);
の部分はlistに追加してあとでまとめて取りやすくしている。
あとは感覚で感じる。

async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {

   // create an instance of the paper
  let paper = CommercialPaper.createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue);

  // Smart contract, rather than paper, moves paper into ISSUED state
  paper.setIssued();

  // Newly issued paper is owned by the issuer
  paper.setOwner(issuer);

  // Add the paper to the list of all similar commercial papers in the ledger world state
  await ctx.paperList.addPaper(paper);

  // Must return a serialized paper to caller of smart contract
  return paper.toBuffer();
}

Representing an object – オブジェクト

自分はこのStateクラスがいまいちよくわからなかった。

class CommercialPaper extends State {...}

stateのコンストラクタは以下。
ここではkeyを生成するパラメータを親クラスに渡していて、

    constructor(stateClass, keyParts) {
        this.class = stateClass;
        this.key = State.makeKey(keyParts);
        this.currentState = null;
    }
	
    static makeKey(keyParts) {
        return keyParts.map(part => JSON.stringify(part)).join(':');
    }

呼び出し元では以下のように渡している。

constructor(obj) {
  super(CommercialPaper.getClass(), [obj.issuer, obj.paperNumber]);
  Object.assign(this, obj);
}

このkeyは重要で、このデータを呼びだす際に必ず必要になる。

Access the ledger – 台帳にアクセスする

ここでPaperListの説明。

class PaperList extends StateList {

以下のようにPaperを追加する。ここでaddState。

async addPaper(paper) {
  return this.addState(paper);
}

親クラスのaddStateでは以下のようになってて key を作るときになっている。
createCompositeKeyを使ってkeyを作っている。

async addState(state) {
  let key = this.ctx.stub.createCompositeKey(this.name, state.getSplitKey());
  let data = State.serialize(state);
  await this.ctx.stub.putState(key, data);
}

これでlistを更新している。
結局このStateListで 台帳更新を全てしている。

Sponsored Link
コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


Hyperledger Fabric
Hyperledger fabric の byfn(Building Your First Network) を調べる

Hyperledger fabric でネットワークを作ろうとするときに byfn(Building …

Hyperledger Fabric
Hyperledger fabric – Fauxton を使用する

Hyperledger fabric で開発をしているとCouchDBの中身を簡単に参照したくなりま …

Hyperledger Fabric
Hyperledger fabric コマンドまとめ

よく使うHyperledger fabricコマンドのメモ[随時追記] Contents1 chai …