【p2p、分布式,区块链笔记 DAM】GUN/SEA(Security, Encryption, Authorization) 模块genkey

[Web3] 基础第5篇: 共识算法与 P2P 通信协议 CometBFT 采用Tentmint 共识,一种易于理解、基本异步的 BFT 共识算法。该算法遵循一个简单的状态机,如下所示:上图展示了 Tendermint BFT 共识流程,描述了一个区块从提议(Propose)到最终提交(Commit)的完整过程。Tendermint 共识采用三阶段投票机制(Prevote、Precommit、Commit) 来确保区块最终性。三阶段投票机制(Prevote → Precommit → Commit)需要 2/3 以上的投票支持 才能进入下一阶段。 阅读详情

genkey

generateAppKey.js

const SEA = require('gun/sea');

// 生成密钥对
SEA.pair().then((pair) => {
  // 输出提示信息
  console.log('This is your secret app key pair.\nAdd this to your .dotenv file:');
  // 将生成的密钥对转换为 JSON 格式并输出
  console.log(`APP_KEY_PAIR='${JSON.stringify(pair)}'`);
});

  • 输出:
$ node ./generateAppKey.js
Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco if anything takes you longer than 5min to figure out!
This is your secret app key pair.
Add this to your .dotenv file:
APP_KEY_PAIR='{"pub":"B14-m6S3i1cgm9bJCsED0FsGbHiDlXJAiKK2OnrPSj0.axmMDTmbdAfU3SjJhgqOn6mH6jDUoazcQ_vHljstyuE","priv":"21kawgH1yBwDLSf4yh63A_AdAja4hh-Q5h_ob_LF-VE","epub":"Z-IWo4zkzXyEL5hWCmvQLY8aoxupbZmJZmKFMDhNJ0U.hoNigMrVpc2npPR17tjOyZchJKk1D8wlQKPCIKZNF_w","epriv":"UUO2sHWG1lrQLNr0t9ObSEHyiasCc_D2HdJS-Vw2FmI"}'
Done in 0.77s.

APP_KEY_PAIR

APP_KEY_PAIR='{"pub":"B14...","priv":"21k...","epub":"Z-I...","epriv":"UUO..."}'

总结

密钥类型功能对比表

密钥类型作用使用场景是否公开说明
pub身份验证、消息签名验证用于验证签名和公开身份可以公开用于确认数据是否由密钥对的拥有者签名。
priv消息签名签署消息、身份认证不可公开pub 的配对私钥,用于对消息签名;一旦泄露可能导致身份伪造。
epub数据加密、公钥加密安全数据传输、密钥交换可以公开用于加密数据,与 epriv 配对;确保对称密钥安全共享。
epriv数据解密解密接收到的加密数据不可公开epub 的配对私钥,用于解密加密的数据;必须严格保密。

使用示例

  • epub / epriv 用于 数据加密 和 解密。假设已经在 .env 文件中保存了密钥对:
APP_KEY_PAIR='{"pub":"B14...","priv":"21k...","epub":"Z-I...","epriv":"UUO..."}'
  • 然后在代码中读取密钥对并加解密数据:
const SEA = require('gun/sea');
const pair = JSON.parse(process.env.APP_KEY_PAIR);

// 数据加密
async function encryptMessage(message, recipientEpub) {
  const encrypted = await SEA.encrypt(message, recipientEpub);
  return encrypted;
}

// 数据解密
async function decryptMessage(encryptedMessage) {
  const decrypted = await SEA.decrypt(encryptedMessage, pair.epriv);
  return decrypted;
}

// 示例用法
const recipientEpub = 'Z-IWo4zkzXyEL5hWCmvQLY8aoxupbZmJZmKFMDhNJ0U.hoNigMrVpc2npPR17tjOyZchJKk1D8wlQKPCIKZNF_w';
const message = 'Hello, secure world!';
encryptMessage(message, recipientEpub).then((encrypted) => {
  console.log('Encrypted Message:', encrypted);
  decryptMessage(encrypted).then((decrypted) => {
    console.log('Decrypted Message:', decrypted);
  });
});

server

  1. 启动服务:通过 Express 和 GUN 创建服务器。
  2. GUN 实例配置:
    • 验证所有进入的 GUN 消息是否带有有效的 JWT。
    • 自动将应用本身认证为 GUN 用户,使其可以管理数据。
  3. API 路由:
    • /api/certificates:允许用户获取证书,以限制其对特定数据路径的访问。
    • /api/tokens:为用户生成 JWT 令牌,用于请求认证。

引入必要的模块

// 引入必要的模块
const express = require('express');       // 用于创建 HTTP 服务器
const cors = require('cors');             // 处理跨域请求
const jwt = require('jsonwebtoken');      // 用于生成和验证 JSON Web Token (JWT)
let Gun = require('gun');                 // GUN 去中心化数据库
const SEA = require('gun/sea');           // GUN 的加密模块 (SEA)

// 引入 bullet-catcher 模块以增强错误处理
require('bullet-catcher');

初始化 Express 应用和读取配置

// 初始化 Express 应用和读取配置

// 读取环境变量(.env 文件中的配置)
require('dotenv').config();

const app = express();
// 设定端口号,默认为 8765
const port = process.env.PORT || 8765;

// 读取 GUN 密钥对和 JWT 密钥
const APP_KEY_PAIR = JSON.parse(process.env.APP_KEY_PAIR); // GUN 应用密钥对
const APP_TOKEN_SECRET = process.env.APP_TOKEN_SECRET;     // 用于 JWT 的密钥

Web 服务配置

// 允许 GUN 提供其 Web 服务
app.use(Gun.serve);// Gun.serve:允许 GUN 提供 HTTP 服务,从而启用 WebSocket 通信

// 创建 HTTP 服务器并监听端口
const server = app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

/**
 * 验证 GUN 消息中的 JWT 是否有效
 * @param {Object} msg - GUN 消息对象
 * @returns {Boolean|Error} - 返回 true 如果验证成功,否则返回错误
 */
function verifyToken(msg) {
  // 检查消息头中是否有 accessToken
  if (msg?.headers?.accessToken) {
    try {
      // 验证 accessToken 是否有效
      jwt.verify(msg.headers.accessToken, APP_TOKEN_SECRET);
      return true; // 如果验证通过,则返回 true
    } catch (err) {
      const error = new Error('Invalid access token'); // 如果验证失败,抛出错误

      // 检查是否是 Token 过期错误
      if (err.name === 'TokenExpiredError') {
        // 如果需要,可以在这里实现自动刷新 token 的逻辑
        error.expiredAt = err.expiredAt;
      }

      return error;
    }
  }
  // 如果消息中没有 accessToken,则返回 false
  return false;
}

// 初始化 GUN 实例,启用 JWT 验证
const gun = Gun({
  web: server,     // 使用刚创建的 HTTP 服务器
  isValid: verifyToken, // 验证传入消息的 accessToken
});

// 同步所有数据
gun.on('out', { get: { '#': { '*': '' } } });

/**
 * 将应用本身授权为 GUN 用户
 * 以便应用可以使用 GUN 网络存取数据
 */
gun.user().auth(APP_KEY_PAIR, ({ err }) => {
  if (err) {
    // 如果认证失败,输出错误信息
    console.error(err);
  }
});

API 路由

// 允许 Express 解析 JSON 请求体
app.use(express.json());

// 如果需要允许跨域访问,可以启用 CORS
// app.use(cors());

创建授权证书的 API

/**
 * 创建授权证书的 API 路由 SEA.certify
 * 允许用户获取权限证书,以限制其修改特定数据路径
 */
app.post('/api/certificates', async (req, res) => {
  // 从请求体中获取用户名和用户的公钥
  const { username, pub: userPubKey } = req.body;

  // 定义访问控制策略
  const policy = [
    // 允许用户添加和编辑他们的 profile 数据
    { '*': 'profiles', '+': '*' }
  ];

  // 设置证书的过期时间为 2 小时
  const expiresAt = Date.now() + 2 * 60 * 60 * 1000;

  try {
    // 使用 GUN 的 SEA 模块生成授权证书
    const certificate = await SEA.certify(
      [userPubKey],     // 被授权的用户公钥
      policy,           // 访问控制策略
      APP_KEY_PAIR,     // 应用的密钥对
      null,             // 回调函数 (可选)
      {
        expiry: expiresAt,   // 设置证书的过期时间
        block: 'blocked',    // 可以定义阻止的路径 (可选)
      }
    );

    // 如果证书生成成功,发送响应
    console.log(`Successfully created certificate for ${username}`);
    res.status(201).send({ certificate, expires_at: expiresAt });
  } catch (err) {
    // 如果生成证书时出错,返回错误信息
    console.error(`Error creating certificate for ${username}:`, err);
    res.status(500).send({ error: err.message });
  }
});

生成 JWT 令牌的 API

/**
 * 生成 JWT 令牌的 API 路由
 * 用户可以通过此路由获取访问令牌
 */
app.post('/api/tokens', async (req, res) => {
  // 从请求体中获取用户名和用户公钥
  const { username, pub } = req.body;

  // 创建 JWT,设置有效期为 1 小时
  const token = jwt.sign({ username, pub }, APP_TOKEN_SECRET, {
    expiresIn: '1h', // 令牌在 1 小时后过期
  });

  // 返回生成的 accessToken
  res.status(201).send({ accessToken: token });
});

测试

  1. 启动服务器:
    node ./server.js
    
  2. 使用 curl 或 Postman 测试 /api/certificates:
    curl -X POST http://localhost:8765/api/certificates \
    -H "Content-Type: application/json" \
    -d '{"username": "alice", "pub": "yourUserPubKey"}'
    
  3. 测试 /api/tokens:
    curl -X POST http://localhost:8765/api/tokens \
    -H "Content-Type: application/json" \
    -d '{"username": "alice", "pub": "yourUserPubKey"}'
    

CG

已知文件名取文件所在目录                                                                           何志丹已知文件名,如何取文件所在目录?最简单的方法是从后向前找"//".但有时,文件名中没有"//",这时要先转化一下.具体代码如下:CString GetPathName(const CString strPathFileName){ //取 阅读详情

相关推荐

应用程序向导

应用程序向导  何志丹            使用应用程序向导可以快速生成程序框架。选择菜单“File→New”命令,此时会弹出“New”对话框,下面对该对话框中的常用选项进行逐一说明。1.文件(Files)属性页 单击“Files”标签,打开“Files”属性页,如图1-3所示。图1-3  文件属性页文件类型虽然多,但常用的只有两种:C/C++ Header Fi

闻缺陷则喜何志丹 3708

两台内网机器直接对话:EasyNTS上云网关平台P2P互联规则怎么配

再决定是否选择“允许服务中继”兜底。

AI与流媒体视频技术 189

Zynq 【SDK裸机开发之PS】——DDR的内存分配使用详解

Zynq如果跑操作系统的话,内存管理的工作都会交给系统来操作,但是如果是裸机的话,则需要自己对DDR3的内存进行管理。

shizhibuyi1234的博客 7378

从异地组网到内网穿透:一套 P2P 直连架构如何演进成远程访问工具

同样是从外网访问家里的 NAS,有的方案装完就能用,有的折腾半天端口映射、公网 IP,最后还是连不上。其实不是,差在底层架构。

jiedianxiaobao的博客 314

LangChain + PlayWright实战:5分钟搞定网页自动化测试(附完整代码)

本文详细介绍了如何利用LangChain与PlayWright构建智能网页自动化测试系统。通过环境配置、核心架构设计、实战Agent构建及性能优化等步骤,开发者可以快速实现高效的Web操作自动化,提升测试效率。文章还提供了完整代码示例和典型问题解决方案。

weixin_27791839的博客 239

从零抓包分析AVDTP:用Wireshark解密蓝牙音频传输全流程

本文详细介绍了如何使用Wireshark抓包工具分析AVDTP协议,解密蓝牙音频传输的全流程。从实验环境搭建到信令交互解析,再到媒体流传输深度分析,逐步揭示蓝牙音频传输的技术本质,帮助开发者深入理解AVDTP协议的工作机制。

sun99的博客 204

快捷键与热键有何异同?

本文对比了热键与快捷键在“粘贴”操作中的异同:用户层面,热键需按Alt+字母组合,快捷键则直接Ctrl+V;开发者层面,修改热键仅需调整菜单标题,而修改快捷键需编辑资源文件中的加速器设置。文章强调专业分工的重要性,并推荐相关排样优化与工具箱技术博文。

闻缺陷则喜何志丹 1746

【云原生之Docker实战】使用docker部署Monica个人开源CRM系统

【云原生之Docker实战】使用docker部署Monica个人开源CRM系统

jks212454的博客 2386

为什么要把父类的析构函数定义成虚函数?

问:为什么要把父类的析构函数定义成虚函数?答:否则子类的析构函数可以未被调用,具体代码如下:class A {public: A(){TRACE("A()/n");}; ~A(){TRACE("~A()/n");}; };class B : public A {public: B(){TRACE("B()/n");}; ~B(){TRACE("~B()/n");};};void CEgDl

闻缺陷则喜何志丹 1526

BPC坏点矫正

whatis the Bad Pixel? 坏点为死点,也就是基本不随照度变化呈现光电线性转换的关系。表现为暗态常亮,亮态常暗。 坏点分类:静态坏点:亮坏点,暗坏点。 动态坏点:在一定像素范围内,该点表现正常,而超过这一范围,该点表现的比周围像素要亮。与sensor ...

camerall 1万+

在 SAP 系统中,成本中心(Cost Center)是成本核算与费用管控的基础组织单元,其设计质量直接决定了后续成本归集、分摊、分析及责任考核的准确性

SAP系统成本中心设计核心要点:1. 设计原则包括责任可控、业务同质、核算颗粒度适配、组织对齐及稳定性平衡;2. 划分维度主要有部门、功能、地域、项目和资产5类,可组合使用;3. 需避免颗粒度过细、跨责任主体归集等常见误区;4. 建议采用"明确目标-梳理业务-设计编码"三步法,建立科学的成本中心体系。合理的成本中心设计能精准归集费用、明确责任主体,为成本分析和管控奠定基础。

金牌架构师 1440

p2pdma和dmabuf区别

。

zly8865372的博客 292

华为OD机试真题2025双机位C卷 C++ 实现【卡牌游戏】

小明正在尝试一种新的牌游戏。游戏规则只如下:首先,小明拿到一张写有数字m的牌。 然后,他会拿到另外n张牌,上面分别写有不同的数字,牌排成一排。小明的目标是从这排牌中找到一串连续的牌,这些牌上数字的总和可以被 m整除。你的任务是判断小明是否可以完成这个目标。

MISAYAONE的博客 281

按Ctrl键会引发几次按键消息

                                                                           何志丹(一),新建一个单文档工程CtrlEg。(二),为CCtrlEgView的WM_KEYDOWN消息和WM_KEYUP消息添加响应函数。具体代码如下:void CCtrlEgView::OnKeyDown(UINT nChar, UINT nRe

闻缺陷则喜何志丹 1820

第1章 环境准备

本章是 Kubernetes 高可用集群部署的前置基础环境配置,所有节点必须严格按顺序执行。主要内容包括:节点规划(IP、角色、配置要求)、VMware 克隆节点环境清理(解决 MAC 地址和主机名冲突)、统一工作目录创建、主机名与 hosts 解析配置、系统基础升级、防火墙与 swap 关闭、内核模块加载(overlay、br_netfilter、ip_vs)、网络参数优化(IP 转发、桥接过滤)、时间同步配置等。Ubuntu 24.04 内核 6.8+ 原生支持 eBPF 和 IPVS,无需手动升级内核

幸福街--linux技术分享 210

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

两台内网机器直接对话:上云网关/端口穿透/设备上云EasyNTS上云网关平台P2P互联规则怎么配

再决定是否选择“允许服务中继”兜底。

EasyCVR视频融合云平台的技术博客 205

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

HarmonyOS 分布式深度:跨端迁移、数据对象与多设备协同

本文深入解析鸿蒙分布式能力实战,聚焦跨端迁移、协同与共享三大形态,详解权限配置、设备发现、onContinue状态管理及分布式数据对象、KV同步机制。强调“先分清场景”“前置条件必全”“数据需重验”,揭示迁移失败、同步失效等七大常见坑,指导开发者规避陷阱,实现真实可用的多设备协同。

信息安全领域优质创作者|操作系统领域专家 109

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

AI分布式Token中转站网关底层实现-东方仙盟

在终端优先同步架构下,所有终端智能体请求不再直连上游 MaaS 平台(千帆、百炼、DeepSeek 等),全部经由分布式 Token 中转站网关统一中继。网关承担虚拟客户密钥签发、上游子账号路由、前置内容安全审计、事务路由调度、可控网络震荡多上游链路容灾、SSE 流式透传、用量记账、封禁熔断、原始 IP 封包签名溯源等核心职责。本文基于 Go 实现分布式网关核心底座,复用架构原有无状态 Token 穿透、事务 ID 幂等、链路探活、多节点中继能力;区分两层密钥体系:面向终端客户的虚拟 Key。

cybersnow精通 28 门计算机语言,凭借其超凡的技术能力,成功开发过上万个应用,广泛涉及政府、商业、个人等众多领域,甚至在检察院、环保局、公安局等专业场景中也大放异彩。不仅熟练掌握单片机和物联网开发,在软件架构设计方面更是独树一帜,自创了跨平台软件 244

EtherCAT从站实现(三):DC同步机制与分布式时钟实现

本文详解EtherCAT伺服从站DC同步机制,解决高精度控制中因主站抖动与传播延迟导致的相位偏差问题。通过ESC硬件维护1ns分辨率全局时间,实现从站自主同步,确保PDO更新与控制环采样精准对齐。核心流程包括传播延迟测量、时钟初始化、漂移补偿及SYNC0/SYNC1信号生成。从站需正确配置DC能力与同步模式,主站则通过DCM机制保障发送周期稳定。调试建议结合示波器与寄存器监控,分阶段验证时序关系,确保多轴协同无误。

yangmu3203的博客 123

分布式管控系统技术架构深度拆解:从编解码协议到SM4硬件级安全

支持音视频同步及异步切换、最大16路混音输出这些能力,在方案阶段是参数,在调试阶段是测试项。具备工程替代价值的节点应集成4路IR红外、2路RS232、4路I/O、2路继电器及1路RS485,这一档配置使节点具备直接驱动声、光、电及环境控制回路的能力,在中小型会议室场景中可以替代独立中控主机。H.265/H.264双标准支持是基础,每路视频的主码流与双码流独立控制(VBR/CBR)才是影响带宽规划的关键——双码流的意义在于将本地存储与远端预览的码率策略解耦,全局单一码率在多路并发场景下很难兼顾画质和带宽。

2603_95485477的博客 143

集中式与分布式怎么选:从订单读写看 KingbaseES 的架构边界

以订单系统为例,一笔付款会扣账户余额、写一条流水、更新订单状态;月末报表则可能按日期统计所有租户的订单。前者要求几项变更一起提交,后者关心查询会覆盖多大范围。讨论集中式与分布式,先把读写请求分开,比先数数据库节点更容易看清问题。KingbaseES 核心数据库是集中式关系数据库。KES RAC 和 KES TDC 也都可以部署为多节点形态,但它们的数据组织方式并不相同。

todoitbo的博客 1万+

Cloudflare Durable Objects 支持自动重试:分布式调用如何避免重复执行?

在分布式系统中,远程调用失败可能导致操作状态不确定。Cloudflare 为 Durable Objects 引入自动重试机制,仅对可重试错误进行智能重试,并通过 retryable() 明确标记幂等操作,避免重复执行。该机制不保证全局精确一次,仍需业务层实现去重,如使用请求标识或幂等键。核心在于区分“未执行”与“已执行但响应丢失”,从而在保障可靠性的同时防止数据错乱。

weixin_47502228的博客 399

粮库分布式温湿度采集系统,基于环境数据的粮食霉变预警开发实战

本方案构建基于分布式温湿度采集的粮食霉变预警系统,针对传统粮库监测滞后、误报率高等痛点,通过分层布设传感节点、边缘计算网关与时序数据平台,融合温升速率、露点判别、多因子耦合等算法,实现从“静态监测”到“动态预警”的升级。系统支持平房仓、浅圆仓等多场景部署,具备国产化适配、断网续传、联动通风互锁等功能,结合工单闭环与模型迭代机制,显著提升储粮安全水平,为智慧粮库建设提供可复制的工程范式。

306

从零搭建一个 AI Infra 实验室㉑:llm-d——从单个 vLLM 走向分布式推理

本篇深入 llm-d 分布式推理架构,解析负载感知路由、前缀缓存感知、KV Cache 本地性与 Prefill/Decode 分离。基于单节点 Kubernetes 和 LLM Simulator,实测智能路由与多 Pod 请求分布,理解从单个 vLLM 走向分布式推理的关键设计与挑战。

mosespaul的博客 322

跨端数据漫游,分布式 KVStore 冲突与合并

等两台设备联网同步后,手机上的清单里只剩下了面包,牛奶凭空蒸发了。这就是典型的分布式数据同步冲突,系统底层的默认策略把你坑了。这就导致了惨剧:如果手机时间比平板快了 5 分钟,那么手机上产生的任何数据,在同步时都会无条件覆盖平板上修改的数据。总的来说,分布式同步不能全靠系统,业务层的版本控制和冲突合并才是数据一致性的定海神针。系统默认的同步策略是 Last-Write-Wins(最后写入者胜出),判断标准是设备的系统时间。要解决这个问题,绝不能依赖底层的时间戳,必须在业务层引入版本号(乐观锁)。

2502_91284977的博客 156

基于分布式软总线的鸿蒙跨端数据同步与冲突合并机制

更恐怖的是,有时候平板上修改的记录,连带把手机上的最新数据给直接抹除了。这就导致了灾难性的数据覆盖。假设用户的手机系统时间比平板快了五分钟,那么在这五分钟的窗口期内,用户在平板上做出的任何修改,在同步时都会被手机上的老旧数据无情覆盖。版本号相同但内容不同时,通过业务层的自定义策略进行合并,这才是分布式应用应有的数据一致性保障。痛定思痛,我们放弃了最粗暴的覆盖式同步,全面重构了基于底层分布式数据管理的冲突解决机制。),这样不仅同步极快,发生冲突时,也只会影响单条记录,而不会导致全局覆写。

2502_91284977的博客 259
上一篇: 【p2p、分布式,区块链笔记 DAM】UserList.js & UserInfo.js
下一篇: 【数学 函数空间】格拉姆-施密特正交化&切比雪夫多项式推导
FakeOccupational
博客等级 码龄6年 2万+粉丝 1727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值