Counterparty プロトコルにおけるデータ保存方法

NO IMAGE

細かいことはドキュメントに書いてなかったので、コードを読んでまとめました。

まとめ

  • ビットコインのトランザクションの中にデータを入れている
  • 過去、色々なデータフォーマットがあった
  • エンコーディングの種類と、それぞれの種類でデータのバージョンがあった
  • 現在のデフォルトは、1-of-3 Multi-sig
  • Multi-sigの場合、2つのニセ公開鍵の中にデータを入れている

前提知識

  • 技術的な基礎知識
  • ビットコインの技術的知識
    • アドレスがどのように作られているのか? (pubkey, pukeyhash, UTXO, uxidなど)
    • Scriptというスクリプト言語を読める
    • Multi-sig の知識
    • Multi-sig そのScriptの形(OPコード)
  • Counterpartyの基礎知識
    • bitcoind, counterpartydがどう動いているのか、など

3つのエンコーディングの種類

  1. OP_RETURN として返す場合、opreturnをエンコーディング・パラメータとして指定する
    • bitcoind 0.9.0以降40byte制限があるので、全てのCounterpartyトランザクションが可能なわけではない
  2. multisigトランザクションとして返す場合、multisig をエンコーディング・パラメータとして指定する
    • auto は、今のところ multisig を指定しているのと同じ
  3. pubkeyhash の場合、 pubkey を指定する
    • UTXO setを汚染するので、推奨しない

ARC4

送信者の一つめのtxid(公開鍵ではない?)をパスワードとして、2つ目3つ目を暗号化する

データの保存方法

  • エンコード: UTF-8
  • プリフィックス: CNTRPRTY
  • 3種類のアウトプットがある
  • データは、ARC4で暗号化
  • 1-of-3 multi-sig
  • 3つの内の最初の2が、ニセ公開鍵(データ)
  • 残りの1つが、元の公開鍵
  • 0でパディング

Multi-sig の Script

こんな感じで構築

tx_script = OP_1                                   # OP_1
tx_script += op_push(33)                           # Push bytes of data chunk (fake) public key    (1/2)
tx_script += data_pubkey_1                         # (Fake) public key                  (1/2)
tx_script += op_push(33)                           # Push bytes of data chunk (fake) public key    (2/2)
tx_script += data_pubkey_2                         # (Fake) public key                  (2/2)
tx_script += op_push(len(dust_return_pubkey))  # Push bytes of source public key
tx_script += dust_return_pubkey                       # Source public key
tx_script += OP_3                                  # OP_3
tx_script += OP_CHECKMULTISIG                      # OP_CHECKMULTISIG

CounterpartyXCP/counterpartyd

データ・フォーマット

# Counterparty protocol
TXTYPE_FORMAT = '>I'

Python3 の struct.pack, struct.unpackを使っている
Python 上で文字列データとして表される C の構造体データの変換をする

issuranceの場合

FORMAT_1 = '>QQ?'
LENGTH_1 = 8 + 8 + 1
FORMAT_2 = '>QQ??If'
LENGTH_2 = 8 + 8 + 1 + 1 + 4 + 4 

データ・フォーマットが何回か変更された模様

FORMAT_1の場合

  1. Asset ID (整数)
  2. Quantity (整数)
  3. Divisible (bool)
            if len(message) != LENGTH_1:
                raise exceptions.UnpackError
            asset_id, quantity, divisible = struct.unpack(FORMAT_1, message)
            callable_, call_date, call_price, description = False, 0, 0.0, ''

FORMAT_2の場合

  1. Asset ID
  2. Quantity
  3. Divisible
  4. callable_
  5. call_date
  6. call_price
  7. Description
            asset_id, quantity, divisible, callable_, call_date, call_price, description = struct.unpack(curr_format, message)

            call_price = round(call_price, 6) # TODO: arbitrary

Counterpartyで使われるフォーマット

  • “>” は、ビッグエンディアンの意味
  • フォーマット文字列の前に整数がついているのは、繰り返し
フォーマット C での型 Python 型 標準のサイズ 備考
Q unsigned long long 整数型 8 (2), (3)
? _Bool 真偽値型(bool) 1 (1)
I unsigned int 整数型 4 (3)
f float 浮動小数点型 4 (4)
H unsigned short 整数型 2 (3)
s char[] 文字列

フォーマットのコード内の例

https://github.com/CounterpartyXCP/counterpartyd/blob/master/lib/messages/issuance.py#L13

トランザクションのパース

def parse_tx(db, tx): の中で mesage_type_idを取得して、そこからデータの形を決めて、パース

    if len(tx['data']) > 4:
        try:
            message_type_id = struct.unpack(config.TXTYPE_FORMAT, tx['data'][:4])[0]
        except struct.error:    # Deterministically raised.
            message_type_id = None
    else:
        message_type_id = None


上記の続き。
message_type_idを見て、メッセージの種類によって個別にパース

 # Protocol change.
    rps_enabled = tx['block_index'] >= 308500 or config.TESTNET

    message = tx['data'][4:]
    if message_type_id == send.ID:
        send.parse(db, tx, message)
    elif message_type_id == order.ID:
        order.parse(db, tx, message)
    elif message_type_id == btcpay.ID:
        btcpay.parse(db, tx, message)
    elif message_type_id == issuance.ID:
        issuance.parse(db, tx, message)
    elif message_type_id == broadcast.ID:
        broadcast.parse(db, tx, message)
    elif message_type_id == bet.ID:
        bet.parse(db, tx, message)
    elif message_type_id == dividend.ID:
        dividend.parse(db, tx, message)
    elif message_type_id == cancel.ID:
        cancel.parse(db, tx, message)
    elif message_type_id == rps.ID and rps_enabled:
        rps.parse(db, tx, message)
    elif message_type_id == rpsresolve.ID and rps_enabled:
        rpsresolve.parse(db, tx, message)
    elif message_type_id == publish.ID and tx['block_index'] != config.MEMPOOL_BLOCK_INDEX:
        publish.parse(db, tx, message)
    elif message_type_id == execute.ID and tx['block_index'] != config.MEMPOOL_BLOCK_INDEX:
        execute.parse(db, tx, message)
    elif message_type_id == destroy.ID:
        destroy.parse(db, tx, message)
    else:

API

  • 全ての create_ API は、署名されてないhexエンコードされた生トランザクション・stringを返す

メッセージ内コンポーネント

  • 送信元アドレス
  • 送信先アドレス(optional)
  • 送信元から送信先に送られるビットコインの量 (もし存在するなら)
  • 送信料金。ビットコイン。ブロックにトランザクションを入れるビットコインマイナーに支払われる。
  • ‘データ’。 特別に作られたトランザクション・アウトプットに組み込まれている。

Assetのデータ

Protocol Specification | Counterparty

  • Asset name
  • Asset ID
  • Description
  • Divisiblity
  • Callability
  • Call date (if callable)
    may be delayed with later issuances
  • Call price (if callable) (non‐negative) may be increased with later issuances

メッセージの種類

  • Send
  • Order
  • BTCPay
  • Issue
  • Broadcast
  • Bet
  • Dividend
  • Burn
  • Cancel

どのようにデータは保存されているか?

以下のフォーラムによると
Detect Counterparty transaction – Development & Technical Discussions on Counterparty Forums

  • UTF-8 の CNTRPRTY の prefixで始まる
  • データは、3種類のアウトプットに保存される
  • 全てのデータは、最初の送信者の公開鍵をパスワードにしたARC4の暗号化で難しくしている
  • Multisig の 1-of-3 の最初の公開鍵は送信者のもの
    • 残り2つの公開鍵は、エンコードされたデータ(0でパディング、length byte でプリフィックス)

コードを見る限り、上記一部間違っているようです。

Counterparty勉強会

プレゼン資料

英語です。以下の動画で日本語で説明しています。
http://crypto-tech.jp/counterparty-doc/#/

YouTube 動画

Counterparty技術勉強会 – YouTube

参考記事

CounterpartyのNumeric Assetを作成する – @yzono blog

検索用語

  • ビットコイン、カウンターパーティ
  • Bitcoin, Bitcoin 2.0, Counterparty, Counterwallet
     

免責事項

本記事に掲載されている記事の内容につきましては、正しい情報を提供することに務めてはおりますが、提供している記事の内容及び参考資料からいかなる損失や損害などの被害が発生したとしても、弊社では責任を負いかねます。実施される際には、法律事務所にご相談ください。

技術・サービス・実装方法等のレビュー、その他解説・分析・意見につきましてはblock-chani.jp運営者の個人的見解です。正確性・正当性を保証するものではありません。本記事掲載の記事内容のご利用は読者様個人の判断により自己責任でお願いいたします。

     

コンセンサス・ベイス(株)とブロックチェーン事業を行なってみませんか?

当サイトを運営するコンセンサス・ベイス株式会社は、2015年設立の国内で最も古いブロックチェーン専門企業です。これまでに、大手企業の顧客を中心に、日本トップクラスのブロックチェーンの開発・コンサルティング実績があります。

ブロックチェーンに関わるビジネスコンサル・システム開発・教育・講演などご希望でしたら、お気軽にお問い合わせください。

     
     

ブロックチェーン学習に最適の書籍の紹介

図解即戦力 ブロックチェーンのしくみと開発がこれ1冊でしっかりわかる教科書

ブロックチェーン イーサリアムへの入り口 第二版 (ブロックチェーン技術書籍)

本書は、ブロックチェーン技術に興味を持ったエンジニアや、その仕組みを学び、自分の仕事に活かしたいビジネスパーソンを対象にして、ブロックチェーンのコア技術とネットワーク維持の仕組みを平易な言葉で解説しています。この本を読んだうえで、実際にコードを書くような専門書、ブロックチェーンビジネスの解説書を読むことで、理解度が飛躍的に高まるでしょう。(はじめにより)

Othersカテゴリの最新記事