NFT の実装 I
今回は仮想通貨とNFTの違いを技術的な視点から深堀していき、NFTを実装するための技術仕様についてまとめたいと思います。
仮想通貨とNFT
仮想通貨とNFTの違いについてご存知でしょうか?
サービスや用途の違いは説明できても、どのような仕組みで実現させれているか技術的な視点で説明できる方は少ないかと思います。
仮想通貨とNFTはそれぞれ代替性トークン、非代替性トークンと呼ばれており、まずはこの2つの違いについて解説していきます。
仮想通貨→代替性トークン
仮想通貨と聞いて、ビットコインやイーサムリアルを思い浮かべる方が多いかと思います。
これらの仮想通貨はその量を10ビットコインや100イーサムリアルなど単位で数えることができ、ユーザの間でやりとりできることが特徴で、これらの特徴を完備したトークンを”代替性トークン”と呼ばれます。
NFT→非代替性トークン
ゲーム内で売買できるアイテムやデジタルアートなどは唯一性・保有者を証明する必要があり、その場合はNFTの仕組みが使用されます。
このようにNFTは”代替不可能なデジタルデータ”の作成を目的としており、この特徴を完備したトークンを”非代替性トークン”と呼びます。
技術仕様からみるトークンの違い
それでは、代替性トークンと非代替性トークンはそれぞれどのような技術仕様で定義され、実装されているのでしょうか?
イーサムリアルを例に深掘りしていきたいと思います。
イーサムリアルと技術仕様(ERC)
イーサムリアルの説明はWikipediaに譲るとして、イーサムリアルのプラットフォーム上で代替性トークンと非代替性トークンはどのように区別して扱われているのでしょうか?
イーサムリアルではイーサリアムコメント要求(ERC : Ethereum Request for Comments)と呼ばれるトークンを発行するための規格が定義されています。
開発者はビジネスニーズに応じて適切なERCを選択し、イーサムリアルプラットフォームで動作するアプリケーション(以下DApp, 分散型アプリケーション)を実装する必要があります。
代替性トークンはERC-20, と非代替性トークンはERC-721で定義されており、それぞれの特徴を簡単な表でまとめると下記となります。
ERC-20とERC-721
ERC-20
ERC-20は代替性トークンの実現に用いられ、そのために必要なオブジェクトとファンクションは下記のように定義されています。
event Transfer( address indexed from, address indexed to, uint256 value );
event Approval( address indexed owner, address indexed spender, uint256 value );
function totalSupply() public view returns(uint256);
function balanceOf(address who) public view returns(uint256);
function transfer(address to, uint256 value) public returns(bool);
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
totalSupply(総支給量)
現在流通しているトークンの総数を表示します。
balanceOf(バランス)
Ethereumのアドレスを受け取り、割り当てられたアドレスにトークンを返します。
transfer(移転)
トークン保有者の要求に応じて、あるアドレスから別のアドレスにトークンを転送します。
allowance, approve and transferFrom(認可、認証、移転元)
それぞれの保有者に代わって他のイーサリアムアドレスにトークンを使用することを許可するなどの高度な機能をサポートします。
ERC-721
ERC-721は非代替性トークンの実現に用いられ、そのために必要なオブジェクトとファンクションは下記のように定義されています。
唯一性を証明するためにowenerOfやtakeOwnershipなどの関数が定義されているのが特徴です。
event Transfer( address indexed _from, address indexed _to, uint256 _tokenId );
event Approval( address indexed _owner, address indexed _approved, uint256 _tokenId );
function balanceOf(address _owner) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function transfer(address _to, uint256 _tokenId) public;
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;
balanceOf(バランス)
そのアドレスのトークンの数を返します。
OwnerOf(オーナ)
そのIDの所有者を出力します。
transfer(移転)
トークンの所有権を現在のオーナーから取り除き、新しいオーナーに移転します。
approve(承認)
Approveは、指定されたトークンIDの所有権を他のアドレスに主張するためのもうひとつの機能です。
takeOwnership(オーナシップ確認)
takeOwnership関数は、_tokenIdを受け取り、メッセージの送信者に対して同様のチェックを行います。
ERCに準拠したDAppを開発する
それでは、ERCに準拠したDAppを開発するにはどうすれば良いのでしょうか?
Solidityと呼ばれるDApp開発用の言語を選択し、OpenZeppelinと呼ばれるライブラリを使用してアプリケーションを開発する方法が一般的です。
SolidityとOpenZeppelinを仕様したDApp開発は次回にまとめたいと思います。