Waves - NFT(Non-Fungible Token)的なコントラクト

NFT(Non-Fungible Token)、代替不可能とかいうアレ。
Wavesにおいては数量=1でトークン発行すれば、それはNFTなわけだが。
そうではなくて、スマートコントラクト(SmartAccount)でやってみるという話。
SmartAccount = Ethereumでいうところのコントラクトアドレスとかいうやつ。たぶん。

何ができれば良いか

  • トークン識別子と所有者が 1対1 対応
  • 所有者のみが別アカウントへ譲渡できる

RIDEとDapp

  • 識別子と持ち主アカウントの対応づけ
    -> まんまDataTransaction (token-id, publickey)
  • 所有者の更新
    -> 現所有者publickeyの署名で同Datatエントリを更新

ということで、以下コントラクトで大枠実現できそうだ

match tx {
  case dtx: DataTransaction =>
    # SmartAccountのDataとして(key, value) = (token-id, 現所有者公開鍵)で管理されている
    # 現所有者の公開鍵を得る
    let owner = getBinary(dtx.sender, dtx.data[0].key)

    # 持ち主なしのとき、新規発行。 発行アカウントがそれを行える
    let signer = if isDefined(owner) then extract(owner) else base58’<トークン発行用アカウントの公開鍵>’

    # 余分なもののないこと かつ 現所有者が署名していること
    size(dtx.data) == 1 && sigVerify(tx.bodyBytes, tx.proofs[0], signer)

    # dtx.data[0].valueに次の持ち主が格納されている
    # そのアカウントとのマルチシグにした方が良いかもしれない
    # && sigVerify(tx.bodyBytes, tx.proofs[1], dtx.data[0].value)
    # その他、追加の条件(特定の参加者のみ)とかあれば、それも合わせて確認できる
  case _ => false
}

一番最初のトークン発行工程について、
上の例では該当Dataエントリが存在しなかったら新規発行とみなし、
発行用の専用アカウントの署名でトランザクション発行ということにしている。
SetScript前に必要分発行しておいても良いと思う。

そしてDapp側にて、このSmartAccountのDataを参照して、なんやかんやする。
(Data参照 -> Node API直か、あるいはWaves Data Service API)

留意点

普通のトークンのようにWavesClient上に見えるわけではない。
いわゆるDapp(後ろでブロックチェーンを使う、何がしかのアプリ)用途と思う。

no gas とは

通常、トランザクションの手数料は送信者(sender)が支払うので、
上記のように、SmartAccount上のDataTransactionで物事を管理するとき、
手数料はSmartAccoountが負担する。トランザクション発行者(署名者)ではない。
つまり、ユーザはWAVES(ネイティブアセット)に一切触らなくて良い、ということになる。
これがNo Gas ということ。たぶん。

所感

試してはいない。動きそうではある。
DataTransactionでのデータ構造とRIDEでのコントラクト(制約付け)で大体やれそう。
というか意図が少し分かった気がする。


See also