30 KiB
30 KiB
灵隙协议补充草案:去中心化身份与寻址
版本:0.1(草案) 状态:草案 层级:基础设施层 依赖:灵隙原始协议
摘要
本草案定义了灵隙协议栈中去中心化场景下的 Agent 身份认证与发现机制,解决无中心化目录时的 AgentID 唯一性和可验证性问题。
1. 背景与目标
1.1 问题陈述
现有协议假设存在中心化的注册表(如灵脉 Meridian),但在以下场景中:
- 临时 P2P 网络
- 跨组织协作
- 离线/断网环境
- 边缘计算场景
中心化注册不可用,需要去中心化的身份认证与发现机制。
1.2 设计目标
| 目标 | 说明 |
|---|---|
| 身份可验证 | AgentID 无法伪造或冒用 |
| 去中心化 | 无需中心化注册表 |
| 高可用 | 无单点故障 |
| 可扩展 | 支持大规模 Agent 网络 |
| 可读性 | 支持人类可读别名(可选) |
2. AgentID 生成规则
2.1 ID 结构
AgentID 由三部分组成:
AgentID = {namespace}:{key_hash}:{alias}
示例:
synapse:7hJ4x9K2mNpQ:llm-agent-01
synapse:3kM8nP5qRsTu:image-gen
did:synapse:abc123def456:chat-bot
| 部分 | 格式 | 说明 |
|---|---|---|
| namespace | string | 命名空间(如 synapse) |
| key_hash | base58 | 公钥哈希的前 16 字节 |
| alias | string(可选) | 人类可读别名 |
2.2 生成算法
func GenerateAgentID(privateKey []byte, namespace string, alias string) string {
// 1. 从私钥派生公钥
publicKey := crypto.GeneratePublicKey(privateKey)
// 2. 计算公钥哈希
hash := sha3.Sum256(publicKey)
// 3. 取前 16 字节,Base58 编码
keyHash := base58.Encode(hash[:16])
// 4. 组装完整 ID
if alias != "" {
return fmt.Sprintf("%s:%s:%s", namespace, keyHash, alias)
}
return fmt.Sprintf("%s:%s", namespace, keyHash)
}
2.3 ID 特性
| 特性 | 说明 |
|---|---|
| 唯一性 | 相同公钥 → 相同 key_hash → 相同 AgentID |
| 不可伪造 | 无法在没有私钥的情况下生成有效 AgentID |
| 可验证 | 任何人都可以用公钥验证 AgentID 真实性 |
| 不可预测 | 私钥随机生成,key_hash 不可预测 |
3. 身份认证机制
3.1 自我认证原理
验证方程:
Verify(AgentID, PublicKey) = true/false
其中:
AgentID.key_hash = Base58(SHA256(PublicKey)[:16])
3.2 签名验证流程
发送方:
1. 用私钥对消息签名
2. 发送 (Message, Signature, PublicKey, AgentID)
接收方:
1. 用 PublicKey 重新计算 AgentID.key_hash
2. 与消息中的 AgentID.key_hash 比较
3. 如匹配,用公钥验证签名
4. 如签名有效,确认消息来源
3.3 消息签名格式
type SignedMessage struct {
Message *UnifiedSynapseMessage // 原始消息
Signature []byte // 签名
PublicKey []byte // 公钥
AgentID string // Agent 标识
}
签名内容:
signature_content =
sender.agent_id |
sender.endpoint |
timestamp |
sha256(payload)
3.4 签名算法
| 算法 | 说明 |
|---|---|
| Ed25519 | 默认,高效且安全 |
| ECDSA-P256 | 兼容性选项 |
| RSA-2048 | 遗留系统兼容 |
4. 分布式发现协议
4.1 发现机制选择
| 场景 | 推荐机制 |
|---|---|
| 小规模(<100 Agent) | 广播查询 |
| 中规模(100-10000) | 分层 DHT |
| 大规模(>10000) | 完整 Kademlia |
4.2 广播查询协议
适用于小型网络,无需复杂路由:
Agent A 想知道 Agent B 的 Endpoint:
1. A 广播查询请求:
{
type: "agent_lookup",
target_id: "B's AgentID",
requester_id: "A's AgentID"
}
2. 知道 B 的节点响应:
{
type: "agent_lookup_response",
target_id: "B's AgentID",
endpoint: "http://B:8080",
signature: "B's signature"
}
3. A 收到响应后,用 B 的公钥验证签名
4.3 分层 DHT 协议
适用于中等规模网络:
层级结构:
Level 0: 本地网络(局域网/子网)
Level 1: 组织内网络
Level 2: 跨组织网络
Level 3: 全局网络
查询流程:
1. 先在本地查询
2. 本地未找到,查询上一层
3. 直到找到或返回"未找到"
4.4 DHT 消息类型
| 消息类型 | 说明 |
|---|---|
dht:ping |
节点存活探测 |
dht:store |
存储 Agent 记录 |
dht:find_node |
查找附近节点 |
dht:find_value |
查找 Agent 记录 |
dht:notify |
通知记录更新 |
4.5 Agent 记录结构
type AgentRecord struct {
AgentID string // Agent 唯一标识
Alias string // 人类可读别名(可选)
Endpoint string // 网络地址
PublicKey []byte // 公钥
TTL int64 // 记录有效期(秒)
Version uint64 // 版本号(递增)
Signature []byte // Agent 对以上字段的签名
Timestamp int64 // 发布时间戳
}
签名内容:
record_signature_content =
agent_id | alias | endpoint | public_key | ttl | version | timestamp
4.1 区块链发现方案
区块链提供了强信任的去中心化注册与发现机制,适合高价值、高安全要求的场景。
4.1.1 链上 Agent 注册表(智能合约)
┌─────────────────────────────────────────────────────────┐
│ Blockchain │
│ ┌─────────────────────────────────────────────────┐ │
│ │ AgentRegistry Contract │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ mapping(agentID => AgentRecord) │ │ │
│ │ │ - agentID: bytes32 │ │ │
│ │ │ - endpoint: string │ │ │
│ │ │ - publicKey: bytes │ │ │
│ │ │ - stake: uint256 │ │ │
│ │ │ - lastHeartbeat: uint256 │ │ │
│ │ │ - status: AgentStatus │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲ 注册 ▲ 查询
│ │
┌────┴────┐ ┌────┴────┐
│ Agent A │ │ Agent B │
└─────────┘ └─────────┘
核心思想:
- Agent 在区块链智能合约中注册身份
- 注册需要质押一定数量的代币作为保证金
- 心跳通过交易上链更新
- 查询通过调用合约
lookup方法 - 所有注册信息不可篡改
4.1.2 智能合约实现
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract AgentRegistry {
// Agent 状态
enum AgentStatus { None, Registered, Active, Suspended, Revoked }
// Agent 记录
struct AgentRecord {
bytes32 agentID; // Agent 标识(公钥哈希)
string endpoint; // 网络地址
bytes publicKey; // 公钥
uint256 stake; // 质押金额
uint256 lastHeartbeat; // 最后心跳时间
uint256 registerTime; // 注册时间
AgentStatus status; // 状态
bytes signature; // Agent 签名
}
// 配置
uint256 public registrationStake = 0.01 ether; // 注册押金
uint256 public heartbeatInterval = 1 hours; // 心跳间隔
uint256 public stakeAmount = 0.1 ether; // 质押要求
// 状态变量
mapping(bytes32 => AgentRecord) public agents;
mapping(address => bytes32) public addressToAgentID;
// 事件
event AgentRegistered(bytes32 indexed agentID, address indexed owner);
event AgentHeartbeat(bytes32 indexed agentID);
event AgentRevoked(bytes32 indexed agentID);
event AgentEndpointUpdated(bytes32 indexed agentID, string endpoint);
// 注册 Agent
function register(
bytes32 _agentID,
string memory _endpoint,
bytes memory _publicKey,
bytes memory _signature
) external payable {
require(msg.value >= registrationStake, "Insufficient stake");
require(agents[_agentID].status == AgentStatus.None, "Already registered");
// 验证签名:AgentID = keccak256(publicKey)
bytes32 derivedID = keccak256(_publicKey);
require(derivedID == _agentID, "AgentID does not match public key");
// 验证签名内容
bytes32 messageHash = keccak256(
abi.encodePacked(_agentID, _endpoint, msg.sender, block.timestamp)
);
require(
verifySignature(messageHash, _signature, _publicKey),
"Invalid signature"
);
agents[_agentID] = AgentRecord({
agentID: _agentID,
endpoint: _endpoint,
publicKey: _publicKey,
stake: msg.value,
lastHeartbeat: block.timestamp,
registerTime: block.timestamp,
status: AgentStatus.Registered,
signature: _signature
});
addressToAgentID[msg.sender] = _agentID;
emit AgentRegistered(_agentID, msg.sender);
}
// 心跳保活(可更新 Endpoint)
function heartbeat(
bytes32 _agentID,
string memory _newEndpoint,
bytes memory _signature
) external {
AgentRecord storage agent = agents[_agentID];
require(agent.status != AgentStatus.None, "Not registered");
// 验证签名
bytes32 messageHash = keccak256(
abi.encodePacked(_agentID, block.timestamp, _newEndpoint)
);
require(
verifySignature(messageHash, _signature, agent.publicKey),
"Invalid signature"
);
// 更新 Endpoint(如有变化)
if (bytes(_newEndpoint).length > 0 &&
keccak256(abi.encodePacked(_newEndpoint)) !=
keccak256(abi.encodePacked(agent.endpoint))) {
agent.endpoint = _newEndpoint;
emit AgentEndpointUpdated(_agentID, _newEndpoint);
}
agent.lastHeartbeat = block.timestamp;
emit AgentHeartbeat(_agentID);
}
// 查询 Agent 信息
function lookup(bytes32 _agentID) external view returns (AgentRecord memory) {
return agents[_agentID];
}
// 验证 Agent 是否活跃
function isActive(bytes32 _agentID) external view returns (bool) {
AgentRecord memory agent = agents[_agentID];
if (agent.status == AgentStatus.None || agent.status == AgentStatus.Revoked) {
return false;
}
// 检查心跳是否过期(3倍心跳间隔)
if (block.timestamp - agent.lastHeartbeat > heartbeatInterval * 3) {
return false;
}
return true;
}
// 追加质押
function stakeMore(bytes32 _agentID) external payable {
AgentRecord storage agent = agents[_agentID];
require(agent.status != AgentStatus.None, "Not registered");
agent.stake += msg.value;
}
// 注销 Agent(可取回质押)
function revoke(bytes32 _agentID) external {
AgentRecord storage agent = agents[_agentID];
require(agent.status != AgentStatus.None, "Not registered");
require(agent.status != AgentStatus.Revoked, "Already revoked");
uint256 refund = agent.stake;
agent.stake = 0;
agent.status = AgentStatus.Revoked;
payable(msg.sender).transfer(refund);
emit AgentRevoked(_agentID);
}
// 验证签名(EIP-191)
function verifySignature(
bytes32 _message,
bytes memory _signature,
bytes memory _publicKey
) internal pure returns (bool) {
bytes32 ethSignedMessageHash = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _message)
);
address signer = recoverSigner(ethSignedMessageHash, _signature);
address expectedSigner = address(uint160(uint256(keccak256(_publicKey))));
return signer == expectedSigner;
}
}
4.1.3 DID(Decentralized Identifiers)
本草案兼容 W3C DID 标准,支持标准的 DID 格式。
DID 格式:
did:synapse:{method-specific-id}
示例:
did:synapse:ethereum:0x1234abcd...5678
did:synapse:polygon:0xabcd...efgh
did:synapse:solana:7DeF...8901
did:synapse:key:z6MkpTHR...
DID 方法:
| 方法 | 说明 |
|---|---|
did:synapse:ethereum |
基于以太坊链上注册表 |
did:synapse:polygon |
基于 Polygon 链 |
did:synapse:solana |
基于 Solana 链 |
did:synapse:key |
基于公钥的离链 DID |
did:synapse:dht |
基于 DHT 的离链 DID |
DID Document 示例:
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://www.w3.org/ns/synapse/v1"
],
"id": "did:synapse:ethereum:0x1234abcd5678",
"verificationMethod": [
{
"id": "did:synapse:ethereum:0x1234abcd5678#keys-1",
"type": "EcdsaSecp256k1VerificationKey2019",
"controller": "did:synapse:ethereum:0x1234abcd5678",
"publicKeyHex": "02b3..."
}
],
"service": [
{
"id": "did:synapse:ethereum:0x1234abcd5678#synapse-agent",
"type": "SynapseAgent",
"serviceEndpoint": "https://agent-01.example.com/api/synapse"
}
],
"synapse:capabilities": [
"text_generation",
"image_generation"
],
"synapse:agentName": "智能写作助手",
"synapse:version": "1.0.0"
}
4.1.4 区块链平台选择
| 平台 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Ethereum | 生态最大、安全最高 | Gas 贵、延迟高 | 高价值交易、核心 Agent |
| Polygon | 低 Gas、快确认 | 中心化程度较高 | 中等价值、大量 Agent |
| Solana | 高吞吐、低延迟 | 稳定性偶有问题 | 高频心跳场景 |
| 联盟链 | 可控、隐私好 | 需要许可机制 | 企业内部、联盟合作 |
| L2 (Arbitrum) | 低 Gas、安全继承 | 复杂度较高 | 通用场景 |
| 本地私链 | 完全可控、零成本 | 信任范围有限 | 测试、内部系统 |
4.1.5 混合架构(推荐)
结合本地缓存、DHT 和区块链的三层架构,平衡性能和安全性:
┌─────────────────────────────────────────────────────────────┐
│ 查询路径(快→慢) │
│ │
│ Agent A │
│ │ │
│ │ 1. 本地缓存查询(内存,微秒级) │
│ │ ─────────────────────────── │
│ │ [cache hit] → 返回 │
│ │ [cache miss] │
│ │ │
│ │ 2. DHT 查询(网络,毫秒~秒级) │
│ │ ─────────────────────────── │
│ │ [dht hit] → 验证签名 → 更新缓存 → 返回 │
│ │ [dht miss] │
│ │ │
│ │ 3. 区块链查询(链上,秒~分钟级) │
│ │ ─────────────────────────── │
│ │ [chain hit] → 验证签名 → 广播DHT → 更新缓存 → 返回 │
│ │ [chain miss] → 未找到 │
│ │
└─────────────────────────────────────────────────────────────┘
分层缓存实现:
type HybridLookup struct {
// L1: 本地缓存(内存,TTL 1分钟)
LocalCache map[string]*AgentRecord
// L2: DHT 网络(分钟级一致性)
DHT DHTClient
// L3: 区块链(最终一致性源)
Blockchain BlockchainClient
}
func (h *HybridLookup) Find(agentID string) (*AgentRecord, error) {
// 1. 查本地缓存
if record, ok := h.LocalCache.Get(agentID); ok {
if record.IsFresh() {
return record, nil
}
}
// 2. 查 DHT
if record, err := h.DHT.FindValue(agentID); err == nil {
// 验证签名
if record.VerifySignature() {
h.LocalCache.Set(agentID, record)
return record, nil
}
}
// 3. 查区块链(最终源)
if record, err := h.Blockchain.Lookup(agentID); err == nil {
// 验证链上签名(已由链上合约验证过)
h.LocalCache.Set(agentID, record)
// 广播到 DHT 加速后续查询
h.DHT.Store(agentID, record)
return record, nil
}
return nil, ErrAgentNotFound
}
4.1.6 链上治理与激励
区块链还可实现链上治理功能:
| 功能 | 说明 |
|---|---|
| 质押机制 | Agent 注册需质押代币,恶意行为被 slash |
| 信誉评分 | 链上可查的 Agent 信誉分 |
| 服务定价 | 智能合约自动结算任务费用 |
| 争议仲裁 | 链上投票仲裁 Agent 纠纷 |
| 协议升级 | 通过 DAO 投票决定协议升级 |
5. 身份冲突处理
5.1 冲突场景
| 场景 | 说明 |
|---|---|
| 同一公钥注册多个别名 | 允许(同一 Agent 的多个别名) |
| 不同公钥生成相同 AgentID | 不可能(公钥哈希唯一) |
| 伪造他人 AgentID | 不可能(无法伪造签名) |
| Endpoint 欺骗 | 需要额外验证 |
5.2 Endpoint 绑定验证
为防止 Endpoint 欺骗,引入双向认证:
1. Agent A 声称自己是 "synapse:abc123:agent-A"
并声称其 Endpoint 是 "http://A:8080"
2. Agent B 收到声明后:
a. 用 A 的公钥验证 AgentID 合法
b. 向 Endpoint 发送挑战
c. A 必须用私钥响应挑战
d. 响应通过,确认 Endpoint 有效
5.3 挑战-响应协议
// 挑战消息
type Challenge struct {
ChallengeID string // 挑战 ID
Nonce []byte // 随机数
Timestamp int64 // 发送时间
}
// 响应消息
type ChallengeResponse struct {
ChallengeID string // 对应的挑战 ID
Nonce []byte // 原样返回的随机数
Signature []byte // 对 Nonce 的签名
}
// 验证流程
func VerifyEndpoint(endpoint string, publicKey []byte, challenge *Challenge) bool {
// 1. 发送挑战到 Endpoint
resp := SendChallenge(endpoint, challenge)
// 2. 验证响应
if resp.ChallengeID != challenge.ChallengeID {
return false // 挑战 ID 不匹配
}
if !bytes.Equal(resp.Nonce, challenge.Nonce) {
return false // Nonce 被篡改
}
// 3. 验证签名
return crypto.Verify(publicKey, challenge.Nonce, resp.Signature)
}
6. 生命周期管理
6.1 状态流转
┌──────────────┐
│ offline │
└──────┬───────┘
│ 注册/上线
▼
┌──────────────┐
┌─────────│ online │─────────┐
│ └──────┬───────┘ │
│ │ 刷新 │ 心跳超时
│ ▼ │
│ ┌──────────────┐ │
│ │ active │ │
│ └──────┬───────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ refreshing│ │ suspended │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
└──────┴───────────────────┴───────┘
│
▼
┌──────────────┐
│ offline │
└──────────────┘
6.2 生命周期消息
| 状态 | 说明 | 触发条件 |
|---|---|---|
| offline | 离线 | 初始状态或主动注销 |
| online | 上线中 | 注册完成,等待首次心跳 |
| active | 活跃 | 定期心跳维持 |
| refreshing | 刷新中 | 更新 Endpoint 或别名 |
| suspended | 挂起 | 心跳超时,未注销 |
| offline | 离线 | 注销或永久离线 |
6.3 消息类型
| 消息类型 | 方向 | 说明 |
|---|---|---|
identity:register |
→ 网络 | 注册 Agent 身份 |
identity:refresh |
→ 网络 | 刷新注册信息 |
identity:challenge |
双向 | Endpoint 验证挑战 |
identity:challenge_response |
双向 | 挑战响应 |
identity:revoke |
→ 网络 | 注销身份 |
identity:lookup |
→ 网络 | 查询 Agent 信息 |
identity:lookup_response |
→ 网络 | 查询响应 |
identity:announce |
→ 网络 | 广播在线状态 |
identity:heartbeat |
→ 网络 | 心跳保活 |
6.4 Register 载荷
type IdentityRegisterPayload struct {
AgentID string // Agent 标识
Alias string // 人类可读别名
Endpoint string // 网络地址
PublicKey []byte // 公钥
TTL int64 // 注册有效期
Version uint64 // 版本号
Signature []byte // Agent 签名
}
6.5 Heartbeat 载荷
type IdentityHeartbeatPayload struct {
AgentID string // Agent 标识
Endpoint string // 当前 Endpoint(可能变化)
TTL int64 // 续期时间
Signature []byte // Agent 签名
}
7. 安全考虑
7.1 威胁模型
| 威胁 | 场景 | 防护措施 |
|---|---|---|
| 身份伪造 | 攻击者声称自己是他人 | 公钥派生 ID + 签名验证 |
| Endpoint 欺骗 | 攻击者声称他人 Endpoint | 挑战-响应协议 |
| 重放攻击 | 攻击者重放旧消息 | 时间戳 + Nonce |
| 中间人攻击 | 拦截并修改消息 | TLS + 签名验证 |
| 女巫攻击 | 一个节点伪装多个身份 | 工作量证明或权益证明(可选) |
| 日食攻击 | 隔离目标节点 | 多路径查询 |
7.2 重放攻击防护
type AntiReplay struct {
RecentNonces map[string]int64 // nonce -> timestamp
Window time.Duration // 时间窗口(5分钟)
}
func (a *AntiReplay) CheckAndAdd(nonce string, timestamp int64) bool {
// 1. 检查时间戳是否在窗口内
now := time.Now().Unix()
if now - timestamp > int64(a.Window.Seconds()) {
return false // 时间戳太旧
}
// 2. 检查 Nonce 是否已使用
if _, exists := a.RecentNonces[nonce]; exists {
return false // 重放
}
// 3. 记录
a.RecentNonces[nonce] = timestamp
return true
}
7.3 私钥保护
| 场景 | 建议 |
|---|---|
| 本地运行 | 使用密钥文件 + 操作系统密钥链 |
| 云端运行 | 使用 HSM/KMS |
| 嵌入式设备 | 使用 TPM |
| 多 Agent 共享 | 密钥分片(如 Shamir's Secret Sharing) |
8. 与现有协议的关系
8.1 与原始协议的整合
本草案扩展 raw-protocol.md 中的 AgentEndpoint:
type AgentEndpoint struct {
AgentID string // 扩展:基于公钥派生
AgentName string // 人类可读名称
SystemID string // 所属系统
Endpoint string // 回调端点
Version string // Agent 版本
// 新增字段
PublicKey []byte // 公钥(用于验证)
Namespace string // 命名空间
Alias string // 人类可读别名
}
8.2 与灵脉(Meridian)的整合
| 模式 | 行为 |
|---|---|
| 中心化可用 | 使用灵脉作为主注册表,本草案作为备份 |
| 去中心化 | 使用本草案的 DHT 机制,完全去中心化 |
| 混合模式 | 核心 Agent 使用中心化,边缘 Agent 使用去中心化 |
8.3 与灵玺(Sigil)的整合
| 组件 | 职责 |
|---|---|
| 灵玺(Sigil) | 密钥管理、签名验证 |
| 本草案 | ID 生成、发现协议、生命周期 |
9. 协议消息汇总
9.1 消息类型列表
| 类型 | 协议前缀 | 说明 |
|---|---|---|
identity:register |
前端 | 注册身份 |
identity:refresh |
前端 | 刷新注册 |
identity:revoke |
前端 | 注销身份 |
identity:challenge |
前端 | 挑战请求 |
identity:challenge_response |
前端 | 挑战响应 |
identity:lookup |
前端 | 查询身份 |
identity:lookup_response |
前端 | 查询响应 |
identity:announce |
前端 | 广播在线 |
identity:heartbeat |
前端 | 心跳保活 |
dht:ping |
DHT | 节点探测 |
dht:store |
DHT | 存储记录 |
dht:find_node |
DHT | 查找节点 |
dht:find_value |
DHT | 查找值 |
dht:notify |
DHT | 通知更新 |
10. 待解决问题(Open Issues)
| 问题 | 说明 | 优先级 |
|---|---|---|
| 隐私保护 | 公钥哈希是否暴露身份? | 高 |
| 密钥轮换 | 私钥更换后如何保持 AgentID? | 高 |
| 名称冲突 | 人类可读别名可能重复 | 中 |
| 性能优化 | DHT 查找延迟 | 中 |
| 移动 Agent | Endpoint 频繁变化 | 低 |
| 链上 Gas 成本 | 区块链交易费用 | 中 |
| DID 方法注册 | W3C 标准 DID 方法注册流程 | 低 |
11. 实现建议
11.1 分阶段实现
Phase 1(最小可行):
- 实现 AgentID 公钥派生
- 实现消息签名验证
- 使用广播进行发现
Phase 2(基本功能):
- 实现分层 DHT
- 实现生命周期管理
- 实现挑战-响应协议
Phase 3(完整功能):
- 实现完整 Kademlia
- 实现隐私保护
- 实现密钥轮换
11.2 推荐库
| 功能 | 推荐库 |
|---|---|
| 加密签名 | golang.org/x/crypto/ed25519 |
| Base58 | github.com/mr-tron/base58 |
| DHT | github.com/anacrolix/go-libutp 或自实现 |
| 分布式存储 | etcd/consul(混合模式) |
12. 参考资料
- Kademlia: A Peer-to-peer Information System Based on the XOR Metric
- Self-Certifying File System (SFS)
- Decentralized Identifiers (DIDs) v1.0
- WebID 2.0
- EIP-191: Signed Data Standard
- EIP-712: Ethereum Typed Structured Data Signing
- DID Method Registry
草案状态:本文档为初始草案,欢迎反馈和讨论。