这篇文章使用xrp测试环境实现以下功能:
1.xrp离线签名交易;
2.xrp充值;
3.xrp生成秘钥对(要自己搭建xrp节点,测试网无法调用生成秘钥对的方法);
4.xrp查询余额
1.maven
首先要下载:ripple-bouncycastle和ripple-core两个jar包,导入本地仓库。
可以到github下载编译
或者,直接下载
com.ripple
ripple-bouncycastle
1.0.0
com.ripple
ripple-core
1.0.0
2.代码:
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import com.warrior.utils.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ripple.core.coretypes.AccountID;
import com.ripple.core.coretypes.Amount;
import com.ripple.core.coretypes.uint.UInt32;
import com.ripple.core.types.known.tx.signed.SignedTransaction;
import com.ripple.core.types.known.tx.txns.Payment;
public class XrpApi {
private static Logger logger = LoggerFactory.getLogger(XrpApi.class);
private String postUrl = "https://s.altnet.rippletest.net:51234";
private final static String RESULT = "result";
private final static String SUCCESS = "success";
private final static String TES_SUCCESS = "tesSUCCESS";
private final static String METHOD_POST_ACCOUNT_INFO = "account_info";
private final static String METHOD_POST_SUBMIT = "submit";
public XrpApi() {
}
public XrpApi(String postUrl) {
this.postUrl = postUrl;
}
/**
* 广播交易
*
* @return
*/
public String pushTx(String sign) throws Exception {
if (StringUtils.isEmpty(sign)) {
logger.error("签名失败:{}");
return null;
}
HashMap params = new HashMap();
params.put("tx_blob", sign);
//签名
JSONObject json = doRequest(METHOD_POST_SUBMIT, params);
if (!isError(json)) {
JSONObject result = json.getJSONObject(RESULT);
if (result != null) {
String engine_result = result.getString("engine_result");
String engine_result_message = result.getString("engine_result_message");
if (TES_SUCCESS.equals(engine_result)) {
String hash = result.getJSONObject("tx_json").getString("hash");
if (!StringUtils.isEmpty(hash)) {
logger.info("转账成功:hash:{}", hash);
return hash;
} else {
logger.error("转账失败:hash:{}", hash);
}
} else {
throw new Exception(engine_result_message);
}
}
}
return null;
}
/**
* 签名
*
* @param value
* @return tx_blob
*/
public String sign(String fromAddress, String privateKey, String toAddress, Long value, Long fee, String memo) {
Map map = getAccountInfo(fromAddress);
Payment payment = new Payment();
payment.as(AccountID.Account, fromAddress);
payment.as(AccountID.Destination, toAddress);
payment.as(UInt32.DestinationTag, memo);
payment.as(Amount.Amount, value.toString());
payment.as(UInt32.Sequence, map.get("accountSequence"));
payment.as(UInt32.LastLedgerSequence, map.get("ledgerCurrentIndex") + 4);
payment.as(Amount.Fee, fee.toString());
SignedTransaction signed = payment.sign(privateKey);
if (signed != null) {
return signed.tx_blob;
}
return null;
}
public Map getAccountInfo(String account) {
HashMap params = new HashMap();
params.put("account", account);
params.put("strict", "true");
params.put("ledger_index", "current");
params.put("queue", "true");
JSONObject re = doRequest(METHOD_POST_ACCOUNT_INFO, params);
if (re != null) {
JSONObject result = re.getJSONObject("result");
if (SUCCESS.equals(result.getString("status"))) {
Map map = new HashMap();
map.put("accountSequence", result.getJSONObject("account_data").getString("Sequence"));
map.put("balance", result.getJSONObject("account_data").getString("Balance"));
map.put("ledgerCurrentIndex", result.getString("ledger_current_index"));
return map;
}
}
return null;
}
private boolean isError(JSONObject json) {
if (json == null || (!StringUtils.isEmpty(json.getString("error")) && json.get("error") != "null")) {
return true;
}
return false;
}
private JSONObject doRequest(String method, Object... params) {
JSONObject param = new JSONObject();
param.put("id", System.currentTimeMillis() + "");
param.put("jsonrpc", "2.0");
param.put("method", method);
if (params != null) {
param.put("params", params);
}
/* String creb = Base64.encodeBase64String((address+":"+password).getBytes());
Map headers = new HashMap<>(2);
headers.put("Authorization","Basic "+creb);*/
String resp = "";
try {
resp = HttpUtil.jsonPost(postUrl, param.toJSONString());
} catch (Exception e) {
logger.info(e.getMessage());
if (e instanceof IOException) {
resp = "{}";
}
}
logger.info(resp);
return JSON.parseObject(resp);
}
/**
* 充值
*
* @param accounts
*/
public void recharge(List accounts) {
for (String account : accounts) {
JSONObject jsonObject = account_tx(account);
System.out.println(jsonObject);
JSONObject resultJson = jsonObject.getJSONObject("result");
if (resultJson == null) {
continue;
}
JSONArray jsonArray = resultJson.getJSONArray("transactions");
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject transaction = (JSONObject) jsonArray.get(i);
JSONObject txJson = transaction.getJSONObject("tx");
Object validated = transaction.get("validated");
String from = txJson.get("Account").toString();
String to = txJson.get("Destination").toString();
String transactionType = txJson.get("TransactionType").toString();
String amount = txJson.get("Amount").toString();
String fee = txJson.get("Fee").toString();
Object destinationTag = txJson.get("DestinationTag");
String hash = txJson.get("hash").toString();
logger.info("from:{},to:{},amount:{},hash:{},destinationTag:{}", from, to, amount, hash, destinationTag);
}
}
}
public JSONObject account_tx(String account) {
HashMap params = new HashMap();
params.put("account", account);
params.put("binary", false);
params.put("forward", false);//false代表获取最新的
params.put("ledger_index_max", -1);
params.put("ledger_index_min", -1);
params.put("limit", 100);
params.put("marker", 15725839);
return doRequest("account_tx", params);
}
public BigDecimal unitToMax(Long number) {
return new BigDecimal(number).divide(BigDecimal.valueOf(1000000), 6, BigDecimal.ROUND_HALF_UP);
}
public Long unitToMini(BigDecimal number) {
return number.multiply(BigDecimal.valueOf(1000000)).setScale(6, BigDecimal.ROUND_HALF_UP).longValue();
}
//创建秘钥对
public void createKey() {
JSONObject jsonObject = doRequest("wallet_propose", new HashMap<>());
System.out.println(jsonObject);
}
//=========================
public static void main(String[] args) {
XrpApi xrpApi = new XrpApi("https://s.altnet.rippletest.net:51234");
//1.转账
/* String fromAddress = "rfbg6ozE1Mak8iH8H54ovVVXBCprSxm4zE";
String fromPrivateKey = "snqxtNkDrzw8Zf8nGu6B3DdQXJgfD";
String toAddress = "rDsd6zh5xArehnq9RNZETTpSr3MFJ39eqL";
BigDecimal amount = BigDecimal.valueOf(10000);
BigDecimal fee = BigDecimal.valueOf(0.0001);
String memo = "123456";//只能是数值
String sign = xrpApi.sign(fromAddress, fromPrivateKey, toAddress, xrpApi.unitToMini(amount), xrpApi.unitToMini(fee), memo);
System.out.println(sign);
String txid = null;
try {
txid = xrpApi.pushTx(sign);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println("txid:" + txid);*/
//2.充值
/* List accounts = new ArrayList<>();
accounts.add("rDsd6zh5xArehnq9RNZETTpSr3MFJ39eqL");
xrpApi.recharge(accounts);*/
//3.生成秘钥对
/* xrpApi = new XrpApi("http://218.17.133.218:7777");
xrpApi.createKey();*/
//4.查询余额
Map accountInfoMap = xrpApi.getAccountInfo("rfbg6ozE1Mak8iH8H54ovVVXBCprSxm4zE");
Long v = Long.valueOf(accountInfoMap.get("balance").toString());
System.out.println(xrpApi.unitToMax(v));
}
}