1. 程式人生 > >BTC比特幣虛擬貨幣java通過rpc呼叫錢包

BTC比特幣虛擬貨幣java通過rpc呼叫錢包

package com.tn.web.service.coin;
import java.io.IOException;
import java.util.*;
import com.tn.entity.coin.UserCoinAddressEntity;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tn.base.Log;
import com.tn.util.HttpUtil;

/**
 * btc操作
 *
 * @author cloud cloud
 * @create 2017/10/27
 **/
@Service
public class CoinBtcService {

	private  String url = "http://127.0.0.1:18332";
	private  String username = "u";
	private  String password = "p";

    private Logger log = Log.get();

    private final static String RESULT = "result";
    private final static String METHOD_SEND_TO_ADDRESS = "sendtoaddress";
    private final static String METHOD_GET_BLOCK = "getblock";
    private final static String METHOD_GET_BLOCK_HASH = "getblockhash";
    private final static String METHOD_GET_TRANSACTION = "gettransaction";
    private final static String METHOD_GET_BLOCK_COUNT = "getblockcount";
    private final static String METHOD_NEW_ADDRESS = "getnewaddress";
    private final static String METHOD_GET_BALANCE = "getbalance";
    private final static int MIN_CONFIRMATION= 6;
    
    //前四個引數在BTC錢包conf檔案中設定
    //錢包密碼PASSWORD開啟錢包後設置的密碼

    /***
     * 取得錢包相關資訊
     * 若獲取失敗,result為空,error資訊為錯誤資訊的編碼
     * */
    public JSONObject getInfo() throws Exception {
    	return doRequest("getinfo");
    }

    /**
     * 獲取塊鏈資訊
     * @return
     * @throws Exception
     */
    public JSONObject getBlockChainInfo() throws Exception {
    	return doRequest("getblockchaininfo");
    }
    

    /**
     * BTC產生地址
     * @return
     */
    public String getNewAddress(){
        JSONObject json = doRequest(METHOD_NEW_ADDRESS);
        if(isError(json)){
            log.error("獲取BTC地址失敗:{}",json.get("error"));
            return "";
        }
        return json.getString(RESULT);
    }

    /**
     * BTC查詢餘額
     * @return
     */
    public double getBalance(){
        JSONObject json = doRequest(METHOD_GET_BALANCE);
        if(isError(json)){
            log.error("獲取BTC餘額:{}",json.get("error"));
            return 0;
        }
        return json.getDouble(RESULT);
    }

    /**
     * BTC轉帳
     * @param addr
     * @param value
     * @return
     */
    public String send(String addr,double value){
        if(vailedAddress(addr)){
            JSONObject json = doRequest(METHOD_SEND_TO_ADDRESS,addr,value);
            if(isError(json)){
                log.error("BTC 轉帳給{} value:{}  失敗 :",addr,value,json.get("error"));
                return "";
            }else{
                log.info("BTC 轉幣給{} value:{} 成功",addr,value);
                return json.getString(RESULT);
            }
        }else{
            log.error("BTC接受地址不正確");
            return "";
        }
    }

    /**
     * 驗證地址的有效性
     * @param address
     * @return
     * @throws Exception
     */
    public boolean vailedAddress(String address) {
        JSONObject json  = doRequest("validateaddress",address);
        if(isError(json)){
            log.error("BTC驗證地址失敗:",json.get("error"));
            return false;
        }else{
            return json.getJSONObject(RESULT).getBoolean("isvalid");
        }
    }


    /**
     * 區塊高度
     * @return
     */
    public int getBlockCount(){
        JSONObject json = null;
        try {
            json = doRequest(METHOD_GET_BLOCK_COUNT);
            if(!isError(json)){
                return json.getInteger("result");
            }else{
                log.error(json.toString());
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    public boolean parseBlock(int index) {
        JSONObject jsonBlockHash = doRequest(METHOD_GET_BLOCK_HASH, index);
        if (isError(jsonBlockHash)) {
            log.error("訪問BTC出錯");
            return false;
        }
        String hash = jsonBlockHash.getString(RESULT);
        JSONObject jsonBlock = doRequest(METHOD_GET_BLOCK, hash);
        if (isError(jsonBlock)) {
            log.error("訪問BTC出錯");
            return false;
        }
        JSONObject jsonBlockResult = jsonBlock.getJSONObject(RESULT);
        int confirm = jsonBlockResult.getInteger("confirmations");
        if (confirm >= MIN_CONFIRMATION) {
            JSONArray jsonArrayTx = jsonBlockResult.getJSONArray("tx");
            if (jsonArrayTx == null || jsonArrayTx.size() == 0) {
                //沒有交易
                return true;
            }
            Iterator<Object> iteratorTxs = jsonArrayTx.iterator();
            while(iteratorTxs.hasNext()){
                String txid = (String) iteratorTxs.next();
                parseTx(txid,confirm,null);
            }
            return true;
        }else{
            return false;
        }
    }

    public void parseTx(String txid,int coinfirm,List<UserCoinAddressEntity> userList){
        JSONObject jsonTransaction = doRequest(METHOD_GET_TRANSACTION, txid);
        if(isError(jsonTransaction)) {
            //log.error("處理BTC tx出錯");
            return;
        }
        JSONObject jsonTransactionResult = jsonTransaction.getJSONObject(RESULT);
        JSONArray jsonArrayVout = jsonTransactionResult.getJSONArray("details");
        if(jsonArrayVout == null || jsonArrayVout.size() == 0){
            return;
        }
        Iterator<Object> iteratorVout = jsonArrayVout.iterator();
        while (iteratorVout.hasNext()) {
            JSONObject jsonVout = (JSONObject) iteratorVout.next();
            double value = jsonVout.getDouble("amount");
        	String category = jsonVout.getString("category");
            if(value >0&&"receive".equals(category)) {
            	String address = jsonVout.getString("address");
                for (UserCoinAddressEntity addressModel : userList) {
                    //如果有地址是分配給用記的地址, 則說明使用者在充值
                    if (address.equals(addressModel.getAddress())) {
                        //新增充值記錄
                    	log.info("使用者充值");
                    	
                    }
                }
            }
        }
    }


    private boolean isError(JSONObject json){
        if( json == null || (StringUtils.isNotEmpty(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((username+":"+password).getBytes());
        Map<String,String> headers = new HashMap<>(2);
        headers.put("Authorization","Basic "+creb);
        String resp = "";
        if (METHOD_GET_TRANSACTION.equals(method)){
            try{
                resp = HttpUtil.jsonPost(url,headers,param.toJSONString());
            }catch (Exception e){
                if (e instanceof IOException){
                    resp = "{}";
                }
            }
        }else{
            resp = HttpUtil.jsonPost(url,headers,param.toJSONString());
        }
        return JSON.parseObject(resp);
    }

    public static void main(String args[]) throws Exception{
    	CoinBtcService btcUtils = new CoinBtcService();
    	System.out.println(btcUtils.getBalance());
    }
}

希望能幫到大家,歡迎大家一起分享。

覺得有用請打賞,你的鼓勵就是我的動力!

有問題可以通過chat向我提問,共同進步