NFTを動かすスマートコントラクトの仕組みを整理してみる

はじめに

こんにちは。
前回の記事では、NFTのトランザクションがどのように生成・署名され、ネットワークへ送信されたあと、ブロックへ記録されるのかを整理しました。

その流れの中で登場したのが、スマートコントラクトです。

NFTの発行や送信では、ウォレットがすべての処理を行っているわけではありません。ウォレットはトランザクションへの署名や送信を担当し、実際にNFTを発行したり、所有者を変更したりする処理は、ブロックチェーン上のスマートコントラクトが実行します。

今回は、

  • スマートコントラクトとは何か
  • 通常のプログラムと何が違うのか
  • NFTのどの情報を管理しているのか
  • mintや送信の際に何が起きるのか

について整理してみようと思います。

スマートコントラクトとは?

スマートコントラクト(Smart Contract)とは、

ブロックチェーン上に配置され、決められたルールに従って処理を実行するプログラム

です。

「コントラクト」という名前から契約書のようなものを想像するかもしれませんが、実際にはブロックチェーン上で動作するプログラムです。

例えばNFTでは、次のような処理を担当します。

  • NFTを新しく発行する
  • NFTの所有者を記録する
  • NFTを別のウォレットへ送る
  • NFTごとの識別番号を管理する
  • メタデータの参照先を返す
  • 特定の処理を実行できるユーザーを制限する

スマートコントラクトには、NFTを管理するためのルールと処理があらかじめ実装されています。

 

Web2のプログラムとの違い

普段利用しているWebサービスでは、処理を実行するプログラムは企業が管理するサーバー上で動作しています。

ユーザー操作 → APIサーバー → プログラム実行 → データベース更新


一方、Web3では、ブロックチェーン上に配置されたスマートコントラクトを呼び出します。

ユーザー操作 → ウォレットで署名 → トランザクション送信 → スマートコントラクト実行 → ブロックへ記録

Web2では、サービス運営者がプログラムやデータベースを管理します。

Web3では、スマートコントラクトの処理結果がブロックチェーン上に記録され、ネットワーク上の複数のノードによって共有されます。

 

スマートコントラクトはどこで動く?

スマートコントラクトは、特定の企業のサーバーだけで動作するものではありません。

トランザクションが送信されると、Ethereumネットワーク上の各ノードがその内容を検証し、スマートコントラクトの処理が実行されます。

Ethereumでは、スマートコントラクトの実行環境として、EVM(Ethereum Virtual Machine)が使われています。

EVMは、

Ethereum上のスマートコントラクトを実行するための共通の実行環境

です。

開発者が作成したスマートコントラクトは、Ethereum上で実行できる形式へ変換され、ブロックチェーンへ配置されます。

この配置処理を、デプロイ(Deploy)と呼びます。

スマートコントラクトを作成 → コンパイル → Ethereumへデプロイ → コントラクトアドレス発行

デプロイされたスマートコントラクトには、ウォレットアドレスのような固有のアドレスが割り当てられます。
利用者やアプリケーションは、そのコントラクトアドレスを指定して処理を呼び出します。

 

NFTのスマートコントラクトは何を管理している?

NFTのスマートコントラクトでは、主に次のような情報を管理しています。

 

Token ID

Token IDは、NFTを識別するための番号です。

例えば、同じスマートコントラクトから3つのNFTを発行した場合、次のように個別の番号が割り当てられます。

  • Token ID:1
  • Token ID:2
  • Token ID:3

それぞれのNFTは、

コントラクトアドレス + Token ID

の組み合わせによって識別されます。
Token IDが同じでも、コントラクトアドレスが異なれば別のNFTです。

所有者情報

スマートコントラクトは、各Token IDをどのウォレットが所有しているかを管理します
イメージとしては、次のような対応関係です。

Token ID 所有者
1 Wallet A
2 Wallet B
3 Wallet A

NFTを送信すると、この所有者情報が更新されます。

NFT本体がウォレット間を移動しているというよりも、スマートコントラクト上の所有者情報が書き換わる、と考えると分かりやすいです。

tokenURI

NFTでは、画像や名前、説明文などの情報をメタデータとして管理します
そのメタデータの参照先を返すものが、tokenURI です。

例えば、Token IDが1のNFTについて問い合わせると、次のようなURIが返されます。

ipfs://example/metadata/1.json

※実際のIPFSのURIでは、[example] の部分にCID(Content Identifier)と呼ばれるハッシュ値のような文字列が入ります。

このJSONファイルには、NFTの名前や画像の保存先などが記載されています。

{ 
  "name": "Sample NFT",
  "description": "NFT sample",
  "image": "ipfs://example/image.png"
}

つまり、スマートコントラクトが画像データそのものを直接保持しているとは限りません。

スマートコントラクトでは所有者情報やToken IDを管理し、画像などの情報は外部ストレージを参照する構成が一般的です。

 

mintすると何が起きる?

mintとは、NFTを新しく発行する処理です
ユーザーがmintボタンを押すと、内部では次のような流れになります。

 

スマートコントラクトのmint処理では、主に次のような処理が行われます。

  • 新しいToken IDを決める
  • 発行先のウォレットアドレスを登録する
  • NFTの発行数を更新する
  • 必要に応じてtokenURIを設定する
  • NFTが発行されたことを示すイベントを記録する

処理が正常に完了し、ブロックへ記録されることで、NFTの発行が完了します。

 

NFTを送ると何が起きる?

NFTを別のウォレットへ送信する場合も、スマートコントラクトが処理を行います。

例えば、Token IDが1のNFTをWallet AからWallet Bへ送ると、所有者情報が次のように更新されます。

  • 変更前:Token ID 1 → Wallet A 

  • 変更後:Token ID 1 → Wallet B 

この変更内容がブロックチェーンへ記録されることで、Wallet Bが新しい所有者になります。

 

 

誰でもmintできるとは限らない

スマートコントラクトでは、誰がどの処理を実行できるかを制御できます
例えば、mint処理について次のようなルールを設定できます。

  • 管理者だけがmintできる
  • 許可リストに登録されたウォレットだけがmintできる
  • 1つのウォレットにつき1回だけmintできる
  • 指定した期間内だけmintできる
  • 所定のETHを支払った場合だけmintできる

このような条件は、スマートコントラクトのプログラムとして実装されます
条件を満たしていない状態で処理を実行すると、トランザクションは失敗します。

 

mint処理のコード例

Ethereumのスマートコントラクト開発では、Solidityという言語がよく使われます
簡略化したmint処理のイメージは、次のようになります。

function mint(address to, uint256 tokenId) public { 
  _safeMint(to, tokenId);
}

この関数では、

  • to:NFTを受け取るウォレットアドレス
  • tokenId:発行するNFTの識別番号

を受け取り、NFTを発行します。

実際のスマートコントラクトでは、これに加えて、

  • 実行権限の確認
  • 発行数の上限確認
  • 二重発行の防止
  • mint料金の確認
  • tokenURIの設定

などの処理が実装されます。

なお、前回の記事で紹介したガス代は、スマートコントラクトの実行にも関係しています。処理が複雑になり、データの書き込み量が増えるほど、消費するガスも多くなります。

 

一度デプロイすると変更できない

一般的なWebサービスでは、サーバー上のプログラムに不具合があれば、修正したコードを再度デプロイできます。

一方、ブロックチェーンへデプロイしたスマートコントラクトのコードは、あとから書き換えることができません
そのため、デプロイ前には十分なテストが必要です。

例えば、次のような不具合があると大きな問題になります。

  • 誰でも管理者向け処理を実行できる
  • NFTを上限なく発行できる
  • NFTを送信できない
  • 売上を引き出せない
  • 誤ったメタデータを参照している

あとから機能を変更できるようにするため、アップグレード可能な設計を採用する場合もあります
ただし、その分仕組みが複雑になり、管理権限やセキュリティについて慎重な設計が必要になります。

スマートコントラクトは自動的に動くのか?

「スマートコントラクト」という言葉から、条件を満たすと自動的に処理が始まる印象を受けるかもしれません
しかし、スマートコントラクトが自ら判断して勝手に動き始めるわけではありません。

基本的には、

  • ユーザー
  • ウォレット
  • DApp ※
  • 外部システム

などからトランザクションが送信されることで、処理が実行されます。

外部からトランザクションを送信 → スマートコントラクトを呼び出す → 処理を実行

つまり、スマートコントラクトは、呼び出されたときに決められたルールに従って処理するプログラムです。

※DApp:ウォレットやスマートコントラクトと連携して動作するWebアプリケーション(例:NFTのmintサイトなど)。

まとめ

今回紹介した内容を整理すると、次のようになります。

用語 役割
スマートコントラクト ブロックチェーン上で処理を実行するプログラム
デプロイ スマートコントラクトをブロックチェーンへ配置する処理
コントラクトアドレス スマートコントラクトを識別するアドレス
Token ID NFTを識別する番号
所有者情報 NFTを所有するウォレットの情報
tokenURI NFTのメタデータ参照先
mint NFTを新しく発行する処理
EVM Ethereum上でスマートコントラクトを実行する環境

NFTの発行や送信では、ウォレットがトランザクションへの署名と送信を行い、そのトランザクションを受け取ったスマートコントラクトが実際の処理を実行します。

NFTは単なる画像データではなく、スマートコントラクトによって、

  • どのNFTが存在するのか
  • 誰が所有しているのか
  • どのような条件で発行や送信ができるのか

が管理されています。

スマートコントラクトは、NFTを動かすための中心的なプログラムといえます。