NFT合约:在 ERC721 上 Safe Mint 并在 OpenSea 上进行售卖
1. 创建智能合约
访问: https://wizard.openzeppelin.com/#erc721
填入必要信息,勾选选项。然后点击【Download】下载 hardhat 开发版本。
2. 配置 Network
在 hardhat.config.ts
中添加网络配置:
networks: {
sepolia: {
chainId: 11155111,
url: process.env.SEPOLIA_RPC_URL || 'https://rpc.sepolia.org',
accounts: [process.env.WALLET_PRIVATE_KEY]
}
}
其中,需要配置钱包私钥用于发布。
3. 配置发布脚本
需要配置一个 initalOwner
。修改 scripts/deploy.ts
脚本:
const instance = await upgrades.deployProxy(ContractFactory, [
'0x6D877f96198E55085CEb56097B099cc7bb814263'
]);
4. 执行发布命令
# 安装依赖
bun install
# 执行测试
bun run test
# 发布到对应网络
bunx hardhat run --network sepolia scripts/deploy.ts
如果看到类似这样的提示,则表示发布成功:
Proxy deployed to 0xE8F638d6B5D747B6caD2d675E1927D02Aa39c0a7
注意: 主要有测试网络余额,部署用了大约 0.05 ETH 花销
通过区块链浏览器查看该合约: https://sepolia.etherscan.io/address/0xE8F638d6B5D747B6caD2d675E1927D02Aa39c0a7
Refs
- 示例代码仓库:https://github.com/new-lingverse/erc721-example
- Opensea 文档: https://docs.opensea.io/docs/deploy-an-nft-contract
创建 Mint 脚本
在 Script 目录下创建 mint.ts
脚本:
const { ethers } = require("hardhat");
async function main() {
// 替换为你的合约地址
const targetContractAddress = "0xYourContractAddress";
const targetContractABI = [
// 替换为你的合约 ABI
"function mint(address to) public"
];
// 获取签名者
const [signer] = await ethers.getSigners();
// 获取合约实例
const targetContract = new ethers.Contract(targetContractAddress, targetContractABI, signer);
// 替换为接收 token 的地址
const recipientAddress = "0xRecipientAddress";
// 调用 mint 函数
const tx = await targetContract.safeMint(
recipientAddress,
'https://v0.md/images/avatar.jpg'
); await tx.wait();
console.log(`Token minted to ${recipientAddress}`);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
其中,需要替换的配置为:
- 替换合约地址,在部署命令完成后提示
- 替换 ABI 信息,位于 artifacts 目录,在部署完之后会生成,如:
artifacts/contracts/MyToken.sol/MyToken.json
- 替换 NFT URL
- 替换接收 Token的地址
执行远程命令
bunx hardhat run --network sepolia scripts/mint.ts
# Token minted to 0x6D877f96198E55085CEb56097B099cc7bb814263
看到对应的输出,即为完成。
注意这一步也是需要手续费的。
挂到 OpenSea 上进行售卖
前置条件
- 注册 OpenSea 并完成邮箱验证,创建 API Key
- 注册 Infura 或者其他 Provider,创建 API Key
参考
- 文档: https://docs.opensea.io/docs/buy-and-sell-setup
- 示例代码: https://github.com/ProjectOpenSea/buy-sell-opensea-sdk-demo/tree/main
封装 SDK
import { Chain, OpenSeaSDK } from 'opensea-js';
import { InfuraProvider, ethers } from 'ethers';
import { config as dotEnvConfig } from 'dotenv';
dotEnvConfig();
export const OPENSEA_API_KEY = process.env.OPENSEA_API_KEY;
export const WALLET_PRIV_KEY = process.env.WALLET_PRIVATE_KEY;
export const INFURA_API_KEY = process.env.INFURA_API_KEY;
let provider = new InfuraProvider('sepolia', INFURA_API_KEY);
export const wallet = new ethers.Wallet(WALLET_PRIV_KEY as string, provider);
export const WALLET_ADDRESS = wallet.address;
export const sdk = new OpenSeaSDK(
wallet,
{
chain: Chain.Sepolia,
apiKey: OPENSEA_API_KEY
},
(line) => console.info(`MAINNET: ${line}`)
);
通过 SDK 上架 OpenSea
import { WALLET_ADDRESS, sdk } from '../lib/sdk';
const createListing = async () => {
// TODO: Fill in the token address and token ID of the NFT you want to sell, as well as the price
let tokenAddress: string = '0xe8f638d6b5d747b6cad2d675e1927d02aa39c0a7';
let tokenId: string = '0';
let listingAmount: string = '1000';
const listing = {
accountAddress: WALLET_ADDRESS,
startAmount: listingAmount,
asset: {
tokenAddress: tokenAddress,
tokenId: tokenId
}
};
try {
const response = await sdk.createListing(listing);
console.log(
'Successfully created a listing with orderHash:',
response.orderHash
);
} catch (error) {
console.error('Error in createListing:', error);
}
};
// Check if the module is the main entry point
if (require.main === module) {
// If yes, run the createOffer function
createListing().catch((error) => {
console.error('Error in createListing:', error);
});
}
export default createListing;
执行运行命令:
bun run --bun scripts/sell.ts
# Successfully created a listing with orderHash: 0x52c40b394976725070ddc3d1b747bc62910cd08be66a508d423a84e285859281
然后就可以在 OpenSea 中进行访问了: https://testnets.opensea.io/zh-CN/assets/sepolia/0xe8f638d6b5d747b6cad2d675e1927d02aa39c0a7/0
文章示例项目没有更改,
仓库地址: https://github.com/new-lingverse/erc721-example