当前位置: 首页 > article >正文

DApp 开发入门指南

DApp 开发入门指南 🔨

在这里插入图片描述

1. DApp 基础概念

1.1 什么是 DApp?

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

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

1.2 DApp 架构

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

2. 开发环境搭建

2.1 基础工具安装

# 安装 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 项目初始化

# 创建新项目
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 合约示例

// 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 合约测试

// 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 组件示例

// 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 集成

// 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 文件存储

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 元数据存储

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 部署脚本

// 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 监控和维护

// 事件监听
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. 相关资源

  • React 文档
  • Hardhat 文档
  • IPFS 文档
  • Web3.js 文档
  • Ethers.js 文档

http://www.kler.cn/a/559052.html

相关文章:

  • 【ubuntu24.04】pycharm安装pygraphviz
  • 一文熟练掌握Spring Framework
  • ElasticSearch查询指南:从青铜到王者的骚操作
  • 【linux核心命令】
  • 从零开始:VirtualBox安装Ubuntu 24.04.1 LTS
  • k8s学习记录:环境搭建(基于Kubeadmin)
  • 计算机毕业设计SpringBoot+Vue.jst0甘肃非物质文化网站(源码+LW文档+PPT+讲解)
  • Mybatis-Plus使用page类实现分页查询
  • 多源BFS(典型算法思想)—— OJ例题算法解析思路
  • Denoising Diffusion Restoration Models论文解读
  • matlab二维艾里光束,阵列艾里光束,可改变光束直径以及距离
  • 基于python+django的宠物商店-宠物管理系统源码+运行步骤
  • 深入解析Zookeeper脑裂问题与CAP取舍:从原理到实战
  • 【MLLM】GRPO在多模态LLM的应用
  • 学术论文翻译
  • Java【网络原理】(1)初识网络
  • 中间件专栏之redis篇——redis基本原理、概念及其相关命令介绍
  • 《Restormer:高效Transformer架构用于高分辨率图像恢复》学习笔记
  • Linux-Ansible命令
  • 多线程篇学习面试