区块链基础:区块与挖矿

1、区块与区块链

(1)Block设计
这里写图片描述

这里写图片描述

区块Hash值计算公式:

Hash=SHA256(最后一个区块的Hash+交易信息+随机数)

(2)Block代码

package com.blockchain.model;

import java.util.List;

/**
 * 区块结构
 */
public class Block {

    /**
     * 区块索引号
     */
    private int index;
    /**
     * 当前区块的hash值,区块唯一标识
     */
    private String hash;
    /**
     * 生成区块的时间戳
     */
    private long timestamp;
    /**
     * 当前区块的交易集合
     */
    private List<Transaction> transactions;
    /**
     * 工作量证明,计算正确hash值的次数
     */
    private int nonce;
    /**
     * 前一个区块的hash值
     */
    private String preHash;

    public Block() {
        super();
    }

    public Block(int index, long timestamp, List<Transaction> transactions, int nonce, String preHash, String hash) {
        super();
        this.index = index;
        this.timestamp = timestamp;
        this.transactions = transactions;
        this.nonce = nonce;
        this.preHash = preHash;
        this.hash = hash;
    }

    //省略getter和setter
}

2、挖矿

(1)挖矿流程

这里写图片描述

(2)挖矿测试代码

package com.blockchain.block;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.alibaba.fastjson.JSON;
import com.blockchain.model.Block;
import com.blockchain.model.Transaction;
import com.blockchain.model.TransactionInput;
import com.blockchain.model.TransactionOutput;
import com.blockchain.model.Wallet;
import com.blockchain.security.CryptoUtil;

/**
 * 区块链测试
 */
public class BlockServiceTest {

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void testBlockMine() throws Exception {
        //创建一个空的区块链
        List<Block> blockchain = new ArrayList<>();
        //生成创世区块,空交易
        Block block = new Block(1,System.currentTimeMillis(),new ArrayList<Transaction>(),1,"","1");
        //加入创世区块到区块链里
        blockchain.add(block);
        System.out.println("初始化区块链:\n"+JSON.toJSONString(blockchain));

        //上一区块到现在发生的交易
        Transaction tx1 = new Transaction();
        Transaction tx2 = new Transaction();
        Transaction tx3 = new Transaction();
        //交易打包
        List<Transaction> txs = new ArrayList<>();
        txs.add(tx1);
        txs.add(tx2);
        txs.add(tx3);
        //加入系统奖励的交易
        Transaction sysTx = new Transaction();
        txs.add(sysTx);
        //获取当前区块链里的最后一个区块
        Block last = blockchain.get(blockchain.size() - 1);
        //随机数开始值
        int nonce = 1;
        String hash = "";
        long start=System.currentTimeMillis();
        while(true){
            //计算新的Hash值
            hash = CryptoUtil.sha256(last.getHash()+JSON.toJSONString(txs) + nonce);
            if (hash.startsWith("0000")) {//验证新Hash值是否正确
                break;
            }
            nonce++;
        }
        System.out.println("=====计算结果正确,计算次数为:" +nonce+ ",hash:" + hash);
        System.out.println("耗时毫秒数:"+(System.currentTimeMillis()-start));
        //构造新区块
        Block newBlock=new Block(last.getIndex()+1,System.currentTimeMillis(),txs,nonce,last.getHash(),hash);
        //新区块加入区块链最后
        blockchain.add(newBlock);
        System.out.println("挖矿后的区块链:" + JSON.toJSONString(blockchain));
    }


}

运行测试样例:Run as –> Junit Test

初始化区块链:
[{"hash":"1","index":1,"nonce":1,"preHash":"","timestamp":1521731140922,"transactions":[]}]
=====计算结果正确,计算次数为:96507,hash:0000c189d48cdd6f0fcd965f6323f6da97f86534d52863e0f4aa90cd23bf700b
耗时毫秒数:613
挖矿后的区块链:[{"hash":"1","index":1,"nonce":1,"timestamp":1521731140922,"transactions":[]},{"hash":"0000c189d48cdd6f0fcd965f6323f6da97f86534d52863e0f4aa90cd23bf700b","index":2,"nonce":96507,"preHash":"1","timestamp":1521731141808,"transactions":[{},{},{},{}]}]

将矿后的区块链信息进行格式化处理:
这里写图片描述

很显然,一个创世区块,一个新区块(其中4个空交易记录)。

发布了478 篇原创文章 · 获赞 307 · 访问量 124万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览