May 1, 2021 追記
現時点で実装が進んでいるコードと、本文の記述との間に不整合がある。コードのほうが正なので、読む前に、注意。

(本文は XMPIP 発行に向けてのメモであり、常に変更される可能性があり、いつかは削除される)

動機

Monaparty にも non-fungible なアセットが欲しい。

Counterparty のアセットは(現時点のモナパーティも)、技術的には non-fungible なアセットをアトミックに生成できない。

全てのアセットは発行時点では rare fungible である。 1枚発行の後 lock を経て non-fungible となり得る。アトミックでない処理には、事故や裏切り発生の余地がある。

発行のアトミック性を無視してよいのであれば subasset を使い NFT を模擬する方法はある。しかし、subasset の発行には named asset が必要であり、その名前空間は狭い。より広い名前空間を持つ numeric asset や subasset に対する NFT 発行の方法を用意すべきである。

方法

subasset の亜種として、non-fungible アセットを実現する。

まず、アセット・オブジェクトに asset_group 属性を追加する。

既存のアセットタイプ named, sub, numeric を持つアセットの asset_group は、null である。

non-fungible アセットの発行時には、このアセットを代表する asset_group の指定が求められる。 asset_group として指定可能なアセットは、下記の条件を満たしたものである。

  • 既に発行済である。
  • issuance 時点で、発行者が所有権を持つ。

上記条件は、subasset において指定できる主アセットと類似だが、numeric asset も指定できる点が異なる(拡張されている)。

モナパーティのコントラクトは、発行された non-fungible を、 numeric アセットして扱う。

subasset の本質は asset_longname 付き numeric asset である。numeric asset は non-fungible アセットを代表できる。よって subasset を asset_group とする non-fungible アセットも発行可能である。
ただし subasset を代表とする non-fungible アセットを活用する場合には、下記の点で留意が必要である。

  • subasset を代表する non-fungible アセットの
    asset_group には、 asset_longname ではなく、 numeric 形式で格納される。

発行後、任意のアセットについて non-fungible であるかは、下記列挙するいずれかの方法で確認できる。

  • アセット・オブジェクトの asset_group に文字列がある。
  • アセットの最新 issuance において fungible が true である。

変更

メッセージの変更

issuance メッセージに non-fungible フラグを追加する。

データベースの変更

  • assets テーブルに asset_group (TEXT) を追加する。
  • issuances テーブルに fungible (BOOL) を追加する。

API の変更

create_issuance メソッドに fungible フラグを追加する。デフォルトは true である。

処理の変更

validate

fungible == false である create_issuance において、validator は、下記のように処理を行う。

  • 発行枚数が1でない場合には、エラーとする。(ポカミス避け)
  • subasset 発行における要件を満たさない場合は、エラーとする。

compose

subasset 発行時のメッセージと同じフォーマットとするが、non-fungible フラグを立てる。

parse

従前 asset_longname としていた変数は alias_name と変更する。

fungible == false で validate に通ったメッセージは、subasset と同等の処理を行う。ただし、下記の点で subasset とは異なる挙動を取る。

  • alias_name に相当する文字列は asset_longname ではなく、asset_group に格納する。
  • 発行時点でアセットをロックし追加発行不可とする。

互換性

non-fungible アセットは、モナパーティの全てのコントラクトにおいて numeric アセットと同じ扱いを受ける。後方互換性は担保されている。

API を利用するアプリケーションにも破壊的な非互換性はもたらさないが、non-fungible を積極的に利用するアプリケーションでは、アセット名の表示において asset_name や asset_longname だけでなく asset_group の活用を検討する余地がある。 asset_name のみでは 1 枚発行ロック済みの numeric アセットとしか視認できない。

(asset_group が存在するアセットの場合に get_ 系 API に追加情報を与える案も検討したが、Counterparty API の「内部データベースの内容をなるべくそのまま提示する」という暗黙の方針に沿った。Counterblock API では別のアプローチも採り得る。)