从零开始构建 NFT 网站(1)- 部署合约
准备工作
Alchemy 账号
创建 Alchemy 应用,获得 API KEY 和 RPC 节点地址。
Metamask 账号
下载 Metamask 插件,创建钱包,获得 ETH 地址和密钥。
领取测试币
每次可以领 0.5 个,没事的时候领点水以备不时之需。地址:https://www.alchemy.com/faucets/ethereum-sepolia
创建一个 Node 项目
mkdir my-nft && cd my-nft
npm init -y
创建 Hardhat 项目
在 my-nft
文件夹下,安装 Hardhat,并创建 dApp
npm install --save-dev hardhat
npx hardhat
这里可能会报错:Error: Cannot find module ‘@nomicfoundation/hardhat-toolbox’
安装一下即可:npm install --save-dev @nomicfoundation/hardhat-toolbo
检查一切是否正常运行:npx hardhat test
现在 Hardhat 开发环境搭建好了,继续安装 OpenZeppelin 合约包,这可以让我们访问 ERC721 接口,我们将在此基础上构建合约。
npm install @openzeppelin/contracts
编写智能合约
在 contracts 文件夹里创建一个名为 MyNFT.sol
的新文件,编写代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// 继承 ERC721 标准的所有方法,要制作有效的 NFT ,必须实现所有方法
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
// 跟踪铸造的 NFT 总数,并为新 NFT 设置唯一 ID
import "@openzeppelin/contracts/utils/Counters.sol";
// 设置访问控制,只有合约所有者才能铸造 NFT
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// 参数:智能合约名称,合约符号
constructor() ERC721("MyNFT", "NFT") {}
// 参数:接收新铸造 NFT 的地址,NFT 元数据(名称,描述等属性)
function mintNFT(address recipient, string memory tokenURI)
public
onlyOwner
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
}
这里有一个小坑,@openzeppelin 5.0.0 删除了 Counters.sol 文件,可以自己写一个计数器替代,也可以降级到 4.9.3
把 Metamask 和 Alchemy 连接到项目
现在已经完成了三个步骤:创建 Metamask 钱包,创建 Alchemy 账号、创建智能合约。
接下来要把三者连接起来:从钱包发送的交易需要使用「私钥」进行签名,我们可以把私钥和 Alchemy API 秘钥存储在环境文件里。
npm install dotenv --save
根目录下创建 .env 文件:
API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key";
PRIVATE_KEY = "your-metamask-private-key";
更新 hardhat.config.js
require("dotenv").config();
require("@nomicfoundation/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.24",
defaultNetwork: "sepolia",
networks: {
hardhat: {},
sepolia: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`],
},
},
};
编写部署脚本
在根目录下创建 deploy.js
,编写代码:
async function main() {
// Grab the contract factory
const MyNFT = await ethers.getContractFactory("MyNFT");
// Start deployment, returning a promise that resolves to a contract object
const myNFT = await MyNFT.deploy(); // Instance of the contract
console.log("Contract deployed to address:", myNFT.target);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
部署合约
npx hardhat run scripts/deploy.js --network sepolia
成功之后应该会输出:
Compiled 18 Solidity files successfully (evm target: paris).
Contract deployed to address: 0x7130Df343097ED88d112Cec1B366bDaa3530a67e
到 Sepolia 浏览器上检查一下:sepolia etherscan
可以看到合约已经成功部署了。