区块链-RUST实战篇(1)

admin 2024年8月12日16:23:24评论8 views字数 2859阅读9分31秒阅读模式

0x01 前言

好久不见。最近有好多想写但没有发的内容,内容很杂很多,一直想找个空闲的时间整理一下。在连续熬了两个通宵之后下定决心,先把最近半生不熟的rust区块链部分给整理一下。

0x02 P2P网络核心概念及应用

1.基本概念

p2p网络是一种分布式系统,可以在网络中的不同计算机间共享资源,比如带宽、cpu等。应用最广泛的就是区块链技术

区块链-RUST实战篇(1)

在p2p网络中,需要清楚以下最基本的两个概念

1.传输协议: 底层使用的是传输层的tcp/udp协议,但会在这个基础上运用多路复用 应用多种应用层协议

2.节点标识: 类似于区块链中的钱包地址,p2p的每个node都需要一个标识,节点标识是通过非对称公钥加密哈希而来

2.程序

我们来着手一个最简单的例子,ping案例

cargo new ping-project

在配置文件中加入如下依赖

[dependencies]
libp2p = "0.46"
tokio = { version = "1.19", features = ["full"] }

如果构建有问题的可以把libp2p的版本换成0.53.1

main.rs

use std::error::Error;

use libp2p::{
   futures::StreamExt,
   identity,
   ping::{Ping, PingConfig},
   swarm::SwarmEvent,
   Multiaddr, PeerId, Swarm,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
   // 生成认证密钥
   let key_pair = identity::Keypair::generate_ed25519();

   // 基于密钥对的公钥,生成节点唯一标识peerId
   let peer_id = PeerId::from(key_pair.public());
   println!("节点ID: {peer_id}");

   // 声明Ping网络行为
   let behaviour = Ping::new(PingConfig::new().with_keep_alive(true));

   // 传输
   let transport = libp2p::development_transport(key_pair).await?;

   // 网络管理模块
   let mut swarm = Swarm::new(transport, behaviour, 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)?;
       println!("链接远程节点: {remote_peer}");
  }

   loop {
       // 匹配网络事件
       match swarm.select_next_some().await {
           // 监听事件
           SwarmEvent::NewListenAddr { address, .. } => {
               println!("本地监听地址: {address}");
          }
           // 网络行为事件
           SwarmEvent::Behaviour(event) => println!("{:?}", event),
           _ => {}
      }
  }
}

当然你也可以分两块写,一个server端,一个client端

在配置文件中写入

[[bin]]
name = "server"
path = "src/server.rs"

[[bin]]
name = "client"
path = "src/client.rs"

我这里写的是第二种

cargo run --bin server

区块链-RUST实战篇(1)

cargo run --bin client /ip4/127.0.0.1/tcp/41677

区块链-RUST实战篇(1)

0x03 区块和区块链

初步了解了P2P,那么接下来将深入区块链

区块链在我的理解上,是一个去中心化、P2P形式的分布式数据库

首先我们了解一下区块

区块存储了基本的信息,比如交易,一个个交易的区块也就构成了狭义理解的区块链

这里我们先暂且不记录过多的信息,搭建一个初步的框架

区块与区块头如下

区块链-RUST实战篇(1)

区块链-RUST实战篇(1)

后面需要计算hash

区块链-RUST实战篇(1)

接下来将从头建造区块,以及实现创世块,创世块prev_hash无值

区块链-RUST实战篇(1)

设置完区块,将继续打造区块链

区块链-RUST实战篇(1)

挖矿模块->把区块加入区块链中

区块链-RUST实战篇(1)

最后完成初始化

区块链-RUST实战篇(1)

 cargo run --example gen_bc --quiet RUST_LOG=info

区块链-RUST实战篇(1)

目录结构如下

区块链-RUST实战篇(1)

0x04 POW 工作量证明

在0x03部分我们完成了初步的区块链实现,但挖矿只需赋值即可,所以我们需要通过工作量证明来

按照pow的思路: ->提出一个计算难题->计算不对称性,使满足目标哈希->验证->区块链增加

目前市面上广为流传的便是:以 SHA256 算法计算一个目标哈希,使得这个哈希值符合前 N 位全是 0。

这个N的数值,从某种意义上来说也可以量化成计算的难度

我们先把blockheader值改改

区块链-RUST实战篇(1)

那接下来我们就可以详细讲讲bits和nonce的含义了

bits:计算难度,区块hash值的前多少位是 0。
nonce:记录满足bits难度,重复计算的次数。

一般来说,计算的区块hash值前多少位是被硬编码的,比如这里我们设置成7

const CURR_BITS: usize = 8;

新建一个pow.rs,用以计算哈希值

区块链-RUST实战篇(1)

进行运行

 cargo run --example gen_bc --quiet RUST_LOG=info

expected `Result<String>`, but found `Result<Vec<u8>>`

区块链-RUST实战篇(1)

可以看到,存在nonce值了

0x05 持久化

之前的区块链是存储在内存中的,无法持久化存储。

搜罗了大部分网上的教程,最简单的方法就是将区块链存储在硬盘中,默认使用默认使用KV数据库sled。

数据库的结构即区块链的结构

好久没用非关系数据库,这次我们选择rust的嵌入式数据库好伙伴!sled!

首先构造一下数据库结构

区块链-RUST实战篇(1)

实现数据库的基本功能

区块链-RUST实战篇(1)

实现区块链与数据库的对接

区块链-RUST实战篇(1)

完成代码见后文,这里我们先测试一下

cargo run --example gen_bc --quiet RUST_LOG=info

区块链-RUST实战篇(1)

可以看到这里测试成功

区块链-RUST实战篇(1)

0x06 总结

这只是实现了区块链的初步功能,还有钱包、交易等功能没有实现,笔者也在慢慢探索,如果感兴趣的话请后续敬请关注吧(后续出点src内容再出区块链了)

初步代码地址

https://github.com/jiankeguyue/Rust_BlockChain

原文始发于微信公众号(剑客古月的安全屋):区块链-RUST实战篇(1)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月12日16:23:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   区块链-RUST实战篇(1)https://cn-sec.com/archives/3058396.html

发表评论

匿名网友 填写信息