こんにちは!新しい技術やセキュリティの勉強、毎日お疲れ様です。「ブロックチェーンやNFTの仕組みを少しずつ任されるようになったけれど、セキュリティの話になると急に難しく感じる…」そんな不安を抱えていませんか?
大丈夫です!一歩ずつ、身近な例えから紐解いていけば必ず理解できるようになりますよ。今日は、NFTの世界でよく問題になる「ロイヤリティ(クリエイターへの還元金)の回避」を防ぐための技術、EIP-2981について、一緒に優しく学んでいきましょう!
—
1. 身近な例えで考えてみよう:フリーマーケットの「マナー」と「鍵」
まずは、現実の世界で考えてみますね。
あなたが心を込めて、世界にひとつだけの素敵なアート作品(あるいは手作りの家具)を作ったとします。最初の買い手Aさんがそれを買ってくれました。ここまでは普通のお買い物です。
しばらくして、Aさんはその作品を「やっぱり別の人の手に渡したいな」と思い、フリマアプリを使ってBさんに売りに出しました。ここでクリエイターのあなたとしては、「次の人に売る時も、売上の一部を少しだけ分けてもらえると、次の作品を作る資金になって嬉しいな」と思いますよね。これが現実の世界の「著作権使用料(ロイヤリティ)」の仕組みです。
優しいフリマと、抜け穴だらけのフリマ
現実のフリマアプリなら、運営会社がルールを決めているので、自動的にクリエイターにお金が支払われるようになっています。
しかし、ブロックチェーンの世界(NFTマーケットプレイス)はどうでしょう?
実は、ここが少し厄介なのです。あるマーケットプレイスは「ちゃんとクリエイターにロイヤリティを払おうね」というルールを守っていても、別の新しいマーケットプレイスが「うちを使えば、ロイヤリティ手数料0円で安く売買できますよ!」とお客さんを奪い合う現象が起きてしまいました。
これでは、クリエイターが泣き寝入りするしかありませんよね。「売買は自由だけど、クリエイターへの敬意(お金)はちゃんと払わせたい!」、これを人の善意に頼らず、仕組み(プログラム)で強制するのが、今回お話しするテーマなんです。
—
2. 攻撃者やずるい人は、どうやってロイヤリティを逃れるの?
悪意のある買い手や、手数料を1円でも安くしたい人は、次のような「抜け穴」を探します。
1. ロイヤリティ機能のないマーケットプレイスを使う
クリエイターへの支払いを無視する設計の取引所で売買する。
2. スマートコントラクトを直接ハック(迂回)する
通常の売買用関数(safeTransferFromなど)を使わず、自分たちで用意した別のプログラムを挟み込んで、形の上では「プレゼントした(無償の譲渡)」に見せかけて売買する。
人間同士の約束事だけでは、こうした「ずるい抜け穴」を防ぎきれません。だからこそ、NFTの基本設計そのものに「このルールは絶対に守ってね」と組み込む必要があるのです。
—
3. 救世主「EIP-2981」とは?
ここで登場するのが EIP-2981(NFT Royalty Standard) です。
これは、イーサリアムなどのブロックチェーンにおいて、「このNFTが売買されたら、誰に、何パーセントのロイヤリティを支払うべきか」を、NFTのプログラム自身が共通の言葉で教えてくれる世界共通の規格(ルールブック)になります。
これがあるおかげで、どんなマーケットプレイスであっても、プログラムが自動的に「あ、このNFTは売買価格の5%をあのクリエイターさんに送らなきゃいけないんだな」と理解し、強制的に計算・送金できるようになるんです。
—
4. 実践!EIP-2981を組み込んだスマートコードを書こう
それでは、実際にSolidityというプログラミング言語を使って、EIP-2981に対応した安全なNFTコントラクトの書き方を見てみましょう。難しく見えますが、日本語のコメントを読みながら一つずつ追っていけば大丈夫です!
以下のコードブロックを参考にしてください。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// OpenZeppelinという、世界中のエンジニアが使っている信頼性の高いライブラリをインポートします
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
// ERC721(NFTの標準)と、ERC2981(ロイヤリティ標準)、Ownable(管理者権限)を合体させます
contract MySecureNFT is ERC721, ERC2981, Ownable {
// コンストラクタ(このコントラクトが最初にブロックチェーンにデプロイされる時に一度だけ動く処理)
constructor(
string memory name,
string memory symbol,
address royaltyReceiver, // ロイヤリティを受け取るクリエイターのウォレットアドレス
uint96 royaltyFeeNumerator // ロイヤリティの割合(例: 5%なら 500 と指定します。分母が10000のため)
) ERC721(name, symbol) Ownable(msg.sender) {
// デプロイ時に、このNFT全体のデフォルトのロイヤリティ設定をここで「強制」登録します
// 第3引数の「500」は、10000分の一、つまり 5% を意味しています。
_setDefaultRoyalty(royaltyReceiver, royaltyFeeNumerator);
}
// コントラクトが特定のインターフェース(規格)をサポートしているか確認するための必須関数
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC2981)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
// 新しいNFTを発行(ミント)する関数(管理者だけが実行できます)
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}
}
コードのポイント解説
_setDefaultRoyaltyという関数を使って、「誰に、何パーセント支払うべきか」をコントラクトの奥深く底に刻み込んでいます。- これにより、マーケットプレイス側がわざわざ外部のデータベースを見に行かなくても、このNFTコントラクトに直接「いくら払えばいい?」と問い合わせる(
royaltyInfo関数を呼び出す)だけで、正しい金額が自動で分かるようになります。
—
5. さらに一歩進んだ防御:マーケットプレイスの制限(強制力を持たせる)
EIP-2981は「正しい金額を教える仕組み」ですが、悪質なマーケットプレイスが「その金額を無視して売買を実行する」ことまでは、これ単体では完全に防げない場合があります。
そのため、実務の現場ではさらに一歩踏み込んで、「承認された信頼できるマーケットプレイス以外での移動(転送)をブロックする」という追加の対策(Operator Filterなどと呼ばれる手法)を組み合わせることがよくあります。
イメージとしては、「信頼できる公式のセキュリティゲート(特定のマーケットプレイス)を通った荷物しか、お家に搬入できませんよ」という防犯ロックをかけるようなものです。
—
まとめ
いかがでしたでしょうか?
- EIP-2981 は、NFTが「私を売る時は、この人にロイヤリティを払ってね!」と自己主張するための、世界共通のプログラム規格です。
- 人の善意やマーケットプレイスのルールに頼るのではなく、コントラクトのコードレベルで組み込むことで、クリエイターの正当な権利を守ることができます。
セキュリティやスマートコントラクトの開発は、最初は覚えることが多くて大変に感じるかもしれません。ですが、こうした「どうやって不正や抜け穴を防ぐか」という視点を持つことは、信頼されるエンジニアへの確かな第一歩です。
焦らず、ご自身のペースで一つずつ引き出しを増やしていきましょう!応援しています!
コメント