< 返回版块

odd-cat 发表于 2021-10-19 20:35

Tags:rust,日报,hash-tree,merkle-tree,sila

rs-merkle:一个用Rust编写的高级散列树库

rs_merkle: an advanced hash tree library for Rust

rs-merkle是一个高级的Rust merkle树库。基本功能包括构建Merkle树、创建和验证单个和多个元素的Merkle证明,即多重证明。高级功能包括对树进行事务性更改,并回滚到以前提交的任何树状态,类似于Git。 该库有两个主要结构。第一个是MerkleTree,它构建了一棵树,可用于验证数据完整性并生成Merkle证明。第二种是MerkleProof,可用于验证集合中是否包含项目。 这个库是高度可定制的。哈希算法和树的构建方式可以通过Hasher trait进行配置。

关于Merkle树

Merkle树,也称为散列树,用于验证两个或多个参与方是否拥有相同的数据,而无需交换整个数据集合。 Merkle树被用于Git、Mercurial、ZFS、IPFS、比特币、以太坊、Cassandra等许多领域。例如,在Git中,Merkle树用于查找本地和远程存储库状态之间的增量,以便通过网络仅传输它们之间的差异。在比特币中,Merkle树用于验证交易是否包含在区块中,而无需下载整个区块内容。ZFS使用Merkle树快速验证数据完整性,提供保护,防止幻象写入、磁盘固件中的错误、电源浪涌和其他原因导致的静默数据损坏。

示例: 验证Merkle证明:

let leaf_values = ["a", "b", "c", "d", "e", "f"];
let leaves: Vec<[u8; 32]> = leaf_values
    .iter()
    .map(|x| Sha256::hash(x.as_bytes()))
    .collect();

let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
let indices_to_prove = vec![3, 4];
let leaves_to_prove = leaves.get(3..5).ok_or("can't get leaves to prove")?;
let merkle_proof = merkle_tree.proof(&indices_to_prove);
let merkle_root = merkle_tree.root().ok_or("couldn't get the merkle root")?;
// Serialize proof to pass it to the client
let proof_bytes = merkle_proof.to_bytes();

// Parse proof back on the client
let proof = MerkleProof::<Sha256>::try_from(proof_bytes)?;

assert!(proof.verify(merkle_root, &indices_to_prove, leaves_to_prove, leaves.len()));

项目地址:https://github.com/antouhou/rs-merkle

项目文档:https://docs.rs/rs_merkle/1.0.0/rs_merkle/


在Rust中使用建造者模式

Builder pattern in Rust

由于Rust不支持函数的可选参数和具名参数,也不支持函数重载,建造者模式在Rust中被广泛使用。 以下是一个使用建造者模式创建一个User结构体的代码示例:

#[derive(Debug)]
struct User {
    id: String,
    email: String,
    first_name: Option<String>,
    last_name: Option<String>
}

struct UserBuilder {
    id: String,
    email: String,
    first_name: Option<String>,
    last_name: Option<String>
}


impl UserBuilder {
    fn new(id: impl Into<String>, email: impl Into<String>) -> Self {
        Self {
            id: id.into(),
            email: email.into(),
            first_name: None,
            last_name: None,
        }
    }

    fn first_name(mut self, first_name: impl Into<String>) -> Self {
        self.first_name = Some(first_name.into());
        self
    }

    fn last_name(mut self, last_name: impl Into<String>) -> Self {
        self.last_name = Some(last_name.into());
        self
    }

    fn build(self) -> User {
        let Self { id, email, first_name, last_name } = self;
        User { id, email, first_name, last_name }
    }
}

impl User {
    fn builder(id: impl Into<String>, email: impl Into<String>) -> UserBuilder {
        UserBuilder::new(id, email)
    }
}

fn main() {
    let greyblake = User::builder("13","greyblake@example.com")
        .first_name("Sergey")
        .build();
    dbg!(greyblake);
}

要点:

  1. 使用UserBuilder来创建User结构体;
  2. 结构体的必要字段通过必选位置显示传入建造者的new方法,可选参数通过setter来设置;
  3. 最后通过build函数返回完整的结构体实例;

sila: 另一个用于团队指导的终端多路复用器。

Another terminal multiplexer for team leads.

sila - 读作[shila],巴利语中代表「道德」;

这是一个简单的终端多路复用器,用rust编写,使用yaml格式的配置文件配置项目。

基本用法

> help

list                      List the terminal names.
pin     <term1> <term2>   Pin one or multiple terminals separated by space. Following commands will be run on top of pinned ones.
unpin   [term1]           Unpin all terminals if no argument is provided or the specific ones.
count                     Count the number of terminals.
exit                      Close the application.

项目地址:https://github.com/alxolr/sila


From 日报小组 odd-cat

社区学习交流平台订阅:

Rust.cc 论坛: 支持 rss

微信公众号:Rust 语言中文社区

评论区

写评论
whispor 2021-10-20 14:18

Rust中Self和self的区别和用法有什么需要注意的么?总是被搞蒙

1 共 1 条评论, 1 页