Derek解读Bytom源码-创世区块
作者:Derek
简介
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockchain/bytom
本章介绍Derek解读-Bytom源码分析-创世区块
作者使用MacOS操作系统,其他平台也大同小异
Golang Version: 1.8
创世区块介绍
区块链里的第一个区块创被称为创世区块。它是区块链里面所有区块的共同祖先。
在比原链中创世区块被硬编码到bytomd中,每一个比原节点都始于同一个创世区块,这能确保创世区块不会被改变。每个节点都把创世区块作为区块链的首区块,从而构建了一个安全的、可信的区块链。
获取创世区块
./bytomcli get-block 0
{
"bits": 2161727821137910500,
"difficulty": "15154807",
"hash": "a75483474799ea1aa6bb910a1a5025b4372bf20bef20f246a2c2dc5e12e8a053",
"height": 0,
"nonce": 9253507043297,
"previous_block_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"size": 546,
"timestamp": 1524549600,
"transaction_merkle_root": "58e45ceb675a0b3d7ad3ab9d4288048789de8194e9766b26d8f42fdb624d4390",
"transaction_status_hash": "c9c377e5192668bc0a367e4a4764f11e7c725ecced1d7b6a492974fab1b6d5bc",
"transactions": [
{
"id": "158d7d7c6a8d2464725d508fafca76f0838d998eacaacb42ccc58cfb0c155352",
"inputs": [
{
"amount": 0,
"arbitrary": "496e666f726d6174696f6e20697320706f7765722e202d2d204a616e2f31312f323031332e20436f6d707574696e6720697320706f7765722e202d2d204170722f32342f323031382e",
"asset_definition": {},
"asset_id": "0000000000000000000000000000000000000000000000000000000000000000",
"type": "coinbase"
}
],
"outputs": [
{
"address": "bm1q3jwsv0lhfmndnlag3kp6avpcq6pkd3xy8e5r88",
"amount": 140700041250000000,
"asset_definition": {},
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"control_program": "00148c9d063ff74ee6d9ffa88d83aeb038068366c4c4",
"id": "e3325bf07c4385af4b60ad6ecc682ee0773f9b96e1cfbbae9f0f12b86b5f1093",
"position": 0,
"type": "control"
}
],
"size": 151,
"status_fail": false,
"time_range": 0,
"version": 1
}
],
"version": 1
}
使用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 **
func NewChain(store Store, txPool *TxPool) (*Chain, error) {
// ...
storeStatus := store.GetStoreStatus()
if storeStatus == nil {
if err := c.initChainStatus(); err != nil {
return nil, err
}
storeStatus = store.GetStoreStatus()
}
// ...
}
当我们第一次启动比原链节点时,store.GetStoreStatus会从db中获取存储状态,获取存储状态的过程是从LevelDB中查询key为blockStore的数据,如果查询出错则认为是第一次运行比原链节点,那么就需要初始化比原主链。
初始化主链
** protocol/protocol.go **
func (c *Chain) initChainStatus() error {
genesisBlock := config.GenesisBlock()
txStatus := bc.NewTransactionStatus()
for i := range genesisBlock.Transactions {
txStatus.SetStatus(i, false)
}
if err := c.store.SaveBlock(genesisBlock, txStatus); err != nil {
return err
}
utxoView := state.NewUtxoViewpoint()
bcBlock := types.MapBlock(genesisBlock)
if err := utxoView.ApplyBlock(bcBlock, txStatus); err != nil {
return err
}
node, err := state.NewBlockNode(&genesisBlock.BlockHeader, nil)
if err != nil {
return err
}
return c.store.SaveChainStatus(node, utxoView)
}
初始化主链有几步操作:
- config.GenesisBlock()获取创世区块
- 设置创世区块中所有交易状态
- 存储创世区块到LevelDB
- state.NewUtxoViewpoint()用于临时小部分utxo状态存储集合
- 实例化BlockNode,BlockNode用于选择最佳链作为主链
- 保存最新主链状态
被硬编码的创世区块
** config/genesis.go **
func genesisTx() *types.Tx {
contract, err := hex.DecodeString("00148c9d063ff74ee6d9ffa88d83aeb038068366c4c4")
if err != nil {
log.Panicf("fail on decode genesis tx output control program")
}
txData := types.TxData{
Version: 1,
Inputs: []*types.TxInput{
types.NewCoinbaseInput([]byte("Information is power. -- Jan/11/2013. Computing is power. -- Apr/24/2018.")),
},
Outputs: []*types.TxOutput{
types.NewTxOutput(*consensus.BTMAssetID, consensus.InitialBlockSubsidy, contract),
},
}
return types.NewTx(txData)
}
func mainNetGenesisBlock() *types.Block {
tx := genesisTx()
txStatus := bc.NewTransactionStatus()
txStatus.SetStatus(0, false)
txStatusHash, err := bc.TxStatusMerkleRoot(txStatus.VerifyStatus)
if err != nil {
log.Panicf("fail on calc genesis tx status merkle root")
}
merkleRoot, err := bc.TxMerkleRoot([]*bc.Tx{tx.Tx})
if err != nil {
log.Panicf("fail on calc genesis tx merkel root")
}
block := &types.Block{
BlockHeader: types.BlockHeader{
Version: 1,
Height: 0,
Nonce: 9253507043297,
Timestamp: 1524549600,
Bits: 2161727821137910632,
BlockCommitment: types.BlockCommitment{
TransactionsMerkleRoot: merkleRoot,
TransactionStatusHash: txStatusHash,
},
},
Transactions: []*types.Tx{tx},
}
return block
}
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的精神,信息即权力可以视为互联网宣言,致力于信息自由传播,让公民隐私得到保护。计算即权力,致力于让资产自由的交易,自由的流动,让公民的财富得到保护,我觉得这是非常好的纪念。
Derek解读Bytom源码-创世区块的更多相关文章
- Derek解读Bytom源码-持久化存储LevelDB
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-孤块管理
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-Api Server接口服务
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-P2P网络 地址簿
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-protobuf生成比原核心代码
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-P2P网络 upnp端口映射
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Derek解读Bytom源码-启动与停止
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- 入口开始,解读Vue源码(一)-- 造物创世
Why? 网上现有的Vue源码解析文章一搜一大批,但是为什么我还要去做这样的事情呢?因为觉得纸上得来终觉浅,绝知此事要躬行. 然后平时的项目也主要是Vue,在使用Vue的过程中,也对其一些约定产生了一 ...
- RxJava系列6(从微观角度解读RxJava源码)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
随机推荐
- XSS攻击原理、示例和防范措施
XSS攻击 XSS(Cross-Site Scripting,跨站脚本)攻击历史悠久,是危害范围非常广的攻击方式. Cross-Site Stripting的缩写本应该是CSS,但是为了避免和Casc ...
- python二叉树的深度遍历之先序遍历流程图
- jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法
jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法 用系统属性System.getProperty("user.dir")获得执行命令的目录(网上 ...
- 拜占庭将军问题(Byzantine Generals Problem),一个关于分布式系统容错问题故事
拜占庭将军问题(Byzantine Generals Problem),一个关于分布式系统容错问题故事 背景:拜占庭帝国派出10支军队,去包围进攻一个强大的敌人,至少6支军队同时进攻才能攻下敌国. 难 ...
- 新服务器上装java PHP环境有什么一键安装的方便的方法?一般都是怎么安装环境的?
新服务器上装java PHP环境有什么一键安装的方便的方法?一般都是怎么安装环境的? linode digitalocean都有很好的教程,下面是ubuntu和centos的两个教程连接. How ...
- Oracle 数据库实现数据合并:merge
1.使用update进行数据更新 1)最简单的更新 update tablea a set a.price=1.00 2)带条件的数据更新 update tablea a set a.price = ...
- P1012 拼数
P1012 拼数 输入输出样例 输入样例 3 13 312 343 输出样例 34331213 注意 当你输入: 6321 32 407 135 13 217 应该输出: 40732321217135 ...
- Django框架----权限组件(具体代码实现)
1.settings """ Django settings for day80 project. Generated by 'django-admin startpro ...
- 第一节 JavaScript概述
第一节 JavaScript概述 JavaScript:其实就是对HTML+CSS静态页面进行样式修改,使其实现各种动态效果. 编写JS脚本基本步骤: 1. HTML+CSS静态布局: 2. 确定要修 ...
- getopt_long_only
st_i2c_parser.c中用到,遂学习一下: 参考:https://blog.csdn.net/pengrui18/article/details/8078813 https://blog.cs ...