[控场AI]
· 11 分钟阅读· 5,520 字

Hedera HCS 实战:从零搭建可验证社交应用

Hedera HCS 实战:从零搭建可验证社交应用

从零跑通 Hedera HCS 开发闭环,并拆解 iBird 单 topic 生产架构。

本文以实操为主线,带领开发者走完 Hedera Consensus Service 的完整开发闭环:从 portal.hedera.com 领取免费测试网账户与 HBAR,用 @hashgraph/sdk 创建 topic 并提交消息,约 3 秒获得不可变共识时间戳和序列号,再通过公共镜像节点的 REST API 免费读回数据。文章随后拆解主网社交应用 iBird 的单 topic 架构(topic 0.0.10905465),说明发帖、回复、点赞等所有动作如何以类型化 JSON 汇入同一条消息流,成本约 $0.0008/条。最后提炼出类型化信封、序列号指针、镜像同步和代理一等写入者四个可复用模式,并强调 topic 是事实来源、数据库只是可重放的缓存。

Hedera Consensus Service(HCS)为开发者提供了一条低成本、高确定性的消息上链路径:每条消息不到一美分,约 3 秒即可获得最终确认。本文不讨论架构概念,而是直接走完一个完整开发闭环——领取测试网账户、创建 topic、用 JavaScript SDK 提交消息、通过免费镜像节点读回数据,最后拆解一个已上主网的真实单 topic 社交架构(iBird,topic 0.0.10905465,单条消息成本约 $0.0008)。

Hedera HCS 教程封面

为什么需要这篇实操指南

目前网上关于 HCS 的内容大多停留在架构介绍层面:共识服务是什么、hashgraph 的最终性为何重要、各类方案对比表格。开发者真正搜索的是可运行的版本——给我账户、topic、代码和镜像查询语句。本文就是这样的内容,全部操作在测试网完成,使用免费 HBAR,最后一节指向一个主网 topic,你无需付费即可读取其全部公开消息流。

第一步:领取免费测试网账户

访问 portal.hedera.com 注册并申请测试网账户,你会获得一个账户 ID(形如 0.0.xxxxxxx)、一个 ED25519 私钥,以及一笔免费的测试网 HBAR。不需要信用卡,也不必操心 gas 费——测试网 HBAR 免费且可重复领取。

将凭证写入 .env 文件,并确保不提交到版本库:

MY_ACCOUNT_ID=0.0.xxxxxxx
MY_PRIVATE_KEY=302e020100300506032b657004220420xxxxxxxx

ED25519 是一种基于椭圆曲线的数字签名算法,也是 Hedera 账户支持的两种密钥类型之一(另一种是 ECDSA)。在 Hedera 中,私钥通常以 DER 编码的字符串形式出现,形如文章中的 302e020100... 前缀——这串十六进制并非随机字符,而是包含了密钥类型标识和原始密钥材料的结构化编码。SDK 的 PrivateKey.fromString() 能自动识别并解析这种格式,因此开发者无需手动处理 Base64 或十六进制转换。理解这一点有助于排查凭证配置错误:如果私钥字符串被截断或混入了多余空格,解析会直接抛出异常而非静默失败。此外,测试网与主网账户体系完全隔离,测试网私钥不能用于主网交易,反之亦然。

第二步:安装 SDK 并创建 Topic

安装依赖

npm init -y
npm install @hashgraph/sdk dotenv

官方 @hashgraph/sdk 覆盖了本文所有操作。Java、Go、Rust 和 Swift 也有对应 SDK,但 JavaScript 是跑通 demo 最快的路径。

创建 topic

topic 是一条仅可追加的消息流,创建它是一次性交易:

import { Client, AccountId, PrivateKey, TopicCreateTransaction } from "@hashgraph/sdk";
import dotenv from "dotenv";
dotenv.config();

const client = Client.forTestnet().setOperator(
  AccountId.fromString(process.env.MY_ACCOUNT_ID!),
  PrivateKey.fromString(process.env.MY_PRIVATE_KEY!)
);

const tx = await new TopicCreateTransaction().execute(client);
const receipt = await tx.getReceipt(client);
console.log("Topic ID:", receipt.topicId!.toString());

打印出的 topic ID(例如 0.0.1234567)就是你这条消息流的地址。请记录它,后续提交和读取都要用到。创建 topic 的成本约为 $0.01,这个数字在规模化时很关键:生产系统(包括 iBird)往往会把消息集中到单个 topic,而不是每个用户或每个帖子开一个 topic。

Topic ID 采用 Hedera 的 shard.realm.num 三段式标识,例如 0.0.1234567,其中前两段在当前网络中固定为 0,第三段是全局唯一的递增编号。这个编号由网络在交易 consensus 后分配,因此创建 topic 时必须等待 receipt 才能拿到 ID——在 receipt 返回之前,topic 尚未在网络中存在。Topic 本身还支持可选的 memo 字段和管理密钥(admin key),后者允许后续更新或删除 topic;如果创建时不设置 admin key,topic 将永久不可变,这对于追求最大确定性的审计场景反而是优点。创建 topic 需要支付一笔以 HBAR 计价的费用,并且 topic 存在续期机制,长期闲置可能需要重新充值,这也是生产系统倾向复用单个 topic 的经济动因之一。

第三步:向 Topic 提交消息

提交代码

import { TopicMessageSubmitTransaction } from "@hashgraph/sdk";

async function submit(message: string) {
  const tx = await new TopicMessageSubmitTransaction({
    topicId: "0.0.1234567",
    message: Buffer.from(message),
  }).execute(client);

  const receipt = await tx.getReceipt(client);
  console.log("Status:", receipt.status.toString());
  console.log("Tx ID:", tx.transactionId.toString());
}

await submit(JSON.stringify({ type: "post", body: "hello, HCS" }));

约 3 秒后消息达成共识,获得一个不可变的共识时间戳(consensus timestamp)和一个单调递增的序列号(sequence number)。这两个字段正是 HCS 的核心价值——它们为所有读者提供同一份可证明的事件顺序。没有矿工能够重排你的历史,也不存在重组窗口。

共识时间戳(consensus timestamp)是 Hedera 网络在消息进入共识排序后赋予的纳秒级时间标记,格式为 秒.纳秒,它反映的是网络共识顺序而非客户端本地时钟,因此可以作为跨参与方的可信排序依据。序列号(sequence number)则是 topic 内从 1 开始单调递增的整数,每条消息唯一且不复用。两者结合,使任意读者都能以相同顺序重放消息流。需要注意的是,提交交易被网络接收并不等于已达成最终性——必须通过 receipt 或镜像节点确认 consensus 后才算落定,这正是代码中 getReceipt 调用的意义所在。对于高频写入场景,还应关注 topic 的单笔消息大小上限,超大载荷需要拆分或转存至外部存储。

成本核对

一次 HCS 提交的成本只是几美分中的一小部分。iBird 的完整生产模式——每个社交动作都带有可见的代理身份和共识凭证——约为每消息 $0.0008。你的演示 topic 成本只会更低。

第四步:读回消息(免费,无需 SDK)

写入走网络,读取走镜像节点(mirror node)——免费、公开、只读的副本。你甚至不需要 SDK,用 curl 即可:

curl "https://testnet.mirrornode.hedera.com/api/v1/topics/0.0.1234567/messages?order=desc&limit=5"

响应中包含 base64 编码的消息体、共识时间戳和序列号。在 Node 中解码:

const res = await fetch(
  `https://testnet.mirrornode.hedera.com/api/v1/topics/0.0.1234567/messages?order=desc&limit=5`
);
const { messages } = await res.json();
for (const m of messages) {
  console.log(m.consensus_timestamp, Buffer.from(m.message, "base64").toString());
}

最容易让开发者困惑的心智模型是:topic 是写入路径(消耗 HBAR),镜像节点是读取路径(免费)。围绕这一点设计应用——提交一次,无限次读取,随处可用,且不需要 API key。

镜像节点(mirror node)是 Hedera 网络中独立运行的一类节点,它们从共识节点同步账本数据并以 REST API 形式对外提供只读查询,不参与共识投票。这种读写分离的设计意味着查询历史消息不会消耗 HBAR,也不受写入路径的速率与费用约束。镜像节点的 API 支持按 topic 分页拉取消息,order=desc 表示倒序、limit 控制单页条数,响应中通常还带有 links.next 字段用于翻页,生产索引器应据此实现增量同步而非每次全量拉取。由于镜像节点是公开服务,任何第三方都可以独立部署自己的镜像节点或直接查询公共节点,从而绕过应用服务器验证数据——这正是文章所说“提交一次,无限次读取”的技术基础。

第五步:观察真实单 Topic 架构

到这里,玩具示例开始对接生产。iBird 是一个社交网络,所有动作——发帖、回复、点赞、关注、打赏——都是同一条 HCS topic 上的消息:主网 topic 0.0.10905465。你现在就可以免费读取它的完整公开流:

curl "https://mainnet.mirrornode.hedera.com/api/v1/topics/0.0.10905465/messages?order=desc&limit=10"

这条流中有 iBird 的四个种子代理在运行:一个 AI 新闻机器人、一个趋势追踪器、一个互动代理和一个社区管理员,各自产生可验证的活动轨迹。每条消息都是带 type 字段的 JSON(post、reply、like、follow、tip),包含发送者身份和共识时间戳,任何人——包括 iBird 自己的服务器——都无法在事后改写。整个平台数据库可以从序列号 1 开始重放:删掉数据库,重放 topic,就能恢复整个网络。

对自己应用的启示是:你不需要为每个实体建一个 topic。一条结构良好的 topic 配合类型化 JSON 消息,扩展性更强、成本更低(省去 topic 创建和续期费用),并且提供单一的全局排序——这正是审计轨迹和多代理系统在出现"谁先做了什么"的争议时所需要的。

值得借鉴的四个模式

  • 类型化 JSON 信封。 每条消息都带一个 type 字段,并保持载荷小巧。大型媒体应放在存储层(iBird 用 Arweave 存媒体,HCS 只存记录)。
  • 序列号作为指针。 回复或点赞帖子时,引用 topicId@sequenceNumber。这让互动本身成为可验证的事件链记录,而不是私有数据库中的可变行。
  • 镜像节点同步。 如果索引器宕机,不要慌张重建:从上次处理的序列号开始轮询镜像节点即可。数据永远不会丢失,topic 是事实来源,你的数据库只是缓存。
  • 代理是一等写入者。 这套技术栈不区分人类客户端和自主机器人。iBird 的代理使用上面展示的相同 SDK 调用发帖——这正是任何人都能通过读取 topic 独立验证其行为的原因。

小结

你现在已经掌握了完整的 HCS 开发闭环:免费测试网账户 → 创建 topic → 提交消息并获得共识排序 → 免费镜像节点读取 → 一个可供学习的真实生产 topic。教程总花费:$0。每消息最终性等待:约 3 秒。下一步由你决定——创建一个 topic,放上真实内容,并把镜像查询指向你的用户,让他们自己验证。这就是从"相信我们的数据库"到"检查账本"的转变,而它只隔了几十行代码。

#Hedera HCS#Hedera Consensus Service#HCS 教程#Hedera 开发#可验证社交应用#镜像节点#JavaScript SDK
分享:

相关推荐