ユーザ用ツール

サイト用ツール


blockchain:openzeppelin_で_erc721_nft_トークンの作成

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

次のリビジョン
前のリビジョン
blockchain:openzeppelin_で_erc721_nft_トークンの作成 [2022/05/05 05:57] – 作成 dotblockchain:openzeppelin_で_erc721_nft_トークンの作成 [2022/05/11 06:50] (現在) dot
行 1: 行 1:
  
 ====== OpenZeppelin で ERC721(NFT) トークンの作成 ====== ====== OpenZeppelin で ERC721(NFT) トークンの作成 ======
 +
 +ほぼ OpenZeppelin オフィシャルの[[https://docs.openzeppelin.com/contracts/4.x/erc721|ドキュメント]]通りに NFT スマートコントラクトを実装します。
 +
 +今回作成する GameItem スマートコントラクトは NFT の生成プログラムです。GameItem の awardItem メソッドを呼び出したときに NFT が生成されます。生成された NFT には NFT の所有者とtokenURIを保持します。tokenURI が指し示す先にゲームアイテムデータの実体があります。
 +
 +tokenURI は NFT を生成する際に指定されます。その指定された URI の所有者を NFT で記録しているということになります。
 +URI はブロックチェーンの外にありますので、所有者が所有する物はブロックチェーンの外にあることになります。このようなデータを「オフチェーン」と呼びます。逆に、所有する物もブロックチェーン上に記録することを「オンチェーン」と呼びます。
 +
 +オフィシャルの[[https://docs.openzeppelin.com/contracts/4.x/erc721|ドキュメント]]より引用。
 +
 +> Note
 +> you’ll notice that the item’s information is included in the metadata, but that information isn’t on-chain! So a game developer could change the underlying metadata, changing the rules of the game! If you’d like to put all item information on-chain, you can extend ERC721 to do so (though it will be rather costly). You could also leverage IPFS to store the tokenURI information, but these techniques are out of the scope of this overview guide.
 +
 +GameItem スマートコントラクトは ERC721URIStorage を継承しているため「オフチェーン」になります。オンチェーンにしたい場合は ERC721 を継承すればOKです。「オンチェーン」の場合は「オフチェーン」よりもガス代が割高になります。また、tokenURI に IPFS の URI を指定することもできます。
 +
 +つまり、ethereum ブロックチェーン上の NFT と IPFS を組み合わせれば、非中央集権を保ったまま改竄できない NFT を実現できます。
  
 ===== 前提 ===== ===== 前提 =====
  
-Truffle と npm をインストールしておいてください。+npm、Truffle、Ganache をインストールしておいてください。
  
 (参考) [[blockchain:truffleを使ったスマートコントラクト開発|Truffleを使ったスマートコントラクト開発]] (参考) [[blockchain:truffleを使ったスマートコントラクト開発|Truffleを使ったスマートコントラクト開発]]
 +
 +(参考) [[blockchain:ethereum構築ハンズオン_ganache編|ethereumブロックチェーンの構築(Ganache編)]]
  
 ===== プロジェクト作成 ===== ===== プロジェクト作成 =====
行 14: 行 32:
 > cd nft_project > cd nft_project
 nft_project> truffle init nft_project> truffle init
 +</code>
 +
 +[[blockchain:truffleを使ったスマートコントラクト開発|Truffleを使ったスマートコントラクト開発]] を参考に truffle-config.js の設定をしてください。(どの ethereum ブロックチェーンに接続するか設定する必要があります。)
 +
 +===== OpenZeppelin のインストール =====
 +
 +npm を使用して OpenZeppelin をインストールします。
 +
 +<code PowerShell>
 nft_project> npm init nft_project> npm init
 This utility will walk you through creating a package.json file. This utility will walk you through creating a package.json file.
行 54: 行 81:
 Is this OK? (yes) Is this OK? (yes)
  
-nft_project> npm install --save @openzeppelin/contracts+nft_project> npm install --save-dev @openzeppelin/contracts 
 +</code> 
 + 
 +===== NFTの実装 ===== 
 + 
 +<code PowerShell> 
 +nft_project> truffle create contract GameItem 
 +nft_project> code contracts/GameItem.sol 
 +</code> 
 + 
 +<code JavaScript> 
 +// contracts/GameItem.sol 
 +// SPDX-License-Identifier: MIT 
 +pragma solidity ^0.8.0; 
 + 
 +import "../node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; 
 +import "../node_modules/@openzeppelin/contracts/utils/Counters.sol"; 
 + 
 +contract GameItem is ERC721URIStorage { 
 +    using Counters for Counters.Counter; 
 +    Counters.Counter private _tokenIds; 
 + 
 +    constructor() ERC721("GameItem", "ITM") {} 
 + 
 +    function awardItem(address player, string memory tokenURI) 
 +        public 
 +        returns (uint256) 
 +    { 
 +        uint256 newItemId = _tokenIds.current(); 
 +        _mint(player, newItemId); 
 +        _setTokenURI(newItemId, tokenURI); 
 + 
 +        _tokenIds.increment(); 
 +        return newItemId; 
 +    } 
 +
 +</code> 
 + 
 +===== マイグレーション ===== 
 + 
 +<code PowerShell> 
 +nft_project> truffle create migration GameItem 
 +nft_project> code .\migrations\1651959757_game_item.js 
 +</code> 
 + 
 +<code JavaScript> 
 +const GameItem = artifacts.require("GameItem"); 
 +module.exports = function(_deployer) { 
 +  // Use deployer to state migration tasks. 
 +  _deployer.deploy(GameItem) 
 +}; 
 +</code> 
 + 
 +===== デプロイ ===== 
 + 
 +<code PowerShell> 
 +nft_project> truffle migrate 
 +</code> 
 + 
 +===== 実行(Mint) ===== 
 + 
 +今回作成したスマートコントラクトの awardItem を実行すると、新しい NFT が生成されます。 
 +新たな NFT を生成することを Mint と言います。実際 awardItem のソースコードでは「_mint(player, newItemId);」と _mint メソッドを呼び出しています。ERC721(NFT) トークンだけでなく ERC20 トークンを新たに生成することも Mint と言います。 
 +Mint は英語の「Minting 鋳造(ちゅうぞう)」から来ています。(例: minting authority 造幣局) 
 + 
 +<code PowerShell> 
 +nft_project> truffle console 
 +truffle(development)> let gameItem = await GameItem.deployed(); 
 +truffle(development)> let address = await web3.eth.getAccounts(); 
 +truffle(development)> let playerAddress = address[0]; 
 +truffle(development)> let transaction = await gameItem.awardItem(playerAddress, "https://game.example/item-id-8u5h2m.json"); 
 +
 +  tx: '0xf32a1d6dd67167b16537ddc0308cdd5918773aca77f91438be056adf38a212bf', 
 +  receipt: { 
 +    transactionHash: '0xf32a1d6dd67167b16537ddc0308cdd5918773aca77f91438be056adf38a212bf', 
 +    transactionIndex: 0, 
 +    blockHash: '0x3c932e396c46e28469fa2db720481e5d1814a624061429bd5eab1a135c0382ff', 
 +    blockNumber: 5, 
 +    from: '0x9384fc1b3f3cc59e6e30a0ba0267451570bb7aa6', 
 +    to: '0x36c73d181564e2bc7ef390f7067ffabf4c23d535', 
 +    gasUsed: 153238, 
 +    cumulativeGasUsed: 153238, 
 +    contractAddress: null, 
 +    logs: [ [Object] ], 
 +    status: true, 
 +    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000008000000000000000000000000000000000020000000000002000000000000000000000000000000000000000000000000040020000000100000000000000000000000000000000000000000000000000000000000', 
 +    rawLogs: [ [Object] ] 
 +  }, 
 +  logs: [ 
 +    { 
 +      logIndex: 0, 
 +      transactionIndex: 0, 
 +      transactionHash: '0xf32a1d6dd67167b16537ddc0308cdd5918773aca77f91438be056adf38a212bf', 
 +      blockHash: '0x3c932e396c46e28469fa2db720481e5d1814a624061429bd5eab1a135c0382ff', 
 +      blockNumber: 5, 
 +      address: '0x36c73D181564e2BC7Ef390F7067FfABf4C23d535', 
 +      type: 'mined', 
 +      id: 'log_ca6a0b3b', 
 +      event: 'Transfer', 
 +      args: [Result] 
 +    } 
 +  ] 
 +
 +</code> 
 + 
 +トランザクションログから Mint した NFT の TOKENID を取得します。 
 +(GameItem スマートコントラクトは内部的に自動インクリメントする TOKENID を生成しています。これが主キーの役割を果たしています。) 
 + 
 +<code PowerShell> 
 +truffle(development)> let TOKENID = transaction.logs[0].args.tokenId; 
 +</code> 
 + 
 +Mint した NFT の所有者と NFT に保存されている tokenURI を確認します。 
 + 
 +<code PowerShell> 
 +truffle(development)> gameItem.ownerOf(TOKENID) 
 +'0x9384FC1B3F3CC59e6e30a0BA0267451570bb7AA6' 
 +truffle(development)> gameItem.tokenURI(TOKENID) 
 +'https://game.example/item-id-8u5h2m.json'
 </code> </code>
blockchain/openzeppelin_で_erc721_nft_トークンの作成.1651730266.txt.gz · 最終更新: 2022/05/05 05:57 by dot