package com.nwnu.syh.service;
import com.alibaba.fastjson.JSON;
import com.nwnu.syh.bean.*;
import com.nwnu.syh.p2p.Message;
import com.nwnu.syh.p2p.P2PService;
import com.nwnu.syh.security.CryptoUtil;
import java.util.*;
/**
* @description: 使用单例模式创建
* @author: 司云航
* @create: 2020-04-02 17:36
*/
public class BlockService {
private static BlockService blockService = new BlockService();
private static P2PService p2pService = P2PService.getInstance();
/**
* 区块链存储结构
*/
private List<Block> blockChain = new ArrayList<>();
/**
* 当前节点钱包集合
*/
private Map<String, Wallet> myWalletMap = new HashMap<>();
/**
* 其他节点钱包集合,钱包只包含公钥
*/
private Map<String, Wallet> otherWalletMap = new HashMap<>();
/**
* 转账交易集合
*/
private List<Transaction> allTransactions = new ArrayList<>();
/**
* 已打包转账交易
*/
private List<Transaction> packedTransactions = new ArrayList<>();
private BlockService(){
int nonce = (int)Math.random()*1000+1;
String firstHash = calculateHash("Chancellor on brink of second bailout for banks"+System.currentTimeMillis(),null,nonce);
// 新建创始区块
Block genesisBlock = new Block(1, System.currentTimeMillis(), firstHash, "Chancellor on brink of second bailout for banks", new ArrayList<Transaction>(), nonce);
blockChain.add(genesisBlock);
System.out.println("生成创始区块:" + JSON.toJSONString(genesisBlock));
}
public static BlockService getInstance(){
return blockService;
}
public List<Block> getBlockChain() {
return blockChain;
}
public void setBlockChain(List<Block> blockChain) {
this.blockChain = blockChain;
}
public Map<String, Wallet> getMyWalletMap() {
return myWalletMap;
}
public void setMyWalletMap(Map<String, Wallet> myWalletMap) {
this.myWalletMap = myWalletMap;
}
public Map<String, Wallet> getOtherWalletMap() {
return otherWalletMap;
}
public void setOtherWalletMap(Map<String, Wallet> otherWalletMap) {
this.otherWalletMap = otherWalletMap;
}
public List<Transaction> getAllTransactions() {
return allTransactions;
}
public void setAllTransactions(List<Transaction> allTransactions) {
this.allTransactions = allTransactions;
}
public List<Transaction> getPackedTransactions() {
return packedTransactions;
}
public void setPackedTransactions(List<Transaction> packedTransactions) {
this.packedTransactions = packedTransactions;
}
/**
* 获取最后一个区块
* @return
*/
public Block getLastBlock(){
return blockChain.size() > 0 ? blockChain.get(blockChain.size()-1) : null;
}
public boolean addBlock(Block newBlock){
if (isValidNewBlock(newBlock, getLastBlock())){
blockChain.add(newBlock);
// 新区块的交易要加入已打包交易中
packedTransactions.addAll(newBlock.getTransactions());
// 所有交易中加入系统交易
newBlock.getTransactions().forEach(tx -> {
if (tx.coinbaseTx()){
allTransactions.add(tx);
}
});
return true;
}
return false;
}
/**
* 验证新区块是否有效
* @param newBlock
* @param previousBlock
* @return
*/
public boolean isValidNewBlock(Block newBlock, Block previousBlock){
if (!previousBlock.getHash().equals(newBlock.getPreviousHash())){
System.out.println("新区块的前一个区块hash验证不通过");
}else{
// 验证新区块hash值得正确性
String hash = calculateHash(newBlock.getPreviousHash(), newBlock.getTransactions(), newBlock.getNonce());
if (!hash.equals(newBlock.getHash())){
System.out.println("新区块的hash值无效:" + hash + " " + newBlock.getHash());
return false;
}
if (!isValidHash(newBlock.getHash())){
return false;
}
}
return true;
}
/**
* 找零时应该再改动一下
* 查找未花费交易
* @param address
* @return
*/
public List<Transaction> findUnspentTransactions(String address){
List<Transaction> unspentTxs = new ArrayList<>();
// 只添加交易id
Set<String> spentTxs = new HashSet<>();
// 查找已花费的UTXO,使用allTransactions考虑未打包交易
for (Transaction tx : allTransactions){
if (tx.coinbaseTx()){
continue;
}
// 自己的公钥和发送者的公钥做对比,相等则说明该笔交易属于自己花费的
if (address.equals(Wallet.getAddress(tx.getTxIn().getPublicKey()))){
spentTxs.add(tx.getTxIn().getTxId());
}
}
// 查找未花费的UTXO
for (Block block : blockChain){
List<Transaction> transactions = block.getTransactions();
for (Transaction tx: transactions
) {
// 如果是别人发送给他的交易
if (address.equals(CryptoUtil.getMD5(tx.getTxOut().getPublicKeyHash()))){
// 如果该交易花费了则不添加
if (!spentTxs.contains(tx.getId())){
unspentTxs.add(tx);
}
}
}
}
return unspentTxs;
}
/**
* 创建交易
* @param senderWallet
* @param recipientWallet
* @param amount
* @return
*/
public Transaction createTransaction(Wallet senderWallet, Wallet recipientWallet, int amount){
List<Transaction> unspentTxs = findUnspentTransactions(senderWallet.getAddress());
// 引用的UTXO
Transaction prevTx = null;
for (Transaction transaction : unspentTxs){
// TODO 找零
if (transaction.getTxOut().getValue() == amount){
prevTx = transaction;
break;
}
}
if (prevTx == null){
return null;
}
TransactionInput txIn = new TransactionInput(prevTx.getId(), amount, null, senderWallet.getPublicKey());
TransactionOutput txOut = new TransactionOutput(amount, recipientWallet.getHashPubKey());
Transaction transaction = new Transaction(CryptoUtil.UUID(), txIn, txOut);
transaction.sign(senderWallet.getPrivateKey(), prevTx);
allTransactions.add(transaction);
return transaction;
}
public Block mine(String toAddress){
// 创建系统奖励的交易
Transaction sysTx = newCoinbaseTx(toAddress);
// allTransactions.add(sysTx);
// 对所有交易进行一个复制
List<Transaction> blockTxs = new ArrayList<>(allTransactions);
blockTxs.add(sysTx);
// 去除已打包进区块的交易
blockTxs.removeAll(packedTransactions);
// 验证所有未打包交易
verifyAllTransaction(blockTxs);
String newBlockHash = "";
int nonce = 0;
long start = System.currentTimeMillis();
System.out.println("开始挖矿");
while (true){
// 计算区块hash值
newBlockHash = calculateHash(getLastBlock().getHash(), blockTxs, nonce);
// 检验hash
if (isValidHash(newBlockHash)){
System.out.println("挖矿成功,正确的hash值:" + newBlockHash);
System.out.println("挖矿耗费时间:" + (System.currentTimeMillis() - start) + "ms");
break;
}
nonce++;
}
// 创建新的区块,新区块验证
没有合适的资源?快使用搜索试试~ 我知道了~
java毕业设计基于SpringBoot+WebSocket+RSA的仿比特币点对点交易系统源码+使用文档+全部资料(优秀项目)
共29个文件
java:19个
properties:2个
zip:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 138 浏览量
2024-04-19
08:25:45
上传
评论
收藏 77KB ZIP 举报
温馨提示
【资源说明】 java毕业设计基于SpringBoot+WebSocket+RSA的仿比特币点对点交易系统源码+使用文档+全部资料(优秀项目)java毕业设计基于SpringBoot+WebSocket+RSA的仿比特币点对点交易系统源码+使用文档+全部资料(优秀项目)java毕业设计基于SpringBoot+WebSocket+RSA的仿比特币点对点交易系统源码+使用文档+全部资料(优秀项目) 【备注】 1、该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过mac/window10/11测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
资源推荐
资源详情
资源评论
收起资源包目录
java毕业设计 基于SpringBoot+WebSocket+RSA的仿比特币点对点交易系统源码+使用文档+全部资料(优秀项目).zip (29个子文件)
BTC-master
mvnw.cmd 6KB
pom.xml 3KB
src
test
java
com
nwnu
syh
SyhApplicationTests.java 210B
main
resources
log4j.properties 566B
application.yml 23B
java
com
nwnu
syh
security
CryptoUtil.java 2KB
RSACoder.java 6KB
controller
TestController.java 533B
ChainServlet.java 2KB
WalletServlet.java 2KB
TransactionServlet.java 3KB
service
BlockService.java 13KB
SyhApplication.java 723B
p2p
Message.java 871B
P2PServer.java 2KB
P2PClient.java 4KB
P2PService.java 11KB
bean
Transaction.java 4KB
Block.java 1KB
Wallet.java 2KB
TransactionInput.java 2KB
TransactionOutput.java 1KB
.mvn
wrapper
maven-wrapper.properties 218B
maven-wrapper.jar 50KB
MavenWrapperDownloader.java 5KB
logContentFile.log 0B
mvnw 10KB
.gitignore 333B
171265889347208773632.zip 416B
共 29 条
- 1
资源评论
不走小道
- 粉丝: 3322
- 资源: 5061
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功