在区块链开发中,DApp(去中心化应用)的开发往往涉及到多个层次:前端、合约和后端。今天我们将演示如何将 Vue 前端、Hardhat 合约 和 Node.js 后端 放在一个项目中,来打造一个完整的区块链应用。
1. 项目结构
我们的目标是创建一个 Monorepo 项目,将所有代码放在同一个仓库里。这样有助于我们统一管理依赖、版本,并能方便地实现前后端协作。
项目的结构如下:
my-dapp-project/
│
├── contracts/ # Hardhat 合约代码
│ ├── MyContract.sol
│ ├── hardhat.config.js
│ └── ...
│
├── scripts/ # Hardhat 部署与交互脚本
│ ├── deploy.js
│ └── ...
│
├── test/ # Hardhat 测试代码
│
├── frontend/ # Vue 前端
│ ├── src/
│ ├── public/
│ ├── package.json
│ └── vite.config.js
│
├── backend/ # 后端服务(Node.js / Express / NestJS 等)
│ ├── src/
│ ├── package.json
│ └── server.js
│
├── shared/ # (可选)前后端共享代码/类型
│ └── contract-types/
│
├── package.json # 根目录 package.json(可用来管理全部子项目依赖)
├── README.md
└── .gitignore
2. 环境搭建
首先,我们需要初始化项目的根目录并安装相关依赖。
2.1 初始化根目录
mkdir my-dapp-project
cd my-dapp-project
npm init -y
2.2 安装 Hardhat
npm install --save-dev hardhat
npx hardhat init
2.3 创建 Vue 前端
我们将在 frontend/
文件夹中创建 Vue 项目。使用 Vue CLI 来创建前端应用:
cd frontend
npm init vue@latest
npm install
2.4 创建 Node.js 后端
在 backend/
文件夹中,我们将创建一个简单的 Node.js 服务来处理后端逻辑:
cd backend
npm init -y
npm install express ethers
在 backend/src/server.js
中,我们会创建一个简单的 Express 服务来监听和处理合约事件。
3. 编写合约
我们将创建一个简单的智能合约 MyContract.sol
,它包含一个简单的存取款功能。
3.1 创建 contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract MyContract {uint256 public balance;function deposit(uint256 amount) public {balance += amount;}function withdraw(uint256 amount) public {require(amount <= balance, "Insufficient funds");balance -= amount;}
}
3.2 部署合约
在 scripts/deploy.js
文件中,我们编写部署脚本:
const hre = require("hardhat");async function main() {const [deployer] = await hre.ethers.getSigners();console.log("Deploying contracts with the account:", deployer.address);const MyContract = await hre.ethers.getContractFactory("MyContract");const contract = await MyContract.deploy();console.log("MyContract deployed to:", contract.address);
}main().catch((error) => {console.error(error);process.exitCode = 1;
});
部署合约后,我们将得到合约地址,并将其传递给前端和后端。
4. 后端与智能合约交互
在后端,我们将使用 ethers.js
连接到区块链,并提供一些 API 来让前端调用智能合约。
4.1 创建后端 server.js
const express = require('express');
const { ethers } = require('ethers');
const app = express();
const port = 3000;// 连接到以太坊节点
const provider = new ethers.JsonRpcProvider('http://localhost:8545');// 智能合约 ABI 和地址
const abi = ["function deposit(uint256 amount) public","function balance() public view returns (uint256)"
];
const contractAddress = 'YOUR_CONTRACT_ADDRESS_HERE';// 创建合约实例
const contract = new ethers.Contract(contractAddress, abi, provider);app.get('/balance', async (req, res) => {const balance = await contract.balance();res.json({ balance: balance.toString() });
});app.post('/deposit', express.json(), async (req, res) => {const { amount } = req.body;const signer = provider.getSigner();const contractWithSigner = contract.connect(signer);await contractWithSigner.deposit(amount);res.json({ message: 'Deposit successful' });
});app.listen(port, () => {console.log(`Server running at http://localhost:${port}`);
});
在这个简单的 Node.js 后端中,我们提供了 /balance
和 /deposit
API,用于查询余额和执行存款操作。
5. 前端与后端交互
在前端,我们将使用 ethers.js
连接到智能合约,并调用合约方法。同时,我们也会通过 API 与后端进行交互。
5.1 安装 ethers.js
cd frontend
npm install ethers
5.2 Vue 前端调用合约
在 Vue 中,我们可以通过 ethers.js
调用智能合约。以下是一个简单的 Vue 组件示例,展示如何与智能合约交互:
<template><div><h1>Balance: {{ balance }}</h1><button @click="deposit">Deposit 10</button></div>
</template><script>
import { ethers } from 'ethers';export default {data() {return {balance: 0,contract: null,};},async mounted() {const provider = new ethers.JsonRpcProvider('http://localhost:8545');const abi = ["function deposit(uint256 amount) public","function balance() public view returns (uint256)"];const contractAddress = 'YOUR_CONTRACT_ADDRESS_HERE';this.contract = new ethers.Contract(contractAddress, abi, provider);this.updateBalance();},methods: {async updateBalance() {this.balance = await this.contract.balance();},async deposit() {const signer = this.contract.provider.getSigner();const contractWithSigner = this.contract.connect(signer);await contractWithSigner.deposit(10);this.updateBalance();}}
};
</script>
6. 启动项目
// 1. 启动本地链:
npx hardhat run scripts/deploy.js --network localhost// 2. 部署合约:
npx hardhat run scripts/deploy.js --network localhost// 3. 启动后端服务
cd backend
node src/server.js// 4. 启动前端服务:
cd frontend
npm run dev
总结
通过将 Vue 前端、Hardhat 合约 和 Node.js 后端 放在同一个项目中,我们可以方便地管理所有代码和依赖,创建一个完整的去中心化应用(DApp)。在这个示例中,前端与后端通过智能合约交互,后端提供了一些 API 来简化与合约的通信。
这个结构不仅适用于简单的 DApp 项目,也可以扩展到更复杂的应用,支持更多的区块链交互、API 处理和前端功能。