安卓编写区块链的尝试(失败)

本文记录了一次在安卓平台上尝试编写区块链的失败经历。作者参照教程创建了Block、TXInput、TXOutput、Transaction类,并实现了工作量证明。在尝试使用RocksDB和SQLite进行数据存储时遇到问题,最终因时间限制和基础知识不足导致项目未完成。文章分享了遇到的困难和学习心得。
摘要由CSDN通过智能技术生成

安卓编写区块链的尝试(失败)

在开始之前,我看了手把手教你实现简易比特币(Java版),看了之后感觉挺容易的样子,我就根据他的代码进行修改尝试。

创建Block.java

Block类中有区块hash,父区块hash,区块交易,时间戳,区块高度,工作量证明的随机数nonce这几个属性,添加org.projectlombok依赖,使用注解的方式可以实现属性的set/get方法,该类有创建区块,创建创世区块(区块链中的第一个区块),和计算区块交易的hash。

package com.example.blockchain;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 区块
 * @author hanru
 *
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Block {

    /**
     * 区块hash值
     */
    private String hash;

    /**
     * 前一个区块的hash值
     */
    private String prevBlockHash;

    /**
     * 区块交易
     */
    private List<Transaction> transactions;

    /**
     * 时间戳,单位秒
     */
    private long timeStamp;

    /**
     * 区块的高度
     */
    private long height;

    /**
     * 工作量证明计数器
     */
    private long nonce;




    /**
     * 创建新的区块
     *
     * @param previousHash
     * @param transactions
     * @return
     */
    public static Block newBlock(String previousHash, List<Transaction> transactions, long height) {
        Block block = new Block("", previousHash, transactions, Instant.now().getEpochSecond(),height,0);
        ProofOfWork pow = ProofOfWork.newProofOfWork(block);
        PowResult powResult = pow.run();
        block.setHash(powResult.getHash());
        block.setNonce(powResult.getNonce());
//    block.setHash();
        return block;
    }
    

    private static final String ZERO_HASH = Hex.encodeHexString(new byte[32]);

    /**
     * 创建创世区块
     * @param coinbase
     * @return
     */
    public static Block newGenesisBlock(Transaction coinbase) {
        List<Transaction> transactions = new ArrayList<>();
        transactions.add(coinbase);
        return Block.newBlock(ByteUtils.ZERO_HASH, transactions,0);
    }

    /**
     * 对区块中的交易信息进行Hash计算
     *
     * @return
     */
    public byte[] hashTransaction() {
        byte[][] txIdArrays = new byte[this.getTransactions().size()][];
      for (int i = 0; i < this.getTransactions().size(); i++) {
         txIdArrays[i] = this.getTransactions().get(i).getTxId();
      }
      return DigestUtils.sha256(ByteUtils.merge(txIdArrays));


    }


}
创建ByteUtils.java

该类的作用是将数据转换承byte[]字节数据

package com.example.blockchain;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.stream.Stream;

/**
 * 字节数组工具类
 *
 */
public class ByteUtils {

   public static final String ZERO_HASH = Hex.encodeHexString(new byte[32]);


   /**
    * 将多个字节数组合并成一个字节数组
    * @param bytes
    * @return
    */
   public static byte[] merge(byte[]... bytes) {
        Stream<Byte> stream = Stream.of();
        for (byte[] b : bytes) {
            stream = Stream.concat(stream, Arrays.stream(ArrayUtils.toObject(b)));
        }
        return ArrayUtils.toPrimitive(stream.toArray(Byte[]::new));
    }
   
   /**
    * long 转化为 byte[]
    * @param val
    * @return
    */
   public static byte[] toBytes(long val) {
        return ByteBuffer.allocate(Long.BYTES).putLong(val).array();
    }
}
创建Blockchain.java

其中的方法有创建区块链,添加区块Block,区块链遍历,打包交易信息创建区块添加到区块链等

package com.example.blockchain;


import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 区块链
 *
 */
@Data
@AllArgsConstructor
public class Blockchain {


	/**
	 * 最后一个区块的hash
	 */
	private String lastBlockHash;


	/**
	 * 创建区块链,createBlockchain
	 * @param address
	 * @return
	 */
	public static Blockchain createBlockchain(String address) {

		String lastBlockHash = "";
		if (StringUtils.isBlank(lastBlockHash)){
			//对应的bucket不存在,说明是第一次获取区块链实例
			// 创建 coinBase 交易
			Transaction coinbaseTX = Transaction.newCoinbaseTX(address, "");
			Block genesisBlock = Block.newGenesisBlock(coinbaseTX);
			lastBlockHash = genesisBlock.getHash();
			RocksDBUtils.getInstance().putBlock(genesisBlock);
			RocksDBUtils.getInstance().putLastBlockHash(lastBlockHash);

		}
		return new Blockchain(lastBlockHash);
	}

	/**
	 * 根据block,添加区块
	 * @param block
	 */
	public void addBlock(Block block) {

		RocksDBUtils.getInstance().putLastBlockHash(block.getHash());
		RocksDBUtils.getInstance().putBlock(block);
		this.lastBlockHash = block.getHash();

	}

	/**
	 * 根据data添加区块
	 * @param data
	 */
//	public void addBlock(String data)  throws Exception{
//
//        String lastBlockHash = RocksDBUtils.getInstance().getLastBlockHash();
//        if (StringUtils.isBlank(lastBlockHash)){
//			throw new Exception("还没有数据库,无法直接添加区块。。");
//		}
//		this.addBlock(Block.newBlock(lastBlockHash,data));
//    }


	/**
	 * 区块链迭代器:内部类
	 */
	public class BlockchainIterator{

		/**
		 * 当前区块的hash
		 */
		private String currentBlockHash;

		/**
		 * 构造函数
		 * @param currentBlockHash
		 */
		public BlockchainIterator(String currentBlockHash) {
			this.currentBlockHash = currentBlockHash;
		}

		/**
		 * 判断是否有下一个区块
		 * @return
		 */
		public boolean hashNext() {
			if (ByteUtils.ZERO_HASH.equals(currentBlockHash)) {
				return false;
			}
			Block lastBlock = RocksDBUtils.getInstance().
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值