type, Web3j web3j, Trans
return create(contract, binary, encodedConstructor, value);
} catch (TransactionException e) {
throw e;
+ } catch (IOException e) {
+ throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/core/src/main/java/com/platon/tx/exceptions/PlatonCallException.java b/core/src/main/java/com/platon/tx/exceptions/PlatonCallException.java
new file mode 100644
index 00000000..a8e2f01a
--- /dev/null
+++ b/core/src/main/java/com/platon/tx/exceptions/PlatonCallException.java
@@ -0,0 +1,44 @@
+package com.platon.tx.exceptions;
+
+import com.platon.protocol.core.Response;
+
+import java.io.IOException;
+
+/**
+ * @Author liushuyu
+ * @Date 2021/5/12 16:46
+ * @Version
+ * @Desc
+ */
+public class PlatonCallException extends RuntimeException {
+
+ private Response response;
+ private int code;
+ private String msg;
+
+ public PlatonCallException(int code, String msg, Response response){
+ this.code = code;
+ this.msg = msg;
+ this.response = response;
+ }
+
+ public PlatonCallException(int code, String msg, Response response, Throwable ex){
+ super(ex);
+ this.code = code;
+ this.msg = msg;
+ this.response = response;
+ }
+
+ public Response getResponse() {
+ return response;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/platon/tx/exceptions/PlatonCallTimeoutException.java b/core/src/main/java/com/platon/tx/exceptions/PlatonCallTimeoutException.java
new file mode 100644
index 00000000..745e10e3
--- /dev/null
+++ b/core/src/main/java/com/platon/tx/exceptions/PlatonCallTimeoutException.java
@@ -0,0 +1,44 @@
+package com.platon.tx.exceptions;
+
+import com.platon.protocol.core.Response;
+
+import java.io.IOException;
+
+/**
+ * @Author liushuyu
+ * @Date 2021/5/12 16:46
+ * @Version
+ * @Desc
+ */
+public class PlatonCallTimeoutException extends IOException {
+
+ private Response response;
+ private int code;
+ private String msg;
+
+ public PlatonCallTimeoutException(int code,String msg,Response response){
+ this.code = code;
+ this.msg = msg;
+ this.response = response;
+ }
+
+ public PlatonCallTimeoutException(int code,String msg,Response response,Throwable ex){
+ super(ex);
+ this.code = code;
+ this.msg = msg;
+ this.response = response;
+ }
+
+ public Response getResponse() {
+ return response;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/com/platon/protocol/admin/RequestTest.java b/core/src/test/java/com/platon/protocol/admin/RequestTest.java
index ecac40ac..d7292a39 100644
--- a/core/src/test/java/com/platon/protocol/admin/RequestTest.java
+++ b/core/src/test/java/com/platon/protocol/admin/RequestTest.java
@@ -20,7 +20,7 @@ protected void initWeb3Client(HttpService httpService) {
public void testPersonalListAccounts() throws Exception {
web3j.personalListAccounts().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"personal_listAccounts\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"personal_listAccounts\","
+ "\"params\":[],\"id\":1}");
}
@@ -28,7 +28,7 @@ public void testPersonalListAccounts() throws Exception {
public void testPersonalNewAccount() throws Exception {
web3j.personalNewAccount("password").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"personal_newAccount\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"personal_newAccount\","
+ "\"params\":[\"password\"],\"id\":1}");
}
@@ -48,7 +48,7 @@ public void testPersonalSendTransaction() throws Exception {
).send();
//CHECKSTYLE:OFF
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"personal_sendTransaction\",\"params\":[{\"from\":\"FROM\",\"to\":\"TO\",\"gas\":\"0x1\",\"gasPrice\":\"0xa\",\"value\":\"0x0\",\"data\":\"0xDATA\",\"nonce\":\"0x1\"},\"password\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"personal_sendTransaction\",\"params\":[{\"from\":\"FROM\",\"to\":\"TO\",\"gas\":\"0x1\",\"gasPrice\":\"0xa\",\"value\":\"0x0\",\"data\":\"0xDATA\",\"nonce\":\"0x1\"},\"password\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -57,7 +57,7 @@ public void testPersonalUnlockAccount() throws Exception {
web3j.personalUnlockAccount(
"0xfc390d8a8ddb591b010fda52f4db4945742c3809", "hunter2", BigInteger.ONE).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"personal_unlockAccount\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"personal_unlockAccount\","
+ "\"params\":[\"0xfc390d8a8ddb591b010fda52f4db4945742c3809\",\"hunter2\",1],"
+ "\"id\":1}");
}
@@ -66,8 +66,16 @@ public void testPersonalUnlockAccount() throws Exception {
public void testPersonalUnlockAccountNoDuration() throws Exception {
web3j.personalUnlockAccount("0xfc390d8a8ddb591b010fda52f4db4945742c3809", "hunter2").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"personal_unlockAccount\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"personal_unlockAccount\","
+ "\"params\":[\"0xfc390d8a8ddb591b010fda52f4db4945742c3809\",\"hunter2\",null],"
+ "\"id\":1}");
}
+
+ @Test
+ public void testTxPoolContent() throws Exception {
+ web3j.txPoolContent().send();
+
+ verifyResult(
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"txpool_content\"," + "\"params\":[],\"id\":1}");
+ }
}
diff --git a/core/src/test/java/com/platon/protocol/admin/ResponseTest.java b/core/src/test/java/com/platon/protocol/admin/ResponseTest.java
index 9bc6caef..9d31f76c 100644
--- a/core/src/test/java/com/platon/protocol/admin/ResponseTest.java
+++ b/core/src/test/java/com/platon/protocol/admin/ResponseTest.java
@@ -8,8 +8,7 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
/**
* Parity/Geth Shared Protocol Response tests.
@@ -90,5 +89,65 @@ public void testPersonalUnlockAccount() {
deserialiseResponse(PersonalUnlockAccount.class);
assertTrue(personalUnlockAccount.accountUnlocked());
}
-
+
+ @Test
+ public void testTxPoolContent() {
+ buildResponse(
+ "{\n"
+ + " \"jsonrpc\": \"2.0\",\n"
+ + " \"id\": 1,\n"
+ + " \"result\": {\n"
+ + " \"pending\": {\n"
+ + " \"0x0032D05F320fa74C871E892F48F0e6387c0Dfe95\": {\n"
+ + " \"0\": {\n"
+ + " \"blockHash\": null,\n"
+ + " \"blockNumber\": null,\n"
+ + " \"from\": \"0x0032d05f320fa74c871e892f48f0e6387c0dfe95\",\n"
+ + " \"gas\": \"0x63cad\",\n"
+ + " \"gasPrice\": \"0x1\",\n"
+ + " \"hash\": \"0x56cf53cbd377535c14b28cd373fa43d129f501b1a20b36903fd14b747c3f6cf5\",\n"
+ + " \"input\": \"0x608060405234801561001057600080fd5b5060405161060a38038061060a833981018060405281019080805190602001909291908051820192919060200180519060200190929190805190602001909291908051906020019092919050505084848160008173ffffffffffffffffffffffffffffffffffffffff1614151515610116576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000815111156101a35773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e600082141561019f573d81fd5b5050505b5050600081111561036d57600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156102b7578273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015156102b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f436f756c64206e6f74207061792073616665206372656174696f6e207769746881526020017f206574686572000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61036c565b6102d1828483610377640100000000026401000000009004565b151561036b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f436f756c64206e6f74207061792073616665206372656174696f6e207769746881526020017f20746f6b656e000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b5b5b5050505050610490565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d6000823e3d60008114610473576020811461047b5760009450610485565b829450610485565b8151158315171594505b505050509392505050565b61016b8061049f6000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a7230582007fffd557dfc8c4d2fdf56ba6381a6ce5b65b6260e1492d87f26c6d4f1d0410800290000000000000000000000008942595a2dc5181df0465af0d7be08c8f23c93af00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000004ba9692da667218aa968ced8cbe59fe193e0d7860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006968500000000000000000000000000000000000000000000000000000000000001240ec78d9e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000006ea3e1c44f2ad3e54cf32a25eb9fab965fc010f0000000000000000000000009542597a73c7371f07b4532bda22d39cfc4912180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n"
+ + " \"nonce\": \"0x0\",\n"
+ + " \"to\": null,\n"
+ + " \"transactionIndex\": null,\n"
+ + " \"value\": \"0x0\",\n"
+ + " \"v\": \"0x1b\",\n"
+ + " \"r\": \"0x1b53058de9ed675d8b6583c559d23013e941905dad28dfd95ba3ff4f38ace0\",\n"
+ + " \"s\": \"0x8631cfd224ee69034f8040d2297a28229ee91cd5acdabc7f1de5be62220\"\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"queued\": {\n"
+ + " \"0x00Bf700CeB382877F8bFa38b05fcC81126f4f228\": {\n"
+ + " \"49\": {\n"
+ + " \"blockHash\": null,\n"
+ + " \"blockNumber\": null,\n"
+ + " \"from\": \"0x00bf700ceb382877f8bfa38b05fcc81126f4f228\",\n"
+ + " \"gas\": \"0xfa00\",\n"
+ + " \"gasPrice\": \"0x3b9aca00\",\n"
+ + " \"hash\": \"0xa87ab980c4d277de6c4faf2670a2ec1b6e577482e582c8082d208b7e630cf395\",\n"
+ + " \"input\": \"0xa6ab36f2000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000009590f23a286dade6fbf778ca651ad560d4e02fdc\",\n"
+ + " \"nonce\": \"0x31\",\n"
+ + " \"to\": \"0x974d7219184a41d4f5e3664ddce808c7853d3ab4\",\n"
+ + " \"transactionIndex\": null,\n"
+ + " \"value\": \"0x0\",\n"
+ + " \"v\": \"0x2b\",\n"
+ + " \"r\": \"0xc747162f13dd24fd03dd00c66c5c3d222595908319333c2b08e7f7def8dad2e7\",\n"
+ + " \"s\": \"0x8e6a2c4e3794d782d51f950e0ba546f44412e8c2409bd39149d78d7ca316e8a\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + "}");
+
+ TxPoolContent content = deserialiseResponse(TxPoolContent.class);
+
+ assertEquals(
+ content.getResult().getPendingTransactions().get(0).getFrom(),
+ "0x0032d05f320fa74c871e892f48f0e6387c0dfe95");
+ assertEquals(
+ content.getResult().getQueuedTransactions().get(0).getFrom(),
+ "0x00bf700ceb382877f8bfa38b05fcc81126f4f228");
+ }
+
}
diff --git a/core/src/test/java/com/platon/protocol/core/RequestTest.java b/core/src/test/java/com/platon/protocol/core/RequestTest.java
index d55e4074..1c89bcec 100644
--- a/core/src/test/java/com/platon/protocol/core/RequestTest.java
+++ b/core/src/test/java/com/platon/protocol/core/RequestTest.java
@@ -27,7 +27,7 @@ public void testWeb3ClientVersion() throws Exception {
web3j.web3ClientVersion().send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"web3_clientVersion\",\"params\":[],\"id\":1}");
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"web3_clientVersion\",\"params\":[],\"id\":1}");
}
@Test
@@ -35,7 +35,7 @@ public void testWeb3Sha3() throws Exception {
web3j.web3Sha3("0x68656c6c6f20776f726c64").send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"web3_sha3\","
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"web3_sha3\","
+ "\"params\":[\"0x68656c6c6f20776f726c64\"],\"id\":1}");
}
@@ -43,21 +43,21 @@ public void testWeb3Sha3() throws Exception {
public void testNetVersion() throws Exception {
web3j.netVersion().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"net_version\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"net_version\",\"params\":[],\"id\":1}");
}
@Test
public void testNetListening() throws Exception {
web3j.netListening().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"net_listening\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"net_listening\",\"params\":[],\"id\":1}");
}
@Test
public void testNetPeerCount() throws Exception {
web3j.netPeerCount().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"net_peerCount\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"net_peerCount\",\"params\":[],\"id\":1}");
}
@Test
@@ -65,35 +65,35 @@ public void testEthProtocolVersion() throws Exception {
web3j.platonProtocolVersion().send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"platon_protocolVersion\",\"params\":[],\"id\":1}");
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_protocolVersion\",\"params\":[],\"id\":1}");
}
@Test
public void testEthSyncing() throws Exception {
web3j.platonSyncing().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_syncing\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_syncing\",\"params\":[],\"id\":1}");
}
@Test
public void testEthGasPrice() throws Exception {
web3j.platonGasPrice().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_gasPrice\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_gasPrice\",\"params\":[],\"id\":1}");
}
@Test
public void testEthAccounts() throws Exception {
web3j.platonAccounts().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_accounts\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_accounts\",\"params\":[],\"id\":1}");
}
@Test
public void testEthBlockNumber() throws Exception {
web3j.platonBlockNumber().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_blockNumber\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_blockNumber\",\"params\":[],\"id\":1}");
}
@Test
@@ -102,7 +102,7 @@ public void testEthGetBalance() throws Exception {
DefaultBlockParameterName.LATEST).send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"platon_getBalance\","
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getBalance\","
+ "\"params\":[\"0x407d73d8a49eeb85d32cf465507dd71d507100c1\",\"latest\"],"
+ "\"id\":1}");
}
@@ -112,7 +112,7 @@ public void testEthGetStorageAt() throws Exception {
web3j.platonGetStorageAt("0x295a70b2de5e3953354a6a8344e616ed314d7251", BigInteger.ZERO,
DefaultBlockParameterName.LATEST).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getStorageAt\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getStorageAt\","
+ "\"params\":[\"0x295a70b2de5e3953354a6a8344e616ed314d7251\",\"0x0\",\"latest\"],"
+ "\"id\":1}");
}
@@ -122,7 +122,7 @@ public void testEthGetTransactionCount() throws Exception {
web3j.platonGetTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1",
DefaultBlockParameterName.LATEST).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getTransactionCount\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getTransactionCount\","
+ "\"params\":[\"0x407d73d8a49eeb85d32cf465507dd71d507100c1\",\"latest\"],"
+ "\"id\":1}");
}
@@ -133,7 +133,7 @@ public void testEthGetBlockTransactionCountByHash() throws Exception {
"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").send();
//CHECKSTYLE:OFF
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getBlockTransactionCountByHash\",\"params\":[\"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getBlockTransactionCountByHash\",\"params\":[\"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -142,7 +142,7 @@ public void testEthGetBlockTransactionCountByNumber() throws Exception {
web3j.platonGetBlockTransactionCountByNumber(
DefaultBlockParameter.valueOf(Numeric.toBigInt("0xe8"))).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getBlockTransactionCountByNumber\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getBlockTransactionCountByNumber\","
+ "\"params\":[\"0xe8\"],\"id\":1}");
}
@@ -151,7 +151,7 @@ public void testEthGetCode() throws Exception {
web3j.platonGetCode("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
DefaultBlockParameter.valueOf(Numeric.toBigInt("0x2"))).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getCode\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getCode\","
+ "\"params\":[\"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\",\"0x2\"],\"id\":1}");
}
@@ -160,7 +160,7 @@ public void testEthSign() throws Exception {
web3j.platonSign("0x8a3106a3e50576d4b6794a0e74d3bb5f8c9acaab",
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_sign\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_sign\","
+ "\"params\":[\"0x8a3106a3e50576d4b6794a0e74d3bb5f8c9acaab\","
+ "\"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"],"
+ "\"id\":1}");
@@ -179,7 +179,7 @@ public void testEthSendTransaction() throws Exception {
+ "970870f072445675058bb8eb970870f072445675")).send();
//CHECKSTYLE:OFF
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_sendTransaction\",\"params\":[{\"from\":\"0xb60e8dd61c5d32be8058bb8eb970870f07233155\",\"to\":\"0xb60e8dd61c5d32be8058bb8eb970870f07233155\",\"gas\":\"0x76c0\",\"gasPrice\":\"0x9184e72a000\",\"value\":\"0x9184e72a\",\"data\":\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\",\"nonce\":\"0x1\"}],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_sendTransaction\",\"params\":[{\"from\":\"0xb60e8dd61c5d32be8058bb8eb970870f07233155\",\"to\":\"0xb60e8dd61c5d32be8058bb8eb970870f07233155\",\"gas\":\"0x76c0\",\"gasPrice\":\"0x9184e72a000\",\"value\":\"0x9184e72a\",\"data\":\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\",\"nonce\":\"0x1\"}],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -190,7 +190,7 @@ public void testEthSendRawTransaction() throws Exception {
+ "072445675058bb8eb970870f072445675").send();
//CHECKSTYLE:OFF
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_sendRawTransaction\",\"params\":[\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_sendRawTransaction\",\"params\":[\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -203,7 +203,7 @@ public void testEthCall() throws Exception {
"0x0"),
DefaultBlockParameter.valueOf("latest")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_call\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_call\","
+ "\"params\":[{\"from\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\","
+ "\"to\":\"0xb60e8dd61c5d32be8058bb8eb970870f07233155\",\"data\":\"0x0\"},"
+ "\"latest\"],\"id\":1}");
@@ -216,7 +216,7 @@ public void testEthEstimateGas() throws Exception {
"0xa70e8dd61c5d32be8058bb8eb970870f07233155",
"0x52b93c80364dc2dd4444c146d73b9836bbbb2b3f", "0x0")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_estimateGas\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_estimateGas\","
+ "\"params\":[{\"from\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\","
+ "\"to\":\"0x52b93c80364dc2dd4444c146d73b9836bbbb2b3f\",\"data\":\"0x0\"}],"
+ "\"id\":1}");
@@ -229,7 +229,7 @@ public void testEthEstimateGasContractCreation() throws Exception {
"0x52b93c80364dc2dd4444c146d73b9836bbbb2b3f", BigInteger.ONE,
BigInteger.TEN, "")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_estimateGas\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_estimateGas\","
+ "\"params\":[{\"from\":\"0x52b93c80364dc2dd4444c146d73b9836bbbb2b3f\","
+ "\"gasPrice\":\"0xa\",\"data\":\"0x\",\"nonce\":\"0x1\"}],\"id\":1}");
}
@@ -240,7 +240,7 @@ public void testEthGetBlockByHash() throws Exception {
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true).send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"platon_getBlockByHash\",\"params\":["
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getBlockByHash\",\"params\":["
+ "\"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\""
+ ",true],\"id\":1}");
}
@@ -250,7 +250,7 @@ public void testEthGetBlockByNumber() throws Exception {
web3j.platonGetBlockByNumber(
DefaultBlockParameter.valueOf(Numeric.toBigInt("0x1b4")), true).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getBlockByNumber\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getBlockByNumber\","
+ "\"params\":[\"0x1b4\",true],\"id\":1}");
}
@@ -259,7 +259,7 @@ public void testEthGetTransactionByHash() throws Exception {
web3j.platonGetTransactionByHash(
"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getTransactionByHash\",\"params\":["
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getTransactionByHash\",\"params\":["
+ "\"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238\"],"
+ "\"id\":1}");
}
@@ -271,7 +271,7 @@ public void testEthGetTransactionByBlockHashAndIndex() throws Exception {
BigInteger.ZERO).send();
//CHECKSTYLE:OFF
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getTransactionByBlockHashAndIndex\",\"params\":[\"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\",\"0x0\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getTransactionByBlockHashAndIndex\",\"params\":[\"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\",\"0x0\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -280,7 +280,7 @@ public void testEthGetTransactionByBlockNumberAndIndex() throws Exception {
web3j.platonGetTransactionByBlockNumberAndIndex(
DefaultBlockParameter.valueOf(Numeric.toBigInt("0x29c")), BigInteger.ZERO).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getTransactionByBlockNumberAndIndex\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getTransactionByBlockNumberAndIndex\","
+ "\"params\":[\"0x29c\",\"0x0\"],\"id\":1}");
}
@@ -289,7 +289,7 @@ public void testEthGetTransactionReceipt() throws Exception {
web3j.platonGetTransactionReceipt(
"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getTransactionReceipt\",\"params\":["
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getTransactionReceipt\",\"params\":["
+ "\"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238\"],"
+ "\"id\":1}");
}
@@ -301,7 +301,7 @@ public void testEthNewFilter() throws Exception {
web3j.platonNewFilter(ethFilter).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_newFilter\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_newFilter\","
+ "\"params\":[{\"topics\":[\"0x12341234\"]}],\"id\":1}");
}
@@ -309,7 +309,7 @@ public void testEthNewFilter() throws Exception {
public void testEthNewBlockFilter() throws Exception {
web3j.platonNewBlockFilter().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_newBlockFilter\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_newBlockFilter\","
+ "\"params\":[],\"id\":1}");
}
@@ -317,7 +317,7 @@ public void testEthNewBlockFilter() throws Exception {
public void testEthNewPendingTransactionFilter() throws Exception {
web3j.platonNewPendingTransactionFilter().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_newPendingTransactionFilter\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_newPendingTransactionFilter\","
+ "\"params\":[],\"id\":1}");
}
@@ -325,7 +325,7 @@ public void testEthNewPendingTransactionFilter() throws Exception {
public void testEthUninstallFilter() throws Exception {
web3j.platonUninstallFilter(Numeric.toBigInt("0xb")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_uninstallFilter\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_uninstallFilter\","
+ "\"params\":[\"0x0b\"],\"id\":1}");
}
@@ -333,7 +333,7 @@ public void testEthUninstallFilter() throws Exception {
public void testEthGetFilterChanges() throws Exception {
web3j.platonGetFilterChanges(Numeric.toBigInt("0x16")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getFilterChanges\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getFilterChanges\","
+ "\"params\":[\"0x16\"],\"id\":1}");
}
@@ -341,7 +341,7 @@ public void testEthGetFilterChanges() throws Exception {
public void testEthGetFilterLogs() throws Exception {
web3j.platonGetFilterLogs(Numeric.toBigInt("0x16")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getFilterLogs\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getFilterLogs\","
+ "\"params\":[\"0x16\"],\"id\":1}");
}
@@ -351,7 +351,7 @@ public void testEthGetLogs() throws Exception {
"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"platon_getLogs\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getLogs\","
+ "\"params\":[{\"topics\":["
+ "\"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b\"]}],"
+ "\"id\":1}");
@@ -365,7 +365,7 @@ public void testEthGetLogsWithNumericBlockRange() throws Exception {
.send();
verifyResult(
- "{\"jsonrpc\":\"2.0\",\"method\":\"platon_getLogs\","
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"platon_getLogs\","
+ "\"params\":[{\"topics\":[],\"fromBlock\":\"0xe8\","
+ "\"toBlock\":\"latest\",\"address\":[\"\"]}],\"id\":1}");
}
@@ -374,7 +374,7 @@ public void testEthGetLogsWithNumericBlockRange() throws Exception {
public void testDbPutString() throws Exception {
web3j.dbPutString("testDB", "myKey", "myString").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"db_putString\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"db_putString\","
+ "\"params\":[\"testDB\",\"myKey\",\"myString\"],\"id\":1}");
}
@@ -382,7 +382,7 @@ public void testDbPutString() throws Exception {
public void testDbGetString() throws Exception {
web3j.dbGetString("testDB", "myKey").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"db_getString\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"db_getString\","
+ "\"params\":[\"testDB\",\"myKey\"],\"id\":1}");
}
@@ -390,7 +390,7 @@ public void testDbGetString() throws Exception {
public void testDbPutHex() throws Exception {
web3j.dbPutHex("testDB", "myKey", "0x68656c6c6f20776f726c64").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"db_putHex\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"db_putHex\","
+ "\"params\":[\"testDB\",\"myKey\",\"0x68656c6c6f20776f726c64\"],\"id\":1}");
}
@@ -398,7 +398,7 @@ public void testDbPutHex() throws Exception {
public void testDbGetHex() throws Exception {
web3j.dbGetHex("testDB", "myKey").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"db_getHex\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"db_getHex\","
+ "\"params\":[\"testDB\",\"myKey\"],\"id\":1}");
}
@@ -406,7 +406,7 @@ public void testDbGetHex() throws Exception {
public void testShhVersion() throws Exception {
web3j.shhVersion().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_version\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_version\","
+ "\"params\":[],\"id\":1}");
}
@@ -421,7 +421,7 @@ public void testShhPost() throws Exception {
Numeric.toBigInt("0x64"),
Numeric.toBigInt("0x64"))).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_post\",\"params\":[{\"from\":\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\",\"to\":\"0x3e245533f97284d442460f2998cd41858798ddf04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a0d4d661997d3940272b717b1\",\"topics\":[\"0x776869737065722d636861742d636c69656e74\",\"0x4d5a695276454c39425154466b61693532\"],\"payload\":\"0x7b2274797065223a226d6\",\"priority\":\"0x64\",\"ttl\":\"0x64\"}],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_post\",\"params\":[{\"from\":\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\",\"to\":\"0x3e245533f97284d442460f2998cd41858798ddf04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a0d4d661997d3940272b717b1\",\"topics\":[\"0x776869737065722d636861742d636c69656e74\",\"0x4d5a695276454c39425154466b61693532\"],\"payload\":\"0x7b2274797065223a226d6\",\"priority\":\"0x64\",\"ttl\":\"0x64\"}],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -429,7 +429,7 @@ public void testShhPost() throws Exception {
public void testShhNewIdentity() throws Exception {
web3j.shhNewIdentity().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_newIdentity\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_newIdentity\",\"params\":[],\"id\":1}");
}
@Test
@@ -437,7 +437,7 @@ public void testShhHasIdentity() throws Exception {
//CHECKSTYLE:OFF
web3j.shhHasIdentity("0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_hasIdentity\",\"params\":[\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_hasIdentity\",\"params\":[\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -445,7 +445,7 @@ public void testShhHasIdentity() throws Exception {
public void testShhNewGroup() throws Exception {
web3j.shhNewGroup().send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_newGroup\",\"params\":[],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_newGroup\",\"params\":[],\"id\":1}");
}
@Test
@@ -453,7 +453,7 @@ public void testShhAddToGroup() throws Exception {
//CHECKSTYLE:OFF
web3j.shhAddToGroup("0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1").send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_addToGroup\",\"params\":[\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_addToGroup\",\"params\":[\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -464,7 +464,7 @@ public void testShhNewFilter() throws Exception {
new ShhFilter("0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1")
.addSingleTopic("0x12341234bf4b564f")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_newFilter\",\"params\":[{\"topics\":[\"0x12341234bf4b564f\"],\"to\":\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"}],\"id\":1}");
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_newFilter\",\"params\":[{\"topics\":[\"0x12341234bf4b564f\"],\"to\":\"0x04f96a5e25610293e42a73908e93ccc8c4d4dc0edcfa9fa872f50cb214e08ebf61a03e245533f97284d442460f2998cd41858798ddfd4d661997d3940272b717b1\"}],\"id\":1}");
//CHECKSTYLE:ON
}
@@ -472,7 +472,7 @@ public void testShhNewFilter() throws Exception {
public void testShhUninstallFilter() throws Exception {
web3j.shhUninstallFilter(Numeric.toBigInt("0x7")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_uninstallFilter\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_uninstallFilter\","
+ "\"params\":[\"0x07\"],\"id\":1}");
}
@@ -480,7 +480,7 @@ public void testShhUninstallFilter() throws Exception {
public void testShhGetFilterChanges() throws Exception {
web3j.shhGetFilterChanges(Numeric.toBigInt("0x7")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_getFilterChanges\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_getFilterChanges\","
+ "\"params\":[\"0x07\"],\"id\":1}");
}
@@ -488,7 +488,38 @@ public void testShhGetFilterChanges() throws Exception {
public void testShhGetMessages() throws Exception {
web3j.shhGetMessages(Numeric.toBigInt("0x7")).send();
- verifyResult("{\"jsonrpc\":\"2.0\",\"method\":\"shh_getMessages\","
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"shh_getMessages\","
+ "\"params\":[\"0x07\"],\"id\":1}");
}
+
+ @Test
+ public void testAdminAddPeer() throws Exception {
+ web3j.adminAddPeer("url").send();
+
+ verifyResult(
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"admin_addPeer\",\"params\":[\"url\"],\"id\":1}");
+ }
+
+ @Test
+ public void testAdminDataDir() throws Exception {
+ web3j.adminDataDir().send();
+
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"admin_datadir\",\"params\":[],\"id\":1}");
+ }
+
+ @Test
+ public void testAdminRemovePeer() throws Exception {
+ web3j.adminRemovePeer("url").send();
+
+ verifyResult(
+ "{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"admin_removePeer\",\"params\":[\"url\"],\"id\":1}");
+ }
+
+ @Test
+ public void testTxPoolStatus() throws Exception {
+ web3j.txPoolStatus().send();
+
+ verifyResult("{\"jsonrpc\":\"2.0\",\"bech32\":true,\"method\":\"txpool_status\",\"params\":[],\"id\":1}");
+ }
+
}
diff --git a/core/src/test/java/com/platon/protocol/core/ResponseTest.java b/core/src/test/java/com/platon/protocol/core/ResponseTest.java
index f5a8f753..88f138a6 100644
--- a/core/src/test/java/com/platon/protocol/core/ResponseTest.java
+++ b/core/src/test/java/com/platon/protocol/core/ResponseTest.java
@@ -1,6 +1,8 @@
package com.platon.protocol.core;
import com.platon.protocol.ResponseTester;
+import com.platon.protocol.admin.methods.response.TxPoolStatus;
+import com.platon.protocol.admin.methods.response.admin.AdminDataDir;
import com.platon.protocol.core.methods.response.*;
import com.platon.utils.Numeric;
import org.junit.Test;
@@ -1257,4 +1259,32 @@ public void testSshMessages() {
ShhMessages shhMessages = deserialiseResponse(ShhMessages.class);
assertThat(shhMessages.getMessages(), equalTo(messages));
}
+
+ @Test
+ public void testAdminDataDir() {
+ buildResponse(
+ "{\n"
+ + " \"jsonrpc\":\"2.0\",\n"
+ + " \"id\":22,\n"
+ + " \"result\":\"sampleDir\"\n"
+ + "}");
+
+ AdminDataDir dataDir = deserialiseResponse(AdminDataDir.class);
+ assertEquals(dataDir.getDataDir(), "sampleDir");
+ }
+
+ @Test
+ public void testTxPoolStatus() {
+ buildResponse(
+ "{\n"
+ + " \"jsonrpc\":\"2.0\",\n"
+ + " \"id\":22,\n"
+ + " \"result\":{ \"pending\": \"0x9\",\n"
+ + " \"queued\": \"0x7\"}\n"
+ + "}");
+
+ TxPoolStatus status = deserialiseResponse(TxPoolStatus.class);
+ assert(status.getPending() == 9);
+ assert(status.getQueued() == 7);
+ }
}
diff --git a/crypto/src/main/java/com/platon/crypto/Base58.java b/crypto/src/main/java/com/platon/crypto/Base58.java
new file mode 100644
index 00000000..30b56eb7
--- /dev/null
+++ b/crypto/src/main/java/com/platon/crypto/Base58.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc.
+ * Copyright 2018 Andreas Schildbach
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.platon.crypto;
+
+
+import java.util.Arrays;
+
+public class Base58 {
+ private static final char[] ALPHABET =
+ "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
+ private static final char ENCODED_ZERO = ALPHABET[0];
+
+ /**
+ * Encodes the given bytes as a base58 string (no checksum is appended).
+ *
+ * @param input the bytes to encode
+ * @return the base58-encoded string
+ */
+ public static String encode(byte[] input) {
+ if (input.length == 0) {
+ return "";
+ }
+ // Count leading zeros.
+ int zeros = 0;
+ while (zeros < input.length && input[zeros] == 0) {
+ ++zeros;
+ }
+ // Convert base-256 digits to base-58 digits (plus conversion to ASCII characters)
+ input = Arrays.copyOf(input, input.length); // since we modify it in-place
+ char[] encoded = new char[input.length * 2]; // upper bound
+ int outputStart = encoded.length;
+ for (int inputStart = zeros; inputStart < input.length; ) {
+ encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)];
+ if (input[inputStart] == 0) {
+ ++inputStart; // optimization - skip leading zeros
+ }
+ }
+ // Preserve exactly as many leading encoded zeros in output as there
+ // were leading zeros in input.
+ while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) {
+ ++outputStart;
+ }
+ while (--zeros >= 0) {
+ encoded[--outputStart] = ENCODED_ZERO;
+ }
+ // Return encoded string (including encoded leading zeros).
+ return new String(encoded, outputStart, encoded.length - outputStart);
+ }
+
+ private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {
+ // this is just long division which accounts for the base of the input digits
+ int remainder = 0;
+ for (int i = firstDigit; i < number.length; i++) {
+ int digit = (int) number[i] & 0xFF;
+ int temp = remainder * base + digit;
+ number[i] = (byte) (temp / divisor);
+ remainder = temp % divisor;
+ }
+ return (byte) remainder;
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/main/java/com/platon/crypto/Bip32ECKeyPair.java b/crypto/src/main/java/com/platon/crypto/Bip32ECKeyPair.java
new file mode 100644
index 00000000..41a75548
--- /dev/null
+++ b/crypto/src/main/java/com/platon/crypto/Bip32ECKeyPair.java
@@ -0,0 +1,172 @@
+package com.platon.crypto;
+
+import com.platon.utils.Numeric;
+import org.bouncycastle.math.ec.ECPoint;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static com.platon.crypto.Hash.hmacSha512;
+import static com.platon.crypto.Hash.sha256hash160;
+
+/**
+ * BIP-32 key pair.
+ *
+ * Adapted from:
+ * https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java
+ */
+public class Bip32ECKeyPair extends ECKeyPair {
+ static final int HARDENED_BIT = 0x80000000;
+
+ private final boolean parentHasPrivate;
+ private final int childNumber;
+ private final int depth;
+ private final byte[] chainCode;
+ private int parentFingerprint;
+
+ private ECPoint publicKeyPoint;
+
+ public Bip32ECKeyPair(BigInteger privateKey, BigInteger publicKey, int childNumber,
+ byte[] chainCode, Bip32ECKeyPair parent) {
+ super(privateKey, publicKey);
+ this.parentHasPrivate = parent != null && parent.hasPrivateKey();
+ this.childNumber = childNumber;
+ this.depth = parent == null ? 0 : parent.depth + 1;
+ this.chainCode = Arrays.copyOf(chainCode, chainCode.length);
+ this.parentFingerprint = parent != null ? parent.getFingerprint() : 0;
+ }
+
+ public static Bip32ECKeyPair create(BigInteger privateKey, byte[] chainCode) {
+ return new Bip32ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey),
+ 0, chainCode, null);
+ }
+
+ public static Bip32ECKeyPair create(byte[] privateKey, byte[] chainCode) {
+ return create(Numeric.toBigInt(privateKey), chainCode);
+ }
+
+ public static Bip32ECKeyPair generateKeyPair(byte[] seed) {
+ byte[] i = hmacSha512("Bitcoin seed".getBytes(), seed);
+ byte[] il = Arrays.copyOfRange(i, 0, 32);
+ byte[] ir = Arrays.copyOfRange(i, 32, 64);
+ Arrays.fill(i, (byte) 0);
+ Bip32ECKeyPair keypair = Bip32ECKeyPair.create(il, ir);
+ Arrays.fill(il, (byte) 0);
+ Arrays.fill(ir, (byte) 0);
+
+ return keypair;
+ }
+
+ public static Bip32ECKeyPair deriveKeyPair(Bip32ECKeyPair master, int[] path) {
+ Bip32ECKeyPair curr = master;
+ if (path != null) {
+ for (int childNumber : path) {
+ curr = curr.deriveChildKey(childNumber);
+ }
+ }
+
+ return curr;
+ }
+
+ public Bip32ECKeyPair deriveChildKey(int childNumber) {
+ if (!hasPrivateKey()) {
+ byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true);
+ ByteBuffer data = ByteBuffer.allocate(37);
+ data.put(parentPublicKey);
+ data.putInt(childNumber);
+ byte[] i = hmacSha512(getChainCode(), data.array());
+ byte[] il = Arrays.copyOfRange(i, 0, 32);
+ byte[] chainCode = Arrays.copyOfRange(i, 32, 64);
+ Arrays.fill(i, (byte) 0);
+ BigInteger ilInt = new BigInteger(1, il);
+ Arrays.fill(il, (byte) 0);
+ ECPoint ki = Sign.publicPointFromPrivate(ilInt).add(getPublicKeyPoint());
+
+ return new Bip32ECKeyPair(null,
+ Sign.publicFromPoint(ki.getEncoded(true)),
+ childNumber, chainCode, this);
+ } else {
+ ByteBuffer data = ByteBuffer.allocate(37);
+ if (isHardened(childNumber)) {
+ data.put(getPrivateKeyBytes33());
+ } else {
+ byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true);
+ data.put(parentPublicKey);
+ }
+ data.putInt(childNumber);
+ byte[] i = hmacSha512(getChainCode(), data.array());
+ byte[] il = Arrays.copyOfRange(i, 0, 32);
+ byte[] chainCode = Arrays.copyOfRange(i, 32, 64);
+ Arrays.fill(i, (byte) 0);
+ BigInteger ilInt = new BigInteger(1, il);
+ Arrays.fill(il, (byte) 0);
+ BigInteger privateKey = getPrivateKey().add(ilInt).mod(Sign.CURVE.getN());
+
+ return new Bip32ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey),
+ childNumber, chainCode, this);
+ }
+ }
+
+ private int getFingerprint() {
+ byte[] id = getIdentifier();
+ return id[3] & 0xFF | (id[2] & 0xFF) << 8 | (id[1] & 0xFF) << 16 | (id[0] & 0xFF) << 24;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public int getParentFingerprint() {
+ return parentFingerprint;
+ }
+
+ public byte[] getChainCode() {
+ return chainCode;
+ }
+
+ public int getChildNumber() {
+ return childNumber;
+ }
+
+ private byte[] getIdentifier() {
+ return sha256hash160(getPublicKeyPoint().getEncoded(true));
+ }
+
+ public ECPoint getPublicKeyPoint() {
+ if (publicKeyPoint == null) {
+ publicKeyPoint = Sign.publicPointFromPrivate(getPrivateKey());
+ }
+ return publicKeyPoint;
+ }
+
+ public byte[] getPrivateKeyBytes33() {
+ final int numBytes = 33;
+
+ byte[] bytes33 = new byte[numBytes];
+ byte[] priv = bigIntegerToBytes32(getPrivateKey());
+ System.arraycopy(priv, 0, bytes33, numBytes - priv.length, priv.length);
+ return bytes33;
+ }
+
+ private boolean hasPrivateKey() {
+ return this.getPrivateKey() != null || parentHasPrivate;
+ }
+
+ private static byte[] bigIntegerToBytes32(BigInteger b) {
+ final int numBytes = 32;
+
+ byte[] src = b.toByteArray();
+ byte[] dest = new byte[numBytes];
+ boolean isFirstByteOnlyForSign = src[0] == 0;
+ int length = isFirstByteOnlyForSign ? src.length - 1 : src.length;
+ int srcPos = isFirstByteOnlyForSign ? 1 : 0;
+ int destPos = numBytes - length;
+ System.arraycopy(src, srcPos, dest, destPos, length);
+ return dest;
+ }
+
+ private static boolean isHardened(int a) {
+ return (a & HARDENED_BIT) != 0;
+ }
+}
diff --git a/crypto/src/main/java/com/platon/crypto/Bip39Wallet.java b/crypto/src/main/java/com/platon/crypto/Bip39Wallet.java
index b4edb416..51fa9cd8 100644
--- a/crypto/src/main/java/com/platon/crypto/Bip39Wallet.java
+++ b/crypto/src/main/java/com/platon/crypto/Bip39Wallet.java
@@ -28,11 +28,4 @@ public String getMnemonic() {
return mnemonic;
}
- @Override
- public String toString() {
- return "Bip39Wallet{"
- + "filename='" + filename + '\''
- + ", mnemonic='" + mnemonic + '\''
- + '}';
- }
}
diff --git a/crypto/src/main/java/com/platon/crypto/Bip44WalletUtils.java b/crypto/src/main/java/com/platon/crypto/Bip44WalletUtils.java
new file mode 100644
index 00000000..ce81769a
--- /dev/null
+++ b/crypto/src/main/java/com/platon/crypto/Bip44WalletUtils.java
@@ -0,0 +1,78 @@
+package com.platon.crypto;
+
+import java.io.File;
+import java.io.IOException;
+
+import static com.platon.crypto.Bip32ECKeyPair.HARDENED_BIT;
+
+public class Bip44WalletUtils extends WalletUtils {
+
+ /**
+ * Generates a BIP-44 compatible Ethereum wallet on top of BIP-39 generated seed.
+ *
+ * @param password Will be used for both wallet encryption and passphrase for BIP-39 seed
+ * @param destinationDirectory The directory containing the wallet
+ * @return A BIP-39 compatible Ethereum wallet
+ * @throws CipherException if the underlying cipher is not available
+ * @throws IOException if the destination cannot be written to
+ */
+ public static Bip39Wallet generateBip44Wallet(String password, File destinationDirectory)
+ throws CipherException, IOException {
+ return generateBip44Wallet(password, destinationDirectory, false);
+ }
+
+ /**
+ * Generates a BIP-44 compatible Ethereum wallet on top of BIP-39 generated seed.
+ *
+ * @param password Will be used for both wallet encryption and passphrase for BIP-39 seed
+ * @param destinationDirectory The directory containing the wallet
+ * @param testNet should use the testNet derive path
+ * @return A BIP-39 compatible Ethereum wallet
+ * @throws CipherException if the underlying cipher is not available
+ * @throws IOException if the destination cannot be written to
+ */
+ public static Bip39Wallet generateBip44Wallet(String password, File destinationDirectory,
+ boolean testNet)
+ throws CipherException, IOException {
+ byte[] initialEntropy = new byte[16];
+ SecureRandomUtils.secureRandom().nextBytes(initialEntropy);
+
+ String mnemonic = MnemonicUtils.generateMnemonic(initialEntropy);
+ byte[] seed = MnemonicUtils.generateSeed(mnemonic, null);
+
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ Bip32ECKeyPair bip44Keypair = generateBip44KeyPair(masterKeypair, testNet);
+
+ String walletFile = generateWalletFile(password, bip44Keypair, destinationDirectory, false);
+
+ return new Bip39Wallet(walletFile, mnemonic);
+ }
+
+ public static Bip32ECKeyPair generateBip44KeyPair(Bip32ECKeyPair master) {
+ return generateBip44KeyPair(master, false);
+ }
+
+ public static Bip32ECKeyPair generateBip44KeyPair(Bip32ECKeyPair master, boolean testNet) {
+ if (testNet) {
+ // /m/44'/0'/0
+ final int[] path = {44 | HARDENED_BIT, 0 | HARDENED_BIT, 0 | HARDENED_BIT, 0};
+ return Bip32ECKeyPair.deriveKeyPair(master, path);
+ } else {
+ // m/44'/206'/0'/0
+ final int[] path = {44 | HARDENED_BIT, 206 | HARDENED_BIT, 0 | HARDENED_BIT, 0};
+ return Bip32ECKeyPair.deriveKeyPair(master, path);
+ }
+ }
+
+ public static Credentials loadBip44Credentials(String password, String mnemonic) {
+ return loadBip44Credentials(password, mnemonic, false);
+ }
+
+ public static Credentials loadBip44Credentials(String password, String mnemonic,
+ boolean testNet) {
+ byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ Bip32ECKeyPair bip44Keypair = generateBip44KeyPair(masterKeypair, testNet);
+ return Credentials.create(bip44Keypair);
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/main/java/com/platon/crypto/Sign.java b/crypto/src/main/java/com/platon/crypto/Sign.java
index a23ccd75..bef97729 100644
--- a/crypto/src/main/java/com/platon/crypto/Sign.java
+++ b/crypto/src/main/java/com/platon/crypto/Sign.java
@@ -211,7 +211,7 @@ public static BigInteger publicKeyFromPrivate(BigInteger privKey) {
/**
* Returns public key point from the given private key.
*/
- private static ECPoint publicPointFromPrivate(BigInteger privKey) {
+ public static ECPoint publicPointFromPrivate(BigInteger privKey) {
/*
* TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group
* order, but that could change in future versions.
@@ -222,6 +222,16 @@ private static ECPoint publicPointFromPrivate(BigInteger privKey) {
return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey);
}
+ /**
+ * Returns public key point from the given curve.
+ *
+ * @param bits representing the point on the curve
+ * @return BigInteger encoded public key
+ */
+ public static BigInteger publicFromPoint(byte[] bits) {
+ return new BigInteger(1, Arrays.copyOfRange(bits, 1, bits.length)); // remove prefix
+ }
+
public static class SignatureData {
private final byte[] v;
private final byte[] r;
diff --git a/crypto/src/main/java/com/platon/crypto/WalletUtils.java b/crypto/src/main/java/com/platon/crypto/WalletUtils.java
index 1f1e97ea..6336b54e 100644
--- a/crypto/src/main/java/com/platon/crypto/WalletUtils.java
+++ b/crypto/src/main/java/com/platon/crypto/WalletUtils.java
@@ -17,6 +17,8 @@
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static com.platon.crypto.Hash.sha256;
import static com.platon.crypto.Keys.ADDRESS_LENGTH_IN_HEX;
@@ -248,7 +250,7 @@ public static String getTestnetKeyDirectory() {
public static String getMainnetKeyDirectory() {
return String.format("%s%skeystore", getDefaultKeyDirectory(), File.separator);
}
-
+
/**
* Get keystore destination directory for a Rinkeby network.
* @return a String containing destination directory
@@ -264,6 +266,12 @@ public static boolean isValidPrivateKey(String privateKey) {
}
public static boolean isValidAddress(String input) {
+ //exclude blank characters and uppercase letters
+ Pattern pattern = Pattern.compile("^[a-z0-9]+$");
+ Matcher matcher = pattern.matcher(input);
+ if(!matcher.find()){
+ return false;
+ }
String cleanInput;
try{
byte [] bytes = Bech32.addressDecode(input);
diff --git a/crypto/src/test/java/com/platon/crypto/Bip32Test.java b/crypto/src/test/java/com/platon/crypto/Bip32Test.java
new file mode 100644
index 00000000..aa0ccd8d
--- /dev/null
+++ b/crypto/src/test/java/com/platon/crypto/Bip32Test.java
@@ -0,0 +1,158 @@
+package com.platon.crypto;
+
+import com.platon.utils.Numeric;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import static com.platon.crypto.Bip32ECKeyPair.HARDENED_BIT;
+import static com.platon.crypto.Hash.sha256;
+
+/**
+ * BIP-32 implementation test.
+ *
+ *
Test vectors taken from BIP-32 definition
+ * https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
+ */
+public class Bip32Test {
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void deriveKeyPairVector1() {
+ // Chain m
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
+ "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
+ null);
+
+ // Chain m/0H
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
+ "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
+ new int[]{0 | HARDENED_BIT});
+
+ // Chain m/0H/1
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
+ "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
+ new int[]{0 | HARDENED_BIT, 1});
+
+ // Chain m/0H/1/2H
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
+ "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
+ new int[]{0 | HARDENED_BIT, 1, 2 | HARDENED_BIT});
+
+ // Chain m/0H/1/2H/2
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
+ "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
+ new int[]{0 | HARDENED_BIT, 1, 2 | HARDENED_BIT, 2});
+
+ // Chain m/0H/1/2H/2/1000000000
+ testGenerated("000102030405060708090a0b0c0d0e0f",
+ "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
+ "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
+ new int[]{0 | HARDENED_BIT, 1, 2 | HARDENED_BIT, 2, 1000000000});
+ }
+
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void deriveKeyPairVector2() {
+ // Chain m
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
+ "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
+ null);
+
+ // Chain m/0
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
+ "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
+ new int[]{0});
+
+ // Chain m/0/2147483647H
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
+ "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
+ new int[]{0, 2147483647 | HARDENED_BIT});
+
+ // Chain m/0/2147483647H/1
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
+ "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
+ new int[]{0, 2147483647 | HARDENED_BIT, 1});
+
+ // Chain m/0/2147483647H/1/2147483646H
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
+ "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
+ new int[]{0, 2147483647 | HARDENED_BIT, 1, 2147483646 | HARDENED_BIT});
+
+ // Chain m/0/2147483647H/1/2147483646H/2
+ testGenerated("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
+ "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
+ "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
+ new int[]{0, 2147483647 | HARDENED_BIT, 1, 2147483646 | HARDENED_BIT, 2});
+ }
+
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void deriveKeyPairVector3() {
+ // Chain m
+ testGenerated("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be",
+ "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
+ "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13",
+ null);
+
+ // Chain m/0H
+ testGenerated("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be",
+ "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
+ "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y",
+ new int[]{0 | HARDENED_BIT});
+ }
+
+ private void testGenerated(String seed, String expectedPriv, String expectedPub, int[] path) {
+ Bip32ECKeyPair pair = Bip32ECKeyPair.generateKeyPair(Numeric.hexStringToByteArray(seed));
+ assertNotNull(pair);
+
+ pair = Bip32ECKeyPair.deriveKeyPair(pair, path);
+ assertNotNull(pair);
+
+ assertEquals(expectedPriv, Base58.encode(addChecksum(serializePrivate(pair))));
+ assertEquals(expectedPub, Base58.encode(addChecksum(serializePublic(pair))));
+ }
+
+ static byte[] addChecksum(byte[] input) {
+ int inputLength = input.length;
+ byte[] checksummed = new byte[inputLength + 4];
+ System.arraycopy(input, 0, checksummed, 0, inputLength);
+ byte[] checksum = hashTwice(input);
+ System.arraycopy(checksum, 0, checksummed, inputLength, 4);
+ return checksummed;
+ }
+
+ static byte[] serializePublic(Bip32ECKeyPair pair) {
+ return serialize(pair, 0x0488B21E, true);
+ }
+
+ static byte[] serializePrivate(Bip32ECKeyPair pair) {
+ return serialize(pair, 0x0488ADE4, false);
+ }
+
+ private static byte[] hashTwice(byte[] input) {
+ return sha256(sha256(input));
+ }
+
+ private static byte[] serialize(Bip32ECKeyPair pair, int header, boolean pub) {
+ ByteBuffer ser = ByteBuffer.allocate(78);
+ ser.putInt(header);
+ ser.put((byte) pair.getDepth());
+ ser.putInt(pair.getParentFingerprint());
+ ser.putInt(pair.getChildNumber());
+ ser.put(pair.getChainCode());
+ ser.put(pub ? pair.getPublicKeyPoint().getEncoded(true) : pair.getPrivateKeyBytes33());
+ return ser.array();
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/test/java/com/platon/crypto/Bip44WalletUtilsTest.java b/crypto/src/test/java/com/platon/crypto/Bip44WalletUtilsTest.java
new file mode 100644
index 00000000..8f495747
--- /dev/null
+++ b/crypto/src/test/java/com/platon/crypto/Bip44WalletUtilsTest.java
@@ -0,0 +1,112 @@
+package com.platon.crypto;
+
+import com.platon.parameters.NetworkParameters;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.platon.crypto.Bip32Test.*;
+import static com.platon.crypto.SampleKeys.PASSWORD;
+import static com.platon.crypto.WalletUtilsTest.createTempDir;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+public class Bip44WalletUtilsTest {
+
+ private File tempDir;
+
+ @Before
+ public void setUp() throws Exception {
+ tempDir = createTempDir();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ for (File file:tempDir.listFiles()) {
+ file.delete();
+ }
+ tempDir.delete();
+ }
+
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void generateBip44KeyPair() {
+ String mnemonic = "spider elbow fossil truck deal circle divert sleep safe report laundry above";
+ byte[] seed = MnemonicUtils.generateSeed(mnemonic, null);
+ String seedStr = bytesToHex(seed);
+ assertEquals("f0d2ab78b96acd147119abad1cd70eb4fec4f0e0a95744cf532e6a09347b08101213b4cbf50eada0eb89cba444525fe28e69707e52aa301c6b47ce1c5ef82eb5",
+ seedStr);
+
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ assertEquals("xprv9s21ZrQH143K2yA9Cdad5gjqHRC7apVUgEyYq5jXeXigDZ3PfEnps44tJprtMXr7PZivEsin6Qrbad7PuiEy4tn5jAEK6A3U46f9KvfRCmD",
+ Base58.encode(addChecksum(serializePrivate(masterKeypair))));
+
+ Bip32ECKeyPair bip44Keypair = Bip44WalletUtils.generateBip44KeyPair(masterKeypair);
+
+ assertEquals("xprvA1UQTpt1bAYoZCH2VvKERY9jEAoGQZiPdrZWg5Z4YoCGcBeSgri9JwdVsUM5HGbhZ9UmcGeSW2MNZCtJwXofUHB5KcswT1Sgr3sDfQhhZqK",
+ Base58.encode(addChecksum(serializePrivate(bip44Keypair))));
+ assertEquals("xpub6ETksLQuRY76mgMVbwrEng6TnCdkp2SF15V7UTxg78jFUyybEQ2Prjwyimr7fPdjGz6UugnjXL4Gt8gNAocgFTtKjRp6azm9NCh7DDpE5oR",
+ Base58.encode(addChecksum(serializePublic(bip44Keypair))));
+ }
+
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void deriveChildKey() {
+ NetworkParameters.selectAlaya();
+ String mnemonic = "spider elbow fossil truck deal circle divert sleep safe report laundry above";
+ byte[] seed = MnemonicUtils.generateSeed(mnemonic, null);
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ Bip32ECKeyPair bip44Keypair = Bip44WalletUtils.generateBip44KeyPair(masterKeypair);
+ for (int i = 0; i < 1; i++) {
+ Bip32ECKeyPair bip32ECKeyPair = bip44Keypair.deriveChildKey(i);
+ String address = Credentials.create(bip32ECKeyPair).getAddress();
+ Assert.assertEquals("atp17rp5teqsstfnn8w80vvmthepn78p0dnn07f9rz",address);
+ }
+ }
+
+ @SuppressWarnings("checkstyle:LineLength")
+ @Test
+ public void generateBip44KeyPairTestNet() {
+ String mnemonic = "spider elbow fossil truck deal circle divert sleep safe report laundry above";
+ byte[] seed = MnemonicUtils.generateSeed(mnemonic, null);
+ String seedStr = bytesToHex(seed);
+ assertEquals("f0d2ab78b96acd147119abad1cd70eb4fec4f0e0a95744cf532e6a09347b08101213b4cbf50eada0eb89cba444525fe28e69707e52aa301c6b47ce1c5ef82eb5",
+ seedStr);
+
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ assertEquals("xprv9s21ZrQH143K2yA9Cdad5gjqHRC7apVUgEyYq5jXeXigDZ3PfEnps44tJprtMXr7PZivEsin6Qrbad7PuiEy4tn5jAEK6A3U46f9KvfRCmD",
+ Base58.encode(addChecksum(serializePrivate(masterKeypair))));
+
+ Bip32ECKeyPair bip44Keypair = Bip44WalletUtils.generateBip44KeyPair(masterKeypair, true);
+
+ assertEquals("xprv9zhLxq63By3SX5hAMKnxjGy7L18bnn7GzDQv53eYYqeRX9M82riC1dqovamttwFpk2ZkDQxgcikBQzs1DTu2KShJJqnqgx83EftUB3k39uc",
+ Base58.encode(addChecksum(serializePrivate(bip44Keypair))));
+ assertEquals("xpub6DghNLcw2LbjjZmdTMKy6Quqt2y6CEq8MSLWsS4A7BBQPwgGaQ2SZSAHmsrqBVxLegjW2mBfcvDBhpeEqCmucTTPJiNLHQkiDuKwHs9gEtk",
+ Base58.encode(addChecksum(serializePublic(bip44Keypair))));
+ }
+
+ @Test
+ public void testGenerateBip44Wallets() throws Exception {
+ Bip39Wallet wallet = Bip44WalletUtils.generateBip44Wallet(PASSWORD, tempDir);
+ byte[] seed = MnemonicUtils.generateSeed(wallet.getMnemonic(), PASSWORD);
+ Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
+ Bip32ECKeyPair bip44Keypair = Bip44WalletUtils.generateBip44KeyPair(masterKeypair);
+ Credentials credentials = Credentials.create(bip44Keypair);
+
+ assertEquals(credentials,
+ Bip44WalletUtils.loadBip44Credentials(PASSWORD, wallet.getMnemonic()));
+ }
+
+ private String bytesToHex(byte[] bytes) {
+ final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
+
+ char[] chars = new char[2 * bytes.length];
+ for (int i = 0; i < bytes.length; ++i) {
+ chars[2 * i] = HEX_CHARS[(bytes[i] & 0xF0) >>> 4];
+ chars[2 * i + 1] = HEX_CHARS[bytes[i] & 0x0F];
+ }
+ return new String(chars);
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/test/java/com/platon/crypto/SignTest.java b/crypto/src/test/java/com/platon/crypto/SignTest.java
index 8e800ec7..60d6ef35 100644
--- a/crypto/src/test/java/com/platon/crypto/SignTest.java
+++ b/crypto/src/test/java/com/platon/crypto/SignTest.java
@@ -1,6 +1,7 @@
package com.platon.crypto;
import com.platon.utils.Numeric;
+import org.bouncycastle.math.ec.ECPoint;
import org.junit.Ignore;
import org.junit.Test;
@@ -49,4 +50,11 @@ public void testInvalidSignature() throws SignatureException {
Sign.signedMessageToKey(
TEST_MESSAGE, new Sign.SignatureData((byte) 27, new byte[]{1}, new byte[]{0}));
}
+
+ @Test
+ public void testPublicKeyFromPrivatePoint() {
+ ECPoint point = Sign.publicPointFromPrivate(SampleKeys.PRIVATE_KEY);
+ assertThat(Sign.publicFromPoint(point.getEncoded(false)),
+ equalTo(SampleKeys.PUBLIC_KEY));
+ }
}
diff --git a/crypto/src/test/java/com/platon/crypto/WalletUtilsTest.java b/crypto/src/test/java/com/platon/crypto/WalletUtilsTest.java
index 27946df6..077aa0a1 100644
--- a/crypto/src/test/java/com/platon/crypto/WalletUtilsTest.java
+++ b/crypto/src/test/java/com/platon/crypto/WalletUtilsTest.java
@@ -207,7 +207,7 @@ public void testGetTestnetKeyDirectory() {
}
- private static File createTempDir() throws Exception {
+ static File createTempDir() throws Exception {
return Files.createTempDirectory(
WalletUtilsTest.class.getSimpleName() + "-testkeys").toFile();
}
diff --git a/doc/Java-SDK-en.md b/doc/Java-SDK-en.md
index 76932c4d..b035cfb8 100644
--- a/doc/Java-SDK-en.md
+++ b/doc/Java-SDK-en.md
@@ -16,7 +16,7 @@ Depending on the build tool, use the following methods to add related dependenci
> Project configuration:
```xml
- platon-public
+ alaya-public
https://sdk.platon.network/nexus/content/groups/public/
```
@@ -26,7 +26,7 @@ Depending on the build tool, use the following methods to add related dependenci
com.alaya.sdk
core
- 0.16.0.0
+ 0.16.1.0
```
@@ -41,7 +41,7 @@ repositories {
> gradle way of reference:
```
-compile "com.alaya.sdk:core:0.16.0.0"
+compile "com.alaya.sdk:core:0.16.1.0"
```
## Basic API Usage
@@ -253,6 +253,78 @@ Request , NetPeerCount> request = currentValidWeb3j.netPeerCount();
BigInteger req = request.send().getQuantity();
```
+### adminAddPeer
+
+> Add a peer to the client node
+
+* **parameters**
+
+ String : peer's URL
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse property is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, BooleanResponse> request = platonWeb3j.adminAddPeer("enode://0abaf3219f454f3d07b6cbcf3c10b6b4ccf605202868e2043b6f5db12b745df0604ef01ef4cb523adc6d9e14b83a76dd09f862e3fe77205d8ac83df707969b47@[::]:16789");
+Boolean resp = request.send().getResult();
+```
+
+### adminRemovePeer
+
+> Remove a peer from the client node
+
+* **parameters**
+
+ String : peer's URL
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse property is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, BooleanResponse> request = platonWeb3j.adminRemovePeer("enode://0abaf3219f454f3d07b6cbcf3c10b6b4ccf605202868e2043b6f5db12b745df0604ef01ef4cb523adc6d9e14b83a76dd09f862e3fe77205d8ac83df707969b47@[::]:16789");
+Boolean resp = request.send().getResult();
+```
+
+### adminDataDir
+
+> Return the current node data directory
+
+* **parameters**
+
+ no
+
+* **return value**
+
+```java
+Request, AdminDataDir>
+```
+
+The result in the AdminDataDir property is the corresponding storage data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request , AdminDataDir> request = platonWeb3j.adminDataDir();
+String resp = request.send().getDataDir();
+```
+
### platonProtocolVersion
> Returns the current platon protocol version
@@ -1154,6 +1226,54 @@ Request, DbGetHex> request = currentValidWeb3j.dbGetHex(databaseName, keyName)
String req = request.send(). GetStoredValue();
```
+### txPoolStatus
+
+> Returns the status of the transaction pool
+
+* **parameters**
+
+ no
+
+* **return value**
+
+```java
+Request, TxPoolStatus>
+```
+
+The result in the TxPoolStatus property is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request , TxPoolStatus> request = platonWeb3j.txPoolStatus();
+TxPoolStatus txPoolStatus = request.send();
+```
+
+### txPoolContent
+
+> Return transaction pool content
+
+* **parameters**
+
+ no
+
+* **return value**
+
+```java
+Request, TxPoolContent>
+```
+
+The result in the TxPoolContent property is the corresponding storage data
+
+* **Example**
+
+```java
+JsonRpc2_0Admin platonWeb3j = new JsonRpc2_0Admin(new HttpService("http://127.0.0.1:6789"));
+Request , TxPoolContent> request = platonWeb3j.txPoolContent();
+TxPoolContent txPoolContent = request.send();
+```
+
### platonEvidences
> Return double sign report data
@@ -1377,21 +1497,21 @@ String debugEconomicConfig = req.send().getEconomicConfigStr();
### getChainId
-> Get chain ID
+> Get chain ID
-- **parameters**
+* **parameters**
- no
+ No
-- **return value**
+* **return value**
```java
Request, PlatonChainId>
```
-The String in the PlatonChainId property is the corresponding stored data
+The String in the PlatonChainId attribute is the corresponding storage data
-- **Example**
+* **Example**
```java
Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
@@ -1399,6 +1519,631 @@ Request, PlatonChainId> req = platonWeb3j.getChainId();
BigInteger chainId = req.send().getChainId();
```
+### adminNodeInfo
+
+> Retrieve all the information we know about the host node at protocol granularity
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, AdminNodeInfo>
+```
+
+The result in the AdminNodeInfo attribute is the corresponding storage data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminNodeInfo nodeInfo = platonWeb3j.adminNodeInfo().send();
+```
+
+### adminPeers
+
+> Retrieve all the information we know about each individual Peer at protocol granularity
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, AdminPeers>
+```
+
+The result in the AdminPeers attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminPeers adminPeers = platonWeb3j.adminPeers().send();
+```
+
+### adminStartRPC
+
+> Start the HTTP RPC API server
+
+* **parameters**
+
+ - String : host : Network address to listen on
+ - Integer : port : Network port to listen on
+ - String : cors : Cross-origin resource sharing header to be used
+ - String : apis : API modules to provide services through the service interface
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStartRPC("127.0.0.1", 6789, null, null).send();
+```
+
+### adminStartWS
+
+> Start the websocket RPC API server
+
+* **parameters**
+
+ - String : host : Network address to listen on
+ - Integer : port : Network port to listen on
+ - String : cors : Cross-origin resource sharing header to be used
+ - String : apis : API modules to provide services through the service interface
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = web3j.adminStartWS("127.0.0.1", 7789, null, null).send();
+```
+
+### adminStopRPC
+
+> Close the currently started HTTP RPC end node
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStopRPC().send();
+```
+
+### adminStopWS
+
+> Close the currently started WebSocket RPC end node
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStopWS().send();
+```
+
+### adminExportChain
+
+> Export the current blockchain to a local file
+
+* **parameters**
+
+ - String : file : file name
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.adminExportChain("1").send();
+```
+
+### adminImportChain
+
+> Import blockchain from local file
+
+* **parameters**
+
+ - String : file : file name
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.adminImportChain("1").send();
+```
+
+### getWaitSlashingNodeList
+
+> Get the node with zero block, the list of nodes that are observed because of zero block
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, DebugWaitSlashingNodeList>
+```
+
+The WaitSlashingNode list object in the DebugWaitSlashingNodeList property is the corresponding storage data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, DebugWaitSlashingNodeList> req = platonWeb3j.getWaitSlashingNodeList();
+DebugWaitSlashingNodeList nodeList = req.send();
+```
+
+### platonGetRawTransactionByHash
+
+> Returns the number of transaction bytes for a given Hash
+
+* **parameters**
+
+ - String : hash : Transaction hash
+
+* **return value**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+The result in the PlatonRawTransaction attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByHash("0x5b99...").send();
+```
+
+### platonGetRawTransactionByBlockHashAndIndex
+
+> Return transactions for a given block hash and index
+
+* **parameters**
+
+ - String : hash : Block hash
+ - String : index : index
+
+* **return value**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+The result in the PlatonRawTransaction attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByBlockHashAndIndex("0xa34...", "0x1").send();
+```
+
+### platonGetRawTransactionByBlockNumberAndIndex
+
+> Return transactions with a given block number and index
+
+* **parameters**
+
+ - String : blockNumber : Block number
+ - String : index : index
+
+* **return value**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+The result in the PlatonRawTransaction attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByBlockNumberAndIndex("0x1", "0x1").send();
+```
+
+### platonGetAddressHrp
+
+> Get chain Hrp
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, PlatonGetAddressHrp>
+```
+
+The result in the PlatonGetAddressHrp attribute is the corresponding storage data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonGetAddressHrp send = platonWeb3j.platonGetAddressHrp().send();
+```
+
+### platonSignTransaction
+
+> The from account will be used to sign the given transaction. The node needs to have the account private key corresponding to the given sender address, and it needs to be unlocked
+
+* **parameters**
+
+ - Transaction : transaction : Transaction object
+
+* **return value**
+
+```java
+Request, PlatonSignTransaction>
+```
+
+The result in the PlatonSignTransaction attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PlatonSignTransaction send = platonWeb3j.platonSignTransaction(transaction).send();
+```
+
+### minerSetGasPrice
+
+> Set the minimum gas price acceptable to miners
+
+* **parameters**
+
+ - String : minGasPrice : Lowest gas price
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.minerSetGasPrice("0x1").send();
+```
+
+### adminPeerEvents
+
+> Create an RPC subscription, which receives peer events from the node's p2p server
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, AdminPeerEvents>
+```
+
+The result in the AdminPeerEvents attribute is the corresponding storage data
+
+* **Example**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminPeerEvents send = web3j.adminPeerEvents().send();
+```
+
+### personalImportRawKey
+
+> Store the given hexadecimal coded key in the key directory and encrypt it with a password
+
+* **parameters**
+
+ - String : keydata : Private key
+ - String : password : password
+
+* **return value**
+
+```java
+Request, PersonalImportRawKey>
+```
+
+The result in the PersonalImportRawKey attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalImportRawKey key = admin.personalImportRawKey("03axxx", "000000").send();
+```
+
+### personalLockAccount
+
+> Lock the account associated with a given address
+
+* **parameters**
+
+ - String : address : Account address
+
+* **return value**
+
+```java
+Request, BooleanResponse>
+```
+
+The result in the BooleanResponse attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse response = admin.personalLockAccount("atp1cxxx").send();
+```
+
+### personalSign
+
+> Use the given account to sign the transaction, the account needs to exist in the node's account library
+
+* **parameters**
+
+ - String : message : The hexadecimal code string of the transaction
+ - String : accountId : Account address
+ - String : password : Account address password
+
+* **return value**
+
+```java
+Request, PersonalSign>
+```
+
+The result in the PersonalSign attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+RawTransaction transaction = RawTransaction.createTransaction(nonce,gasPrice,gasLimit,toAddress,value,data);
+byte[] encode = TransactionEncoder.encode(transaction);
+String hexSignedTransaction = Numeric.toHexString(encode);
+PersonalSign send = admin.personalSign(hexSignedTransaction, "atp1xxx","000000").send();
+```
+
+### personalSignAndSendTransaction
+
+> Use the from address of the transaction to sign and send the transaction. The from account needs to exist in the node's account library
+
+* **parameters**
+
+ - Transaction : transaction : Transaction object
+ - String : password : Account address password
+
+* **return value**
+
+```java
+Request, PersonalSign>
+```
+
+The result in the PersonalSign attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PersonalSign send = admin.personalSignAndSendTransaction(transaction, "000000").send();
+```
+
+### personalSignTransaction
+
+> Use the from address of the transaction to sign, and the from account needs to exist in the node's account database
+
+* **parameters**
+
+ - Transaction : transaction : Transaction object
+ - String : password : From account address password
+
+* **return value**
+
+```java
+Request, PlatonSignTransaction>
+```
+
+The result in the PlatonSignTransaction attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PlatonSignTransaction send = admin.personalSignTransaction(transaction,"000000").send();
+```
+
+### personalEcRecover
+
+> Returns the address of the account used to create the signature
+
+* **parameters**
+
+ - String : message : Raw data
+ - String : signiture : Signed data
+
+* **return value**
+
+```java
+Request, PersonalEcRecover>
+```
+
+The result in the PersonalEcRecover attribute is the corresponding storage data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalEcRecover send = admin.personalEcRecover("0xebxxx","0xa4f5xxx").send();
+```
+
+### personalListWallets
+
+> Return the list of wallets managed by this node
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, PersonalListWallets>
+```
+
+The result in the PersonalListWallets attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalListWallets send = admin.personalListWallets().send();
+```
+
+### personalOpenWallet
+
+> Start the hardware wallet opening program, establish a USB connection and try to authenticate with the provided password. Please note that this method may return an additional challenge that needs to be opened a second time (for example, Trezor PIN matrix challenge)
+
+* **parameters**
+
+ - String : url : URL
+ - String : passphrase : password
+
+* **return value**
+
+```java
+Request, VoidResponse>
+```
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+VoidResponse send = admin.personalOpenWallet("http://localhost:8080", "000000").send();
+```
+
+### personalUnlockAccount
+
+> Use the given password to unlock the account associated with the given address for a duration of seconds. The default is 300 seconds. If the account is unlocked, it will return an indication
+
+* **parameters**
+
+ - String : address : address
+ - String : passphrase : password
+
+* **return value**
+
+```java
+Request, PersonalUnlockAccount>
+```
+
+The result in the PersonalUnlockAccount attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalUnlockAccount response = admin.personalUnlockAccount("atp1xxx", "111111").send();
+```
+
+### personalListAccounts
+
+> Returns a list of addresses of accounts managed by this node
+
+* **parameters**
+
+ No
+
+* **return value**
+
+```java
+Request, PersonalListAccounts>
+```
+
+The result in the PersonalListAccounts attribute is the corresponding stored data
+
+* **Example**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalListAccounts send = admin.personalListAccounts().send();
+```
+
## System Contract Call
diff --git a/doc/Java-SDK-zh.md b/doc/Java-SDK-zh.md
index 1dc6654a..342b4bac 100644
--- a/doc/Java-SDK-zh.md
+++ b/doc/Java-SDK-zh.md
@@ -16,7 +16,7 @@ sidebar_label: Java SDK
> 项目配置:
```xml
- platon-public
+ alaya-public
https://sdk.platon.network/nexus/content/groups/public/
```
@@ -26,7 +26,7 @@ sidebar_label: Java SDK
com.alaya.sdk
core
- 0.16.0.0
+ 0.16.1.0
```
@@ -41,7 +41,7 @@ repositories {
> gradle引用方式:
```
-compile "com.alaya.sdk:core:0.16.0.0"
+compile "com.alaya.sdk:core:0.16.1.0"
```
## 基础api使用
@@ -252,6 +252,78 @@ Request , NetPeerCount> request = currentValidWeb3j.netPeerCount();
BigInteger req = request.send().getQuantity();
```
+### adminAddPeer
+
+> 新增一个端点到客户端节点
+
+* **参数**
+
+ String :端点URL
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, BooleanResponse> request = platonWeb3j.adminAddPeer("enode://0abaf3219f454f3d07b6cbcf3c10b6b4ccf605202868e2043b6f5db12b745df0604ef01ef4cb523adc6d9e14b83a76dd09f862e3fe77205d8ac83df707969b47@[::]:16789");
+Boolean resp = request.send().getResult();
+```
+
+### adminRemovePeer
+
+> 从客户端节点移除一个端点
+
+* **参数**
+
+ String :端点URL
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, BooleanResponse> request = platonWeb3j.adminRemovePeer("enode://0abaf3219f454f3d07b6cbcf3c10b6b4ccf605202868e2043b6f5db12b745df0604ef01ef4cb523adc6d9e14b83a76dd09f862e3fe77205d8ac83df707969b47@[::]:16789");
+Boolean resp = request.send().getResult();
+```
+
+### adminDataDir
+
+> 返回当前节点数据目录
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, AdminDataDir>
+```
+
+AdminDataDir属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request , AdminDataDir> request = platonWeb3j.adminDataDir();
+String resp = request.send().getDataDir();
+```
+
### platonProtocolVersion
> 返回当前platon协议版本
@@ -1153,6 +1225,54 @@ Request , DbGetHex> request = currentValidWeb3j.dbGetHex(databaseName,keyName)
String req = request.send().getStoredValue();
```
+### txPoolStatus
+
+> 返回交易池状态
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, TxPoolStatus>
+```
+
+TxPoolStatus属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request , TxPoolStatus> request = platonWeb3j.txPoolStatus();
+TxPoolStatus txPoolStatus = request.send();
+```
+
+### txPoolContent
+
+> 返回交易池内容
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, TxPoolContent>
+```
+
+TxPoolContent属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+JsonRpc2_0Admin platonWeb3j = new JsonRpc2_0Admin(new HttpService("http://127.0.0.1:6789"));
+Request , TxPoolContent> request = platonWeb3j.txPoolContent();
+TxPoolContent txPoolContent = request.send();
+```
+
### platonEvidences
> 返回双签举报数据
@@ -1397,6 +1517,631 @@ Request, PlatonChainId> req = platonWeb3j.getChainId();
BigInteger chainId = req.send().getChainId();
```
+### adminNodeInfo
+
+> 以协议粒度检索我们知道的有关主机节点的所有信息。
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, AdminNodeInfo>
+```
+
+AdminNodeInfo属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminNodeInfo nodeInfo = platonWeb3j.adminNodeInfo().send();
+```
+
+### adminPeers
+
+> 以协议粒度检索我们知道的关于每个单独 Peer 的所有信息
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, AdminPeers>
+```
+
+AdminPeers属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminPeers adminPeers = platonWeb3j.adminPeers().send();
+```
+
+### adminStartRPC
+
+> 启动 HTTP RPC API 服务器
+
+* **参数**
+
+ - String : host : 要监听的网络地址
+ - Integer : port : 要监听的网络端口
+ - String : cors : 要使用的跨源资源共享头
+ - String : apis : 要透过该服务接口提供服务的API模块
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStartRPC("127.0.0.1", 6789, null, null).send();
+```
+
+### adminStartWS
+
+> 启动 websocket RPC API 服务器
+
+* **参数**
+
+ - String : host : 要监听的网络地址
+ - Integer : port : 要监听的网络端口
+ - String : cors : 要使用的跨源资源共享头
+ - String : apis : 要透过该服务接口提供服务的API模块
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = web3j.adminStartWS("127.0.0.1", 7789, null, null).send();
+```
+
+### adminStopRPC
+
+> 关闭当前启动的HTTP RPC端结点
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStopRPC().send();
+```
+
+### adminStopWS
+
+> 关闭当前启动的WebSocket RPC端结点
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+WebSocketService webSocketService = new WebSocketService("ws://127.0.0.1:7790",false);
+webSocketService.connect();
+Web3j platonWeb3j = Web3j.build(webSocketService);
+BooleanResponse send = platonWeb3j.adminStopWS().send();
+```
+
+### adminExportChain
+
+> 将当前区块链导出到本地文件中
+
+* **参数**
+
+ - String : file : 文件名
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.adminExportChain("1").send();
+```
+
+### adminImportChain
+
+> 从本地文件导入区块链
+
+* **参数**
+
+ - String : file : 文件名
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.adminImportChain("1").send();
+```
+
+### getWaitSlashingNodeList
+
+> 获取零出块的节点,因为零出块而被观察的节点列表
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, DebugWaitSlashingNodeList>
+```
+
+DebugWaitSlashingNodeList属性中的WaitSlashingNode列表对象即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Request, DebugWaitSlashingNodeList> req = platonWeb3j.getWaitSlashingNodeList();
+DebugWaitSlashingNodeList nodeList = req.send();
+```
+
+### platonGetRawTransactionByHash
+
+> 返回给定Hash的交易字节数
+
+* **参数**
+
+ - String : hash : 交易hash
+
+* **返回值**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+PlatonRawTransaction属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByHash("0x5b99...").send();
+```
+
+### platonGetRawTransactionByBlockHashAndIndex
+
+> 返回给定区块哈希和索引的交易
+
+* **参数**
+
+ - String : hash : 块hash
+ - String : index : 索引
+
+* **返回值**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+PlatonRawTransaction属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByBlockHashAndIndex("0xa34...", "0x1").send();
+```
+
+### platonGetRawTransactionByBlockNumberAndIndex
+
+> 返回给定区块号和索引的交易
+
+* **参数**
+
+ - String : blockNumber : 块号
+ - String : index : 索引
+
+* **返回值**
+
+```java
+Request, PlatonRawTransaction>
+```
+
+PlatonRawTransaction属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonRawTransaction send = platonWeb3j.platonGetRawTransactionByBlockNumberAndIndex("0x1", "0x1").send();
+```
+
+### platonGetAddressHrp
+
+> 获取链Hrp
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, PlatonGetAddressHrp>
+```
+
+PlatonGetAddressHrp属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+PlatonGetAddressHrp send = platonWeb3j.platonGetAddressHrp().send();
+```
+
+### platonSignTransaction
+
+> 将使用 from 帐户签署给定的交易。节点需要有给定的发件人地址对应的账户私钥,并且需要解锁
+
+* **参数**
+
+ - Transaction : transaction : 交易对象
+
+* **返回值**
+
+```java
+Request, PlatonSignTransaction>
+```
+
+PlatonSignTransaction属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PlatonSignTransaction send = platonWeb3j.platonSignTransaction(transaction).send();
+```
+
+### minerSetGasPrice
+
+> 设置矿工可接受的最低gas price
+
+* **参数**
+
+ - String : minGasPrice : 最低gas price
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse send = platonWeb3j.minerSetGasPrice("0x1").send();
+```
+
+### adminPeerEvents
+
+> 创建一个 RPC 订阅,它从节点的 p2p服务器接收 peer 事件
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, AdminPeerEvents>
+```
+
+AdminPeerEvents属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Web3j platonWeb3j = Web3j.build(new HttpService("http://127.0.0.1:6789"));
+AdminPeerEvents send = web3j.adminPeerEvents().send();
+```
+
+### personalImportRawKey
+
+> 将给定的十六进制编码密钥存储到密钥目录中,并使用密码对其进行加密
+
+* **参数**
+
+ - String : keydata : 私钥
+ - String : password : 密码
+
+* **返回值**
+
+```java
+Request, PersonalImportRawKey>
+```
+
+PersonalImportRawKey属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalImportRawKey key = admin.personalImportRawKey("03axxx", "000000").send();
+```
+
+### personalLockAccount
+
+> 锁定与给定地址关联的帐户
+
+* **参数**
+
+ - String : address : 账户地址
+
+* **返回值**
+
+```java
+Request, BooleanResponse>
+```
+
+BooleanResponse属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+BooleanResponse response = admin.personalLockAccount("atp1cxxx").send();
+```
+
+### personalSign
+
+> 使用给定的账户对交易进行签名,账户需要存在于节点的账户库中
+
+* **参数**
+
+ - String : message : 交易的16进制编码字符串
+ - String : accountId : 账户地址
+ - String : password : 账户地址密码
+
+* **返回值**
+
+```java
+Request, PersonalSign>
+```
+
+PersonalSign属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+RawTransaction transaction = RawTransaction.createTransaction(nonce,gasPrice,gasLimit,toAddress,value,data);
+byte[] encode = TransactionEncoder.encode(transaction);
+String hexSignedTransaction = Numeric.toHexString(encode);
+PersonalSign send = admin.personalSign(hexSignedTransaction, "atp1xxx","000000").send();
+```
+
+### personalSignAndSendTransaction
+
+> 使用交易的from地址进行签名并发送交易,from账户需要存在于节点的账户库中
+
+* **参数**
+
+ - Transaction : transaction : 交易对象
+ - String : password : 账户地址密码
+
+* **返回值**
+
+```java
+Request, PersonalSign>
+```
+
+PersonalSign属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PersonalSign send = admin.personalSignAndSendTransaction(transaction, "000000").send();
+```
+
+### personalSignTransaction
+
+> 使用交易的from地址进行签名,from账户需要存在于节点的账户库中
+
+* **参数**
+
+ - Transaction : transaction : 交易对象
+ - String : password : from账户地址密码
+
+* **返回值**
+
+```java
+Request, PlatonSignTransaction>
+```
+
+PlatonSignTransaction属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+Transaction transaction = new Transaction("atp1xxx",nonce,gasPrice,gasLimit,toAddress,value,data);
+PlatonSignTransaction send = admin.personalSignTransaction(transaction,"000000").send();
+```
+
+### personalEcRecover
+
+> 返回用于创建签名的帐户的地址
+
+* **参数**
+
+ - String : message : 原始数据
+ - String : signiture : 签名后的数据
+
+* **返回值**
+
+```java
+Request, PersonalEcRecover>
+```
+
+PersonalEcRecover属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalEcRecover send = admin.personalEcRecover("0xebxxx","0xa4f5xxx").send();
+```
+
+### personalListWallets
+
+> 返回此节点管理的钱包列表
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, PersonalListWallets>
+```
+
+PersonalListWallets属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalListWallets send = admin.personalListWallets().send();
+```
+
+### personalOpenWallet
+
+> 启动硬件钱包打开程序,建立 USB 连接并尝试通过提供的密码进行身份验证。请注意,该方法可能会返回一个需要第二次打开的额外质询(例如,Trezor PIN 矩阵质询)
+
+* **参数**
+
+ - String : url : 网址
+ - String : passphrase : 密码
+
+* **返回值**
+
+```java
+Request, VoidResponse>
+```
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+VoidResponse send = admin.personalOpenWallet("http://localhost:8080", "000000").send();
+```
+
+### personalUnlockAccount
+
+> 使用给定密码解锁与给定地址关联的帐户持续时间秒。默认 300 秒。如果帐户已解锁,它会返回一个指示
+
+* **参数**
+
+ - String : address : 地址
+ - String : passphrase : 密码
+
+* **返回值**
+
+```java
+Request, PersonalUnlockAccount>
+```
+
+PersonalUnlockAccount属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalUnlockAccount response = admin.personalUnlockAccount("atp1xxx", "111111").send();
+```
+
+### personalListAccounts
+
+> 返回此节点管理的帐户的地址列表
+
+* **参数**
+
+ 无
+
+* **返回值**
+
+```java
+Request, PersonalListAccounts>
+```
+
+PersonalListAccounts属性中的result即为对应存储数据
+
+* **示例**
+
+```java
+Admin admin = Admin.build(new HttpService("http://127.0.0.1:6789"));
+PersonalListAccounts send = admin.personalListAccounts().send();
+```
+
## 系统合约调用
系统接口主要包含经济模型和治理相关的合约接口:
diff --git a/gradle.properties b/gradle.properties
index 56048813..d48a1ed8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
group=com.alaya.sdk
-version=0.16.0.0
+version=0.16.1.0
mavenReleases=https://sdk.platon.network/nexus/content/repositories/releases/
mavenSnapshots=https://sdk.platon.network/nexus/content/repositories/snapshots/
systemProp.sonar.host.url=http://192.168.16.173:9000
diff --git a/integration-tests/src/test/java/com/platon/protocol/core/JsonRpc2_0Web3jTest.java b/integration-tests/src/test/java/com/platon/protocol/core/JsonRpc2_0Web3jTest.java
new file mode 100644
index 00000000..caeac57d
--- /dev/null
+++ b/integration-tests/src/test/java/com/platon/protocol/core/JsonRpc2_0Web3jTest.java
@@ -0,0 +1,76 @@
+package com.platon.protocol.core;
+
+import com.platon.parameters.NetworkParameters;
+import com.platon.protocol.Web3j;
+import com.platon.protocol.core.methods.response.DebugWaitSlashingNodeList;
+import com.platon.protocol.core.methods.response.PlatonChainId;
+import com.platon.protocol.http.HttpService;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * @Author liushuyu
+ * @Date 2021/7/6 15:52
+ * @Version
+ * @Desc
+ */
+public class JsonRpc2_0Web3jTest {
+
+ private static final Logger logger = LoggerFactory.getLogger("JsonRpc2_0Web3jTest");
+
+ @Before
+ public void init(){
+ NetworkParameters.selectPlatON();
+ }
+
+ /**
+ * 底层1.0.0版本
+ * @throws IOException
+ */
+ @Test
+ public void testChainId_version15_0_0() throws IOException {
+ Web3j web3j = Web3j.build(new HttpService("http://192.168.120.150:6789"));
+ PlatonChainId send = web3j.getChainId().send();
+ Assert.assertTrue(send.getError() != null);
+ }
+
+ /**
+ * 底层1.1.0版本
+ * @throws IOException
+ */
+ @Test
+ public void testChainId_version16_0_0() throws IOException {
+ Web3j web3j = Web3j.build(new HttpService("http://192.168.120.150:6780"));
+ PlatonChainId send = web3j.getChainId().send();
+ Assert.assertTrue(send.getError() == null);
+ }
+
+ /**
+ * 底层1.0.0版本
+ * @throws IOException
+ */
+ @Test
+ public void testGetWaitSlashingNodeList_version15_0_0() throws IOException {
+ Web3j web3j = Web3j.build(new HttpService("http://192.168.120.150:6789"));
+ DebugWaitSlashingNodeList nodeList = web3j.getWaitSlashingNodeList().send();
+ Assert.assertTrue(nodeList.getResult() != null);
+ Assert.assertTrue(nodeList.getError() == null);
+ }
+
+ /**
+ * 底层1.1.0版本
+ * @throws IOException
+ */
+ @Test
+ public void testGetWaitSlashingNodeList_version16_0_0() throws IOException {
+ Web3j web3j = Web3j.build(new HttpService("http://192.168.120.150:6780"));
+ DebugWaitSlashingNodeList nodeList = web3j.getWaitSlashingNodeList().send();
+ Assert.assertTrue(nodeList.getResult() != null);
+ Assert.assertTrue(nodeList.getError() == null);
+ }
+}
\ No newline at end of file
diff --git a/utils/src/main/java/com/platon/crypto/Hash.java b/utils/src/main/java/com/platon/crypto/Hash.java
index 9eeea0fe..0bc583d7 100644
--- a/utils/src/main/java/com/platon/crypto/Hash.java
+++ b/utils/src/main/java/com/platon/crypto/Hash.java
@@ -1,6 +1,10 @@
package com.platon.crypto;
import com.platon.utils.Numeric;
+import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+import org.bouncycastle.crypto.digests.SHA512Digest;
+import org.bouncycastle.crypto.macs.HMac;
+import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jcajce.provider.digest.Keccak;
import java.nio.charset.StandardCharsets;
@@ -74,4 +78,22 @@ public static byte[] sha256(byte[] input) {
throw new RuntimeException("Couldn't find a SHA-256 provider", e);
}
}
+
+ public static byte[] hmacSha512(byte[] key, byte[] input) {
+ HMac hMac = new HMac(new SHA512Digest());
+ hMac.init(new KeyParameter(key));
+ hMac.update(input, 0, input.length);
+ byte[] out = new byte[64];
+ hMac.doFinal(out, 0);
+ return out;
+ }
+
+ public static byte[] sha256hash160(byte[] input) {
+ byte[] sha256 = sha256(input);
+ RIPEMD160Digest digest = new RIPEMD160Digest();
+ digest.update(sha256, 0, sha256.length);
+ byte[] out = new byte[20];
+ digest.doFinal(out, 0);
+ return out;
+ }
}