blockchain - 使用 infura, ipfs 创建NFT(erc721) truffle compile deploy exec mint
访问量: 875
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个参数的: