在以太坊區塊鏈中,有很多的MPT(Merkle Patricia Tries)(代表每個區塊):
? 狀態前綴樹
? 存儲前綴樹
? 轉賬前綴樹
? 回執前綴樹
為了得到某個特定區塊中的MPT,我們需要獲得它的跟哈希,作為參考。以下的命令可以讓我們獲得狀態,轉賬和創世區塊中回執的根哈希。

注意:如果你想得到最新區塊(而不是創世區塊)的根哈希,請使用以下命令。
安裝npm,節點,level和ethereumjs
我們會使用nodejs,level和ethereumjs 的結合來檢測leveldb數據庫。以下的命令可以幫助我們準備測試環境。
cd ~
sudo apt-get update
sudo apt-get upgrade
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - sudo apt-get install -y nodejs
sudo apt-get install nodejs
npm -v
nodejs -v
npm install levelup leveldown rlp merkle-patricia-tree --save
git clone https://github.com/ethereumjs/ethereumjs-vm.git
cd ethereumjs-vm
npm install ethereumjs-account ethereumjs-util --save
從這時候開始,運行以下代碼會得到以太坊賬戶秘鑰(會存儲在以太坊網絡的狀態根部)。代碼和以太坊leveldb數據庫連接,進入以太坊的狀態(從區塊鏈的區塊中使用stateRoot數值),并且然后可以使用秘鑰進入到以太坊網絡中的所有賬戶。
//Just importing the requirements
var Trie = require('merkle-patricia-tree/secure');
var levelup = require('levelup');
var leveldown = require('leveldown');
var RLP = require('rlp');
var assert = require('assert');
//Connecting to the leveldb database
var db = levelup(leveldown('/home/timothymccallum/gethDataDir/geth/chaindata'));
//Adding the "stateRoot" value from the block so that we can inspect the state root at that block height.
var root = '0x8c77785e3e9171715dd34117b047dffe44575c32ede59bde39fbf5dc074f2976';
//Creating a trie object of the merkle-patricia-tree library
var trie = new Trie(db, root);
//Creating a nodejs stream object so that we can access the data
var stream = trie.createReadStream()
//Turning on the stream (because the node js stream is set to pause by default)
stream.on('data', function (data){
//printing out the keys of the "state trie"
console.log(data.key);
});
有趣地是,一旦轉賬發生了,以太坊中的賬戶只是添加到狀態樹中(和那個特定賬戶相關的)。例如,使用“geth account new”創建新的賬戶不會包含在狀態樹中包含那個賬戶;甚至在很多區塊被挖出后。但是,如果成功的轉賬(花費燃料費并且已經包含在挖礦區塊)是記錄在賬戶中,然后只有它會出現在狀態樹中。這是很聰明的邏輯,因為會保護欺詐者無法連續創建新的賬戶以及使得狀態樹堵塞。
對數據解碼
你已經注意到,查詢leveldb可以回復解碼的結果。這是由于,以太坊使用了自己特定的“修改版的MPT(Merkle Patricia Trie)”,用來和leveldb進行交互。以太坊Wiki提供了設計和部署以太坊MPT(Merkle Patricia Trie)和RLP(Recursive Length Prefix)解碼的信息。簡單地說,以太坊已經在前綴樹數據結構擴展。例如,修改版的MPT(Merkle Patricia Trie)包含一種通過“extension”節點,來創建快捷方式的方法。
在以太坊中,單個的修改版的MPT(Merkle Patricia Trie)節點是:
? 空的字節(對應NULL)
? 包含17個對象的數組(對應分支)
? 包含2個對象的數組(對應樹葉)
? 包含2個對象的數組(對應擴展)
以太坊前綴樹是通過固定的規則來設計和創建的,最好的檢測方法是使用電腦代碼。接下來的例子使用了ethereumjs。Ethereumjs很容易安裝和使用;它是完美地可以快速對接到以太坊leveldb數據庫。
下面的代碼(當提供一個特定的區塊stateRoot以及以太坊賬戶地址)會以可讀的形式返回賬戶的正確余額。
//Mozilla Public License 2.0
//As per https://github.com/ethereumjs/ethereumjs-vm/blob/master/LICENSE
//Requires the following packages to run as nodejs file https://gist.github.com/tpmccallum/0e58fc4ba9061a2e634b7a877e60143a
//Getting the requirements
var Trie = require('merkle-patricia-tree/secure');
var levelup = require('levelup');
var leveldown = require('leveldown');
var utils = require('ethereumjs-util');
var BN = utils.BN;
var Account = require('ethereumjs-account');
//Connecting to the leveldb database
var db = levelup(leveldown('/home/timothymccallum/gethDataDir/geth/chaindata'));
//Adding the "stateRoot" value from the block so that we can inspect the state root at that block height.
var root = '0x9369577baeb7c4e971ebe76f5d5daddba44c2aa42193248245cf686d20a73028';
//Creating a trie object of the merkle-patricia-tree library
var trie = new Trie(db, root);
var address = '0xccc6b46fa5606826ce8c18fece6f519064e6130b';
trie.get(address, function (err, raw) {
if (err) return cb(err)
//Using ethereumjs-account to create an instance of an account
var account = new Account(raw)
console.log('Account Address: ' + address);
//Using ethereumjs-util to decode and present the account balance
console.log('Balance: ' + (new BN(account.balance)).toString());
})
結論
我們已經表現出以太坊有能力來管理狀態。這種超前的設計有很多好處。
可移動性
假設移動設備和物聯網設備是很普遍的,未來電商就取決于安全,穩定和快速的移動應用。
我們認知到了可移動性的優勢,我們也知道區塊鏈大小的逐漸增加是難以置信的。將整個區塊鏈存儲在移動設備是不可能的。
快速,并且不會損失安全性
以太坊狀態的設計以及對于修改版的MPT(Merkle Patricia Trie)的使用,提供了很多機會。以太坊前綴樹上的每個功能都使用了加密哈希。而且,前綴樹根據節點的特殊加密哈希可以用來證明前綴樹沒有被欺詐。
例如,任何對于前綴樹的修改,都會完全改變根部哈希。這個加密功能會為輕客戶端提供一個機會(那些沒有存儲整個區塊鏈的設備),從而可以快速地訪問區塊鏈。也就是說,賬戶“0x … 4857”是否有足夠的資金來完成對于區塊高度“5044866”的轉賬?
速度限制
以太坊描述了個很有趣的問題,就是存儲賬戶的概念。想象這種場景,兩個用戶都可以每天從賬戶中拿出全部余額的1%。這個觀點只在未來規劃中提到,但是它卻獲得了很多興趣,因為理論上來說,它可以作為以太坊基礎協議層的一部分(和必須要作為第二層和第三方錢包相反)。也許你想起了我們之前討論的比特幣UTXO。UTXO對于區塊鏈數據是盲目的,比特幣區塊鏈沒有存儲用戶的賬戶余額。因此,比特幣的底層協議層基本上不可能完成任何類型的每日速度限制。
消費者的信心
我們看到了關于輕客戶端的很多開發,更為特別地是,安全、穩定、快速的移動應用,可以和區塊鏈技術交互。
電子商務的區塊鏈成功部署,一定會支持速度,安全和可用性。這能夠提高消費者的信心,同時也通過聰明的設計,提供更高的可用性,安全性和性能,進而提高了主流的接受能力。
原文:https://hackernoon.com/getting-deep-into-ethereum-how-data-is-stored-in-ethereum-e3f669d96033
作者:vasa
編譯:nuszjj
版權申明:本內容來自于互聯網,屬第三方匯集推薦平臺。本文的版權歸原作者所有,文章言論不代表鏈門戶的觀點,鏈門戶不承擔任何法律責任。如有侵權請聯系QQ:3341927519進行反饋。