5

Here's what I've been able to get going to far. I can open the blockchain database but I can't seem to create a valid blockchain object (nor call the blockchain.getBlock() function successfully). I'm running against the local database files for my geth.exe node running against mainnet.

Geth.exe 1.7.3 running against mainnet in a Windows 10 laptop.

const LevelUp = require('levelup');
const LevelDown = require('leveldown');
const RLP = require('rlp');
const Trie = require('merkle-patricia-tree');

const Account = require('ethereumjs-account')
const Transaction = require('ethereumjs-tx')
const Block = require('ethereumjs-block')
const Blockchain = require('ethereumjs-blockchain')

const Util = require('ethereumjs-util')
const BN = Util.BN

var dboptions = { createIfMissing: false };
var BlockchainDB = LevelUp(LevelDown('/Users/mwher/AppData/Roaming/Ethereum/geth/chaindata'), dboptions); // my geth mainnet datadir
//console.log('BlockchainDB:');
//console.log(BlockchainDB);

//the genesis state root
var root = 'd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544';
console.log('root:');
console.log(root);

/* console.log('BlockchainDB.get:');
BlockchainDB.get(new Buffer(root, 'hex'), { // WORKS => BlockchainDB is good
    encoding: 'binary'
}, function (err, value) {
    console.log('RLP.decode(value):');
    console.log(RLP.decode(value));
}); */

// https://etherscan.io/block/1
var block1 = new Buffer('88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6', 'hex');
console.log('block1:' + block1);

const options = { blockDb: BlockchainDB, validate: false };
var blockchain = new Blockchain(options)

blockchain._init( function(err, data) {
    console.log('Initialized');
/*     console.log(err);
    console.log(data);
    console.log('blockchain.0:');
    console.log(blockchain); */

    console.log('blockchain.getBlock.1a:start');
    var bn = 0;
    var hn = Number(bn);
    blockchain.getBlock(hn, function (err, data) { // WORKS for block bn = 0 but not bn = 1
        console.log('blockchain.getBlock.1a.err:', err);
        //console.log('blockchain.getBlock.1a.data:', data);

        console.log('b.1a:');
        var b = new Block(data);
        //console.log(b);
        console.log('Number.1a.JSON:', b.toJSON(true));
        console.log('Number.1a.fields:' + b.header._fields);
        console.log('Number.1a.difficulty:' + (new BN(b.header.difficulty).toString()));
        console.log('Number.1a.gasLimit:' + (new BN(b.header.gasLimit).toString()));
        console.log('Number.1a.timestamp:' + (new BN(b.header.timestamp).toString()));
        console.log('Number.1a.number:' + (new BN(b.header.number).toString()));
        console.log('Number.1a.nonce:' + (new BN(b.header.nonce).toString()), b.header.nonce);
        console.log('Number.1a.extraData:', b.header.extraData);
    });

});

UPDATE: The code was pretty much working all along but I wasn't looking at the err value from getBlock().

UPDATE2: The above updated code now WORKS for block 0 (zero) - still doesn't work for block 1.

You can verify this works for block zero by comparing the log messages to https://etherscan.io/block/0 but I still get the message 'blockchain.getBlock.1a.err: NotFoundError: Key not found in database 1' when I set var bn = 1;

UPDATE3: By added the following code to my JS script (from here https://gist.github.com/daragao/cda5d96d4d4248826762992badb0f96d#L71-98), it appears I've been able to dump out the keys from my local geth database:

const enc = 'binary';
BlockchainDB
  .createReadStream({ encoding: enc, valueEncoding: enc, keyEncoding: enc, keys: true, values: false })
  .on('data',(data) => {
    const keyBin = new Buffer(data, enc);
    const keyBinHex = keyBin.toString('hex');
    console.log(keyBinHex);
   });

...over 300 million keys that look like the following (first 10 rows):

000000339465437a96b9a10371bb4a192815189c9eedcf161a457c618aced55a
0000006ef5936dd01319447945152cdbb95135449f5ba6e701514823abf87cb1
0000008ed8a5e4b794d0ee71b0a1cc9a31de66099dccac511f867f9edbfc59d6
000000dccbeea3c1f013fccf82b3a071fb43177f003f642c00266c8715c286a9
000000f2533a255a343519bcbf7f82b2354b6b894ebdbfc7a4afc9072e5c4fda
00000115188f5faf17c7821e192a1c1adef78cd913f2024bcbe748446df644f7
0000015f9d45bd11a0cf2e545433a15c712aef0a3d335ab4ceb6e0190bcac144
00000161c05c94651393d431f438b4deac9382b2571e8334c9e13fc62d3b9ae5
000001b92f228b64b2c428fc37891d3d126bf74a421c7341b101abed1320e87e
000001e74d9e8ae320613947c4e6cce1a4d6d43abafb4f9a5b13eeb9f394a247

More news at 11...

0

An idea, instead of

var blockchain = new Blockchain()

try to instantiate using

var blockchain = new Blockchain({blockDB : BlockChainDB})

according to the ethereumjs-blockchain github page

EDIT: ethereumjs-blockchain interacts with LevelDB, but expects a format of block hashes as keys and RLP encoded blocks as values (see the source). geth also uses LevelDB, but stores the state trie (see this answer). This makes it possible to pass the DB to Blockchain constructor (like any LevelDB), but not to interact with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.