又一期的干货保姆级教程,这次我们来到了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
欢迎打赏~~~