Block 区块
所有的交易都被分组为“区块”。区块链就是一系列链接在一起的这样的块。首先,我先带大家看下此类的全貌,它都包含哪些核心属性和方法。
类地址:org.ethereum.core.Block
/* 区块头 */
private BlockHeader header;
/* 交易列表 */
private List<Transaction> transactionsList = new CopyOnWriteArrayList<>();
/* Uncle列表 */
private List<BlockHeader> uncleList = new CopyOnWriteArrayList<>();
一个区块包括:
- 区块头
- 关于包含在此区块中交易集的信息
- uncle列表
区块头
每个块都有一个块“区块头”,区块头是一个区块的一部分:
类地址:org.ethereum.core.BlockHeader
private byte[] parentHash;
private byte[] unclesHash;
private byte[] coinbase;
private byte[] stateRoot;
private byte[] txTrieRoot;
private byte[] receiptTrieRoot;
private byte[] logsBloom;
private byte[] difficulty;
private long timestamp;
private long number;
private byte[] gasLimit;
private long gasUsed;
private byte[] mixHash;
private byte[] extraData;
private byte[] nonce;
private byte[] hashCache;
- parentHash:父区块头的Hash值(这也是使得区块变成区块链的原因)
- ommerHash:当前区块ommers列表的Hash值
- coinbase:接收挖此区块费用的账户地址
- stateRoot:状态树根节点的Hash值
- txTrieRoot:包含此区块所列的所有交易的树的根节点Hash值
- receiptsRoot:包含此区块所列的所有交易收据的树的根节点Hash值
- logsBloom:由日志信息组成的一个Bloom过滤器 (数据结构)
- difficulty: 此区块的难度级别
- timestamp:此区块成立时的unix的时间戳
- number:当前区块的计数(创世纪块的区块序号为0,对于每个后续区块,区块序号都增加1)
- gasLimit:每个区块的当前gas limit
- gasUsed: 此区块中交易所用的总gas量
- mixHash:一个Hash值,当与nonce组合时,证明此区块已经执行了足够的计算
- extraData:与此区块相关的附加数据
- nonce:一个Hash值,当与mixHash组合时,证明此区块已经执行了足够的计算
测试
现在,我们对该类进行简单的使用。我们直接写一个测试用例进行测试。我写测试用例的目的是告诉大家该怎么用,里面的加密我这里先不讲,后续统一将区块里面的加密转移等等,你们自然就懂了,你也跟着我一样,不要在意里面的具体加密实现,先学会这么用这个类。
package org.ethereum.core;
import org.ethereum.trie.Trie;
import org.ethereum.trie.TrieImpl;
import org.ethereum.util.RLP;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class BlockTest {
@Test
public void test() {
byte[] parentHash = new byte[0];
byte[] uncleHash = new byte[0];
byte[] minerCoinbase = Hex.decode("fffefd"); // {-1, -2, -3}
long blockNumber = 0;
byte[] GasLimit = new byte[0];
byte[] extraData = new byte[0];
byte[] calcTxTrie = new byte[0];
Block block = new Block(
parentHash,
uncleHash, // uncleHash
minerCoinbase,
new byte[0], // log bloom - from tx receipts
new byte[0], // difficulty computed right after block creation
blockNumber,
GasLimit, // (add to config ?)
0, // gas used - computed after running all transactions
0, // block time
extraData, // extra data
new byte[0], // mixHash (to mine)
new byte[0], // nonce (to mine)
new byte[0], // receiptsRoot - computed after running all transactions
calcTxTrie, // TransactionsRoot - computed after running all transactions
new byte[]{0}, // stateRoot - computed after running all transactions
null,
null);
block.getEncoded();
/**
* 加载区块
*
* 注意,我通过上面的block的`block.getEncoded()`生成的block1。
* 然后进行参数打印。
*/
Block block1 = new Block(block.getEncoded());
System.out.println("ParentHash : " + block1.getParentHash());
System.out.println("uncleHash : " + block1.getUnclesHash());
// 注意这里,把16进制转化为我们之前传的【字符串】
System.out.println("coinbase : " + Hex.toHexString(block1.getHeader().getCoinbase()));
System.out.println("log bloom : " + block1.getLogBloom());
System.out.println("difficulty : " + block1.getDifficulty());
System.out.println("blockNumber: " + block1.getNumber());
System.out.println("Gas Limit : " + block1.getGasLimit());
System.out.println("Gas Used : " + block1.getGasUsed());
System.out.println("timestamp : " + block1.getTimestamp());
System.out.println("extraData : " + block1.getExtraData());
System.out.println("mixHash : " + block1.getMixHash());
System.out.println("nonce : " + block1.getNonce());
System.out.println("Receipts Root : " + block1.getStateRoot());
System.out.println("state Root : " + block1.getStateRoot());
System.out.println("transaction List : " + block1.getTransactionsList());
System.out.println("uncle List : " + block1.getUncleList());
}
}