NFTスマートコントラクト開発の基礎:1

ブロックチェーン利用の増加に伴い、Ethereum(イーサリアム)に関する日本語の学習教材も増加してきた。

日本語化されたマスタリング・イーサリアム等の書籍は存在するが、残念ながら初心者が学習するにはハードルが高い。

created by Rinker
オライリージャパン
¥4,400 (2023/01/27 19:27:33時点 Amazon調べ-詳細)

そこで、筆者がSolidityを学習する上で非常に有用であったUdemyの講座を紹介したい。

上記の講座を受講し、筆者のメモを以下にまとめた。

本記事は当該講座受講の補助教材として受講環境の向上に資すると考えたため公開しており、上記講座のセクション2部分に対応する。

なお、講座のコンテンツを侵害しないように原典からの引用や筆者の保有するNFTを例示するなどの配慮を行っている。

目次

ERC-721

ERC-721とは何かを理解するために、まずはEIP(Ethereum Improvement Proposals)について確認する。

EIP

イーサリアム改善提案改善提案(EIP) Github リポジトリは 2015 年 10 月に作成されました。 EIP プロセスは、Bitcoin 改善提案(BIP)に基づいており、この BIP 自体Python 改善提案 (PEP)に準じています。

イーサリアム改善提案(EIP)は、イーサリアムの新しい機能やプロセスに関する提案を規定する標準規格です。 EIP には、技術仕様の変更案が含まれており、コミュニティの 「信頼できる情報源」として機能します。 イーサリアムのネットワークアップグレードとアプリケーションの標準規格は、EIP プロセスでの議論を通じて開発されます。

https://ethereum.org/ja/eips/

EIP-1にEIPを書くためのガイドラインが記載されており、そこではEIPは以下のように分類され、それぞれに独自のEIPリストがある。

EIP Types概要
Standard TrackEthereum 実装に影響を与える変更で、さらにCore, Networking, Interface, ERCの4つのカテゴリに分かれる。ERCのカテゴリにEIP-721が定義されている。
Metaイーサリアムを取り巻くプロセスを記述やプロセスへの変更の提案など。例えば手順、ガイドライン、意思決定プロセスの変更、イーサリアム開発で使用されるツールまたは環境の変更が含まれる。
Informationalイーサリアムの設計上の問題について説明するか、イーサリアム コミュニティに一般的なガイドラインや情報を提供するもので、新しい機能を提案するものではない。

ERC-721

EIP-721の内容は以下のリンクのとおり。

EIP-721は、スマートコントラクト内の NFT 用の標準 API の実装を可能にするもので、NFT を追跡および転送するための基本的な機能を提供する。

全てのNFTは区別可能で、それぞれのオーナーシップを個別に追跡可能とするため、ERC-721スマートコントラクト内の一意のIDによって識別される。

オプション機能であるメタデータ拡張(metadata extension)を使用すると、NFTをURIと関連付けるメカニズムが提供される。すなわち、NFTに名前、説明、画像などの追加のプロパティを含めることができる。

2075
https://docs.opensea.io/docs/metadata-standards

OpenSeaのMetadata Standardsに準拠して記載された情報はOpenSeaで適切に表示されるようになっている。

プロパティについては以下のように示されている。

imageThis is the URL to the image of the item. Can be just about any type of image (including SVGs, which will be cached into PNGs by OpenSea), and can be IPFS URLs or paths. We recommend using a 350 x 350 image.
image_dataRaw SVG image data, if you want to generate images on the fly (not recommended). Only use this if you’re not including the image parameter.
external_urlThis is the URL that will appear below the asset’s image on OpenSea and will allow users to leave OpenSea and view the item on your site.
descriptionA human readable description of the item. Markdown is supported.
nameName of the item.
attributesThese are the attributes for the item, which will show up on the OpenSea page for the item. (see below)
background_colorBackground color of the item on OpenSea. Must be a six-character hexadecimal without a pre-pended #.
animation_urlA URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, and OGG are supported, along with the audio-only extensions MP3, WAV, and OGA.
Animation_url also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported.
youtube_urlA URL to a YouTube video.

ERC-721商品の例

筆者が保有する”CloneX #16922″を例に見てみる。

OpenSeaで当該NFTのDetailsを参照すると、0x49cF6f5d44E70224e2E23fDcdd2C053F30aDA28BというコントラクトアドレスのID7721であることがわかる。

jsonファイルを参照すると、各プロパティが記載されていることがわかる。

{
	"name": "CloneX #16922",
	"description": "🧬 CLONE X 🧬\n\n20,000 next-gen Avatars, by RTFKT and Takashi Murakami 🌸\n\nIf you own a clone without any Murakami trait please read the terms regarding RTFKT - Owned Content here: https://rtfkt.com/legal-2A\n\nYou are also entitled to a commercial license, please read the terms to that here: https://rtfkt.com/legal-2C",
	"attributes": [
		{
			"trait_type": "DNA",
			"value": "Human"
		},
		{
			"trait_type": "Eye Color",
			"value": "BLU"
		},
		{
			"trait_type": "Hair",
			"value": "YLLW Spiked"
		},
		{
			"trait_type": "Jewelry",
			"value": "GLD G-Link"
		},
		{
			"trait_type": "Clothing",
			"value": "SPACE TRIP Tee"
		}
	],
	"image": "https://clonex-assets.rtfkt.com/images/7721.png"
}

各プロパティは以下のように表示に反映される。

EVM

イーサリアム仮想マシン(Ethereum Virtual Machine)はスマートコントラクトと呼ばれるEVMプログラムの実行環境であり、システムの状態がどのように変更されるかを特定する。

イーサリアムの状態は各ノードにローカルデータベース(通常はGoogleのLevelDB)として格納され、ブロックチェーン上のデータベースにはトランザクションとシステムの状態が、「マークルパトリシアツリー(パトリシア木)」と呼ばれるシリアライズされたハッシュデータ構造でブロックチェーンヘッダーに保管される

現在の状態から次の状態に変更を与えるのはトランザクションであり、トランザクションによりスマートコントラクトの中で管理されている残高などの情報を変更することができる。

以下はYellowpaper(Whitepaperよりも詳細な仕様に関して言及した書類)の解説記事の抜粋である。

https://www.lucassaldanha.com/ethereum-yellow-paper-walkthrough-2/

リーフノードでデータが変更されると、ルートノードのハッシュが変更される。

これにより、リーフノード全体で全てのデータを比較して同じデータを持っていることを確認することなく、ルートノードのハッシュを比較することで足りる。

https://www.lucassaldanha.com/ethereum-yellow-paper-walkthrough-2/

リーフノードはAccount Stateを管理しており、storageRootは スマートコントラクトに関連づけられた残高情報などのデータ(EOAはこれを持たない)が含まれるAccount Storage trieにリンクしている。

Transactions tireにはブロックに含まれる全てのトランザクションが含まれており、Root NodeのハッシュはブロックヘッダのtransactionsRootフィールドに含まれている。

Recipets tireにはブロックに含まれるトランザクションの全ての受信が含まれ、Root NodeのハッシュはブロックヘッダのrecipesRootsフィールドに含まれている。

ERC-721定義機能

再びEIP-721を参照する。

この中で、機能定義はfunctionとして定義されている。

追跡、送信、代理権限に関しては定義されているが、NFTを作成するmintと消却するburnについては仕様に含まれていないため、別途実装する必要がある。

balanceOf

オーナーに割り当てられた全てのNFTをカウントする。

ゼロアドレスに割り当てられたNFTは向こうと見做され、この関数はゼロアドレスに関するクエリに対してはthrowされる。

_ownerは残高を問い合わせるアドレスで、戻り値は_ownerが保有するNFTの数である(ゼロの場合もある)。

function balanceOf(address _owner) external view returns (uint256);

ownerOf

NFTのオーナーを検索する。

ゼロアドレスに割り当てられたNFTは無効と見做され、この関数はゼロアドレスに関するクエリに対してはthrowされる。

_tokenIdはNFTの識別子で、戻り値はNFTのオーナーのアドレスである。

function ownerOf(uint256 _tokenId) external view returns (address);

safeTransferFrom

NFTのオーナーシップを、あるアドレスから別のアドレスに移す。

msg.senderが現在のオーナー、承認されたオペレータ、またはこのNFTの承認されたアドレスでない場合はthrowされる。

また、Fromが現在の所有者でない場合、_toがゼロアドレスの場合、_tokenIdが有効なNFTでない場合はthrowされる。

転送が完了すると、この関数は _to がスマートコントラクト(コードサイズ > 0)であるかどうかをチェックする。

もしそうなら、_to に対して onERC721Received を呼び出し、その戻り値がbytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))の通りでない場合はthrowされる。

_from はNFTの現在のオーナー、_to は新しいオーナー、_tokenIdは転送するNFT、data_toのコールで送信される、指定された形式を持たない追加データである。

function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

transferFrom

NFTのオーナーシップを譲渡するが、_to がNFTを受信する能力があるか(ない場合は永久に失われる)どうかを確認することは、Callerの責任である。

safeTransferFromとの違いは、transferFromにおいては上記の黄色マーカー部の手続が省略されており、これは送信先がスマートコントラクトであった場合にNFTを受信する能力があるかどうかの確認である。

msg.sender が現在のオーナー、承認されたオペレータ、または承認されたアドレスでない場合はthrowされる。

また、Fromが現在の所有者でない場合、_toがゼロアドレスの場合、_tokenIdが有効なNFTでない場合はthrowされる。

_from はNFTの現在のオーナー、_to は新しいオーナー、_tokenIdは転送するNFTである。

  function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

approve

NFTの承認済みアドレスの変更または再確認。

ゼロアドレスは承認されたアドレスがないことを示す。

msg.senderがNFTの現在のオーナー、または現在のオーナーに権限を与えられたオペレータでない場合はthrowされる。

_approvedは新しい承認済みNFTコントローラー、_tokenIdは承認するNFTである。

function approve(address _approved, uint256 _tokenId) external payable;

setApprovalForAll

msg.sender のすべての資産を管理する第三者 (オペレータ)の承認を有効化または無効化する。

ApprovalForAll イベントを発行し、コントラクトはオーナーごとに複数のオペレータを許可しなければならない。

_operatorは承認されたオペレータのセットに追加するアドレス、_approvedはオペレータが承認される場合はTrue、承認を取り消す場合はFalseを指定する。

function setApprovalForAll(address _operator, bool _approved) external;

getApproved

単一の NFT に対して承認されたアドレスを取得する。

_tokenId が有効な NFT でない場合にはthrowされる。

_tokenIdは承認済みアドレスを検索するNFTで、returnはこのNFTの承認済みアドレス、または存在しない場合はゼロアドレス。

function getApproved(uint256 _tokenId) external view returns (address);

isApprovedForAll

あるアドレスが他のアドレスの認可されたオペレータであるかどうかを問い合わせる。

_ownerはNFTを所有するアドレスで、_operatorはオーナーの代理を務めるアドレスである。

returnは、 _operator_owner の認可を受けたオペレータであればTrue、そうでなければFalseを返す

function isApprovedForAll(address _owner, address _operator) external view returns (bool);

OpenZeppelin

コミュニティにより精査されたコードを基盤にした安全なスマートコントラクト開発用のライブラリを提供している。

ERC-721の仕様に定義されていなかったmintやburnなどの機能が多数用意されている

created by Rinker
オライリージャパン
¥4,400 (2023/01/27 13:11:25時点 Amazon調べ-詳細)

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次