LINE BlockchainでのNFT発行方法とEthereumとの違い
CryptoGames.incをお手伝いさせていただいているPacyです。
この記事は、LINE DC Advent Calendar 2021 (クリスマスプレゼント付き) Advent Calendar 2021 23日目の記事です。(と、空いてしまっていたのでEthereum Advent Calendar 2021の15日目にも入れさせていただきました。)
LINE Blockchain、皆さん使っておられるでしょうか?
来年の春NFTマーケットプレースLINENFTをリリースするとのことで、最近巷を騒がせているのもあり採用を検討されてる方も多いかと思います。
弊社でも今年の8月頃からPUI PUIモルカーのNFT販売など広く採用させていただいていて知見がある程度溜まってきたため共有させていただきます。
TL;DR
LINE Blockchainの(NFT用)コントラクトはERC1155のコントラクトが1つあるようなイメージ
Ethereumとの違いはTokenIdの指定をしてのミントができずミントするとインクリメントされたTokenIdが返ってくる点
独自の概念が出てくるので図表へのまとめと発行フローのシーケンス図へのまとめを行った
書かないこと
LINEBlockchainの仕組みなどブロックチェーン自体の説明
対象
最低限、NFTが何か知っている人
LINEBlockchainの使い方が知りたい人
使い方の面でEthereumとの違いが知りたい人
基本概念
公式のDocsに全て書いていることではあるのですが、文章で書かれているので一望できるように図表にまとめました。[1]
Chromeだと縮小画像がぼやけて見える仕様があるので拡大してご覧ください。
かなり独自な仕様になっています。Ethereumとの対応はわかりやすさ優先にしているため、あくまで似ているものがあるとすればこれかなという目安程度の対応で考えていただければと思います。
現状、独自コントラクトのデプロイはできず、Blockchainサービスを作成した時点で全アイテムトークン共通のContractId(Ethereumで言うところのContractAddress)が発行されます。
ERC1155に似ていてTokenごとに複数個発行できます。ERC1155では同じTokenIdに対して1つのMetadataしか設定できないのに対し、LINEBlockchainでは同じTokenTypeに対し別々のMatadataを設定できるのが違いです。
詳細は単語集があるので上記概要を念頭に置きつつ、わからない単語を検索しながら公式Docsを読むのが理解しやすいです。
NFT発行の流れ
NFT発行フローについてです。
Ethereumの場合は、TokenIdを指定してミントを行うのですが、LINEBlockchainの場合はまずTokenTypeを生成し、そのTokenTypeに対してミントをすると該当するNFTのTokenIndexが返ってきて、このTokenType+TokenIndex=TokenIdとなる仕様になっています。
TokenIdを指定してのミントはできないのが特徴です。
シーケンス図
2通りのやり方があります。1つはポーリング、2つはcallbackを用いたものです。
それぞれシーケンス図に示します。
まずポーリングですが、TokenType生成後sleepを噛ませたのちトランザクション実行結果を見に行き、生成されたTokenTypeが何かを取得します。その後取得したTokenTypeに対してミントを行う流れです。
画像や動画はEthereumと違いMetadataでの指定ではなく、別途サーバーを用意しそこへTokenIdと対応するパスで配信できるようにアップロードする必要があります。[2]
シーケンス図のオブジェクト名ですが、それぞれのapiエンドポイントに対応するLambdaを立てて運用しているため立てているLambda関数名で記載しています。
Lambda関数とapiエンドポイントの対応は画像の下に示すのでご参考ください。
createNft関数:
POST /v1/item-tokens/{contractId}/non-fungibles
getTransactionInfo関数:
GET /v1/transactions/{txHash}
mintNfts関数:
POST /v1/item-tokens/{contractId}/non-fungibles/{tokenType}/mint
次にcallbackでの呼び出しの流れを示します。
だいぶ簡素になるため本当はこちらで実装するのが好ましいのですが、2021年11月の時点では担当の方とやりとりしたところcallbackが取得できないバグがあるとのことなのでポーリングを使ってくださいとの回答をいただいています。
マーケットを作る際などのミント先としては運営のサービスウォレットにミントしておき、購入がなされたら購入者のウォレットへトランスファーするのがおすすめです。
運営のサービスウォレットへミントしたNFTをユーザーウォレットへトランスファーするのは簡単で下記のapiを叩くだけです。
ですが、ユーザーウォレットへミントしたNFTをプログラムでトランスファーしたい場合には1度該当NFTを所有しているユーザーの承認を得る必要があり、若干フローが複雑になります。
ユースケースとして必要な方のために、ユーザー承認を経てユーザーウォレットのNFTをトランスファーする際のシーケンス図も示しておくので参考にしてください。
requestProxy関数:
POST /v1/users/{userId}/item-tokens/{contractId}/request-proxy?requestType={requestType}
getRequestSessionStatus関数:
GET /v1/user-requests/{requestSessionToken}
commitRequestSession関数:
POST /v1/user-requests/{requestSessionToken}/commit
transferUserNft関数:
POST /v1/users/{fromUserId}/item-tokens/{contractId}/non-fungibles/{tokenType}/{tokenIndex}/transfer
実装
実装面で言うと、Ethereumと違ってread系のリクエストを含めた全てのapiリクエストにおいてapi_secretでの署名が必要です。
一部自前で実装しましたがちょっと大変です。実際にプロダクション運用している、署名を自動でやってくれるdoublejumptokyoのライブラリがあるので紹介しておきます。
GitHub - doublejumptokyo/go-lbd: Library for Golang to call LINE Blockchain Developers API.
LINEBlockchainに限らず、ブロックチェーンとのやりとりはLambdaなどに閉じておくと色々と便利です。
例えば、Ethereumとの疎通はWeb3やEthersといった共通インターフェースを持ったjs系ライブラリ(もしくはGoEthereumなど)で行うことが主流ですが、サーバーサイドがjsではない場合にlambdaを介して呼ぶことでフロントでの資産を活かしつつ言語間の違いを吸収することができます。
また、トランザクションの署名に必要な秘密鍵をサーバーにもたずLambdaに持たせることでKMSなどAWSのセキュリティ機構を簡単に活用することができ、どのコントラクトをどのアドレスで実行するかなどをLambdaを使う側からDIすることで立てるLambdaがユースケースに対して1つになります。
LINEBlockchainとの疎通用Lambdaで弊社で別の設計戦略として使っているのはCDKによるデプロイのIaC化です。ASMを用いてLambdaの動作確認をローカル実行でテストしつつ問題がなければそのまま環境変数ごとLambdaのファンクション群をデプロイできます。
雛形となるレポジトリを個人的に作っているのでよかったら見てみてください。API Gatewayは一応用意していますが、使わずにSDKで疎通する方が簡単かと思います。
GitHub - lilpacy/go-lambda-apigw-cdk: go x lambda x api gateway x cdk boilerplate
Tips
LINEBlockchainにはEtherscanのようなExplorerもあります。
トランザクションの確認などに重宝します。
また、BitmaxWalletはWebからも使うことができ、テストネットへの切り替えもできるようになっているため開発中はLINE Developersのコンソールだけでなくこちらも見るようにするといいです。
LINE BITMAX Wallet|LINEのブロックチェーンウォレット
ちなみにテストネットへの切り替えですが、できるようにするためにテストユーザーの登録が必要です。
下記の記事を参考にしてみてください。
テストユーザーを登録する | LINE Blockchain Docs
今後
LINEBlockchainはEVM互換ではなくSolidityで書いたスマートコントラクトは動きません。
現状、自前のコントラクトを動かすこともできないのですが、今後WebAssembly (WASM)のスマートコントラクトに対応するそうなのでより広いユースケースで使われるようになりそうで楽しみです。
Web 以外でも期待される WebAssembly - Blockchain との親和性について - LINE ENGINEERING
-
2021年8月時点の公式ドキュメントをもとにまとめたものです ↩︎
Discussion