Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yangjianyao committed Mar 31, 2020
0 parents commit e6b40f7
Show file tree
Hide file tree
Showing 186 changed files with 49,381 additions and 0 deletions.
141 changes: 141 additions & 0 deletions bitcoin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ztuo.bc.wallet</groupId>
<artifactId>wallet-rpc</artifactId>
<version>1.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bitcoin</artifactId>
<version>${project-version}</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.ztuo.bc.wallet</groupId>
<artifactId>btc-support</artifactId>
</dependency>
</dependencies>
<!-- <build>-->
<!-- <finalName>${project.artifactId}-${version}</finalName>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <artifactId>maven-surefire-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <skip>true</skip>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<build>
<finalName>bitcoin</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- spring boot thin jar configuration -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- main 入口 -->
<mainClass>com.ztuo.bc.wallet.WalletBtcApplication</mainClass>
<!-- 设置为ZIP,此模式下spring-boot-maven-plugin会将Manifest.MF文件中的Main-Class设置为org.springframework.boot.loader.PropertiesLauncher -->
<layout>ZIP</layout>
<outputDirectory>${user.dir}/target</outputDirectory>
<!-- 需要包含的jar包 -->
<includes>
<include>
<groupId>com.ztuo.bc.wallet</groupId>
<artifactId>rpc-common</artifactId>
</include>
<include>
<groupId>com.ztuo.bc.wallet</groupId>
<artifactId>btc-support</artifactId>
</include>
<include>
<groupId>com.ztuo.bc.wallet</groupId>
<artifactId>wallet-mbg</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- third-party jar into lib directory -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<!-- 需要排除的jar的 groupId -->
<excludeGroupIds>
com.ztuo.bc
</excludeGroupIds>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
17 changes: 17 additions & 0 deletions bitcoin/src/main/java/com/ztuo/bc/wallet/WalletBtcApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.ztuo.bc.wallet;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.scheduling.annotation.EnableScheduling;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableEurekaClient
@EnableSwagger2
@SpringBootApplication
@EnableScheduling
public class WalletBtcApplication {
public static void main(String[] args){
SpringApplication.run(WalletBtcApplication.class,args);
}
}
146 changes: 146 additions & 0 deletions bitcoin/src/main/java/com/ztuo/bc/wallet/component/BitcoinWatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.ztuo.bc.wallet.component;

import com.alibaba.fastjson.JSON;
import com.spark.blockchain.rpcclient.Bitcoin;
import com.ztuo.bc.wallet.constants.SystemId;
import com.ztuo.bc.wallet.entity.Coin;
import com.ztuo.bc.wallet.entity.Deposit;
import com.ztuo.bc.wallet.mapper.BlockRecordBtcMapper;
import com.ztuo.bc.wallet.mapperextend.AddressBtcMapperExtend;
import com.ztuo.bc.wallet.model.BlockRecordBtc;
import com.ztuo.bc.wallet.service.BitcoinRPCClientExtend;
import com.ztuo.bc.wallet.service.BitcoinUtilExtend;
import com.ztuo.bc.wallet.service.TxidService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

@Component
public class BitcoinWatcher extends Watcher {
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private BitcoinRPCClientExtend rpcClient;
@Autowired
private AddressBtcMapperExtend addressBtcMapper;
@Autowired
private BlockRecordBtcMapper blockRecordBtcMapper;
@Autowired
private BitcoinUtilExtend bitcoinUtil;
@Autowired
private Coin coin;
private Logger logger = LoggerFactory.getLogger(BitcoinWatcher.class);

@Override
public List<Deposit> replayBlock(Long startBlockNumber, Long endBlockNumber) {
List<Deposit> deposits = new ArrayList<Deposit>();
Set<String> needUpdateAddresses = new HashSet<>();
try {
//查询数据库地址池
List<String> allAddress = this.addressBtcMapper.getAllAddress();
for (Long blockHeight = startBlockNumber; blockHeight <= endBlockNumber; blockHeight++) {
logger.info("开始查看:" + blockHeight);
String blockHash = rpcClient.getBlockHash(blockHeight.intValue());
//获取区块
Bitcoin.Block block = rpcClient.getBlock(blockHash);
// Bitcoin.Block block = rpcClient.getBlock("000000000000021c0b38de03d2936ffb8a9b2fe036c6643d8badcd64d5fdc7ba");
List<String> txids = block.tx();
// logger.info(blockHeight + "区块内txid:" + JSON.stringify(txids));
//遍历区块中的交易
for (String txid : txids) {
Bitcoin.RawTransaction transaction = rpcClient.getRawTransaction(txid);
// Object getblock = rpcClient.query("getblock", "000000000000021c0b38de03d2936ffb8a9b2fe036c6643d8badcd64d5fdc7ba", 2);
//遍历vOut
List<Bitcoin.RawTransaction.Out> outs = transaction.vOut();
for (Bitcoin.RawTransaction.Out out : outs) {
if (out.scriptPubKey() != null && out.scriptPubKey().addresses() != null) {
String outAddress = out.scriptPubKey().addresses().get(0);
if (outAddress != null && allAddress.contains(outAddress)) {
// if (outAddress != null && !allAddress.contains(outAddress)) {
//发送链上余额变动信息到kafka
Deposit deposit = new Deposit();
deposit.setTxid(transaction.txId());
deposit.setBlockHeight((long) block.height());
deposit.setBlockHash(transaction.blockHash());
BigDecimal amount = BigDecimal.valueOf(out.value());
deposit.setAmount(amount);
deposit.setAddress(outAddress);
deposit.setTime(transaction.time());
//如果是找零则不发送kafka消息
// if (!chargeAddress.equals(outAddress)&&coin.getMinSpentAmount().compareTo(amount)<0&&!txidService.isTxIdExist(deposit.getTxid())) {
if (coin.getMinSpentAmount().compareTo(amount)<0) {
deposits.add(deposit);
}
logger.info("BTC本系统交易数据:" + JSON.toJSONString(deposit));
//生成用户余额表需更新list
needUpdateAddresses.add(outAddress);
//插入扫描记录
this.insertBlockRecord((long) block.height(),transaction,outAddress,amount,false);
}
}
}
//遍历vIn
// List<Bitcoin.RawTransaction.In> ins = transaction.vIn();
// for (Bitcoin.RawTransaction.In in : ins) {
// // 为空说明该交易是铸币交易,区块奖励,结束本次循环
// if (in.txid()!=null&&in.getTransactionOutput() != null
// && in.getTransactionOutput().scriptPubKey() != null
// && in.getTransactionOutput().scriptPubKey().addresses() != null) {
// String inAddress = in.getTransactionOutput().scriptPubKey().addresses().get(0);
// if (inAddress != null && allAddress.contains(inAddress)) {
// needUpdateAddresses.add(inAddress);
// //插入扫描记录
// this.insertBlockRecord((long) block.height(),transaction,inAddress,new BigDecimal(in.getTransactionOutput().value()),true);
// }
// }
// }
}
}
//更新余额表
logger.info("需更新的余额地址列表为:" + needUpdateAddresses.toString());
for (String address : needUpdateAddresses) {
this.bitcoinUtil.syncAddressBalance(address);
}
} catch (Exception e) {
e.printStackTrace();
}
return deposits;
}

/*插入区块扫描记录*/
public void insertBlockRecord(Long height,Bitcoin.RawTransaction transaction, String address, BigDecimal amount, Boolean isInt) {
BlockRecordBtc blockRecordBtc = new BlockRecordBtc();
blockRecordBtc.setBlockHash(transaction.blockHash());
blockRecordBtc.setBlockHeight(height.toString());
blockRecordBtc.setCreateTime(new Date());
blockRecordBtc.setTxid(transaction.txId());
blockRecordBtc.setCurrency(coin.getName());
blockRecordBtc.setAmount(amount);
if (isInt) {
blockRecordBtc.setFromAddress(address);
} else {
blockRecordBtc.setToAddress(address);
}
blockRecordBtc.setSysId(SystemId.APP.getName());
blockRecordBtc.setStatus("0");
this.blockRecordBtcMapper.insert(blockRecordBtc);
}

@Override
public Long getNetworkBlockHeight() {
try {
return Long.valueOf(rpcClient.getBlockCount());
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.ztuo.bc.wallet.config;

import com.spark.blockchain.rpcclient.BitcoinException;
import com.ztuo.bc.wallet.service.BitcoinRPCClientExtend;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.MalformedURLException;

/**
* 初始化RPC客户端
*/
@Configuration
public class RpcClientConfig {
private Logger logger = LoggerFactory.getLogger(RpcClientConfig.class);


@Bean
public BitcoinRPCClientExtend setClient(@Value("${coin.rpc}") String uri){
try {
logger.info("uri={}",uri);
BitcoinRPCClientExtend client = new BitcoinRPCClientExtend(uri);
int blockCount = client.getBlockCount();
logger.info("blockHeight={}",blockCount);
return client;
} catch (MalformedURLException e) {
logger.info("init wallet failed");
e.printStackTrace();
return null;
} catch (BitcoinException e) {
logger.info("BitcoinException");
e.printStackTrace();
return null;
}
}
@Bean
public NetworkParameters setParameters(@Value("${rpc.environment.istest}") String isTest){
try {
logger.info("isTest={}",isTest);
NetworkParameters parameters = "true".equals(isTest) ? TestNet3Params.get() : MainNetParams.get();
return parameters;
} catch (Exception e) {
logger.info("init parameters failed");
e.printStackTrace();
return null;
}
}
}
Loading

0 comments on commit e6b40f7

Please sign in to comment.