这篇文章详细介绍了如何使用生成性AI技术、IPFS和Foundry工具创建和部署一个ERC-721 NFT集合,涵盖了从图像生成到合约部署的全部步骤。文章结构清晰,内容丰富,适合希望快速上手NFT开发的读者。
非同质化代币(NFT)在最近获得了极大的关注,并被全球最大的品牌所采纳。在此前,生成NFT图像需要具备艺术或设计背景,而我们将向你展示如何利用生成性AI快速推出你的收藏。
在本指南中,我们将使用:
你可以在 这里 查看参考代码库,或在下面的详细指南中跟随操作。
npm i -S axios dotenv
我们需要一个 OpenAI API 密钥(也称为秘密密钥)和一个 QuickNode API 密钥,这些将在后续步骤中使用。在项目根目录中创建一个新的 .env 文件,并添加以下值:
.env
OPENAI_API_KEY=your-openai-api-key
QUICKNODE_API_KEY=your-quicknode-api-key
按照 OpenAI 提供的步骤为 生成你的密钥。要使用此密钥,你必须在你的 OpenAI 账户上加载少量资金。每次运行本指南中的代码时,费用约为 $0.10。如果你希望免费完成本教程,你可以手动将提示输入到 ChatGPT 界面中。
稍后我们会介绍 QuickNode API 密钥。
为了使用 OpenAI API 生成图像,我们将使用以下代码。如果你希望了解有关如何使用此 API 的更多信息,可以查看 OpenAI API 文档。我们将使用 创建图像端点 来获取一个 base64 编码的 JSON,便于保存到我们的文件系统。
如果你打算生成大量图像,请记住他们的 速率限制。
创建 generate-images.js 文件并粘贴以下代码。
generate-images.js
require('dotenv').config();
const axios = require('axios');
const fs = require('fs');
const generateImage = async (prompt) => {
try {
const response = await axios.post(
'https://api.openai.com/v1/images/generations',
{
prompt: prompt,
n: 5, // 生成的图像数量
size: "1024x1024", // 图像大小
response_format: "b64_json" // 返回文件本身,编码为 base64 JSON,这样我们可以直接保存
},
{
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
} catch (error) {
console.error("生成图像时出错:", error);
return null;
}
};
const saveImage = (imageData, index) => {
const buffer = Buffer.from(imageData, 'base64');
fs.writeFileSync(`./image_${index}.png`, buffer);
};
const main = async () => {
const imageData = await generateImage("酷炫的像素艺术 NFT,具有赛博朋克主题");
for (let i = 0; i < 5; i++) {
if (imageData) {
saveImage(imageData.data[i].b64_json, i);
}
}
};
main();
如果你希望使用与我们赛博朋克像素艺术不同的风格,你可以更新传递给 generateImage()
的提示(第36行)。如果没有,你可以执行上述代码以生成我们的图像。
node generate-images.js
请随意查看你将用于NFT的图像文件!
接下来,我们需要生成NFT元数据并将文件上传到IPFS。我们将“固定”这些文件,以确保它们永久可用。但首先,我们需要连接到 IPFS 节点。
提示
要在 QuickNode 上使用 IPFS,需要选择 Build 计划或更高级别的计划。有关更多信息,请查看我们的定价计划 这里。
一旦你的账户在有付费计划并可以访问 IPFS 后,你将生成一个API密钥。要为你的 QuickNode 账户生成 API 密钥,你可以按照 这里 的指示进行。确保配置密钥以访问 IPFS_REST。
使用你的密钥更新我们在第二步创建的 .env 文件。
现在你已获得IPFS访问权限,我们可以进入有趣的部分。
为了使用你的 QuickNode 账户生成NFT元数据并上传/固定到IPFS,我们将使用以下代码。此代码与视频略有不同,因为它利用了我们已安装的 axios
库,而不是已弃用的 request-promise
库。创建 upload-images.js 文件并粘贴以下代码。
upload-images.js
require('dotenv').config();
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');
async function uploadToIPFS(filePath, fileName, contentType) {
try {
const formData = new FormData();
formData.append('Body', fs.createReadStream(filePath));
formData.append('Key', fileName);
formData.append('ContentType', contentType);
const response = await axios.post(
'https://api.quicknode.com/ipfs/rest/v1/s3/put-object',
formData,
{
headers: {
...formData.getHeaders(),
'x-api-key': `${process.env.QUICKNODE_API_KEY}`,
},
}
);
return response.data;
} catch (error) {
console.error('上传到 IPFS 时出错:', error);
throw error;
}
}
function createNFTMetadata(filePath, imageUrl) {
const name = 'NFT 名称';
const description = 'NFT 描述';
const metadata = {
name,
description,
image: imageUrl,
attributes: [] // 在此处添加任何其他属性
};
fs.writeFileSync(filePath, JSON.stringify(metadata));
}
async function main() {
try {
for (let i = 0; i < 5; i++) {
const imageName = `image_${i}.png`;
const imagePath = `./${imageName}`;
// 上传图像
const imageUploadResponse = await uploadToIPFS(
imagePath,
imageName,
'image/png'
);
console.log('图像已上传:', imageUploadResponse);
// 创建元数据
const imageUrl = `https://quicknode.quicknode-ipfs.com/ipfs/${imageUploadResponse.pin.cid}`;
const metadataFile = `metadata_${i}.json`;
const metadataPath = `./${metadataFile}`;
createNFTMetadata(metadataPath, imageUrl);
// 上传元数据
const metadataUploadResponse = await uploadToIPFS(
metadataPath,
metadataFile,
'application/json'
);
console.log('元数据已上传:', metadataUploadResponse);
}
} catch (error) {
console.error('错误:', error);
}
}
main();
如果你希望创建一个更适合生产的收藏,可以进一步调整 attributes
值。
要执行此代码,我们将在终端中运行以下命令:
node upload-images.js
通过获取 CID 并将其添加到此 URL 的末尾,确认你的文件在 IPFS 上可用: https://quicknode.quicknode-ipfs.com/ipfs/ENTER-CID-HERE
重要! 保存你的元数据文件的 CIDs。我们将在第二部分第六步中需要这些。
现在我们的文件已经上传,我们准备好部署合约并铸造我们的NFT了!
Foundry 是一个强大的 EVM 开发工具包,我们将使用它来部署我们的智能合约。如果你想了解更多关于 Foundry 的信息,可以查看我们的 Foundry 入门指南。
如果你还没有安装 Foundry,可以在终端中使用以下命令进行安装。
curl -L https://foundry.paradigm.xyz | bash
现在,在我们的根目录中,我们将在一个新的 nft 文件夹中初始化一个 Foundry 项目。我们将使用以下终端命令进行操作:
forge init nft
更新你的配置文件,添加我们的 Solidity 版本。
foundry.toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.23"
## 查看更多配置选项 https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
最后,你将需要删除三个包含“Counter”字样的文件。你可以在 nft/test/、nft/src/ 和 nft/script/ 文件夹中找到它们。
在这里,我们将利用 OpenZepplin ERC-721 合约。我们将首先使用以下终端命令导入它们:
git submodule add https://github.com/OpenZeppelin/openzeppelin-contracts lib/openzeppelin-contracts
然后,我们将创建我们的合约代码。在 nft/src/ 目录中创建 NFT.sol 文件,并粘贴以下代码:
nft/src/NFT.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract NFT is ERC721, ERC721URIStorage, Ownable {
constructor(address initialOwner)
ERC721("MyToken", "MTK")
Ownable(initialOwner)
{}
function safeMint(address to, uint256 tokenId, string memory uri)
public
onlyOwner
{
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// 下面的函数是 Solidity 所需的重写。
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721URIStorage)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
首先,我们需要生成一个地址。对于本指南,我们将使用 vanity-eth.tk 提供的简单网络界面,但如果安全性对你很重要,你应该查看我们的如何使用 JavaScript、Go、PHP、Python 或 Ruby 创建以太坊地址的指南。
然后,你将在 nft/ 目录中创建一个新的 .env 文件。
nft/.env
PRIVATE_KEY=0xyour-private-key
OWNER=your-address
TESTNET_RPC_URL=your-rpc-url
将你的私钥添加(确保其前面有0x),并将你的地址(也要有0x前缀)添加到所有者变量中。稍后我们会讨论你的 RPC URL。
为了部署智能合约并铸造我们的NFT,我们需要支付交易费用。在测试网络中,使用测试网络代币来完成这项工作,你可以在 https://faucet.quicknode.com/ethereum/sepolia 免费获取。
确保你在使用水龙头时已登录到你的 QuickNode 账户,以获取额外的代币并解除某些限制。
只需输入你在以上第三步中生成的地址。
虽然你可以绝对运行自己的以太坊节点(请查看我们的指南 在这里),你可以在 QuickNode 获取免费端点。只需创建一个账户(如果你还没有),然后在左侧找到端点,创建一个 Ethereum Sepolia 的端点。
创建端点后,复制“HTTP Provider”端点 URL,并将其添加到我们在第三步中创建的 .env 文件中。
现在我们要告诉 Foundry 如何部署我们的合约。为了简化操作,我们还将告诉它在过程中铸造我们的 NFT。
在 nft/script/ 目录中创建 NFT.s.sol 文件,并粘贴以下代码:
nft/script/NFT.s.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;
import {Script} from "forge-std/Script.sol";
import {NFT} from "../src/NFT.sol";
contract NFTScript is Script {
function setUp() public {}
function run() public {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
NFT nft = new NFT(vm.envAddress("OWNER"));
nft.safeMint(
vm.envAddress("OWNER"),
0,
"https://quicknode.quicknode-ipfs.com/ipfs/cid-of-metadata_0-file"
);
nft.safeMint(
vm.envAddress("OWNER"),
1,
"https://quicknode.quicknode-ipfs.com/ipfs/cid-of-metadata_1-file"
);
nft.safeMint(
vm.envAddress("OWNER"),
2,
"https://quicknode.quicknode-ipfs.com/ipfs/cid-of-metadata_2-file"
);
nft.safeMint(
vm.envAddress("OWNER"),
3,
"https://quicknode.quicknode-ipfs.com/ipfs/cid-of-metadata_3-file"
);
nft.safeMint(
vm.envAddress("OWNER"),
4,
"https://quicknode.quicknode-ipfs.com/ipfs/cid-of-metadata_4-file"
);
vm.stopBroadcast();
}
}
用我们在第一部分第四步中保存的 CIDs 更新你的文件中的 IPFS URL。
现在在你的终端中,你将导航到 nft/ 目录。
cd nft/
加载你的环境变量。
source .env
最后,运行 Foundry 部署命令。
forge script script/NFT.s.sol:NFTScript --rpc-url $TESTNET_RPC_URL --broadcast
你应该会看到一行显示:
✅ [成功]哈希: [交易哈希]
抓取那笔交易哈希,并在 https://sepolia.etherscan.io 查找它。
恭喜你!你已经部署了一个 ERC-721 智能合约,并借助生成性 AI 铸造了 5 个 NFT。如果你正在构建类似的项目或对本指南有任何疑问,请随时通过 Discord 或 Twitter 与我们联系。
让我们知道 如果你有任何反馈或对新主题的请求。我们乐意倾听你的声音。
- 原文链接: quicknode.com/guides/eth...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!