NFT合约:在 ERC721 上 Safe Mint 并在 OpenSea 上进行售卖

in #opensea3 months ago

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

创建 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

参考

封装 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