:2026-09-18 11:18 点击:2
随着区块链技术的飞速发展,去中心化应用(DApp)正逐渐从概念走向现实,以太坊作为全球最大的智能合约平台,无疑是DApp开发的首选阵地,本文将带你走进以太坊DApp的实战开发世界,从基础概念到实际操作,为你铺设一条清晰的入门路径。
在动手之前,我们首先要明确几个核心概念:
为何选择以太坊? 以太坊是第一个支持图灵完备智能合约的区块链平台,拥有庞大的开发者社区、成熟的开发工具链(如Truffle, Hardhat, Web3.js)、丰富的生态资源(如OpenSea, Uniswap)以及强大的ERC代币标准(如ERC-20, ERC-721),这些都使其成为DApp开发的热土。
一个典型的以太坊DApp通常由以下几个部分组成:
实战的第一步是搭建开发环境:
npm install -g truffle
让我们通过一个简单的“投票DApp”来体验开发流程,这个DApp允许用户对特定提案进行投票。
创建一个新的项目目录,并初始化一个Truffle项目:
mkdir voting-dapp cd voting-dapp truffle init
这会创建几个文件夹:contracts/(存放智能合约)、migrations/(部署脚本)、test/(测试文件)以及truffle-config.js(配置文件)。
在contracts/目录下创建一个新的Solidity文件,例如Voting.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Voting {
// 提案名称到得票数的映射
mapping(string => uint256) public votes;
// 投票人地址,防止重复投票
mapping(address => bool) public hasVoted;
// 提案列表
string[] public proposals;
constructor(string[] memory _proposals) {
proposals = _proposals;
}
// 投票函数
function vote(string memory proposalName) public {
require(!hasVoted[msg.sender], "You have already voted.");
bool proposalExists = false;
for (uint i = 0; i < proposals.length; i++) {
if (keccak256(bytes(proposals[i])) == keccak256(bytes(proposalName))) {
proposalExists = true;
break;
}
}
require(proposalExists, "Proposal does not exist.");
votes[proposalName]++;
hasVoted[msg.sender] = true;
}
// 获取提案得票数
function getVotes(string memory proposalName) public view returns (uint256) {
return votes[proposalName];
}
}
这个合约定义了投票的基本功能:初始化提案列表、投票、查询得票数,并防止重复投票。
在项目根目录运行:
truffle compile
如果成功,build/contracts/目录下会生成Voting.json文件,这是合约的ABI(应用程序二进制接口)和字节码。
在migrations/目录下创建一个新的部署脚本,例如2_deploy_voting.js:
const Voting = artifacts.require("Voting");
module.exports = function (deployer) {
// 部署合约时传入提案列表
deployer.deploy(Voting, ["Proposal 1", "Proposal 2", "Proposal 3"]);
};
部署到本地Ganache:
确保Ganache正在运行,且端口与truffle-config.js中配置的一致(默认7545),然后运行:
truffle migrate --network development
部署到测试网(如Goerli):
truffle-config.js中配置Goerli网络信息(需要Infura等节点服务URL和你的测试网私钥)。truffle migrate --network goerli。部署成功后,你可以在build/contracts/Voting.json中找到合约地址。
在项目根目录下创建src/文件夹,用于存放前端代码,安装Web3.js库:
npm install web3
创建src/index.html和src/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">Voting DApp</title>
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="app.js" defer></script>
</head>
<body>
<h1>以太坊投票DApp</h1>
<div id="proposals"></div>
<div id="result"></div>
<input type="text" id="voteInput" placeholder="输入提案名称投票">
<button id="voteButton">投票</button>
</body>
</html>
app.js:
let contract;
let web3;
let accounts;
// 合约ABI(从build/contracts/Voting.json中复制)
const abi = [
// 这里粘贴Voting.json中的abi数组
// 为了简洁,这里省略,实际开发中请完整复制
{
"inputs": [
{
"internalTyp
e": "string[]",
"name": "_proposals",
"type": "string[]"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "proposals",
"outputs": [
{
"internalType": "string[]",
"name": "",
"type": "string[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "proposalName",
"type": "string"
}
],
"name": "getVotes",
"outputs": [
{
"internalType": "
本文由用户投稿上传,若侵权请提供版权资料并联系删除!