Derek解读-Bytom源码分析-创世区块
简介
https://github.com/Bytom/bytom
本章介绍Derek解读-Bytom源码分析-创世区块
作者使用MacOS操作系统,其他平台也大同小异
Golang Version: 1.8
创世区块介绍
区块链里的第一个区块创被称为创世区块。它是区块链里面所有区块的共同祖先。
在比原链中创世区块被硬编码到bytomd中,每一个比原节点都始于同一个创世区块,这能确保创世区块不会被改变。每个节点都把创世区块作为区块链的首区块,从而构建了一个安全的、可信的区块链。
获取创世区块
1 | ./bytomcli get-block 0 |
使用bytomcli客户端查询高度为0的区块信息。我们可以看到以上输出结果。
- bits: 目标值,挖矿时计算的hash之后要小于等于的目标值则新块构建成功
- difficulty: 难度值,矿工找到下一个有效区块的难度。该参数并不存储在区块链上,是由bits计算得出
- hash: 当前区块hash
- height: 当前区块高度
- nonce: 随机数,挖矿时反复使用不同的nonce来生成不同哈希值
- previous_block_hash: 当前区块的父区块hash值
- size: 当前区块的字节数
- timestamp: 出块时间
- transaction_merkle_root: 创世区块的merkle树根节点
- transactions: 当前块中的utxo交易
由于创世区块是第一个块,创世区块的父区块,也就是previous_block_hash参数,默认情况下为0000000000000000000000000000000000000000000000000000000000000000
时间戳timestamp为1524549600,时间为2018-04-24 14:00:00也就是比原链上主网的时间。
源码分析
获取区块链状态
protocol/protocol.go
1 | func NewChain(store Store, txPool *TxPool) (*Chain, error) { |
当我们第一次启动比原链节点时,store.GetStoreStatus会从db中获取存储状态,获取存储状态的过程是从LevelDB中查询key为blockStore的数据,如果查询出错则认为是第一次运行比原链节点,那么就需要初始化比原主链。
初始化主链
protocol/protocol.go
1 | func (c *Chain) initChainStatus() error { |
初始化主链有几步操作:
- config.GenesisBlock()获取创世区块
- 设置创世区块中所有交易状态
- 存储创世区块到LevelDB
- state.NewUtxoViewpoint()用于临时小部分utxo状态存储集合
- 实例化BlockNode,BlockNode用于选择最佳链作为主链
- 保存最新主链状态
被硬编码的创世区块
config/genesis.go
1 | func genesisTx() *types.Tx { |
mainNetGenesisBlock主要有如下操作:
- 生成创世区块中的交易,默认就一笔交易
- 设置块中的交易状态为false
- 将创世区块设置为merkle树的根节点
- 实例化Block块并返回
genesisTx函数生成创世区块中的交易,默认就一笔交易,一笔交易中包含input输入和output输出。
input输入:
输入中有一句话”Information is power. – Jan/11/2013. Computing is power. – Apr/24/2018.”这是为了纪念Aaron Swartz的精神
output输出:
输出中我们看到consensus.InitialBlockSubsidy创世区块的奖励。总共140700041250000000/1e8 = 1407000412。也就是14亿个BTM币。
计算即权力
引用比原链创始人长铗的话:
4月24号,我们主网上线,信息即权力,2013年Jaruary11;计算即权力,2018年April24。这句话是为了纪念Aaron Swartz的精神,信息即权力可以视为互联网宣言,致力于信息自由传播,让公民隐私得到保护。计算即权力,致力于让资产自由的交易,自由的流动,让公民的财富得到保护,我觉得这是非常好的纪念。