最近公司須要ETH兌換功能,ETH轉帳須要區塊打包,這個時候就須要區塊檢測,目前只是簡單整合,後面會將區塊自動檢測代碼上傳致QQ羣對於區塊鏈開發不太熟悉的童鞋,能夠看看:區塊鏈開發(零)如何開始學習以太坊及區塊鏈歡迎你們加企鵝羣一塊兒討論:260532022首先引入一下依賴pom.xml,主要依賴是 org.web3jjava
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xiaobin</groupId>
<artifactId>eth-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eth-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<version>1.4.6</version>
</dependency>
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>複製代碼
接下來在application.yml文件中配置以太坊節點路徑,這個節點能夠使用測試節點git
spring:
application:
name: xiaobin-eth-demo
server:
port: 8080
web3j:
client-address: http://localhost:8545複製代碼
再就是須要將Web3j對象交給Spring進行管理github
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測試一下web
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;
}
}複製代碼
獲取當前以太坊節點高度,訪問結果圖spring
固然還有更多的方法,這裏沒有去測試了,你們有空能夠本身測測哦apache
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<Type> inputParameters = new ArrayList<>();
List<TypeReference<?>> outputParameters = new ArrayList<>();
Address address = new Address(fromAddress);
inputParameters.add(address);
TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
};
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<Type> 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羣哦json