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. 相关资源

相关推荐
love530love2 分钟前
【笔记】 Podman Desktop 中部署 Stable Diffusion WebUI (GPU 支持)
人工智能·windows·笔记·python·容器·stable diffusion·podman
程序员晚枫21 分钟前
Python 3.14正式发布!这5大新特性太炸裂了
python
自学AI的鲨鱼儿29 分钟前
ubuntu22.04安装gvm管理go
开发语言·后端·golang
先做个垃圾出来………31 分钟前
SortedList
python
这里有鱼汤33 分钟前
从DeepSeek到Kronos,3个原因告诉你:Kronos如何颠覆传统量化预测
后端·python·aigc
晓宜42 分钟前
Java25 新特性介绍
java·python·算法
旭意44 分钟前
C++微基础备战蓝桥杯之数组篇10.1
开发语言·c++·蓝桥杯
深栈1 小时前
机器学习:决策树
人工智能·python·决策树·机器学习·sklearn
MediaTea1 小时前
Python:匿名函数 lambda
开发语言·python
R-G-B1 小时前
【06】C#入门到精通——C# 多个 .cs文件项目 同一项目下添加多个 .cs文件
开发语言·c#·c# 多个 .cs文件项目