From a231149467dc2e1f3aeef2a1284b7dcec830af2d Mon Sep 17 00:00:00 2001 From: kyonRay Date: Tue, 30 Jan 2024 10:06:17 +0800 Subject: [PATCH] (transaction): fix transaction struct coredump bug, use inherit TransactionData and builder interfaces. --- bcos-c-sdk/bcos_sdk_c_common.cpp | 1 + bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp | 42 +- bindings/java/jni/scripts/java2jni.sh | 2 +- .../org_fisco_bcos_sdk_jni_rpc_RpcJniObj.cpp | 2 +- ...ties_tx_TransactionStructBuilderJniObj.cpp | 1335 ++++++++++++----- ...lities_tx_TransactionStructBuilderJniObj.h | 18 + .../sdk/jni/utilities/tx/Transaction.java | 18 +- .../jni/utilities/tx/TransactionBytes.java | 22 - .../sdk/jni/utilities/tx/TransactionData.java | 20 +- .../jni/utilities/tx/TransactionDataV2.java | 84 +- .../tx/TransactionStructBuilderJniObj.java | 14 + .../tx/TransactionStructBuilderV2JniObj.java | 77 - .../sdk/jni/utilities/tx/TransactionV2.java | 67 - .../jni/utilities/tx/TransactionVersion.java | 29 +- .../bcos/sdk/jni/test/tx/TestTxStruct.java | 407 +++-- .../bcos/sdk/jni/test/tx/TestTxStructV2.java | 511 +++---- 16 files changed, 1512 insertions(+), 1137 deletions(-) delete mode 100644 bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes.java delete mode 100644 bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderV2JniObj.java delete mode 100644 bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionV2.java diff --git a/bcos-c-sdk/bcos_sdk_c_common.cpp b/bcos-c-sdk/bcos_sdk_c_common.cpp index fd7821923..2cb7d34b7 100644 --- a/bcos-c-sdk/bcos_sdk_c_common.cpp +++ b/bcos-c-sdk/bcos_sdk_c_common.cpp @@ -228,6 +228,7 @@ void bcos_sdk_c_handle_response( if (errorPtr && errorPtr->errorCode() != 0) { resp->error = errorPtr->errorCode(); + // not copy here because cpp sdk will release the errorPtr resp->desc = (char*)errorPtr->errorMessage().c_str(); resp->data = NULL; resp->size = 0; diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp index 95233ec4a..5d34da6b5 100644 --- a/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp @@ -643,32 +643,32 @@ void bcos_sdk_destroy_transaction_data_struct(struct bcos_sdk_c_transaction_data return; } - if (transaction_data && transaction_data->chain_id) + if (transaction_data->chain_id) { bcos_sdk_c_free(transaction_data->chain_id); } - if (transaction_data && transaction_data->group_id) + if (transaction_data->group_id) { bcos_sdk_c_free(transaction_data->group_id); } - if (transaction_data && transaction_data->nonce) + if (transaction_data->nonce) { bcos_sdk_c_free(transaction_data->nonce); } - if (transaction_data && transaction_data->to) + if (transaction_data->to) { bcos_sdk_c_free(transaction_data->to); } - if (transaction_data && transaction_data->abi) + if (transaction_data->abi) { bcos_sdk_c_free((void*)transaction_data->abi); } - if (transaction_data && transaction_data->input) + if (transaction_data->input) { if (transaction_data->input->buffer) { @@ -974,12 +974,12 @@ void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transact return; } - if (transaction && transaction->transaction_data) + if (transaction->transaction_data) { bcos_sdk_destroy_transaction_data_struct(transaction->transaction_data); } - if (transaction && transaction->data_hash) + if (transaction->data_hash) { if (transaction->data_hash->buffer) { @@ -988,7 +988,7 @@ void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transact bcos_sdk_c_free(transaction->data_hash); } - if (transaction && transaction->signature) + if (transaction->signature) { if (transaction->signature->buffer) { @@ -997,7 +997,7 @@ void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transact bcos_sdk_c_free(transaction->signature); } - if (transaction && transaction->sender) + if (transaction->sender) { if (transaction->sender->buffer) { @@ -1006,7 +1006,7 @@ void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transact bcos_sdk_c_free(transaction->sender); } - if (transaction && transaction->extra_data) + if (transaction->extra_data) { bcos_sdk_c_free(transaction->extra_data); } @@ -1322,32 +1322,32 @@ void bcos_sdk_destroy_transaction_data_struct_v2( return; } - if (transaction_data && transaction_data->chain_id) + if (transaction_data->chain_id) { bcos_sdk_c_free(transaction_data->chain_id); } - if (transaction_data && transaction_data->group_id) + if (transaction_data->group_id) { bcos_sdk_c_free(transaction_data->group_id); } - if (transaction_data && transaction_data->nonce) + if (transaction_data->nonce) { bcos_sdk_c_free(transaction_data->nonce); } - if (transaction_data && transaction_data->to) + if (transaction_data->to) { bcos_sdk_c_free(transaction_data->to); } - if (transaction_data && transaction_data->abi) + if (transaction_data->abi) { bcos_sdk_c_free((void*)transaction_data->abi); } - if (transaction_data && transaction_data->input) + if (transaction_data->input) { if (transaction_data->input->buffer) { @@ -1356,22 +1356,22 @@ void bcos_sdk_destroy_transaction_data_struct_v2( bcos_sdk_c_free((void*)transaction_data->input); } - if (transaction_data && transaction_data->value) + if (transaction_data->value) { bcos_sdk_c_free(transaction_data->value); } - if (transaction_data && transaction_data->gas_price) + if (transaction_data->gas_price) { bcos_sdk_c_free(transaction_data->gas_price); } - if (transaction_data && transaction_data->max_fee_per_gas) + if (transaction_data->max_fee_per_gas) { bcos_sdk_c_free(transaction_data->max_fee_per_gas); } - if (transaction_data && transaction_data->max_priority_fee_per_gas) + if (transaction_data->max_priority_fee_per_gas) { bcos_sdk_c_free(transaction_data->max_priority_fee_per_gas); } diff --git a/bindings/java/jni/scripts/java2jni.sh b/bindings/java/jni/scripts/java2jni.sh index fd00b93da..35c0f91ec 100644 --- a/bindings/java/jni/scripts/java2jni.sh +++ b/bindings/java/jni/scripts/java2jni.sh @@ -30,7 +30,7 @@ function convert_java_to_jni() { # convert_java_to_jni ${JAVA_SOURCE_PATH} # classes="rpc.RpcJniObj amop.AmopJniObj event.EventSubJniObj BcosSDKJniObj" -classes="BcosSDKJniObj utilities.keypair.KeyPairJniObj utilities.tx.TransactionBuilderJniObj utilities.tx.TransactionBuilderV2JniObj utilities.tx.TransactionStructBuilderJniObj utilities.tx.TransactionStructBuilderV2JniObj utilities.receipt.ReceiptBuilderJniObj utilities.signature.SignatureJniObj" +classes="BcosSDKJniObj utilities.keypair.KeyPairJniObj utilities.tx.TransactionBuilderJniObj utilities.tx.TransactionBuilderV2JniObj utilities.tx.TransactionStructBuilderJniObj utilities.receipt.ReceiptBuilderJniObj utilities.signature.SignatureJniObj" for class in ${classes} do diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcJniObj.cpp index cb5f1b546..92c192aa6 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcJniObj.cpp @@ -81,7 +81,7 @@ static void on_receive_rpc_response(struct bcos_sdk_c_struct_response* resp) // byte[] data jfieldID dataFieldID = env->GetFieldID(responseClass, "data", "[B"); - if (errorMsgFieldID == NULL) + if (dataFieldID == NULL) { env->ExceptionDescribe(); env->DeleteGlobalRef(jcallback); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.cpp index b7d528df0..12f34235b 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.cpp @@ -5,387 +5,752 @@ #include "org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_exception.h" -struct bcos_sdk_c_bytes* convert_to_bytes_struct(JNIEnv* env, jobject bytesObj) -{ - try - { - if (bytesObj == NULL) - { - return NULL; - } - struct bcos_sdk_c_bytes* bytes = - (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); - jclass bytesClass = env->GetObjectClass(bytesObj); - jfieldID bufferField = env->GetFieldID(bytesClass, "buffer", "[B"); - jfieldID lengthField = env->GetFieldID(bytesClass, "length", "I"); - - jbyteArray bufferArray = (jbyteArray)env->GetObjectField(bytesObj, bufferField); - jbyte* bufferData = env->GetByteArrayElements(bufferArray, nullptr); - jsize bufferLength = env->GetArrayLength(bufferArray); - bytes->length = (uint32_t)env->GetIntField(bytesObj, lengthField); - bytes->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); - memcpy(bytes->buffer, bufferData, bufferLength); - - env->ReleaseByteArrayElements(bufferArray, bufferData, 0); - - return bytes; - } - catch (...) +// tx data v2: java obj => c struct +struct bcos_sdk_c_transaction_data_v2* convert_to_tx_v2_data_struct( + JNIEnv* env, jobject transactionObject) +{ + if (transactionObject == NULL) { + THROW_JNI_EXCEPTION( + env, "exception in convert_to_tx_data_struct, transactionObject is nullptr"); return NULL; } -} -jobject convert_to_bytes_jobject(JNIEnv* env, const struct bcos_sdk_c_bytes* bytes_struct) -{ - try - { - if (bytes_struct == NULL) - { - return NULL; - } - - jclass txBytesClass = - env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes"); - if (txBytesClass == NULL) - { - env->FatalError( - "No such class, className: " - "org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes"); - } - jmethodID txBytesMtd = env->GetMethodID(txBytesClass, "", "()V"); - if (txBytesMtd == NULL) - { - env->FatalError("No such constructor in TransactionBytes, constructor()"); - } - jfieldID bufferField = env->GetFieldID(txBytesClass, "buffer", "[B"); - jfieldID lengthField = env->GetFieldID(txBytesClass, "length", "I"); - - jobject jTxBytesObj = env->NewObject(txBytesClass, txBytesMtd); - // buffer - jbyteArray bufferArray = env->NewByteArray(bytes_struct->length); - env->SetByteArrayRegion( - bufferArray, 0, bytes_struct->length, reinterpret_cast(bytes_struct->buffer)); - env->SetObjectField(jTxBytesObj, bufferField, bufferArray); - // length - env->SetIntField(jTxBytesObj, lengthField, bytes_struct->length); - - env->DeleteLocalRef(bufferArray); - - return jTxBytesObj; - } - catch (...) + jclass txDataClass = env->GetObjectClass(transactionObject); + + bcos_sdk_c_transaction_data_v2* tx_data_struct = (struct bcos_sdk_c_transaction_data_v2*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v2)); + // version + jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); + tx_data_struct->version = env->GetIntField(transactionObject, versionField); + + // blockLimit + jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); + tx_data_struct->block_limit = env->GetLongField(transactionObject, blockLimitField); + + // chainId + jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); + jstring chainIdString = (jstring)env->GetObjectField(transactionObject, chainIdField); + const char* chainIdValue = GET_J_STRING_CONTENT_DEF(env, chainIdString, ""); + tx_data_struct->chain_id = strdup(chainIdValue); + + // groupId + jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); + jstring groupIdString = (jstring)env->GetObjectField(transactionObject, groupIdField); + const char* groupIdValue = GET_J_STRING_CONTENT_DEF(env, groupIdString, ""); + tx_data_struct->group_id = strdup(groupIdValue); + + // nonce + jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); + jstring nonceString = (jstring)env->GetObjectField(transactionObject, nonceField); + const char* nonceValue = GET_J_STRING_CONTENT_DEF(env, nonceString, ""); + tx_data_struct->nonce = strdup(nonceValue); + + // to + jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); + jstring toString = (jstring)env->GetObjectField(transactionObject, toField); + const char* toValue = GET_J_STRING_CONTENT_DEF(env, toString, ""); + tx_data_struct->to = strdup(toValue); + + // abi + jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); + jstring abiString = (jstring)env->GetObjectField(transactionObject, abiField); + const char* abiValue = GET_J_STRING_CONTENT_DEF(env, abiString, ""); + tx_data_struct->abi = strdup(abiValue); + + // input byte[] + jfieldID inputField = env->GetFieldID(txDataClass, "input", "[B"); + jbyteArray inputbytes = (jbyteArray)env->GetObjectField(transactionObject, inputField); + if (inputbytes == nullptr) { + THROW_JNI_EXCEPTION(env, "exception in input filed."); return NULL; } + struct bcos_sdk_c_bytes* bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(inputbytes, nullptr); + jsize bufferLength = env->GetArrayLength(inputbytes); + bytes->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(bytes->buffer, bufferData, bufferLength); + bytes->length = bufferLength; + + tx_data_struct->input = bytes; + + + // value + jfieldID valueField = env->GetFieldID(txDataClass, "value", "Ljava/lang/String;"); + jstring valueString = (jstring)env->GetObjectField(transactionObject, valueField); + const char* valueChar = GET_J_STRING_CONTENT_DEF(env, valueString, ""); + tx_data_struct->value = strdup(valueChar); + + // gas_price + jfieldID gasPriceField = env->GetFieldID(txDataClass, "gasPrice", "Ljava/lang/String;"); + jstring gasPriceString = (jstring)env->GetObjectField(transactionObject, gasPriceField); + const char* gasPriceChar = GET_J_STRING_CONTENT_DEF(env, gasPriceString, ""); + tx_data_struct->gas_price = strdup(gasPriceChar); + + // gas_limit + jfieldID gasLimitField = env->GetFieldID(txDataClass, "gasLimit", "J"); + tx_data_struct->gas_limit = env->GetLongField(transactionObject, gasLimitField); + + // max_fee_per_gas + jfieldID maxFeePerGasField = env->GetFieldID(txDataClass, "maxFeePerGas", "Ljava/lang/String;"); + jstring maxFeePerGasString = (jstring)env->GetObjectField(transactionObject, maxFeePerGasField); + const char* maxFeePerGasChar = GET_J_STRING_CONTENT_DEF(env, maxFeePerGasString, ""); + tx_data_struct->max_fee_per_gas = strdup(maxFeePerGasChar); + + // max_priority_fee_per_gas + jfieldID maxPriorityFeePerGasField = + env->GetFieldID(txDataClass, "maxPriorityFeePerGas", "Ljava/lang/String;"); + jstring maxPriorityFeePerGasString = + (jstring)env->GetObjectField(transactionObject, maxPriorityFeePerGasField); + const char* maxPriorityFeePerGasChar = + GET_J_STRING_CONTENT_DEF(env, maxPriorityFeePerGasString, ""); + tx_data_struct->max_priority_fee_per_gas = strdup(maxPriorityFeePerGasChar); + + // release source + if (chainIdString) + env->ReleaseStringUTFChars(chainIdString, chainIdValue); + if (groupIdString) + env->ReleaseStringUTFChars(groupIdString, groupIdValue); + if (nonceString) + env->ReleaseStringUTFChars(nonceString, nonceValue); + if (toString) + env->ReleaseStringUTFChars(toString, toValue); + if (abiString) + env->ReleaseStringUTFChars(abiString, abiValue); + if (inputbytes) + env->ReleaseByteArrayElements(inputbytes, bufferData, 0); + if (valueString) + env->ReleaseStringUTFChars(valueString, valueChar); + if (gasPriceString) + env->ReleaseStringUTFChars(gasPriceString, gasPriceChar); + if (maxFeePerGasString) + env->ReleaseStringUTFChars(maxFeePerGasString, maxFeePerGasChar); + if (maxPriorityFeePerGasString) + env->ReleaseStringUTFChars(maxPriorityFeePerGasString, maxPriorityFeePerGasChar); + + return tx_data_struct; } +// tx data: java obj => c struct struct bcos_sdk_c_transaction_data* convert_to_tx_data_struct( JNIEnv* env, jobject transactionObject) { - try + if (transactionObject == NULL) { - if (transactionObject == NULL) - { - THROW_JNI_EXCEPTION( - env, "exception in convert_to_tx_data_struct, transactionObject is nullptr"); - return NULL; - } + THROW_JNI_EXCEPTION( + env, "exception in convert_to_tx_data_struct, transactionObject is nullptr"); + return NULL; + } - bcos_sdk_c_transaction_data* tx_data_struct = - (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); - jclass txDataClass = env->GetObjectClass(transactionObject); - - // version - jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); - tx_data_struct->version = env->GetIntField(transactionObject, versionField); - - // blockLimit - jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); - tx_data_struct->block_limit = env->GetLongField(transactionObject, blockLimitField); - - // chainId - jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); - jstring chainIdString = (jstring)env->GetObjectField(transactionObject, chainIdField); - const char* chainIdValue = env->GetStringUTFChars(chainIdString, nullptr); - tx_data_struct->chain_id = strdup(chainIdValue); - - // groupId - jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); - jstring groupIdString = (jstring)env->GetObjectField(transactionObject, groupIdField); - const char* groupIdValue = env->GetStringUTFChars(groupIdString, nullptr); - tx_data_struct->group_id = strdup(groupIdValue); - - // nonce - jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); - jstring nonceString = (jstring)env->GetObjectField(transactionObject, nonceField); - const char* nonceValue = env->GetStringUTFChars(nonceString, nullptr); - tx_data_struct->nonce = strdup(nonceValue); - - // to - jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); - jstring toString = (jstring)env->GetObjectField(transactionObject, toField); - const char* toValue = env->GetStringUTFChars(toString, nullptr); - tx_data_struct->to = strdup(toValue); - - // abi - jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); - jstring abiString = (jstring)env->GetObjectField(transactionObject, abiField); - const char* abiValue = env->GetStringUTFChars(abiString, nullptr); - tx_data_struct->abi = strdup(abiValue); - - // input - jfieldID inputField = env->GetFieldID( - txDataClass, "input", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jobject inputObject = env->GetObjectField(transactionObject, inputField); - struct bcos_sdk_c_bytes* inputStruct = convert_to_bytes_struct(env, inputObject); - if (inputStruct == NULL) - { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_struct"); - return NULL; - } - tx_data_struct->input = inputStruct; + bcos_sdk_c_transaction_data* tx_data_struct = + (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); + jclass txDataClass = env->GetObjectClass(transactionObject); + + // version + jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); + tx_data_struct->version = env->GetIntField(transactionObject, versionField); + + // blockLimit + jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); + tx_data_struct->block_limit = env->GetLongField(transactionObject, blockLimitField); + + // chainId + jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); + jstring chainIdString = (jstring)env->GetObjectField(transactionObject, chainIdField); + const char* chainIdValue = GET_J_STRING_CONTENT_DEF(env, chainIdString, ""); + tx_data_struct->chain_id = strdup(chainIdValue); + + // groupId + jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); + jstring groupIdString = (jstring)env->GetObjectField(transactionObject, groupIdField); + const char* groupIdValue = GET_J_STRING_CONTENT_DEF(env, groupIdString, ""); + tx_data_struct->group_id = strdup(groupIdValue); + + // nonce + jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); + jstring nonceString = (jstring)env->GetObjectField(transactionObject, nonceField); + const char* nonceValue = GET_J_STRING_CONTENT_DEF(env, nonceString, ""); + tx_data_struct->nonce = strdup(nonceValue); + + // to + jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); + jstring toString = (jstring)env->GetObjectField(transactionObject, toField); + const char* toValue = GET_J_STRING_CONTENT_DEF(env, toString, ""); + tx_data_struct->to = strdup(toValue); + + // abi + jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); + jstring abiString = (jstring)env->GetObjectField(transactionObject, abiField); + const char* abiValue = GET_J_STRING_CONTENT_DEF(env, abiString, ""); + tx_data_struct->abi = strdup(abiValue); + + // input byte[] + jfieldID inputField = env->GetFieldID(txDataClass, "input", "[B"); + jbyteArray inputbytes = (jbyteArray)env->GetObjectField(transactionObject, inputField); + if (inputbytes == nullptr) + { + THROW_JNI_EXCEPTION(env, "exception in input filed."); + return NULL; + } + struct bcos_sdk_c_bytes* bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(inputbytes, nullptr); + jsize bufferLength = env->GetArrayLength(inputbytes); + bytes->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(bytes->buffer, bufferData, bufferLength); + bytes->length = bufferLength; + + tx_data_struct->input = bytes; - // release source + // release source + if (chainIdString) env->ReleaseStringUTFChars(chainIdString, chainIdValue); + if (groupIdString) env->ReleaseStringUTFChars(groupIdString, groupIdValue); + if (nonceString) env->ReleaseStringUTFChars(nonceString, nonceValue); + if (toString) env->ReleaseStringUTFChars(toString, toValue); + if (abiString) env->ReleaseStringUTFChars(abiString, abiValue); + if (inputbytes) + env->ReleaseByteArrayElements(inputbytes, bufferData, 0); - return tx_data_struct; - } - catch (...) - { - return NULL; - } + return tx_data_struct; } +// tx data: c struct => java obj jobject convert_to_tx_data_jobject( JNIEnv* env, const struct bcos_sdk_c_transaction_data* transactionData) { - try + if (transactionData == NULL) { - if (transactionData == NULL) - { - THROW_JNI_EXCEPTION( - env, "exception in convert_to_tx_data_jobject, transactionData is nullptr"); - return NULL; - } + THROW_JNI_EXCEPTION( + env, "exception in convert_to_tx_data_jobject, transactionData is nullptr"); + return NULL; + } - jclass txDataClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionData"); - if (txDataClass == NULL) - { - env->FatalError( - "No such class, className: " - "org/fisco/bcos/sdk/jni/utilities/tx/TransactionData"); - } - jmethodID txDataMtd = env->GetMethodID(txDataClass, "", "()V"); - if (txDataMtd == NULL) - { - env->FatalError("No such constructor in TransactionData, constructor()"); - } - jobject jTxDataObj = env->NewObject(txDataClass, txDataMtd); - - // version - jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); - env->SetIntField(jTxDataObj, versionField, transactionData->version); - // block_limit - jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); - env->SetLongField(jTxDataObj, blockLimitField, transactionData->block_limit); - // chain_id - jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); - env->SetObjectField(jTxDataObj, chainIdField, env->NewStringUTF(transactionData->chain_id)); - // group_id - jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); - env->SetObjectField(jTxDataObj, groupIdField, env->NewStringUTF(transactionData->group_id)); - // nonce - jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); - env->SetObjectField(jTxDataObj, nonceField, env->NewStringUTF(transactionData->nonce)); - // to - jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); - env->SetObjectField(jTxDataObj, toField, env->NewStringUTF(transactionData->to)); - // abi - jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); - env->SetObjectField(jTxDataObj, abiField, env->NewStringUTF(transactionData->abi)); - - // input - jobject jInput = convert_to_bytes_jobject(env, transactionData->input); - if (jInput == NULL) - { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_jobject"); - return NULL; - } - jfieldID inputField = env->GetFieldID( - txDataClass, "input", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - env->SetObjectField(jTxDataObj, inputField, jInput); + jclass txDataClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionData"); + if (txDataClass == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/TransactionData"); + } + jmethodID txDataMtd = env->GetMethodID(txDataClass, "", "()V"); + if (txDataMtd == NULL) + { + env->FatalError("No such constructor in TransactionData, constructor()"); + } + jobject jTxDataObj = env->NewObject(txDataClass, txDataMtd); + + // version + jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); + env->SetIntField(jTxDataObj, versionField, transactionData->version); + // block_limit + jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); + env->SetLongField(jTxDataObj, blockLimitField, transactionData->block_limit); + // chain_id + jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, chainIdField, env->NewStringUTF(transactionData->chain_id)); + // group_id + jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, groupIdField, env->NewStringUTF(transactionData->group_id)); + // nonce + jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, nonceField, env->NewStringUTF(transactionData->nonce)); + // to + jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, toField, env->NewStringUTF(transactionData->to)); + // abi + jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, abiField, env->NewStringUTF(transactionData->abi)); + + if (transactionData->input) + { + jfieldID inputField = env->GetFieldID(txDataClass, "input", "[B"); + jbyteArray bufferArray = + env->NewByteArray(static_cast(transactionData->input->length)); + env->SetByteArrayRegion(bufferArray, 0, static_cast(transactionData->input->length), + reinterpret_cast(transactionData->input->buffer)); + env->SetObjectField(jTxDataObj, inputField, bufferArray); + } + return jTxDataObj; +} - // release - env->DeleteLocalRef(jInput); +// tx data v2: c struct => java obj +jobject convert_to_tx_v2_data_jobject( + JNIEnv* env, const struct bcos_sdk_c_transaction_data_v2* transactionData) +{ + if (transactionData == NULL) + { + THROW_JNI_EXCEPTION( + env, "exception in convert_to_tx_data_jobject, transactionData is nullptr"); + return NULL; + } - return jTxDataObj; + jclass txDataClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2"); + if (txDataClass == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2"); } - catch (...) + jmethodID txDataMtd = env->GetMethodID(txDataClass, "", "()V"); + if (txDataMtd == NULL) { - return NULL; + env->FatalError("No such constructor in TransactionData, constructor()"); } + jobject jTxDataObj = env->NewObject(txDataClass, txDataMtd); + + // version + jfieldID versionField = env->GetFieldID(txDataClass, "version", "I"); + env->SetIntField(jTxDataObj, versionField, transactionData->version); + // block_limit + jfieldID blockLimitField = env->GetFieldID(txDataClass, "blockLimit", "J"); + env->SetLongField(jTxDataObj, blockLimitField, transactionData->block_limit); + // chain_id + jfieldID chainIdField = env->GetFieldID(txDataClass, "chainId", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, chainIdField, env->NewStringUTF(transactionData->chain_id)); + // group_id + jfieldID groupIdField = env->GetFieldID(txDataClass, "groupId", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, groupIdField, env->NewStringUTF(transactionData->group_id)); + // nonce + jfieldID nonceField = env->GetFieldID(txDataClass, "nonce", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, nonceField, env->NewStringUTF(transactionData->nonce)); + // to + jfieldID toField = env->GetFieldID(txDataClass, "to", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, toField, env->NewStringUTF(transactionData->to)); + // abi + jfieldID abiField = env->GetFieldID(txDataClass, "abi", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, abiField, env->NewStringUTF(transactionData->abi)); + // input + if (transactionData->input) + { + jfieldID inputField = env->GetFieldID(txDataClass, "input", "[B"); + jbyteArray bufferArray = + env->NewByteArray(static_cast(transactionData->input->length)); + env->SetByteArrayRegion(bufferArray, 0, static_cast(transactionData->input->length), + reinterpret_cast(transactionData->input->buffer)); + env->SetObjectField(jTxDataObj, inputField, bufferArray); + } + + // value + jfieldID valueField = env->GetFieldID(txDataClass, "value", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, valueField, env->NewStringUTF(transactionData->value)); + // gas_price + jfieldID gasPriceField = env->GetFieldID(txDataClass, "gasPrice", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, gasPriceField, env->NewStringUTF(transactionData->gas_price)); + // gas_limit + jfieldID gasLimitField = env->GetFieldID(txDataClass, "gasLimit", "J"); + env->SetLongField(jTxDataObj, gasLimitField, transactionData->gas_limit); + // max_fee_per_gas + jfieldID maxFeePerGasField = env->GetFieldID(txDataClass, "maxFeePerGas", "Ljava/lang/String;"); + env->SetObjectField( + jTxDataObj, maxFeePerGasField, env->NewStringUTF(transactionData->max_fee_per_gas)); + // max_priority_fee_per_gas + jfieldID maxPriorityFeePerGasField = + env->GetFieldID(txDataClass, "maxPriorityFeePerGas", "Ljava/lang/String;"); + env->SetObjectField(jTxDataObj, maxPriorityFeePerGasField, + env->NewStringUTF(transactionData->max_priority_fee_per_gas)); + + + return jTxDataObj; } +// tx: c struct => java obj jobject convert_to_tx_jobject(JNIEnv* env, const struct bcos_sdk_c_transaction* tx_struct) { - try + if (tx_struct == NULL) { - if (tx_struct == NULL) - { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_jobject, tx_struct is nullptr"); - return NULL; - } + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_jobject, tx_struct is nullptr"); + return NULL; + } - jclass txClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); - if (txClass == NULL) + jclass txClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); + if (txClass == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); + } + jmethodID txMtd = env->GetMethodID(txClass, "", "()V"); + if (txMtd == NULL) + { + env->FatalError("No such constructor in Transaction, constructor()"); + } + jfieldID txDataField = env->GetFieldID( + txClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jfieldID dataHashField = env->GetFieldID(txClass, "dataHash", "[B"); + jfieldID signatureField = env->GetFieldID(txClass, "signature", "[B"); + jfieldID senderField = env->GetFieldID(txClass, "sender", "[B"); + jfieldID importTimeField = env->GetFieldID(txClass, "importTime", "J"); + jfieldID attributeField = env->GetFieldID(txClass, "attribute", "I"); + jfieldID extraDataField = env->GetFieldID(txClass, "extraData", "Ljava/lang/String;"); + + jobject javaTxObj = env->NewObject(txClass, txMtd); + // TransactionData + jobject javaTxDataObj = convert_to_tx_data_jobject(env, tx_struct->transaction_data); + if (javaTxDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in TransactionData field."); + return NULL; + } + env->SetObjectField(javaTxObj, txDataField, javaTxDataObj); + // DataHash byte[] + { + if (tx_struct->data_hash != NULL) { - env->FatalError( - "No such class, className: " - "org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->data_hash->length)); + env->SetByteArrayRegion(bufferArray, 0, + static_cast(tx_struct->data_hash->length), + reinterpret_cast(tx_struct->data_hash->buffer)); + env->SetObjectField(javaTxObj, dataHashField, bufferArray); } - jmethodID txMtd = env->GetMethodID(txClass, "", "()V"); - if (txMtd == NULL) + } + // Signature byte[] + { + if (tx_struct->signature != NULL) { - env->FatalError("No such constructor in Transaction, constructor()"); + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->signature->length)); + env->SetByteArrayRegion(bufferArray, 0, + static_cast(tx_struct->signature->length), + reinterpret_cast(tx_struct->signature->buffer)); + env->SetObjectField(javaTxObj, signatureField, bufferArray); } - jfieldID txDataField = env->GetFieldID( - txClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); - jfieldID dataHashField = env->GetFieldID( - txClass, "dataHash", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID signatureField = env->GetFieldID( - txClass, "signature", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID senderField = env->GetFieldID( - txClass, "sender", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID importTimeField = env->GetFieldID(txClass, "importTime", "J"); - jfieldID attributeField = env->GetFieldID(txClass, "attribute", "I"); - jfieldID extraDataField = env->GetFieldID(txClass, "extraData", "Ljava/lang/String;"); - - jobject javaTxObj = env->NewObject(txClass, txMtd); - // TransactionData - jobject javaTxDataObj = convert_to_tx_data_jobject(env, tx_struct->transaction_data); - if (javaTxDataObj == NULL) + } + // Sender byte[] + { + if (tx_struct->sender != NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_jobject"); - return NULL; + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->sender->length)); + env->SetByteArrayRegion(bufferArray, 0, static_cast(tx_struct->sender->length), + reinterpret_cast(tx_struct->sender->buffer)); + env->SetObjectField(javaTxObj, senderField, bufferArray); } - env->SetObjectField(javaTxObj, txDataField, javaTxDataObj); - // DataHash - jobject javaDataHashObj = convert_to_bytes_jobject(env, tx_struct->data_hash); - if (javaDataHashObj == NULL) + } + // ImportTime + env->SetLongField(javaTxObj, importTimeField, tx_struct->import_time); + // Attribute + env->SetIntField(javaTxObj, attributeField, tx_struct->attribute); + // ExtraData + jstring javaExtraData = env->NewStringUTF(tx_struct->extra_data); + env->SetObjectField(javaTxObj, extraDataField, javaExtraData); + + return javaTxObj; +} + +// tx v2: c struct => java obj +jobject convert_to_tx_v2_jobject(JNIEnv* env, const struct bcos_sdk_c_transaction_v2* tx_struct) + +{ + if (tx_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_jobject, tx_struct is nullptr"); + return NULL; + } + + jclass txClass = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); + if (txClass == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/Transaction"); + } + jmethodID txMtd = env->GetMethodID(txClass, "", "()V"); + if (txMtd == NULL) + { + env->FatalError("No such constructor in Transaction, constructor()"); + } + jfieldID txDataField = env->GetFieldID( + txClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jfieldID dataHashField = env->GetFieldID(txClass, "dataHash", "[B"); + jfieldID signatureField = env->GetFieldID(txClass, "signature", "[B"); + jfieldID senderField = env->GetFieldID(txClass, "sender", "[B"); + jfieldID importTimeField = env->GetFieldID(txClass, "importTime", "J"); + jfieldID attributeField = env->GetFieldID(txClass, "attribute", "I"); + jfieldID extraDataField = env->GetFieldID(txClass, "extraData", "Ljava/lang/String;"); + + jobject javaTxObj = env->NewObject(txClass, txMtd); + // TransactionData + jobject javaTxDataObj = convert_to_tx_v2_data_jobject(env, tx_struct->transaction_data); + if (javaTxDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in TransactionData field."); + return NULL; + } + env->SetObjectField(javaTxObj, txDataField, javaTxDataObj); + // DataHash byte[] + { + if (tx_struct->data_hash) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_jobject"); - return NULL; + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->data_hash->length)); + env->SetByteArrayRegion(bufferArray, 0, + static_cast(tx_struct->data_hash->length), + reinterpret_cast(tx_struct->data_hash->buffer)); + env->SetObjectField(javaTxObj, dataHashField, bufferArray); } - env->SetObjectField(javaTxObj, dataHashField, javaDataHashObj); - // Signature - jobject javaSignatureObj = convert_to_bytes_jobject(env, tx_struct->signature); - if (javaSignatureObj == NULL) + } + // Signature byte[] + { + if (tx_struct->signature) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_jobject"); - return NULL; + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->signature->length)); + env->SetByteArrayRegion(bufferArray, 0, + static_cast(tx_struct->signature->length), + reinterpret_cast(tx_struct->signature->buffer)); + env->SetObjectField(javaTxObj, signatureField, bufferArray); } - env->SetObjectField(javaTxObj, signatureField, javaSignatureObj); - // Sender - jobject javaSenderObj = convert_to_bytes_jobject(env, tx_struct->sender); - env->SetObjectField(javaTxObj, senderField, javaSenderObj); - // ImportTime - env->SetLongField(javaTxObj, importTimeField, tx_struct->import_time); - // Attribute - env->SetIntField(javaTxObj, attributeField, tx_struct->attribute); - // ExtraData - jstring javaExtraData = env->NewStringUTF(tx_struct->extra_data); - env->SetObjectField(javaTxObj, extraDataField, javaExtraData); - - return javaTxObj; } - catch (...) + // Sender byte[] { - return NULL; + if (tx_struct->sender) + { + jbyteArray bufferArray = + env->NewByteArray(static_cast(tx_struct->sender->length)); + env->SetByteArrayRegion(bufferArray, 0, static_cast(tx_struct->sender->length), + reinterpret_cast(tx_struct->sender->buffer)); + env->SetObjectField(javaTxObj, senderField, bufferArray); + } } + // ImportTime + env->SetLongField(javaTxObj, importTimeField, tx_struct->import_time); + // Attribute + env->SetIntField(javaTxObj, attributeField, tx_struct->attribute); + // ExtraData + jstring javaExtraData = env->NewStringUTF(tx_struct->extra_data); + env->SetObjectField(javaTxObj, extraDataField, javaExtraData); + + return javaTxObj; } +// tx: java obj => c struct struct bcos_sdk_c_transaction* convert_to_tx_struct(JNIEnv* env, jobject jTxObj) { - try + if (jTxObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct, Transaction is nullptr"); + return NULL; + } + + jclass javaTxClass = env->GetObjectClass(jTxObj); + jfieldID transactionDataField = env->GetFieldID( + javaTxClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jfieldID dataHashField = env->GetFieldID(javaTxClass, "dataHash", "[B"); + jfieldID signatureField = env->GetFieldID(javaTxClass, "signature", "[B"); + jfieldID senderField = env->GetFieldID(javaTxClass, "sender", "[B"); + jfieldID importTimeField = env->GetFieldID(javaTxClass, "importTime", "J"); + jfieldID attributeField = env->GetFieldID(javaTxClass, "attribute", "I"); + jfieldID extraDataField = env->GetFieldID(javaTxClass, "extraData", "Ljava/lang/String;"); + + struct bcos_sdk_c_transaction* txStruct = + (struct bcos_sdk_c_transaction*)malloc(sizeof(struct bcos_sdk_c_transaction)); + // TransactionData + jobject javaTxDataObj = env->GetObjectField(jTxObj, transactionDataField); + struct bcos_sdk_c_transaction_data* txDataStruct = + convert_to_tx_data_struct(env, javaTxDataObj); + if (txDataStruct == NULL) { - if (jTxObj == NULL) + THROW_JNI_EXCEPTION(env, "exception in txDataStruct field."); + return NULL; + } + txStruct->transaction_data = txDataStruct; + // DataHash byte[] + { + jbyteArray dataHashBytes = (jbyteArray)env->GetObjectField(jTxObj, dataHashField); + if (dataHashBytes == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct, jTxObj is nullptr"); + THROW_JNI_EXCEPTION(env, "exception in DataHash field."); return NULL; } + struct bcos_sdk_c_bytes* dataHash = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(dataHashBytes, nullptr); + jsize bufferLength = env->GetArrayLength(dataHashBytes); + dataHash->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(dataHash->buffer, bufferData, bufferLength); + dataHash->length = bufferLength; + + // release temp dataHashBytes + env->ReleaseByteArrayElements(dataHashBytes, bufferData, 0); + txStruct->data_hash = dataHash; + } - jclass javaTxClass = env->GetObjectClass(jTxObj); - jfieldID transactionDataField = env->GetFieldID(javaTxClass, "transactionData", - "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); - jfieldID dataHashField = env->GetFieldID( - javaTxClass, "dataHash", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID signatureField = env->GetFieldID( - javaTxClass, "signature", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID senderField = env->GetFieldID( - javaTxClass, "sender", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes;"); - jfieldID importTimeField = env->GetFieldID(javaTxClass, "importTime", "J"); - jfieldID attributeField = env->GetFieldID(javaTxClass, "attribute", "I"); - jfieldID extraDataField = env->GetFieldID(javaTxClass, "extraData", "Ljava/lang/String;"); - - struct bcos_sdk_c_transaction* txStruct = - (struct bcos_sdk_c_transaction*)malloc(sizeof(struct bcos_sdk_c_transaction)); - // TransactionData - jobject javaTxDataObj = env->GetObjectField(jTxObj, transactionDataField); - struct bcos_sdk_c_transaction_data* txDataStruct = - convert_to_tx_data_struct(env, javaTxDataObj); - if (txDataStruct == NULL) + // Signature byte[] + { + jbyteArray signatureBytes = (jbyteArray)env->GetObjectField(jTxObj, signatureField); + if (signatureBytes == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + THROW_JNI_EXCEPTION(env, "exception in Signature field."); return NULL; } - txStruct->transaction_data = txDataStruct; - // DataHash - jobject javaDataHashObj = env->GetObjectField(jTxObj, dataHashField); - struct bcos_sdk_c_bytes* dataHashStruct = convert_to_bytes_struct(env, javaDataHashObj); - if (dataHashStruct == NULL) + struct bcos_sdk_c_bytes* signature = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(signatureBytes, nullptr); + jsize bufferLength = env->GetArrayLength(signatureBytes); + signature->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(signature->buffer, bufferData, bufferLength); + signature->length = bufferLength; + + // release temp signatureBytes + env->ReleaseByteArrayElements(signatureBytes, bufferData, 0); + txStruct->signature = signature; + } + // Sender byte[] + { + jbyteArray senderBytes = (jbyteArray)env->GetObjectField(jTxObj, senderField); + if (senderBytes == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_struct"); - return NULL; + // sender can be null + txStruct->sender = NULL; } - txStruct->data_hash = dataHashStruct; - // Signature - jobject javaSignatureObj = env->GetObjectField(jTxObj, signatureField); - struct bcos_sdk_c_bytes* signatureStruct = convert_to_bytes_struct(env, javaSignatureObj); - if (signatureStruct == NULL) + else { - THROW_JNI_EXCEPTION(env, "exception in convert_to_bytes_struct"); - return NULL; + struct bcos_sdk_c_bytes* sender = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(senderBytes, nullptr); + jsize bufferLength = env->GetArrayLength(senderBytes); + sender->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(sender->buffer, bufferData, bufferLength); + sender->length = bufferLength; + + // release temp senderBytes + env->ReleaseByteArrayElements(senderBytes, bufferData, 0); + txStruct->sender = sender; } - txStruct->signature = signatureStruct; - // Sender - jobject javaSenderObj = env->GetObjectField(jTxObj, senderField); - struct bcos_sdk_c_bytes* senderStruct = convert_to_bytes_struct(env, javaSenderObj); - txStruct->sender = senderStruct; - // ImportTime - jlong importTimeValue = env->GetLongField(jTxObj, importTimeField); - txStruct->import_time = (int64_t)importTimeValue; - // Attribute - jint attributeValue = env->GetIntField(jTxObj, attributeField); - txStruct->attribute = (int32_t)attributeValue; - // ExtraData - jstring javaExtraData = (jstring)env->GetObjectField(jTxObj, extraDataField); - const char* extraDataValue = env->GetStringUTFChars(javaExtraData, NULL); - txStruct->extra_data = strdup(extraDataValue); - - env->ReleaseStringUTFChars(javaExtraData, extraDataValue); + } + // ImportTime + jlong importTimeValue = env->GetLongField(jTxObj, importTimeField); + txStruct->import_time = (int64_t)importTimeValue; + // Attribute + jint attributeValue = env->GetIntField(jTxObj, attributeField); + txStruct->attribute = (int32_t)attributeValue; + // ExtraData + jstring javaExtraData = (jstring)env->GetObjectField(jTxObj, extraDataField); + const char* extraDataValue = GET_J_STRING_CONTENT_DEF(env, javaExtraData, ""); + txStruct->extra_data = strdup(extraDataValue); + + env->ReleaseStringUTFChars(javaExtraData, extraDataValue); + + return txStruct; +} - return txStruct; +// tx v2: java obj => c struct +struct bcos_sdk_c_transaction_v2* convert_to_tx_v2_struct(JNIEnv* env, jobject jTxObj) +{ + if (jTxObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct, Transaction is nullptr"); + return NULL; } - catch (...) + + jclass javaTxClass = env->GetObjectClass(jTxObj); + jfieldID transactionDataField = env->GetFieldID( + javaTxClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jfieldID dataHashField = env->GetFieldID(javaTxClass, "dataHash", "[B"); + jfieldID signatureField = env->GetFieldID(javaTxClass, "signature", "[B"); + jfieldID senderField = env->GetFieldID(javaTxClass, "sender", "[B"); + jfieldID importTimeField = env->GetFieldID(javaTxClass, "importTime", "J"); + jfieldID attributeField = env->GetFieldID(javaTxClass, "attribute", "I"); + jfieldID extraDataField = env->GetFieldID(javaTxClass, "extraData", "Ljava/lang/String;"); + + struct bcos_sdk_c_transaction_v2* txStruct = + (struct bcos_sdk_c_transaction_v2*)malloc(sizeof(struct bcos_sdk_c_transaction_v2)); + // TransactionData + jobject javaTxDataObj = env->GetObjectField(jTxObj, transactionDataField); + struct bcos_sdk_c_transaction_data_v2* txDataStruct = + convert_to_tx_v2_data_struct(env, javaTxDataObj); + if (txDataStruct == NULL) { + THROW_JNI_EXCEPTION(env, "exception in txDataStruct field."); return NULL; } + txStruct->transaction_data = txDataStruct; + // DataHash byte[] + { + jbyteArray dataHashBytes = (jbyteArray)env->GetObjectField(jTxObj, dataHashField); + if (dataHashBytes == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in DataHash field."); + return NULL; + } + struct bcos_sdk_c_bytes* dataHash = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(dataHashBytes, nullptr); + jsize bufferLength = env->GetArrayLength(dataHashBytes); + dataHash->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(dataHash->buffer, bufferData, bufferLength); + dataHash->length = bufferLength; + + // release temp dataHashBytes + env->ReleaseByteArrayElements(dataHashBytes, bufferData, 0); + txStruct->data_hash = dataHash; + } + + // Signature byte[] + { + jbyteArray signatureBytes = (jbyteArray)env->GetObjectField(jTxObj, signatureField); + if (signatureBytes == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in Signature field."); + return NULL; + } + struct bcos_sdk_c_bytes* signature = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(signatureBytes, nullptr); + jsize bufferLength = env->GetArrayLength(signatureBytes); + signature->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(signature->buffer, bufferData, bufferLength); + signature->length = bufferLength; + + // release temp signatureBytes + env->ReleaseByteArrayElements(signatureBytes, bufferData, 0); + txStruct->signature = signature; + } + // Sender byte[] + { + jbyteArray senderBytes = (jbyteArray)env->GetObjectField(jTxObj, senderField); + if (senderBytes == NULL) + { + // sender can be null + txStruct->sender = NULL; + } + else + { + struct bcos_sdk_c_bytes* sender = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + jbyte* bufferData = env->GetByteArrayElements(senderBytes, nullptr); + jsize bufferLength = env->GetArrayLength(senderBytes); + sender->buffer = (uint8_t*)malloc(bufferLength * sizeof(uint8_t)); + memmove(sender->buffer, bufferData, bufferLength); + sender->length = bufferLength; + // release temp senderBytes + env->ReleaseByteArrayElements(senderBytes, bufferData, 0); + txStruct->sender = sender; + } + } + // ImportTime + jlong importTimeValue = env->GetLongField(jTxObj, importTimeField); + txStruct->import_time = (int64_t)importTimeValue; + // Attribute + jint attributeValue = env->GetIntField(jTxObj, attributeField); + txStruct->attribute = (int32_t)attributeValue; + // ExtraData + jstring javaExtraData = (jstring)env->GetObjectField(jTxObj, extraDataField); + const char* extraDataValue = GET_J_STRING_CONTENT_DEF(env, javaExtraData, ""); + txStruct->extra_data = strdup(extraDataValue); + + env->ReleaseStringUTFChars(javaExtraData, extraDataValue); + + return txStruct; } /* @@ -397,14 +762,43 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStruct( JNIEnv* env, jclass, jobject jTransactionDataObj) { - struct bcos_sdk_c_transaction_data* tx_data_struct = - convert_to_tx_data_struct(env, jTransactionDataObj); - if (tx_data_struct == NULL) + if (jTransactionDataObj == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); - return nullptr; + THROW_JNI_EXCEPTION(env, "transactionDataObject is nullptr"); + return NULL; + } + const char* tx_data_hex = nullptr; + if (env->IsInstanceOf(jTransactionDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v2* tx_data_struct = + convert_to_tx_v2_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_hex = bcos_sdk_encode_transaction_data_struct_to_hex_v2(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v2(tx_data_struct); + } + } + else + { + struct bcos_sdk_c_transaction_data* tx_data_struct = + convert_to_tx_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_hex = bcos_sdk_encode_transaction_data_struct_to_hex(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct(tx_data_struct); + } } - const char* tx_data_hex = bcos_sdk_encode_transaction_data_struct_to_hex(tx_data_struct); if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -418,10 +812,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTr free((void*)tx_data_hex); tx_data_hex = NULL; } - if (tx_data_struct) - { - bcos_sdk_destroy_transaction_data_struct(tx_data_struct); - } + return jTxDataHex; } @@ -435,14 +826,43 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStructToJson( JNIEnv* env, jclass, jobject jTransactionDataObj) { - struct bcos_sdk_c_transaction_data* tx_data_struct = - convert_to_tx_data_struct(env, jTransactionDataObj); - if (tx_data_struct == NULL) + if (jTransactionDataObj == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); - return nullptr; + THROW_JNI_EXCEPTION(env, "transactionDataObject is nullptr"); + return NULL; + } + const char* tx_data_json = nullptr; + if (env->IsInstanceOf(jTransactionDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v2* tx_data_struct = + convert_to_tx_v2_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_json = bcos_sdk_encode_transaction_data_struct_to_json_v2(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v2(tx_data_struct); + } + } + else + { + struct bcos_sdk_c_transaction_data* tx_data_struct = + convert_to_tx_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_json = bcos_sdk_encode_transaction_data_struct_to_json(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct(tx_data_struct); + } } - const char* tx_data_json = bcos_sdk_encode_transaction_data_struct_to_json(tx_data_struct); if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -456,10 +876,6 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTr free((void*)tx_data_json); tx_data_json = NULL; } - if (tx_data_struct) - { - bcos_sdk_destroy_transaction_data_struct(tx_data_struct); - } return jTxDataJson; } @@ -473,7 +889,7 @@ JNIEXPORT jobject JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStruct( JNIEnv* env, jclass, jstring jTxDataHexStr) { - checkJString(env, jTxDataHexStr); + CHECK_OBJECT_NOT_NULL(env, jTxDataHexStr, nullptr); const char* tx_data_hex_str = env->GetStringUTFChars(jTxDataHexStr, nullptr); struct bcos_sdk_c_transaction_data* tx_data_struct = bcos_sdk_decode_transaction_data_struct_from_hex(tx_data_hex_str); @@ -500,6 +916,43 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTr return jTxDataObj; } +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionDataStructV2 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStructV2( + JNIEnv* env, jclass, jstring jTxDataHexStr) +{ + CHECK_OBJECT_NOT_NULL(env, jTxDataHexStr, nullptr); + + const char* tx_data_hex_str = env->GetStringUTFChars(jTxDataHexStr, nullptr); + struct bcos_sdk_c_transaction_data_v2* tx_data_struct_v2 = + bcos_sdk_decode_transaction_data_struct_from_hex_v2(tx_data_hex_str); + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jobject jTxDataObj = convert_to_tx_v2_data_jobject(env, tx_data_struct_v2); + if (jTxDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_v2_data_jobject"); + return nullptr; + } + + // release source + if (tx_data_struct_v2) + { + bcos_sdk_destroy_transaction_data_struct_v2(tx_data_struct_v2); + } + env->ReleaseStringUTFChars(jTxDataHexStr, tx_data_hex_str); + + return jTxDataObj; +} + /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj * Method: calcTransactionDataStructHash @@ -509,16 +962,44 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_calcTransactionDataStructHash( JNIEnv* env, jclass, jint jCrytpTyte, jobject jTransactionDataObj) { - struct bcos_sdk_c_transaction_data* tx_data_struct = - convert_to_tx_data_struct(env, jTransactionDataObj); - if (tx_data_struct == NULL) + if (jTransactionDataObj == NULL) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); - return nullptr; + THROW_JNI_EXCEPTION(env, "transactionDataObject is nullptr"); + return NULL; } + const char* tx_data_hash = nullptr; int crypto_type = jCrytpTyte; - const char* tx_data_hash = - bcos_sdk_calc_transaction_data_struct_hash(crypto_type, tx_data_struct); + if (env->IsInstanceOf(jTransactionDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v2* tx_data_struct = + convert_to_tx_v2_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_hash = bcos_sdk_calc_transaction_data_struct_hash_v2(crypto_type, tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v2(tx_data_struct); + } + } + else + { + struct bcos_sdk_c_transaction_data* tx_data_struct = + convert_to_tx_data_struct(env, jTransactionDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_data_hash = bcos_sdk_calc_transaction_data_struct_hash(crypto_type, tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct(tx_data_struct); + } + } if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -528,10 +1009,6 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_calcTran jstring jTxDataHash = env->NewStringUTF(tx_data_hash); // release source - if (tx_data_struct) - { - bcos_sdk_destroy_transaction_data_struct(tx_data_struct); - } if (tx_data_hash) { free((void*)tx_data_hash); @@ -552,23 +1029,51 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_createEn JNIEnv* env, jclass, jobject jTxDataObj, jstring jSignature, jstring jTxDataHash, jint jAttribute, jstring jExtraData) { - checkJString(env, jSignature); - checkJString(env, jTxDataHash); - checkJString(env, jExtraData); + CHECK_OBJECT_NOT_NULL(env, jTxDataObj, nullptr); + CHECK_OBJECT_NOT_NULL(env, jSignature, nullptr); + CHECK_OBJECT_NOT_NULL(env, jTxDataHash, nullptr); + CHECK_OBJECT_NOT_NULL(env, jExtraData, nullptr); - struct bcos_sdk_c_transaction_data* tx_data_struct = convert_to_tx_data_struct(env, jTxDataObj); - if (tx_data_struct == NULL) - { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); - return nullptr; - } + const char* tx_str = nullptr; const char* signature = env->GetStringUTFChars(jSignature, NULL); const char* tx_data_hash = env->GetStringUTFChars(jTxDataHash, NULL); int attribute = jAttribute; const char* extra_data = env->GetStringUTFChars(jExtraData, NULL); + if (env->IsInstanceOf(jTxDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v2* tx_data_struct = + convert_to_tx_v2_data_struct(env, jTxDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_str = bcos_sdk_create_encoded_transaction_v2( + tx_data_struct, signature, tx_data_hash, attribute, extra_data); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v2(tx_data_struct); + } + } + else + { + struct bcos_sdk_c_transaction_data* tx_data_struct = + convert_to_tx_data_struct(env, jTxDataObj); + if (tx_data_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_struct"); + return nullptr; + } + tx_str = bcos_sdk_create_encoded_transaction( + tx_data_struct, signature, tx_data_hash, attribute, extra_data); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct(tx_data_struct); + } + } + - const char* tx_str = bcos_sdk_create_encoded_transaction( - tx_data_struct, signature, tx_data_hash, attribute, extra_data); if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -581,10 +1086,6 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_createEn env->ReleaseStringUTFChars(jSignature, signature); env->ReleaseStringUTFChars(jTxDataHash, tx_data_hash); env->ReleaseStringUTFChars(jExtraData, extra_data); - if (tx_data_struct) - { - bcos_sdk_destroy_transaction_data_struct(tx_data_struct); - } if (tx_str) { free((void*)tx_str); @@ -603,13 +1104,43 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStruct( JNIEnv* env, jclass, jobject jTransactionObj) { - struct bcos_sdk_c_transaction* tx_struct = convert_to_tx_struct(env, jTransactionObj); - if (tx_struct == NULL) + CHECK_OBJECT_NOT_NULL(env, jTransactionObj, nullptr); + + jclass javaTxClass = env->GetObjectClass(jTransactionObj); + jfieldID transactionDataField = env->GetFieldID( + javaTxClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jobject javaTxDataObj = env->GetObjectField(jTransactionObj, transactionDataField); + CHECK_OBJECT_NOT_NULL(env, javaTxDataObj, nullptr); + const char* tx_hex = nullptr; + if (env->IsInstanceOf(javaTxDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); - return nullptr; + bcos_sdk_c_transaction_v2* tx_struct = convert_to_tx_v2_struct(env, jTransactionObj); + if (tx_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); + return nullptr; + } + tx_hex = bcos_sdk_encode_transaction_struct_to_hex_v2(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct_v2(tx_struct); + } + } + else + { + struct bcos_sdk_c_transaction* tx_struct = convert_to_tx_struct(env, jTransactionObj); + if (tx_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); + return nullptr; + } + tx_hex = bcos_sdk_encode_transaction_struct_to_hex(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct(tx_struct); + } } - const char* tx_hex = bcos_sdk_encode_transaction_struct_to_hex(tx_struct); if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -624,10 +1155,6 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTr free((void*)tx_hex); tx_hex = NULL; } - if (tx_struct) - { - bcos_sdk_destroy_transaction_struct(tx_struct); - } return jTxHex; } @@ -641,13 +1168,42 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStructToJson( JNIEnv* env, jclass, jobject jTransactionObj) { - struct bcos_sdk_c_transaction* tx_struct = convert_to_tx_struct(env, jTransactionObj); - if (tx_struct == NULL) + CHECK_OBJECT_NOT_NULL(env, jTransactionObj, nullptr); + jclass javaTxClass = env->GetObjectClass(jTransactionObj); + jfieldID transactionDataField = env->GetFieldID( + javaTxClass, "transactionData", "Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;"); + jobject javaTxDataObj = env->GetObjectField(jTransactionObj, transactionDataField); + CHECK_OBJECT_NOT_NULL(env, javaTxDataObj, nullptr); + const char* tx_json = nullptr; + if (env->IsInstanceOf(javaTxDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2")) == JNI_TRUE) { - THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); - return nullptr; + bcos_sdk_c_transaction_v2* tx_struct = convert_to_tx_v2_struct(env, jTransactionObj); + if (tx_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); + return nullptr; + } + tx_json = bcos_sdk_encode_transaction_struct_to_json_v2(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct_v2(tx_struct); + } + } + else + { + struct bcos_sdk_c_transaction* tx_struct = convert_to_tx_struct(env, jTransactionObj); + if (tx_struct == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_struct"); + return nullptr; + } + tx_json = bcos_sdk_encode_transaction_struct_to_json(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct(tx_struct); + } } - const char* tx_json = bcos_sdk_encode_transaction_struct_to_json(tx_struct); if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); @@ -661,10 +1217,6 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTr free((void*)tx_json); tx_json = NULL; } - if (tx_struct) - { - bcos_sdk_destroy_transaction_struct(tx_struct); - } return jTxJson; } @@ -678,7 +1230,7 @@ JNIEXPORT jobject JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStruct( JNIEnv* env, jclass, jstring jTxHexStr) { - checkJString(env, jTxHexStr); + CHECK_OBJECT_NOT_NULL(env, jTxHexStr, nullptr); const char* tx_hex_str = env->GetStringUTFChars(jTxHexStr, nullptr); struct bcos_sdk_c_transaction* tx_struct = @@ -705,3 +1257,40 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTr return jTxObj; } + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionStructV2 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionV2; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStructV2( + JNIEnv* env, jclass, jstring jTxHexStr) +{ + CHECK_OBJECT_NOT_NULL(env, jTxHexStr, nullptr); + + const char* tx_hex_str = env->GetStringUTFChars(jTxHexStr, nullptr); + struct bcos_sdk_c_transaction_v2* tx_struct_v2 = + bcos_sdk_decode_transaction_struct_from_hex_v2(tx_hex_str); + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jobject jTxObj = convert_to_tx_v2_jobject(env, tx_struct_v2); + if (jTxObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_v2_jobject"); + return nullptr; + } + + // release source + if (tx_struct_v2) + { + bcos_sdk_destroy_transaction_struct_v2(tx_struct_v2); + } + env->ReleaseStringUTFChars(jTxHexStr, tx_hex_str); + + return jTxObj; +} diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h index ba591e8a8..82048c474 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h @@ -34,6 +34,15 @@ JNIEXPORT jobject JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStruct( JNIEnv*, jclass, jstring); +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionDataStructV2 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStructV2( + JNIEnv*, jclass, jstring); + /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj * Method: calcTransactionDataStructHash @@ -80,6 +89,15 @@ JNIEXPORT jobject JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStruct( JNIEnv*, jclass, jstring); +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionStructV2 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStructV2( + JNIEnv*, jclass, jstring); + #ifdef __cplusplus } #endif diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/Transaction.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/Transaction.java index be12e487c..c5a8adbf7 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/Transaction.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/Transaction.java @@ -2,9 +2,9 @@ public class Transaction { private TransactionData transactionData; - private TransactionBytes dataHash; - private TransactionBytes signature; - private TransactionBytes sender; + private byte[] dataHash; + private byte[] signature; + private byte[] sender; private long importTime; private int attribute; private String extraData; @@ -17,27 +17,27 @@ public void setTransactionData(TransactionData transactionData) { this.transactionData = transactionData; } - public TransactionBytes getDataHash() { + public byte[] getDataHash() { return dataHash; } - public void setDataHash(TransactionBytes dataHash) { + public void setDataHash(byte[] dataHash) { this.dataHash = dataHash; } - public TransactionBytes getSignature() { + public byte[] getSignature() { return signature; } - public void setSignature(TransactionBytes signature) { + public void setSignature(byte[] signature) { this.signature = signature; } - public TransactionBytes getSender() { + public byte[] getSender() { return sender; } - public void setSender(TransactionBytes sender) { + public void setSender(byte[] sender) { this.sender = sender; } diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes.java deleted file mode 100644 index 09e2b1495..000000000 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBytes.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.fisco.bcos.sdk.jni.utilities.tx; - -public class TransactionBytes { - private byte[] buffer; - private int length; - - public byte[] getBuffer() { - return buffer; - } - - public void setBuffer(byte[] buffer) { - this.buffer = buffer; - } - - public int getLength() { - return length; - } - - public void setLength(int length) { - this.length = length; - } -} diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionData.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionData.java index 6baea446e..50f6af128 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionData.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionData.java @@ -1,14 +1,14 @@ package org.fisco.bcos.sdk.jni.utilities.tx; public class TransactionData { - private int version; - private long blockLimit; - private String chainId; - private String groupId; - private String nonce; - private String to; - private String abi; - private TransactionBytes input; + protected int version; + protected long blockLimit; + protected String chainId; + protected String groupId; + protected String nonce; + protected String to; + protected String abi; + protected byte[] input; public int getVersion() { return version; @@ -66,11 +66,11 @@ public void setAbi(String abi) { this.abi = abi; } - public TransactionBytes getInput() { + public byte[] getInput() { return input; } - public void setInput(TransactionBytes input) { + public void setInput(byte[] input) { this.input = input; } } diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2.java index 290a1776a..e83bb4796 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV2.java @@ -1,83 +1,11 @@ package org.fisco.bcos.sdk.jni.utilities.tx; -public class TransactionDataV2 { - private int version; - private long blockLimit; - private String chainId; - private String groupId; - private String nonce; - private String to; - private String abi; - private TransactionBytes input; - private String value; - private String gasPrice; - private long gasLimit; - private String maxFeePerGas; - private String maxPriorityFeePerGas; - - public int getVersion() { - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public long getBlockLimit() { - return blockLimit; - } - - public void setBlockLimit(long blockLimit) { - this.blockLimit = blockLimit; - } - - public String getChainId() { - return chainId; - } - - public void setChainId(String chainId) { - this.chainId = chainId; - } - - public String getGroupId() { - return groupId; - } - - public void setGroupId(String groupId) { - this.groupId = groupId; - } - - public String getNonce() { - return nonce; - } - - public void setNonce(String nonce) { - this.nonce = nonce; - } - - public String getTo() { - return to; - } - - public void setTo(String to) { - this.to = to; - } - - public String getAbi() { - return abi; - } - - public void setAbi(String abi) { - this.abi = abi; - } - - public TransactionBytes getInput() { - return input; - } - - public void setInput(TransactionBytes input) { - this.input = input; - } +public class TransactionDataV2 extends TransactionData { + protected String value; + protected String gasPrice; + protected long gasLimit; + protected String maxFeePerGas; + protected String maxPriorityFeePerGas; public String getValue() { return value; diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderJniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderJniObj.java index ec2c29e60..dfe34ac0e 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderJniObj.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderJniObj.java @@ -30,6 +30,13 @@ public static native String encodeTransactionDataStructToJson(TransactionData tr public static native TransactionData decodeTransactionDataStruct(String transactionDataHex) throws JniException; + /** + * @param transactionDataHex transactionData hex string + * @return TxData + */ + public static native TransactionDataV2 decodeTransactionDataStructV2(String transactionDataHex) + throws JniException; + /** * @param cryptoType crypto type * @param transactionData Transaction Data struct @@ -73,4 +80,11 @@ public static native String encodeTransactionStructToJson(Transaction transactio */ public static native Transaction decodeTransactionStruct(String transactionHex) throws JniException; + + /** + * @param transactionHex transaction hex string + * @return Tx + */ + public static native Transaction decodeTransactionStructV2(String transactionHex) + throws JniException; } diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderV2JniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderV2JniObj.java deleted file mode 100644 index c1945f3d4..000000000 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderV2JniObj.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.fisco.bcos.sdk.jni.utilities.tx; - -import org.fisco.bcos.sdk.jni.common.JniException; -import org.fisco.bcos.sdk.jni.common.JniLibLoader; - -public class TransactionStructBuilderV2JniObj { - - static { - JniLibLoader.loadJniLibrary(); - } - - /** - * @param TransactionDataV2 Transaction Data struct - * @return Hexed Transaction Data - */ - public static native String encodeTransactionDataStructV2(TransactionDataV2 transactionData) - throws JniException; - - /** - * @param TransactionDataV2 Transaction Data struct - * @return Json Transaction Data - */ - public static native String encodeTransactionDataStructToJsonV2(TransactionDataV2 transactionData) - throws JniException; - - /** - * @param transactionDataHex transactionData hex string - * @return TxData - */ - public static native TransactionDataV2 decodeTransactionDataStructV2(String transactionDataHex) - throws JniException; - - /** - * @param cryptoType crypto type - * @param transactionData Transaction Data struct - * @return Hash hex string - */ - public static native String calcTransactionDataStructHashV2( - int cryptoType, TransactionDataV2 transactionData) throws JniException; - - /** - * @param transactionData - * @param signature - * @param transactionDataHash - * @param attribute - * @param extraData - * @return signedTransaction string - */ - public static native String createEncodedTransactionV2( - TransactionDataV2 transactionData, - String signature, - String transactionDataHash, - int attribute, - String extraData) - throws JniException; - - /** - * @param transaction Transaction struct - * @return Hexed Transaction - */ - public static native String encodeTransactionStructV2(TransactionV2 transaction) - throws JniException; - - /** - * @param transaction Transaction struct - * @return Json Transaction - */ - public static native String encodeTransactionStructToJsonV2(TransactionV2 transaction) - throws JniException; - - /** - * @param transactionHex transaction hex string - * @return Tx - */ - public static native TransactionV2 decodeTransactionStructV2(String transactionHex) - throws JniException; -} diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionV2.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionV2.java deleted file mode 100644 index ca37b2009..000000000 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionV2.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.fisco.bcos.sdk.jni.utilities.tx; - -public class TransactionV2 { - private TransactionDataV2 transactionData; - private TransactionBytes dataHash; - private TransactionBytes signature; - private TransactionBytes sender; - private long importTime; - private int attribute; - private String extraData; - - public TransactionDataV2 getTransactionData() { - return transactionData; - } - - public void setTransactionData(TransactionDataV2 transactionData) { - this.transactionData = transactionData; - } - - public TransactionBytes getDataHash() { - return dataHash; - } - - public void setDataHash(TransactionBytes dataHash) { - this.dataHash = dataHash; - } - - public TransactionBytes getSignature() { - return signature; - } - - public void setSignature(TransactionBytes signature) { - this.signature = signature; - } - - public TransactionBytes getSender() { - return sender; - } - - public void setSender(TransactionBytes sender) { - this.sender = sender; - } - - public long getImportTime() { - return importTime; - } - - public void setImportTime(long importTime) { - this.importTime = importTime; - } - - public int getAttribute() { - return attribute; - } - - public void setAttribute(int attribute) { - this.attribute = attribute; - } - - public String getExtraData() { - return extraData; - } - - public void setExtraData(String extraData) { - this.extraData = extraData; - } -} diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion.java index df0543acf..79d1d0a0b 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion.java @@ -1,16 +1,27 @@ package org.fisco.bcos.sdk.jni.utilities.tx; public enum TransactionVersion { - V0(0), - V1(1); + V0(0), + V1(1); - private int value; + private int value; - TransactionVersion(int value) { - this.value = value; - } + TransactionVersion(int value) { + this.value = value; + } - public int getValue() { - return value; - } + public int getValue() { + return value; + } + + public static TransactionVersion fromInt(int value) { + switch (value) { + case 0: + return V0; + case 1: + return V1; + default: + return V0; + } + } } diff --git a/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStruct.java b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStruct.java index 81c8f77d0..e4fbf7120 100644 --- a/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStruct.java +++ b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStruct.java @@ -2,6 +2,9 @@ import java.security.SecureRandom; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + import org.fisco.bcos.sdk.jni.BcosSDKJniObj; import org.fisco.bcos.sdk.jni.common.JniConfig; import org.fisco.bcos.sdk.jni.common.JniException; @@ -15,28 +18,28 @@ public class TestTxStruct { - // ------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------ - - // HelloWorld Source Code: - - // HelloWorld Source Code: - /** - * pragma solidity>=0.4.24 <0.6.11; - * - *

contract HelloWorld { string name; - * - *

constructor() public { name = "Hello, World!"; } - * - *

function get() public view returns (string memory) { return name; } - * - *

function set(string memory n) public { name = n; } } - */ - private static final String hwBIN = - "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c146100f6575b600080fd5b6100f46004803603602081101561005157600080fd5b810190808035906020019064010000000081111561006e57600080fd5b82018360208201111561008057600080fd5b803590602001918460018302840111640100000000831117156100a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610179565b005b6100fe610193565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f16801561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061018f929190610235565b5050565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561022b5780601f106102005761010080835404028352916020019161022b565b820191906000526020600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; - - private static final String hwSmBIN = - "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe052d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; + // ------------------------------------------------------------------------------ + // ------------------------------------------------------------------------------ + + // HelloWorld Source Code: + + // HelloWorld Source Code: + /** + * pragma solidity>=0.4.24 <0.6.11; + * + *

contract HelloWorld { string name; + * + *

constructor() public { name = "Hello, World!"; } + * + *

function get() public view returns (string memory) { return name; } + * + *

function set(string memory n) public { name = n; } } + */ + private static final String hwBIN = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c146100f6575b600080fd5b6100f46004803603602081101561005157600080fd5b810190808035906020019064010000000081111561006e57600080fd5b82018360208201111561008057600080fd5b803590602001918460018302840111640100000000831117156100a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610179565b005b6100fe610193565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f16801561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061018f929190610235565b5050565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561022b5780601f106102005761010080835404028352916020019161022b565b820191906000526020600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; + + private static final String hwSmBIN = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe052d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; /* { @@ -50,200 +53,188 @@ public class TestTxStruct { } */ - public static byte[] fromHex(String hexString) { - if (hexString.startsWith("0x")) { - hexString = hexString.substring(2); - } + public static byte[] fromHex(String hexString) { + if (hexString.startsWith("0x")) { + hexString = hexString.substring(2); + } - if (hexString.length() % 2 != 0) { - throw new IllegalArgumentException("Invalid hex string: " + hexString); - } + if (hexString.length() % 2 != 0) { + throw new IllegalArgumentException("Invalid hex string: " + hexString); + } - int length = hexString.length() / 2; - byte[] bytes = new byte[length]; + int length = hexString.length() / 2; + byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { - String twoChars = hexString.substring(i * 2, i * 2 + 2); - bytes[i] = (byte) Integer.parseInt(twoChars, 16); - } + for (int i = 0; i < length; i++) { + String twoChars = hexString.substring(i * 2, i * 2 + 2); + bytes[i] = (byte) Integer.parseInt(twoChars, 16); + } - return bytes; - } - - public static String generateNonce() { - byte[] nonceBytes = new byte[16]; - SecureRandom secureRandom = new SecureRandom(); - secureRandom.nextBytes(nonceBytes); - StringBuilder hex = new StringBuilder(); - for (byte b : nonceBytes) { - hex.append(String.format("%02x", b)); + return bytes; } - return hex.toString(); - } - public static String getBinary(boolean isSM) { - return isSM ? hwSmBIN : hwBIN; - } + public static String generateNonce() { + byte[] nonceBytes = new byte[16]; + SecureRandom secureRandom = new SecureRandom(); + secureRandom.nextBytes(nonceBytes); + StringBuilder hex = new StringBuilder(); + for (byte b : nonceBytes) { + hex.append(String.format("%02x", b)); + } + return hex.toString(); + } - public static void Usage() { - System.out.println("Desc: test transaction struct [HelloWorld set]"); - System.out.println( - "Usage: java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.jni.test.tx.TestTxStruct"); - System.exit(0); - } + public static String getBinary(boolean isSM) { + return isSM ? hwSmBIN : hwBIN; + } - public static void main(String[] args) throws JniException, InterruptedException { - if (args.length > 1) { - Usage(); + public static void Usage() { + System.out.println("Desc: test transaction struct [HelloWorld set]"); + System.out.println( + "Usage: java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.jni.test.tx.TestTxStruct"); + System.exit(0); } - String endpoint = "127.0.0.1:20200"; - String group = "group0"; - String node = ""; - JniConfig jniConfig = Utility.newJniConfig(Arrays.asList(endpoint)); - jniConfig.setDisableSsl(true); - BcosSDKJniObj bcosSDKJni = BcosSDKJniObj.build(jniConfig); - RpcJniObj rpcJniObj = RpcJniObj.build(bcosSDKJni.getNativePointer()); - System.out.println("build Rpc"); - rpcJniObj.start(); - - boolean smCrypto = false; - - long keyPair = KeyPairJniObj.createJniKeyPair(smCrypto ? 1 : 0); - String jniKeyPairAddress = KeyPairJniObj.getJniKeyPairAddress(keyPair); - - long blockLimit = 1111; - String groupID = "group0"; - String chainID = "chain0"; - String data = getBinary(smCrypto); - System.out.printf(" [test Tx Struct] new account, address: %s\n", jniKeyPairAddress); - - // construct TransactionData - TransactionData transactionDataStruct = new TransactionData(); - transactionDataStruct.setGroupId(groupID); - transactionDataStruct.setChainId(chainID); - transactionDataStruct.setTo(""); - transactionDataStruct.setAbi(""); - transactionDataStruct.setVersion(0); - transactionDataStruct.setNonce(generateNonce()); - transactionDataStruct.setBlockLimit(blockLimit); - // input - TransactionBytes inputBytes = new TransactionBytes(); - byte[] bytesInput = fromHex(data); - inputBytes.setBuffer(bytesInput); - inputBytes.setLength(bytesInput.length); - transactionDataStruct.setInput(inputBytes); - - // encode TxData to hex tx data - String txDataHex = - TransactionStructBuilderJniObj.encodeTransactionDataStruct(transactionDataStruct); - // decode hex tx data to TxData - TransactionData decodeTransactionDataStructHex = - TransactionStructBuilderJniObj.decodeTransactionDataStruct(txDataHex); - // assert - Assert.assertEquals( - transactionDataStruct.getChainId(), decodeTransactionDataStructHex.getChainId()); - Assert.assertEquals( - transactionDataStruct.getGroupId(), decodeTransactionDataStructHex.getGroupId()); - Assert.assertEquals(transactionDataStruct.getAbi(), decodeTransactionDataStructHex.getAbi()); - Assert.assertEquals( - transactionDataStruct.getBlockLimit(), decodeTransactionDataStructHex.getBlockLimit()); - - // encode TxData to json tx data - String txDataJson = - TransactionStructBuilderJniObj.encodeTransactionDataStructToJson(transactionDataStruct); - System.out.printf(" [test Tx Struct] txDataJson: %s\n", txDataJson); - - // calc tx data hash - String txDataHash = - TransactionStructBuilderJniObj.calcTransactionDataStructHash( - smCrypto ? 1 : 0, decodeTransactionDataStructHex); - System.out.printf(" [test Tx Struct] txDataHash: %s\n", txDataHash); - // signature tx data hash - String signature = TransactionBuilderJniObj.signTransactionDataHash(keyPair, txDataHash); - System.out.printf(" [test Tx Struct] signature: %s\n", signature); - - // construct tx - Transaction transactionStruct = new Transaction(); - TransactionBytes dataHashBytes = new TransactionBytes(); - dataHashBytes.setBuffer(txDataHash.getBytes()); - dataHashBytes.setLength(txDataHash.getBytes().length); - TransactionBytes signatureBytes = new TransactionBytes(); - signatureBytes.setBuffer(signature.getBytes()); - signatureBytes.setLength(signature.getBytes().length); - transactionStruct.setTransactionData(decodeTransactionDataStructHex); - transactionStruct.setDataHash(dataHashBytes); - transactionStruct.setSignature(signatureBytes); - transactionStruct.setSender(null); - transactionStruct.setImportTime(0); - transactionStruct.setAttribute(0); - transactionStruct.setExtraData(""); - // assert - Assert.assertEquals( - transactionStruct.getTransactionData().getBlockLimit(), - decodeTransactionDataStructHex.getBlockLimit()); - Assert.assertEquals( - transactionStruct.getTransactionData().getGroupId(), - decodeTransactionDataStructHex.getGroupId()); - Assert.assertEquals( - transactionStruct.getTransactionData().getChainId(), - decodeTransactionDataStructHex.getChainId()); - Assert.assertEquals( - transactionStruct.getTransactionData().getAbi(), decodeTransactionDataStructHex.getAbi()); - Assert.assertArrayEquals(transactionStruct.getDataHash().getBuffer(), txDataHash.getBytes()); - Assert.assertArrayEquals(transactionStruct.getSignature().getBuffer(), signature.getBytes()); - - // encode Tx to hex tx - String txHex = TransactionStructBuilderJniObj.encodeTransactionStruct(transactionStruct); - // decode hex tx to Tx - Transaction decodeTransactionStructHex = - TransactionStructBuilderJniObj.decodeTransactionStruct(txHex); - // assert - Assert.assertEquals( - transactionStruct.getTransactionData().getBlockLimit(), - decodeTransactionStructHex.getTransactionData().getBlockLimit()); - Assert.assertEquals( - transactionStruct.getTransactionData().getGroupId(), - decodeTransactionStructHex.getTransactionData().getGroupId()); - Assert.assertEquals( - transactionStruct.getTransactionData().getChainId(), - decodeTransactionStructHex.getTransactionData().getChainId()); - Assert.assertEquals( - transactionStruct.getTransactionData().getAbi(), - decodeTransactionStructHex.getTransactionData().getAbi()); - Assert.assertArrayEquals( - transactionStruct.getDataHash().getBuffer(), - decodeTransactionStructHex.getDataHash().getBuffer()); - Assert.assertArrayEquals( - transactionStruct.getSignature().getBuffer(), - decodeTransactionStructHex.getSignature().getBuffer()); - - // encode Tx to json tx - String txJson = TransactionStructBuilderJniObj.encodeTransactionStructToJson(transactionStruct); - System.out.printf(" [test Tx Struct] txJson: %s\n", txJson); - // create tx string - String txString = - TransactionStructBuilderJniObj.createEncodedTransaction( - decodeTransactionDataStructHex, signature, txDataHash, 0, ""); - // System.out.printf(" [test Tx Struct] txString: %s\n", txString); - - // rpc send tx - rpcJniObj.sendTransaction( - group, - node, - txString, - false, - new RpcCallback() { - @Override - public void onResponse(Response response) { - System.out.println("response error code: ==>>> " + response.getErrorCode()); - String dataStr = new String(response.getData()); - System.out.println("response data: ==>>> " + dataStr); - } - }); - - Thread.sleep(2000); - rpcJniObj.stop(); - System.out.printf(" [test Tx Struct] finish !! \n"); - } + public static void main(String[] args) throws JniException, InterruptedException, ExecutionException { + if (args.length > 1) { + Usage(); + } + + String endpoint = "127.0.0.1:20200"; + String group = "group0"; + String node = ""; + JniConfig jniConfig = Utility.newJniConfig(Arrays.asList(endpoint)); + jniConfig.setDisableSsl(true); + BcosSDKJniObj bcosSDKJni = BcosSDKJniObj.build(jniConfig); + RpcJniObj rpcJniObj = RpcJniObj.build(bcosSDKJni.getNativePointer()); + System.out.println("build Rpc"); + rpcJniObj.start(); + + boolean smCrypto = false; + + long keyPair = KeyPairJniObj.createJniKeyPair(smCrypto ? 1 : 0); + String jniKeyPairAddress = KeyPairJniObj.getJniKeyPairAddress(keyPair); + + long blockLimit = 1111; + String groupID = "group0"; + String chainID = "chain0"; + String data = getBinary(smCrypto); + System.out.printf(" [test Tx Struct] new account, address: %s\n", jniKeyPairAddress); + + // construct TransactionData + TransactionData transactionDataStruct = new TransactionData(); + transactionDataStruct.setGroupId(groupID); + transactionDataStruct.setChainId(chainID); + transactionDataStruct.setTo(""); + transactionDataStruct.setAbi(""); + transactionDataStruct.setVersion(0); + transactionDataStruct.setNonce(generateNonce()); + transactionDataStruct.setBlockLimit(blockLimit); + // input + byte[] bytesInput = fromHex(data); + transactionDataStruct.setInput(bytesInput); + + // encode TxData to hex tx data + String txDataHex = + TransactionStructBuilderJniObj.encodeTransactionDataStruct(transactionDataStruct); + // decode hex tx data to TxData + TransactionData decodeTransactionDataStructHex = + TransactionStructBuilderJniObj.decodeTransactionDataStruct(txDataHex); + // assert + Assert.assertEquals( + transactionDataStruct.getChainId(), decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionDataStruct.getGroupId(), decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals(transactionDataStruct.getAbi(), decodeTransactionDataStructHex.getAbi()); + Assert.assertEquals( + transactionDataStruct.getBlockLimit(), decodeTransactionDataStructHex.getBlockLimit()); + + // encode TxData to json tx data + String txDataJson = + TransactionStructBuilderJniObj.encodeTransactionDataStructToJson(transactionDataStruct); + System.out.printf(" [test Tx Struct] txDataJson: %s\n", txDataJson); + + // calc tx data hash + String txDataHash = + TransactionStructBuilderJniObj.calcTransactionDataStructHash( + smCrypto ? 1 : 0, decodeTransactionDataStructHex); + System.out.printf(" [test Tx Struct] txDataHash: %s\n", txDataHash); + // signature tx data hash + String signature = TransactionBuilderJniObj.signTransactionDataHash(keyPair, txDataHash); + System.out.printf(" [test Tx Struct] signature: %s\n", signature); + + // construct tx + Transaction transactionStruct = new Transaction(); + transactionStruct.setTransactionData(decodeTransactionDataStructHex); + transactionStruct.setDataHash(fromHex(txDataHash)); + transactionStruct.setSignature(fromHex(signature)); + transactionStruct.setSender(null); + transactionStruct.setImportTime(0); + transactionStruct.setAttribute(0); + transactionStruct.setExtraData(""); + // assert + Assert.assertEquals( + transactionStruct.getTransactionData().getBlockLimit(), + decodeTransactionDataStructHex.getBlockLimit()); + Assert.assertEquals( + transactionStruct.getTransactionData().getGroupId(), + decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals( + transactionStruct.getTransactionData().getChainId(), + decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionStruct.getTransactionData().getAbi(), decodeTransactionDataStructHex.getAbi()); + Assert.assertArrayEquals(transactionStruct.getDataHash(), fromHex(txDataHash)); + Assert.assertArrayEquals(transactionStruct.getSignature(), fromHex(signature)); + + // encode Tx to hex tx + String txHex = TransactionStructBuilderJniObj.encodeTransactionStruct(transactionStruct); + // decode hex tx to Tx + Transaction decodeTransactionStructHex = + TransactionStructBuilderJniObj.decodeTransactionStruct(txHex); + // assert + Assert.assertEquals( + transactionStruct.getTransactionData().getBlockLimit(), + decodeTransactionStructHex.getTransactionData().getBlockLimit()); + Assert.assertEquals( + transactionStruct.getTransactionData().getGroupId(), + decodeTransactionStructHex.getTransactionData().getGroupId()); + Assert.assertEquals( + transactionStruct.getTransactionData().getChainId(), + decodeTransactionStructHex.getTransactionData().getChainId()); + Assert.assertEquals( + transactionStruct.getTransactionData().getAbi(), + decodeTransactionStructHex.getTransactionData().getAbi()); + Assert.assertArrayEquals( + transactionStruct.getDataHash(), + decodeTransactionStructHex.getDataHash()); + Assert.assertArrayEquals( + transactionStruct.getSignature(), + decodeTransactionStructHex.getSignature()); + + // encode Tx to json tx + String txJson = TransactionStructBuilderJniObj.encodeTransactionStructToJson(transactionStruct); + System.out.printf(" [test Tx Struct] txJson: %s\n", txJson); + // create tx string + String txString = + TransactionStructBuilderJniObj.createEncodedTransaction( + decodeTransactionDataStructHex, signature, txDataHash, 0, ""); + // System.out.printf(" [test Tx Struct] txString: %s\n", txString); + + CompletableFuture future = new CompletableFuture<>(); + // rpc send tx + rpcJniObj.sendTransaction( + group, + node, + txString, + false, + future::complete); + + Response response = future.get(); + System.out.println("response error code: ==>>> " + response.getErrorCode()); + String dataStr = new String(response.getData()); + System.out.println("response data: ==>>> " + dataStr); + rpcJniObj.stop(); + System.out.println(" [test Tx Struct] finish !!"); + } } diff --git a/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV2.java b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV2.java index 4f304dede..16db16885 100644 --- a/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV2.java +++ b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV2.java @@ -2,6 +2,9 @@ import java.security.SecureRandom; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + import org.fisco.bcos.sdk.jni.BcosSDKJniObj; import org.fisco.bcos.sdk.jni.common.JniConfig; import org.fisco.bcos.sdk.jni.common.JniException; @@ -15,26 +18,26 @@ public class TestTxStructV2 { - // ------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------ - - // HelloWorld Source Code: - /** - * pragma solidity>=0.4.24 <0.6.11; - * - *

contract HelloWorld { string name; - * - *

constructor() public { name = "Hello, World!"; } - * - *

function get() public view returns (string memory) { return name; } - * - *

function set(string memory n) public { name = n; } } - */ - private static final String hwBIN = - "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c146100f6575b600080fd5b6100f46004803603602081101561005157600080fd5b810190808035906020019064010000000081111561006e57600080fd5b82018360208201111561008057600080fd5b803590602001918460018302840111640100000000831117156100a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610179565b005b6100fe610193565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f16801561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061018f929190610235565b5050565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561022b5780601f106102005761010080835404028352916020019161022b565b820191906000526020600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; - - private static final String hwSmBIN = - "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe052d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; + // ------------------------------------------------------------------------------ + // ------------------------------------------------------------------------------ + + // HelloWorld Source Code: + /** + * pragma solidity>=0.4.24 <0.6.11; + * + *

contract HelloWorld { string name; + * + *

constructor() public { name = "Hello, World!"; } + * + *

function get() public view returns (string memory) { return name; } + * + *

function set(string memory n) public { name = n; } } + */ + private static final String hwBIN = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c146100f6575b600080fd5b6100f46004803603602081101561005157600080fd5b810190808035906020019064010000000081111561006e57600080fd5b82018360208201111561008057600080fd5b803590602001918460018302840111640100000000831117156100a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610179565b005b6100fe610193565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f16801561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061018f929190610235565b5050565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561022b5780601f106102005761010080835404028352916020019161022b565b820191906000526020600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; + + private static final String hwSmBIN = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027657805160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe052d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; /* { @@ -48,257 +51,243 @@ public class TestTxStructV2 { } */ - public static byte[] fromHex(String hexString) { - if (hexString.startsWith("0x")) { - hexString = hexString.substring(2); + public static byte[] fromHex(String hexString) { + if (hexString.startsWith("0x")) { + hexString = hexString.substring(2); + } + + if (hexString.length() % 2 != 0) { + throw new IllegalArgumentException("Invalid hex string: " + hexString); + } + + int length = hexString.length() / 2; + byte[] bytes = new byte[length]; + + for (int i = 0; i < length; i++) { + String twoChars = hexString.substring(i * 2, i * 2 + 2); + bytes[i] = (byte) Integer.parseInt(twoChars, 16); + } + + return bytes; } - if (hexString.length() % 2 != 0) { - throw new IllegalArgumentException("Invalid hex string: " + hexString); + public static String generateNonce() { + byte[] nonceBytes = new byte[16]; + SecureRandom secureRandom = new SecureRandom(); + secureRandom.nextBytes(nonceBytes); + StringBuilder hex = new StringBuilder(); + for (byte b : nonceBytes) { + hex.append(String.format("%02x", b)); + } + return hex.toString(); } - int length = hexString.length() / 2; - byte[] bytes = new byte[length]; + public static String getBinary(boolean isSM) { + return isSM ? hwSmBIN : hwBIN; + } - for (int i = 0; i < length; i++) { - String twoChars = hexString.substring(i * 2, i * 2 + 2); - bytes[i] = (byte) Integer.parseInt(twoChars, 16); + public static void Usage() { + System.out.println("Desc: test transaction struct V2 [HelloWorld set]"); + System.out.println( + "Usage: java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.jni.test.tx.TestTxStructV2"); + System.exit(0); } - return bytes; - } + public static void main(String[] args) throws JniException, InterruptedException, ExecutionException { + if (args.length > 1) { + Usage(); + } - public static String generateNonce() { - byte[] nonceBytes = new byte[16]; - SecureRandom secureRandom = new SecureRandom(); - secureRandom.nextBytes(nonceBytes); - StringBuilder hex = new StringBuilder(); - for (byte b : nonceBytes) { - hex.append(String.format("%02x", b)); - } - return hex.toString(); - } + String endpoint = "127.0.0.1:20200"; + String group = "group0"; + String node = ""; + JniConfig jniConfig = Utility.newJniConfig(Arrays.asList(endpoint)); + jniConfig.setDisableSsl(true); + BcosSDKJniObj bcosSDKJni = BcosSDKJniObj.build(jniConfig); + RpcJniObj rpcJniObj = RpcJniObj.build(bcosSDKJni.getNativePointer()); + System.out.println("build Rpc"); + rpcJniObj.start(); + long blockLimit = rpcJniObj.getBlockLimit(group); - public static String getBinary(boolean isSM) { - return isSM ? hwSmBIN : hwBIN; - } + boolean smCrypto = false; - public static void Usage() { - System.out.println("Desc: test transaction struct V2 [HelloWorld set]"); - System.out.println( - "Usage: java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.jni.test.tx.TestTxStructV2"); - System.exit(0); - } + long keyPair = KeyPairJniObj.createJniKeyPair(smCrypto ? 1 : 0); + String jniKeyPairAddress = KeyPairJniObj.getJniKeyPairAddress(keyPair); + System.out.printf(" [test Tx Struct V2] new account, address: %s\n", jniKeyPairAddress); - public static void main(String[] args) throws JniException, InterruptedException { - try { - if (args.length > 1) { - Usage(); - } - - String endpoint = "127.0.0.1:20200"; - String group = "group0"; - String node = ""; - JniConfig jniConfig = Utility.newJniConfig(Arrays.asList(endpoint)); - jniConfig.setDisableSsl(true); - BcosSDKJniObj bcosSDKJni = BcosSDKJniObj.build(jniConfig); - RpcJniObj rpcJniObj = RpcJniObj.build(bcosSDKJni.getNativePointer()); - System.out.println("build Rpc"); - rpcJniObj.start(); - - boolean smCrypto = false; - - long keyPair = KeyPairJniObj.createJniKeyPair(smCrypto ? 1 : 0); - String jniKeyPairAddress = KeyPairJniObj.getJniKeyPairAddress(keyPair); - System.out.printf(" [test Tx Struct V2] new account, address: %s\n", jniKeyPairAddress); - - String groupID = "group0"; - String chainID = "chain0"; - String data = getBinary(smCrypto); - long blockLimit = 1; - String value = "11"; - String gasPrice = "0"; - long gasLimit = 0; - String maxFeePerGas = "11"; - String maxPriorityFeePerGas = "22"; - - // construct TransactionDataV2 - TransactionDataV2 transactionDataStructV2 = new TransactionDataV2(); - transactionDataStructV2.setGroupId(groupID); - transactionDataStructV2.setChainId(chainID); - transactionDataStructV2.setTo(""); - transactionDataStructV2.setAbi(""); - transactionDataStructV2.setVersion(1); - transactionDataStructV2.setNonce(generateNonce()); - transactionDataStructV2.setBlockLimit(blockLimit); - transactionDataStructV2.setValue(value); - transactionDataStructV2.setGasPrice(gasPrice); - transactionDataStructV2.setGasLimit(gasLimit); - transactionDataStructV2.setMaxFeePerGas(maxFeePerGas); - transactionDataStructV2.setMaxPriorityFeePerGas(maxPriorityFeePerGas); - // input - TransactionBytes inputBytes = new TransactionBytes(); - byte[] bytesInput = fromHex(data); - inputBytes.setBuffer(bytesInput); - inputBytes.setLength(bytesInput.length); - transactionDataStructV2.setInput(inputBytes); - - // encode TxData to hex tx data - String txDataHex = - TransactionStructBuilderV2JniObj.encodeTransactionDataStructV2(transactionDataStructV2); - // decode hex tx data to TxData - TransactionDataV2 decodeTransactionDataStructHex = - TransactionStructBuilderV2JniObj.decodeTransactionDataStructV2(txDataHex); - // TransactionDataV2 decodeTransactionDataStructHex2 = - // TransactionStructBuilderV2JniObj.decodeTransactionDataStructV2(null); - // TransactionDataV2 decodeTransactionDataStructHex3 = - // TransactionStructBuilderV2JniObj.decodeTransactionDataStructV2(""); - - // assert - Assert.assertEquals( - transactionDataStructV2.getChainId(), decodeTransactionDataStructHex.getChainId()); - Assert.assertEquals( - transactionDataStructV2.getGroupId(), decodeTransactionDataStructHex.getGroupId()); - Assert.assertEquals( - transactionDataStructV2.getAbi(), decodeTransactionDataStructHex.getAbi()); - Assert.assertEquals( - transactionDataStructV2.getBlockLimit(), decodeTransactionDataStructHex.getBlockLimit()); - Assert.assertEquals( - transactionDataStructV2.getValue(), decodeTransactionDataStructHex.getValue()); - Assert.assertEquals( - transactionDataStructV2.getGasPrice(), decodeTransactionDataStructHex.getGasPrice()); - Assert.assertEquals( - transactionDataStructV2.getGasLimit(), decodeTransactionDataStructHex.getGasLimit()); - Assert.assertEquals( - transactionDataStructV2.getMaxFeePerGas(), - decodeTransactionDataStructHex.getMaxFeePerGas()); - Assert.assertEquals( - transactionDataStructV2.getMaxPriorityFeePerGas(), - decodeTransactionDataStructHex.getMaxPriorityFeePerGas()); - - // encode TxData to json tx data - String txDataJson = - TransactionStructBuilderV2JniObj.encodeTransactionDataStructToJsonV2( - transactionDataStructV2); - System.out.printf(" [test Tx Struct V2] txDataJson: %s\n", txDataJson); - - // calc tx data hash - String txDataHash = - TransactionStructBuilderV2JniObj.calcTransactionDataStructHashV2( - smCrypto ? 1 : 0, decodeTransactionDataStructHex); - System.out.printf(" [test Tx Struct V2] txDataHash: %s\n", txDataHash); - // signature tx data hash - String signature = TransactionBuilderJniObj.signTransactionDataHash(keyPair, txDataHash); - System.out.printf(" [test Tx Struct V2] signature: %s\n", signature); - - // construct tx - TransactionV2 transactionStructV2 = new TransactionV2(); - TransactionBytes dataHashBytes = new TransactionBytes(); - dataHashBytes.setBuffer(txDataHash.getBytes()); - dataHashBytes.setLength(txDataHash.getBytes().length); - TransactionBytes signatureBytes = new TransactionBytes(); - signatureBytes.setBuffer(signature.getBytes()); - signatureBytes.setLength(signature.getBytes().length); - transactionStructV2.setTransactionData(decodeTransactionDataStructHex); - transactionStructV2.setDataHash(dataHashBytes); - transactionStructV2.setSignature(signatureBytes); - transactionStructV2.setSender(null); - transactionStructV2.setImportTime(0); - transactionStructV2.setAttribute(0); - transactionStructV2.setExtraData(""); - // assert - Assert.assertEquals( - transactionStructV2.getTransactionData().getBlockLimit(), - decodeTransactionDataStructHex.getBlockLimit()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getGroupId(), - decodeTransactionDataStructHex.getGroupId()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getChainId(), - decodeTransactionDataStructHex.getChainId()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getChainId(), - decodeTransactionDataStructHex.getChainId()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getAbi(), - decodeTransactionDataStructHex.getAbi()); - Assert.assertArrayEquals( - transactionStructV2.getDataHash().getBuffer(), txDataHash.getBytes()); - Assert.assertArrayEquals( - transactionStructV2.getSignature().getBuffer(), signature.getBytes()); - - // encode Tx to hex tx - String txHex = - TransactionStructBuilderV2JniObj.encodeTransactionStructV2(transactionStructV2); - // decode hex tx to Tx - TransactionV2 decodeTransactionStructHex = - TransactionStructBuilderV2JniObj.decodeTransactionStructV2(txHex); - - // assert - Assert.assertEquals( - transactionStructV2.getTransactionData().getBlockLimit(), - decodeTransactionStructHex.getTransactionData().getBlockLimit()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getGroupId(), - decodeTransactionStructHex.getTransactionData().getGroupId()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getChainId(), - decodeTransactionStructHex.getTransactionData().getChainId()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getAbi(), - decodeTransactionStructHex.getTransactionData().getAbi()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getValue(), - decodeTransactionStructHex.getTransactionData().getValue()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getGasLimit(), - decodeTransactionStructHex.getTransactionData().getGasLimit()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getGasPrice(), - decodeTransactionStructHex.getTransactionData().getGasPrice()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getMaxFeePerGas(), - decodeTransactionStructHex.getTransactionData().getMaxFeePerGas()); - Assert.assertEquals( - transactionStructV2.getTransactionData().getMaxPriorityFeePerGas(), - decodeTransactionStructHex.getTransactionData().getMaxPriorityFeePerGas()); - Assert.assertArrayEquals( - transactionStructV2.getDataHash().getBuffer(), - decodeTransactionStructHex.getDataHash().getBuffer()); - Assert.assertArrayEquals( - transactionStructV2.getSignature().getBuffer(), - decodeTransactionStructHex.getSignature().getBuffer()); - - // encode Tx to json tx - String txJson = - TransactionStructBuilderV2JniObj.encodeTransactionStructToJsonV2(transactionStructV2); - System.out.printf(" [test Tx Struct V2] txJson: %s\n", txJson); - // create tx string - String txString = - TransactionStructBuilderV2JniObj.createEncodedTransactionV2( - decodeTransactionDataStructHex, signature, txDataHash, 0, ""); - // System.out.printf(" [test Tx Struct V2] txString: %s\n", txString); - - // rpc send tx - rpcJniObj.sendTransaction( - group, - node, - txString, - false, - new RpcCallback() { - @Override - public void onResponse(Response response) { - System.out.println("response error code: ==>>> " + response.getErrorCode()); - String dataStr = new String(response.getData()); - System.out.println("response data: ==>>> " + dataStr); - } - }); - - Thread.sleep(2000); - rpcJniObj.stop(); - System.out.printf(" [test Tx Struct V2] finish !! \n"); - } catch (JniException e) { - System.out.println("test tx struct V2 failed, error: " + e.getMessage()); + String groupID = "group0"; + String chainID = "chain0"; + String data = getBinary(smCrypto); + String value = "0x11"; + String gasPrice = "0x10"; + long gasLimit = 0; + String maxFeePerGas = "0x11"; + String maxPriorityFeePerGas = "0x22"; + + // construct TransactionDataV2 + TransactionDataV2 transactionDataStructV2 = new TransactionDataV2(); + transactionDataStructV2.setGroupId(groupID); + transactionDataStructV2.setChainId(chainID); + transactionDataStructV2.setTo(""); + transactionDataStructV2.setAbi(""); + transactionDataStructV2.setVersion(1); + transactionDataStructV2.setNonce(generateNonce()); + transactionDataStructV2.setBlockLimit(blockLimit); + transactionDataStructV2.setValue(value); + transactionDataStructV2.setGasPrice(gasPrice); + transactionDataStructV2.setGasLimit(gasLimit); + transactionDataStructV2.setMaxFeePerGas(maxFeePerGas); + transactionDataStructV2.setMaxPriorityFeePerGas(maxPriorityFeePerGas); + // input + byte[] bytesInput = fromHex(data); + transactionDataStructV2.setInput(bytesInput); + + // encode TxData to hex tx data + String txDataHex = + TransactionStructBuilderJniObj.encodeTransactionDataStruct(transactionDataStructV2); + // decode hex tx data to TxData + TransactionDataV2 decodeTransactionDataStructHex = + TransactionStructBuilderJniObj.decodeTransactionDataStructV2(txDataHex); + // TransactionDataV2 decodeTransactionDataStructHex2 = + // TransactionStructBuilderV2JniObj.decodeTransactionDataStructV2(null); + // TransactionDataV2 decodeTransactionDataStructHex3 = + // TransactionStructBuilderV2JniObj.decodeTransactionDataStructV2(""); + + // assert + Assert.assertEquals( + transactionDataStructV2.getChainId(), decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionDataStructV2.getGroupId(), decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals( + transactionDataStructV2.getAbi(), decodeTransactionDataStructHex.getAbi()); + Assert.assertEquals( + transactionDataStructV2.getBlockLimit(), decodeTransactionDataStructHex.getBlockLimit()); + Assert.assertEquals( + transactionDataStructV2.getValue(), decodeTransactionDataStructHex.getValue()); + Assert.assertEquals( + transactionDataStructV2.getGasPrice(), decodeTransactionDataStructHex.getGasPrice()); + Assert.assertEquals( + transactionDataStructV2.getGasLimit(), decodeTransactionDataStructHex.getGasLimit()); + Assert.assertEquals( + transactionDataStructV2.getMaxFeePerGas(), + decodeTransactionDataStructHex.getMaxFeePerGas()); + Assert.assertEquals( + transactionDataStructV2.getMaxPriorityFeePerGas(), + decodeTransactionDataStructHex.getMaxPriorityFeePerGas()); + + // encode TxData to json tx data + String txDataJson = + TransactionStructBuilderJniObj.encodeTransactionDataStructToJson( + transactionDataStructV2); + System.out.printf(" [test Tx Struct V2] txDataJson: %s\n", txDataJson); + + // calc tx data hash + String txDataHash = + TransactionStructBuilderJniObj.calcTransactionDataStructHash( + smCrypto ? 1 : 0, decodeTransactionDataStructHex); + System.out.printf(" [test Tx Struct V2] txDataHash: %s\n", txDataHash); + // signature tx data hash + String signature = TransactionBuilderJniObj.signTransactionDataHash(keyPair, txDataHash); + System.out.printf(" [test Tx Struct V2] signature: %s\n", signature); + + // construct tx + Transaction transactionStructV2 = new Transaction(); + transactionStructV2.setTransactionData(decodeTransactionDataStructHex); + transactionStructV2.setDataHash(fromHex(txDataHash)); + transactionStructV2.setSignature(fromHex(signature)); + transactionStructV2.setSender(null); + transactionStructV2.setImportTime(0); + transactionStructV2.setAttribute(0); + transactionStructV2.setExtraData(""); + // assert + Assert.assertEquals( + transactionStructV2.getTransactionData().getBlockLimit(), + decodeTransactionDataStructHex.getBlockLimit()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getGroupId(), + decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getChainId(), + decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getChainId(), + decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getAbi(), + decodeTransactionDataStructHex.getAbi()); + Assert.assertArrayEquals( + transactionStructV2.getDataHash(), fromHex(txDataHash)); + Assert.assertArrayEquals( + transactionStructV2.getSignature(), fromHex(signature)); + + // encode Tx to hex tx + String txHex = + TransactionStructBuilderJniObj.encodeTransactionStruct(transactionStructV2); + // decode hex tx to Tx + Transaction decodeTransactionStructHex = + TransactionStructBuilderJniObj.decodeTransactionStructV2(txHex); + + // assert + Assert.assertEquals( + transactionStructV2.getTransactionData().getBlockLimit(), + decodeTransactionStructHex.getTransactionData().getBlockLimit()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getGroupId(), + decodeTransactionStructHex.getTransactionData().getGroupId()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getChainId(), + decodeTransactionStructHex.getTransactionData().getChainId()); + Assert.assertEquals( + transactionStructV2.getTransactionData().getAbi(), + decodeTransactionStructHex.getTransactionData().getAbi()); + TransactionDataV2 transactionData = (TransactionDataV2) transactionStructV2.getTransactionData(); + TransactionDataV2 decodeTransactionData = (TransactionDataV2) decodeTransactionStructHex.getTransactionData(); + Assert.assertEquals( + transactionData.getValue(), + decodeTransactionData.getValue()); + Assert.assertEquals( + transactionData.getGasLimit(), + decodeTransactionData.getGasLimit()); + Assert.assertEquals( + transactionData.getGasPrice(), + decodeTransactionData.getGasPrice()); + Assert.assertEquals( + transactionData.getMaxFeePerGas(), + decodeTransactionData.getMaxFeePerGas()); + Assert.assertEquals( + transactionData.getMaxPriorityFeePerGas(), + decodeTransactionData.getMaxPriorityFeePerGas()); + Assert.assertArrayEquals( + transactionStructV2.getDataHash(), + decodeTransactionStructHex.getDataHash()); + Assert.assertArrayEquals( + transactionStructV2.getSignature(), + decodeTransactionStructHex.getSignature()); + + // encode Tx to json tx + String txJson = + TransactionStructBuilderJniObj.encodeTransactionStructToJson(transactionStructV2); + System.out.printf(" [test Tx Struct V2] txJson: %s\n", txJson); + // create tx string + String txString = + TransactionStructBuilderJniObj.createEncodedTransaction( + decodeTransactionDataStructHex, signature, txDataHash, 0, ""); + // System.out.printf(" [test Tx Struct V2] txString: %s\n", txString); + CompletableFuture future = new CompletableFuture<>(); + + // rpc send tx + rpcJniObj.sendTransaction( + group, + node, + txString, + false, + future::complete); + + Response response = future.get(); + System.out.println("response error code: ==>>> " + response.getErrorCode()); + String dataStr = new String(response.getData()); + System.out.println("response data: ==>>> " + dataStr); + rpcJniObj.stop(); + System.out.println(" [test Tx Struct V2] finish !! "); } - } }