216 lines
5.3 KiB
Rust
216 lines
5.3 KiB
Rust
//! 区块结构定义
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
use sha3::{Digest, Sha3_384};
|
||
use chrono::{DateTime, Utc};
|
||
|
||
/// 区块头
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct BlockHeader {
|
||
pub version: u32,
|
||
pub height: u64,
|
||
pub timestamp: DateTime<Utc>,
|
||
pub prev_hash: String,
|
||
pub merkle_root: String,
|
||
pub state_root: String,
|
||
pub validator: String,
|
||
pub signature: String,
|
||
}
|
||
|
||
impl BlockHeader {
|
||
pub fn new(height: u64, prev_hash: String, validator: String) -> Self {
|
||
BlockHeader {
|
||
version: 1,
|
||
height,
|
||
timestamp: Utc::now(),
|
||
prev_hash,
|
||
merkle_root: String::new(),
|
||
state_root: String::new(),
|
||
validator,
|
||
signature: String::new(),
|
||
}
|
||
}
|
||
|
||
/// 计算区块头哈希
|
||
pub fn hash(&self) -> String {
|
||
let data = format!(
|
||
"{}{}{}{}{}{}{}",
|
||
self.version,
|
||
self.height,
|
||
self.timestamp.timestamp(),
|
||
self.prev_hash,
|
||
self.merkle_root,
|
||
self.state_root,
|
||
self.validator
|
||
);
|
||
|
||
let hash = Sha3_384::digest(data.as_bytes());
|
||
hex::encode(hash)
|
||
}
|
||
}
|
||
|
||
/// 交易结构
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Transaction {
|
||
pub from: String,
|
||
pub to: String,
|
||
pub amount: u64,
|
||
pub nonce: u64,
|
||
pub signature: String,
|
||
}
|
||
|
||
impl Transaction {
|
||
pub fn new(from: String, to: String, amount: u64, nonce: u64) -> Self {
|
||
Transaction {
|
||
from,
|
||
to,
|
||
amount,
|
||
nonce,
|
||
signature: String::new(),
|
||
}
|
||
}
|
||
|
||
/// 计算交易哈希
|
||
pub fn hash(&self) -> String {
|
||
let data = format!(
|
||
"{}{}{}{}",
|
||
self.from, self.to, self.amount, self.nonce
|
||
);
|
||
let hash = Sha3_384::digest(data.as_bytes());
|
||
hex::encode(hash)
|
||
}
|
||
}
|
||
|
||
/// 区块体
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct BlockBody {
|
||
pub transactions: Vec<Transaction>,
|
||
}
|
||
|
||
impl BlockBody {
|
||
pub fn new() -> Self {
|
||
BlockBody {
|
||
transactions: Vec::new(),
|
||
}
|
||
}
|
||
|
||
pub fn add_transaction(&mut self, tx: Transaction) {
|
||
self.transactions.push(tx);
|
||
}
|
||
|
||
/// 计算Merkle根
|
||
pub fn calculate_merkle_root(&self) -> String {
|
||
if self.transactions.is_empty() {
|
||
return String::from("0000000000000000000000000000000000000000000000000000000000000000");
|
||
}
|
||
|
||
let mut hashes: Vec<String> = self.transactions
|
||
.iter()
|
||
.map(|tx| tx.hash())
|
||
.collect();
|
||
|
||
while hashes.len() > 1 {
|
||
let mut new_hashes = Vec::new();
|
||
|
||
for chunk in hashes.chunks(2) {
|
||
let combined = if chunk.len() == 2 {
|
||
format!("{}{}", chunk[0], chunk[1])
|
||
} else {
|
||
format!("{}{}", chunk[0], chunk[0])
|
||
};
|
||
|
||
let hash = Sha3_384::digest(combined.as_bytes());
|
||
new_hashes.push(hex::encode(hash));
|
||
}
|
||
|
||
hashes = new_hashes;
|
||
}
|
||
|
||
hashes[0].clone()
|
||
}
|
||
}
|
||
|
||
impl Default for BlockBody {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
/// 完整区块
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Block {
|
||
pub header: BlockHeader,
|
||
pub body: BlockBody,
|
||
}
|
||
|
||
impl Block {
|
||
pub fn new(height: u64, prev_hash: String, validator: String) -> Self {
|
||
Block {
|
||
header: BlockHeader::new(height, prev_hash, validator),
|
||
body: BlockBody::new(),
|
||
}
|
||
}
|
||
|
||
pub fn add_transaction(&mut self, tx: Transaction) {
|
||
self.body.add_transaction(tx);
|
||
}
|
||
|
||
/// 完成区块(计算Merkle根和哈希)
|
||
pub fn finalize(&mut self) {
|
||
self.header.merkle_root = self.body.calculate_merkle_root();
|
||
}
|
||
|
||
/// 获取区块哈希
|
||
pub fn hash(&self) -> String {
|
||
self.header.hash()
|
||
}
|
||
|
||
/// 获取区块高度
|
||
pub fn height(&self) -> u64 {
|
||
self.header.height
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_block_creation() {
|
||
let block = Block::new(1, "genesis".to_string(), "validator1".to_string());
|
||
assert_eq!(block.height(), 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_transaction_hash() {
|
||
let tx = Transaction::new(
|
||
"alice".to_string(),
|
||
"bob".to_string(),
|
||
100,
|
||
1
|
||
);
|
||
let hash = tx.hash();
|
||
assert!(!hash.is_empty());
|
||
assert_eq!(hash.len(), 96); // SHA3-384 = 48 bytes = 96 hex chars
|
||
}
|
||
|
||
#[test]
|
||
fn test_merkle_root() {
|
||
let mut body = BlockBody::new();
|
||
body.add_transaction(Transaction::new("a".to_string(), "b".to_string(), 10, 1));
|
||
body.add_transaction(Transaction::new("c".to_string(), "d".to_string(), 20, 2));
|
||
|
||
let root = body.calculate_merkle_root();
|
||
assert!(!root.is_empty());
|
||
}
|
||
|
||
#[test]
|
||
fn test_block_finalize() {
|
||
let mut block = Block::new(1, "genesis".to_string(), "validator1".to_string());
|
||
block.add_transaction(Transaction::new("alice".to_string(), "bob".to_string(), 100, 1));
|
||
block.finalize();
|
||
|
||
assert!(!block.header.merkle_root.is_empty());
|
||
}
|
||
}
|