I’m writing a blockchain in Java, as a personal project. See my public repo. Read my previous post Building a Blockchain: Introduction. In this post, I will describe the core entities: accounts, transactions and blocks.
Each account is referenced by an address, and contains:
- Balance: in weis (basic units), 32 bytes
- Nonce: count of transactions already sent by this account
- Code: the hash of the code associated with this account (or null, if this account is not a smart contract)
- Storage Root: Root hash of the Trie containing the smart contract storage of this account (or null if the account is not a smart contract)
Each transaction involves two accounts: the sender and the receiver of the transaction. In my current implementation, I still have the sender address. Using TDD (Test-Driven Development) workflow, I plan to change this field to a signature, using elliptic curves digital signature. Read Signing and Verifying Ethereum Signatures. Source code: Transaction.java.
Now, the transaction contains:
- Sender Address: the address of the account that sends the transaction
- Receiver Address: the address of the account that receives and executes the transaction
- Value: value transferred from sender to receiver (it could be zero)
- Data: additional data to use when the receiver is a smart contract
- Nonce: number of transaction (counting from 0) emitted by the sender account
- Gas limit: top gas unit to pay
- Gas price: the price of each gas unit
Finally, the block has a block header, a transaction list (it could be empty), and an uncle list (it could empty, too). Source code: Block.java.
My current block header implementation contains:
- Block number
- Hash of parent block
- State Root Hash of the world state trie at the end of the execution of the transaction contained in the block
- Number of transactions
- Transaction Hash of the transactions Merkle Tree
- Number of uncles
- Uncles Hash of the uncles Merkle Tree
- Coinbase (address of the miner account that generate this block)
Notably I don’t have the Bloom filter of the block. I think it is not needed. One missing piece: the Transaction Receipts Hash. I should add the entity Transaction Receipt, that should contains the executed transaction, the gas used, the result, and the emitted logs.
In the next blog posts, I will discuss the serialization and storage of these entities. Then, I will describe the process of new transactions and blocks, and the inter-nodes communication.
Angel “Java” Lopez