密码学实用工具
概述
密码学实用工具为 Soroban Smart Contract 提供了一组密码学工具, 包括哈希函数、Merkle 树验证和基于 Merkle 的分发系统。 这些实用工具实现了安全的数据验证和高效的代币分发机制。 密码学实用工具由两个主要包组成:
-
Crypto:一组用于 Soroban 合约的密码学原语和实用工具。
-
Merkle Distributor:一种使用 Merkle 证明来验证分发代币或其他资产的系统。
Crypto 包
crypto 包为 Soroban 合约提供了基本的密码学原语和实用工具, 重点是哈希和 Merkle 树操作。
主要组件
Hashers(哈希器)
提供了一个通用的 Hasher
特征以及常见哈希函数的实现:
-
Sha256
:SHA-256 哈希函数的实现 -
Keccak256
:Keccak-256 哈希函数的实现(在 Ethereum 中使用)
每个哈希器都遵循相同的接口:
pub trait Hasher {
type Output;
fn new(e: &Env) -> Self;
fn update(&mut self, input: Bytes);
fn finalize(self) -> Self::Output;
}
使用示例
哈希数据
use soroban_sdk::{Bytes, Env};
use stellar_contract_utils::crypto::keccak::Keccak256;
use stellar_contract_utils::crypto::hasher::Hasher;
// 使用 Keccak256 哈希一些数据
let e = Env::default();
let data = Bytes::from_slice(&e, "Hello, world!".as_bytes());
let mut hasher = Keccak256::new(&e);
hasher.update(data);
let hash = hasher.finalize();
验证 Merkle 证明
use soroban_sdk::{BytesN, Env, Vec};
use stellar_crypto::keccak::Keccak256;
use stellar_crypto::merkle::Verifier;
// 验证叶子是 Merkle 树的一部分
let e = Env::default();
let root = /* merkle 根作为 BytesN<32> */;
let leaf = /* 要验证的叶子作为 BytesN<32> */;
let proof = /* 证明作为 Vec<BytesN<32>> */;
let is_valid = Verifier::<Keccak256>::verify(&e, proof, root, leaf);
Merkle Distributor
Merkle Distributor 包构建在 crypto 包之上,提供了一个使用 Merkle 证明来验证分发代币或 其他资产的系统。
关键概念
使用示例
use soroban_sdk::{contract, contractimpl, contracttype, Address, BytesN, Env, Vec};
use stellar_contract_utils::crypto::keccak::Keccak256;
use stellar_contract_utils::merkle_distributor::{IndexableLeaf, MerkleDistributor};
// 定义叶节点结构
#[contracttype]
struct LeafData {
pub index: u32,
pub address: Address,
pub amount: i128,
}
// 为叶子结构实现 IndexableLeaf
impl IndexableLeaf for LeafData {
fn index(&self) -> u32 {
self.index
}
}
#[contract]
pub struct TokenDistributor;
#[contractimpl]
impl TokenDistributor {
// 使用 Merkle 根初始化分发器
pub fn initialize(e: &Env, root: BytesN<32>) {
MerkleDistributor::<Keccak256>::set_root(e, root);
}
// 通过提供证明来声明代币
pub fn claim(e: &Env, leaf: LeafData, proof: Vec<BytesN<32>>) {
// 验证证明并标记为已声明
MerkleDistributor::<Keccak256>::verify_and_set_claimed(e, leaf.clone(), proof);
// 根据叶子数据转移代币或执行其他操作
// ...
}
// 检查是否已声明索引
pub fn is_claimed(e: &Env, index: u32) -> bool {
MerkleDistributor::<Keccak256>::is_claimed(e, index)
}
}