做者:Dereknode
Github地址:https://github.com/Bytom/bytomgit
Gitee地址:https://gitee.com/BytomBlockchain/bytomgithub
本章介紹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的區塊信息。咱們能夠看到以上輸出結果。操作系統
因爲創世區塊是第一個塊,創世區塊的父區塊,也就是previous_block_hash參數,默認狀況下爲00000000000000000000000000000000000000000000000000000000000000003d
時間戳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/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主要有以下操做:
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的精神,信息即權力能夠視爲互聯網宣言,致力於信息自由傳播,讓公民隱私獲得保護。計算即權力,致力於讓資產自由的交易,自由的流動,讓公民的財富獲得保護,我以爲這是很是好的記念。