基于Java语言构建区块链(一)—— 基本原型

简介: 最终内容请以原文为准:https://wangwei.one/posts/df195d9.html 引言 区块链技术是一项比人工智能更具革命性的技术,人工智能只是提高了人类的生产力,而区块链则将改变人类社会的生产关系,它将会颠覆我们人类社会现有的协作方式。

最终内容请以原文为准:https://wangwei.one/posts/df195d9.html

引言

区块链技术是一项比人工智能更具革命性的技术,人工智能只是提高了人类的生产力,而区块链则将改变人类社会的生产关系,它将会颠覆我们人类社会现有的协作方式。了解和掌握区块链相关知识和技术,是我们每位开发人员必须要去做的事情,这样我们才能把握住这波时代趋势的红利。

本文将基于Java语言构建简化版的blockchain,来实现数字货币。

创建区块

区块链是由包含交易信息的区块从后向前有序链接起来的数据结构。区块被从后向前有序地链接在这个链条里,每个区块都指向前一个区块。以比特币为例,每个区块主要包含如下信息字段:

  • 区块大小:用字节表示的区块数据大小
  • 区块头:组成区块头的几个字段

    • 区块头hash值
    • 父区块头hash值
    • 时间戳:区块产生的近似时间
    • Merkle根:该区块中交易的merkle树根的哈希值
    • 难度目标:该区块工作量证明算法的难度目标
    • Nonce:用于工作量证明算法的计数器
  • 交易计数器:交易的数量
  • 交易:记录在区块里的交易信息

详见:《精通比特币》(第二版)第9章——区块链

区块数据结构

在这里,我们主要是为了实现最简单的区块链结构,仅仅包含以下几个信息字段:

/**
 * 区块
 *
 * @author wangwei
 * @date 2018/02/02
 */
@Data
public class Block {

    /**
     * 区块hash值
     */
    private String hash;
    /**
     * 前一个区块的hash值
     */
    private String previousHash;
    /**
     * 区块数据
     */
    private String data;
    /**
     * 区块创建时间(单位:秒)
     */
    private long timeStamp;

    public Block() {
    }

    public Block(String hash, String previousHash, String data, long timeStamp) {
        this();
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timeStamp = timeStamp;
    }
}
区块Hash值计算

加密Hash值,一个通过SHA256算法对区块头进行二次哈希计算而得到的数字指纹。Hash值用于确保blockchain的安全。Hash计算是计算敏感的操作,即使在高性能电脑也需要花费一段时间来完成计算(这也就是为什么人们购买高性能GPU进行比特币挖矿的原因)。blockchain架构设计有意使Hash计算变得困难,这样做是为了加大新增一个block的难度,进而防止block在增加后被随意修改。

/**
 * <p> 创建新区块 </p>
 *
 * @param previousHash
 * @param data
 * @return
 */
public static Block newBlock(String previousHash, String data) {
        Block block = new Block("", previousHash, data.getBytes(),     Instant.now().getEpochSecond());
        block.setHash();
        return block;
}

/**
 * 计算区块Hash
 * <p>
 * 注意:在准备区块数据时,一定要从原始数据类型转化为byte[],不能直接从字符串进行转换
 *
 * @return
 */
private void setHash() {
    byte[] prevBlockHashBytes = {};
    if (StringUtils.isNoneBlank(this.getPrevBlockHash())) {
        prevBlockHashBytes = new BigInteger(this.getPrevBlockHash(), 16).toByteArray();
    }

    byte[] headers = ByteUtils.merge(
           prevBlockHashBytes,
           this.getData().getBytes(),
           ByteUtils.toBytes(this.getTimeStamp()));

    this.setHash(DigestUtils.sha256Hex(headers));
}

创建区块链

区块链本质上是一种有序反向链接链表的数据结构。这意味着,block按照插入的顺序存放,同时每个block都保存指向上一个block的链接。这种结构保证可以快速获取最新插入的block同时获取它的hash值。这种结构保证可以快速获取最新插入的block同时(高效地)获取它的hash值。

区块链数据结构
/**
 * <p> 区块链 </p>
 *
 * @author wangwei
 * @date 2018/02/02
 */
public class Blockchain {
    
    @Getter
    private List<Block> blockList;

    public Blockchain(List<Block> blockList) {
        this.blockList = blockList;
    }
}    
添加区块

新增一个添加区块链的方法

/**
 * <p> 添加区块  </p>
 *
 * @param data 数据
 */
public void addBlock(String data) {
   Block previousBlock = blockList.get(blockList.size() - 1);
   this.addBlock(Block.newBlock(previousBlock.getHash(), data));
}

/**
 * <p> 添加区块  </p>
 *
 * @param block 区块
 */
public void addBlock(Block block) {
   this.blockList.add(block);
}
创世区块

在添加区块之前,区块链必须有个创世区块,在Block中新增创世区块方法:

/**
  * <p> 创建创世区块 </p>
  *
  * @return
  */
public static Block newGenesisBlock() {
   return Block.newBlock("", "Genesis Block");
}
创建区块链

再在Blockchain中新增创建区块链的方法:

/**
 * <p> 创建区块链 </p>
 *
 * @return
 */
public static Blockchain newBlockchain() {
    List<Block> blocks = new LinkedList<>();
    blocks.add(Block.newGenesisBlock());
    return new Blockchain(blocks);
}

测试运行

/**
 * 测试
 *
 * @author wangwei
 * @date 2018/02/05
 */
public class BlockchainTest {

    public static void main(String[] args) {

        Blockchain blockchain = Blockchain.newBlockchain();
        blockchain.addBlock("Send 1 BTC to Ivan");
        blockchain.addBlock("Send 2 more BTC to Ivan");

        for (Block block : blockchain.getBlockList()) {
            System.out.println("Prev. hash: " + block.getPreviousHash());
            System.out.println("Data: " + block.getData());
            System.out.println("Hash: " + block.getHash());
            System.out.println();
        }
    }
}

/**
 * 输出如下信息:
 */
Prev. hash: 
Data: Genesis Block
Hash: 4492cb9d396a9a52e7ff17ef3782f022ddcdc7b2c276bc6dd3d448b0655eb3d4

Prev. hash: 4492cb9d396a9a52e7ff17ef3782f022ddcdc7b2c276bc6dd3d448b0655eb3d4
Data: Send 1 BTC to Ivan
Hash: cd716d59d98ad673035ab7035ece751718ea9842944a4743c298bebc0fe24c04

Prev. hash: cd716d59d98ad673035ab7035ece751718ea9842944a4743c298bebc0fe24c04
Data: Send 2 more BTC to Ivan
Hash: 42f78d6a86f88aa9b5b10e468494dfd1b3f558a9fb74a01eb348c2cbfc5d000a

总结

我们构建了一个非常简单的区块链原型:它只是一个块的数组,每个块都与前一个块有连接。 实际的区块链要复杂得多。

  • 缺少交易信息:我们的区块链还没有任何交易信息。
  • 缺少工作量证明:我们的生产区块非常简单快捷,实际的区块链中,生产一个区块需要进行大量的计算。
  • 缺少共识机制:区块链是一个非单一决策者的分布式数据库。 因此,一个新的区块必须得到网络的其他参与者的确认和批

在以后的文章中,我们将介绍这些功能。

资料

目录
相关文章
|
5月前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
406 3
|
6月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
2296 1
|
6月前
|
安全 Java API
使用 Java 构建强大的 REST API 的四个基本技巧
本文结合探险领域案例,分享Java构建REST API的四大核心策略:统一资源命名、版本控制与自动化文档、安全防护及标准化异常处理,助力开发者打造易用、可维护、安全可靠的稳健API服务。
445 116
|
6月前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
3359 58
|
5月前
|
人工智能 缓存 自然语言处理
Java与多模态AI:构建支持文本、图像和音频的智能应用
随着大模型从单一文本处理向多模态能力演进,现代AI应用需要同时处理文本、图像、音频等多种信息形式。本文深入探讨如何在Java生态中构建支持多模态AI能力的智能应用。我们将完整展示集成视觉模型、语音模型和语言模型的实践方案,涵盖从文件预处理、多模态推理到结果融合的全流程,为Java开发者打开通往下一代多模态AI应用的大门。
495 41
|
5月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
393 18
|
5月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
470 8
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
Java与生成式AI:构建内容生成与创意辅助系统
生成式AI正在重塑内容创作、软件开发和创意设计的方式。本文深入探讨如何在Java生态中构建支持文本、图像、代码等多种生成任务的创意辅助系统。我们将完整展示集成大型生成模型(如GPT、Stable Diffusion)、处理生成任务队列、优化生成结果以及构建企业级生成式AI应用的全流程,为Java开发者提供构建下一代创意辅助系统的完整技术方案。
333 10
|
5月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
226 4
|
5月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
754 4