EOS JAVA RPC呼叫(線上簽名)
開發前看一下EOS白皮書最好,先了解EOS的架構及相關歷程。有助於後續的開發。本地安裝個EOS,試一試命令。博主本人是隻本地啟動錢包wallet,其它api呼叫其它節點提供的介面。(本篇文章需要本地啟動一個錢包服務keosd或者eosio. 最新一篇文章採用離線簽名無需啟動服務https://blog.csdn.net/liu1765686161/article/details/83308819)
EOS測試網路https://tools.cryptokylin.io
1,首選需要下載eos.java.rpc.wrapper-1.0-SNAPSHOT.jar包
https://download.csdn.net/download/liu1765686161/10767940
或者檢視原始碼 https://github.com/EOSEssentials/eos-java-rpc-wrapper
2,加入專案工程 maven的話有可能需要額外加入依賴
<dependency>
<groupId>com.github-eos</groupId>
<artifactId>eos-java-rpc-wrapper</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-jackson</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.4</version>
</dependency>
3,開始呼叫
package com.tn.web.service.coin;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.tn.base.Log;
import com.tn.constant.CoinConstant;
import com.tn.util.BigDecimalUtil;
import com.tn.util.DateUtil;
import com.tn.util.JsonUtil;
import client.EosApiClientFactory;
import client.EosApiRestClient;
import client.domain.common.ActionTrace;
import client.domain.common.transaction.PackedTransaction;
import client.domain.common.transaction.SignedPackedTransaction;
import client.domain.common.transaction.TransactionAction;
import client.domain.common.transaction.TransactionAuthorization;
import client.domain.response.chain.AbiJsonToBin;
import client.domain.response.chain.Block;
import client.domain.response.chain.ChainInfo;
import client.domain.response.chain.transaction.PushedTransaction;
import client.domain.response.history.action.Action;
import client.domain.response.history.action.Actions;
/**
* eos操作
* @author xhl
* @create 2017/10/27
**/
@Service
public class CoinEosService {
private Logger log = Log.get();
private String walletUrl = "";//本地啟動的wallet
//正式網路https://api-v2.eosasia.one
private String chainUrl = "https://api-kylin.eosasia.one";//測試網路
//建議用active賬戶
private String ownerAccount = "";
private String ownerAccountPublicKey = "";
private String walletName = "";//建立的錢包名
private String walletPassword = "";//錢包密碼
private static final String EOS_TOKEN = "eosio.token";
private static final String ACTION_TRANSFER = "transfer";
EosApiRestClient eosApiRestClient = null;
@PostConstruct
public void init(){
this.eosApiRestClient = EosApiClientFactory.newInstance(walletUrl,
chainUrl, chainUrl).newRestClient();
}
/**
* 獲取賬戶交易資訊
* index 查詢到第幾條記錄
**/
public boolean getActions(int index){
try {
//account賬戶,index:查詢到第幾條記錄,offset:每次查詢幾條資料 從0開始
Actions actions = eosRpcService.getActions(account, index,0);
if (actions != null) {
List<Action> list = actions.getActions();
if (list==null || list.size() == 0) {
return false;
}
//不可變更區塊高度
int lastIrreversibleBlock = actions.getLastIrreversibleBlock();
//每次處理一條資料,不需要去重
//list = this.removeDuplicate(list);
for (Action action : list) {
ActionTrace actionTrace = action.getActionTrace();
String account = actionTrace.getAct().getAccount();
if (!EOS_TOKEN.equals(account)) {
log.info("非EOS交易記錄:{}",account);
return true;
}
if (action.getBlockNum() > lastIrreversibleBlock) {
log.info("未確認交易:{}",account);
return false;
}
String name = actionTrace.getAct().getName();
if (!ACTION_TRANSFER.equals(name)) {
log.info("非EOS轉賬交易記錄:{}",account);
return true;
}
//{from=eosqxyx11111, to=eosqxyx22222, quantity=10.0000 EOS, memo=test}
log.info("交易詳情:{}",actionTrace.getAct().getData().toString());
JSONObject json = JSONObject.parseObject(JsonUtil.getSting(actionTrace.getAct().getData()));
if (!account.equals(json.getString("to"))) {
log.info("非充值記錄:{}",actionTrace.getTrxId());
return true;
}
String[] quantity = json.getString("quantity").split(" ");
if (!CoinConstant.COIN_EOS.equals(quantity[1])) {
log.info("非EOS充值記錄:{}",json.getString("quantity"));
return true;
}
String memo = json.getString("memo");
if (StringUtils.isEmpty(memo)) {
log.info("記錄memo為空");
return true;
}
//判斷是否存在使用者,並新增充值記錄
/*UserEntity user = userService.getUserById(Integer.parseInt(memo));
if (user == null) {
log.info("使用者資訊不存在:memo:{}",memo);
return true;
}
record.setUserId(user.getUserId());
rechargeParse(record);*/
return true;
}
}
} catch (Exception e1) {
e1.printStackTrace();
log.error("獲取使用者交易記錄失敗:{}",e1.getMessage());
}
return false;
}
/**
* 去重
* @param list
* @return
*/
public List<Action> removeDuplicate(List<Action> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).getActionTrace().getTrxId()
.equals(list.get(i).getActionTrace().getTrxId())) {
list.remove(j);
}
}
}
return list;
}
public String getAddress(){
return ownerAccount;
}
public double getBalance(){
List<String> list = eosApiRestClient.getCurrencyBalance(EOS_TOKEN, ownerAccount, "EOS");
if (list != null && list.size() > 0) {
return Double.parseDouble(list.get(0).replaceAll(" EOS", ""));
}
return 0.00;
}
public String getJsonToBin(String from, String to, Double amount, String memo){
Map<String, String> args = new HashMap<>(4);
args.put("from", from);
args.put("to", to);
//amount 必須要保留4位小數,不夠補0
args.put("quantity", BigDecimalUtil.getFourString(amount)+" EOS");
args.put("memo", memo);
AbiJsonToBin data = eosApiRestClient.abiJsonToBin(EOS_TOKEN, "transfer", args);
if (data != null) {
return data.getBinargs();
}
return null;
}
/**
* 傳送交易
* @param fromAccount
* @param toAccount
* @param amount 保留4位小數點
* @param memo
* @return
*/
public String send(String toAccount,double amount,String memo){
String binargs = this.getJsonToBin(ownerAccount, toAccount, amount, memo);
ChainInfo chainInfo = eosApiRestClient.getChainInfo();
Block block = eosApiRestClient.getBlock(chainInfo.getHeadBlockId());
TransactionAuthorization transactionAuthorization = new TransactionAuthorization();
transactionAuthorization.setActor(ownerAccount);
//傳送者許可權等級 這一步要注意賬戶和許可權要對應上
//transactionAuthorization.setPermission("owner");
transactionAuthorization.setPermission("active");
TransactionAction transactionAction = new TransactionAction();
transactionAction.setAccount(EOS_TOKEN);
transactionAction.setName(ACTION_TRANSFER);
transactionAction.setData(binargs);
transactionAction.setAuthorization(Collections.singletonList(transactionAuthorization));
//設定交易期限
Date date = DateUtil.getStringToDate(block.getTimeStamp(),"yyyy-MM-dd'T'HH:mm:ss");
date = DateUtil.addMin(date, 1);
String exPiration = DateUtil.dateToString(date,"yyyy-MM-dd'T'HH:mm:ss");
PackedTransaction packedTransaction = new PackedTransaction();
packedTransaction.setRefBlockPrefix(block.getRefBlockPrefix().toString());
packedTransaction.setRefBlockNum(block.getBlockNum().toString());
packedTransaction.setExpiration(exPiration);
packedTransaction.setRegion("0");
packedTransaction.setMax_net_usage_words("0");
packedTransaction.setActions(Collections.singletonList(transactionAction));
//開啟錢包
eosApiRestClient.openWallet(walletName);
//解鎖錢包
eosApiRestClient.unlockWallet(walletName, walletPassword);
SignedPackedTransaction signedPackedTransaction = eosApiRestClient.signTransaction(packedTransaction,
Collections.singletonList(ownerAccountPublicKey), chainInfo.getChainId());
PushedTransaction pushedTransaction= eosApiRestClient.pushTransaction("none", signedPackedTransaction);
if (pushedTransaction != null) {
log.info("EOS轉賬成功:transactionId:{}",pushedTransaction.getTransactionId());
return pushedTransaction.getTransactionId();
}else {
log.info("EOS轉賬失敗");
}
return null;
}
}
4,定時任務 獲取使用者交易記錄 來確認使用者充值 這是我的示例。具體可以根據自己業務來
/**
* EOS處理
*/
private void eosJob(){
//代表的是賬戶記錄處理到第幾條,不是區塊高度
Integer eosIndex = coinParseService.getBlockHeight("EOS");
log.info("EOS當前處理記錄數:{}",eosIndex);
if (coinEosService.getActions(eosIndex)) {
log.info("eos執行完畢");
eosIndex += 1;
//更新處理進度
coinParseService.updateBlockRecord("EOS", reIndex);
}
}
希望能幫到大家,歡迎大家一起分享。
---------------------
作者:其修遠兮
來源:CSDN
原文:https://blog.csdn.net/liu1765686161/article/details/82180070
版權宣告:本文為博主原創文章,轉載請附上博文連結!