跳到主要内容前端调用 Solidity 智能合约连接 MetaMask 钱包并部署至 Alchemy 测试网 | 极客日志SolidityNode.js大前端
前端调用 Solidity 智能合约连接 MetaMask 钱包并部署至 Alchemy 测试网
综述由AI生成如何构建基于 Solidity 的智能合约 DApp。内容包括编写 Counter 合约、配置 Hardhat 环境、使用 ethers.js 连接 MetaMask 钱包实现前端交互,以及通过 Alchemy 节点将合约部署到 Sepolia 测试网。教程涵盖了从本地开发到测试网部署的完整流程,包括私钥管理、网络配置及交易验证。
星河入梦27 浏览 1. DApp 前端代码
在 VSCode 中右键,新增 src 目录,新建 index.html 和 index.ts 文件。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
index.ts
import { ethers } from "ethers";
import { abi } from '../artifacts/contracts/Counter.sol/Counter.json';
function getEth() {
const eth = window.ethereum;
if (!eth) {
throw new Error("No ethereum provider found");
}
return eth;
}
async () {
eth = ();
result = eth.({ : }) [];
result && result. > ;
}
() {
metamask = ();
signers = metamask.({ : }) [];
signers. > ;
}
() {
(! () && ! ()) {
();
}
provider = ethers.(());
address = ;
contract = ethers.(address, abi, provider.());
counter = .();
() {
counter. = contract.();
}
();
btn = .();
btn. = ;
btn. = () {
contract.();
}
contract.(contract..(), () {
counter. = args[].() || contract.();
});
..(counter);
..(btn);
}
() {
();
}
();
function
requestAccess
const
getEth
const
await
request
method
"eth_requestAccounts"
as
string
return
length
0
async
function
hasSigners
const
getEth
const
await
request
method
"eth_accounts"
as
string
return
length
0
async
function
getContract
if
await
hasSigners
await
requestAccess
throw
new
Error
"No ethereum provider found"
const
new
BrowserProvider
getEth
const
"0x5FbDB2315678afecb367f032d93F642f64180aa3"
const
new
Contract
await
getSigner
const
document
createElement
"div"
async
function
getCount
innerHTML
await
getCount
getCount
const
document
createElement
"button"
innerHTML
"increment"
onclick
async
function
await
count
on
filters
CounterInc
async
function
{ args }
innerHTML
0
toString
await
getCount
document
body
appendChild
document
body
appendChild
async
function
main
await
getContract
main
在 package.json 所在目录下新建 webpack.common.js、webpack.dev.js、webpack.prod.js 及 .env 文件。
const dotenv = require("dotenv");
dotenv.config();
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
resolve: {
extensions: [".js", ".ts", ".json"],
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
inject: "body",
}),
],
};
const webpack = require("webpack");
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.common");
module.exports = merge(baseConfig, {
mode: "development",
plugins: [
new webpack.DefinePlugin({
'process.env.CONTRACT_ADDRESS': JSON.stringify(process.env.CONTRACT_ADDRESS),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
}),
],
devServer: {
historyApiFallback: true,
port: 8080,
hot: true
}
});
const webpack = require("webpack");
const baseConfig = require("./webpack.common");
const { merge } = require("webpack-merge");
module.exports = merge(baseConfig, {
mode: "production",
plugins: [
new webpack.DefinePlugin({
'process.env.CONTRACT_ADDRESS': JSON.stringify(process.env.CONTRACT_ADDRESS),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
}),
],
});
PRIVATE_KEY=私钥地址
ALCHEMY_API_KEY=ALCHEMY 的 key
{
"scripts": {
"dev": "webpack serve --config webpack.dev.js",
"build": "webpack --config webpack.prod.js",
"deploy:local": "npx hardhat run scripts/deploy-counter.ts --network localhost"
}
}
2. Solidity 代码
在 contracts 目录下新建 Counter.sol 文件。
pragma solidity ^0.8.24;
import "hardhat/console.sol";
contract Counter {
uint counter;
event CounterInc(uint counter);
function count() public {
counter++;
console.log("Now, counter is: ", counter);
emit CounterInc(counter);
}
function getCount() public view returns (uint) {
return counter;
}
}
3. 编写部署代码
在 package.json 所有目录下新增 scripts 目录,创建 deploy-counter.ts 文件。
import "@nomicfoundation/hardhat-ethers";
import { ethers } from "hardhat";
async function deploy() {
const Counter = await ethers.getContractFactory("Counter");
const counter = await Counter.deploy();
await counter.waitForDeployment();
console.log('counter address is', await counter.getAddress());
return counter;
}
async function count(counter: any) {
await counter.count();
console.log('count is', await counter.getCount());
}
deploy().then(count);
4. 连接小狐狸钱包
创建钱包时建议使用助记词方式,完全自主控制。屏幕显示 12 个单词后请立即手抄保存,不要拍照。
首先在根目录执行以下命令启动本地以太坊区块链节点:
导出测试私钥并导入 MetaMask,确保账户拥有测试 ETH 余额。
5. 启动 Webpack 开发服务器
npx hardhat run scripts/deploy-counter.ts --network localhost
npx webpack serve --config webpack.dev.js
点击连接按钮授权 MetaMask,然后点击 'increment' 按钮调用合约函数。确认弹窗即代表发送区块链交易,合约计数器将递增并触发事件更新界面。
6. 部署到 Alchemy 测试网
注册 Alchemy 账号并创建应用,获取 API Key。
编辑 .env 文件,填入私钥和 Alchemy API Key:
PRIVATE_KEY=填写刚刚复制的私钥,添加前缀 0x
ALCHEMY_API_KEY=nr6k9FBd4Rvwi83XSr6xR
编辑 hardhat.config.ts 文件,配置 sepolia_eth 网络:
import "hardhat-gas-reporter";
import "@nomicfoundation/hardhat-toolbox";
import "@nomicfoundation/hardhat-ethers";
import "@nomicfoundation/hardhat-verify";
const dotenv = require('dotenv');
dotenv.config();
type Config = import('hardhat/config').HardhatUserConfig;
const config: Config = {
solidity: "0.8.28",
networks: {
hardhat: { chainId: 31337 },
sepolia_eth: {
url: `https://eth-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`,
accounts: [process.env.PRIVATE_KEY]
}
},
gasReporter: {
enabled: true
}
};
export default config;
修改 tsconfig.json,注释掉 "strict": true 以避免编译错误。
npx hardhat run scripts/deploy-counter.ts --network sepolia_eth
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online