【SpringBoot】SpringBoot实现基本的区块链的步骤与代码
以下是Spring Boot实现基本的区块链代码的步骤:
-
创建一个Block类,它表示一个区块,包含一个区块头和一个区块体。区块头包括版本号、时间戳、前一个区块的哈希值和当前区块的哈希值。区块体包含交易数据。
-
创建一个Blockchain类,它表示整个区块链,包含一个链列表和一个未确认交易列表。添加一个Genesis区块(创世区块)。
-
实现哈希函数,可以使用SHA256算法对数据进行哈希。
-
实现一个简单的工作量证明算法,目的是确保新区块的生成需要付出一定的计算力。可以使用计算拼图的方式来实现工作量证明算法。
-
实现一个简单的交易系统,包括交易数据的创建和验证。可以将交易数据保存在未确认交易列表中,然后在新区块生成后将其加入到区块链中。
-
实现一个简单的P2P网络,让不同的节点之间可以互相通信。可以使用websocket协议来实现P2P网络。
-
实现一个简单的共识协议,让不同的节点之间可以达成共识,确保区块链的一致性。可以使用最长链原则来实现共识协议。
-
创建一个Spring Boot应用程序,将以上所有代码整合起来,并提供简单的REST接口,让外部应用程序可以调用区块链的各种功能。
下面是一个简单实现的代码示例:
- Block类
public class Block {private int version;private long timeStamp;private String previousHash;private String hash;private List<Transaction> transactions;// getters and setters
}
2.Blockchain类
public class Blockchain {private List<Block> chain = new ArrayList<>();private List<Transaction> currentTransactions = new ArrayList<>();public Blockchain() {// create genesis blockBlock genesisBlock = new Block(1, System.currentTimeMillis(), "", "");chain.add(genesisBlock);}public void addBlock(Block block) {String previousHash = getLastBlock().getHash();String hash = calculateHash(block.getVersion(), block.getTimeStamp(), previousHash, block.getTransactions());block.setHash(hash);chain.add(block);currentTransactions.clear();}public Block getLastBlock() {return chain.get(chain.size() - 1);}public void addTransaction(Transaction transaction) {currentTransactions.add(transaction);}// getters and setters
}
3.哈希函数
public static String calculateHash(int version, long timeStamp, String previousHash, List<Transaction> transactions) {String data = version + timeStamp + previousHash + transactions.toString();MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));return bytesToHex(hash);
}private static String bytesToHex(byte[] hash) {StringBuffer hexString = new StringBuffer();for (int i = 0; i < hash.length; i++) {String hex = Integer.toHexString(0xff & hash[i]);if(hex.length() == 1) hexString.append('0');hexString.append(hex);}return hexString.toString();
}
4.工作量证明算法
public static Block mineBlock(Block block, int difficulty) {String target = new String(new char[difficulty]).replace('\0', '0');while (!block.getHash().substring(0, difficulty).equals(target)) {block.setNonce(block.getNonce() + 1);block.setHash(calculateHash(block.getVersion(), block.getTimeStamp(), block.getPreviousHash(), block.getTransactions(), block.getNonce()));}return block;
}public static String calculateHash(int version, long timeStamp, String previousHash, List<Transaction> transactions, int nonce) {String data = version + timeStamp + previousHash + transactions.toString() + nonce;MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));return bytesToHex(hash);
}
5.交易系统
public class Transaction {private String sender;private String recipient;private int amount;// getters and setters
}@RestController
public class TransactionController {@Autowiredprivate Blockchain blockchain;@PostMapping("/transactions/new")public ResponseEntity<String> addTransaction(@RequestBody Transaction transaction) {blockchain.addTransaction(transaction);return ResponseEntity.ok("Transaction added");}
}
6.P2P网络
@Component
public class P2PClient {@Autowiredprivate Blockchain blockchain;@Autowiredprivate P2PServer p2pServer;private WebSocketSession session;private String address;@EventListenerpublic void handleWebSocketConnectListener(SessionConnectedEvent event) {session = event.getSession();address = session.getRemoteAddress().getHostName();p2pServer.addClient(this);}@EventListenerpublic void handleWebSocketCloseListener(SessionDisconnectEvent event) {p2pServer.removeClient(this);}public void sendMessage(String message) throws IOException {session.sendMessage(new TextMessage(message));}public void broadcast(String message) throws IOException {for (P2PClient client : p2pServer.getClients()) {if (!client.getAddress().equals(address)) {client.sendMessage(message);}}}// getters and setters
}@Component
public class P2PServer {@Autowiredprivate Blockchain blockchain;private List<P2PClient> clients = new ArrayList<>();public void addClient(P2PClient client) {clients.add(client);}public void removeClient(P2PClient client) {clients.remove(client);}public List<P2PClient> getClients() {return clients;}@Scheduled(fixedDelay = 1000)public void broadcastBlockchain() throws IOException {ObjectMapper objectMapper = new ObjectMapper();String blockchainJson = objectMapper.writeValueAsString(blockchain);for (P2PClient client : clients) {client.sendMessage(blockchainJson);}}
}
7.共识协议
public class Consensus {public static boolean resolveConflicts(List<Blockchain> blockchains) {int maxLength = blockchains.size();Blockchain longestBlockchain = null;for (Blockchain blockchain : blockchains) {if (blockchain.getChain().size() > maxLength && isValidChain(blockchain.getChain())) {maxLength = blockchain.getChain().size();longestBlockchain = blockchain;}}if (longestBlockchain != null) {blockchain.setChain(longestBlockchain.getChain());blockchain.setCurrentTransactions(longestBlockchain.getCurrentTransactions());return true;} else {return false;}}private static boolean isValidChain(List<Block> chain) {Block lastBlock = chain.get(0);int currentIndex = 1;while (currentIndex < chain.size()) {Block block = chain.get(currentIndex);if (!block.getPreviousHash().equals(lastBlock.getHash())) {return false;}currentIndex++;}return true;}
}@RestController
public class ConsensusController {@Autowiredprivate List<P2PClient> peers;@GetMapping("/nodes/resolve")public ResponseEntity<String> resolveConflicts() throws IOException {List<Blockchain> blockchains = new ArrayList<>();blockchains.add(blockchain);for (P2PClient peer : peers) {RestTemplate restTemplate = new RestTemplate();ResponseEntity<String> response = restTemplate.getForEntity(peer.getUrl() + "/chain", String.class);if (response.getStatusCode() == HttpStatus.OK) {Blockchain remoteBlockchain = objectMapper.readValue(response.getBody(), Blockchain.class);blockchains.add(remoteBlockchain);}}if (Consensus.resolveConflicts(blockchains)) {return ResponseEntity.ok("Conflict resolved. Blockchain updated.");} else {return ResponseEntity.ok("No conflicts found.");}}
}
8.Spring Boot应用程序
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
这只是一个简单的实现示例,实际上要实现一个完整的区块链系统需要更多的功能和细节。此外,还需要处理各种安全问题,例如拒绝服务攻击、双重支付等。因此,建议在实际应用中使用成熟的区块链框架,而不是从头开始编写自己的区块链代码。
相关文章:
【SpringBoot】SpringBoot实现基本的区块链的步骤与代码
以下是Spring Boot实现基本的区块链代码的步骤: 创建一个Block类,它表示一个区块,包含一个区块头和一个区块体。区块头包括版本号、时间戳、前一个区块的哈希值和当前区块的哈希值。区块体包含交易数据。 创建一个Blockchain类,它…...

Photoscan/Metashape 2.0.0中的地面激光扫描处理
在Metashape(原Photoscan)2.0.0, 结构化地面激光扫描和非结构化航空激光扫描都可以使用导入点云(文件>导入>导入点云)命令导入。导入时会保留所有点属性(包括结构化信息)。 本文讨论以下主题 如何将激光扫描数据导入项目&am…...

git快速使用
1、下载git 设置签名 2、基本概念 工作区:写代码的地方。 暂存区:.git的.index 工作区:.git 3、常用操作 本地codinggit init, 初始化一个本地仓库,项目根目录下会出现个.gitgit remote add origin gitgithub.com…...
java 实现代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,它允许一个对象(代理对象)充当另一个对象(被代理对象)的接口,以控制对该对象的访问。代理模式通常用于以下情况: 远程代理…...
【每日一题】力扣1768. 交替合并字符串
题目以及链接: 1768. 交替合并字符串 给你两个字符串 word1 和 word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 示例 1&…...

vscode新建vue3文件模板
输入快捷新建的名字 enter 确认后在文件中输入以下内容 {// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and// description. The prefix is what is used to trigger the snippet and the body will be expand…...
MySql学习笔记02——MySql的简单介绍
MySQL 常用命令 注意在mysql中使用的命令需要用英文分号结尾(启动/关闭mysql服务不需要带分号) net start mysql 启动mysql服务(需要管理员启动cmd) net stop mysql关闭mysql服务(需要管理员启动cmd) m…...

mysql-1:认识mysql
文章目录 数据库概述什么是数据库什么是关系型数据库 MySQL的概述MySQL是什么MySQL发展历程 SQL的概述什么是SQLSQL发展的简要历史:SQL语言分类 数据库概述 什么是数据库 数据库就是[存储数据的仓库],其本质是一个[文件系统],数据按照特定的…...
算法通关村-----堆在查找和排序中的应用
数组中的第K个最大元素 问题描述 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。详见le…...
直方图统计增强方法
直方图统计增强方法的原理: 直方图统计增强是一种基于像素值分布的图像增强技术,通过调整像素值的分布来增强图像的对比度和细节。其原理是根据图像的直方图信息,将原始像素值映射到一个新的像素值域,从而改变图像的亮度和对比…...

字节二面:如果高性能渲染十万条数据?
前言 最近博主在字节面试中遇到这样一个面试题,这个问题也是前端面试的高频问题,作为一名前端开发工程师,我们虽然可能很少会遇到后端返回十万条数据的情况,但是了解掌握如何处理这种情况,能让你对前端性能优化有更深的…...

Mysql高阶语句(二)
一、设置别名(alias ——>as) 在 MySQL 查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者 多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了࿰…...

算法笔记 二叉搜索树
二叉搜索树(Binary Search Tree,简称 BST)是一种数据结构,用于存储具有可比较键(通常是数字或字符串)的元素 1 结构特点 节点结构:每个节点都有一个键和两个子节点(左子节点和右子…...
微软牵手Linux:Ubuntu“系统”上架win10应用商店啦
导读继SUSE Linux登陆之后,Ubuntu今天正式以UWP应用的身份上架Win10应用商店。Windows Insider用户升级到Win10秋季创意者更新预览版Build 16190及以上就可以下载和安装Ubuntu系统应用。一旦下载和安装完Ubuntu应用后,它将开始在你的Windows10 PC上安装U…...
leetcode做题笔记126. 单词接龙 II
按字典 wordList 完成从单词 beginWord 到单词 endWord 转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk 这样的单词序列,并满足: 每对相邻的单词之间仅有单个字母不同。转换过程中的每个单词 s…...
windows下运行springboot的jar包,修改替换class文件,修改配置文件application,打包
在windows下跑springboot的jar包,经常会用到一些命令行和操作。 1、修改配置文件(以application.yml为例) #提取文件 jar xvf mqtt-10.1.0.jar BOOT-INF/classes/application.yml#将文件装回jar包 jar uvf mqtt-10.1.0.jar BOOT-INF/classe…...
PMD 检查java代码:可以去掉无用的括号(UselessParentheses)
这个规则的优先级比较低。 https://docs.pmd-code.org/pmd-doc-6.55.0/pmd_rules_java_codestyle.html#uselessparentheses 无用的括号可以去掉。当然,有时候为了避免理解起来困难,加上括号反而更加清晰。 例如: public static short calc…...

【数据结构练习】栈的面试题集锦
目录 前言: 1.进栈过程中可以出栈的选择题 2.将递归转化为循环 3.逆波兰表达式求值 4.有效的括号 5. 栈的压入、弹出序列 6. 最小栈 前言: 数据结构想要学的好,刷题少不了,我们不仅要多刷题,还要刷好题&#x…...

简单工厂模式概述和使用
目录 一、简单工厂模式简介1. 定义2. 使用动机 二、简单工厂模式结构1.模式结构2. 时序图 三、简单工厂的使用实例四、简单工厂模式优缺点五、简单工厂模式在Java中的应用 一、简单工厂模式简介 原文链接 1. 定义 简单工厂模式(Simple Factory Pattern):又称为静…...

软件工程概述
软件工程概述 软件工程指的是应用计算机科学、数学及管理科学等原理,以工程化的原则和方法来解决软件问题的工程,目的是提高软件生产效率、提高软件质量、降低软件成本。 1. 计算机软件 计算机软件指的是计算机系统中的程序及其文档。程序是计算任务的…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...

算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

RabbitMQ 各类交换机
为什么要用交换机? 交换机用来路由消息。如果直发队列,这个消息就被处理消失了,那别的队列也需要这个消息怎么办?那就要用到交换机 交换机类型 1,fanout:广播 特点 广播所有消息:将消息…...
PCA笔记
✅ 问题本质:为什么让矩阵 TT 的行列式为 1? 这个问题通常出现在我们对数据做**线性变换(旋转/缩放)**的时候,比如在 PCA 中把数据从原始坐标系变换到主成分方向时。 📌 回顾一下背景 在 PCA 中ÿ…...
Three.js进阶之粒子系统(一)
一些特定模糊现象,经常使用粒子系统模拟,如火焰、爆炸等。Three.js提供了多种粒子系统,下面介绍粒子系统 一、Sprite粒子系统 使用场景:下雨、下雪、烟花 ce使用代码: var materialnew THRESS.SpriteMaterial();//…...
CSP信奥赛C++常用系统函数汇总
# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout(<iostream>) cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化:ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...

人工智能学习09-变量作用域
人工智能学习概述—快手视频 人工智能学习09-变量作用域—快手视频...