I'm trying to create a sequence of block for a blockchain with the ethereumjs-monorepo. Those are the versions i'm using
"@ethereumjs/block": "^5.0.1",
"@ethereumjs/blockchain": "^7.0.1",
"@ethereumjs/common": "^4.1.0",
"@ethereumjs/tx": "^5.1.0",
"@ethereumjs/vm": "^7.1.0",
"@ethereumjs/util": "^9.0.1"
I'm running the following code
import { Block } from '@ethereumjs/block'
import { TransactionFactory } from '@ethereumjs/tx'
import { Blockchain } from '@ethereumjs/blockchain'
import { Common, CustomChain } from '@ethereumjs/common'
import { VM } from '@ethereumjs/vm'
import { privateToPublic, publicToAddress, Address, Account } from '@ethereumjs/util'
import { randomBytes } from 'crypto'
const createAccount = () => {
const privateKey = randomBytes(32);
const publicKey = privateToPublic(privateKey)
const pubAddr = publicToAddress(publicKey)
const address = new Address(pubAddr)
const details = new Account(BigInt(0), BigInt(100000000))
return { privateKey, publicKey, address, details }
}
async function createBlocks() {
const common = Common.custom(CustomChain.PolygonMumbai)
common.setEIPs([1559]);
const blockchain = await Blockchain.create({ common })
const vm = await VM.create({ common, blockchain })
await vm.stateManager.checkpoint()
const account = createAccount();
vm.stateManager.putAccount(account.address, account.details)
await vm.stateManager.commit()
let timestamp = Math.floor(Date.now() / 1000)
let lastBlock = common.genesis()
let lastHash = blockchain.genesisBlock.hash();
for (let i = 1; i < 10; i++) {
const transactions: any = [];
//if (i !== 0) {
for (let j = 0; j < 6; j++, account.details.nonce++) {
const txData = {
"hash": "0xce97011d4977ad8eec16b87bedefda436357734f9e39d8c3ce2d508af99d868d",
"accessList": [],
from: account.address.toString(),
"gasLimit": "0x5208",
"gasPrice": "0x5804253a",
"input": "0x",
"maxFeePerGas": "0x5804253a",
"maxPriorityFeePerGas": "0x5804252a",
"nonce": account.details.nonce,
"to": "0x38a50480fdd3d612c5f5f86dd0a81d4b73555391",
"transactionIndex": j,
"type": "0x2",
"value": "0x1402462f6000"
}
const tx = TransactionFactory.fromTxData(txData, { common })
const signedTx = tx.sign(account.privateKey);
transactions.push(signedTx)
console.log(signedTx.toJSON());
}
//}
const blockData = {
header: {
number: i,
timestamp: timestamp++,
gasLimit: lastBlock.gasLimit,
parentHash: lastHash,
baseFeePerGas: lastBlock.baseFeePerGas,
},
transactions,
}
//console.log(blockData);
const block = Block.fromBlockData(blockData, { common })
//await block.genTxTrie();
console.log(i);
await block.genTxTrie() // Generate the transaction trie
await blockchain.putBlock(block)
lastHash = block.hash();
const result = await vm.runBlock({ block, generate: true })
// Display the block, transactions, and receipts in JSON format
console.log(JSON.stringify(block.toJSON(), null, 2))
transactions.forEach((tx: any) => console.log(JSON.stringify(tx.toJSON(), null, 2)))
result.receipts.forEach((receipt: any) => console.log(JSON.stringify(receipt, null, 2)))
}
}
createBlocks().catch(console.error)
I keep getting this error
Error: invalid transaction trie (block number=1 hash=0xd837b21b15426eedcd23ceb3658edfc04563d5e9c9ad6962c7da56106fb7cbfc hf=shanghai baseFeePerGas=7 txs=6 uncles=0)
at Block.validateData (D:\github\node_modules\@ethereumjs\block\src\block.ts:550:13)
at async Blockchain.validateBlock (D:\github\node_modules\@ethereumjs\blockchain\src\blockchain.ts:657:5)
at async D:\github\node_modules\@ethereumjs\blockchain\src\blockchain.ts:493:11
at async Blockchain.runWithLock (D:\github\node_modules\@ethereumjs\blockchain\src\blockchain.ts:296:21)
at async Blockchain._putBlockOrHeader (D:\github\node_modules\@ethereumjs\blockchain\src\blockchain.ts:454:5)
at async Blockchain.putBlock (D:\github\node_modules\@ethereumjs\blockchain\src\blockchain.ts:385:5)
at async createBlocks (D:\github\test.ts:80:5)
I understand that the block has to be computed when created but from the documentation i don't understand what i'm missing to let the blockchain.putBlock create a block with a correct trie, since its getting the transactions in the building block, it should be able to create the correct trie no?
well i managed to get it working so i'll post it there even tho it seems not many people are using this lately but just in case :p
I had to create a trie using the @ethereumjs/trie, get the results from the transaction i made and pass it to the block header before the block gets created.