blockchain - 使用 infura, ipfs 创建NFT(erc721) truffle compile deploy exec mint
访问量: 852
refer to: https://docs.infura.io/infura/tutorials/ethereum/create-an-nft-using-truffle
1. 需要创建一个IPFS 项目,在infura上。
如下图所示。
点击确认后,有一个绑定信用卡的过程。
绑定后,创建项目,增加 subdomain, 例如我的叫bigbanana
2. 上传LOGO文件到 IPFS
然后找到一个LOGO文件(例如叫做 bigbanana.png , 放到当前目录下),上传到IPFS 服务器上:
(记得把下面的??? 替换成你自己的。 前面的是project id, 后面的是project secret )
$ curl "https://ipfs.infura.io:5001/api/v0/add" -X POST -F file=@"bigbanana.png" \ -u "2AodumQVzetdQryc6A3PMg?????:deee615b42df210a945d49da39b?????"
结果:
{"Name":"bigbanana.png","Hash":"QmUfZohadE7vYABSpR97gVyUWu1DuTUeAq4Y1HVcGVyxXR","Size":"15895"}
打开网址,就可以看到对应的结果了:
3. 创建metadata的JSON 文件
metadata.json 内容如下;
{ "name": "Big Big Banana", "description": "The Banana is big! ", "image": "https://bigbanana.infura-ipfs.io/ipfs/QmUfZohadE7vYABSpR97gVyUWu1DuTUeAq4Y1HVcGVyxXR", "attributes": [ { "trait_type": "taste", "value": "So good so sweet"}, { "trait_type": "event", "value": "2022 , year , to , study , solidity contract"} ] }
然后给它上传到远程
$ curl "https://ipfs.infura.io:5001/api/v0/add" \ -X POST \ -F file=@"metadata.json" \ -u "2AodumQVzetdQryc6A3PMg?????:deee615b42df210a945d49da39b?????" 结果如下: {"Name":"metadata.json","Hash":"QmX6RYeTT8W4MymKaY6eBtoReHCFkVTV2XByctjV91aERu","Size":"349"}
然后访问对应的web url ,就可以看到该json文件了:
4. 创建truffle 文件夹
编辑package.json
{ "dependencies": { "@openzeppelin/contracts": "^4.6.0", "@truffle/hdwallet-provider": "^2.0.9", "dotenv": "^16.0.1", "solc": "^0.8.14-fixed", "web3": "^1.7.3" }, "devDependencies": { "truffle-plugin-verify": "^0.5.26" } }
$ npm install (注意这里可能需要梯子)
truffle init
创建contract: contracts/BigBigBanana.sol
$ cat contracts/BigBigBanana.sol //Contract based on [https://docs.openzeppelin.com/contracts/4.x/erc721](https://docs.openzeppelin.com/contracts/4.x/erc721) // SPDX-License-Identifier: MIT pragma solidity 0.8.15; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract BigBigBanana is ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("Big Big Banana", "BBB") {} function mintNFT(address recipient, string memory tokenURI) public returns (uint256){ _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _safeMint(recipient, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; } }
修改truffle-config.js
require('dotenv').config(); const HDWalletProvider = require('@truffle/hdwallet-provider'); const { INFURA_API_URL, MNEMONIC } = process.env; module.exports = { networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*" }, goerli: { provider: () => new HDWalletProvider(MNEMONIC, INFURA_API_URL), network_id: '5', gas: 5500000, // gasPrice: 50000000000, // 50 gwei networkCheckTimeout: 1000000, timeoutBlocks: 200, addressIndex: 2 } }, compilers: { solc: { version: '0.8.15' } } };
.env 文件内容为:
# 下面几个是调用的时候使用 ETHEREUM_NETWORK = "goerli" INFURA_PROJECT_ID = "6d5b3edb39ed4ac39731a6f10754????" # address: 0xc0dD5021e298dB57bEF361C735cd1C04cef2???? SIGNER_PRIVATE_KEY = "a7d856cf836a71422df6a76837e1c67022aba9bda349b0a9e85a496c????????" # 下面2个是发布的时候使用 INFURA_API_URL = "wss://goerli.infura.io/ws/v3/427a8f460d514ebfadf0d6c60b09ef27" MNEMONIC = "margin blouse tenant chat hub chef addict club rather prize ???? ????
5. 编译: truffle compile
$ truffle compile Compiling your contracts... =========================== > Compiling ./contracts/BigBigBanana.sol > Compiling ./contracts/Migrations.sol > Compiling @openzeppelin/contracts/access/Ownable.sol > Compiling @openzeppelin/contracts/token/ERC721/ERC721.sol > Compiling @openzeppelin/contracts/token/ERC721/IERC721.sol > Compiling @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol > Compiling @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol > Compiling @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol > Compiling @openzeppelin/contracts/utils/Address.sol > Compiling @openzeppelin/contracts/utils/Context.sol > Compiling @openzeppelin/contracts/utils/Counters.sol > Compiling @openzeppelin/contracts/utils/Strings.sol > Compiling @openzeppelin/contracts/utils/introspection/ERC165.sol > Compiling @openzeppelin/contracts/utils/introspection/IERC165.sol > Artifacts written to /mnt/d/workspace/test_erc_721_bigbanana_infura/build/contracts > Compiled successfully using: - solc: 0.8.15+commit.e14f2714.Emscripten.clang
6. 发布 truffle deploy --network goerli --interactive
2_deploy_contract.js ==================== Deploying 'BigBigBanana' ------------------------ > transaction hash: 0x66efcaff257688c4fc272289e2cdea7c61e0621a0043a61e0f6aea9870c008a1 > Blocks: 0 Seconds: 8 > contract address: 0x3223BBDf275782d54587E3520183Ad3DFE033D46 > block number: 7088953 > block timestamp: 1655690375 > account: 0xc0dD5021e298dB57bEF361C735cd1C04cef2E48A > balance: 5.443236181770190214 > gas used: 2880887 (0x2bf577) > gas price: 2.500000008 gwei > value sent: 0 ETH > total cost: 0.007202217523047096 ETH > Saving migration to chain. > Saving artifacts ------------------------------------- > Total cost: 0.007202217523047096 ETH Summary ======= > Total deployments: 2 > Final cost: 0.007827602525048328 ETH
7. 创建一个 脚本: mint.js 内容如下:
const TOKEN_URI = "https://bigbanana.infura-ipfs.io/ipfs/QmX6RYeTT8W4MymKaY6eBtoReHCFkVTV2XByctjV91aERu" const CONTRACT_ADDRESS = "0x3223BBDf275782d54587E3520183Ad3DFE033D46" const PUBLIC_ADDRESS = "0xc0dD5021e298dB57bEF361C735cd1C04cef2E48A" // Loading the compiled contract Json const contractJson = require('./build/contracts/BigBigBanana.json') module.exports = async function (callback) { // web3 是Truffle的自动引入的对象 const contract = new web3.eth.Contract( contractJson.abi, CONTRACT_ADDRESS ); // 获得 network , 这个是根据参数传入的 const network = await web3.eth.net.getNetworkType() // 生成一个tx, 该tx是调用了 mintNFT产生的 const tx = contract.methods.mintNFT(PUBLIC_ADDRESS, TOKEN_URI) // 发送! const receipt = await tx .send({ from: (await web3.eth.getAccounts())[0],// 使用了HD wallet中的第一个account gas: await tx.estimateGas(), }) .on('transactionHash', (txhash) => { console.log(`Mining transaction ...`) console.log(`https://${network}.etherscan.io/tx/${txhash}`) }) .on('error', function(error){ console.error(`An error happened: ${error}`) callback() }) .then(function(receipt){ // Success, you've minted the NFT. The transaction is now on chain! console.log( `Success: The NFT has been minted and mined in block ${receipt.blockNumber}`) callback() }) }
8 .运行该mint 脚本 (在truffle 环境中; truffle exec mint.js --network goerli)
$ truffle exec mint.js --network goerli Using network 'goerli'. Mining transaction ... https://goerli.etherscan.io/tx/0x6b61670c5dccd8fa46814546df06ffe7150bcbd399f5626ee31597cbcbb37a26 Success: The NFT has been minted and mined in block 7089096
就可以发现,我们的NFT已经被挖掘出来了,给到了对应的账户地址中
看下面的 transfer data, 可以看到, mint的时候,是传入了2个参数的: