💭

TapyrusのCOLOR識別子について

2022/05/21に公開

Tapyrus の COLOR 識別子について

就活モチベが吹き飛んだので趣味に走ります。
Tapyrus の COLOR 識別子について、軽くまとめる記事。

COLOR 識別子とは

Tapyrus で発行される Token などに対し、識別子として付与される。OP_COLOR 以後に記載され、この opcode が出現することでスタック最上位の要素が COLOR 識別子として解釈される。また、その UTXO は任意のトークンを示すこととなる。

tapyrus-cli にて、トークンを発行すると

{
  "color": "c3fe867030bbc10029a2d11a7ef4719a4b6ef11e5bdbe0d023bd5a57732c48cf99",
  "txid": "28618a610078b4460b8302e3cc4a1e822b600024b399ede7815de9b830a4a83a"
}

のような形で出力が返るが、このcolor要素が COLOR 識別子である。

端的に Token の ID と解釈できる。

COLOR 識別子の構造

COLOR 識別子は 1 バイトの「タイプ(TYPE)」と 32 バイトの「ペイロード(PAYLOAD)」で構成される。タイプとペイロードの内容については以下の通り。

タイプ 定義 ペイロード
0xC1 Reissuable Token 発行 TX のインプットの scriptPubkey の SHA256 値
0xC2 Non-Reissuable Token 発行 TX のインプットの OutPoint の SHA256 値
0xC3 Non-Fungible Token 発行 TX のインプットの OutPoint の SHA256 値

発行 TX のインプットの OutPoint、つまり発行に用いる UTXO はチェーン上で一意であることから COLOR 識別子も一意なものであることがわかる。またこれにより UTXO 単体で COLOR 識別子を導出することが可能である。

COLOR 識別子を導出してみる

NFT の発行を例として導出してみる。

発行に用いる UTXO は以下とする。

UTXO-01

{
  "txid": "08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d",
  "vout": 0,
  "address": "1EjNxzpqw411MfY8i2HFLHjDvUERfR9VLj",
  "token": "TPC",
  "amount": 0.00050000,
  "label": "",
  "scriptPubKey": "76a914969d7101a2c2aa9b25310785ecfa837e1220df7988ac",
  "confirmations": 7660,
  "spendable": true,
  "solvable": true,
  "safe": true
},

タイプ

タイプについて、NFT を発行するので「0xC3(16 進数表示で c3 )」となる。

ペイロード

ペイロードの内容は「発行 TX のインプットの OutPoint の SHA256 値」である。

「発行 TX」は今から作る(tapyrus-cli issuetokenで生成される)トランザクションのこと。
「発行 TX のインプット」は発行に用いる UTXO。つまり上記で示したUTXO-01

UTXO-01のアウトポイントを導出する。導出には tapyrusrb を用いる。

$ irb

# tapyrusrbを導入
irb(main):001:0> require 'tapyrus'
=> true

# TXID
irb(main):002:0> txid = '08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d'
=> "08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d"

# index
irb(main):003:0> index = 0
=> 0

# TXIDからアウトポイントオブジェクトを生成
irb(main):004:0> out_point = Tapyrus::OutPoint.from_txid(txid, index)
=> #<Tapyrus::OutPoint:0x00000001045a6388 @index=0, @tx_hash="9d265f369d4df6d73b45111f2eacaf0827cb7f3c360587ada87390b2034c5008">

# アウトポイントオブジェクトのペイロードを取得
irb(main):005:0> out_point_payload = out_point.to_payload
=> "\x9D&_6\x9DM\xF6\xD7;E\x11\x1F.\xAC\xAF\b'\xCB\x7F<6\x05\x87\xAD\xA8s\x90\xB2\x03LP\b\x00\x00\x00\x00"

# アウトポイントのペイロードのSHA256値を求め、バイナリをHexに変換
irb(main):006:0> Tapyrus::sha256(out_point_payload).bth
=> "47b0042d422289833b5c74b169efcd54f16aa0de97085fb12c787222f7ded1c7"

これで COLOR 識別子の「ペイロード」が

47b0042d422289833b5c74b169efcd54f16aa0de97085fb12c787222f7ded1c7

であることが得られた。

COLOR 識別子

上記より、「タイプ」と「ペイロード」を組み合わせることで COLOR 識別子は

c347b0042d422289833b5c74b169efcd54f16aa0de97085fb12c787222f7ded1c7

であることがわかる。これで導出は完了。

確認

実際に発行し確認してみる。

$ tapyrus-cli issuetoken 3 1 08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d 0
{
  "color": "c347b0042d422289833b5c74b169efcd54f16aa0de97085fb12c787222f7ded1c7",
  "txid": "d8129bc7e3287bf38895cc203d8472d2e5888b94df189900b27f826d2f88eb4f"
}

導出した COLOR 識別子と同じものが出力された。導出は成功。

補足

ペイロードの導出を tapyrusrb に丸投げしたので使わずやってみる。SHA256 は流石にライブラリに頼る。

$ irb

# digestを導入
irb(main):001:0> require "digest"
=> true

# TXID
irb(main):002:0> txid = '08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d'
=> "08504c03b29073a8ad8705363c7fcb2708afac2e1f11453bd7f64d9d365f269d"

# index
irb(main):003:0> index = 0
=> 0

# OutPointの導出
irb(main):004:0> outpoint = [[txid].pack('H*').reverse, index].pack('a32V')
=> "\x9D&_6\x9DM\xF6\xD7;E\x11\x1F.\xAC\xAF\b'\xCB\x7F<6\x05\x87\xAD\xA8s\x90\xB2\x03LP\b\x00\x00\x00\x00"

# COLOR識別子の導出
irb(main):005:0> Digest::SHA256.digest(outpoint).unpack('H*').first
=> "47b0042d422289833b5c74b169efcd54f16aa0de97085fb12c787222f7ded1c7"

まとめると

OutPoint の導出は

TXID をバイナリに変換しエンディアンを反転したものとインデックスを pack する。pack テンプレート文字列の内容は「a: ASCII 文字, 32: 32 バイト, V: リトルエンディアンの 32bit 符号なし整数」

COLOR 識別子の導出は

OutPoint の SHA256 値を求め、16 進数文字列へ変換

以上

自己満のコーナーでした。理解するととても単純な構造。

参考

https://docs.ruby-lang.org/ja/latest/doc/pack_template.html

https://github.com/chaintope/tapyrusrb/blob/69ae2753841bf598c4e769f2f37cf4d067708ab1/lib/tapyrus/out_point.rb

GitHubで編集を提案

Discussion

ログインするとコメントできます