最近研究了下区块链,东西真的挺多的,具体的资料什么的就先不赘述了,主要是说一下java整合web3j的一些常用功能;
首先本地下载geth钱包:
下载地址:Downloads | Go Ethereum,下载之后是个 .exe文件,然后安装就好了,安装之后把geth的安装目录加入到系统环境变量的path里,
验证是否安装成功,打开cmd窗口,输入 geth version 如果出来下面的内容,表示安装好了。
(如果不加任何任何参数直接运行 geth ,会自动连接到以太坊公网,此时会开始同步区块)
详细安装步骤参考:
搭建以太坊私链(单节点,多节点,windows,linux)_hantangduhey的博客-CSDN博客_以太坊私链
接下来开始搭建项目:
JDK:jdk1.8
geth: Geth/v1.4.11-stable/windows/go1.6.2
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
IDE:IDEA
框架:springboot 2.0.5.RELEASE
首先pom.xml:
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot-web3j</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-web3j</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>web3j-spring-boot-starter</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
接下来application.properties
web3j.client-address=http://127.0.0.1:8545/
#web3j.client-address=http://127.0.0.1:8487/
web3j.admin-client=true
web3j.http-timeout-seconds=600
接下来服务层:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.crypto.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.DefaultBlockParameterNumber;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class Web3JService {
private static final Logger LOGGER = LoggerFactory.getLogger(Web3JService.class);
@Autowired
Web3j web3j;
//设置需要的矿工费
private final BigInteger GAS_PRICE = BigInteger.valueOf(1);
private final BigInteger GAS_LIMIT = BigInteger.valueOf(21000L);
/**
* 获取版本号
* @return
*/
public String getVersion(){
try {
String version = web3j.web3ClientVersion().send().getWeb3ClientVersion();
return version;
}catch (Exception e){
e.printStackTrace();
}
return "";
}
/**
* 获取账号列表
* @return
*/
public List<String> getAccounts(){
List<String> result = new ArrayList<>();
try {
result = web3j.ethAccounts().send().getAccounts();
}catch (Exception e){
e.printStackTrace();
}
return result;
}
/**
* 获取账户余额
* @return
*/
public BigDecimal getBalanceById(String id) {
try {
DefaultBlockParameterNumber defaultBlockParameterNumber = new DefaultBlockParameterNumber(web3j.ethBlockNumber().send().getBlockNumber());
EthGetBalance ethGetBalance = web3j.ethGetBalance(id, defaultBlockParameterNumber).send();
if (ethGetBalance != null ) {
BigDecimal banlance = Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER);
return banlance;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 创建钱包
*/
public Map<String,Object> createWallet(String password,HttpServletRequest request){
Bip39Wallet wallet;
Map<String, Object> result = new HashMap<>();
try {
// String filePath = request.getSession().getServletContext().getRealPath("/data/wallet/");
String filePath = "E:/pictures";
File file = new File(filePath); //指定一个目录
String fileName = WalletUtils.generateNewWalletFile(password, file, false);//方法返回创建的钱包文件名
Credentials credentials = WalletUtils.loadCredentials(password,filePath +"/" +fileName );
String returnAddress = credentials.getAddress();
//公钥16进制字符串表示:
String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
//私钥16进制字符串表示:
String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
result.put("address",returnAddress);
result.put("publicKey",publicKey);
result.put("privateKey",privateKey);
result.put("fileName",fileName);
}catch (Exception e){
e.printStackTrace();
System.out.printf("创建以太坊钱包失败");
}
return result;
}
/**
* 转账
* @param pwd 密码
* @param file 账号文件
* @param toAddress 转到的地址
* @param amount 数量
* @return tx
*/
@SuppressWarnings("Since15")
public String transferAccount(String pwd ,File file,String toAddress,String amount){
//交易的哈希值
String transactionHash = new String();
try {
Credentials credentials = WalletUtils.loadCredentials(pwd, file);
//获取发送的地址
String fromAddress = credentials.getAddress();
//获得nonce 从0开始,每笔交易加1,获取最后的nonce
BigInteger nonce = getNonceByFromAddress(fromAddress);
//发送的数量
BigDecimal bigDecimal = Convert.toWei(amount, Convert.Unit.ETHER);
/**
* 正式使用--开始
*/
//创建交易
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, GAS_PRICE,GAS_LIMIT, toAddress,BigInteger.valueOf(bigDecimal.longValue()));//nonce gasprice gas toAddress
//签名Transaction,这里要对交易做签名
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
//获取交易订单号
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
transactionHash = ethSendTransaction.getTransactionHash();
}catch (Exception e){
e.printStackTrace();
}
return transactionHash;
}
/**
* 根据tx值查询交易信息
* @param tx 0xb6bfc5374a62cbad558eb16a209b43b9a3b0f9dd55cd26349d9682cf4fb2af2a
*/
@SuppressWarnings("Since15")
public Map<String, Object> getTxInfo(String tx){
org.web3j.protocol.core.methods.response.Transaction transaction = null;
Map<String, Object> result = new HashMap<>();
try {
if(web3j.ethGetTransactionByHash(tx).sendAsync() != null){
if(web3j.ethGetTransactionByHash(tx).sendAsync().get().getTransaction() != null){
org.web3j.protocol.core.methods.response.Transaction transaction1 = web3j.ethGetTransactionByHash(tx).sendAsync().get().getTransaction().get();
if(transaction1 !=null){
transaction =transaction1;
}
}
}
if(transaction != null){
String to = transaction.getTo();
String from = transaction.getFrom();
BigInteger value = transaction.getValue();
int v = transaction.getV();
String creates = transaction.getCreates();
BigInteger gas = transaction.getGas();
BigInteger gasPrice = transaction.getGasPrice();
BigInteger nonce = transaction.getNonce();
String blockNumber = transaction.getBlockNumber().toString();
String s = transaction.getS();
String blockNumberRaw = transaction.getBlockNumberRaw();
String hash = transaction.getHash();
String input = transaction.getInput();
byte[] bytes = Numeric.hexStringToByteArray(input);
String inputStr = new String(bytes);
result.put("to",to);
result.put("from",from);
result.put("value",value);
result.put("v",v);
result.put("nonce",nonce);
result.put("creates",creates);
result.put("blockNumber",blockNumber);
result.put("gas",gas);
result.put("gasPrice",gasPrice);
result.put("s",s);
result.put("blockNumberRaw",blockNumberRaw);
result.put("hash",hash);
result.put("input",inputStr);
}
}catch (Exception e){
e.printStackTrace();
}
return result ;
}
/**
* 获取nonce
* @param address
* @return
*/
public BigInteger getNonceByFromAddress(String address){
try{
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(address,DefaultBlockParameterName.LATEST).sendAsync().get();
return ethGetTransactionCount.getTransactionCount();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
后续发布基于nodejs的web3开发