BTC比特币虚拟货币java通过rpc调用钱包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liu1765686161/article/details/79446959
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.BigDecimalUtil;
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 long getBalance(){
        JSONObject json = doRequest(METHOD_GET_BALANCE);
        if(isError(json)){
            log.error("获取BTC余额:{}",json.get("error"));
            return 0;
        }
        return BigDecimalUtil.inputConvert(json.getDouble(RESULT));
    }

    /**
     * BTC转帐
     * @param addr
     * @param value
     * @return
     */
    public String send(String addr,long value){
        if(vailedAddress(addr)){
            double amt = BigDecimalUtil.outputConvert(value);
            JSONObject json = doRequest(METHOD_SEND_TO_ADDRESS,addr,amt);
            if(isError(json)){
                log.error("BTC 转帐给{} value:{}  失败 :",addr,amt,json.get("error"));
                return "";
            }else{
                log.info("BTC 转币给{} value:{} 成功",addr,amt);
                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向我提问,共同进步

猜你喜欢

转载自blog.csdn.net/liu1765686161/article/details/79446959