目录
[📌 项目简介:留言上链 DApp(MessageBoard DApp)](#📌 项目简介:留言上链 DApp(MessageBoard DApp))
[🧠 技术栈](#🧠 技术栈)
[🔶 1. Solidity 智能合约代码(MessageBoard.sol)](#🔶 1. Solidity 智能合约代码(MessageBoard.sol))
[🔷 2. 前端代码(index.html + script.js)](#🔷 2. 前端代码(index.html + script.js))
[📄 index.html](#📄 index.html)
[📜 script.js](#📜 script.js)
[💅 style.css](#💅 style.css)
[🧪 测试建议](#🧪 测试建议)
📌 项目简介:留言上链 DApp(MessageBoard DApp)
-
用户可以输入留言,点击按钮后信息将上链保存。
-
展示所有用户的留言。
-
使用以太坊测试网部署合约。
🧠 技术栈
-
Solidity(智能合约)
-
Ethers.js(前端与链交互)
-
HTML/CSS/JS(简单前端)
-
Remix + Metamask + 测试网(部署)
🔶 1. Solidity 智能合约代码(MessageBoard.sol)
bash
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract MessageBoard {
struct Message {
address sender;
string content;
uint256 timestamp;
}
Message[] public messages;
event NewMessage(address indexed sender, string content, uint256 timestamp);
function postMessage(string calldata _content) public {
messages.push(Message(msg.sender, _content, block.timestamp));
emit NewMessage(msg.sender, _content, block.timestamp);
}
function getMessages() public view returns (Message[] memory) {
return messages;
}
function getMessageCount() public view returns (uint256) {
return messages.length;
}
}
部署提示:使用 Remix IDE,连接 Metamask 钱包选择测试网(如 Sepolia),部署后复制合约地址。
🔷 2. 前端代码(index.html + script.js)
📄 index.html
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>留言上链 DApp</title>
<script src="https://cdn.jsdelivr.net/npm/ethers/dist/ethers.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>留言上链 DApp</h1>
<textarea id="messageInput" placeholder="请输入留言内容"></textarea><br />
<button onclick="postMessage()">发送留言</button>
<button onclick="loadMessages()">刷新留言</button>
<div id="messageList"></div>
<script src="script.js"></script>
</body>
</html>
📜 script.js
javascript
const contractAddress = "你的合约地址";
const contractABI = [
// 仅保留必要的 ABI 函数
"function postMessage(string _content)",
"function getMessages() view returns (tuple(address sender, string content, uint256 timestamp)[])"
];
let provider, signer, contract;
async function init() {
if (typeof window.ethereum !== 'undefined') {
provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
signer = provider.getSigner();
contract = new ethers.Contract(contractAddress, contractABI, signer);
loadMessages();
} else {
alert("请安装 Metamask 插件");
}
}
async function postMessage() {
const message = document.getElementById("messageInput").value;
if (!message) return alert("请输入内容");
const tx = await contract.postMessage(message);
await tx.wait();
alert("留言已上链!");
loadMessages();
}
async function loadMessages() {
const messages = await contract.getMessages();
const list = document.getElementById("messageList");
list.innerHTML = "";
messages.forEach((msg) => {
const div = document.createElement("div");
const time = new Date(msg.timestamp * 1000).toLocaleString();
div.innerText = `🗨️ ${msg.content}\n👤 ${msg.sender}\n🕒 ${time}`;
div.style.margin = "12px";
list.appendChild(div);
});
}
window.onload = init;
💅 style.css
javascript
body {
font-family: sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
textarea {
width: 100%;
height: 80px;
margin-bottom: 10px;
}
button {
margin-right: 10px;
}
🧪 测试建议
-
用 Remix 部署合约到 Sepolia 测试网。
-
在前端代码中替换
contractAddress
。 -
用浏览器打开
index.html
文件(确保开启 Metamask)。 -
输入留言并发送,刷新查看链上内容。