从零开始:以太坊Dapp开发全流程教程**

区块链技术的兴起,特别是以太坊平台的成熟,为去中心化应用(DApps)的开发提供了广阔的天地,DApp结合了智能合约的强大后端与用户友好的前端,为互联网带来了新的可能性,本教程将带你一步步了解以太坊DApp开发的核心概念和基本流程,助你迈出构建自己去中心化应用的第一步。
什么是DApp?
DApp(Decentralized Application),即去中心化应用,与传统的中心化应用不同,其后端运行在一个去中心化的点对点网络上(如以太坊),而不是依赖单一的服务器,智能合约构成了DApp的核心逻辑和业务规则,存储在区块链上,一旦部署便不可篡改,前端则与传统应用类似,可以是网页、移动端等,用户通过前端与智能合约进行交互。
以太坊DApp开发的核心组件
在开始开发之前,我们需要了解几个核心组件:
开发环境准备
在动手之前,我们需要搭建好开发环境:
# 全局安装Hardhat npm install --save-dev hardhat
开发流程详解
步骤1:初始化项目与配置Hardhat

cd my-dapp # 初始化Hardhat项目 npx hardhat init
按照提示选择Create a JavaScript project,然后选择Yes添加.gitignore文件和示例测试,完成后,你会看到一个包含contracts/, scripts/, test/等目录的项目结构。
步骤2:编写智能合约
在contracts目录下,创建一个新的Solidity文件,例如SimpleStorage.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private _storedData;
event DataUpdated(uint256 newValue);
function set(uint256 x) public {
_storedData = x;
emit DataUpdated(x);
}
function get() public view returns (uint256) {
return _storedData;
}
}
这个简单的合约包含一个set函数(存储一个整数)和一个get函数(获取存储的整数)。
步骤3:编译智能合约
Hardhat会自动配置好编译环境,在项目根目录运行:
npx hardhat compile
编译成功后,会在artifacts/contracts/目录下生成ABI(Application Binary Interface)和字节码(Bytecode)文件,这些是与前端交互所必需的。
步骤4:部署智能合约
在scripts目录下,创建一个部署脚本,例如deploy.js:

async function main() {
// 获取合约工厂
const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
// 部署合约
const simpleStorage = await SimpleStorage.deploy();
// 等待部署完成
await simpleStorage.deployed();
console.log("SimpleStorage deployed to:", simpleStorage.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
配置Hardhat连接到测试网(如Goerli),你需要从 faucet 获取一些测试ETH,在项目根目录创建.env文件,并添加你的私钥(注意安全,不要提交到代码仓库!)和Alchemy或Infura的RPC URL:
PRIVATE_KEY=你的私钥
GOERLI_RPC_URL=https://goerli.infura.io/v3/你的项目ID
安装dotenv:
npm install --save-dev dotenv
修改hardhat.config.js,添加网络配置:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.17",
networks: {
goerli: {
url: process.env.GOERLI_RPC_URL,
accounts: [process.env.PRIVATE_KEY],
},
},
};
部署到测试网:
npx hardhat run scripts/deploy.js --network goerli
部署成功后,你会得到合约的地址,记下它,我们将在前端使用。
步骤5:开发前端
在项目根目录安装ethers.js:
npm install ethers
创建一个简单的index.html文件和一个app.js文件:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">以太坊DApp示例</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
input, button { padding: 8px; margin: 5px; }
#result { margin-top: 10px; font-weight: bold; }
</style>
</head>
<body>
<h1>SimpleStorage DApp</h1>
<div>
<input type="number" id="numberInput" placeholder="输入一个数字">
<button onclick="setNumber()">设置</button>
<button onclick="getNumber()">获取</button>
</div>
<div id="result"></div>
<script src="app.js"></script>
</body>
</html>
app.js:
// 合约地址(部署后替换)
const contractAddress = "0x...你的合约地址...";
// 合约ABI(从artifacts/contracts/SimpleStorage.sol/SimpleStorage.json中复制)
const contractABI = [
// 这里粘贴完整的ABI数组
"function set(uint256 x) public",
"function get() public view returns (uint256)",
// ... 其他ABI项
];
let ethereum;
let simpleContract;
// 检查并连接MetaMask
window.addEventListener('load', async () => {
if (window.ethereum) {
ethereum = window.ethereum;
try {
// 请求账户访问
await ethereum.request({ method: 'eth_requestAccounts' });
console.log('MetaMask connected!');
initContract();
} catch (error) {
console.error('User denied account access', error);
}
} else {
console.error('MetaMask not installed! Please install MetaMask.');
document.getElementById('result').innerText = '请安装MetaMask!';
}
});
// 初始化合约
async function initContract() {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
simpleContract = new ethers.Contract(contractAddress, contractABI, signer);
}
// 设置数字
async function setNumber() {
const numberInput = document.getElementById('numberInput');
const number = numberInput.value;
if (!number) {
alert('请输入一个数字!');
return;
}
try {
const tx = await simpleContract.set(number);
await tx.wait();
document.getElementById('result').innerText = `设置成功!交易哈希: ${tx.hash}`;
numberInput.value
免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com