1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { ethers } from 'ethers'
import assert from 'assert'
import fs from 'fs'
import { exit } from 'process'
const keccak256 = ethers.utils.keccak256
const rlp = require('rlp')
// local geth
const provider = new ethers.providers.JsonRpcProvider('http://192.168.1.213:8545')
/*
type extblock struct {
Header *Header
Txs []*Transaction
Uncles []*Header
}
*/
function getTransactionRlp(tx : any): Buffer {
let dat: any
// TODO: there are also type 1 transactions
if (tx.type == "0x2") {
let accesslist = tx.accessList.map((x : any) => [x.address, x.storageKeys])
// london
dat = [
tx.chainId,
tx.nonce,
tx.maxPriorityFeePerGas,
tx.maxFeePerGas,
tx.gas,
tx.to,
tx.value,
tx.input,
accesslist,
tx.v,
tx.r,
tx.s,
]
dat = dat.map((x : any) => (x == "0x0") ? "0x" : x)
dat = Buffer.concat([Buffer.from([parseInt(tx.type)]), rlp.encode(dat)])
assert(keccak256(dat) == tx.hash)
} else {
// pre london
dat = [
tx.nonce,
tx.gasPrice,
tx.gas,
tx.to,
tx.value,
tx.input,
tx.v,
tx.r,
tx.s,
];
dat = dat.map((x : any) => (x == "0x0") ? "0x" : x)
dat = rlp.encode(dat)
assert(keccak256(dat) == tx.hash)
dat = rlp.decode(dat)
}
//console.log(tx)
return dat
}
function getBlockRlp(block : any): Buffer {
let dat = [
block['parentHash'],
block['sha3Uncles'],
block['miner'],
block['stateRoot'],
block['transactionsRoot'],
block['receiptsRoot'],
block['logsBloom'],
block['difficulty'],
block['number'],
block['gasLimit'],
block['gasUsed'],
block['timestamp'],
block['extraData'],
block['mixHash'],
block['nonce'],
block['baseFeePerGas']
];
dat = dat.map((x : any) => (x == "0x0") ? "0x" : x)
//console.log(dat)
let rdat = rlp.encode(dat)
assert(keccak256(rdat) == block['hash'])
return rdat
}
async function getBlock(blockNumber: Number) {
let blockData = await provider.send("eth_getBlockByNumber", ["0x"+(blockNumber).toString(16), true])
const blockHeaderRlp = getBlockRlp(blockData)
//console.log(blockData)
const txsRlp = blockData.transactions.map(getTransactionRlp)
fs.writeFileSync(`data/block_${blockNumber}`, blockHeaderRlp)
fs.writeFileSync(`data/txs_${blockNumber}`, rlp.encode(txsRlp))
}
async function main() {
await getBlock(13247501)
await getBlock(13247502)
}
main().then(() => process.exit(0))