成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

以太坊創(chuàng)世區(qū)塊與鏈配置載入分析

姘擱『 / 3524人閱讀

摘要:本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接以太坊創(chuàng)世區(qū)塊與鏈配置載入分析,原文已更新,請讀者前往原文閱讀。以太坊允許通過創(chuàng)世配置文件來初始化創(chuàng)世區(qū)塊,也可使用選擇使用內(nèi)置的多個網(wǎng)絡(luò)環(huán)境的創(chuàng)世配置。再準(zhǔn)備兩個以太坊賬戶,以便在創(chuàng)世時存入資產(chǎn)。

本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)
原文鏈接:以太坊創(chuàng)世區(qū)塊與鏈配置載入分析,原文已更新,請讀者前往原文閱讀。

創(chuàng)世區(qū)塊作為第零個區(qū)塊,其他區(qū)塊直接或間接引用到創(chuàng)世區(qū)塊。因此節(jié)點啟動之初必須載入正確的創(chuàng)世區(qū)塊信息,且不得任意修改。

以太坊允許通過創(chuàng)世配置文件來初始化創(chuàng)世區(qū)塊,也可使用選擇使用內(nèi)置的多個網(wǎng)絡(luò)環(huán)境的創(chuàng)世配置。默認(rèn)使用以太坊主網(wǎng)創(chuàng)世配置。

創(chuàng)世配置文件

如果你需要搭建以太坊私有鏈,那么了解創(chuàng)世配置是必須的,否則你大可不關(guān)心創(chuàng)世配置。下面是一份 JSON 格式的創(chuàng)世配置示例:

{
    "config": {
        "chainId": 1,
        "homesteadBlock": 1150000,
        "daoForkBlock": 1920000,
        "daoForkSupport": true,
        "eip150Block": 2463000,
        "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
        "eip155Block": 2675000,
        "eip158Block": 2675000,
        "byzantiumBlock": 4370000,
        "constantinopleBlock": 7280000,
        "petersburgBlock": 7280000,
        "ethash": {}
    },
    "nonce": "0x42",
    "timestamp": "0x0",
    "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
    "gasLimit": "0x1388",
    "difficulty": "0x400000000",
    "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "number": "0x0",
    "gasUsed": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "alloc": {
        "000d836201318ec6899a67540690382780743280": {
            "balance": "0xad78ebc5ac6200000"
        },
        "001762430ea9c3a26e5749afdb70da5f78ddbb8c": {
            "balance": "0xad78ebc5ac6200000"
        }
    }
}

根據(jù)配置用途可分為三大類:

鏈配置

config項是定義鏈配置,會影響共識協(xié)議,雖然鏈配置對創(chuàng)世影響不大,但新區(qū)塊的出塊規(guī)則均依賴鏈配置。

創(chuàng)世區(qū)塊頭信息配置

nonce:隨機(jī)數(shù),對應(yīng)創(chuàng)世區(qū)塊 Nonce 字段。

timestamp:UTC時間戳,對應(yīng)創(chuàng)世區(qū)塊 Time字段。

extraData:額外數(shù)據(jù),對應(yīng)創(chuàng)世區(qū)塊 Extra 字段。

gasLimit必填,燃料上限,對應(yīng)創(chuàng)世區(qū)塊 GasLimit 字段。

difficulty必填,難度系數(shù),對應(yīng)創(chuàng)世區(qū)塊 Difficulty 字段。搭建私有鏈時,需要根據(jù)情況選擇合適的難度值,以便調(diào)整出塊。

minHash:一個哈希值,對應(yīng)創(chuàng)世區(qū)塊的MixDigest字段。和 nonce 值一起證明在區(qū)塊上已經(jīng)進(jìn)行了足夠的計算。

coinbase:一個地址,對應(yīng)創(chuàng)世區(qū)塊的Coinbase字段。

初始賬戶資產(chǎn)配置

alloc 項是創(chuàng)世中初始賬戶資產(chǎn)配置。在生成創(chuàng)世區(qū)塊時,將此數(shù)據(jù)集中的賬戶資產(chǎn)寫入?yún)^(qū)塊中,相當(dāng)于預(yù)挖礦。這對開發(fā)測試和私有鏈非常好用,不需要挖礦就可以直接為任意多個賬戶分配資產(chǎn)。

自定義創(chuàng)世

如果你計劃部署以太坊私有網(wǎng)絡(luò)或者一個獨立的測試環(huán)境,那么需要自定義創(chuàng)世,并初始化它。為了統(tǒng)一溝通,推薦先在用戶根目錄創(chuàng)建一個文件夾 deepeth,以做為《以太坊設(shè)計與實現(xiàn)》電子書學(xué)習(xí)工作目錄。

mkdir $HOME/deepeth && cd $HOME/deepeth

再準(zhǔn)備兩個以太坊賬戶,以便在創(chuàng)世時存入資產(chǎn)。

geth --datadir $HOME/deepeth account new

因為是學(xué)習(xí)使用,推薦使用統(tǒng)一密碼 foobar,執(zhí)行兩次命令,創(chuàng)建好兩個賬戶。這里使用 --datadir 參數(shù)指定以太坊運行時數(shù)據(jù)存放目錄,是讓大家將數(shù)據(jù)統(tǒng)一存放在一個本課程學(xué)習(xí)文件夾中。

再將下面配置內(nèi)容保存到 $HOME/deepeth/genesis.json 文件,其中 alloc 項替換成剛剛創(chuàng)建的兩個以太坊賬戶地址。

{
    "config": {
        "chainId": 8888,
        "homesteadBlock": 0,
        "daoForkBlock": 0,
        "daoForkSupport": true,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "byzantiumBlock": 0,
        "constantinopleBlock": 0,
        "petersburgBlock": 0,
        "ethash": {}
    },
    "nonce": "0x42",
    "timestamp": "0x0",
    "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
    "gasLimit": "0x1388",
    "difficulty": "0x1",
    "alloc": {
        "093f59f1d91017d30d8c2caa78feb5beb0d2cfaf": {
            "balance": "0xffffffffffffffff"
        },
        "ddf7202cbe0aaed1c2d5c4ef05e386501a054406": {
            "balance": "0xffffffffffffffff"
        }
    }
}

然后,執(zhí)行 geth 子命令 init 初始化創(chuàng)世區(qū)塊。

geth  --datadir $HOME/deepeth init genesis.json

執(zhí)行成功后,便可啟動該私有鏈:

geth --maxpeers 0 --datadir $HOME/deepeth  console

執(zhí)行如下命令,可以查看到前面創(chuàng)建的兩個賬戶,均已有資產(chǎn):

eth.getBalance(eth.accounts[0])
// 18446744073709551615
eth.getBalance(eth.accounts[1])
// 18446744073709551615

至此,我們已完成創(chuàng)世定制版。

內(nèi)置的創(chuàng)世配置

上面我已完成自定義創(chuàng)世,但以太坊作為去中心平臺,需要許多節(jié)點一起參與。僅僅為了測試,多個節(jié)點來搭建私有鏈比較麻煩。如果希望和別人一起聯(lián)調(diào),或者需要在測試網(wǎng)絡(luò)中測試DAPP時,該怎么辦呢?那么,可使用以太坊測試網(wǎng)絡(luò)。以太坊公開的測試網(wǎng)絡(luò)有 5 個,目前仍在運行的有 4 個,具體見下表格。

測試網(wǎng) 共識機(jī)制 出塊間隔 提供方 上線時間 備注 狀態(tài)
Morden PoW 以太坊官方 2015.7 因難度炸彈被迫退役 stopped
Ropsten PoW 30秒 以太坊官方 2016.11 接替Morden running
Kovan PoA 4秒 以太坊錢包Parity開發(fā)團(tuán)隊 2017.3 不支持geth running
Rinkeby PoA 15秒 以太坊官方 2017.4 最常用,只支持geth running
Sokol PoA 5秒 以太坊官方POA.network團(tuán)隊 2017.12 不支持geth running
G?rli PoA 15秒 以太坊柏林社區(qū) 2018.9 首個以太坊2.0實驗場 running

支持 geth 的3個測試網(wǎng)絡(luò)的創(chuàng)世配置已內(nèi)置在以太坊代碼中,具體見 core/genesis.go 文件:

// DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
func DefaultTestnetGenesisBlock() *Genesis{}
// DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block.
func DefaultRinkebyGenesisBlock() *Genesis
// DefaultGoerliGenesisBlock returns the G?rli network genesis block.
func DefaultGoerliGenesisBlock() *Genesis{}

當(dāng)然不會缺以太坊主網(wǎng)創(chuàng)世配置,也是 geth 運行的默認(rèn)配置。

// DefaultGenesisBlock returns the Ethereum main net genesis block.
func DefaultGenesisBlock() *Genesis{}

如果你不想自定義創(chuàng)世配置文件用于開發(fā)測試,那么以太坊也提供一份專用于本地開發(fā)的配置。

// DeveloperGenesisBlock returns the "geth --dev" genesis block. Note, this must
// be seeded with the
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis

運行 geth --dev console 可臨時運行使用。但如果需要長期使用此模式,則需要指定 datadir。

geth --dev --datadir $HOME/deepeth/dev console

首次運行 dev 模式會自動創(chuàng)建一個空密碼的賬戶,并開啟挖礦。當(dāng)有新交易時,將立刻打包出塊。

geth 創(chuàng)世區(qū)塊加載流程

在運行 geth 時需根據(jù)配置文件加載創(chuàng)世配置以及創(chuàng)世區(qū)塊,并校驗其合法性。如果配置信息隨意變更,易引起共識校驗不通過等問題。只有在加載并檢查通過時,才能繼續(xù)運行程序。

創(chuàng)世加載流程

上圖是一個簡要流程,下面分別講解“加載創(chuàng)世配置”和“安裝創(chuàng)世區(qū)塊”兩個子流程。

加載創(chuàng)世配置

應(yīng)使用哪種創(chuàng)世配置,由用戶在啟動 geth 時決定。下圖是創(chuàng)世配置選擇流程圖:

通過 geth 命令參數(shù)可選擇不同網(wǎng)絡(luò)配置,可以通過 networkid 選擇,也可使用網(wǎng)絡(luò)名稱啟用。

使用 networkid:
不同網(wǎng)絡(luò)使用不同ID標(biāo)識。

1=Frontier,主網(wǎng)環(huán)境,是默認(rèn)選項。

2=Morden 測試網(wǎng)絡(luò),但已禁用。

3=Ropsten 測試網(wǎng)絡(luò)。

4=Rinkeby 測試網(wǎng)絡(luò)。

直接使用網(wǎng)絡(luò)名稱:

testnet: Ropsten 測試網(wǎng)絡(luò)。

rinkeby: Rinkeby 測試網(wǎng)絡(luò)。

goerli: G?rli 測試網(wǎng)絡(luò)。

dev: 本地開發(fā)環(huán)境。

geth 啟動時根據(jù)不同參數(shù)選擇加載不同網(wǎng)絡(luò)配置,并對應(yīng)不同網(wǎng)絡(luò)環(huán)境。如果不做任何選擇,雖然在此不會做出選擇,但在后面流程中會默認(rèn)使用主網(wǎng)配置。

安裝創(chuàng)世區(qū)塊

上面已初步選擇創(chuàng)世配置,而這一步則根據(jù)配置加載或者初始化創(chuàng)世單元。下圖是處理流程:

首先,需要從數(shù)據(jù)庫中根據(jù)區(qū)塊高度 0 讀取創(chuàng)世區(qū)塊哈希。如果不存在則說明本地屬于第一次啟動,直接使用運行時創(chuàng)世配置來構(gòu)建創(chuàng)世區(qū)塊。屬于首次,還需要存儲創(chuàng)世區(qū)塊和鏈配置。

如果存在,則需要使用運行時創(chuàng)世配置構(gòu)建創(chuàng)世區(qū)塊并和本次已存儲的創(chuàng)世區(qū)塊哈希進(jìn)行對比。一旦不一致,則返回錯誤,不得繼續(xù)。

隨后,還需要檢查鏈配置。先從數(shù)據(jù)庫獲取鏈配置,如果不存在,則無需校驗直接使用運行時鏈配置。否則,需要檢查運行時鏈配置是否正確,只有正確時才能替換更新。但有一個例外:主網(wǎng)配置不得隨意更改,由代碼控制而非人為指定。

總的來說,以太坊默認(rèn)使用主網(wǎng)配置,只有在首次運行時才創(chuàng)建和存儲創(chuàng)世區(qū)塊,其他時候僅僅用于校驗。而鏈配置除主網(wǎng)外則在規(guī)則下可隨時變更。

構(gòu)建創(chuàng)建區(qū)塊

上面我們已知曉總體流程,這里再細(xì)說下以太坊是如何根據(jù)創(chuàng)世配置生成創(chuàng)世區(qū)塊。核心代碼位于 core/genesis.go:229。

func (g *Genesis) ToBlock(db ethdb.Database) *types.Block{
    if db == nil {
        db = rawdb.NewMemoryDatabase()
    }
    statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))//?
    for addr, account := range g.Alloc { //?
        statedb.AddBalance(addr, account.Balance)
        statedb.SetCode(addr, account.Code)
        statedb.SetNonce(addr, account.Nonce)
        for key, value := range account.Storage {
            statedb.SetState(addr, key, value)
        }
    }
    root := statedb.IntermediateRoot(false)//?
    head := &types.Header{//?
        Number:     new(big.Int).SetUint64(g.Number),
        Nonce:      types.EncodeNonce(g.Nonce),
        Time:       g.Timestamp,
        ParentHash: g.ParentHash,
        Extra:      g.ExtraData,
        GasLimit:   g.GasLimit,
        GasUsed:    g.GasUsed,
        Difficulty: g.Difficulty,
        MixDigest:  g.Mixhash,
        Coinbase:   g.Coinbase,
        Root:       root,
    }
    //?
    if g.GasLimit == 0 {
        head.GasLimit = params.GenesisGasLimit
    }
    if g.Difficulty == nil {
        head.Difficulty = params.GenesisDifficulty
    }

    statedb.Commit(false)//?
    statedb.Database().TrieDB().Commit(root, true)//?

    return types.NewBlock(head, nil, nil, nil)//?
}

上面代碼是根據(jù)創(chuàng)世配置生成創(chuàng)世區(qū)塊的代碼邏輯,細(xì)節(jié)如下:

? 創(chuàng)世區(qū)塊無父塊,從零初始化全新的 state(后續(xù)文章會詳細(xì)講解 state對象)。

? 遍歷配置中 Alloc 項賬戶集合數(shù)據(jù),直接寫入 state 中。
這里不單可以設(shè)置 balance,還可以設(shè)置 code、nonce 以及任意多個 storage 數(shù)據(jù)。
意味著創(chuàng)世時便可以直接部署智能合約。例如下面配置則在創(chuàng)世時部署了一個名為093f59f1d91017d30d8c2caa78feb5beb0d2cfaf 的智能合約。

"alloc": {
        "093f59f1d91017d30d8c2caa78feb5beb0d2cfaf": {
            "balance": "0xffffffffffffffff",
            "nonce": "0x3",
            "code":"0x606060",
            "storage":{
            "11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa":"1234ff"
            }
        }
}

? 將賬戶數(shù)據(jù)寫入 state 后,便可以計算出 state 數(shù)據(jù)的默克爾樹的根值,稱之為 StateRoot。
此值記錄在區(qū)塊頭 Root 字段中。

? 創(chuàng)世配置的一部分配置,則直接映射到區(qū)塊頭中,完成創(chuàng)世區(qū)塊頭的構(gòu)建。

? 因為 GasLimitDifficulty 直接影響到下一個區(qū)塊出塊處理。
因此未設(shè)置時使用默認(rèn)配置(Difficulty=131072,GasLimit=4712388)。

? 提交 state,將 state 數(shù)據(jù)提交到底層的內(nèi)存 trie 數(shù)據(jù)中。

? 將內(nèi)存 trie 數(shù)據(jù)更新到 db 中。

這是多余的一步,因為提交到數(shù)據(jù)庫是由外部進(jìn)行,這里只需要負(fù)責(zé)生成區(qū)塊。

? 利用區(qū)塊頭創(chuàng)建區(qū)塊,且區(qū)塊中無交易記錄。

深入淺出區(qū)塊鏈 - 系統(tǒng)學(xué)習(xí)區(qū)塊鏈,學(xué)區(qū)塊鏈都在這里,打造最好的區(qū)塊鏈技術(shù)博客。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/24645.html

相關(guān)文章

  • 運行以太私有網(wǎng)絡(luò)

    摘要:運行以太坊私有網(wǎng)絡(luò)以太坊以的形式來標(biāo)識一個網(wǎng)絡(luò),推薦使用的形式去指定,主網(wǎng)絡(luò)的是默認(rèn)的,如果你想要建立私有網(wǎng)絡(luò),你可以指定一個新的網(wǎng)絡(luò)。 運行以太坊私有網(wǎng)絡(luò) network ID 以太坊以 netWorkID的形式來標(biāo)識一個網(wǎng)絡(luò),推薦使用--networkid的形式去指定,主網(wǎng)絡(luò)的networkid是1(默認(rèn)的),如果你想要建立私有網(wǎng)絡(luò),你可以指定一個新的網(wǎng)絡(luò)id。 創(chuàng)建創(chuàng)世區(qū)塊 創(chuàng)世...

    王陸寬 評論0 收藏0
  • Mac環(huán)境搭建以太私有鏈

    摘要:原文地址石匠的為了測試以太坊智能合約,最方便的是在本地搭建一個以太坊私有鏈。網(wǎng)絡(luò)在連接到其他節(jié)點的時候會用到,以太坊公網(wǎng)的網(wǎng)絡(luò)是,為了不與公有鏈網(wǎng)絡(luò)沖突,運行私有鏈節(jié)點的時候要指定自己的網(wǎng)絡(luò)。當(dāng)設(shè)置為表示使用發(fā)布該鏈。 原文地址: 石匠的blog 為了測試以太坊智能合約,最方便的是在本地搭建一個以太坊私有鏈。在mac上搭建環(huán)境主要需要以下步驟。 geth安裝 geth是go-ether...

    張金寶 評論0 收藏0
  • 如何搭建以太私有鏈

    摘要:本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接如何搭建以太坊私有鏈原文已更新,請讀者前往原文閱讀在開發(fā)以太坊時,很多時候需要搭建一條以太坊私有鏈,通過本文一起看看如何在上進(jìn)行搭建。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:如何搭建以太坊私有鏈原文已更新,請讀者前往原文閱讀 在開發(fā)以太坊時,很多時候需要搭建一條以太坊私有鏈,通過本文一起看看如何在Mac上進(jìn)行搭建。 寫在前面 閱讀本文前,你應(yīng)該對以太...

    J4ck_Chan 評論0 收藏0
  • 搭建以太本地開發(fā)環(huán)境

    摘要:本文所搭建的環(huán)境是在上的開發(fā)環(huán)境,其他操作系統(tǒng)上與此非常相似,依然有參考價值。作為一枚區(qū)塊鏈開發(fā)工程師,本地的開發(fā)環(huán)境是必不可少的。因為我們是私有鏈,所以可以寫的大一些,方便開發(fā)測試。 本文所搭建的環(huán)境是在 Mac 上的開發(fā)環(huán)境,其他操作系統(tǒng)上與此非常相似,依然有參考價值。 作為一枚區(qū)塊鏈開發(fā)工程師,本地的開發(fā)環(huán)境是必不可少的。我們首先看看需要哪些工具: go-ethereum so...

    Ethan815 評論0 收藏0
  • 以太本地開發(fā)環(huán)境搭建

    摘要:本文所搭建的環(huán)境是在上的開發(fā)環(huán)境,其他操作系統(tǒng)上與此非常相似,依然有參考價值。作為一枚區(qū)塊鏈開發(fā)工程師,本地的開發(fā)環(huán)境是必不可少的。因為我們是私有鏈,所以可以寫的大一些,方便開發(fā)測試。 本文所搭建的環(huán)境是在 Mac 上的開發(fā)環(huán)境,其他操作系統(tǒng)上與此非常相似,依然有參考價值。 作為一枚區(qū)塊鏈開發(fā)工程師,本地的開發(fā)環(huán)境是必不可少的。我們首先看看需要哪些工具: go-ethereum so...

    fancyLuo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<