美文网首页
区块链的hello world实现(三

区块链的hello world实现(三

作者: abaeccdce206 | 来源:发表于2018-04-13 10:53 被阅读66次

    由于在笔记二中提到区块链数据有2大部分组成
    1:交易数据
    2:区块信息(hash值 工作量等)

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import org.json.JSONObject;
    
    public class BlockChain {
    // 存储区块链
    private List<Map<String, Object>> chain;
    // 该实例变量用于当前的交易信息列表
    private List<Map<String, Object>> currentTransactions;
    private static BlockChain blockChain = null;
    
    private BlockChain() {
            // 初始化区块链以及当前的交易信息列表
            chain = new ArrayList<Map<String, Object>>();
            currentTransactions = new ArrayList<Map<String, Object>>();
    
            // 创建创世区块
            newBlock(100, "0");
            }
    //因为新的区块都是依赖上一个区块hash值产生,所以创世区块稍微特殊,在初始化的时候生成,用于理解比特币的创世区块
    
    // 创建单例对象,保持区块一致性
    public static BlockChain getInstance() {
            if (blockChain == null) {
    synchronized (BlockChain.class) {
            if (blockChain == null) {
            blockChain = new BlockChain();
            }
            }
            }
            return blockChain;
            }
    
    public List<Map<String, Object>> getChain() {
            return chain;
            }
    
    public void setChain(List<Map<String, Object>> chain) {
            this.chain = chain;
            }
    
    public List<Map<String, Object>> getCurrentTransactions() {
            return currentTransactions;
            }
    
    public void setCurrentTransactions(List<Map<String, Object>> currentTransactions) {
            this.currentTransactions = currentTransactions;
            }
    
    /**
     * @return 得到区块链中的最后一个区块
    * 用于存放最近的交易记录,也是为下次生成新的区块做准备
     */
    public Map<String, Object> lastBlock() {
            return getChain().get(getChain().size() - 1);
            }
    
    /**
     * 在区块链上新建一个区块
     *
     * @param proof
    
    
    
     * @param previous_hash
     *            上一个区块的hash值
     * @return 返回新建的区块
     */
    public Map<String, Object> newBlock(long proof, String previous_hash) {
    
            Map<String, Object> block = new HashMap<String, Object>();
            block.put("index", getChain().size() + 1);
            block.put("timestamp", System.currentTimeMillis());
            block.put("transactions", getCurrentTransactions());
            block.put("proof", proof);
            // 如果没有传递上一个区块的hash就计算出区块链中最后一个区块的hash
            block.put("previous_hash", previous_hash != null ? previous_hash : hash(getChain().get(getChain().size() - 1)));
    
            // 重置当前的交易信息列表
            setCurrentTransactions(new ArrayList<Map<String, Object>>());
    
            getChain().add(block);
    
            return block;
            }
    
    /**
     * 生成新交易信息,信息将加入到下一个待挖的区块中
     *
     * @param sender
     *            发送方的地址
     * @param recipient
     *            接收方的地址
     * @param amount
     *            交易数量
     * @return 返回该交易事务的块的索引
     */
    public int newTransactions(String sender, String recipient, long amount) {
    
            Map<String, Object> transaction = new HashMap<String, Object>();
            transaction.put("sender", sender);
            transaction.put("recipient", recipient);
            transaction.put("amount", amount);
    
            getCurrentTransactions().add(transaction);
    
            return (Integer) lastBlock().get("index") + 1;
            }
    
    /**
     * 生成区块的 SHA-256格式的 hash值
     *
     * @param block
     *            区块
     * @return 返回该区块的hash
     */
    public static Object hash(Map<String, Object> block) {
            return new Encrypt().getSHA256(new JSONObject(block).toString());
            }
    
            /**
             * 简单的工作量证明:
             *   - 查找一个 p' 使得 hash(pp') 以4个0开头
             *   - p 是上一个块的证明, p' 是当前的证明
             *
             * @param last_proof
             *               上一个块的证明
             * @return
             */
            public long proofOfWork(long last_proof) {
                    long proof = 0;
                    while (!validProof(last_proof, proof)) {
                            proof += 1;
                    }
                    return proof;
            }
    
            /**
             * 验证证明: 是否hash(last_proof, proof)以4个0开头?
             *
             * @param last_proof
             *            上一个块的证明
             * @param proof
             *            当前的证明
             * @return 以4个0开头返回true,否则返回false
            *目前比特币是18个0开头的hash值,计算难度相当大
             */
            public boolean validProof(long last_proof, long proof) {
                    String guess = last_proof + "" + proof;
                    String guess_hash = new Encrypt().getSHA256(guess);
                    return guess_hash.startsWith("0000");
            }
    
     }
    
    
    
    

    相关文章

      网友评论

          本文标题:区块链的hello world实现(三

          本文链接:https://www.haomeiwen.com/subject/cbfckftx.html