找回密码
 立即注册

扫一扫,登录网站

首页 百科 查看内容
  • 20579
  • 0
  • 分享到

深度| 以太坊的数据到底是如何存储在以太坊网络的?

2018-8-9 10:12

来源: 巴比特

分析以太坊数据库


以太坊区块链中,有很多的MPT(Merkle Patricia Tries)(代表每个区块):


• 状态前缀树
• 存储前缀树
• 转账前缀树
• 回执前缀树

为了得到某个特定区块中的MPT,我们需要获得它的跟哈希,作为参考。以下的命令可以让我们获得状态,转账和创世区块中回执的根哈希。

1*IbnRm4TYAY55u7Ax2ZL_6A

注意:如果你想得到最新区块(而不是创世区块)的根哈希,请使用以下命令。

安装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进行反馈。
1234
相关新闻
发表评论

请先 注册/登录 后参与评论

    回顶部