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><inputvalue={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.mzph.cn/bicheng/71508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙状态管理概述 v2

状态管理v2 概述状态管理之v2ObservedV2 和 Trace状态管理V1版本对嵌套类对象属性变化直接观测的局限性ObservedV2 和 Trace 使用场景 Local状态管理V1版本State装饰器的局限性 Param状态管理V1版本接受外部传入的装饰器的局限性 OnceEventComputedComputed 使用场景 TypePersi…

Git中revert和reset区别?

git revert 和 git reset 都用于撤销 Git 中的提交&#xff0c;但它们的作用和使用场景不同&#xff1a; git revert: 作用&#xff1a;创建一个新的提交&#xff0c;撤销指定的提交内容。使用场景&#xff1a;用于“回滚”已推送到远程仓库的提交。这种方法不会改变提交历史&a…

LabVIEW开发中的电机控制与相机像素差

在电机控制系统中&#xff0c;我们需要精确控制电机运动与相机拍摄画面之间的关系。理想情况下&#xff0c;当电机带动相机移动同样的距离时&#xff0c;相机拍摄画面中两点之间的像素差应当是一个固定值。然而&#xff0c;在实际应用中&#xff0c;我们发现这一像素差并非固定…

从零到一:构建现代 React 应用的完整指南

1. create-react-app (CRA) 简介: create-react-app 是官方推荐的 React 项目脚手架工具,提供了一个开箱即用的开发环境,帮助开发者快速启动 React 应用。它会自动配置 Webpack、Babel、ESLint 等工具,让你专注于开发而不需要手动配置工具链。 特点: 零配置:CRA 自动配…

rman 备份恢复1

前提&#xff1a; rman用户必须具有sysdba权限 使用常用连接方式如下&#xff1a; rman target / rman target sys/oracle rman target sys/oracleprod1 catalog dav/oracledav_db 一个rman连接会产生两个进程&#xff0c;action字段为空的就是rman的监控进程&#xff0c;另…

Qt程序退出相关资源释放问题

目录 问题背景&#xff1a; aboutToQuit 代码举例 closeEvent事件 代码举例 程序退出方式 quit() exit(int returnCode 0) close() 问题背景&#xff1a; 实际项目中程序退出前往往需要及进行一些资源释放、配置保存、线程中断等操作&#xff0c;避免资源浪费&#xff…

【DeepSeek】Mac m1电脑部署DeepSeek

一、电脑配置 个人电脑配置 二、安装ollama 简介&#xff1a;Ollama 是一个强大的开源框架&#xff0c;是一个为本地运行大型语言模型而设计的工具&#xff0c;它帮助用户快速在本地运行大模型&#xff0c;通过简单的安装指令&#xff0c;可以让用户执行一条命令就在本地运…

[生活杂项][运动教程]自由泳

https://v.youku.com/v_show/id_XMzgzMjkwMzg0MA.html?spma2h0k.11417342.soresults.dtitle https://v.youku.com/v_show/id_XMzgxNjM2NjY4NA.html?spma2h0k.11417342.soresults.dtitle

Linux的指令与热键

一.指令 1.pwd :显示一个用户当前所处的目录 2.ls :显示当前目录下的文件&#xff08;显示当前文件属性&#xff09; ls -l :显示当前目录下文件的属性及更多内容&#xff08;ll是ls -l的别名&#xff0c;用法相同&#xff09; ls -l 目录&#xff1a;显示指定目录内容 ls…

【Dubbo+Zookeeper】——SpringBoot+Dubbo+Zookeeper知识整合

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

【OS安装与使用】part5-ubuntu22.04基于conda安装pytorch+tensorflow

文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 明确pytorch安装依赖2.2.2 conda创建虚拟环境2.2.3 安装pytorch2.2.4 验证pytorch安装2.2.5 安装Tensorflow2.2.6 验证Tensorflow安装 三、疑问四、总结 一、待解决问题 1.1 问题…

马拉车算法

Manacher算法 ,用于处理最长回文字符串的问题&#xff0c;可以在O&#xff08;n&#xff09;的情况下&#xff0c;求出一个字符串的最长回文字符串 回文串的基础解法&#xff1a; 以每个点为中心对称点&#xff0c;看左右两边的点是否相同。这种算法的时间复杂度为O&#xff0…

气象学中的CDO插值(多方法+多分辨率)

文章目录 说明CDO代码 说明 需要新建.sh脚本文件&#xff0c;将下面的CDO代码复制到.sh脚本中&#xff0c;然后运行插值程序。 CDO代码 #!/bin/bash # # 用户配置区&#xff08;按实际需求修改&#xff09; # input_directory"2m_temperature" # 自定义路径 gr…

计算机网络:应用层 —— 动态主机配置协议 DHCP

文章目录 什么是 DHCP&#xff1f;DHCP 的产生背景DHCP 的工作过程工作流程地址分配机制 DHCP 中继代理总结 什么是 DHCP&#xff1f; 动态主机配置协议&#xff08;DHCP&#xff0c;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;用于自动分…

【OS安装与使用】part3-ubuntu安装Nvidia显卡驱动+CUDA 12.4

文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 更改镜像源2.2.2 安装NVIDIA显卡驱动&#xff1a;nvidia-550&#xff08;1&#xff09;查询显卡ID&#xff08;2&#xff09;PCI ID Repository查询显卡型号&#xff08;3&#xf…

数据导入AI训练步骤——人工智能训练

一、人工操作转化 数据导入过程 整理excel表格&#xff0c;通过数据库管理工具导入数据&#xff0c;补充数据格式&#xff0c;调整sql语句 复制数据到目标数据 二、整理表格 三、导入数据 通过数据库导入数据 四、合并 五、验证更新数据 六、 更新数据 update temp_cus_hmz…

我国首条大型无人机城际低空物流航线成功首航

首航震撼开场&#xff1a;羊肉 “飞” 越 540 公里 在夜色的笼罩下&#xff0c;榆阳马合通用机场的跑道上&#xff0c;一架大型固定翼无人机蓄势待发&#xff0c;机身被灯光照亮&#xff0c;宛如一只即将展翅翱翔的钢铁巨鸟。它的货舱里&#xff0c;满满装载着新鲜的榆林羊肉&a…

《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一&#xff1a;AlexNet【下】【论文精读】】的心得。 《跟李沐…

微软Win11新动态:官方“换机助手”曝光,PC数据迁移或迎全新体验

目录 微软入局数据迁移领域,第三方工具或面临挑战 无缝迁移体验:近距离传输与OTP验证 模拟图仅为概念设计,最终功能或存变数 发布时间未定,Insider用户或率先体验 总结 微软在近期发布了Windows 11 Insider Beta频道的最新版本Build 22635.4945。尽管此次更新并未引入重…

Could not initialize class io.netty.util.internal.Platfor...

异常信息&#xff1a; Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class io.netty.util.internal.PlatformDependent0 Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjec…