Desde un punto de vista técnico, la cadena de bloques es una base de datos descentralizada, distribuida de igual a igual, que garantiza la coherencia final. Primero implementemos el bloque y la cadena de bloques.


bloquear

Los bloques almacenan información válida en la cadena de bloques, como transacciones. En esta parte, primero implementamos un bloque simple y una cadena de bloques, construimos el marco y luego lo mejoramos gradualmente a medida que se agregan nuevas funciones.


encabezado de bloque

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]pub struct BlockHeader {    timestamp: i64,    prev_hash: String,    nonce: usize,}
  • marca de tiempo: marca de tiempo

  • prev_hash: valor hash del bloque anterior

  • nonce: número aleatorio, utilizado para calcular la prueba de trabajo

bloquear

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]pub struct Block {    header: BlockHeader,    data: String,    hash: String,}
  • encabezado: encabezado de bloque

  • datos: Los datos almacenados en el bloque.Cuando la función de transacción se implemente más tarde, este campo se modificará a un conjunto de transacciones.

  • hash: valor hash del bloque

Se calcula y almacena un valor hash en cada bloque, y el hash del bloque anterior se almacena en el encabezado del bloque, formando así una cadena de bloques. Como se muestra en la figura:

imagen

Calcular el valor hash

Podemos codificar el encabezado del bloque, porque el encabezado del bloque contiene toda la información del bloque, y el valor hash de la transacción se agregará al encabezado del bloque más adelante.


Primero use las bibliotecas serde y bincode para serializar el encabezado del bloque en bytes y luego use SHA256 para calcular el valor hash.

pub fn serialize<T>(data: &T) -> Result<Vec<u8>, BlockchainError> where    T: Serialize + ?Sized{    Ok(bincode::serialize(data)?)}
pub fn hash_to_str(data: &[u8]) -> String { let mut hasher = Sha3::sha3_256(); hasher.input(data); hasher.result_str()}

Crear nuevos bloques e implementar bloques de génesis

El bloque de génesis es el primer bloque de la cadena de bloques, por lo que el prev_hash en el encabezado del bloque no tiene valor.

pub fn new(data: &str, prev_hash: &str) -> Self {    let mut block = Block {        header: BlockHeader {             timestamp: Utc::now().timestamp(),             prev_hash: prev_hash.into(),             nonce: 0,         },        data: data.into(),        hash: String::new(),    };    block.set_hash();
block}
pub fn create_genesis_block() -> Self { Self::new("创世区块", "")}

cadena de bloques

Ahora almacenamos primero el bloque en la memoria, y la última parte almacenará el bloque en la base de datos KV.

pub struct Blockchain {    blocks: Vec<Block>,    height: usize,}
  • bloques: colección de bloques

  • altura: La altura de la cadena de bloques, es decir, el número de bloques.

minería

es agregar el bloque a la cadena

pub fn mine_block(&mut self, data: &str) {    let prev_block = self.blocks.last().unwrap();    let block = Block::new(data, prev_block.get_hash().as_str());    self.blocks.push(block);    self.height += 1;}

Crea una cadena de bloques y únete a un bloque

let mut bc = Blockchain::new();
bc.mine_block("Justin -> Bob 2 btc");bc.mine_block("Justin -> Bruce 2 btc");
bc.blocks_info();

Resultados de la:

$ RUST_LOG=info cargo run --example gen_bc --quiet
INFO blockchain_rust_part_1::blocks::blockchain: Block { header: BlockHeader { timestamp: 1650188197, prev_hash: "", nonce: 0, }, data: "创世区块", hash: "dc7e47a45b9b898269efbc4e05cff5d2c8c9dac17cd181451471e62cdcd646c6",}INFO blockchain_rust_part_1::blocks::blockchain: Block { header: BlockHeader { timestamp: 1650188197, prev_hash: "dc7e47a45b9b898269efbc4e05cff5d2c8c9dac17cd181451471e62cdcd646c6", nonce: 0, }, data: "Justin -> Bob 2 btc", hash: "8620a3e7965c71ccf391898bb53a374db8d133a2c7dcbfa05cea9b83a06c04dc",}INFO blockchain_rust_part_1::blocks::blockchain: Block { header: BlockHeader { timestamp: 1650188197, prev_hash: "8620a3e7965c71ccf391898bb53a374db8d133a2c7dcbfa05cea9b83a06c04dc", nonce: 0, }, data: "Justin -> Bruce 2 btc", hash: "3618c57b1aec52b56f820bc20a03f171174a059c5a982e486e0975c1eccbaa12",}

Estructura de ingeniería


imagen

Código completo:

https://github.com/Justin02180218/blockchain_rust