关于java 接入Filcoin相关操作(保姆级)

又一期的干货保姆级教程,这次我们来到了FIL,4月份的价格直逼240,虽然目前价格低迷但是基数永远是无价的,该研究还是得研究(公司强迫)。
话不多说,直接上流程。
首先这个节点,我得说说,要求蛮高的(关键是穷),所以我们决定,搭是不可能搭的,这辈子都不可能搭。
幸好Infura爸爸提供了目前还是Beta版本的节点可以供我们使用,来看看都有哪些我们日常会用到的。

infura地址
选择FILCOIN
就可以看到infura给咱们提供了哪些方法。
使用前记得注册一个PROJECTS,里面的ID和SECRET是需要用到的。
需要用到的jar包有以下这些:

<!--FILCOIN-->
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.bitcoinj</groupId>
            <artifactId>bitcoinj-core</artifactId>
            <version>0.14.7</version>
        </dependency>
        <dependency>
            <groupId>com.github.apetersson</groupId>
            <artifactId>Blake2b</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>co.nstant.in</groupId>
            <artifactId>cbor</artifactId>
            <version>0.9</version>
        </dependency>
        <dependency>
            <groupId>com.madgag.spongycastle</groupId>
            <artifactId>prov</artifactId>
            <version>1.58.0.0</version>
        </dependency>
        <!--FILCOIN结束-->

下面,直接上代码。

生成地址(离线)

 /**
     * 生成地址和私钥
     *
     * @param pathNumber
     * @return
     */
    public static Map<String, String> getBip44Credentials(int pathNumber) {
        Map<String, String> map = new HashMap<>(3);
        byte[] seed = MnemonicUtils.generateSeed(SEEDCODE, PASSWORD);
        DeterministicKey rootPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(rootPrivateKey);
        ImmutableList<ChildNumber> path = ImmutableList.of(new ChildNumber(44, true), FIL_HARDENED, ChildNumber.ZERO_HARDENED);
        DeterministicKey fourpath = deterministicHierarchy.get(path, true, true);
        DeterministicKey fourpathhd = HDKeyDerivation.deriveChildKey(fourpath, 0);
        DeterministicKey fivepathhd = HDKeyDerivation.deriveChildKey(fourpathhd, pathNumber);
        Blake2b.Digest blake2b1 = Blake2b.Digest.newInstance(20);
        ECKey ecKey = ECKey.fromPrivate(fivepathhd.getPrivKey(), false);
        String pulStr = ecKey.getPublicKeyAsHex();
        byte[] bytes = Numeric.hexStringToByteArray(pulStr);
        byte[] black2HashByte = blake2b1.digest(bytes);
        String black2HashStr = Numeric.toHexStringNoPrefix(black2HashByte);
        String black2HashSecond = "0x01" + black2HashStr;
        Blake2b.Digest blake2b2 = Blake2b.Digest.newInstance(4);
        byte[] checksumBytes = blake2b2.digest(Numeric.hexStringToByteArray(black2HashSecond));
        byte[] addressBytes = new byte[black2HashByte.length + checksumBytes.length];
        System.arraycopy(black2HashByte, 0, addressBytes, 0, black2HashByte.length);
        System.arraycopy(checksumBytes, 0, addressBytes, black2HashByte.length, checksumBytes.length);
        byte[] privKeyBytes = ecKey.getPrivKeyBytes();
        String privatekey = HexUtil.encodeHexStr(privKeyBytes);
        String basePrivKey = Base64.encodeBase64String(privKeyBytes);
        String key = "{\"Type\":\"secp256k1\",\"PrivateKey\":" + "\"" +basePrivKey + "\"}";
        String longPrivateKey = HexUtil.encodeHexStr(key.getBytes());
        map.put("address", "f1" + Base32.encode(addressBytes).toLowerCase());
        //64位私钥
        map.put("privateKey", privatekey);
        //160位私钥
        map.put("longPrivateKey", longPrivateKey);
        //f 正式 t 测试 1 钱包 2 合约
        return map;
    }

这个入参相当于每个地址的随机数。
也都是明文的地址和私钥。

获取地址余额

这边开始就需要用到节点了!

//获取余额
    private final static String BALANCE = "Filecoin.WalletBalance";

public static BigDecimal getbalance(String address) {
        String[] addr = {address};
        String body = getBody(BALANCE, addr);
        if (body != null) {
            JSONObject jsonBody = JSONObject.parseObject(body);
            if (jsonBody != null) {
                String balance = jsonBody.getString("result");
                if (balance != null) {
                    return (new BigDecimal(balance));
                }
            }
        }
        return BigDecimal.ZERO;
    }

getBody()里面就是正常的参数构造,网络请求。解析返回参数。
ps:网络请求是需要ID和SECRET的。
例如:HttpRequest.get(URL).basicAuth(PROJECT_ID, PROJECT_SECRET);

获取区块高度


//当前区块高度
    private final static String BLOCK_HEIGHT = "Filecoin.ChainHead";
public static BigInteger getBlockHeight() {
        List<JSONObject> jsonObjects = new ArrayList<>();
        String body;
        BigInteger b = BigInteger.ZERO;
        try {
            body = getBody(BLOCK_HEIGHT, jsonObjects);
            JSONObject jsonBody = JSONObject.parseObject(body);
            if (jsonBody != null) {
                String result = jsonBody.getString("result");
                if (result != null) {
                    JSONObject object = JSONObject.parseObject(result);
                    if (object != null) {
                        b = new BigInteger(object.getString("Height"));
                        return b;
                    }
                }
            }
            return b;
        }catch (Exception e){
           logger.error("API异常。。。");
        }
        return b;
    }

获取NONCE

 public BigInteger getNonce(String address) {
        String[] addr = {address};
        String body = getBody(NONCE, addr);
        if (body != null) {
            JSONObject jsonBody = JSONObject.parseObject(body);
            if (jsonBody != null) {
                String balance = jsonBody.getString("result");
                if (balance != null) {
                    return new BigDecimal(balance).toBigInteger();
                }
            }
        }
        return BigInteger.ZERO;
    }

获取交易需要的GasLimit

/**
     * 查询GasLimit
     */
    public static BigInteger getGasLimit(String from, String to, BigInteger nonce, BigDecimal getbalance) {
        JSONObject jsonObject = new JSONObject();
        JSONObject[] arr = {getParamsJsonObject(from, to, nonce, getbalance, BigInteger.ZERO, "0", "0"), null};
        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("method", "Filecoin.GasEstimateGasLimit");
        jsonObject.put("params", arr);
        jsonObject.put("id", 0);
        String json = jsonObject.toJSONString();
        String body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
        JSONObject jsonBody = JSONObject.parseObject(body);
        return jsonBody.getBigInteger("result");
    }

获取交易需要的GasPremium

/**
     * 查询GasPremium
     */
    public static String getGasPremium(String address, BigInteger gasLimit) {
        JSONObject jsonObject = new JSONObject();
        Object[] arr = {2, address, gasLimit, null};
        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("method", "Filecoin.GasEstimateGasPremium");
        jsonObject.put("params", arr);
        jsonObject.put("id", 0);
        String json = jsonObject.toJSONString();
        String body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
        JSONObject jsonBody = JSONObject.parseObject(body);
        String result = jsonBody.getString("result");
        result = new BigDecimal(result).multiply(new BigDecimal("2")).toPlainString();
        return result;
    }

获取交易需要的GasFeeCap

/**
     * 查询GasFeeCap
     */
    public static String getGasFeeCap(String address, BigInteger nonce, BigInteger gasLimit, String addrto, String gasPremium) {
        JSONObject jsonObject = new JSONObject();
        Object[] arr = {getParamsJsonObject(address, nonce, gasLimit, "0", gasPremium, addrto), 100, null};
        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("method", "Filecoin.GasEstimateFeeCap");
        jsonObject.put("params", arr);
        jsonObject.put("id", 0);
        String json = jsonObject.toJSONString();
        String body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
        JSONObject jsonBody = JSONObject.parseObject(body);
        String result = jsonBody.getString("result");
        result = new BigDecimal(result).multiply(new BigDecimal("0.12")).divide(new BigDecimal("10000"), 0, BigDecimal.ROUND_HALF_UP).toPlainString();
        return result;
    }

通过区块高度获取交易父区块

public static JSONArray ChainGetTipSetByHeight(BigInteger height) {
        JSONObject jsonObject = new JSONObject();
        BigInteger[] arr = {height, null};
        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("method", "Filecoin.ChainGetTipSetByHeight");
        jsonObject.put("params", arr);
        jsonObject.put("id", 0);
        String json = jsonObject.toJSONString();
        JSONArray jsonArray=new JSONArray();
        String body="";
        try {
            body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
            JSONObject jsonBody = JSONObject.parseObject(body);
            jsonArray = jsonBody.getJSONObject("result").getJSONArray("Cids");
        }catch (Exception e){
            e.printStackTrace();
            logger.error("ChainGetTipSetByHeight 异常:"+e.getMessage()+"==============="+body);
        }

        return jsonArray;
    }

通过父区块,获取交易信息

public static HashSet ChainGetParentMessages(JSONArray blockHash) {
        JSONObject jsonObject = new JSONObject();
        HashSet hashSet = new HashSet();
        for (int i = 0; i < blockHash.size(); i++) {
            JSONObject blockHashObject = blockHash.getJSONObject(i);
            JSONObject[] arr = {blockHashObject};
            jsonObject.put("jsonrpc", "2.0");
            jsonObject.put("method", "Filecoin.ChainGetParentMessages");
            jsonObject.put("params", arr);
            jsonObject.put("id", 0);
            String json = jsonObject.toJSONString();
            String body="";
            try {
                body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
                JSONObject jsonBody = JSONObject.parseObject(body);
                JSONArray jsonCids = jsonBody.getJSONArray("result");
                for (int j = 0; j < jsonCids.size(); j++) {
                    JSONObject jsonCidsObject = jsonCids.getJSONObject(j);
                    int intValue = jsonCidsObject.getJSONObject("Message").getIntValue("Method");
                    if (intValue == 0) {
                        hashSet.add(jsonCidsObject);
                    }
                }
            }catch (Exception e){
                logger.error("ChainGetParentMessages 异常:  "+e.getMessage()+"========"+body);
            }
        }
        return hashSet;
    }

通过Hash验证交易成功与否

public static Boolean StateReplay(String txHash) {
        Boolean flag = false;
        JSONObject jsonTxhash = new JSONObject();
        jsonTxhash.put("/", txHash);
        JSONObject jsonObject = new JSONObject();
        JSONObject[] arr = {null, jsonTxhash};
        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("method", "Filecoin.StateReplay");
        jsonObject.put("params", arr);
        jsonObject.put("id", 0);
        String json = jsonObject.toJSONString();
        String body="";
        try {
            body = HttpRequest.post(URL).basicAuth(PROJECT_ID, PROJECT_SECRET).body(json).execute().body();
            JSONObject jsonBody = JSONObject.parseObject(body);
            String hash = jsonBody.getJSONObject("result").getJSONObject("MsgCid").getString("/");
            if (hash.equals(txHash)) {
                flag = true;
            }
        }catch (Exception e){
            logger.error("StateReplay 异常: "+e.getMessage()+"========"+body);
        }

        return flag;
    }

因为安全原因,私钥的过程省略。。。
推送交易(广播),大家可以选用infura上提供的方法在这里插入图片描述

好啦,上述就是今日份的内容。上面的代码都可以直接使用。
有需要深入交流的朋友可以加QQ:296563552
欢迎打赏~~~在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值