Java&&区块链

引言

区块链:一种由密码学算法、共识机制、点对点传输、数学、计算机编程等多种技术为基础,而形成的分布式记账系统。

在过去的学习中,我们已经系统的学习了一下区块链的基本知识,如区块链的定义,智能合约,以及区块链的应用等。但我们貌似还没有实际的用代码编写出一条区块链出来(just一点点简单基础的功能👌),本文将系统的带领大家(可能也没有那么系统,菜鸟勿喷🥺)怎么用代码实打实的敲出一个盛夏(不是),敲出一条区块链来。

一.哈希算法

StringUtil(计算哈希值)

java.security.MessageDigest的用法

import java.security.MessageDigest;

public class StringUtil {
    public static String applySha256(String input) {
        try {
            // 获取 SHA-256 消息摘要实例
            MessageDigest digest = MessageDigest.getInstance("SHA-256");

            // 将输入字符串转换为字节数组并进行哈希运算
            byte[] hash = digest.digest(input.getBytes("UTF-8"));

            // 创建一个 StringBuffer 来存储哈希值的十六进制表示
            StringBuffer hexString = new StringBuffer();

            // 遍历哈希字节数组,将每个字节转换为两位的十六进制字符串
            for (byte b : hash) {
                hexString.append(String.format("%02x",b));

//                String hex = Integer.toHexString(0xff & b);
//                if (hex.length() == 1) hexString.append('0'); // 如果十六进制字符串长度为1,则在前面补0
//                hexString.append(hex);
            }

            // 返回十六进制字符串
            return hexString.toString();
        } catch (Exception e) {
            // 捕获异常并抛出运行时异常
            throw new RuntimeException(e);
        }
    }
}

二.区块链的共识机制

POW(工作量证明)

由于不同的节点接受数据有所区别,为了保证数据一致性,每个区块数据只能由一个节点进行记录。

BTC通过“工作量证明”(Proof of Work,PoW)来确认记账节点。每个节点如果想生成一个新的区块并写入区块链,必须解出比特币网络出的PoW问题。

其关键的要素是工作量证明函数、区块信息及难度值。

工作量证明函数是这道题的计算方式,区块决定了这道题的输入数据,难度值决定了这道题所需要的计算量。

可以简单理解成就是将不同的nonce值作为输入,尝试进行SHA256哈希运算,找出满足给定数量前导0的哈希值的过程。而要求的前导0的个数越多,代表难度越大。

difficult就是前导0的个数,如difficult=4,就是哈希的前四位为0

在这里插入图片描述

以下代码结合了前一章计算哈希的方法

public class ProofOfWork {
    public static void main(String[] args) {
        // 要进行哈希的数据
        String data = "Some data to hash";
        // 挖矿难度级别
        int difficulty = 4;
        // 调用挖矿方法并获取哈希值
        String hash = mine(data, difficulty);
        // 打印挖矿得到的哈希值
        System.out.println("Mined Hash: " + hash);
    }

    /**
     * 挖矿方法
     * @param data 要进行哈希的数据
     * @param difficulty 挖矿难度级别
     * @return 满足难度要求的哈希值
     */
    public static String mine(String data, int difficulty) {
        // 初始化nonce值
        long nonce = 0;
        // 记录挖矿次数
        int count = 0;
        // 生成目标字符串,由difficulty个'0'组成
        String target = new String(new char[difficulty]).replace('\0', '0');
        // 计算初始哈希值
        String hash = calculateHash(data, nonce);
        // 循环直到找到满足条件的哈希值
        while (!hash.substring(0, difficulty).equals(target)) {
            count++;
            nonce++;
            // 重新计算哈希值
            hash = calculateHash(data, nonce);
            // 打印当前挖矿次数、哈希值和nonce值
            System.out.println("第" + count + "次挖矿" + "  哈希值:" + hash + "  nonce值:" + nonce + "\n");
        }
        // 返回满足条件的哈希值
        return hash;
    }

    /**
     * 计算哈希值
     * @param data 要进行哈希的数据
     * @param nonce 当前的nonce值
     * @return 计算得到的SHA-256哈希值
     */
    public static String calculateHash(String data, long nonce) {
        // 使用SHA-256算法计算哈希值
        return StringUtil.applySha256(data + nonce);
    }
}
```


三.区块链与智能合约的结合运用

Block(定义区块)

public class Block {
    private String hash;
    private String previousHash;
    private String data;
    private long timeStamp;
    private int nonce;

    public Block(String data) {
        this.data = data;
        this.timeStamp = System.currentTimeMillis();
        this.hash = calculateHash();
    }
    
	//计算哈希值
    public String calculateHash() {
        return StringUtil.applySha256(previousHash + timeStamp + nonce + data);
    }
	
	//挖矿
    public void mineBlock(int difficulty) {
        String target = new String(new char[difficulty]).replace('\0', '0');
        while (!hash.substring(0, difficulty).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("Block Mined!!! : " + hash);
    }

    public String getHash() {
        return hash;
    }

    public void setPreviousHash(String previousHash) {
        this.previousHash = previousHash;
    }

    @Override
    public String toString() {
        return "Block{" +
                "hash='" + hash + '\'' +
                ", previousHash='" + previousHash + '\'' +
                ", data='" + data + '\'' +
                ", timeStamp=" + timeStamp +
                ", nonce=" + nonce +
                '}';
    }
}

Blockchain(上链)

创世区块(Genesis Block)是一条区块链中的第一个区块,它在区块链网络创建之初被添加到区块链中。

创世区块的创建标志着一个新的区块链的诞生,它通常包含一些特定的数据和参数,为后续区块的添加提供了基础。

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

public class Blockchain {
    private List<Block> chain;

    public Blockchain() {
        this.chain = new ArrayList<>();
        // 创建创世区块
        this.chain.add(createGenesisBlock());
    }
	
    //生成创世区块,前一区块哈希值为0,在这里我们定义data="genesisBlock"
    private Block createGenesisBlock() {
        return new Block("genesisBlock");
    }

    public Block getLatestBlock() {
        return this.chain.get(this.chain.size() - 1);
    }

    public void addBlock(Block newBlock) {
        newBlock.setPreviousHash(this.getLatestBlock().getHash());
        newBlock.mineBlock(4); // 假设难度为4
        this.chain.add(newBlock);
    }

    public List<Block> getChain() {
        return this.chain;
    }
}

SmartContract(智能合约)

智能合约就是存在于区块链上的计算机程序。它们仅在由用户(或其他合约)发出的交易触发时执行。

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

public class SmartContract {
    private String owner;
    private Map<String, Integer> balances;
    private Blockchain blockchain;

    public SmartContract(String owner, Blockchain blockchain) {
        this.owner = owner;
        this.blockchain = blockchain;
        this.balances = new HashMap<>();
        this.balances.put(owner, 1000); // 初始代币分配给合约所有者
    }

    // 获取账户余额
    public int getBalance(String account) {
        return balances.getOrDefault(account, 0);
    }

    // 转账方法
    public boolean transfer(String from, String to, int amount) {
        if (balances.getOrDefault(from, 0) >= amount) {
            balances.put(from, balances.get(from) - amount);
            balances.put(to, balances.getOrDefault(to, 0) + amount);
            // 创建新的区块并添加到区块链
            String transactionData = from + " transferred " + amount + " to " + to;
            Block newBlock = new Block(blockchain.getLatestBlock().getHash(), transactionData);

            //上链  需要进行挖矿,才能将账本上链,在addBlock里有挖矿函数
            blockchain.addBlock(newBlock);
            return true;
        }
        return false;
    }
}


三.区块链中的加密算法

Ctrl+鼠标左键了解→RSA算法

RSA算法基于大数因子分解的数学难题,它使用一对密钥:公钥和私钥。

公钥用于加密数据,私钥用于解密数据。公钥可以公开分享给其他人,而私钥必须保密。

在BTC中,人们使用公私钥进行转账,在阅读上文后,可以对RSA算法怎么用Java实现有个基本了解

那么可以进一步完善一下我们的区块链系统,增加公私钥加密和数字签名

KeyPairGeneratorUtil(生成一个RSA密钥对)

import java.security.KeyPair; // 导入 KeyPair 类,用于表示公钥和私钥对
import java.security.KeyPairGenerator; // 导入 KeyPairGenerator 类,用于生成公钥和私钥对
import java.security.NoSuchAlgorithmException; // 导入 NoSuchAlgorithmException 类,用于处理算法不可用的异常

public class KeyPairGeneratorUtil {
    /**
     * 生成一个 RSA 密钥对
     *
     * @return KeyPair 包含生成的公钥和私钥
     * @throws NoSuchAlgorithmException 如果指定的算法不可用时抛出异常
     */
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        // 获取一个 KeyPairGenerator 实例,指定使用 "RSA" 算法
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");

        // 初始化 KeyPairGenerator,指定密钥大小为 2048 位
        keyGen.initialize(2048);

        // 生成并返回密钥对
        return keyGen.genKeyPair();
    }
}

CryptoUtil(用于签名和验证数据)

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

/**
 * CryptoUtil 是一个用于签名和验证数据的实用工具类。
 */
public class CryptoUtil {

    /**
     * 使用私钥对数据进行签名。
     *
     * @param data 要签名的数据
     * @param privateKey 用于签名的私钥
     * @return 签名后的字节数组
     * @throws Exception 如果签名过程出错
     */
    public static byte[] sign(String data, PrivateKey privateKey) throws Exception {
        // 获取 SHA256withRSA 签名实例
        Signature signature = Signature.getInstance("SHA256withRSA");
        // 初始化签名对象,使用私钥
        signature.initSign(privateKey);
        // 更新签名对象,传入数据的字节形式
        signature.update(data.getBytes());
        // 执行签名操作并返回签名后的字节数组
        return signature.sign();
    }

    /**
     * 使用公钥验证数据的签名。
     *
     * @param data 原始数据
     * @param signatureBytes 签名后的字节数组
     * @param publicKey 用于验证的公钥
     * @return 如果签名验证成功则返回 true,否则返回 false
     * @throws Exception 如果验证过程出错
     */
    public static boolean verify(String data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
        // 获取 SHA256withRSA 签名实例
        Signature signature = Signature.getInstance("SHA256withRSA");
        // 初始化验证对象,使用公钥
        signature.initVerify(publicKey);
        // 更新验证对象,传入数据的字节形式
        signature.update(data.getBytes());
        // 执行验证操作并返回验证结果
        return signature.verify(signatureBytes);
    }
}

在了解了公私钥加密和数字签名后,我们可以对前面的代码进行修改,使其可以运用上新功能

SmartContract(高级版)

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

public class SmartContract {
    // 存储用户余额的映射
    private Map<String, Integer> balances = new HashMap<>();
    // 区块链实例
    private Blockchain blockchain;

    // 构造函数,初始化合约,设置初始用户和区块链
    public SmartContract(String initialUser, Blockchain blockchain) {
        this.blockchain = blockchain;
        // 设置初始用户的余额为1000
        balances.put(initialUser, 1000); // 初始余额
    }

    // 获取用户余额
    public int getBalance(String user) {
        // 如果用户不存在,返回0
        return balances.getOrDefault(user, 0);
    }

    // 转账方法
    public boolean transfer(PublicKey fromKey, PublicKey toKey, int amount, PrivateKey fromPrivateKey) {
        // 将公钥转换为字符串表示
        String from = fromKey.toString();
        String to = toKey.toString();
        // 检查发送方余额是否足够
        if (getBalance(from) >= amount) {
            try {
                // 创建交易数据字符串
                String data = from + to + amount;
                // 使用发送方的私钥对数据进行签名
                byte[] signature = CryptoUtil.sign(data, fromPrivateKey);

                // 验证签名是否有效
                if (CryptoUtil.verify(data, signature, fromKey)) {
                    // 更新发送方和接收方的余额
                    balances.put(from, getBalance(from) - amount);
                    balances.put(to, getBalance(to) + amount);
                    // 创建新的区块并添加到区块链
                    blockchain.addBlock(new Block("from:" + from + "\n" + "to:" + to + "\n"));
                    return true; // 转账成功
                }
            } catch (Exception e) {
                e.printStackTrace(); // 捕获并打印异常
            }
        }
        return false; // 转账失败
    }
}

四.the last–Main

将前面的知识全部整合一下,我们可以编写出一个main来运用他们

import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

public class Main {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        // 创建一个新的区块链实例
        Blockchain blockchain = new Blockchain();

        // 生成 Alice 和 Bob 的密钥对
        KeyPair keyPairAlice = KeyPairGeneratorUtil.generateKeyPair();
        KeyPair keyPairBob = KeyPairGeneratorUtil.generateKeyPair();

        // 获取 Alice 和 Bob 的公钥和私钥
        PublicKey publicKeyAlice = keyPairAlice.getPublic();
        PrivateKey privateKeyAlice = keyPairAlice.getPrivate();
        PublicKey publicKeyBob = keyPairBob.getPublic();

        // 创建一个智能合约实例,绑定 Alice 的公钥和区块链
        SmartContract contract = new SmartContract(publicKeyAlice.toString(), blockchain);

        // 打印 Alice 和 Bob 的初始余额
        System.out.println("Alice's balance: " + contract.getBalance(publicKeyAlice.toString()));
        System.out.println("Bob's balance: " + contract.getBalance(publicKeyBob.toString()));

        // Alice 向 Bob 转账 100 代币
        if (contract.transfer(publicKeyAlice, publicKeyBob, 100, privateKeyAlice)) {
            System.out.println("Transfer successful!"); // 转账成功
        } else {
            System.out.println("Transfer failed!"); // 转账失败
        }

        // 打印 Alice 和 Bob 的余额
        System.out.println("Alice's balance: " + contract.getBalance(publicKeyAlice.toString()));
        System.out.println("Bob's balance: " + contract.getBalance(publicKeyBob.toString()));

        // 打印区块链中的所有区块
        for (Block block : blockchain.getChain()) {
            System.out.println(block.toString());
        }
    }
}
  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
区块链Java SDK是一种软件开发工具包,可以用于与区块链网络进行交互和开发区块链应用程序。它提供了一系列的Java类和方法,使开发人员可以轻松地与区块链进行通信、管理账户、执行交易等操作。 使用区块链Java SDK,开发人员可以方便地创建和管理区块链网络中的账户和钱包。他们可以通过SDK中的方法来生成新的账户、导入已有账户、查询余额和交易历史等。同时,SDK还提供了安全的加密算法,用于对账户的私钥进行保护,确保账户的安全性。 除了账户管理,区块链Java SDK还支持交易的创建和执行。开发人员可以使用SDK提供的方法创建不同类型的交易,例如转账交易、合约调用等。SDK还提供了签名和验证的功能,可以对交易进行数字签名,从而确保交易的有效性和完整性。 另外,区块链Java SDK还提供了一些高级功能,例如查询区块链的状态、执行智能合约等。开发人员可以使用SDK中封装好的方法来查询区块链上的信息,例如区块高度、当前时间戳等。同时,SDK也支持与智能合约的交互,开发人员可以使用SDK中的方法来执行智能合约的函数,读取或写入区块链上的数据。 总之,区块链Java SDK为开发人员提供了一套方便易用的工具,帮助他们与区块链网络进行交互和开发区块链应用程序。它使得开发人员可以更快速地开发出安全可靠的区块链应用,并为区块链技术的广泛应用提供了支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值