Skip to content

Commit d2308de

Browse files
committed
Update run-blockchain example
1 parent 9b62fd0 commit d2308de

File tree

4 files changed

+145
-168
lines changed

4 files changed

+145
-168
lines changed

examples/run-blockchain/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Run Blockchain example
2+
3+
This directory contains an example on how to run a blockchain.
4+
5+
The example does these things:
6+
7+
1. Instantiates a VM and a Blockchain
8+
1. Creates the accounts from `./test-data.json`'s `pre`
9+
1. Creates a genesis block
10+
1. Puts the blocks from `./test-data.json`'s `blocks` into the Blockchain
11+
1. Runs the Blockchain on the VM.
12+
13+
## Installation
14+
15+
1. Run `npm install` in the root of this project
16+
17+
## Running the example
18+
19+
1. Run `npm run build:dist` in the root of this project
20+
1. Run `npm run example` in this directory

examples/run-blockchain/index.js

Lines changed: 0 additions & 168 deletions
This file was deleted.

examples/run-blockchain/index.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import VM from '../../'
2+
3+
import Account from 'ethereumjs-account'
4+
import * as utils from 'ethereumjs-util'
5+
import { promisify } from 'util'
6+
7+
const Trie = require('merkle-patricia-tree/secure')
8+
const Block = require('ethereumjs-block')
9+
const Blockchain = require('ethereumjs-blockchain')
10+
const BlockHeader = require('ethereumjs-block/header.js')
11+
const level = require('level')
12+
const levelMem = require('level-mem')
13+
const testData = require('./test-data')
14+
15+
const rlp = utils.rlp
16+
17+
async function main() {
18+
const state = new Trie()
19+
const blockchainDB = levelMem()
20+
21+
const hardfork = testData.network.toLowerCase()
22+
23+
const blockchain = new Blockchain({ db: blockchainDB, hardfork })
24+
blockchain.ethash.cacheDB = level('./.cachedb')
25+
26+
const vm = new VM({
27+
state: state,
28+
blockchain: blockchain,
29+
hardfork,
30+
})
31+
32+
vm.on('beforeTx', (tx: any) => {
33+
tx._homestead = true
34+
})
35+
36+
vm.on('beforeBlock', (block: any) => {
37+
block.header.isHomestead = function() {
38+
return true
39+
}
40+
})
41+
42+
await setupPreConditions(state, testData)
43+
44+
await setGenesisBlock(blockchain, hardfork)
45+
46+
await putBlocks(blockchain, hardfork, testData)
47+
48+
await vm.runBlockchain(blockchain)
49+
50+
const blockchainHead = await promisify(vm.blockchain.getHead.bind(vm.blockchain))()
51+
state.root = blockchainHead.header.stateRoot
52+
53+
console.log('--- Finished processing the BlockChain ---')
54+
console.log('New head:', '0x' + blockchain.meta.rawHead.toString('hex'))
55+
console.log('Expected:', testData.lastblockhash)
56+
}
57+
58+
async function setupPreConditions(state: any, testData: any) {
59+
for (const address of Object.keys(testData.pre)) {
60+
const acctData = testData.pre[address]
61+
const account = new Account()
62+
63+
account.nonce = utils.toBuffer(acctData.nonce)
64+
account.balance = utils.toBuffer(acctData.balance)
65+
66+
const storageTrie = state.copy()
67+
storageTrie.root = null
68+
69+
for (const hexStorageKey of Object.keys(acctData.storage)) {
70+
const val = utils.toBuffer(acctData.storage[hexStorageKey])
71+
const storageKey = utils.setLength(utils.toBuffer(hexStorageKey), 32)
72+
73+
await promisify(storageTrie.put.bind(storageTrie))(storageKey, rlp.encode(val))
74+
}
75+
76+
const codeBuf = utils.toBuffer(acctData.code)
77+
78+
await setCode(account, state, codeBuf)
79+
80+
account.stateRoot = storageTrie.root
81+
82+
await promisify(state.put.bind(state))(utils.toBuffer(address), account.serialize())
83+
}
84+
}
85+
86+
async function setCode(account: Account, state: any, code: Buffer) {
87+
return new Promise((resolve, reject) => {
88+
account.setCode(state, code, (err, codeHash) => {
89+
if (err) {
90+
reject(err)
91+
return
92+
}
93+
94+
resolve(codeHash)
95+
})
96+
})
97+
}
98+
99+
async function setGenesisBlock(blockchain: any, hardfork: string) {
100+
const genesisBlock = new Block({ hardfork })
101+
genesisBlock.header = new BlockHeader(testData.genesisBlockHeader, { hardfork })
102+
103+
await promisify(blockchain.putGenesis.bind(blockchain))(genesisBlock)
104+
}
105+
106+
async function putBlocks(blockchain: any, hardfork: string, testData: any) {
107+
for (const blockData of testData.blocks) {
108+
const block = new Block(utils.toBuffer(blockData.rlp), { hardfork })
109+
await promisify(blockchain.putBlock.bind(blockchain))(block)
110+
}
111+
}
112+
113+
main()
114+
.then(() => process.exit(0))
115+
.catch(err => {
116+
console.error(err)
117+
process.exit(1)
118+
})

examples/run-blockchain/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "run-blockchain",
3+
"private": true,
4+
"scripts": {
5+
"example": "ts-node index.ts"
6+
}
7+
}

0 commit comments

Comments
 (0)