.jpg)
随着区块链技术的发展,去中心化应用(DApp)正逐渐改变我们对互联网交互的认知,以太坊作为全球最大的智能合约平台,为DApp开发提供了成熟的底层支持,本文将以一个简单的“任务清单(Todo List)”DApp为例,带大家从零开始了解以太坊DApp的开发流程,包括智能合约编写、部署、前端交互以及测试全流程,即使你是区块链新手,也能通过本示例快速上手DApp开发的核心概念。
开发环境准备
在开始之前,我们需要搭建以下开发环境:
安装Node.js和npm
Node.js是JavaScript运行时环境,npm是Node.js的包管理器,前往Node.js官网下载LTS版本并安装(安装时会自动配置npm)。
安装Truffle框架
Truffle是以太坊最流行的智能合约开发框架,提供了编译、测试、部署等一站式工具,打开终端,运行:
npm install -g truffle
安装Ganache
Ganache是一个个人区块链,用于本地开发和测试,它会预先分配100个测试账户,每个账户有100个ETH,方便我们模拟交易。
- 下载地址:Ganache官网
- 下载后安装并启动,选择“Quickstart”即可创建一个本地私有链。
安装MetaMask
MetaMask是浏览器钱包,用于与以太坊网络交互(包括本地网络)。
- 下载地址:MetaMask官网
- 安装浏览器插件后,点击“创建钱包”,按照提示设置密码并备份助记词(助记词需妥善保管,泄露将导致资产丢失)。
创建项目结构
在本地创建一个项目文件夹(如TodoListDApp),并初始化项目:
mkdir TodoListDApp cd TodoListDApp npm init -y
使用Truffle创建标准项目结构:
truffle init
执行后,项目目录会生成以下文件夹:
contracts/:存放智能合约代码migrations/:存放部署脚本test/:存放测试文件truffle-config.js:Truffle配置文件
编写智能合约
智能合约是DApp的核心,运行在以太坊网络上,定义了业务逻辑,我们在contracts/目录下创建TodoList.sol文件,编写一个简单的任务清单合约:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TodoList {
// 定义任务结构体
struct Task {
uint id;
string content;
bool completed;
}
// 存储任务列表,键为任务ID,值为任务结构体
mapping(uint => Task) public tasks;
// 记录任务总数
uint public taskCount = 0;
// 创建任务的函数
function createTask(string memory _content) public {
taskCount++;
tasks[taskCount] = Task(taskCount, _content, false);
}
// 切换任务完成状态的函数
function toggleCompleted(uint _id) public {
Task storage task = tasks[_id];
task.completed = !task.completed;
}
// 删除任务的函数(可选)
function deleteTask(uint _id) public {
delete tasks[_id];
taskCount--; // 注意:实际项目中需更严谨的ID管理
}
}
代码解析:
SPDX-License-Identifier:许可证标识,MIT表示开源。pragma solidity ^0.8.0:指定Solidity版本,^0.8.0表示兼容0.8.0及以上版本。struct Task:定义任务结构体,包含ID、内容和完成状态。mapping(uint => Task):存储任务列表,类似键值对存储。createTask:创建新任务,taskCount自增作为任务ID。toggleCompleted:切换任务的完成状态(true/false)。
编译智能合约
在终端运行以下命令,编译智能合约:
truffle compile
编译成功后,build/contracts/目录会生成TodoList.json文件,这是合约的ABI(应用程序二进制接口)和字节码,后续前端交互需要用到。
部署智能合约
部署是将智能合约上传到以太坊网络的过程,我们使用migrations/目录下的部署脚本。
编写部署脚本
在migrations/目录下创建2_deploy_todo_list.js文件(文件名以数字_开头,Truffle会按顺序执行):
const TodoList = artifacts.require("TodoList");
module.exports = function (deployer) {
deployer.deploy(TodoList);
};
配置网络
打开truffle-config.js,配置本地网络(Ganache的默认端口是7545):
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545, // Ganache默认端口
network_id: "*", // 匹配任何网络ID
},
},
compilers: {
solc: {
version: "0.8.0", // 与合约版本一致
},
},
};
执行部署
确保Ganache正在运行,在终端执行:
truffle migrate --network development
部署成功后,终端会显示合约地址(如TodoList address: 0x5FbDB2315678afecb367f032d93F642f64180aa3),这个地址是后续交互的关键。
开发前端界面
前端是用户与DApp交互的入口,我们使用React(基于HTML/CSS/JavaScript)来构建。
安装React
在项目根目录下创建client文件夹,并初始化React项目:
npx create-react-app client cd client npm install
安装web3.js
web3.js是用于与以太坊交互的JavaScript库,我们需要安装它:
npm install web3
连接MetaMask
打开client/src/App.js,编写代码连接MetaMask并加载合约:
import React, { useEffect, useState } from "react";
import Web3 from "web3";
import TodoList from "./TodoList.json"; // 导入合约ABI
function App() {
const [web3, setWeb3] = useState(null);
const [account, setAccount] = useState("");
const [contract, setContract] = useState(null);
const [tasks, setTasks] = useState([]);
const [taskContent, setTaskContent] = useState("");
// 初始化Web3和合约
useEffect(() => {
const init = async () => {
// 检查MetaMask是否安装
if (window.ethereum) {
const web3Instance = new Web3(window.ethereum);
try {
// 请求账户权限
await window.ethereum.request({ method: "eth_requestAccounts" });
const accounts = await web3Instance.eth.getAccounts();
setAccount(accounts[0]);
// 加载合约
const networkId = await web3Instance.eth.net.getId();
const deployedNetwork = TodoList.networks[networkId];
const contractInstance = new web3Instance.eth.Contract(
TodoList.abi,
deployedNetwork && deployedNetwork.address
);
setContract(contractInstance);
// 加载任务列表
const taskCount = await contractInstance.methods.taskCount().call();
const loadedTasks = [];
for (let i = 1; i <= taskCount; i++) {
const task = await contractInstance.methods.tasks(i).call();
loadedTasks.push(task);
}
setTasks(loadedTasks);
} catch (error) {
console.error("初始化失败:", error);
}
} else {
alert("请安装MetaMask!");
}
};
init();
}, []);
// 创建任务
const createTask = async () => {
if (!taskContent.trim()) return;
try {
await contract.methods.createTask(taskContent).send({ from: account });
// 重新加载任务列表
const taskCount = await contract.methods.taskCount().call();
const loadedTasks = [];
for (let i = 1; i <= taskCount; i++) {
const task = await contract.methods.tasks(i).call();
loadedTasks.push(task);
}
setTasks(loadedTasks);
setTaskContent("");
} catch (error) {
console.error("创建任务失败:", error);
}
};
// 切换任务状态
const toggleCompleted =本文来自用户投稿,不代表币大大立场,如若转载,请注明出处:https://czxurui.com/jys/300353.html


发表回复
评论列表(0条)