diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..51494ea33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.gradle/ +.idea/ +build \ No newline at end of file diff --git a/build.gradle b/build.gradle index 08b0ab1cc..bae34f7ba 100644 --- a/build.gradle +++ b/build.gradle @@ -15,18 +15,22 @@ apply plugin: 'jacoco' repositories { // Use jcenter for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. - jcenter() - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + //jcenter() + mavenLocal() + mavenCentral() + maven { url 'https://dl.bintray.com/ethereum/maven/' } + maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } sourceCompatibility = '1.8' version = '3.0.0' -task javadocJar(type: Jar) { - // from javadoc - classifier = 'javadoc' -} +//task javadocJar(type: Jar) { +// // from javadoc +// classifier = 'javadoc' +//} googleJavaFormat { options style: 'AOSP' @@ -45,3 +49,19 @@ jacocoTestReport { html.enabled false } } + +dependencies { + compile 'org.apache.commons:commons-lang3:3.1' + compile 'io.netty:netty-all:4.1.50.Final' + compile 'com.fasterxml.jackson.core:jackson-databind:2.11.0' + compile group: 'commons-codec', name: 'commons-codec', version: '1.14' + + + + testCompile 'junit:junit:4.12' + testCompile 'org.mockito:mockito-core:2.23.0' +} + +archivesBaseName = 'java-sdk' +group = 'org.fisco-bcos' +version = '1.0.0-SNAPSHOT' \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..2fe81a7d9 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..9109989e3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/org/fisco/bcos/sdk/amop/AMOP.java b/src/main/java/org/fisco/bcos/sdk/amop/AMOP.java new file mode 100644 index 000000000..f725e8ba8 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/amop/AMOP.java @@ -0,0 +1,67 @@ +package org.fisco.bcos.sdk.amop; + +import java.util.List; +import org.fisco.bcos.sdk.channel.Channel; + +/** + * AMOP module interface + * + * @author Maggie + */ +public interface AMOP { + /** + * Create a AMOP object + * + * @param channel + * @param configFile + * @return AMOP instance + */ + static AMOP build(Channel channel, String configFile) { + // TODO + return null; + } + + /** + * Subscribe a normal topic + * + * @param topicName + */ + void subscribeTopic(String topicName); + + /** + * Subscribe a topic which need verify + * + * @param topicName + * @param privateKey + */ + void subscribeNeedVerifyTopics(String topicName, String privateKey); + + /** + * Config a topic which is need verification, after that user can send message to verified + * subscriber. + * + * @param topicName + * @param publicKeys + */ + void addNeedVerifyTopics(String topicName, List publicKeys); + + /** + * Unsubscribe a topic + * + * @param topicName + */ + void unsubscribeTopic(String topicName); + + /** + * Get all subscribe topics + * + * @return topic name list + */ + List getSubTopics(); + + /** Start */ + void start(); + + /** Stop */ + void stop(); +} diff --git a/src/main/java/org/fisco/bcos/sdk/channel/Channel.java b/src/main/java/org/fisco/bcos/sdk/channel/Channel.java new file mode 100644 index 000000000..e9a4dc345 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/channel/Channel.java @@ -0,0 +1,81 @@ +package org.fisco.bcos.sdk.channel; + +import java.util.List; +import org.fisco.bcos.sdk.model.Message; +import org.fisco.bcos.sdk.model.MsgType; + +public interface Channel { + /** + * Init channel module + * + * @param filepath config file path. + * @return + */ + Channel build(String filepath); + + /** + * Add a message handler to handle specific type messages. When one message comes the handler + * will be notified, handler.onMessage(ChannleHandlerContext ctx, Message msg) called. + * + * @param type + * @param handler + */ + void addMessageHandler(MsgType type, MsgHandler handler); + + /** + * Add a connect handler, when one connect success, call handler.onConnect(ChannleHandlerContext + * ctx)is called + * + * @param handler + */ + void addConnectHandler(MsgHandler handler); + + /** + * Add a disconnect handler, when one connection disconnect, + * handler.onDisconnect(ChannleHandlerContext ctx) is called + * + * @param handler + */ + void addDisconnectHandler(MsgHandler handler); + + /** + * Send message to peer + * + * @param out message + * @param peerIpPort the peer to send to + * @param callback response callback + */ + void sendToPeer(Message out, String peerIpPort, ResponseCallback callback); + + /** + * Send to a best peer with highest block height in Group + * + * @param out + * @param groupId + * @param callback + */ + void sendToGroup(Message out, String groupId, ResponseCallback callback); + + /** + * Broadcast to all peer + * + * @param out + * @param callback + */ + void broadcast(Message out, ResponseCallback callback); + + /** + * Send to an random peer + * + * @param out + * @param callback + */ + void sendToRandom(Message out, ResponseCallback callback); + + /** + * Get connection information + * + * @return List of connection information + */ + List getConnectionInfo(); +} diff --git a/src/main/java/org/fisco/bcos/sdk/channel/ConnectionInfo.java b/src/main/java/org/fisco/bcos/sdk/channel/ConnectionInfo.java new file mode 100644 index 000000000..c5123d0dd --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/channel/ConnectionInfo.java @@ -0,0 +1,4 @@ +package org.fisco.bcos.sdk.channel; + +/** Connection information */ +public class ConnectionInfo {} diff --git a/src/main/java/org/fisco/bcos/sdk/channel/MsgHandler.java b/src/main/java/org/fisco/bcos/sdk/channel/MsgHandler.java new file mode 100644 index 000000000..ed8594a3f --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/channel/MsgHandler.java @@ -0,0 +1,33 @@ +package org.fisco.bcos.sdk.channel; + +import io.netty.channel.ChannelHandlerContext; +import org.fisco.bcos.sdk.model.Message; + +/** + * Message handler interface Each module which would like to get notified by the "network" module + * should implement this interface + */ +public interface MsgHandler { + + /** + * OnConnect action. Called when connect success. + * + * @param ctx ChannelHandlerContext of the connection from netty + */ + void onConnect(ChannelHandlerContext ctx); + + /** + * OnMessage action. Called when one message comes from the network. + * + * @param ctx ChannelHandlerContext of the connection from netty + * @param msg Message from the network + */ + void onMessage(ChannelHandlerContext ctx, Message msg); + + /** + * OnDisconnect action Called when one connection disconnect. + * + * @param ctx ChannelHandlerContext of the connection from netty + */ + void onDisconnect(ChannelHandlerContext ctx); +} diff --git a/src/main/java/org/fisco/bcos/sdk/channel/PeerSelectRule.java b/src/main/java/org/fisco/bcos/sdk/channel/PeerSelectRule.java new file mode 100644 index 000000000..bd53d3866 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/channel/PeerSelectRule.java @@ -0,0 +1,13 @@ +package org.fisco.bcos.sdk.channel; + +import java.util.List; + +public interface PeerSelectRule { + /** + * PeerSelectRule Costomize a rule to select a peer to send message to + * + * @param conns + * @return + */ + String select(List conns); +} diff --git a/src/main/java/org/fisco/bcos/sdk/channel/ResponseCallback.java b/src/main/java/org/fisco/bcos/sdk/channel/ResponseCallback.java new file mode 100644 index 000000000..301ab54f0 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/channel/ResponseCallback.java @@ -0,0 +1,16 @@ +package org.fisco.bcos.sdk.channel; + +import org.fisco.bcos.sdk.model.Message; +import org.fisco.bcos.sdk.model.Response; + +/** ResponseCallback is to define a callback to handle response from node */ +public abstract class ResponseCallback { + private Message message; + + /** + * OnResponse + * + * @param response + */ + public abstract void onResponse(Response response); +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/Client.java b/src/main/java/org/fisco/bcos/sdk/client/Client.java new file mode 100644 index 000000000..83f279e3e --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/Client.java @@ -0,0 +1,771 @@ +package org.fisco.bcos.sdk.client; + +import java.math.BigInteger; +import java.util.List; +import org.fisco.bcos.sdk.channel.Channel; +import org.fisco.bcos.sdk.client.request.DefaultBlockParameter; +import org.fisco.bcos.sdk.client.request.Transaction; +import org.fisco.bcos.sdk.client.response.*; + +/** Client This is the interface of client module */ +public interface Client { + /** + * Build a client instance GroupId is identified, all interfaces are available + * + * @param channel + * @param GroupId + * @return + */ + static Client build(Channel channel, String GroupId) { + // TODO + return null; + } + + /** + * Build a client instance Can only call interfaces relate to group management and node + * management + * + * @param channel + * @return + */ + static Client build(Channel channel) { + // TODO + return null; + } + + /** + * Ledger operation: send transaction + * + * @param signedTransactionData transaction string + * @return SendTransaction + */ + SendTransaction sendRawTransaction(String signedTransactionData); + + /** + * Ledger operation: async send transaction + * + * @param signedTransactionData + * @param callback + */ + void sendRawTransactionAsync( + String signedTransactionData, RespCallback callback); + + /** + * Ledger operation: call contract functions without sending transaction + * + * @param transaction + * @return Call + */ + Call call(Transaction transaction); + + /** + * Ledger operation: async call contract functions without sending transaction + * + * @param transaction + * @param callback + */ + void callAsync(Transaction transaction, RespCallback callback); + + /** + * Ledger operation: send raw transaction and get proof + * + * @param signedTransactionData + * @return + */ + SendTransaction sendRawTransactionAndGetProof(String signedTransactionData); + + /** + * Ledger operation: async send transaction and get proof + * + * @param signedTransactionData + * @param callback + */ + void sendRawTransactionAndGetProofAsync( + String signedTransactionData, RespCallback callback); + + /** + * Ledger operation: get block number + * + * @return block number + */ + BlockNumber getBlockNumber(); + + /** + * Ledger operation: async get block number + * + * @param callback + */ + void getBlockNumberAsync(RespCallback callback); + + /** + * Ledger operation: get code + * + * @param address + * @return + */ + Code getCode(String address); + + /** + * Ledger operation: async get code + * + * @param address + * @param callback + */ + void getCodeAsync(String address, RespCallback callback); + + /** + * Ledger operation: get total transaction count + * + * @return TotalTransactionCount + */ + TotalTransactionCount getTotalTransactionCount(); + + /** + * Ledger operation: async get total transaction count + * + * @param callback + */ + void getTotalTransactionCountAsync(RespCallback callback); + + /** + * Ledger operation: get block by hash + * + * @param blockHash + * @param returnFullTransactionObjects + * @return + */ + BcosBlock getBlockByHash(String blockHash, boolean returnFullTransactionObjects); + + /** + * Ledger operation: async get block by hash + * + * @param blockHash + * @param returnFullTransactionObjects + * @param callback + */ + void getBlockByHashAsync( + String blockHash, + boolean returnFullTransactionObjects, + RespCallback callback); + + /** + * Ledger operation: get block by block number + * + * @param blockNumber + * @param returnFullTransactionObjects + * @return block + */ + BcosBlock getBlockByNumber(BigInteger blockNumber, boolean returnFullTransactionObjects); + + /** + * Ledger operation: async get block by block number + * + * @param blockNumber + * @param returnFullTransactionObjects + * @param callback + */ + void getBlockByNumberAsync( + BigInteger blockNumber, + boolean returnFullTransactionObjects, + RespCallback callback); + + /** + * Ledger operation: get block hash by block number + * + * @param blockNumber + * @return block hash + */ + BlockHash getBlockHashByNumber(BigInteger blockNumber); + + /** + * Ledger operation: async get block hash by block number + * + * @param blockNumber + * @param callback + */ + void getBlockHashByNumberAsync(BigInteger blockNumber, RespCallback callback); + + /** + * Ledger operation: get block header by block hash + * + * @param blockHash + * @param returnSealerList + * @return block header + */ + BcosBlockHeader getBlockHeaderByHash(String blockHash, boolean returnSealerList); + + /** + * Ledger operation: async get block header by block hash + * + * @param blockHash + * @param returnSealerList + * @param callback + */ + void getBlockHeaderByHashAsync( + String blockHash, boolean returnSealerList, RespCallback callback); + + /** + * Ledger operation: get trnasaction by hash + * + * @param transactionHash + * @return transaction + */ + BcosTransaction getTransactionByHash(String transactionHash); + + /** + * Ledger operation: async get trnasaction by hash + * + * @param transactionHash + * @param callback + */ + void getTransactionByHashAsync(String transactionHash, RespCallback callback); + + /** + * Ledger operation: get transaction and proof by hash + * + * @param transactionHash + * @return transaction with proof + */ + TransactionWithProof getTransactionByHashWithProof(String transactionHash); + + /** + * Ledger operation: async get transaction and proof by hash + * + * @param transactionHash + * @param callback + */ + void getTransactionByHashWithProofAsync( + String transactionHash, RespCallback callback); + + /** + * Ledger operation: get transaction by block number and index + * + * @param defaultBlockParameter + * @param transactionIndex + * @return transaction + */ + BcosTransaction getTransactionByBlockNumberAndIndex( + DefaultBlockParameter defaultBlockParameter, BigInteger transactionIndex); + + /** + * Ledger operation: async get transaction by block number and index + * + * @param defaultBlockParameter + * @param transactionIndex + * @param callback + */ + void getTransactionByBlockNumberAndIndexAsync( + DefaultBlockParameter defaultBlockParameter, + BigInteger transactionIndex, + RespCallback callback); + + /** + * Ledger operation: get transaction receipt by transaction hash + * + * @param transactionHash + * @return + */ + BcosTransactionReceipt getTransactionReceipt(String transactionHash); + + /** + * Ledger operation: async get transaction receipt by transaction hash + * + * @param transactionHash + * @param callback + */ + void getTransactionReceiptAsync( + String transactionHash, RPCResponse callback); + + /** + * Ledger operation: get transaction receipt and proof by transaction hash + * + * @param transactionHash + * @return + */ + TransactionReceiptWithProof getTransactionReceiptByHashWithProof(String transactionHash); + + /** + * Ledger operation: async get transaction receipt and proof by transaction hash + * + * @param transactionHash + * @param callback + */ + void getTransactionReceiptByHashWithProofAsync( + String transactionHash, RPCResponse callback); + + /** + * Ledger operation: get pending transactions in transaction pool + * + * @return pending transactions + */ + PendingTransactions getPendingTransaction(); + + /** + * Ledger operation: async get pending transactions in transaction pool + * + * @param callback + */ + void getPendingTransactionAsync(RPCResponse callback); + + /** + * Ledger operation: get pending transaction size + * + * @return PendingTxSize + */ + PendingTxSize getPendingTxSize(); + + /** + * Ledger operation: async get pending transaction size + * + * @param callback + */ + void getPendingTxSizeAsync(RPCResponse callback); + + /** + * Get cached block height + * + * @return block number + */ + BigInteger getBlockNumberCache(); + + /** + * Group operation: generate a new group + * + * @param groupId + * @param timestamp + * @param enableFreeStorage + * @param nodeList + * @return generate group reply message + */ + GenerateGroup generateGroup( + int groupId, long timestamp, boolean enableFreeStorage, List nodeList); + + /** + * Group operation: generate a new group + * + * @param groupId + * @param timestamp + * @param enableFreeStorage + * @param nodeList + * @param peerIpPort send to the specific peer + * @return generate group reply message + */ + GenerateGroup generateGroup( + int groupId, + long timestamp, + boolean enableFreeStorage, + List nodeList, + String peerIpPort); + + /** + * Group operation: async generate a new group + * + * @param groupId + * @param timestamp + * @param enableFreeStorage + * @param nodeList + * @param callback + */ + void generateGroupAsync( + int groupId, + long timestamp, + boolean enableFreeStorage, + List nodeList, + RespCallback callback); + + /** + * Group operation: async generate a new group + * + * @param groupId + * @param timestamp + * @param enableFreeStorage + * @param nodeList + * @param peerIpPort send to the specific peer + * @param callback + */ + void generateGroupAsync( + int groupId, + long timestamp, + boolean enableFreeStorage, + List nodeList, + String peerIpPort, + RespCallback callback); + + /** + * Group operation: start a group + * + * @param groupId + * @return start group rpc reply + */ + StartGroup startGroup(int groupId); + + /** + * Group operation: async start a group + * + * @param groupId + * @param callback + */ + void startGroupAsync(int groupId, RespCallback callback); + + /** + * Group operation: start a group + * + * @param groupId + * @param peerIpPort + * @return start group rpc reply + */ + StartGroup startGroup(int groupId, String peerIpPort); + + /** + * Group operation: async start a group + * + * @param groupId + * @param peerIpPort + * @param callback + */ + void startGroupAsync(int groupId, String peerIpPort, RespCallback callback); + + /** + * Group operation: stop a group + * + * @param groupId + * @return stop group rpc reply + */ + StopGroup stopGroup(int groupId); + + /** + * Group operation: async stop a group + * + * @param groupId + * @param callback + */ + void stopGroupAsync(int groupId, RespCallback callback); + + /** + * Group operation: stop a group + * + * @param groupId + * @param peerIpPort + * @return stop group rpc reply + */ + StopGroup stopGroup(int groupId, String peerIpPort); + + /** + * Group operation: async stop a group + * + * @param groupId + * @param peerIpPort + * @param callback + */ + void stopGroupAsync(int groupId, String peerIpPort, RespCallback callback); + + /** + * Group operation: remove a group + * + * @param groupId + * @return remove group rpc reply + */ + RemoveGroup removeGroup(int groupId); + + /** + * Group operation: async remove a group + * + * @param groupId + * @param callback + */ + void removeGroupAsync(int groupId, RespCallback callback); + + /** + * Group operation: remove a group + * + * @param groupId + * @param peerIpPort + * @return remove group rpc reply + */ + RemoveGroup removeGroup(int groupId, String peerIpPort); + + /** + * Group operation: async remove a group + * + * @param groupId + * @param peerIpPort + * @param callback + */ + void removeGroupAsync(int groupId, String peerIpPort, RespCallback callback); + + /** + * Group operation: recover a group + * + * @param groupId + * @return recover group rpc reply + */ + RecoverGroup recoverGroup(int groupId); + + /** + * Group operation: async recover a group + * + * @param groupId + * @param callback + */ + void recoverGroupAsync(int groupId, RespCallback callback); + + /** + * Group operation: recover a group + * + * @param groupId + * @param peerIpPort + * @return recover group rpc reply + */ + RecoverGroup recoverGroup(int groupId, String peerIpPort); + + /** + * Group operation: async recover a group + * + * @param groupId + * @param peerIpPort + * @param callback + */ + void recoverGroupAsync(int groupId, String peerIpPort, RespCallback callback); + + /** + * Group operation: query group status + * + * @param groupId + * @return group status + */ + QueryGroupStatus queryGroupStatus(int groupId); + + /** + * Group operation: async query group status + * + * @param groupId + * @param callback + */ + void queryGroupStatusAsync(int groupId, RespCallback callback); + + /** + * Group operation: query group status + * + * @param groupId + * @param peerIpPort + * @return group status + */ + QueryGroupStatus queryGroupStatus(int groupId, String peerIpPort); + + /** + * Group operation: async query group status + * + * @param groupId + * @param peerIpPort + * @param callback + */ + void queryGroupStatusAsync( + int groupId, String peerIpPort, RespCallback callback); + + /** + * Group operation: get peer group list + * + * @return grouplist + */ + GroupList getGroupList(); + + /** + * Group operation: get peer group list + * + * @param peerIpPort send to the specific peer + * @return grouplist + */ + GroupList getGroupList(String peerIpPort); + + /** + * Group operation: async get peer group list + * + * @param callback + */ + void getGroupListAsync(RespCallback callback); + + /** + * Group operation: async get peer group list + * + * @param peerIpPort send to the specific peer + * @param callback + */ + void getGroupListAsync(String peerIpPort, RespCallback callback); + + /** + * Group operation: get group peers + * + * @return + */ + GroupPeers getGroupPeers(); + + /** + * Group operation: async get group peers + * + * @param callback + */ + void getGroupPeersAsync(RespCallback callback); + + /** + * Group operation: get group peers + * + * @param peerIpPort + * @return + */ + GroupPeers getGroupPeers(String peerIpPort); + + /** + * Group operation: async get group peers + * + * @param peerIpPort + * @param callback + */ + void getGroupPeersAsync(String peerIpPort, RespCallback callback); + + /** + * Peer operation: get connected peers + * + * @return peers + */ + Peers getPeers(); + + /** + * Peer operation: async get connected peers + * + * @param callback + */ + void getPeersAsync(RespCallback callback); + + /** + * Peer operation: get node ids + * + * @return + */ + NodeIDList getNodeIDList(); + + /** + * Peer operation: async get node ids + * + * @param callback + */ + void getNodeIDListAsync(RespCallback callback); + + /** + * Peer operation: get observer node list + * + * @return observer node list + */ + ObserverList getObserverList(); + + /** + * Peer operation: async get observer node list + * + * @param callback + */ + void getObserverList(RespCallback callback); + + /** + * Peer operation: get sealer node list + * + * @return sealer node list + */ + SealerList getSealerList(); + + /** + * Peer operation: async get sealer node list + * + * @param callback + */ + void getSealerListAsync(RespCallback callback); + + /** + * Peer operation: get pbft view + * + * @return pbft view + */ + PbftView getPbftView(); + + /** + * Peer operation: async get pbft view + * + * @param callback + */ + void getPbftViewAsync(RespCallback callback); + + /** + * Peer operation: get node version + * + * @return node version + */ + NodeVersion getNodeVersion(); + + /** + * Peer operation: get node version + * + * @param callback + */ + void getNodeVersion(RespCallback callback); + + /** + * Peer operation: get consensus status + * + * @return consensus status + */ + ConsensusStatus getConsensusStatus(); + + /** + * Peer operation: async get consensus status + * + * @param callback + */ + void getConsensusStates(RespCallback callback); + + /** + * Peer operation: get system config + * + * @param key + * @return system config + */ + SystemConfig getSystemConfigByKey(String key); + + /** + * Peer operation: get system config + * + * @param key + * @param peerIpPort + * @return system config + */ + SystemConfig getSystemConfigByKey(String key, String peerIpPort); + + /** + * Peer operation: async get system config + * + * @param key + * @param callback + */ + void getSystemConfigByKeyAsync(String key, RespCallback callback); + + /** + * Peer operation: async get system config + * + * @param key + * @param peerIpPort + * @param callback + */ + void getSystemConfigByKeyAsync( + String key, String peerIpPort, RespCallback callback); + + /** + * Peer operation: get sync status + * + * @return sync status + */ + SyncStatus getSyncStatus(); + + /** + * Peer operation: async get sync status + * + * @param callback + */ + void getSyncStatus(RespCallback callback); +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/ObjectMapperFactory.java b/src/main/java/org/fisco/bcos/sdk/client/ObjectMapperFactory.java new file mode 100644 index 000000000..eab3a8797 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/ObjectMapperFactory.java @@ -0,0 +1,66 @@ +package org.fisco.bcos.sdk.client; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; +import com.fasterxml.jackson.databind.module.SimpleModule; +import org.fisco.bcos.sdk.client.serializer.RawResponseDeserializer; + +/** Factory for managing our ObjectMapper instances. */ +public class ObjectMapperFactory { + + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); + + static { + configureObjectMapper(DEFAULT_OBJECT_MAPPER, false); + } + + public static ObjectMapper getObjectMapper() { + return getObjectMapper(false); + } + + public static ObjectMapper getObjectMapper(boolean shouldIncludeRawResponses) { + if (!shouldIncludeRawResponses) { + return DEFAULT_OBJECT_MAPPER; + } + + return configureObjectMapper(new ObjectMapper(), true); + } + + public static ObjectReader getObjectReader() { + return DEFAULT_OBJECT_MAPPER.reader(); + } + + private static ObjectMapper configureObjectMapper( + ObjectMapper objectMapper, boolean shouldIncludeRawResponses) { + if (shouldIncludeRawResponses) { + SimpleModule module = new SimpleModule(); + module.setDeserializerModifier( + new BeanDeserializerModifier() { + @Override + public JsonDeserializer modifyDeserializer( + DeserializationConfig config, + BeanDescription beanDesc, + JsonDeserializer deserializer) { + if (RPCResponse.class.isAssignableFrom(beanDesc.getBeanClass())) { + return new RawResponseDeserializer(deserializer); + } + + return deserializer; + } + }); + + objectMapper.registerModule(module); + } + + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + return objectMapper; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/RPCResponse.java b/src/main/java/org/fisco/bcos/sdk/client/RPCResponse.java new file mode 100644 index 000000000..59130c15d --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/RPCResponse.java @@ -0,0 +1,131 @@ +package org.fisco.bcos.sdk.client; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * Response template + * + * @author Maggie + * @param the response data structure + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class RPCResponse { + private long id; + private String jsonrpc; + private T result; + private Error error; + private String rawResponse; + + public RPCResponse() {} + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getJsonrpc() { + return jsonrpc; + } + + public void setJsonrpc(String jsonrpc) { + this.jsonrpc = jsonrpc; + } + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + public Error getError() { + return error; + } + + public void setError(Error error) { + this.error = error; + } + + public boolean hasError() { + return error != null; + } + + public String getRawResponse() { + return rawResponse; + } + + public void setRawResponse(String rawResponse) { + this.rawResponse = rawResponse; + } + + public static class Error { + private int code; + private String message; + private String data; + + public Error() {} + + public Error(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Error)) { + return false; + } + + Error error = (Error) o; + + if (getCode() != error.getCode()) { + return false; + } + if (getMessage() != null + ? !getMessage().equals(error.getMessage()) + : error.getMessage() != null) { + return false; + } + return getData() != null ? getData().equals(error.getData()) : error.getData() == null; + } + + @Override + public int hashCode() { + int result = getCode(); + result = 31 * result + (getMessage() != null ? getMessage().hashCode() : 0); + result = 31 * result + (getData() != null ? getData().hashCode() : 0); + return result; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/RespCallback.java b/src/main/java/org/fisco/bcos/sdk/client/RespCallback.java new file mode 100644 index 000000000..5368b8374 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/RespCallback.java @@ -0,0 +1,16 @@ +package org.fisco.bcos.sdk.client; + +/** + * Callback function to executed when client get response from the node. + * + * @author Maggie + * @param for the response data structures in package client/response + */ +public interface RespCallback { + /** + * onResponse is the call back function + * + * @param t the response data structure + */ + void onResponse(T t); +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameter.java b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameter.java new file mode 100644 index 000000000..2bd6ff7fa --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameter.java @@ -0,0 +1,21 @@ +package org.fisco.bcos.sdk.client.request; + +import java.math.BigInteger; + +/** + * Wrapper for parameter that takes either a block number or block name as input + * + *

See the + * specification for further information. + */ +public interface DefaultBlockParameter { + static DefaultBlockParameter valueOf(BigInteger blockNumber) { + return new DefaultBlockParameterNumber(blockNumber); + } + + static DefaultBlockParameter valueOf(String blockName) { + return DefaultBlockParameterName.fromString(blockName); + } + + String getValue(); +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterName.java b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterName.java new file mode 100644 index 000000000..7f372f006 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterName.java @@ -0,0 +1,33 @@ +package org.fisco.bcos.sdk.client.request; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DefaultBlockParameterName implements DefaultBlockParameter { + EARLIEST("earliest"), + LATEST("latest"), + PENDING("pending"); + + private String name; + + DefaultBlockParameterName(String name) { + this.name = name; + } + + @JsonValue + @Override + public String getValue() { + return name; + } + + public static DefaultBlockParameterName fromString(String name) { + if (name != null) { + for (DefaultBlockParameterName defaultBlockParameterName : + DefaultBlockParameterName.values()) { + if (name.equalsIgnoreCase(defaultBlockParameterName.name)) { + return defaultBlockParameterName; + } + } + } + return valueOf(name); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterNumber.java b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterNumber.java new file mode 100644 index 000000000..50c2e54ef --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/request/DefaultBlockParameterNumber.java @@ -0,0 +1,29 @@ +package org.fisco.bcos.sdk.client.request; + +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigInteger; +import org.fisco.bcos.sdk.utils.Numeric; + +/** DefaultBlockParameter implementation that takes a numeric value. */ +public class DefaultBlockParameterNumber implements DefaultBlockParameter { + + private BigInteger blockNumber; + + public DefaultBlockParameterNumber(BigInteger blockNumber) { + this.blockNumber = blockNumber; + } + + public DefaultBlockParameterNumber(long blockNumber) { + this(BigInteger.valueOf(blockNumber)); + } + + @Override + @JsonValue + public String getValue() { + return Numeric.encodeQuantity(blockNumber); + } + + public BigInteger getBlockNumber() { + return blockNumber; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/request/Transaction.java b/src/main/java/org/fisco/bcos/sdk/client/request/Transaction.java new file mode 100644 index 000000000..d84ffad69 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/request/Transaction.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.client.request; + +public class Transaction {} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/AbiDefinition.java b/src/main/java/org/fisco/bcos/sdk/client/response/AbiDefinition.java new file mode 100644 index 000000000..741283182 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/AbiDefinition.java @@ -0,0 +1,315 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** AbiDefinition wrapper. */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AbiDefinition { + private boolean constant; + private List inputs; + private String name; + private List outputs; + private String type; + private boolean payable; + + private String stateMutability; + + public AbiDefinition() {} + + public AbiDefinition( + boolean constant, + List inputs, + String name, + List outputs, + String type, + boolean payable) { + this(constant, inputs, name, outputs, type, payable, null); + } + + public AbiDefinition( + boolean constant, + List inputs, + String name, + List outputs, + String type, + boolean payable, + String stateMutability) { + this.constant = constant; + this.inputs = inputs; + this.name = name; + this.outputs = outputs; + this.type = type; + this.payable = payable; + this.stateMutability = stateMutability; + } + + public boolean isConstant() { + return constant; + } + + public void setConstant(boolean constant) { + this.constant = constant; + } + + public List getInputs() { + return inputs; + } + + public void setInputs(List inputs) { + this.inputs = inputs; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getOutputs() { + return outputs; + } + + public boolean hasOutputs() { + return !outputs.isEmpty(); + } + + public void setOutputs(List outputs) { + this.outputs = outputs; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isPayable() { + return payable; + } + + public void setPayable(boolean payable) { + this.payable = payable; + } + + public String getStateMutability() { + return stateMutability; + } + + public void setStateMutability(String stateMutability) { + this.stateMutability = stateMutability; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof AbiDefinition)) { + return false; + } + + AbiDefinition that = (AbiDefinition) o; + + if (isConstant() != that.isConstant()) { + return false; + } + if (isPayable() != that.isPayable()) { + return false; + } + if (getInputs() != null + ? !getInputs().equals(that.getInputs()) + : that.getInputs() != null) { + return false; + } + if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) { + return false; + } + if (getOutputs() != null + ? !getOutputs().equals(that.getOutputs()) + : that.getOutputs() != null) { + return false; + } + if (getStateMutability() != null + ? !getStateMutability().equals(that.getStateMutability()) + : that.getStateMutability() != null) { + return false; + } + return getType() != null ? getType().equals(that.getType()) : that.getType() == null; + } + + @Override + public int hashCode() { + int result = (isConstant() ? 1 : 0); + result = 31 * result + (getInputs() != null ? getInputs().hashCode() : 0); + result = 31 * result + (getName() != null ? getName().hashCode() : 0); + result = 31 * result + (getOutputs() != null ? getOutputs().hashCode() : 0); + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (isPayable() ? 1 : 0); + result = 31 * result + (getStateMutability() != null ? getStateMutability().hashCode() : 0); + return result; + } + + public static class NamedType { + + private String name; + private String type; + private Type type0; + private boolean indexed; + + public NamedType() {} + + public NamedType(String name, String type) { + this.name = name; + this.type = type; + this.setType0(new Type(name)); + } + + public NamedType(String name, String type, boolean indexed) { + this.name = name; + this.type = type; + this.indexed = indexed; + this.setType0(new Type(name)); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isIndexed() { + return indexed; + } + + public void setIndexed(boolean indexed) { + this.indexed = indexed; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NamedType)) { + return false; + } + + NamedType namedType = (NamedType) o; + + if (isIndexed() != namedType.isIndexed()) { + return false; + } + + if (getName() != null + ? !getName().equals(namedType.getName()) + : namedType.getName() != null) { + return false; + } + return getType() != null + ? getType().equals(namedType.getType()) + : namedType.getType() == null; + } + + @Override + public int hashCode() { + int result = getName() != null ? getName().hashCode() : 0; + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (isIndexed() ? 1 : 0); + return result; + } + + public Type getType0() { + return type0; + } + + public void setType0(Type type0) { + this.type0 = type0; + } + + public static class Type { + public String name; + public String baseName; + public List depth = new ArrayList(); + + public Type(String name) { + int index = name.indexOf("["); + this.baseName = (-1 == index) ? name.trim() : name.substring(0, index); + + this.name = name; + this.doParser(); + } + + private void doParser() { + Pattern p = Pattern.compile("\\[[0-9]{0,}\\]"); + Matcher m = p.matcher(name); + while (m.find()) { + String s = m.group(); + String dig = s.substring(s.indexOf("[") + 1, s.indexOf("]")).trim(); + if (dig.isEmpty()) { + depth.add(new Integer(0)); + } else { + depth.add(Integer.valueOf(dig)); + } + } + } + + @Override + public String toString() { + return "Type [name=" + name + ", baseName=" + baseName + ", depth=" + depth + "]"; + } + + public String getName() { + return name; + } + + public int getDimensions() { + if (arrayType()) { + return depth.get(depth.size() - 1); + } + return 0; + } + + public String getBaseName() { + return baseName; + } + + public boolean arrayType() { + return 0 != getDepth(); + } + + public boolean staticArray() { + return arrayType() && (depth.get(depth.size() - 1) > 0); + } + + public boolean dynamicArray() { + return arrayType() && (depth.get(depth.size() - 1) == 0); + } + + public int getDepth() { + return depth.size(); + } + + public List getDepthArray() { + return depth; + } + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlock.java b/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlock.java new file mode 100644 index 000000000..b692ae72c --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlock.java @@ -0,0 +1,581 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.fisco.bcos.sdk.client.ObjectMapperFactory; +import org.fisco.bcos.sdk.utils.Numeric; + +public class BcosBlock extends RPCRPCResponse { + + @Override + @JsonDeserialize(using = BcosBlock.ResponseDeserialiser.class) + public void setResult(Block result) { + super.setResult(result); + } + + public Block getBlock() { + return getResult(); + } + + public static class Block { + private String number; + private String hash; + private String parentHash; + private String nonce; + private String sha3Uncles; + private String logsBloom; + private String transactionsRoot; + private String stateRoot; + private String receiptsRoot; + private String author; + private String sealer; + private String mixHash; + private List extraData; + private String gasLimit; + private String gasUsed; + private String timestamp; + private List transactions; + private List uncles; + private List sealerList; + + public Block() {} + + @Override + public String toString() { + return "Block [number=" + + number + + ", hash=" + + hash + + ", parentHash=" + + parentHash + + ", nonce=" + + nonce + + ", sha3Uncles=" + + sha3Uncles + + ", logsBloom=" + + logsBloom + + ", transactionsRoot=" + + transactionsRoot + + ", stateRoot=" + + stateRoot + + ", receiptsRoot=" + + receiptsRoot + + ", author=" + + author + + ", sealer=" + + sealer + + ", mixHash=" + + mixHash + + ", extraData=" + + extraData + + ", gasLimit=" + + gasLimit + + ", gasUsed=" + + gasUsed + + ", timestamp=" + + timestamp + + ", transactions=" + + transactions + + ", uncles=" + + uncles + + ", sealFields=" + + sealerList + + "]"; + } + + public Block( + String number, + String hash, + String parentHash, + String nonce, + String sha3Uncles, + String logsBloom, + String transactionsRoot, + String stateRoot, + String receiptsRoot, + String author, + String sealer, + String mixHash, + List extraData, + String gasLimit, + String gasUsed, + String timestamp, + List transactions, + List uncles, + List sealerList) { + this.number = number; + this.hash = hash; + this.parentHash = parentHash; + this.nonce = nonce; + this.sha3Uncles = sha3Uncles; + this.logsBloom = logsBloom; + this.transactionsRoot = transactionsRoot; + this.stateRoot = stateRoot; + this.receiptsRoot = receiptsRoot; + this.author = author; + this.sealer = sealer; + this.mixHash = mixHash; + this.extraData = extraData; + this.gasLimit = gasLimit; + this.gasUsed = gasUsed; + this.timestamp = timestamp; + this.transactions = transactions; + this.uncles = uncles; + this.sealerList = sealerList; + } + + public BigInteger getNumber() { + return Numeric.decodeQuantity(number); + } + + public String getNumberRaw() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getParentHash() { + return parentHash; + } + + public void setParentHash(String parentHash) { + this.parentHash = parentHash; + } + + public BigInteger getNonce() { + if (nonce == null) return new BigInteger("0"); + return Numeric.decodeQuantity(nonce); + } + + public String getNonceRaw() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getSha3Uncles() { + return sha3Uncles; + } + + public void setSha3Uncles(String sha3Uncles) { + this.sha3Uncles = sha3Uncles; + } + + public String getLogsBloom() { + return logsBloom; + } + + public void setLogsBloom(String logsBloom) { + this.logsBloom = logsBloom; + } + + public String getTransactionsRoot() { + return transactionsRoot; + } + + public void setTransactionsRoot(String transactionsRoot) { + this.transactionsRoot = transactionsRoot; + } + + public String getStateRoot() { + return stateRoot; + } + + public void setStateRoot(String stateRoot) { + this.stateRoot = stateRoot; + } + + public String getReceiptsRoot() { + return receiptsRoot; + } + + public void setReceiptsRoot(String receiptsRoot) { + this.receiptsRoot = receiptsRoot; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getSealer() { + return sealer; + } + + public void setSealer(String sealer) { + this.sealer = sealer; + } + + public String getMixHash() { + return mixHash; + } + + public void setMixHash(String mixHash) { + this.mixHash = mixHash; + } + + public List getExtraData() { + return extraData; + } + + public void setExtraData(List extraData) { + this.extraData = extraData; + } + + public BigInteger getGasLimit() { + return Numeric.decodeQuantity(gasLimit); + } + + public String getGasLimitRaw() { + return gasLimit; + } + + public void setGasLimit(String gasLimit) { + this.gasLimit = gasLimit; + } + + public BigInteger getGasUsed() { + return Numeric.decodeQuantity(gasUsed); + } + + public String getGasUsedRaw() { + return gasUsed; + } + + public void setGasUsed(String gasUsed) { + this.gasUsed = gasUsed; + } + + public BigInteger getTimestamp() { + return Numeric.decodeQuantity(timestamp); + } + + public String getTimestampRaw() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public List getTransactions() { + return transactions; + } + + @JsonDeserialize(using = ResultTransactionDeserialiser.class) + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + public List getUncles() { + return uncles; + } + + public void setUncles(List uncles) { + this.uncles = uncles; + } + + public List getSealerList() { + return sealerList; + } + + public void setSealerList(List sealerList) { + this.sealerList = sealerList; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Block)) { + return false; + } + + Block block = (Block) o; + + if (getNumberRaw() != null + ? !getNumberRaw().equals(block.getNumberRaw()) + : block.getNumberRaw() != null) { + return false; + } + if (getHash() != null ? !getHash().equals(block.getHash()) : block.getHash() != null) { + return false; + } + if (getParentHash() != null + ? !getParentHash().equals(block.getParentHash()) + : block.getParentHash() != null) { + return false; + } + if (getNonceRaw() != null + ? !getNonceRaw().equals(block.getNonceRaw()) + : block.getNonceRaw() != null) { + return false; + } + if (getSha3Uncles() != null + ? !getSha3Uncles().equals(block.getSha3Uncles()) + : block.getSha3Uncles() != null) { + return false; + } + if (getLogsBloom() != null + ? !getLogsBloom().equals(block.getLogsBloom()) + : block.getLogsBloom() != null) { + return false; + } + if (getTransactionsRoot() != null + ? !getTransactionsRoot().equals(block.getTransactionsRoot()) + : block.getTransactionsRoot() != null) { + return false; + } + if (getStateRoot() != null + ? !getStateRoot().equals(block.getStateRoot()) + : block.getStateRoot() != null) { + return false; + } + if (getReceiptsRoot() != null + ? !getReceiptsRoot().equals(block.getReceiptsRoot()) + : block.getReceiptsRoot() != null) { + return false; + } + if (getAuthor() != null + ? !getAuthor().equals(block.getAuthor()) + : block.getAuthor() != null) { + return false; + } + if (getSealer() != null + ? !getSealer().equals(block.getSealer()) + : block.getSealer() != null) { + return false; + } + if (getMixHash() != null + ? !getMixHash().equals(block.getMixHash()) + : block.getMixHash() != null) { + return false; + } + if (getExtraData() != null + ? !getExtraData().equals(block.getExtraData()) + : block.getExtraData() != null) { + return false; + } + if (getGasLimitRaw() != null + ? !getGasLimitRaw().equals(block.getGasLimitRaw()) + : block.getGasLimitRaw() != null) { + return false; + } + if (getGasUsedRaw() != null + ? !getGasUsedRaw().equals(block.getGasUsedRaw()) + : block.getGasUsedRaw() != null) { + return false; + } + if (getTimestampRaw() != null + ? !getTimestampRaw().equals(block.getTimestampRaw()) + : block.getTimestampRaw() != null) { + return false; + } + if (getTransactions() != null + ? !getTransactions().equals(block.getTransactions()) + : block.getTransactions() != null) { + return false; + } + if (getUncles() != null + ? !getUncles().equals(block.getUncles()) + : block.getUncles() != null) { + return false; + } + return getSealerList() != null + ? getSealerList().equals(block.getSealerList()) + : block.getSealerList() == null; + } + + @Override + public int hashCode() { + int result = getNumberRaw() != null ? getNumberRaw().hashCode() : 0; + result = 31 * result + (getHash() != null ? getHash().hashCode() : 0); + result = 31 * result + (getParentHash() != null ? getParentHash().hashCode() : 0); + result = 31 * result + (getNonceRaw() != null ? getNonceRaw().hashCode() : 0); + result = 31 * result + (getSha3Uncles() != null ? getSha3Uncles().hashCode() : 0); + result = 31 * result + (getLogsBloom() != null ? getLogsBloom().hashCode() : 0); + result = + 31 * result + + (getTransactionsRoot() != null + ? getTransactionsRoot().hashCode() + : 0); + result = 31 * result + (getStateRoot() != null ? getStateRoot().hashCode() : 0); + result = 31 * result + (getReceiptsRoot() != null ? getReceiptsRoot().hashCode() : 0); + result = 31 * result + (getAuthor() != null ? getAuthor().hashCode() : 0); + result = 31 * result + (getSealer() != null ? getSealer().hashCode() : 0); + result = 31 * result + (getMixHash() != null ? getMixHash().hashCode() : 0); + result = 31 * result + (getExtraData() != null ? getExtraData().hashCode() : 0); + result = 31 * result + (getGasLimitRaw() != null ? getGasLimitRaw().hashCode() : 0); + result = 31 * result + (getGasUsedRaw() != null ? getGasUsedRaw().hashCode() : 0); + result = 31 * result + (getTimestampRaw() != null ? getTimestampRaw().hashCode() : 0); + result = 31 * result + (getTransactions() != null ? getTransactions().hashCode() : 0); + result = 31 * result + (getUncles() != null ? getUncles().hashCode() : 0); + result = 31 * result + (getSealerList() != null ? getSealerList().hashCode() : 0); + return result; + } + } + + public interface TransactionResult { + T get(); + } + + public static class TransactionHash implements TransactionResult { + private String value; + + public TransactionHash() {} + + public TransactionHash(String value) { + this.value = value; + } + + @Override + public String get() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TransactionHash)) { + return false; + } + + TransactionHash that = (TransactionHash) o; + + return value != null ? value.equals(that.value) : that.value == null; + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + } + + public static class TransactionObject extends Transaction + implements TransactionResult { + public TransactionObject() {} + + public TransactionObject( + String hash, + String nonce, + String blockHash, + String blockNumber, + String transactionIndex, + String from, + String to, + String value, + String gasPrice, + String gas, + String input, + String creates, + String publicKey, + String raw, + String r, + String s, + int v) { + super( + hash, + nonce, + blockHash, + blockNumber, + transactionIndex, + from, + to, + value, + gasPrice, + gas, + input, + creates, + publicKey, + raw, + r, + s, + v); + } + + @Override + public Transaction get() { + return this; + } + } + + public static class ResultTransactionDeserialiser + extends JsonDeserializer> { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public List deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + + List transactionResults = new ArrayList<>(); + JsonToken nextToken = jsonParser.nextToken(); + + if (nextToken == JsonToken.START_OBJECT) { + Iterator transactionObjectIterator = + objectReader.readValues(jsonParser, TransactionObject.class); + while (transactionObjectIterator.hasNext()) { + transactionResults.add(transactionObjectIterator.next()); + } + } else if (nextToken == JsonToken.VALUE_STRING) { + jsonParser.getValueAsString(); + + Iterator transactionHashIterator = + objectReader.readValues(jsonParser, TransactionHash.class); + while (transactionHashIterator.hasNext()) { + transactionResults.add(transactionHashIterator.next()); + } + } + + return transactionResults; + } + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Block deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, Block.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlockHeader.java b/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlockHeader.java new file mode 100644 index 000000000..bad67b0fb --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BcosBlockHeader.java @@ -0,0 +1,275 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; +import org.fisco.bcos.sdk.client.RPCResponse; + +public class BcosBlockHeader extends RPCResponse { + + @Override + public void setResult(BlockHeader result) { + super.setResult(result); + } + + public BlockHeader getBlockHeader() { + return getResult(); + } + + public static class Signature { + private String index; + private String signature; + + public Signature() {} + + public Signature(String index, String signature) { + this.index = index; + this.signature = signature; + } + + public String getIndex() { + return index; + } + + public void setIndex(String index) { + this.index = index; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + } + + public static class BlockHeader { + private String dbHash; + private List extraData; + private String gasLimit; + private String gasUsed; + private String hash; + private String logsBloom; + private BigInteger number; + private String parentHash; + private String transactionsRoot; + private String sealer; + private List sealerList; + private List signatureList; + private String stateRoot; + private String receiptsRoot; + private String timestamp; + + public BlockHeader() {} + + public String getDbHash() { + return dbHash; + } + + public void setDbHash(String dbHash) { + this.dbHash = dbHash; + } + + public List getExtraData() { + return extraData; + } + + public void setExtraData(List extraData) { + this.extraData = extraData; + } + + public String getGasLimit() { + return gasLimit; + } + + public void setGasLimit(String gasLimit) { + this.gasLimit = gasLimit; + } + + public String getGasUsed() { + return gasUsed; + } + + public void setGasUsed(String gasUsed) { + this.gasUsed = gasUsed; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getLogsBloom() { + return logsBloom; + } + + public void setLogsBloom(String logsBloom) { + this.logsBloom = logsBloom; + } + + public BigInteger getNumber() { + return number; + } + + public void setNumber(BigInteger number) { + this.number = number; + } + + public String getParentHash() { + return parentHash; + } + + public void setParentHash(String parentHash) { + this.parentHash = parentHash; + } + + public String getTransactionsRoot() { + return transactionsRoot; + } + + public void setTransactionsRoot(String transactionsRoot) { + this.transactionsRoot = transactionsRoot; + } + + public String getSealer() { + return sealer; + } + + public void setSealer(String sealer) { + this.sealer = sealer; + } + + public List getSealerList() { + return sealerList; + } + + public void setSealerList(List sealerList) { + this.sealerList = sealerList; + } + + public String getStateRoot() { + return stateRoot; + } + + public void setStateRoot(String stateRoot) { + this.stateRoot = stateRoot; + } + + public String getReceiptsRoot() { + return receiptsRoot; + } + + public void setReceiptsRoot(String receiptsRoot) { + this.receiptsRoot = receiptsRoot; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public List getSignatureList() { + return signatureList; + } + + public void setSignatureList(List signatureList) { + this.signatureList = signatureList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BlockHeader that = (BlockHeader) o; + return Objects.equals(dbHash, that.dbHash) + && Objects.equals(extraData, that.extraData) + && Objects.equals(gasLimit, that.gasLimit) + && Objects.equals(gasUsed, that.gasUsed) + && Objects.equals(hash, that.hash) + && Objects.equals(logsBloom, that.logsBloom) + && Objects.equals(number, that.number) + && Objects.equals(parentHash, that.parentHash) + && Objects.equals(transactionsRoot, that.transactionsRoot) + && Objects.equals(sealer, that.sealer) + && Objects.equals(sealerList, that.sealerList) + && Objects.equals(signatureList, that.signatureList) + && Objects.equals(stateRoot, that.stateRoot) + && Objects.equals(receiptsRoot, that.receiptsRoot) + && Objects.equals(timestamp, that.timestamp); + } + + @Override + public int hashCode() { + return Objects.hash( + dbHash, + extraData, + gasLimit, + gasUsed, + hash, + logsBloom, + number, + parentHash, + transactionsRoot, + sealer, + sealerList, + signatureList, + stateRoot, + receiptsRoot, + timestamp); + } + + @Override + public String toString() { + return "BlockHeader{" + + "dbHash='" + + dbHash + + '\'' + + ", extraData=" + + extraData + + ", gasLimit='" + + gasLimit + + '\'' + + ", gasUsed='" + + gasUsed + + '\'' + + ", hash='" + + hash + + '\'' + + ", logsBloom='" + + logsBloom + + '\'' + + ", number=" + + number + + ", parentHash='" + + parentHash + + '\'' + + ", transactionsRoot='" + + transactionsRoot + + '\'' + + ", sealer='" + + sealer + + '\'' + + ", sealerList=" + + sealerList + + ", signatureList=" + + signatureList + + ", stateRoot='" + + stateRoot + + '\'' + + ", receiptsRoot='" + + receiptsRoot + + '\'' + + ", timestamp='" + + timestamp + + '\'' + + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransaction.java b/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransaction.java new file mode 100644 index 000000000..2ce28a32a --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransaction.java @@ -0,0 +1,48 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import java.io.IOException; +import java.util.Optional; +import org.fisco.bcos.sdk.client.ObjectMapperFactory; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** + * Transaction object returned by: + * + *

    + *
  • eth_getTransactionByHash + *
  • eth_getTransactionByBlockHashAndIndex + *
  • eth_getTransactionByBlockNumberAndIndex + *
+ * + *

This differs slightly from the request {@link SendTransaction} Transaction object. + * + *

See docs + * for further details. + */ +public class BcosTransaction extends RPCResponse { + + public Optional getTransaction() { + return Optional.ofNullable(getResult()); + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Transaction deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, Transaction.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransactionReceipt.java b/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransactionReceipt.java new file mode 100644 index 000000000..0f8b02b8a --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BcosTransactionReceipt.java @@ -0,0 +1,35 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import java.io.IOException; +import java.util.Optional; +import org.fisco.bcos.sdk.client.ObjectMapperFactory; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getTransactionReceipt. */ +public class BcosTransactionReceipt extends RPCResponse { + + public Optional getTransactionReceipt() { + return Optional.ofNullable(getResult()); + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public TransactionReceipt deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, TransactionReceipt.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BlockHash.java b/src/main/java/org/fisco/bcos/sdk/client/response/BlockHash.java new file mode 100644 index 000000000..cbebb685c --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BlockHash.java @@ -0,0 +1,10 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getBlockHashByNumber */ +public class BlockHash extends RPCResponse { + public String getBlockHashByNumber() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/BlockNumber.java b/src/main/java/org/fisco/bcos/sdk/client/response/BlockNumber.java new file mode 100644 index 000000000..979d35ce7 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/BlockNumber.java @@ -0,0 +1,12 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.client.RPCResponse; +import org.fisco.bcos.sdk.utils.Numeric; + +/** getblockNumber. */ +public class BlockNumber extends RPCResponse { + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/Call.java b/src/main/java/org/fisco/bcos/sdk/client/response/Call.java new file mode 100644 index 000000000..80e79bcc8 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/Call.java @@ -0,0 +1,49 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** + * RPC response of ledger call + * + * @author Maggie + */ +public class Call extends RPCResponse { + + public static class CallOutput { + private String currentBlockNumber; + private String output; + private String status; + + public String getCurrentBlockNumber() { + return currentBlockNumber; + } + + public void setCurrentBlockNumber(String number) { + this.currentBlockNumber = number; + } + + public String getOutput() { + return output; + } + + public void setOutput(String output) { + this.output = output; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + public CallOutput getValue() { + return getResult(); + } + + public void setResult(CallOutput result) { + super.setResult(result); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/Code.java b/src/main/java/org/fisco/bcos/sdk/client/response/Code.java new file mode 100644 index 000000000..c83559b50 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/Code.java @@ -0,0 +1,14 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** + * Get code response + * + * @author Maggie + */ +public class Code extends RPCResponse { + public String getCode() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/ConsensusStatus.java b/src/main/java/org/fisco/bcos/sdk/client/response/ConsensusStatus.java new file mode 100644 index 000000000..891c93d07 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/ConsensusStatus.java @@ -0,0 +1,10 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getConsensusStatus */ +public class ConsensusStatus extends RPCResponse { + public String getConsensusStatus() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/GenerateGroup.java b/src/main/java/org/fisco/bcos/sdk/client/response/GenerateGroup.java new file mode 100644 index 000000000..558a2f357 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/GenerateGroup.java @@ -0,0 +1,36 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class GenerateGroup extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/GroupList.java b/src/main/java/org/fisco/bcos/sdk/client/response/GroupList.java new file mode 100644 index 000000000..8c2d481e8 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/GroupList.java @@ -0,0 +1,12 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getGroupList */ +public class GroupList extends RPCResponse> { + + public List getGroupList() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/GroupPeers.java b/src/main/java/org/fisco/bcos/sdk/client/response/GroupPeers.java new file mode 100644 index 000000000..5c6593a5f --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/GroupPeers.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getGroupPeers */ +public class GroupPeers extends RPCResponse> { + public List getGroupPeers() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/Log.java b/src/main/java/org/fisco/bcos/sdk/client/response/Log.java new file mode 100644 index 000000000..4ca27b1bf --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/Log.java @@ -0,0 +1,250 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.math.BigInteger; +import java.util.List; +import org.fisco.bcos.sdk.utils.Numeric; + +/** + * Log object used by {@link BcosTransactionReceipt}. + * + *

It's not clear in the docs If only a list of + * hashes are returned for filters created with eth_newBlockFilter or + * eth_newPendingTransactionFilter. + */ +public class Log { + private boolean removed; + private String logIndex; + private String transactionIndex; + private String transactionHash; + private String blockHash; + private String blockNumber; + private String address; + private String data; + private String type; + private List topics; + + public Log() {} + + public Log( + boolean removed, + String logIndex, + String transactionIndex, + String transactionHash, + String blockHash, + String blockNumber, + String address, + String data, + String type, + List topics) { + this.removed = removed; + this.logIndex = logIndex; + this.transactionIndex = transactionIndex; + this.transactionHash = transactionHash; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.address = address; + this.data = data; + this.type = type; + this.topics = topics; + } + + @JsonIgnore + public boolean isRemoved() { + return removed; + } + + public void setRemoved(boolean removed) { + this.removed = removed; + } + + public BigInteger getLogIndex() { + return convert(logIndex); + } + + @JsonIgnore + public String getLogIndexRaw() { + return logIndex; + } + + public void setLogIndex(String logIndex) { + this.logIndex = logIndex; + } + + public BigInteger getTransactionIndex() { + return convert(transactionIndex); + } + + @JsonIgnore + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getTransactionHash() { + return transactionHash; + } + + public void setTransactionHash(String transactionHash) { + this.transactionHash = transactionHash; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return convert(blockNumber); + } + + @JsonIgnore + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @JsonIgnore + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + private BigInteger convert(String value) { + if (value != null) { + return Numeric.decodeQuantity(value); + } else { + return null; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Log)) { + return false; + } + + Log log = (Log) o; + + if (isRemoved() != log.isRemoved()) { + return false; + } + if (getLogIndexRaw() != null + ? !getLogIndexRaw().equals(log.getLogIndexRaw()) + : log.getLogIndexRaw() != null) { + return false; + } + if (getTransactionIndexRaw() != null + ? !getTransactionIndexRaw().equals(log.getTransactionIndexRaw()) + : log.getTransactionIndexRaw() != null) { + return false; + } + if (getTransactionHash() != null + ? !getTransactionHash().equals(log.getTransactionHash()) + : log.getTransactionHash() != null) { + return false; + } + if (getBlockHash() != null + ? !getBlockHash().equals(log.getBlockHash()) + : log.getBlockHash() != null) { + return false; + } + if (getBlockNumberRaw() != null + ? !getBlockNumberRaw().equals(log.getBlockNumberRaw()) + : log.getBlockNumberRaw() != null) { + return false; + } + if (getAddress() != null + ? !getAddress().equals(log.getAddress()) + : log.getAddress() != null) { + return false; + } + if (getData() != null ? !getData().equals(log.getData()) : log.getData() != null) { + return false; + } + if (getType() != null ? !getType().equals(log.getType()) : log.getType() != null) { + return false; + } + return getTopics() != null ? getTopics().equals(log.getTopics()) : log.getTopics() == null; + } + + @Override + public int hashCode() { + int result = (isRemoved() ? 1 : 0); + result = 31 * result + (getLogIndexRaw() != null ? getLogIndexRaw().hashCode() : 0); + result = + 31 * result + + (getTransactionIndexRaw() != null + ? getTransactionIndexRaw().hashCode() + : 0); + result = 31 * result + (getTransactionHash() != null ? getTransactionHash().hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (getBlockNumberRaw() != null ? getBlockNumberRaw().hashCode() : 0); + result = 31 * result + (getAddress() != null ? getAddress().hashCode() : 0); + result = 31 * result + (getData() != null ? getData().hashCode() : 0); + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (getTopics() != null ? getTopics().hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "Log [logIndex=" + + logIndex + + ", transactionIndex=" + + transactionIndex + + ", transactionHash=" + + transactionHash + + ", blockHash=" + + blockHash + + ", blockNumber=" + + blockNumber + + ", address=" + + address + + ", data=" + + data + + ", topics=" + + topics + + "]"; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/MerkleProofUnit.java b/src/main/java/org/fisco/bcos/sdk/client/response/MerkleProofUnit.java new file mode 100644 index 000000000..fdc084f01 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/MerkleProofUnit.java @@ -0,0 +1,59 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import java.util.Objects; + +/** + * MerkleProofUnit object used by both {@link TransactionReceiptWithProof} and {@link + * TransactionWithProof}. + */ +public class MerkleProofUnit { + private List left; + private List right; + + public MerkleProofUnit() {} + + public MerkleProofUnit(List left, List right) { + this.left = left; + this.right = right; + } + + public List getLeft() { + return left; + } + + public void setLeft(List left) { + this.left = left; + } + + public List getRight() { + return right; + } + + public void setRight(List right) { + this.right = right; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MerkleProofUnit)) { + return false; + } + MerkleProofUnit that = (MerkleProofUnit) o; + return Objects.equals(getLeft(), that.getLeft()) + && Objects.equals(getRight(), that.getRight()); + } + + @Override + public int hashCode() { + return Objects.hash(getLeft(), getRight()); + } + + @Override + public String toString() { + return "MerkleProofUnit{" + "left=" + left + ", right=" + right + '}'; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/NodeIDList.java b/src/main/java/org/fisco/bcos/sdk/client/response/NodeIDList.java new file mode 100644 index 000000000..278c149fb --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/NodeIDList.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getNodeIDList */ +public class NodeIDList extends RPCResponse> { + public List getNodeIDList() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/NodeVersion.java b/src/main/java/org/fisco/bcos/sdk/client/response/NodeVersion.java new file mode 100644 index 000000000..68de9af09 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/NodeVersion.java @@ -0,0 +1,132 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getNodeVersion. */ +public class NodeVersion extends RPCResponse { + + public Version getNodeVersion() { + return getResult(); + } + + public static class Version { + @JsonProperty("Build Time") + private String buildTime; + + @JsonProperty("Build Type") + private String buildType; + + @JsonProperty("Chain Id") + private String chainID; + + @JsonProperty("FISCO-BCOS Version") + private String version; + + @JsonProperty("Git Branch") + private String gitBranch; + + @JsonProperty("Git Commit Hash") + private String gitCommit; + + @JsonProperty("Supported Version") + private String supportedVersion; + + public Version() { + super(); + } + + public Version( + String buildTime, + String buildType, + String chainID, + String version, + String gitBranch, + String gitCommit, + String supportedVersion) { + super(); + this.buildTime = buildTime; + this.buildType = buildType; + this.chainID = chainID; + this.version = version; + this.gitBranch = gitBranch; + this.gitCommit = gitCommit; + this.supportedVersion = supportedVersion; + } + + public String getBuildTime() { + return buildTime; + } + + public void setBuildTime(String buildTime) { + this.buildTime = buildTime; + } + + public String getChainID() { + return chainID; + } + + public String getSupportedVersion() { + return supportedVersion; + } + + public void setChainID(String chainID) { + this.chainID = chainID; + } + + public void setSupportedVersion(String supportedVersion) { + this.supportedVersion = supportedVersion; + } + + public String getBuildType() { + return buildType; + } + + public void setBuildType(String buildType) { + this.buildType = buildType; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getGitBranch() { + return gitBranch; + } + + public void setGitBranch(String gitBranch) { + this.gitBranch = gitBranch; + } + + public String getGitCommit() { + return gitCommit; + } + + public void setGitCommit(String gitCommit) { + this.gitCommit = gitCommit; + } + + @Override + public String toString() { + return "Version [buildTime=" + + buildTime + + ", buildType=" + + buildType + + ", chainID=" + + chainID + + ", version=" + + version + + ", gitBranch=" + + gitBranch + + ", gitCommit=" + + gitCommit + + ", supportedVersion=" + + supportedVersion + + "]"; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/ObserverList.java b/src/main/java/org/fisco/bcos/sdk/client/response/ObserverList.java new file mode 100644 index 000000000..96e28da87 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/ObserverList.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +public class ObserverList extends RPCResponse> { + + public List getObserverList() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/PbftView.java b/src/main/java/org/fisco/bcos/sdk/client/response/PbftView.java new file mode 100644 index 000000000..3f3724c02 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/PbftView.java @@ -0,0 +1,13 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.client.RPCResponse; +import org.fisco.bcos.sdk.utils.Numeric; + +/** getPbftView */ +public class PbftView extends RPCResponse { + + public BigInteger getPbftView() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/Peers.java b/src/main/java/org/fisco/bcos/sdk/client/response/Peers.java new file mode 100644 index 000000000..be2305e5d --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/Peers.java @@ -0,0 +1,56 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getPeers */ +public class Peers extends RPCResponse> { + + public List getPeers() { + return getResult(); + } + + public static class Peer { + @JsonProperty("IPAndPort") + private String IPAndPort; + + @JsonProperty("NodeID") + private String nodeID; + + @JsonProperty("Topic") + private List topic; + + public Peer() {} + + public Peer(String IPAndPort, String nodeID, List topic) { + this.IPAndPort = IPAndPort; + this.nodeID = nodeID; + this.topic = topic; + } + + public String getIPAndPort() { + return IPAndPort; + } + + public void setIPAndPort(String IPAndPort) { + this.IPAndPort = IPAndPort; + } + + public String getNodeID() { + return nodeID; + } + + public void setNodeID(String nodeID) { + this.nodeID = nodeID; + } + + public List getTopic() { + return topic; + } + + public void setTopic(List topic) { + this.topic = topic; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/PendingTransactions.java b/src/main/java/org/fisco/bcos/sdk/client/response/PendingTransactions.java new file mode 100644 index 000000000..7934f53d0 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/PendingTransactions.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getPendingTransactions */ +public class PendingTransactions extends RPCResponse> { + public List getPendingTransactions() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/PendingTxSize.java b/src/main/java/org/fisco/bcos/sdk/client/response/PendingTxSize.java new file mode 100644 index 000000000..4b579f232 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/PendingTxSize.java @@ -0,0 +1,12 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.client.RPCResponse; +import org.fisco.bcos.sdk.utils.Numeric; + +/** getPendingTxSize */ +public class PendingTxSize extends RPCResponse { + public BigInteger getPendingTxSize() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/QueryGroupStatus.java b/src/main/java/org/fisco/bcos/sdk/client/response/QueryGroupStatus.java new file mode 100644 index 000000000..02fcadf96 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/QueryGroupStatus.java @@ -0,0 +1,55 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class QueryGroupStatus extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String status; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + + "code='" + + code + + '\'' + + ", status='" + + status + + '\'' + + ", message='" + + message + + '\'' + + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/RecoverGroup.java b/src/main/java/org/fisco/bcos/sdk/client/response/RecoverGroup.java new file mode 100644 index 000000000..2c22e4cc8 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/RecoverGroup.java @@ -0,0 +1,36 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class RecoverGroup extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/RemoveGroup.java b/src/main/java/org/fisco/bcos/sdk/client/response/RemoveGroup.java new file mode 100644 index 000000000..c81711e0a --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/RemoveGroup.java @@ -0,0 +1,36 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class RemoveGroup extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/SealerList.java b/src/main/java/org/fisco/bcos/sdk/client/response/SealerList.java new file mode 100644 index 000000000..b9842df7b --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/SealerList.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.client.response; + +import java.util.List; +import org.fisco.bcos.sdk.client.RPCResponse; + +public class SealerList extends RPCResponse> { + + public List getSealerList() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/SendTransaction.java b/src/main/java/org/fisco/bcos/sdk/client/response/SendTransaction.java new file mode 100644 index 000000000..cba968acd --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/SendTransaction.java @@ -0,0 +1,10 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** Return data structure of send transaction */ +public class SendTransaction extends RPCResponse { + public String getTransactionHash() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/StartGroup.java b/src/main/java/org/fisco/bcos/sdk/client/response/StartGroup.java new file mode 100644 index 000000000..c87c77f80 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/StartGroup.java @@ -0,0 +1,36 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class StartGroup extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/StopGroup.java b/src/main/java/org/fisco/bcos/sdk/client/response/StopGroup.java new file mode 100644 index 000000000..547697608 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/StopGroup.java @@ -0,0 +1,36 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +public class StopGroup extends RPCResponse { + + public Status getStatus() { + return getResult(); + } + + public static class Status { + private String code; + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "Status{" + "code='" + code + '\'' + ", message='" + message + '\'' + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/SyncStatus.java b/src/main/java/org/fisco/bcos/sdk/client/response/SyncStatus.java new file mode 100644 index 000000000..08aa49aee --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/SyncStatus.java @@ -0,0 +1,163 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.io.IOException; +import org.fisco.bcos.sdk.client.ObjectMapperFactory; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** + * getSyncStatus + * + *

Returns an object with data about the sync status or false. + */ +public class SyncStatus extends RPCResponse { + + @Override + @JsonDeserialize(using = SyncStatus.ResponseDeserialiser.class) + public void setResult(SyncStatus.Result result) { + super.setResult(result); + } + + public boolean isSyncing() { + return getResult().isSyncing(); + } + + public static class Result { + private boolean isSyncing = true; + + public Result() {} + + public boolean isSyncing() { + return isSyncing; + } + + public void setSyncing(boolean syncing) { + isSyncing = syncing; + } + } + + @JsonIgnoreProperties({"knownStates", "pulledStates"}) + // these fields although not present in the RPC specification are returned by Geth 1.4.10 + public static class Syncing extends Result { + + private String startingBlock; + private String currentBlock; + private String highestBlock; + private String knownStates; + private String pulledStates; + + public Syncing() {} + + public Syncing( + String startingBlock, + String currentBlock, + String highestBlock, + String knownStates, + String pulledStates) { + this.startingBlock = startingBlock; + this.currentBlock = currentBlock; + this.highestBlock = highestBlock; + this.knownStates = knownStates; + this.pulledStates = pulledStates; + } + + public String getStartingBlock() { + return startingBlock; + } + + public void setStartingBlock(String startingBlock) { + this.startingBlock = startingBlock; + } + + public String getCurrentBlock() { + return currentBlock; + } + + public void setCurrentBlock(String currentBlock) { + this.currentBlock = currentBlock; + } + + public String getHighestBlock() { + return highestBlock; + } + + public void setHighestBlock(String highestBlock) { + this.highestBlock = highestBlock; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Syncing)) { + return false; + } + + Syncing syncing = (Syncing) o; + + if (isSyncing() != syncing.isSyncing()) { + return false; + } + if (getStartingBlock() != null + ? !getStartingBlock().equals(syncing.getStartingBlock()) + : syncing.getStartingBlock() != null) { + return false; + } + if (getCurrentBlock() != null + ? !getCurrentBlock().equals(syncing.getCurrentBlock()) + : syncing.getCurrentBlock() != null) { + return false; + } + if (getHighestBlock() != null + ? !getHighestBlock().equals(syncing.getHighestBlock()) + : syncing.getHighestBlock() != null) { + return false; + } + if (knownStates != null + ? !knownStates.equals(syncing.knownStates) + : syncing.knownStates != null) { + return false; + } + return pulledStates != null + ? pulledStates.equals(syncing.pulledStates) + : syncing.pulledStates == null; + } + + @Override + public int hashCode() { + int result = getStartingBlock() != null ? getStartingBlock().hashCode() : 0; + result = 31 * result + Boolean.hashCode(isSyncing()); + result = 31 * result + (getCurrentBlock() != null ? getCurrentBlock().hashCode() : 0); + result = 31 * result + (getHighestBlock() != null ? getHighestBlock().hashCode() : 0); + result = 31 * result + (knownStates != null ? knownStates.hashCode() : 0); + result = 31 * result + (pulledStates != null ? pulledStates.hashCode() : 0); + return result; + } + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Result deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + Result result; + if (jsonParser.getCurrentToken() == JsonToken.VALUE_FALSE) { + result = new Result(); + result.setSyncing(jsonParser.getBooleanValue()); + } else { + result = objectReader.readValue(jsonParser, Syncing.class); + } + return result; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/SystemConfig.java b/src/main/java/org/fisco/bcos/sdk/client/response/SystemConfig.java new file mode 100644 index 000000000..59942ffc5 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/SystemConfig.java @@ -0,0 +1,10 @@ +package org.fisco.bcos.sdk.client.response; + +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getSystemConfigByKey */ +public class SystemConfig extends RPCResponse { + public String getSystemConfigByKey() { + return getResult(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/TotalTransactionCount.java b/src/main/java/org/fisco/bcos/sdk/client/response/TotalTransactionCount.java new file mode 100644 index 000000000..cec5eb0df --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/TotalTransactionCount.java @@ -0,0 +1,48 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.client.RPCResponse; +import org.fisco.bcos.sdk.utils.Numeric; + +/** getTotalTransactionCount */ +public class TotalTransactionCount extends RPCResponse { + public TransactionCount getTotalTransactionCount() { + return getResult(); + } + + public class TransactionCount { + private String txSum; + private String blockNumber; + + public TransactionCount() {} + + public TransactionCount(String txSum, String blockNumber) { + this.txSum = txSum; + this.blockNumber = blockNumber; + } + + public BigInteger getTxSum() { + return Numeric.decodeQuantity(txSum); + } + + public String getTxSumRaw() { + return txSum; + } + + public void setTxSum(String txSum) { + this.txSum = txSum; + } + + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(blockNumber); + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/Transaction.java b/src/main/java/org/fisco/bcos/sdk/client/response/Transaction.java new file mode 100644 index 000000000..b1c01e943 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/Transaction.java @@ -0,0 +1,341 @@ +package org.fisco.bcos.sdk.client.response; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.utils.Numeric; + +/** Transaction object used by both {@link BcosTransaction} and {@link BcosBlock}. */ +public class Transaction { + private String hash; + private String nonce; + private String blockHash; + private String blockNumber; + private String transactionIndex; + private String from; + private String to; + private String value; + private String gasPrice; + private String gas; + private String input; + private String creates; + private String publicKey; + private String raw; + private String r; + private String s; + private int v; // see https://github.com/web3j/web3j/issues/44 + + public Transaction() {} + + public Transaction( + String hash, + String nonce, + String blockHash, + String blockNumber, + String transactionIndex, + String from, + String to, + String value, + String gas, + String gasPrice, + String input, + String creates, + String publicKey, + String raw, + String r, + String s, + int v) { + this.hash = hash; + this.nonce = nonce; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.transactionIndex = transactionIndex; + this.from = from; + this.to = to; + this.value = value; + this.gasPrice = gasPrice; + this.gas = gas; + this.input = input; + this.creates = creates; + this.publicKey = publicKey; + this.raw = raw; + this.r = r; + this.s = s; + this.v = v; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public BigInteger getNonce() { + return Numeric.decodeQuantity(nonce); + } + + public String getNonceRaw() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(blockNumber); + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public BigInteger getTransactionIndex() { + return Numeric.decodeQuantity(transactionIndex); + } + + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigInteger getValue() { + return Numeric.decodeQuantity(value); + } + + public String getValueRaw() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public BigInteger getGasPrice() { + return Numeric.decodeQuantity(gasPrice); + } + + public String getGasPriceRaw() { + return gasPrice; + } + + public void setGasPrice(String gasPrice) { + this.gasPrice = gasPrice; + } + + public BigInteger getGas() { + return Numeric.decodeQuantity(gas); + } + + public String getGasRaw() { + return gas; + } + + public void setGas(String gas) { + this.gas = gas; + } + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public String getCreates() { + return creates; + } + + public void setCreates(String creates) { + this.creates = creates; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getRaw() { + return raw; + } + + public void setRaw(String raw) { + this.raw = raw; + } + + public String getR() { + return r; + } + + public void setR(String r) { + this.r = r; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public int getV() { + return v; + } + + // public void setV(byte v) { + // this.v = v; + // } + + // Workaround until Geth & Parity return consistent values. At present + // Parity returns a byte value, Geth returns a hex-encoded string + // https://github.com/ethereum/go-ethereum/issues/3339 + public void setV(Object v) { + if (v instanceof String) { + this.v = Numeric.toBigInt((String) v).intValueExact(); + } else { + this.v = ((Integer) v); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Transaction)) { + return false; + } + + Transaction that = (Transaction) o; + + if (getV() != that.getV()) { + return false; + } + if (getHash() != null ? !getHash().equals(that.getHash()) : that.getHash() != null) { + return false; + } + if (getNonceRaw() != null + ? !getNonceRaw().equals(that.getNonceRaw()) + : that.getNonceRaw() != null) { + return false; + } + if (getBlockHash() != null + ? !getBlockHash().equals(that.getBlockHash()) + : that.getBlockHash() != null) { + return false; + } + if (getBlockNumberRaw() != null + ? !getBlockNumberRaw().equals(that.getBlockNumberRaw()) + : that.getBlockNumberRaw() != null) { + return false; + } + if (getTransactionIndexRaw() != null + ? !getTransactionIndexRaw().equals(that.getTransactionIndexRaw()) + : that.getTransactionIndexRaw() != null) { + return false; + } + if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) { + return false; + } + if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) { + return false; + } + if (getValueRaw() != null + ? !getValueRaw().equals(that.getValueRaw()) + : that.getValueRaw() != null) { + return false; + } + if (getGasPriceRaw() != null + ? !getGasPriceRaw().equals(that.getGasPriceRaw()) + : that.getGasPriceRaw() != null) { + return false; + } + if (getGasRaw() != null + ? !getGasRaw().equals(that.getGasRaw()) + : that.getGasRaw() != null) { + return false; + } + if (getInput() != null ? !getInput().equals(that.getInput()) : that.getInput() != null) { + return false; + } + if (getCreates() != null + ? !getCreates().equals(that.getCreates()) + : that.getCreates() != null) { + return false; + } + if (getPublicKey() != null + ? !getPublicKey().equals(that.getPublicKey()) + : that.getPublicKey() != null) { + return false; + } + if (getRaw() != null ? !getRaw().equals(that.getRaw()) : that.getRaw() != null) { + return false; + } + if (getR() != null ? !getR().equals(that.getR()) : that.getR() != null) { + return false; + } + return getS() != null ? getS().equals(that.getS()) : that.getS() == null; + } + + @Override + public int hashCode() { + int result = getHash() != null ? getHash().hashCode() : 0; + result = 31 * result + (getNonceRaw() != null ? getNonceRaw().hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (getBlockNumberRaw() != null ? getBlockNumberRaw().hashCode() : 0); + result = + 31 * result + + (getTransactionIndexRaw() != null + ? getTransactionIndexRaw().hashCode() + : 0); + result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0); + result = 31 * result + (getTo() != null ? getTo().hashCode() : 0); + result = 31 * result + (getValueRaw() != null ? getValueRaw().hashCode() : 0); + result = 31 * result + (getGasPriceRaw() != null ? getGasPriceRaw().hashCode() : 0); + result = 31 * result + (getGasRaw() != null ? getGasRaw().hashCode() : 0); + result = 31 * result + (getInput() != null ? getInput().hashCode() : 0); + result = 31 * result + (getCreates() != null ? getCreates().hashCode() : 0); + result = 31 * result + (getPublicKey() != null ? getPublicKey().hashCode() : 0); + result = 31 * result + (getRaw() != null ? getRaw().hashCode() : 0); + result = 31 * result + (getR() != null ? getR().hashCode() : 0); + result = 31 * result + (getS() != null ? getS().hashCode() : 0); + result = 31 * result + getV(); + return result; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceipt.java b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceipt.java new file mode 100644 index 000000000..37206c467 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceipt.java @@ -0,0 +1,371 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.math.BigInteger; +import java.util.List; +import org.fisco.bcos.sdk.utils.Numeric; + +/** TransactionReceipt object used by {@link BcosTransactionReceipt}. */ +public class TransactionReceipt { + private String transactionHash; + private String transactionIndex; + private String blockHash; + private String blockNumber; + private String gasUsed; + private String contractAddress; + private String root; + // status is only present on Byzantium transactions onwards + // see EIP 658 https://github.com/ethereum/EIPs/pull/658 + private String status; + private String message; + private String from; + private String to; + private String input; + private String output; + private List logs; + private String logsBloom; + private List txProof; + private List receiptProof; + + public TransactionReceipt() {} + + public TransactionReceipt( + String transactionHash, + String transactionIndex, + String blockHash, + String blockNumber, + String gasUsed, + String contractAddress, + String root, + String status, + String message, + String from, + String to, + String input, + String output, + List logs, + String logsBloom) { + this.transactionHash = transactionHash; + this.transactionIndex = transactionIndex; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.gasUsed = gasUsed; + this.contractAddress = contractAddress; + this.root = root; + this.status = status; + this.message = message; + this.from = from; + this.to = to; + this.input = input; + this.output = output; + this.logs = logs; + this.logsBloom = logsBloom; + } + + public String getTransactionHash() { + return transactionHash; + } + + public void setTransactionHash(String transactionHash) { + this.transactionHash = transactionHash; + } + + public BigInteger getTransactionIndex() { + return Numeric.decodeQuantity(transactionIndex); + } + + @JsonIgnore + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(blockNumber); + } + + @JsonIgnore + public String getBlockNumberRaw() { + return blockNumber; + } + + public String getOutput() { + return output; + } + + public void setOutput(String output) { + this.output = output; + } + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public BigInteger getGasUsed() { + return Numeric.decodeQuantity(gasUsed); + } + + @JsonIgnore + public String getGasUsedRaw() { + return gasUsed; + } + + public void setGasUsed(String gasUsed) { + this.gasUsed = gasUsed; + } + + public String getContractAddress() { + return contractAddress; + } + + public void setContractAddress(String contractAddress) { + this.contractAddress = contractAddress; + } + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonIgnore + public boolean isStatusOK() { + if (null == status) { + return true; + } + + try { + BigInteger statusQuantity = Numeric.decodeQuantity(status); + return BigInteger.ZERO.equals(statusQuantity); + } catch (Exception e) { + return false; + } + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public List getLogs() { + return logs; + } + + public void setLogs(List logs) { + this.logs = logs; + } + + public String getLogsBloom() { + return logsBloom; + } + + public void setLogsBloom(String logsBloom) { + this.logsBloom = logsBloom; + } + + public List getTxProof() { + return txProof; + } + + public void setTxProof(List txProof) { + this.txProof = txProof; + } + + public List getReceiptProof() { + return receiptProof; + } + + public void setReceiptProof(List receiptProof) { + this.receiptProof = receiptProof; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TransactionReceipt)) { + return false; + } + + TransactionReceipt that = (TransactionReceipt) o; + + if (getTransactionHash() != null + ? !getTransactionHash().equals(that.getTransactionHash()) + : that.getTransactionHash() != null) { + return false; + } + if (transactionIndex != null + ? !transactionIndex.equals(that.transactionIndex) + : that.transactionIndex != null) { + return false; + } + if (getBlockHash() != null + ? !getBlockHash().equals(that.getBlockHash()) + : that.getBlockHash() != null) { + return false; + } + if (blockNumber != null + ? !blockNumber.equals(that.blockNumber) + : that.blockNumber != null) { + return false; + } + if (gasUsed != null ? !gasUsed.equals(that.gasUsed) : that.gasUsed != null) { + return false; + } + if (getContractAddress() != null + ? !getContractAddress().equals(that.getContractAddress()) + : that.getContractAddress() != null) { + return false; + } + if (getRoot() != null ? !getRoot().equals(that.getRoot()) : that.getRoot() != null) { + return false; + } + if (getStatus() != null + ? !getStatus().equals(that.getStatus()) + : that.getStatus() != null) { + return false; + } + if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) { + return false; + } + if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) { + return false; + } + if (getLogs() != null ? !getLogs().equals(that.getLogs()) : that.getLogs() != null) { + return false; + } + if (getOutput() != null + ? !getOutput().equals(that.getOutput()) + : that.getOutput() != null) { + return false; + } + if (getInput() != null ? !getInput().equals(that.getInput()) : that.getInput() != null) { + return false; + } + return getLogsBloom() != null + ? getLogsBloom().equals(that.getLogsBloom()) + : that.getLogsBloom() == null; + } + + @Override + public int hashCode() { + int result = getTransactionHash() != null ? getTransactionHash().hashCode() : 0; + result = 31 * result + (transactionIndex != null ? transactionIndex.hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (blockNumber != null ? blockNumber.hashCode() : 0); + result = 31 * result + (gasUsed != null ? gasUsed.hashCode() : 0); + result = 31 * result + (getContractAddress() != null ? getContractAddress().hashCode() : 0); + result = 31 * result + (getRoot() != null ? getRoot().hashCode() : 0); + result = 31 * result + (getStatus() != null ? getStatus().hashCode() : 0); + result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0); + result = 31 * result + (getTo() != null ? getTo().hashCode() : 0); + result = 31 * result + (getOutput() != null ? getOutput().hashCode() : 0); + result = 31 * result + (getInput() != null ? getInput().hashCode() : 0); + result = 31 * result + (getLogs() != null ? getLogs().hashCode() : 0); + result = 31 * result + (getLogsBloom() != null ? getLogsBloom().hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "TransactionReceipt{" + + "transactionHash='" + + transactionHash + + '\'' + + ", transactionIndex='" + + transactionIndex + + '\'' + + ", blockHash='" + + blockHash + + '\'' + + ", blockNumber='" + + blockNumber + + '\'' + + ", gasUsed='" + + gasUsed + + '\'' + + ", contractAddress='" + + contractAddress + + '\'' + + ", root='" + + root + + '\'' + + ", status='" + + status + + '\'' + + ", message='" + + message + + '\'' + + ", from='" + + from + + '\'' + + ", to='" + + to + + '\'' + + ", input='" + + input + + '\'' + + ", output='" + + output + + '\'' + + ", logs=" + + logs + + ", logsBloom='" + + logsBloom + + '\'' + + ", transAndProof=" + + txProof + + ", receiptAndProof=" + + receiptProof + + '}'; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceiptWithProof.java b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceiptWithProof.java new file mode 100644 index 000000000..38084a618 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionReceiptWithProof.java @@ -0,0 +1,78 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.Objects; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getTransactionReceiptWithProof. */ +public class TransactionReceiptWithProof + extends RPCResponse { + + public ReceiptAndProof getTransactionReceiptWithProof() { + return getResult(); + } + + public static class ReceiptAndProof { + @JsonProperty("transactionReceipt") + private TransactionReceipt transactionReceipt; + + @JsonProperty("receiptProof") + private List receiptProof; + + public ReceiptAndProof() { + super(); + } + + public ReceiptAndProof( + TransactionReceipt transactionReceipt, List receiptProof) { + super(); + this.transactionReceipt = transactionReceipt; + this.receiptProof = receiptProof; + } + + public TransactionReceipt getTransactionReceipt() { + return transactionReceipt; + } + + public void setTransactionReceipt(TransactionReceipt transactionReceipt) { + this.transactionReceipt = transactionReceipt; + } + + public List getReceiptProof() { + return receiptProof; + } + + public void setReceiptProof(List receiptProof) { + this.receiptProof = receiptProof; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ReceiptAndProof)) { + return false; + } + ReceiptAndProof that = (ReceiptAndProof) o; + return getTransactionReceipt().equals(that.getTransactionReceipt()) + && getReceiptProof().equals(that.getReceiptProof()); + } + + @Override + public int hashCode() { + return Objects.hash(getTransactionReceipt(), getReceiptProof()); + } + + @Override + public String toString() { + return "ReceiptProof{" + + "transactionReceipt=" + + transactionReceipt + + ", receiptProof=" + + receiptProof + + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/response/TransactionWithProof.java b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionWithProof.java new file mode 100644 index 000000000..856b3d3d3 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/response/TransactionWithProof.java @@ -0,0 +1,71 @@ +package org.fisco.bcos.sdk.client.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.Objects; +import org.fisco.bcos.sdk.client.RPCResponse; + +/** getTransactionWithProof. */ +public class TransactionWithProof extends RPCResponse { + + public TransAndProof getTransactionWithProof() { + return getResult(); + } + + public static class TransAndProof { + @JsonProperty("transaction") + private Transaction transaction; + + @JsonProperty("txProof") + private List txProof; + + public TransAndProof() { + super(); + } + + public TransAndProof(Transaction transaction, List txProof) { + super(); + this.transaction = transaction; + this.txProof = txProof; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + public List getTxProof() { + return txProof; + } + + public void setTxProof(List txProof) { + this.txProof = txProof; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TransAndProof)) { + return false; + } + TransAndProof tranProof = (TransAndProof) o; + return Objects.equals(getTransaction(), tranProof.getTransaction()) + && Objects.equals(getTxProof(), tranProof.getTxProof()); + } + + @Override + public int hashCode() { + return Objects.hash(getTransaction(), getTxProof()); + } + + @Override + public String toString() { + return "TransAndProof{" + "transaction=" + transaction + ", txProof=" + txProof + '}'; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/client/serializer/RawResponseDeserializer.java b/src/main/java/org/fisco/bcos/sdk/client/serializer/RawResponseDeserializer.java new file mode 100644 index 000000000..e1582272c --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/client/serializer/RawResponseDeserializer.java @@ -0,0 +1,54 @@ +package org.fisco.bcos.sdk.client.serializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; +import org.fisco.bcos.sdk.client.RPCResponse; + +public class RawResponseDeserializer extends StdDeserializer + implements ResolvableDeserializer { + private final JsonDeserializer defaultDeserializer; + + public RawResponseDeserializer(JsonDeserializer defaultDeserializer) { + super(RPCResponse.class); + this.defaultDeserializer = defaultDeserializer; + } + + @Override + public RPCResponse deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + RPCResponse deserializedResponse = (RPCResponse) defaultDeserializer.deserialize(jp, ctxt); + + deserializedResponse.setRawResponse(getRawResponse(jp)); + return deserializedResponse; + } + + // Must implement ResolvableDeserializer when modifying BeanDeserializer + // otherwise deserializing throws JsonMappingException + @Override + public void resolve(DeserializationContext ctxt) throws JsonMappingException { + ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt); + } + + private String getRawResponse(JsonParser jp) throws IOException { + final InputStream inputSource = (InputStream) jp.getInputSource(); + + if (inputSource == null) { + return ""; + } + + inputSource.reset(); + + return streamToString(inputSource); + } + + private String streamToString(InputStream input) throws IOException { + return new Scanner(input, StandardCharsets.UTF_8.name()).useDelimiter("\\Z").next(); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/contract/Contract.java b/src/main/java/org/fisco/bcos/sdk/contract/Contract.java new file mode 100644 index 000000000..07272c1b5 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/contract/Contract.java @@ -0,0 +1,31 @@ +package org.fisco.bcos.sdk.contract; + +import java.util.List; +import org.fisco.bcos.sdk.eventsub.EventCallback; + +public abstract class Contract { + // TODO + // Relay on transaction module and abi module + + /** + * Subscribe event + * + * @param abi + * @param bin + * @param topic0 + * @param fromBlock + * @param toBlock + * @param otherTopics + * @param callback + */ + public void subscribeEvent( + String abi, + String bin, + String topic0, + String fromBlock, + String toBlock, + List otherTopics, + EventCallback callback) { + // TODO + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/eventsub/EventCallback.java b/src/main/java/org/fisco/bcos/sdk/eventsub/EventCallback.java new file mode 100644 index 000000000..737635e95 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/eventsub/EventCallback.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.eventsub; + +public abstract class EventCallback {} diff --git a/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogFilter.java b/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogFilter.java new file mode 100644 index 000000000..1ca3a90a6 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogFilter.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.eventsub; + +public class EventLogFilter {} diff --git a/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogParams.java b/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogParams.java new file mode 100644 index 000000000..1bbb7b25a --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/eventsub/EventLogParams.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.eventsub; + +public class EventLogParams {} diff --git a/src/main/java/org/fisco/bcos/sdk/eventsub/EventSubscribe.java b/src/main/java/org/fisco/bcos/sdk/eventsub/EventSubscribe.java new file mode 100644 index 000000000..1d6b24b3b --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/eventsub/EventSubscribe.java @@ -0,0 +1,51 @@ +package org.fisco.bcos.sdk.eventsub; + +import java.util.List; +import org.fisco.bcos.sdk.channel.Channel; + +/** + * Event subscribe interface + * + * @author Maggie + */ +public interface EventSubscribe { + /** + * Create a Event Subscribe instance + * + * @param ch + * @param groupId + * @return EventSubscribe Object + */ + static EventSubscribe build(Channel ch, String groupId) { + // TODO + return null; + } + + /** + * Subscribe event + * + * @param params + * @param callback + */ + void subscribeEvent(EventLogParams params, EventCallback callback); + + /** + * Unsubscribe events + * + * @param filterId + */ + void unsubscribeEvent(String filterId); + + /** + * Get all subscribed event. + * + * @return list of event log filters + */ + List getAllSubscribedEvent(); + + /** Start */ + void start(); + + /** Stop */ + void stop(); +} diff --git a/src/main/java/org/fisco/bcos/sdk/model/Message.java b/src/main/java/org/fisco/bcos/sdk/model/Message.java new file mode 100644 index 000000000..ab4e4fb9e --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/model/Message.java @@ -0,0 +1,6 @@ +package org.fisco.bcos.sdk.model; + +import java.io.Serializable; + +/** Messages between sdk and FISCO BCOS node. */ +public class Message implements Serializable {} diff --git a/src/main/java/org/fisco/bcos/sdk/model/MsgType.java b/src/main/java/org/fisco/bcos/sdk/model/MsgType.java new file mode 100644 index 000000000..a3f8f7a97 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/model/MsgType.java @@ -0,0 +1,43 @@ +package org.fisco.bcos.sdk.model; + +/** Message types send from fisco bcos node. */ +public enum MsgType { + + /** + * Message types which Client module interested in. CHANNEL_RPC_REQUEST: type of rpc request + * message TRANSACTION_NOTIFY: type of transaction notify message BLOCK_NOTIFY: type of block + * notify message + */ + CHANNEL_RPC_REQUEST(0x12), + TRANSACTION_NOTIFY(0x1000), + BLOCK_NOTIFY(0x1001), + + /** + * Message types processed by Client module. CLIENT_HEARTBEAT:type of heart beat message + * CLIENT_HANDSHAKE:type of hand shake message + */ + CLIENT_HEARTBEAT(0x13), + CLIENT_HANDSHAKE(0x14), + + /** + * Message types processed by EventSubscribe module CLIENT_REGISTER_EVENT_LOG:type of event log + * filter register request and response message EVENT_LOG_PUSH:type of event log push message + */ + CLIENT_REGISTER_EVENT_LOG(0x15), + EVENT_LOG_PUSH(0x1002), + + /** + * Message types processed by AMOP module AMOP_REQUEST:type of request message from sdk + * AMOP_RESPONSE:type of response message to sdk AMOP_MULBROADCAST:type of mult broadcast + * message AMOP_CLIENT_TOPICS:type of topic request message REQUEST_TOPICCERT:type of request + * verify message UPDATE_TOPIICSTATUS:type of update status message + */ + AMOP_REQUEST(0x30), + AMOP_RESPONSE(0x31), + AMOP_MULBROADCAST(0x35), + AMOP_CLIENT_TOPICS(0x32), + REQUEST_TOPICCERT(0x37), + UPDATE_TOPIICSTATUS(0x38); + + MsgType(int i) {} +} diff --git a/src/main/java/org/fisco/bcos/sdk/model/Response.java b/src/main/java/org/fisco/bcos/sdk/model/Response.java new file mode 100644 index 000000000..fb7bae439 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/model/Response.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.model; + +public class Response {} diff --git a/src/main/java/org/fisco/bcos/sdk/network/Connection.java b/src/main/java/org/fisco/bcos/sdk/network/Connection.java new file mode 100644 index 000000000..2ba9909ac --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/network/Connection.java @@ -0,0 +1,3 @@ +package org.fisco.bcos.sdk.network; + +public class Connection {} diff --git a/src/main/java/org/fisco/bcos/sdk/network/Network.java b/src/main/java/org/fisco/bcos/sdk/network/Network.java new file mode 100644 index 000000000..dc5426c23 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/network/Network.java @@ -0,0 +1,6 @@ +package org.fisco.bcos.sdk.network; + +/** Network interface Modules interact with the network module through this interface */ +public interface Network { + Network build(); +} diff --git a/src/main/java/org/fisco/bcos/sdk/utils/Numeric.java b/src/main/java/org/fisco/bcos/sdk/utils/Numeric.java new file mode 100644 index 000000000..be0d40708 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/utils/Numeric.java @@ -0,0 +1,229 @@ +package org.fisco.bcos.sdk.utils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import org.apache.commons.codec.binary.Hex; +import org.fisco.bcos.sdk.utils.exceptions.DecodingException; +import org.fisco.bcos.sdk.utils.exceptions.EncodingException; + +/** + * Message codec functions. + * + *

Implementation as per https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding + */ +public final class Numeric { + + private static final String HEX_PREFIX = "0x"; + + private Numeric() {} + + public static String encodeQuantity(BigInteger value) throws EncodingException { + if (value.signum() != -1) { + return HEX_PREFIX + value.toString(16); + } else { + throw new EncodingException("Negative values are not supported"); + } + } + + public static BigInteger decodeQuantity(String value) { + if (!isValidHexQuantity(value)) { + try { + if (value == null) return new BigInteger("0"); + return new BigInteger(value); + } catch (NumberFormatException e) { + throw new DecodingException("Negative ", e); + } + } else { + try { + return new BigInteger(value.substring(2), 16); + } catch (NumberFormatException e) { + throw new DecodingException("value is not a hex number or a decimal number"); + } + } + } + + private static boolean isValidHexQuantity(String value) { + if (value == null) { + return false; + } + + if (value.length() < 3) { + return false; + } + + if (!value.startsWith(HEX_PREFIX)) { + return false; + } + + // If TestRpc resolves the following issue, we can reinstate this code + // https://github.com/ethereumjs/testrpc/issues/220 + // if (value.length() > 3 && value.charAt(2) == '0') { + // return false; + // } + + return true; + } + + public static String cleanHexPrefix(String input) { + if (containsHexPrefix(input)) { + return input.substring(2); + } else { + return input; + } + } + + public static String prependHexPrefix(String input) { + if (!containsHexPrefix(input)) { + return HEX_PREFIX + input; + } else { + return input; + } + } + + public static boolean containsHexPrefix(String input) { + return !Strings.isEmpty(input) + && input.length() > 1 + && input.charAt(0) == '0' + && input.charAt(1) == 'x'; + } + + public static BigInteger toBigInt(byte[] value, int offset, int length) { + return toBigInt((Arrays.copyOfRange(value, offset, offset + length))); + } + + public static BigInteger toBigInt(byte[] value) { + return new BigInteger(1, value); + } + + public static BigInteger toBigInt(String hexValue) { + String cleanValue = cleanHexPrefix(hexValue); + return toBigIntNoPrefix(cleanValue); + } + + public static BigInteger toBigIntNoPrefix(String hexValue) { + return new BigInteger(hexValue, 16); + } + + public static String toHexStringWithPrefix(BigInteger value) { + return HEX_PREFIX + value.toString(16); + } + + public static String toHexStringNoPrefix(byte[] input) { + return Hex.encodeHexString(input); + } + + public static String toHexStringNoPrefix(BigInteger value) { + return value.toString(16); + } + + public static String toHexStringWithPrefixZeroPadded(BigInteger value, int size) { + return toHexStringZeroPadded(value, size, true); + } + + public static String toHexStringWithPrefixSafe(BigInteger value) { + String result = toHexStringNoPrefix(value); + if (result.length() < 2) { + result = Strings.zeros(1) + result; + } + return HEX_PREFIX + result; + } + + public static String toHexStringNoPrefixZeroPadded(BigInteger value, int size) { + return toHexStringZeroPadded(value, size, false); + } + + private static String toHexStringZeroPadded(BigInteger value, int size, boolean withPrefix) { + String result = toHexStringNoPrefix(value); + + int length = result.length(); + if (length > size) { + throw new UnsupportedOperationException( + "Value " + result + "is larger then length " + size); + } else if (value.signum() < 0) { + throw new UnsupportedOperationException("Value cannot be negative"); + } + + if (length < size) { + result = Strings.zeros(size - length) + result; + } + + if (withPrefix) { + return HEX_PREFIX + result; + } else { + return result; + } + } + + public static byte[] toBytesPadded(BigInteger value, int length) { + byte[] result = new byte[length]; + byte[] bytes = value.toByteArray(); + + int bytesLength; + int srcOffset; + if (bytes[0] == 0) { + bytesLength = bytes.length - 1; + srcOffset = 1; + } else { + bytesLength = bytes.length; + srcOffset = 0; + } + + if (bytesLength > length) { + throw new RuntimeException("Input is too large to put in byte array of size " + length); + } + + int destOffset = length - bytesLength; + System.arraycopy(bytes, srcOffset, result, destOffset, bytesLength); + return result; + } + + public static byte[] hexStringToByteArray(String input) { + String cleanInput = cleanHexPrefix(input); + + int len = cleanInput.length(); + + if (len == 0) { + return new byte[] {}; + } + + byte[] data; + int startIdx; + if (len % 2 != 0) { + data = new byte[(len / 2) + 1]; + data[0] = (byte) Character.digit(cleanInput.charAt(0), 16); + startIdx = 1; + } else { + data = new byte[len / 2]; + startIdx = 0; + } + + for (int i = startIdx; i < len; i += 2) { + data[(i + 1) / 2] = + (byte) + ((Character.digit(cleanInput.charAt(i), 16) << 4) + + Character.digit(cleanInput.charAt(i + 1), 16)); + } + return data; + } + + public static String toHexString(byte[] input, int offset, int length, boolean withPrefix) { + return withPrefix + ? toHexString(Arrays.copyOfRange(input, offset, offset + length)) + : toHexStringNoPrefix(Arrays.copyOfRange(input, offset, offset + length)); + } + + public static String toHexString(byte[] input) { + StringBuilder stringBuilder = new StringBuilder(2 + input.length * 2); + stringBuilder.append("0x").append(Hex.encodeHexString(input)); + return stringBuilder.toString(); + } + + public static byte asByte(int m, int n) { + return (byte) ((m << 4) | n); + } + + public static boolean isIntegerValue(BigDecimal value) { + return value.signum() == 0 || value.scale() <= 0 || value.stripTrailingZeros().scale() <= 0; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/utils/Strings.java b/src/main/java/org/fisco/bcos/sdk/utils/Strings.java new file mode 100644 index 000000000..38d19a936 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/utils/Strings.java @@ -0,0 +1,46 @@ +package org.fisco.bcos.sdk.utils; + +import java.util.List; + +/** String utility functions. */ +public class Strings { + + private Strings() {} + + public static String toCsv(List src) { + // return src == null ? null : String.join(", ", src.toArray(new String[0])); + return join(src, ", "); + } + + public static String join(List src, String delimiter) { + return src == null ? null : String.join(delimiter, src.toArray(new String[0])); + } + + public static String capitaliseFirstLetter(String string) { + if (string == null || string.length() == 0) { + return string; + } else { + return string.substring(0, 1).toUpperCase() + string.substring(1); + } + } + + public static String lowercaseFirstLetter(String string) { + if (string == null || string.length() == 0) { + return string; + } else { + return string.substring(0, 1).toLowerCase() + string.substring(1); + } + } + + public static String zeros(int n) { + return repeat('0', n); + } + + public static String repeat(char value, int n) { + return new String(new char[n]).replace("\0", String.valueOf(value)); + } + + public static boolean isEmpty(String s) { + return s == null || s.length() == 0; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/utils/exceptions/DecodingException.java b/src/main/java/org/fisco/bcos/sdk/utils/exceptions/DecodingException.java new file mode 100644 index 000000000..09938a2e7 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/utils/exceptions/DecodingException.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.utils.exceptions; + +public class DecodingException extends RuntimeException { + public DecodingException(String message) { + super(message); + } + + public DecodingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/utils/exceptions/EncodingException.java b/src/main/java/org/fisco/bcos/sdk/utils/exceptions/EncodingException.java new file mode 100644 index 000000000..8950fc325 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/utils/exceptions/EncodingException.java @@ -0,0 +1,11 @@ +package org.fisco.bcos.sdk.utils.exceptions; + +public class EncodingException extends RuntimeException { + public EncodingException(String message) { + super(message); + } + + public EncodingException(String message, Throwable cause) { + super(message, cause); + } +}