8 个版本
0.4.0 | 2023年7月13日 |
---|---|
0.3.4 | 2023年3月1日 |
0.3.3 | 2023年2月22日 |
0.3.2 | 2022年11月10日 |
0.1.0 | 2021年6月4日 |
#1547 in 神奇豆子
55KB
1.5K SLoC
认证映射
此软件包提供了一种映射,可以被互联网计算机canister用来实现认证查询。
特性
-
增量认证。canister可以在保持认证成本相对较低的同时存储数千个条目。
-
不存在证明。如果请求的键不在映射中,返回的树结构允许调用者验证这一点。
-
相对较小的Merkle证明。证书的额外大小为O(log N),其中N是映射中的条目数量。
实现细节
canister使用增强的红黑二叉搜索树来存储条目。搜索树的每个节点都附带了从该节点根部的子树构建的哈希树的根哈希。每次旋转或修改树时,相应的哈希都会在O(1)时间内重新计算。
lib.rs
:
此软件包提供了一个由Merkle树支持的映射,可以被互联网计算机canister用来实现认证查询。
您可以使用 RbTree
类型,将已知的名称映射到您想要认证的值,来认证您的数据。在将它的 root_hash
记录到您的 canister 的 认证数据 中后,查询调用可以访问一个 数据证书,证明 IC 认证了该哈希值,在 路径 /canister/<canister id>/certified_data
下。通过提供这个证书以及证明值存在于哈希中的 witness
,您可以向调用者证明 IC 认证了数据。
示例
thread_local! {
static COUNTER: Cell<i32> = Cell::new(0);
static TREE: RefCell<RbTree<&'static str, Hash>> = RefCell::new(RbTree::new());
}
#[update]
fn inc() {
let count = COUNTER.with(|counter| {
let count = counter.get() + 1;
counter.set(count);
count
});
TREE.with(|tree| {
let mut tree = tree.borrow_mut();
tree.insert("counter", leaf_hash(&count.to_be_bytes()));
ic_cdk::api::set_certified_data(&tree.root_hash());
})
}
#[derive(CandidType)]
struct CertifiedCounter {
count: i32,
certificate: Vec<u8>,
witness: Vec<u8>,
}
#[query]
fn get() -> CertifiedCounter {
let certificate = ic_cdk::api::data_certificate().expect("No data certificate available");
let witness = TREE.with(|tree| {
let tree = tree.borrow();
let mut witness = vec![];
let mut witness_serializer = serde_cbor::Serializer::new(&mut witness);
witness_serializer.self_describe();
tree.witness(b"counter").serialize(&mut witness_serializer).unwrap();
witness
});
let count = COUNTER.with(|counter| counter.get());
CertifiedCounter {
count,
certificate,
witness,
}
}
依赖关系
~0.5–0.8MB
~19K SLoC