0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Hyperledger Fabricのチェーンコードで`getStateByRange` の仕様が微妙っぽかったので調べてみたら微妙だった

Posted at

Hyperledger Fabricのチェーンコードを実装していて気になったのでメモ。

Hyperledger Fabricってなんぞ?という方はこちらをご参考ください。

Amazon Managed BlockchainがリリースされたのでHyperledger Fabricも合わせて情報をまとめてみた - Qiita
https://qiita.com/kai_kou/items/5a968f42c5f96296f6fe

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita
https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e

getStateByRange メソッドの範囲指定でendKey は取得範囲に入らない

ひとまず再現コード抜粋。TypeScriptで実装しています。

TypeScriptを利用した実装方法については下記をご参考ください。

Hyperledger Fabricのチェーンコード(Node.js)をTypeScriptで実装できるようにしてみた - Qiita
https://qiita.com/kai_kou/items/0726c9a462bdcaf3856c

チェーンコード実装(抜粋)
()

  async Invoke(stub: ChaincodeStub): Promise<ChaincodeResponse> {
    let ret = stub.getFunctionAndParameters();
    const {fcn, params} =  stub.getFunctionAndParameters();
    console.info(ret);

    const method = (this as any)[fcn];
    if (!method) {
      throw new Error('Received unknown function ' + ret.fcn + ' invocation');
    }

    try {
      let payload = await method(stub, params);
      return Shim.success(payload);
    } catch (err) {
      return Shim.error(err);
    }
  }

  async queryByRange(stub: ChaincodeStub, args: string[]): Promise<Buffer> {
    if (args.length != 2) {
      throw new Error('Incorrect number of arguments.');
    }

    let startKey = args[0];
    let endKey = args[1];
    let results = [];

    let iterator = await stub.getStateByRange(startKey, endKey);
    while(true) {
      const res = await iterator.next();
      if (res.value && res.value.value.toString()) {
        let item = JSON.parse(res.value.value.toString('utf8'));
        results.push(item);
      }

      if (res.done) {
        await iterator.close();
        return Buffer.from(JSON.stringify(results));
      }
    }
  }
()
  • value.value とか気持ち悪いなぁ
  • .toString('utf8') って'utf8' を指定しないと'JSON.parse' できなくてハマります。

ステートDBには以下のようなデータが保存されている前提です。

ステートDBの中身
[
  {"id":"hoge01","hoge":"hoge"},
  {"id":"hoge02","hoge":"hoge"},
  {"id":"hoge03","hoge":"hoge"}
]

で、チェーンコードのqueryByRange を実行して情報を取得してみます。
※Fablic CLIで実行、パラメータはいろいろ省略しています。

> docker exec cli peer chaincode query \
  -o $ORDERER -C mychannel -n $cc_name \
  -c '{"function":"queryByRange","Args":["hoge01", "hoge01"]}'

[]

あれ取れない。

> docker exec cli peer chaincode query \
  -o $ORDERER -C mychannel -n $cc_name \
  -c '{"function":"queryByRange","Args":["hoge01", "hoge02"]}'

[{"id":"hoge01","hoge":"hoge"}]

お、まさか。。。

> docker exec cli peer chaincode query \
  -o $ORDERER -C mychannel -n $cc_name \
  -c '{"function":"queryByRange","Args":["hoge01", "hoge03"]}'

[{"id":"hoge01","hoge":"hoge"},{"id":"hoge02","hoge":"hoge"}]

なるほど。endKey は取得対象外なのね。。。

気になって仕様を確認してみたら確かにそういう仕様でした。

Hyperledger Fabric Node.js Contract and Shim Class: ChaincodeStub
https://fabric-shim.github.io/master/fabric-shim.ChaincodeStub.html

Returns a range iterator over a set of keys in the ledger. The iterator can be used to iterate over all keys between the startKey (inclusive) and endKey (exclusive).

Google翻訳

元帳の一連のキーに対する範囲反復子を返します。 反復子はstartKey(これを含む)とendKey(これを含まない)の間のすべてのキーを反復処理するために使用できます。

endKey(これを含まない)

oh...
そうですか。

キーに数値を含めてインクリメントする場合ならまあ対応は楽ですが、キーにULIDを利用しようとしてたのでこれはちっと面倒な感じです。むむむぅ。

参考

Hyperledger Fabric Node.js Contract and Shim Class: ChaincodeStub
https://fabric-shim.github.io/master/fabric-shim.ChaincodeStub.html

Amazon Managed BlockchainがリリースされたのでHyperledger Fabricも合わせて情報をまとめてみた - Qiita
https://qiita.com/kai_kou/items/5a968f42c5f96296f6fe

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita
https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e

Hyperledger Fabricのチェーンコード(Node.js)をTypeScriptで実装できるようにしてみた - Qiita
https://qiita.com/kai_kou/items/0726c9a462bdcaf3856c

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?