白话区块链,用rust实现一个mini区块链!
2024-06-21 09:36 阅读(134)
区块链并不神秘

区块链其实并不神秘,它是由加密技术、点对点网络、数据存储、共识算法组成。这些技术早在“区块链”这个词流行之前就已经存在并趋于成熟,区块链基于这些比较成熟的技术组合而来,是知识和技术的积累,是灵感的爆发,是量到质的飞跃。这个灵感的爆发来自于日本的“中本聪”,他提出了区块链的概念并发布了《比特币白皮书:一种点对点的电子现金系统》(pdf电子书微信公众号后台回复:比特币)。

区块链发展的三个阶段

2008年全球金融危机爆发,这次危机让很多先行者对现代金融体系逐渐失望,中本聪敏锐的察觉到,大部分互联网贸易都需要依赖“可信任的第三方金融机构”,一旦遇到极端的信任危机,信任关系失衡将导致金融体系结构塌陷。中本聪想到了去掉第三方担保的可能性,设计了一套基于密码学无需买卖双方彼此信任就能完成支付的数字货币系统——比特币,该系统还原了支付本来的样子并创新性的引入了支付脚本。但该脚本目前有缺陷,只支持顺序执行的指令,对于分支判断及循环逻辑是不支持的,这限制了比特币在支付领域的灵活性,在某些特定场景不能完成支付。

V神看到了比特币技术架构中的局限性,他扩展了支付脚本的功能,使其更加智能,发布了《以太坊:一个下一代加密货币和去中心化应用平台》(pdf电子书微信公众号后台回复:以太坊)。他在加密货币的基础上增加了智能合约功能,该功能可以将一切事实锚定到以太坊进行交易,实现价值的传递,这也是区块链发展的最终形态是价值网络的由来,以太坊将区块链技术推向高潮。

起源一次著名的黑客攻击事件——The DAO事件,该事件导致以太坊中价值6000万美元的以太币被偷走,事件发生后,以太坊社区发生激烈讨论,一部分人主张将以太坊主网回滚至攻击之前,另一部分人主张不回滚。最终的结果是以太坊在2016年7月20日进行了硬分叉,将以太坊分裂成为两个网络ETH和ETC。ETH删除了黑客攻击的痕迹,并将被盗走的以太币归还给原始拥有者,现在说的以太坊就是这一个回滚的分支。ETC保留了黑客攻击的痕迹,以保持区块链去中心化和不可篡改的基本原则,这一分叉导致了区块链的野蛮生长。

什么是软分叉呢?什么是硬分叉?

软分叉是区块链部分节点版本升级后仍然能够互相兼容,存储上是同一条链;硬分叉是从某个节点开始完全不兼容,从而形成了多个链条。如下图所示:

图片

图片

为什么会野蛮生长呢?

在硬分叉前你有100枚ETH,硬分叉后你有100枚ETH和100枚ETC,相当于在什么都没有干的情况下,凭空多出来100个有价值的凭证,这还了得,资本逐利的本性看到了这一点,潘多拉的魔盒被打开。

后来各种各样的白皮书相继发布,越来越多的硬分叉,凭空创造着财富,但这终究是一个梦幻泡影,随着资本的推动和越来越多人的站台,将这一虚假的繁荣推向了高潮。直到潮水退去,才发现谁谁谁都没有穿底裤:)

硬分叉之后,以太坊的圈层出现了割裂,形成了公链圈和联盟链圈,驱动着区块链技术朝着两个不同的方向发展。

其中公链圈得到了大量资本的青睐和投资,逐渐演变为去中心化金融,术语称之为DeFi(Decentralised Finance),DiFi是运行在区块链上的金融服务。由于不断有硬分叉,导致形成了不同的区块链网络,不同区块链网络间的通信就叫跨链,但往往区块链和区块链不直接互通,而是通过中继链来桥接,减少耦合。

图片

联盟链圈主要在企业商业活动中发力,侧重往数据存证、数据交换、价值转移方向发展。

总结:不管是比特币还是以太坊,以及后面出现的狗币、猫币等各种币,它的底层技术其实都是区块链。数字货币只是区块链的应用方向之一。

区块链的特点

区块链主要有以下特点:

最简单的可以用铁锁连环这幅图来解释:

图片

每把锁代表着一家小区业主,他们不需要物业公司统一管理,只需要管理维护自己的锁就能保证系统的正常运行。每一把锁有大有小,有贵的有便宜的,业主也可能有多辆车,但在这个系统中他们没有地位上的差别。而且,当有新的业主加入或者有业主搬走,只需要增加或去掉相应的锁就好。

你有没有发现,这里面就蕴含了去中心化的概念。每一把锁只有锁主人能打开,包含了不可篡改的含义。

区块链中的核心技术
区块链面临的技术问题和考验
挖矿和挖矿奖励

区块链节点数据需要大量的存储,而普通个人计算机是无法胜任的,需要专门的服务器或为挖矿而生的矿机机主门提供存储,并且计算区块需要消耗一定的电力和计算资源,为了区块链的正常发展,需要给他们的付出以一定的回报,起到正向激励作用,给他们发比特币作为付出的奖励。

区块链结构

区块主要包含:区块头和区块体。

区块头包含该区块的基本属性:前置区块哈希用于区块间的关联、交易根哈希用于区块和交易之间的关联、区块高度用于标记当前区块在区块链中的位置方便定位、时间戳用于记录打包的时间。

区块交易是一个默克尔树,它是一种树形数据结构,它的构建逻辑是使用相邻的叶子节点进行哈希运算,将得到的哈希值作为两个叶子节点的父节点,依次往上直到根节点。

多个区块之间前后连接形成区块链。

使用rust实现一个mini区块链

使用技术:

区块核心属性:

区块头核心属性:

使用rust结构体表示如下所示:


/// 区块头

#[derive(Serialize, Debug, PartialEq, Eq)]

struct BlockHeader {

    pre_hash: String,

    txs_hash: String,

    time: i64,

}



/// 区块体

#[derive(Debug)]

struct Block {

    // 区块头

    header: BlockHeader,

    // 区块包含的所有交易数据

    tranxs: String,

    // 区块的hash

    hash: String,

}

多个区块相互连接形成区块链,区块链用结构体表示如下:

struct BlockChain {

    blocks: Vec<Block>,

}

接下来为Block实现new方法,用于新建新的区块。

impl Block {

    fn new(txs: String, pre_hash: String) -> Self {

        // 挖矿

        println!("开始挖矿....");

        thread::sleep(Duration::from_secs(5));



        // 准备区块数据

        let time = Utc::now().timestamp();

        let txs_serialize = serialize(&txs);

        let txs_hash = cal_hash(&txs_serialize);

        let mut block = Block {

            header: BlockHeader {

                time: time,

                txs_hash: txs_hash,

                pre_hash: pre_hash,

            },

            tranxs: txs,

            hash: "".to_string(),

        };

        block.set_block_hash();

        println!("产生出一个区块");

        block

    }

    // 计算区块的hash

    fn set_block_hash(&mut self) {

        let header = serialize(&self.header);

        self.hash = cal_hash(&header);

    }

}

方法中sleep五秒,表示挖矿。接下来为BlockChain实现new方法,区块链中的第一个块为创世块,其hash值固定为“2024”。通过add_block方法向区块链中添加区块。

impl BlockChain {

    fn new() -> Self {

        BlockChain {

            blocks: vec![Self::genesis_block()],

        }

    }

    // 添加区块

    fn add_block(&mut self, txs: String) {

        // 前一个区块的hash

        let last_index = self.blocks.len() - 1;

        let pre_block = &self.blocks[last_index];

        let pre_hash = pre_block.hash.clone();

        // 创建新块并加入区块链

        let new_block = Block::new(txs, pre_hash);

        self.blocks.push(new_block);

    }



    // 区块链信息

    fn display(&self) {

        for i in self.blocks.iter() {

            println!("{:#?}", i);

        }

    }



    /// 创世块

    fn genesis_block() -> Block {

        Block::new("创世块".to_string(), "2024".to_string())

    }

}

为了简化,区块中的交易数据使用字符串表示(交易数据应该构建为一棵默克尔树的,防止串改)。

下面编写测试用例:

fn main() {

    let mut block_chain = BlockChain::new();

    let txs = r#"

    账户A向账户B转账5元;

    账户B向账户C转账4.6元;

    账户E向账户A转账100元;

    "#

    .to_string();

    block_chain.add_block(txs);



    let txs = r#"

    账户E向账户B转账5元;

    账户B向账户C转账4.6元;

    账户C向账户A转账100元;

    "#

    .to_string();

    block_chain.add_block(txs);



    block_chain.display();

}

输出如下所示:

图片

目前rust实现的区块链有很多,包括很火的solana,感兴趣的童鞋可以关注一波!