DApp 开发入门指南

DApp 开发入门指南 🔨

1. DApp 基础概念

1.1 什么是 DApp?

去中心化应用(DApp)是基于区块链的应用程序,特点是:

  • 后端运行在区块链网络
  • 前端可以是任何框架
  • 使用智能合约处理业务逻辑
  • 数据存储在区块链上

1.2 DApp 架构

复制代码
前端 (Web/Mobile)
    ↕️
Web3 接口层
    ↕️
智能合约层
    ↕️
区块链网络

2. 开发环境搭建

2.1 基础工具安装

bash 复制代码
# 安装 Node.js 和 npm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install node

# 安装 Hardhat
npm install --save-dev hardhat

# 安装 Web3.js 或 Ethers.js
npm install web3
# 或
npm install ethers

2.2 项目初始化

bash 复制代码
# 创建新项目
mkdir my-dapp
cd my-dapp

# 初始化项目
npm init -y
npx hardhat init

# 安装前端依赖
npm install react react-dom
npm install @web3-react/core @web3-react/injected-connector

3. 智能合约开发

3.1 合约示例

solidity 复制代码
// contracts/TodoList.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract TodoList {
    struct Task {
        uint id;
        string content;
        bool completed;
    }
    
    mapping(uint => Task) public tasks;
    uint public taskCount;
    
    event TaskCreated(uint id, string content);
    event TaskCompleted(uint id, bool completed);
    
    function createTask(string memory _content) public {
        taskCount++;
        tasks[taskCount] = Task(taskCount, _content, false);
        emit TaskCreated(taskCount, _content);
    }
    
    function toggleCompleted(uint _id) public {
        Task memory _task = tasks[_id];
        _task.completed = !_task.completed;
        tasks[_id] = _task;
        emit TaskCompleted(_id, _task.completed);
    }
}

3.2 合约测试

javascript 复制代码
// test/TodoList.test.js
const { expect } = require("chai");

describe("TodoList", function() {
    let TodoList;
    let todoList;
    let owner;
    
    beforeEach(async function() {
        TodoList = await ethers.getContractFactory("TodoList");
        [owner] = await ethers.getSigners();
        todoList = await TodoList.deploy();
        await todoList.deployed();
    });
    
    it("Should create a new task", async function() {
        await todoList.createTask("Test task");
        const task = await todoList.tasks(1);
        expect(task.content).to.equal("Test task");
    });
});

4. 前端开发

4.1 React 组件示例

jsx 复制代码
// src/components/TodoList.js
import { useState, useEffect } from 'react';
import { ethers } from 'ethers';
import TodoList from '../artifacts/contracts/TodoList.sol/TodoList.json';

const TodoListComponent = () => {
    const [tasks, setTasks] = useState([]);
    const [newTask, setNewTask] = useState('');
    const [contract, setContract] = useState(null);
    
    useEffect(() => {
        const init = async () => {
            if (window.ethereum) {
                const provider = new ethers.providers.Web3Provider(window.ethereum);
                const signer = provider.getSigner();
                const contract = new ethers.Contract(
                    CONTRACT_ADDRESS,
                    TodoList.abi,
                    signer
                );
                setContract(contract);
                loadTasks(contract);
            }
        };
        init();
    }, []);
    
    const loadTasks = async (contract) => {
        const taskCount = await contract.taskCount();
        const loadedTasks = [];
        for (let i = 1; i <= taskCount; i++) {
            const task = await contract.tasks(i);
            loadedTasks.push(task);
        }
        setTasks(loadedTasks);
    };
    
    const createTask = async () => {
        if (!newTask) return;
        try {
            const tx = await contract.createTask(newTask);
            await tx.wait();
            setNewTask('');
            loadTasks(contract);
        } catch (error) {
            console.error("Error creating task:", error);
        }
    };
    
    return (
        <div>
            <h1>Todo List</h1>
            <input
                value={newTask}
                onChange={(e) => setNewTask(e.target.value)}
                placeholder="New task..."
            />
            <button onClick={createTask}>Add Task</button>
            <ul>
                {tasks.map(task => (
                    <li key={task.id.toString()}>
                        {task.content}
                        {task.completed ? " ✓" : ""}
                    </li>
                ))}
            </ul>
        </div>
    );
};

export default TodoListComponent;

4.2 Web3 集成

javascript 复制代码
// src/utils/web3.js
import { InjectedConnector } from '@web3-react/injected-connector';
import { Web3Provider } from '@ethersproject/providers';

export const injected = new InjectedConnector({
    supportedChainIds: [1, 3, 4, 5, 42]
});

export const getLibrary = (provider) => {
    const library = new Web3Provider(provider);
    library.pollingInterval = 12000;
    return library;
};

5. IPFS 集成

5.1 文件存储

javascript 复制代码
import { create } from 'ipfs-http-client';

const ipfs = create({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' });

async function uploadToIPFS(file) {
    try {
        const added = await ipfs.add(file);
        const url = `https://ipfs.infura.io/ipfs/${added.path}`;
        return url;
    } catch (error) {
        console.error('Error uploading file: ', error);
    }
}

5.2 元数据存储

javascript 复制代码
async function saveMetadata(data) {
    const metadata = JSON.stringify(data);
    try {
        const added = await ipfs.add(metadata);
        return added.path;
    } catch (error) {
        console.error('Error saving metadata: ', error);
    }
}

6. 部署和维护

6.1 部署脚本

javascript 复制代码
// scripts/deploy.js
async function main() {
    const TodoList = await ethers.getContractFactory("TodoList");
    const todoList = await TodoList.deploy();
    await todoList.deployed();
    
    console.log("TodoList deployed to:", todoList.address);
}

main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
    });

6.2 监控和维护

javascript 复制代码
// 事件监听
contract.on("TaskCreated", (id, content) => {
    console.log(`New task created: ${content} (ID: ${id})`);
    updateUI();
});

// 错误处理
function handleError(error) {
    if (error.code === 4001) {
        console.log('Transaction rejected by user');
    } else if (error.code === -32603) {
        console.log('Internal JSON-RPC error');
    }
    // 处理其他错误...
}

7. 最佳实践

7.1 安全考虑

  1. 输入验证
  2. 权限控制
  3. 重入攻击防护
  4. Gas 优化

7.2 用户体验

  1. 交易等待提示
  2. 错误友好提示
  3. 离线功能支持
  4. 响应式设计

8. 相关资源

相关推荐
RSABLOCKCHAIN17 小时前
AI Agents in LangGraph-2
人工智能·python
WA内核拾荒者18 小时前
WhatsApp 账号异常检测的自动化告警系统设计
数据库·python·自动化
码流怪侠19 小时前
【GitHub】Bend:让 GPU 并行编程像写 Python 一样简单
python·github
魔力女仆19 小时前
分享一个 JS 鼠标跟随贪吃蛇背景库
开发语言·javascript·计算机外设
2401_8949155319 小时前
GEO 搜索优化完整源码从零部署:环境配置、集群搭建全流程
开发语言·python·tcp/ip·算法·unity
麻瓜老宋20 小时前
AI开发C语言应用按步走,表达式计算器calc的第二十二步,分号赋值链式修复、TOKEN_ASSIGN
c语言·开发语言·atomcode
zhiSiBuYu051721 小时前
Python3 模块开发与应用实战指南
python
颜x小1 天前
[C#] C++与c#语法对比
开发语言·c++·c#
databook1 天前
用方差阈值过滤掉“惰性特征”
python·机器学习·scikit-learn