最近公司需要ETH兑换功能,ETH转账需要区块打包,这个时候就需要区块检测,目前只是简单整合,后面会将区块自动检测代码上传致QQ群对于区块链开发不太熟悉的童鞋,可以看看:区块链开发(零)如何开始学习以太坊及区块链欢迎大家加企鹅群一起讨论:260532022首先引入一下依赖pom.xml,主要依赖是 org.web3j
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE
com.xiaobin
eth-demo
0.0.1-SNAPSHOT
eth-demo
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.web3j
core
3.4.0
com.github.briandilley.jsonrpc4j
jsonrpc4j
1.4.6
com.mashape.unirest
unirest-java
1.4.9
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
接下来在application.yml文件中配置以太坊节点路径,这个节点可以使用测试节点
spring:
application:
name: xiaobin-eth-demo
server:
port: 8080
web3j:
client-address: http://localhost:8545
再就是需要将Web3j对象交给Spring进行管理
package com.xiaobin.ethdemo.config;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 创建时间: 2019/9/23 23:21
* 备注:
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@Configuration
public class EthConfig {
@Value("${web3j.client-address}")
private String rpc;
@Bean
public Web3j web3j() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(30*1000, TimeUnit.MILLISECONDS);
builder.writeTimeout(30*1000, TimeUnit.MILLISECONDS);
builder.readTimeout(30*1000, TimeUnit.MILLISECONDS);
OkHttpClient httpClient = builder.build();
Web3j web3j = Web3j.build(new HttpService(rpc,httpClient,false));
return web3j;
}
}
Controller测试一下
package com.xiaobin.ethdemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthBlockNumber;
/**
* 创建时间: 2019/9/23 23:32
* 备注:
* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事
**/
@RestController
@RequestMapping("/eth")
public class WalletController {
@Autowired
private Web3j web3j;
@GetMapping("height")
public long getHeight() {
try {
EthBlockNumber blockNumber = web3j.ethBlockNumber().send();
long blockHeight = blockNumber.getBlockNumber().longValue();
return blockHeight;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
当然还有更多的方法,这里没有去测试了,大家有空可以自己测测哦
public static BigInteger getNonce(Web3j web3j, String addr) {
try {
EthGetTransactionCount getNonce = web3j.ethGetTransactionCount(addr, DefaultBlockParameterName.PENDING).send();
if (getNonce == null){
throw new RuntimeException("net error");
}
return getNonce.getTransactionCount();
} catch (IOException e) {
throw new RuntimeException("net error");
}
}
public static BigInteger getNonce(Web3j web3j, String addr) {
try {
EthGetTransactionCount getNonce = web3j.ethGetTransactionCount(addr, DefaultBlockParameterName.PENDING).send();
if (getNonce == null){
throw new RuntimeException("net error");
}
return getNonce.getTransactionCount();
} catch (IOException e) {
throw new RuntimeException("net error");
}
}
public static BigInteger getTokenBalance(Web3j web3j, String fromAddress, String contractAddress) {
String methodName = "balanceOf";
List inputParameters = new ArrayList<>();
List> outputParameters = new ArrayList<>();
Address address = new Address(fromAddress);
inputParameters.add(address);
TypeReference typeReference = new TypeReference() {
};
outputParameters.add(typeReference);
Function function = new Function(methodName, inputParameters, outputParameters);
String data = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createEthCallTransaction(fromAddress, contractAddress, data);
EthCall ethCall;
BigInteger balanceValue = BigInteger.ZERO;
try {
ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
List results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
balanceValue = (BigInteger) results.get(0).getValue();
} catch (IOException e) {
e.printStackTrace();
}
return balanceValue;
}
public static String transferETH(Web3j web3j, String fromAddr, String privateKey, String toAddr, BigDecimal amount, String data){
// 获得nonce
BigInteger nonce = getNonce(web3j, fromAddr);
// value 转换
BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
// 构建交易
Transaction transaction = Transaction.createEtherTransaction(fromAddr, nonce, gasPrice, null, toAddr, value);
// 计算gasLimit
BigInteger gasLimit = getTransactionGasLimit(web3j, transaction);
// 查询调用者余额,检测余额是否充足
BigDecimal ethBalance = getBalance(web3j, fromAddr);
BigDecimal balance = Convert.toWei(ethBalance, Convert.Unit.ETHER);
// balance < amount gasLimit ??
if (balance.compareTo(amount.add(new BigDecimal(gasLimit.toString()))) < 0) {
throw new RuntimeException("余额不足,请核实");
}
return signAndSend(web3j, nonce, gasPrice, gasLimit, toAddr, value, data, chainId, privateKey);
}
public static String signAndSend(Web3j web3j, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, BigInteger value, String data, byte chainId, String privateKey) {
String txHash = "";
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, value, data);
if (privateKey.startsWith("0x")){
privateKey = privateKey.substring(2);
}
ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
Credentials credentials = Credentials.create(ecKeyPair);
byte[] signMessage;
if (chainId > ChainId.NONE){
signMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
} else {
signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
}
String signData = Numeric.toHexString(signMessage);
if (!"".equals(signData)) {
try {
EthSendTransaction send = web3j.ethSendRawTransaction(signData).send();
txHash = send.getTransactionHash();
System.out.println(JSON.toJSONString(send));
} catch (IOException e) {
throw new RuntimeException("交易异常");
}
}
return txHash;
}
有什么问题或者缺少什么依赖包,可以加QQ群哦