区块详解 - ethereumj

半兽人 发表于: 2018-05-23   最后更新时间: 2018-05-23 16:58:41  
{{totalSubscript}} 订阅, 5,932 游览

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组合时,证明此区块已经执行了足够的计算

screenshot

测试

现在,我们对该类进行简单的使用。我们直接写一个测试用例进行测试。我写测试用例的目的是告诉大家该怎么用,里面的加密我这里先不讲,后续统一将区块里面的加密转移等等,你们自然就懂了,你也跟着我一样,不要在意里面的具体加密实现,先学会这么用这个类。

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());
    }
}
更新于 2018-05-23

查看ethereumj更多相关的文章或提一个关于ethereumj的问题,也可以与我们一起分享文章