p2p、分布式,区块链笔记: libp2p基础
通信密钥 noise::{Keypair, X25519Spec}
- X25519/Ed25519类似RSA 算法。
- Noise 用于设计和实现安全通信协议。它允许通信双方
在没有预先共享密钥的情况下进行安全的密钥交换,并通过加密和身份验证保护通信内容。libp2p提供了对 Noise 协议的原生支持,它允许节点之间使用 Noise 协议进行安全的点对点通信。 - 例:
use libp2p::{noise::{Keypair, X25519Spec},identity,};,let local_keys = Keypair::<X25519Spec>::new().into_authentic(&identity::Keypair::generate_ed25519());
identity::Keypair
- 在
libp2p中,identity::Keypair是一个用于管理加密和身份验证密钥的结构体。它允许你生成和管理加密算法(如椭圆曲线加密)所需的公钥和私钥对,以及进行数字签名和验证等操作。 - 下面是一个简单的示例,展示如何使用
Keypair生成一个Ed25519算法的密钥对,并使用它进行签名和验证:
use libp2p::identity::{Keypair, ed25519};fn main() {// 生成一个 Ed25519 类型的密钥对let keypair = Keypair::generate_ed25519();// 获取公钥和私钥let public_key = keypair.public();let private_key = keypair.secret();// 创建一个消息let message = b"Hello, libp2p!";// 使用私钥对消息进行签名let signature = keypair.sign(message);// 使用公钥验证签名assert!(public_key.verify(message, &signature).is_ok());println!("Message: {:?}", message);println!("Signature: {:?}", signature);
}
transport
- 传输在两个对等方之间提供面向连接的通信 通过有序的数据流(即连接)
- 负责从一个peer到另一个peer的实际数据的传输
- 收听和拨号
- 例如使用
let transport = libp2p::development_transport(local_keys).await?;调用libp2p提供的高级API函数development_transport来创建传输。这个函数封装了传输的创建过程,通常会使用一组默认的配置参数和最佳实践,以便快速启动和测试libp2p应用程序。在这种情况下,local_keys是本地密钥,用于加密和身份验证。有关这个API的未来发展可以看这个ISSUE。 - 还可以手动配置和创建传输(transport)。下面的例子使用了TokioTcpConfig作为基础的TCP传输配置,手动指定了协议升级、身份认证和多路复用的配置。这种方式适用于需要精确控制传输行为和配置的场景,允许开发者根据具体需求进行灵活的设置和调整。
//Creates transport which is a feature of the lib p2p frameworklet transport = TokioTcpConfig::new()//Upgrades version of the transport once connection is established as Version 1 of the multi-stream-select protocol is the version that interacts with the noise protocol//in short handles protocol negotiation.upgrade(upgrade::Version::V1)//Authenticates that channel is secure with the noise XX handshake.authenticate(libp2p::noise::NoiseConfig::xx(auth_keys).into_authenticated())//multiplex transport negotiates multiple sub-streams and/or connections on the authenticated transport.multiplex(mplex::MplexConfig::new())//boxed allows only output and error types to be captured.boxed();
行为控制 Swarm
- Swarm 包含整个网络的状态。运行一组节点并管理它们之间的连接和行为。整个 libp2p 网络的行为可以通过其进行控制。
- 例子
// https://stackoverflow.com/questions/74126811/rust-libp2p-cannot-find-function-development-transport-in-crate-libp2p
extern crate core;// 显式地声明对 core crate(包含Rust核心标准库)的依赖。use libp2p::{futures::StreamExt,noise::{Keypair, NoiseConfig, X25519Spec},identity,PeerId,tcp::TcpConfig,swarm::{DummyBehaviour,Swarm,SwarmEvent},
};
use std::error::Error;#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {// 生成身份密钥对let local_keys = identity::Keypair::generate_ed25519();// 从公钥生成peeridlet local_peer_id = PeerId::from(local_keys.public());println!("local_peer_id is {:?}",local_peer_id);// 采用“默认”行为let behaviour = DummyBehaviour::default();// 创建 libp2p transport实现peer间的数据let transport = libp2p::development_transport(local_keys).await?;let mut swarm = {Swarm::new(transport, behaviour, local_peer_id)};swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;// 本机中所有的IPV4地址,使用 TCP 协议,端口号为 0 表示让操作系统自动选择一个空闲端口来监听.loop {match swarm.select_next_some().await {SwarmEvent::NewListenAddr { address, .. } => {println!("Listening on local address {:?}", address)}_ => {}}}Ok(())
}
- 运行效果
local_peer_id is PeerId("12D3KooWD4BMTXhmTV46fSbdRv238dRudXcXq9VPSF1PH4N4nWVk")
Listening on local address "/ip4/192.168.0.102/tcp/51516"
Listening on local address "/ip4/127.0.0.1/tcp/51516"
local_peer_id is PeerId("12D3KooWJRoPgqPPC8adBwrFHfx4XtCpCu1BprzBofgVirxoceJB")
Listening on local address "/ip4/192.168.0.102/tcp/51519"
Listening on local address "/ip4/127.0.0.1/tcp/51519"
在 peer 节点之间交换 ping 命令
use libp2p::futures::StreamExt; // 异步流有关
use libp2p::ping::{Ping, PingConfig};// ping 命令相关依赖
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, PeerId};
use std::error::Error;#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {let new_key = identity::Keypair::generate_ed25519();let new_peer_id = PeerId::from(new_key.public());println!("New Peer ID is: {:?}", new_peer_id);let transport = libp2p::development_transport(new_key).await?;let behaviour = Ping::new(PingConfig::new().with_keep_alive(true));let mut swarm = Swarm::new(transport, behaviour, new_peer_id);swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;// 本地节点向远程节点发出连接 从命令行输入的参数取出if let Some(remote_peer) = std::env::args().nth(1) {let remote_peer_multiaddr: Multiaddr = remote_peer.parse()?;swarm.dial(remote_peer_multiaddr)?;// 需要libp2p ,version = "0.46"println!("Dialed remote peer: {:?}", remote_peer); // 打印远程地址}loop {match swarm.select_next_some().await {SwarmEvent::NewListenAddr { address, .. } => {println!("Listening on local Address {:?}", address)}SwarmEvent::Behaviour(event) => println!("Event received from peer is {:?}", event),_ => {}}}
}
- 运行效果
PS C:\Users\kingchuxing\Documents\CODE\P2PRecipeApp> cargo run
New Peer ID is: PeerId("12D3KooWFR97CdrL7jvboqU6MxyWjRzfHsR5V2sgs23yqg4xetnV")
Listening on local Address "/ip4/192.168.0.102/tcp/50997"
Listening on local Address "/ip4/127.0.0.1/tcp/50997"
PS C:\Users\kingchuxing\Documents\CODE\P2PRecipeApp> cargo run /ip4/192.168.0.102/tcp/50997
New Peer ID is: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG")
Dialed remote peer: "/ip4/192.168.0.102/tcp/50997" //对远程地址进行了拨号
Listening on local Address "/ip4/192.168.0.102/tcp/51014"
Listening on local Address "/ip4/127.0.0.1/tcp/51014"
Event received from peer is Event { peer: PeerId("12D3KooWFR97CdrL7jvboqU6MxyWjRzfHsR5V2sgs23yqg4xetnV"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWFR97CdrL7jvboqU6MxyWjRzfHsR5V2sgs23yqg4xetnV"), result: Ok(Ping { rtt: 314.3µs }) }
- 后续两个peer之间会不断的ping和pang
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 250.7µs }) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 319.7µs }) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 479.6µs }) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 217.8µs }) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 266.7µs }) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Pong) }
Event received from peer is Event { peer: PeerId("12D3KooWMGLjRBpysfHqjYWcYPf89bDNWH4S9Ao8RXj5tBehksCG"), result: Ok(Ping { rtt: 1.0212ms }) }
mdns发现peer
- 在计算机网络中,mDNS (Multicast DNS) 是一种用于在局域网内部广播和发现服务的协议。它允许设备在没有集中式DNS服务器的情况下相互发现和通信,特别是在没有预先配置的情况下。
use libp2p::{futures::StreamExt, identity,mdns::{Mdns, MdnsConfig, MdnsEvent},swarm::{Swarm, SwarmEvent},PeerId,
};
use std::error::Error;#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {let new_key = identity::Keypair::generate_ed25519();let new_peer_id = PeerId::from(new_key.public());println!("New Peer ID is: {:?}", new_peer_id);let transport = libp2p::development_transport(new_key).await?; // 使用密钥对创建传输let behaviour = Mdns::new(MdnsConfig::default()).await?; // 创建网络行为let mut swarm = Swarm::new(transport, behaviour, new_peer_id); // 创建Swarmswarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;loop {match swarm.select_next_some().await {SwarmEvent::NewListenAddr { address, .. } => {println!("Listening on local Address {:?}", address)}SwarmEvent::Behaviour(MdnsEvent::Discovered(peers)) => {for (peer, addr) in peers {println!("discovered {} {}", peer, addr);}}SwarmEvent::Behaviour(MdnsEvent::Expired(expired)) => {for (peer, addr) in expired {println!("expired {} {}", peer, addr);}}_ => {}}}
}
- 运行效果
PS C:\Users\kingchuxing\Documents\CODE\P2PRecipeApp> cargo run
New Peer ID is: PeerId("12D3KooWMU94yU8ZAFnPdRwLyQ9FuR47sVQfMG9VJUiiykCvmYdt")
Listening on local Address "/ip4/192.168.0.102/tcp/51361"
Listening on local Address "/ip4/127.0.0.1/tcp/51361"
discovered 12D3KooWNMofXEV4fp5NCEBF3m7km3keRnAuScrhoKqvc5Jiacy9 /ip4/192.168.0.102/tcp/51360
discovered 12D3KooWNMofXEV4fp5NCEBF3m7km3keRnAuScrhoKqvc5Jiacy9 /ip4/127.0.0.1/tcp/51360
PS C:\Users\kingchuxing\Documents\CODE\P2PRecipeApp> cargo runFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.28sRunning `target\debug\P2PRecipeApp.exe`
New Peer ID is: PeerId("12D3KooWNMofXEV4fp5NCEBF3m7km3keRnAuScrhoKqvc5Jiacy9")
Listening on local Address "/ip4/192.168.0.102/tcp/51360"
Listening on local Address "/ip4/127.0.0.1/tcp/51360"
discovered 12D3KooWMU94yU8ZAFnPdRwLyQ9FuR47sVQfMG9VJUiiykCvmYdt /ip4/192.168.0.102/tcp/51361
discovered 12D3KooWMU94yU8ZAFnPdRwLyQ9FuR47sVQfMG9VJUiiykCvmYdt /ip4/127.0.0.1/tcp/51361
CG
- Swarm部分相关代码来自教程使用 Async Rust 构建简单的 P2P 节点【完结】
相关文章:
p2p、分布式,区块链笔记: libp2p基础
通信密钥 noise::{Keypair, X25519Spec} X25519/Ed25519类似RSA 算法。Noise 用于设计和实现安全通信协议。它允许通信双方在没有预先共享密钥的情况下进行安全的密钥交换,并通过加密和身份验证保护通信内容。libp2p 提供了对 Noise 协议的原生支持,它允…...
企业本地大模型用Ollama+Open WebUI+Stable Diffusion可视化问答及画图
最近在尝试搭建公司内部用户的大模型,可视化回答,并让它能画图出来, 主要包括四块: Ollama 管理和下载各个模型的工具Open WebUI 友好的对话界面Stable Diffusion 绘图工具Docker 部署在容器里,提高效率以上运行环境Win10, Ollama,SD直接装在windows10下, 然后安装Docker…...
Unity学习笔记---调试
使用Log进行调试 使用Debug.Log方法可以将一些运行时信息打印到Console窗口中。 打印时间戳 //获取时间 Debug.Log(DateTime.Now.ToString());//打印毫秒级的时间 Debug.Log(((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000) * 0.001); 打印自定义文…...
Py之dashscope:dashscope的简介、安装和使用方法、案例应用之详细攻略
Py之dashscope:dashscope的简介、安装和使用方法、案例应用之详细攻略 目录 dashscope的简介 1、产品的主要特点和优势包括: dashscope的安装和使用方法 1、安装 2、使用方法 dashscope的案例应用 1、通义千问-Max:通义千问2.5系列 2…...
Go使用Gin框架开发的Web程序部署在Linux时,无法绑定监听Ipv4端口
最近有写一部分go语言开发的程序,在部署程序时发现,程序在启动后并没有绑定ipv4的端口,而是直接监听绑定ipv6的端口。 当我用netstat -antup | grep 3601查找我的gin服务启动的端口占用情况的时候发现,我的服务直接绑定了tcp6 &a…...
【图解大数据技术】Hadoop、HDFS、MapReduce、Yarn
【图解大数据技术】Hadoop、HDFS、MapReduce、Yarn HadoopHDFSHDFS架构写文件流程读文件流程 MapReduceMapReduce简介MapReduce整体流程 Yarn Hadoop Hadoop是Apache开源的分布式大数据存储与计算框架,由HDFS、MapReduce、Yarn三部分组成。广义上的Hadoop其实是指H…...
AGPT•intelligence:带你领略全新量化交易的风采
随着金融科技的快速发展,量化交易已经成为了投资领域的热门话题。越来越多的投资者开始关注和使用量化交易软件来进行投资决策。在市场上有许多量化交易软件可供选择。 Delaek,是一位资深的金融科技专家,在 2020年成立一家专注于数字资产量化…...
HarmonyOS Next开发学习手册——创建轮播 (Swiper)
Swiper 组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。通常,在一些应用首页显示推荐的内容时,需要用到轮播显示的能力。 针对复杂页面场景,可以使用 Sw…...
【计算机视觉】mmcv库详细介绍
文章目录 MMVC库概览特点和优势主要组件应用案例示例一:数据加载和处理示例二:模型训练和验证MMVC库概览 MMCV 是一个用于计算机视觉研究的开源库,它为各种视觉任务提供了底层的、高度优化的 API。该库涵盖了从数据加载到模型训练的各个方面,广泛应用于开源项目,如 MMDet…...
【面试系列】Go 语言高频面试题
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…...
React 扩展
文章目录 PureComponent1. 使用 React.Component,不会进行浅比较2. 使用 shouldComponentUpdate 生命周期钩子,手动比较3. 使用 React.PureComponent,自动进行浅比较 Render Props1. 使用 Children props(通过组件标签体传入结构&…...
IT入门知识第八部分《云计算》(8/10)
目录 云计算:现代技术的新篇章 1. 云计算基础 1.1 云计算的起源和发展 云计算的早期概念 云计算的发展历程 1.2 云计算的核心特点 按需自助服务 广泛的网络访问 资源池化 快速弹性 按使用量付费 1.3 云计算的优势和挑战 成本效益 灵活性和可扩展性 维…...
Linux-笔记 全志T113移植正点4.3寸RGB屏幕笔记
目录 前言 线序整理 软件 显示调试 触摸调试 背光调试 前言 由于手头有一块4.3寸的RGB屏幕(触摸IC为GT1151),正好开发板上也有40Pin的RGB接口,就想着给移植一下,前期准备工作主要是整理好线序,然后用转接板与杜邦线连接验证好…...
Linux shell编程学习笔记59: ps 获取系统进程信息,类似于Windows系统中的tasklist 命令
0 前言 系统进程信息是电脑网络信息安全检查中的一块重要内容,对于使用Linux和基于Linux作为操作系统的电脑来说,可以使用ps命令。 1 ps命令 的功能、格式和选项说明 1.1 ps命令 的功能 Linux 中的ps(意为:process status&…...
在Android中使用ProgressBar显示进度
在Android中使用ProgressBar显示进度 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Android应用中使用ProgressBar来显示进度。ProgressB…...
Java基础面试题(简单版):
1.java的8个基本数据类型? 整型: byte(占用1个字节) short(占用2个字节) int(占用4个字节) long(占用8个字节) 浮点型: float(占用4个字节)、double(占用8个字节) 字符型: char 布尔型: boolean 2.ArrayList和LinkedList的区别? 可以说ArrayList和LinkedList除了是同属于集合…...
Chrome插件:Postman Interceptor 调试的终极利器
今天给大家介绍一款非常实用的工具——Postman Interceptor。 这个工具可以捕捉任何网站的请求,并将其发送到Postman客户端。 对于经常和API打交道的程序员来说,Postman Interceptor真的是神器级别的存在。 下面就让我详细说说这个插件怎么用…...
SpringBoot学习04-[定制SpringMVC]
定制SpringMVC 定制SpringMvc的自动配置定制springmvc-configurePathMatch配置定制SpringMVC-拦截器Interceptor定制SpringMVC-CORS配置全局cors配置针对某个方法加跨域解决 WebMvcConfigurer原理定制SpringMVC-JSONJSON开发jackson的使用定制化json序列化和反序列化 JSON国际化…...
QT拖放事件之六:自定义MIME类型的存储及读取demo
1、MIME类型描述 MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。 浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL…...
架构师必知的绝活-JVM调优
前言 为什么要学JVM? 首先:面试需要 了解JVM能帮助回答面试中的复杂问题。面试中涉及到的JVM相关问题层出不穷,难道每次面试都靠背几百上千条面试八股? 其次:基础知识决定上层建筑 自己写的代码都不知道是怎么回事&a…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
