NFTアート複製してみた
Motivation
「NFTアート複製してみた」みたいな30秒ぐらいの啓蒙動画を作ったらいいんじゃないでしょうか
TikTokとかでもうあるかも
TODO
ストーリーを整える
画像を切り針していく
✅短いのを作っていく
動画の要点
NFTアートは複製できる
NFTでアートをする嬉しいポイントは、こんな点を持ち込めること
デジタルデータに手垢をつける(購入者のモチベーションUP。新たな概念)
「あの人が持っていたデータ」
クリエイター早期支援という名誉(購入者のモチベーションUP。考え方としてあったがシステマチックになった)
「わしが育てた」
二次流通市場でクリエイターに還元がある(クリエイターのモチベーションUP)
今まではクリエイターが売ったら還元がなかった
NFTがなんなのかわかる(自分でも作れる)
NFTアートは投機マネーの行き先に過ぎないが、NFTの応用例は面白いかも
自由に受け渡しできる現在の所有者を示すトークン
動画のストーリー
NFTアートというのが流行っています。最近はNHKなどでも聞くことがあります
事例説明
2021年3月にBeepleというアーティストの作品がChristie'sで75億円で落札されたのがきっかけ NFTの出自である仮想通貨の市場規模は拡大し続けていました
インフレへのリスクヘッジ
2018年ごろからNFTアートの販売プラットフォームがで始め、2021年には世界最古の国際競売会Sotheby'sがNFTプラットフォームを立ち上げるなどアートの分野では大きな潮流になっています Twitterでもたまに話題になっているのを見かけた人も多いのではないでしょうか?
NFTとは何かをGoogleで調べると、複製できないアートという説明が出てきます
これにはアートでもアートじゃない文脈もありますが、「複製できるデジタルデータに唯一無二を与える」という説明をどれもしています
この言葉から自分が想像したのは、「現実の絵画と違って、デジタルのイラストは、いくらでも複製できる。一点ものキャンバスに書かれているアートの希少性は出せないが、これを出せる」
実際にNFTアートは複製できないのか、NFTの火付け役となったアートで試してみました
NFTアートは、ネットにアップした画像のURLをNFTに付与しているだけです
以外と簡単にできてしまいましたね
NFTアートであっても、そのアート自体は複製できるということです
注:実際にはできなくすることもできる。
実際NFTをやっている人たちは当然このことを知っていて、弁護士事務所ではこの点は明確に指摘されています
a16zのpodcastでも指摘されています
Linda: Yeah, exactly. So anyone can copy this; but if you actually look at the CryptoPunk NFT itself, you’ll see who owned this.
では何が「デジタルデータをユニークにする」のでしょうか?
結論から言うと、NFT自体がユニークで、NFTを所持している人がわかると言うことです
このことを指して所有権と呼んだりしますが、デジタルデータに日本の法律である物権にあたる所有権は存在しないので誤解を招きやすいです
NFTアートはNFTのメジャーな応用例の一つです
Linda: So, you can really do whatever you want with this. But the most common, basic thing I’ve seen is just people selling their artwork, and someone purchasing it, and then maybe storing that like on their virtual land, or having it displayed on their profile. And there’s like a social element to it: People talk about it a lot, like hey I just purchased this piece of art, and they’ll talk about it on Twitter. And there’s an app that aggregates purchases from all of these different marketplaces, and displays it almost like an Instagram feed — so you can have like a social element to who’s purchasing what, who owns what, and have people form communities around it.
これを理解するためにはNFTというものを掘り下げる必要があります
NFT最大1億ドル投資するというファンドMeta4 CapitalのBrandonの説明をみてみましょう
「NFTは単なるピクセルではありません。文化、技術、金融の交差点なのです。NFTは価値を獲得し、利用し、分配する方法についての新しい考え方を示しています。私たちはブロックチェーン技術によって、知的財産が媒介されなくなり、Web3で物事が最終的にどうなるかを目の当たりにしているのです」(Buchanan氏)。
Linda: So, NFT stands for “non-fungible token”, which is just a term used to describe a unique digital asset, whose ownership is tracked on a blockchain.
NFTとは「non-fungible token」の略で、ブロックチェーン上でその所有者を追跡するユニークなデジタル資産を表す用語です。
This can be a really broad set of assets from: digital goods, like virtual lands and artwork; to a claim on physical assets, like real estate or clothing items.
これは、仮想の土地やアートのようなデジタル商品から、不動産や衣料品のような物理的な資産に対する請求権まで、実に幅広い資産の集合体です
と、いずれも抽象的な説明になります。全然わからない
このインタビューは後半まで読むと示唆に富んでいるのですが、先に進みましょう
わからない時には自分でやってみるのが一番です。ここからは実際に自分でNFTを作って見ることにします
これをやります
NFTをETHチェーン上にデプロイ
NFTを発行
自分のNFTアートを作る
NFTはユニークなトークンをオーナーのアドレスに紐づけるSmart contract
早速なんのことかわからないんですが
Ethereumというものがあります。これは暗号通貨の一種です。暗号通貨というのは取引の記録がblockchainという改竄できないデータベースの上に乗っているものだと一旦受け入れてください ここの話を掘り下げると長くなって動画の焦点がぼやける上に基素.iconも深い理解をしていないので早々に切り上げます
例えばAさんがBさんに支払いをしたとき、blockhainにはその履歴が全て残ります
この情報は全て公開されているので誰でもみることができます
Ethereumの仕様は公開で議論されています
つまりEIP-721を読めばNFTの技術的な側面は完全に理解したと言って良いでしょう
「APIってなんですか?」「お父さんスイッチのようなものです。処理を命令する方法ということです」
眺めてみるとトークンの所有者を判別するようなownerOf()やらがあります
ユニークなトークンとその所有者の判別ができるものがNFTでした
NFTアートというのは、アートに紐づいた所有者が判別できるユニークなトークンということですね
トークンを持っていたら、その人がアートの所有者と見做せるということです
このことを「デジタルデータに唯一無二を与える」と言っていたわけです
では実際に独自のNFTを作って、NFTアートを作ってみましょう
案外かんたんに作れましたね。でも結局これでいいことってなんなんでしょう?
NFTアートの良い点
NFTを持っている人しか見られないというような技術も表れてきています
NFTアートの話は以上です
NFTのアート以外への転用も考えられます。自体はNFTの応用例のような展開も考えられそうです サービス増えてきたら、いつの間にか身近な技術になっているかもしれませんね。多分5年ぐらいはかかると思います(雑予想)
コードを置いておいたので、試せます。
それでは
2-4番目の記事ではNFTアートは複製不可能ということが書いてあります。本当でしょうか?
やってみよう
どうやって作るのか調べてみましょう
NFTアートの作り方
openseaで出品する時に、external linkにIPFS hashで作られたアイテムのURLを入力 というような流れ
流れを整理するとこうなる
出品者のやること
ネットに画像をアップ
そのURLをNFTのメタ情報に追加
NFTトークンを発行して売る
購入者のやること
NFTを手に入れる
アートの情報はNFTのメタ情報のIPFSのURLを参照する
NFTアートとは、NFTのメタデータにアートのURLが含まれたものということみたい
ということは、トークンのメタ情報のIPFSを見ればアート自体は見ることができるはずです
実際にやってみましょう
この時点で「NFTアートを複製してみた」は達成されてしまいました
実際のところ、当然やっている側はそれを知っていていますし、Twitterでも注意喚起している人はたくさんいます
この高解像度ファイルはIPFSに記録されており、誰でもアクセスしてダウンロードすることができます
では、コンテンツが固有のものでないとしたら、それはいったい何なのでしょうか?実は、それはトークンそのものなのです。
NFTのポインタが、中央のエンティティやアーティスト自身が管理しているURLを指している場合、アーティストはそのURLに保存されている画像を交換したり、完全に削除したりすることができます。また、リンク自体が削除され、NFTが404のサイトを指すことになるかもしれません。
このような事態を回避し、データを永遠に残すために、クリスティーズのBeepleのアート作品をはじめとする最近のプロジェクトでは、IPFSを採用しています。 視覚的に理解することをこの企画の目標とします
せっかくなのでこれをやってみましょう
自分でNFTを作る
NFTを出す
NFTを複製する
NFTアートを複製する
同じファイルに違うNFTを発行する
やらない
NFTを実際に売る
計算のための料金(gas)がかかる
10-30ドル
現在イーサリアムはスケーラビリティに問題を抱えている
ウォレットはアプリケーションからサポートされていなければいけない
自分のNFTを作ってみよう
In this tutorial, we will walk through creating and deploying an ERC-721 smart contract on the Ropsten test network using MetaMask, Solidity, Hardhat, Pinata and Alchemy (don’t fret if you don’t understand what any of this means yet — we will explain it!). Alchemyに登録、アプリを作成する
Chromeにインストール
https://gyazo.com/5fe2b5df913b33e68ff9f3ec445d6e2a
パスワードを入力するだけでインストールできる
ブラウザ変えたらどうなるの?
secret recovery phraseで復帰
高度な設定から
https://gyazo.com/863ee12e90d1edab0d27e93dc157335a
https://gyazo.com/89e30fb1e8786a98a90ae92e962c52be
test networkのWalletアドレスに偽のETHを追加する
https://gyazo.com/c7ebf22eb8998a7df1c5895436342063
5分程度待たされた挙句に無言で猫が消えて何も起こらない
コンソールに502が表示されている
再度実行しようとすると60s待てと言われる
https://gyazo.com/3d847fce55b4e3c9473cdf0917362165
他の方法を探しているといつの間にか表示されている
0.42 Etherあることがわかる
code:json
Error: 500 {"error":"ethjs-query while formatting outputs from RPC '{\"value\":{\"code\":-32000,\"message\":\"nonce too low\"}}'"} https://gyazo.com/f79b7971123e976ce44f522d4c41fb45
0x5d423c655aa0000 = 420000000000000000 wei = 0.42 EHTER
gweiで表示されているところが多い
npmのプロジェクトを作成する
code:zsh
npm install --save-dev hardhat
npx hardhat
❯ Create an empty hardhat.config.js
プロジェクトフォルダーを作る
code:zsh
mkdir contracts
mkdir scripts
スマートコントラクトをかく
code:zsh
npm install @openzeppelin/contracts
コントラクトのコード
コントラクトとは
A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain.
code:MyNFT.sol
// SPDX-License-Identifier: MIT
// ↑ライセンス表示
pragma solidity ^0.8.0;
solidityのバージョン指定。このバージョン向けのコードってことpragmaはコンパイラがソースをどう扱うかという指示
code:MyNFT.sol
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
code:MyNFT.sol
import "@openzeppelin/contracts/utils/Counters.sol";
NFTにIDを設定するために使うカウンタ
code:MyNFT.sol
import "@openzeppelin/contracts/access/Ownable.sol";
別にこうしなくても良い
code:MyNFT
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
実装に使うライブラリ
code:MyNFT.sol
contract MyNFT is ERC721URIStorage, Ownable {
MyNFTはERC721URIStorageとOwnableを継承している
code:MyNFT.sol
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// スマートコントラクトの名前 , シンボルを渡す
constructor() ERC721("MyNFT", "NFT") {}
// NFTを作る関数
// recipient 新しく作成されたNFTを受け取るアドレス
// tokenURI NFTのメタデータを記述したJSONとして解決される必要がある文字列。パート2で解説
function mintNFT(address recipient, string memory tokenURI)
public onlyOwner
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
}
環境変数に不調な情報を入れる
Walletから送られるトランザクションはprivate keyが必要
APIのURLの一部にキーを入れて使う形式らしい。いいの?
後からhardhat.config.jsでこの値を読み込んで使う
code:hardhat.config.js
/**
* @type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.1",
defaultNetwork: "ropsten",
networks: {
hardhat: {},
ropsten: {
url: API_URL,
accounts: [0x${PRIVATE_KEY}]
}
},
}
hardhatでコンパイル
npx hardhat compile
デプロイスクリプトを作る
code:deploy.js
async function main() {
const MyNFT = await ethers.getContractFactory("MyNFT")
code:deploy.js
// Start deployment, returning a promise that resolves to a contract object
const myNFT = await MyNFT.deploy()
await myNFT.deployed()
console.log("Contract deployed to address:", myNFT.address)
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
デプロイ
npx hardhat --network ropsten run scripts/deploy.js
結果
FormがMetaMaskのWalletのアカウントと一致している
裏で何が起きているのか
2つの重要なcall
eth_sendRawTransaction
eth_getTransactionByHash
与えられたhashに対するtransaction(典型的にはtransactionを送信するときに起こる)の情報を読み出すリクエスト NFTを作成する
Minting an NFTとは
メタデータを記述してtokenURIに渡す
こんな感じで使う
code:js
// デプロイしたコントラクトを取得して
const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
// mintする
nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
NFTを発行するときにこれをわたす
データの準備
Pinataを使ってNFTアセットとメタデータをIPFSに保存する PINATAサインアップして
ファイルをアップロードするとCIDが発行される
JSONでメタデータを記述して、これもPINATAにアップロードする
contractのインスタンスを作成する
contractをデプロイしたときのファイルを開いてアドレスを確認する
0x4a8837a22024c6bddc3496cde6433ea1864618fb
各種情報を入力
NFTをmintする
mintを実行するスクリプトを動かした
https://gyazo.com/9bb59828c73da800b987e044ec90f493
nonceは1
gasは500000(0.5mwei)を指定したのに2.21gweiになっているのはなぜ?
2分後にmineされた
https://gyazo.com/3a167cf2166aaeba8a92b71c04e0f3c9
ここまでで、EthereumのblockcahinにNFTをデプロイし、mintした
トランザクションを眺める
MyNFTに対してトークンID 1で発行されたことがわかる
https://gyazo.com/26278bcb8ffb4d7622c68e317bde20e6
Contractのアドレスを見るとMintしたことがわかる
しかしRead contractがないのでJSONを見ることができない
https://gyazo.com/5c835ebfddd210f961dd4b0941a4b2d3https://gyazo.com/a1305c33f80ed4b919821103dd727a1d
Verify & Publish Contract Source Codeをすればいいのだろうか?
埋めるところがいくつかあってわからなかったので、試していない
compilerのバージョンを要求された
artifactos/build-infoのmetadataにあるバージョンでいいのかな?
コードをデコンパイルする機能がある
動かんかった
再度同じスクリプトを動かせば、1つのデジタルアートに対してもう一つNFTを作ることもできる
smart contract
ID
を入力するだけ
PCは非対応
At the moment you can see your NFTs only on Metamask Mobile. You can add NFTs as custom tokens in the web extension, but you will not be able to see them natively in the UI.
メタデータ(tokenURI)をどうやってみるのか?
tokenURIを取得すればメタデータの入ったJSONが見られるはず
ABIはartifactsに格納されているので次のコードで出すことができる
code:js
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
console.log(JSON.stringify(contract.abi))
Ethereumのmainnetだと閲覧サービスがある
Ropsstenに対応してるのもあるかな?
contract.methods.tokenURI(1).call()で行けるらしい
公式ドキュメント読んでも辿り着けなかった
もちろんエディタの補完でも出ない
全てのトークンの検索(なんかの役に立つか?)
つまりこれで確認できる
tokenURIに設定したipfsが返ってきた
基素.icon
NFTの実態はtokenURIにのURLの先にある
tokenURIはなんでも自由に書き込める。自由にやられるとプラットフォーマーごとに対応できないはずなので、実際には出すプラットフォームの規約に従って作ることになりそう
テストとかも書けるらしい
APIドキュメントがこなれてない
やる前のNFTのイメージ
胡散臭いし、有用性がわからない
blockchainはグローバルなステート
smart contractはステートを使ってプログラムを書くことができる仕組み
blockchainにコンテンツやコードを埋め込んでおくと、それを他者が勝手に使ってもっと良いサービスができる可能性を増やす
法律的な課題はかなりありそうだけど、このコモンズ的考え方は面白い NFTはデジタルデータに所有者とその履歴を刻むことができる
心理的な意味づけを持たせることができる
「あの人が使っていたデータ」
権利証明書として使える
このコンテンツのクリエイターだということを証明する
1番目にMintした人をクリエイターとみなす
このアバターを所持している人ということを証明する
discordサーバーに入れる人だと証明する
簡単に「5ヶ月以上500円くれたら発行するトークンでしか入れないサーバー」とかいう条件をクリエイターが自由に作れたらクリエイター支援の文脈で流行るかもしれない
そのような柔軟性はサービス提供者にしか存在していない
クリエイターからするとプラットフォーマーの中間マージンを減らせる可能性がある
プラットフォームを自分で運営するということに他ならないが
この調子だとOSSのプラットフォームができるだろうと思う
1ポチでデプロイできないと使われないだろうけど
サービス提供者はそれよりはるかにいいものを提供しないとクリエイターに選ばれない世界になるかも
この辺りはNFTじゃなくて単にblockchainに載せてるだけでもいいパターンが多分ある
NFTは所有者がユニークであることを保証できるのが特徴だけど、その性質が不要なこともありそう
例えば?
実際のデータ取得の課題はかなりありそう
blockchainに埋め込まれた(実際にはその先のサーバーの)300MBのアバターデータをすぐダウンロードできるか?
blockhainに埋め込まれたデータを、所有者のみが取得できるソリューションが普及していない
このユースケースはかなりあるはず
「購入した人だけにコンテンツを見せたい」というケース