1. 程式人生 > >EOS JAVA RPC呼叫(線上簽名)

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 
版權宣告:本文為博主原創文章,轉載請附上博文連結!