关于如何使用 curl 命令来获取奇亚(Chia, XCH) 接口之获取主链相关信息(含最新块高),请移步 https://www.twle.cn/t/19316#reply0
这里只贴上 Java 使用 HttpsURLConnection 来实现的版本
首先生成证书
生成证书要经过两个 shell 命令
将 .crt
和 .key
导出为 server.p12
openssl pkcs12 -export -in ~/.chia/mainnet/config/ssl/full_node/private_full_node.crt -inkey ~/.chia/mainnet/config/ssl/full_node/private_full_node.key -password pass:110220 -name localhost -out server.p12
将 .p12
导出为 .jks
keytool -importkeystore -srckeystore server.p12 -destkeystore keystore.jks -srcstoretype pkcs12 -deststoretype jks -deststorepass 110220 -srcstorepass 110220 -deststoretype pkcs12
其次解释下几个要点
- 忽略证书验证
X509TrustManager x509m = new X509TrustManager() { //返回受信任的X509证书数组。 @Override public X509Certificate[] getAcceptedIssuers() { return null; } // 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。 //在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。 @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证, //因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。 @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }; SSLContext sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(kmf.getKeyManagers(), new TrustManager[]{x509m},null);
- 忽略域名和证书的匹配
// 不检查域名和证书是否配对 HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
- 添加自签名的证书
// keystore KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("/Users/yufei/Downloads/thsh/keystore.jks"),"110220".toCharArray()); KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509", "SunJSSE"); kmf.init(ks,"110220".toCharArray());
全部代码如下
package thsh; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.HostnameVerifier; import java.io.IOException; import java.net.URL; public class App { public static void main(String[] args) throws Exception{ // keystore KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("/Users/yufei/Downloads/thsh/keystore.jks"),"110220".toCharArray()); KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509", "SunJSSE"); kmf.init(ks,"110220".toCharArray()); String posted = "{}"; X509TrustManager x509m = new X509TrustManager() { //返回受信任的X509证书数组。 @Override public X509Certificate[] getAcceptedIssuers() { return null; } // 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。 //在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。 @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证, //因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。 @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }; SSLContext sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(kmf.getKeyManagers(), new TrustManager[]{x509m},null); // 不检查域名和证书是否配对 HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); URL serverUrl = new URL("https://localhost:8555/get_blockchain_state"); HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection(); conn.setSSLSocketFactory(sslcontext.getSocketFactory()); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; utf-8"); conn.setRequestProperty("Accept", "application/json"); //必须设置false,否则会自动redirect到重定向后的地址 conn.setInstanceFollowRedirects(false); conn.setDoOutput(true); conn.setDoInput(true); try(OutputStream os = conn.getOutputStream()) { byte[] input = posted.getBytes("utf-8"); os.write(input, 0, input.length); } conn.connect(); String result = getReturn(conn); System.out.println(result); } /*请求url获取返回的内容*/ public static String getReturn(HttpsURLConnection connection) throws IOException{ StringBuffer buffer = new StringBuffer(); //将返回的输入流转换成字符串 try(InputStream inputStream = connection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){ String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } String result = buffer.toString(); return result; } } }
输出结果如下
{"blockchain_state": {"difficulty": 1056, "genesis_challenge_initialized": true, "mempool_size": 10, "peak": {"challenge_block_info_hash": "0x9f16cd40f3520633550a8c6b3ed2f1763e4b7524835bc7fce7abdd8e8c3fbf04", "challenge_vdf_output": {"data": "0x00005d62f70f96305e7bf18987b6c2fdd39c54d4df25754cdad364bffc4bd267e4d7e9e799e965c0cdc01845a802da4177f955ce0aca52da0fcf6f1695c148e107052a24d766c33e37edbe8abb9c6195c6d59187674b97a5424144bdf05df0a7a1050100"}, "deficit": 0, "farmer_puzzle_hash": "0xd7fa58bf5fdef6063622e391b1a6e27bba83f4a93388166909fe7e882a7a5e22", "fees": null, "finished_challenge_slot_hashes": null, "finished_infused_challenge_slot_hashes": null, "finished_reward_slot_hashes": null, "header_hash": "0xd9683002e5a3681cad6927187796901b3af6f54befb6d7e5a2f5927fc033b8e3", "height": 371692, "infused_challenge_vdf_output": {"data": "0x030020d0308f0dcf12ea4d6c5d9fd9e18db7b7326875eba14b42ca4b9f72ca112927bb78e99f1eeb50c2679ad0283e9a447c190e5af7ecb58031d95413e191a253462fa3228ad81d57d353982b999b4f11a03edc4922bb3d987d8d7aa9af5e9a46030100"}, "overflow": false, "pool_puzzle_hash": "0xd7fa58bf5fdef6063622e391b1a6e27bba83f4a93388166909fe7e882a7a5e22", "prev_hash": "0x437f692f17a4257a8b878f0e0bb2a80380da0bd7996a5eebf85dec56dd264eed", "prev_transaction_block_hash": null, "prev_transaction_block_height": 371690, "required_iters": 142434, "reward_claims_incorporated": null, "reward_infusion_new_challenge": "0x7bc5bcb109c66e2ec68e4d9bdfb15ba10b2e43de96bff0f67a406900f615e9aa", "signage_point_index": 45, "sub_epoch_summary_included": null, "sub_slot_iters": 111673344, "timestamp": null, "total_iters": 1209271856226, "weight": 77768896}, "space": 17964932862054492160, "sub_slot_iters": 111673344, "sync": {"sync_mode": false, "sync_progress_height": 0, "sync_tip_height": 0, "synced": true}}, "success": true}
目前尚无回复