diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5a96c2b55..cdfc877cb 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -11,7 +11,7 @@ on: - "Changelog.md" - "README.md" release: - types: [published, created, edited] + types: [ published, created, edited ] env: CCACHE_DIR: ${{ github.workspace }}/ccache @@ -21,45 +21,43 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-latest] + os: [ macos-latest ] steps: - uses: actions/checkout@v2 with: fetch-depth: 5 - name: Nightly default run: rustup default nightly - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache with: path: | - /home/runner/.hunter - /github/home/.hunter - /Users/runner/.hunter - /home/runner/.hunter/_Base/Download/ - /github/home/.hunter/_Base/Download/ - /Users/runner/.hunter/_Base/Download/ + /usr/local/share/vcpkg ccache - key: hunter-clang-v3-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + key: vcpkg-clang-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} restore-keys: | - hunter-clang-v3-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - hunter-clang-v3-notest-${{ runner.temp }}-${{ github.base_ref }}- - hunter-clang-v3-notest-${{ runner.temp }}- + vcpkg-clang-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + vcpkg-clang-v1-notest-${{ runner.temp }}-${{ github.base_ref }}- + vcpkg-clang-v1-notest-${{ runner.temp }}- - name: install macOS dependencies if: runner.os == 'macOS' - run: brew install ccache - - name: install Ubuntu dependencies - if: runner.os == 'Linux' - run: sudo apt install -y git curl openssl build-essential clang cmake ccache + run: brew install ccache lcov - name: configure if: runner.os == 'macOS' - run: export SDKROOT=$(xcrun --sdk macosx --show-sdk-path) && CC=/usr/bin/clang CXX=/usr/bin/clang++ mkdir build && cd build && cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON - - name: configure - if: runner.os == 'Linux' - run: CC=/usr/bin/clang CXX=/usr/bin/clang++ mkdir build && cd build && cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON + run: | + export SDKROOT=$(xcrun --sdk macosx --show-sdk-path) && CC=/usr/bin/clang CXX=/usr/bin/clang++ + mkdir build && cd build + cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON -DCOVERAGE=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake - name: compile run: export CFLAGS="${CFLAGS} -fPIC";export CXXFLAGS="${CXXFLAGS} -fPIC"; cd build && make -j4 - name: run test - run: CTEST_OUTPUT_ON_FAILURE=TRUE make test + run: cd build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - name: print link.txt + run: cat build/CMakeFiles/bcos-c-sdk*.dir/link.txt + - name: strip libbcos-c-sdk.dylib + run: strip build/libbcos-c-sdk.dylib || strip -x build/libbcos-c-sdk.dylib + - name: strip libbcos-sdk-jni.dylib + run: strip bindings/java/jni/src/main/resources/META-INF/native/libbcos-sdk-jni.dylib || strip -x bindings/java/jni/src/main/resources/META-INF/native/libbcos-sdk-jni.dylib - uses: actions/upload-artifact@v2 with: name: libbcos-c-sdk.dylib.zip @@ -73,54 +71,55 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ ubuntu-20.04 ] steps: - uses: actions/checkout@v2 with: fetch-depth: 5 - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache with: path: | - /home/runner/.hunter - /github/home/.hunter - /Users/runner/.hunter - /home/runner/.hunter/_Base/Download/ - /github/home/.hunter/_Base/Download/ - /Users/runner/.hunter/_Base/Download/ - deps/src + /usr/local/share/vcpkg ccache - key: hunter-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - restore-keys: | - hunter-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - hunter-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}- - hunter-gcc-v2-notest-${{ runner.temp }}- - - uses: actions/cache@v2 - id: ccache - with: - path: ccache - key: cache-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + key: vcpkg-gcc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} restore-keys: | - ccache-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - cache-gcc-v2-notest-${{ runner.temp }}-${{ github.base_ref }}- - cache-gcc-v2-notest-${{ runner.temp }}- + vcpkg-gcc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + vcpkg-gcc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}- + vcpkg-gcc-v1-notest-${{ runner.temp }}- - name: install Ubuntu dependencies - run: sudo apt install -y git curl openssl build-essential cmake ccache + run: sudo apt install -y git curl openssl build-essential cmake ccache lcov - name: configure run: | export CC='gcc-10'; export CXX='g++-10' - export CFLAGS="${CFLAGS} -fPIC";export CXXFLAGS="${CXXFLAGS} -fPIC"; mkdir -p build && cd build && cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON + export CFLAGS="${CFLAGS} -fPIC";export CXXFLAGS="${CXXFLAGS} -fPIC"; + mkdir -p build && cd build + cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON -DCOVERAGE=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake - name: compile run: cd build && make -j4 - name: run test - run: CTEST_OUTPUT_ON_FAILURE=TRUE make test + run: cd build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - name: print link.txt + run: cat build/CMakeFiles/bcos-c-sdk*.dir/link.txt + - name: run coverage + run: cd build && make cov + - name: upload coverage report + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./build/coverage.info + version: "v0.1.15" + flags: unittests + name: c sdk coverage + fail_ci_if_error: false + verbose: true build_with_centos: name: build_with_centos runs-on: ubuntu-latest container: image: docker.io/centos:7 volumes: - - /github/home/.hunter:/github/home/.hunter + - /usr/local/share/vcpkg:/usr/local/share/vcpkg steps: - uses: actions/checkout@v2 with: @@ -130,28 +129,29 @@ jobs: with: toolchain: nightly-2021-06-17 override: true - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache with: path: | - /home/runner/.hunter - /github/home/.hunter - /Users/runner/.hunter - /home/runner/.hunter/_Base/Download/ - /github/home/.hunter/_Base/Download/ - /Users/runner/.hunter/_Base/Download/ - ccache - deps/src + /usr/local/share/vcpkg ccache - key: hunter-centos-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + key: vcpkg-centos-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} restore-keys: | - hunter-centos-v2-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - hunter-centos-v2-notest-${{ runner.temp }}-${{ github.base_ref }}- - hunter-centos-v2-notest-${{ runner.temp }}- + vcpkg-centos-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + vcpkg-centos-v1-notest-${{ runner.temp }}-${{ github.base_ref }}- + vcpkg-centos-v1-notest-${{ runner.temp }}- - name: install CentOS dependencies run: | yum install -y epel-release centos-release-scl - yum install -y java-11-openjdk-devel git make gcc gcc-c++ glibc-static glibc-devel openssl cmake3 ccache devtoolset-11 llvm-toolset-7.0 rh-perl530-perl libzstd-devel zlib-devel flex bison python-devel python3-devel + yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm + yum install -y java-11-openjdk-devel wget git make gcc gcc-c++ glibc-static glibc-devel openssl openssl-devel ccache devtoolset-11 llvm-toolset-7.0 rh-perl530-perl libzstd-devel zlib-devel flex bison python-devel python3-devel + - name: reinstall cmake + run: | + wget -c https://github.com/Kitware/CMake/releases/download/v3.27.8/cmake-3.27.8-linux-x86_64.tar.gz + tar -zxvf cmake-3.27.8-linux-x86_64.tar.gz && mkdir -p /usr/local/cmake && cd cmake-3.27.8-linux-x86_64 && cp -r * /usr/local/cmake + ln -s /usr/local/cmake/bin/cmake /usr/bin/cmake + cmake --version + git --version - name: configure run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" @@ -159,13 +159,20 @@ jobs: . /opt/rh/rh-perl530/enable export LIBCLANG_PATH=/opt/rh/llvm-toolset-7.0/root/lib64/ . /opt/rh/llvm-toolset-7.0/enable - alias cmake='cmake3' java -version export CFLAGS="${CFLAGS} -fPIC" export CXXFLAGS="${CXXFLAGS} -fPIC" mkdir -p build && cd build - cmake3 ../ -DHUNTER_STATUS_DEBUG=ON -DBUILD_JNI=ON -DBUILD_SAMPLE=ON + cmake ../ -DBUILD_JNI=ON -DBUILD_SAMPLE=ON -DTESTS=ON -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake make -j4 + - name: run test + run: cd build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + - name: print link.txt + run: cat build/CMakeFiles/bcos-c-sdk*.dir/link.txt + - name: strip libbcos-c-sdk.so + run: strip build/libbcos-c-sdk.so || strip -x build/libbcos-c-sdk.so + - name: strip libbcos-sdk-jni.so + run: strip bindings/java/jni/src/main/resources/META-INF/native/libbcos-sdk-jni.so || strip -x bindings/java/jni/src/main/resources/META-INF/native/libbcos-sdk-jni.so - uses: actions/upload-artifact@v2 with: name: libbcos-c-sdk.so.zip @@ -175,53 +182,48 @@ jobs: name: libbcos-sdk-jni.so.zip path: bindings/java/jni/src/main/resources/META-INF/native/libbcos-sdk-jni.so build_with_windows: - name: build_with_windows - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-2019] - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 5 - - uses: actions/cache@v2 - id: cache - with: - path: | - /home/runner/.hunter - /github/home/.hunter - /Users/runner/.hunter - /home/runner/.hunter/_Base/Download/ - /github/home/.hunter/_Base/Download/ - /Users/runner/.hunter/_Base/Download/ - C:/.hunter/ - C:/.hunter/_Base/Download/ - ccache - key: hunter-msvc-v3-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - restore-keys: | - hunter-msvc-v3-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} - hunter-msvc-v3-notest-${{ runner.temp }}-${{ github.base_ref }}- - hunter-msvc-v3-notest-${{ runner.temp }}- - - name: Add MSbuild to PATH - uses: microsoft/setup-msbuild@v1.1 - - name: configure - if: runner.os == 'Windows' - run: mkdir -p build && cd build && cmake -G "Visual Studio 16 2019" -A x64 ../ -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_STATUS_DEBUG=ON -DTESTS=ON -DBUILD_JNI=ON - - name: compile - run: cd build && MSBuild bcos-c-sdk.sln /p:Configuration=Release /p:Platform=x64 - - uses: actions/upload-artifact@v2 - with: - name: bcos-c-sdk.lib.zip - path: D:\a\bcos-c-sdk\bcos-c-sdk\build\Release\bcos-c-sdk.lib - - uses: actions/upload-artifact@v2 - with: - name: bcos-c-sdk.dll.zip - path: D:\a\bcos-c-sdk\bcos-c-sdk\build\Release\bcos-c-sdk.dll - - uses: actions/upload-artifact@v2 - with: - name: bcos-sdk-jni.lib.zip - path: D:\a\bcos-c-sdk\bcos-c-sdk\bindings\java\jni\src\main\resources\META-INF\native\Release\bcos-sdk-jni.lib - - uses: actions/upload-artifact@v2 - with: - name: bcos-sdk-jni.dll.zip - path: D:\a\bcos-c-sdk\bcos-c-sdk\bindings\java\jni\src\main\resources\META-INF\native\Release\bcos-sdk-jni.dll + name: build_with_windows + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ windows-2019 ] + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + - uses: actions/cache@v3 + id: cache + with: + path: | + C:\vcpkg + ccache + key: vcpkg-msvc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + restore-keys: | + vcpkg-msvc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + vcpkg-msvc-v1-notest-${{ runner.temp }}-${{ github.base_ref }}- + vcpkg-msvc-v1-notest-${{ runner.temp }}- + - name: Add MSbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + - name: configure + if: runner.os == 'Windows' + run: | + mkdir -p build && cd build + cmake -G "Visual Studio 16 2019" -A x64 ../ -DCMAKE_BUILD_TYPE=Release -DBOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN7 -D_WIN32_WINNT=0x0601 -DTESTS=ON -DBUILD_JNI=ON -DVCPKG_TARGET_TRIPLET='x64-windows-static' -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake || cat C:\vcpkg\buildtrees\fisco-bcos-cpp-sdk\build-x64-windows-static-dbg-out.log + - name: compile + run: cd build && MSBuild bcos-c-sdk.sln /p:Configuration=Release /p:Platform=x64 + - uses: actions/upload-artifact@v2 + with: + name: bcos-c-sdk.lib.zip + path: D:\a\bcos-c-sdk\bcos-c-sdk\build\Release\bcos-c-sdk.lib + - uses: actions/upload-artifact@v2 + with: + name: bcos-c-sdk.dll.zip + path: D:\a\bcos-c-sdk\bcos-c-sdk\build\Release\bcos-c-sdk.dll + - uses: actions/upload-artifact@v2 + with: + name: bcos-sdk-jni.lib.zip + path: D:\a\bcos-c-sdk\bcos-c-sdk\bindings\java\jni\src\main\resources\META-INF\native\Release\bcos-sdk-jni.lib + - uses: actions/upload-artifact@v2 + with: + name: bcos-sdk-jni.dll.zip + path: D:\a\bcos-c-sdk\bcos-c-sdk\bindings\java\jni\src\main\resources\META-INF\native\Release\bcos-sdk-jni.dll diff --git a/.gitignore b/.gitignore index b13126567..edad50017 100644 --- a/.gitignore +++ b/.gitignore @@ -36,9 +36,12 @@ deps *.out *.app .cache -build +build** deps .gradle .vscode/ .idea/ .DS_Store +vcpkg_installed** + +conf** diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..fe07c999a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg diff --git a/CMakeLists.txt b/CMakeLists.txt index 72f22d45f..1f5015ba5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,67 +20,51 @@ cmake_minimum_required(VERSION 3.14) set(CMAKE_CXX_STANDARD 20) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "-pthread -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fexceptions") -endif() - -set(CMAKE_OSX_DEPLOYMENT_TARGET "12" CACHE STRING "Minimum OS X deployment version") - -# export windows dll symbol -if(WIN32) - message(STATUS "Compile on Windows") - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") -endif() +#set(CMAKE_OSX_DEPLOYMENT_TARGET "13" CACHE STRING "Minimum OS X deployment version") # URL_BASE download domain name -include(FetchContent) - -if(NOT DEFINED URL_BASE) +if (NOT DEFINED URL_BASE) set(URL_BASE "github.com") +endif () + +if (WIN32) + set(VCPKG_C_FLAGS -D_WIN32_WINNT=0x0601 -DWINVER=0x0601) + set(VCPKG_CXX_FLAGS -D_WIN32_WINNT=0x0601 -DWINVER=0x0601) + add_definitions(-D_WIN32_WINNT=0x0601) + add_definitions(-DBOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN7) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +else () + add_definitions(-DBOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX) +endif () - # set(URL_BASE "github.com.cnpmjs.org") -endif() - -# include(FetchContent) -# set(BCOS_CMAKE_SCRIPTS_DIR ${CMAKE_CURRENT_BINARY_DIR}/bcos-cmake-scripts) -# FetchContent_Declare(bcos-cmake-scripts -# GIT_REPOSITORY https://${URL_BASE}/FISCO-BCOS/bcos-cmake-scripts.git -# GIT_TAG 364f603f4ec112cb79840ea4026243399d7c419b -# SOURCE_DIR ${BCOS_CMAKE_SCRIPTS_DIR} -# ) -# FetchContent_MakeAvailable(bcos-cmake-scripts) set(JAVA_SDK_JNI_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake" CACHE PATH "The cmake path for the library") # list(APPEND CMAKE_MODULE_PATH ${BCOS_CMAKE_SCRIPTS_DIR}) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH ${JAVA_SDK_JNI_CMAKE_DIR}) -# include hunter include(Options) set(ARCH_NATIVE OFF) -if("${ARCHITECTURE}" MATCHES "aarch64") +if ("${ARCHITECTURE}" MATCHES "aarch64") set(ARCH_NATIVE ON) -endif() +endif () -include(HunterGate) -HunterGate( - URL "https://${URL_BASE}/FISCO-BCOS/hunter/archive/2b5b25ecffaba74393740bf0b8758c4e8d9297cf.tar.gz" - SHA1 "5d8365a327be260cf24d2b125a71ee7069aca28f" - FILEPATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake" -) +set(VCPKG_BUILD_TYPE "Release") +if (NOT DEFINED CMAKE_TOOLCHAIN_FILE) + find_package(Git REQUIRED) + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- vcpkg WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +endif () # project name -project(bcos-c-sdk VERSION "3.4.0") +project(bcos-c-sdk VERSION "3.6.0") # Debug, Release, RelWithDebInfo, MinSizeRel -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -endif() - -include_directories(${CMAKE_INSTALL_INCLUDEDIR}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include(InstallDependencies) +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE MinSizeRel) +endif () # basic settings include(Options) @@ -91,15 +75,29 @@ include(InstallConfig) # install the include files for hash include(InstallInclude) +include(IncludeDirectories) +include(GNUInstallDirs) + +find_package(Boost COMPONENTS log_setup log serialization chrono system filesystem thread iostreams unit_test_framework) +find_package(OpenSSL REQUIRED) +find_package(Microsoft.GSL CONFIG REQUIRED) +find_package(fmt REQUIRED) +find_package(TBB REQUIRED) +find_package(unofficial-secp256k1 CONFIG REQUIRED) +find_package(jsoncpp CONFIG REQUIRED) +find_package(wedprcrypto REQUIRED) +find_package(HSM-CRYPTO REQUIRED) +find_package(ZLIB REQUIRED) +find_package(fiscobcos REQUIRED) file(GLOB_RECURSE SOURCES "bcos-c-sdk/*.h" "bcos-c-sdk/*.cpp" "bcos-c-sdk/*.c") # rust static library linking requirements for macos -if(APPLE) +if (APPLE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -framework Security -framework Foundation") -else() +else () set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-as-needed -ldl") -endif() +endif () # static lib set(BCOS_C_SDK_STATIC_TARGET "bcos-c-sdk-static") @@ -108,56 +106,64 @@ set(BCOS_C_SDK_STATIC_TARGET "bcos-c-sdk-static") set(BCOS_C_SDK_TARGET "bcos-c-sdk") # add suffix for arm -if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") +if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") message(STATUS "Building arm architecture, CMAKE_HOST_SYSTEM_PROCESSOR => ${CMAKE_HOST_SYSTEM_PROCESSOR}") set(BCOS_C_SDK_TARGET "bcos-c-sdk-aarch64") set(BCOS_C_SDK_STATIC_TARGET "bcos-c-sdk-static-aarch64") -endif() +endif () add_library(${BCOS_C_SDK_STATIC_TARGET} ${SOURCES}) -target_link_libraries(${BCOS_C_SDK_STATIC_TARGET} PUBLIC bcos-cpp-sdk::bcos-cpp-sdk) +target_include_directories(${BCOS_C_SDK_STATIC_TARGET} PUBLIC $ $) +target_link_libraries(${BCOS_C_SDK_STATIC_TARGET} PUBLIC fiscobcos::bcos-cpp-sdk) add_library(${BCOS_C_SDK_TARGET} SHARED ${SOURCES}) -target_link_libraries(${BCOS_C_SDK_TARGET} PUBLIC bcos-cpp-sdk::bcos-cpp-sdk) +target_include_directories(${BCOS_C_SDK_TARGET} PUBLIC $ $) +target_link_libraries(${BCOS_C_SDK_TARGET} PUBLIC fiscobcos::bcos-cpp-sdk) add_dependencies(${BCOS_C_SDK_STATIC_TARGET} BuildInfo.h) add_dependencies(${BCOS_C_SDK_TARGET} BuildInfo.h) # build sample exec -if(BUILD_SAMPLE) +if (BUILD_SAMPLE) add_subdirectory(sample) -endif() +endif () # build sample exec -if(BUILD_JNI) +if (BUILD_JNI) # find JNI find_package(JNI REQUIRED) include_directories(${JNI_INCLUDE_DIRS}) - add_subdirectory(bindings/java/jni/src/main/c) -endif() + add_subdirectory(${CMAKE_SOURCE_DIR}/bindings/java/jni/src/main/c) +endif () # ut and binary exe -# if (TESTS) -# enable_testing() -# set(CTEST_OUTPUT_ON_FAILURE TRUE) -# add_subdirectory(test) -# endif() +if (TESTS) + enable_testing() + set(CTEST_OUTPUT_ON_FAILURE TRUE) + add_subdirectory(test) +endif () + +# for code coverage +if (COVERAGE) + include(Coverage) + config_coverage("cov" "'/usr*' '${CMAKE_CURRENT_SOURCE_DIR}/bcos-cmake-scripts*' '${CMAKE_CURRENT_SOURCE_DIR}/test/Main*'") +endif () # SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib) install( - TARGETS ${BCOS_C_SDK_TARGET} - EXPORT "${TARGETS_EXPORT_NAME}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + TARGETS ${BCOS_C_SDK_TARGET} + EXPORT "${TARGETS_EXPORT_NAME}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) install( - TARGETS ${BCOS_C_SDK_STATIC_TARGET} - EXPORT "${TARGETS_EXPORT_NAME}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + TARGETS ${BCOS_C_SDK_STATIC_TARGET} + EXPORT "${TARGETS_EXPORT_NAME}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) diff --git a/bcos-c-sdk/bcos_sdk_c.cpp b/bcos-c-sdk/bcos_sdk_c.cpp index cdd91f57d..b9f8584a8 100644 --- a/bcos-c-sdk/bcos_sdk_c.cpp +++ b/bcos-c-sdk/bcos_sdk_c.cpp @@ -208,6 +208,7 @@ void bcos_sdk_start(void* sdk) try { + BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_start") << LOG_KV("sdk", sdk); ((bcos::cppsdk::Sdk*)sdk)->start(); } catch (const std::exception& e) @@ -217,8 +218,6 @@ void bcos_sdk_start(void* sdk) << LOG_KV("errorMsg", errorMsg); bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); } - - BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_start") << LOG_KV("sdk", sdk); } /** @@ -231,10 +230,9 @@ void bcos_sdk_stop(void* sdk) bcos_sdk_clear_last_error(); if (sdk) { + BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_stop") << LOG_KV("sdk", sdk); ((bcos::cppsdk::Sdk*)sdk)->stop(); } - - BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_stop") << LOG_KV("sdk", sdk); } /** @@ -247,11 +245,10 @@ void bcos_sdk_destroy(void* sdk) bcos_sdk_clear_last_error(); if (sdk) { + BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_destroy") << LOG_KV("sdk", sdk); ((bcos::cppsdk::Sdk*)sdk)->stop(); delete (bcos::cppsdk::Sdk*)sdk; } - - BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_destroy") << LOG_KV("sdk", sdk); } /** @@ -267,14 +264,13 @@ void bcos_sdk_register_block_notifier(void* sdk, const char* group, void* contex BCOS_SDK_C_PARAMS_VERIFICATION(group, ); BCOS_SDK_C_PARAMS_VERIFICATION(callback, ); + BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_register_block_notifier") << LOG_KV("sdk", sdk) + << LOG_KV("group", group); auto service = ((bcos::cppsdk::Sdk*)sdk)->service(); service->registerBlockNumberNotifier( group, [context, callback](const std::string& _group, int64_t _blockNumber) { callback(_group.c_str(), _blockNumber, context); }); - - BCOS_LOG(INFO) << LOG_BADGE("bcos_sdk_register_block_notifier") << LOG_KV("sdk", sdk) - << LOG_KV("group", group); } /** @@ -318,4 +314,20 @@ const char* bcos_sdk_get_group_chain_id(void* sdk, const char* group) auto chainID = groupInfo->chainID(); return strdup(chainID.c_str()); +} + +uint32_t bcos_sdk_get_local_protocol_info(void* sdk) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(sdk, 0); + + return ((bcos::cppsdk::Sdk*)sdk)->localProtocolInfo(); +} + +uint32_t bcos_sdk_get_negotiated_protocol_info(void* sdk) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(sdk, 0); + + return ((bcos::cppsdk::Sdk*)sdk)->negotiatedProtocolInfo(); } \ No newline at end of file diff --git a/bcos-c-sdk/bcos_sdk_c.h b/bcos-c-sdk/bcos_sdk_c.h index 87b8abf3a..335cf2f90 100644 --- a/bcos-c-sdk/bcos_sdk_c.h +++ b/bcos-c-sdk/bcos_sdk_c.h @@ -37,7 +37,7 @@ extern "C" { * * @return const char* */ -const char* bcos_sdk_version(); +const char* bcos_sdk_version(void); /** * @brief: create bcos sdk object by config object @@ -115,6 +115,10 @@ void bcos_sdk_get_group_wasm_and_crypto(void* sdk, const char* group, int* wasm, * @return const char* : chain id */ const char* bcos_sdk_get_group_chain_id(void* sdk, const char* group); + +uint32_t bcos_sdk_get_local_protocol_info(void* sdk); + +uint32_t bcos_sdk_get_negotiated_protocol_info(void* sdk); // -------------------------------------------------------------------- #ifdef __cplusplus diff --git a/bcos-c-sdk/bcos_sdk_c_common.cpp b/bcos-c-sdk/bcos_sdk_c_common.cpp index fd7821923..e9683ea1c 100644 --- a/bcos-c-sdk/bcos_sdk_c_common.cpp +++ b/bcos-c-sdk/bcos_sdk_c_common.cpp @@ -59,6 +59,10 @@ struct bcos_sdk_c_config* bcos_sdk_c_config_create_empty() char* my_strdup(const char* s) { + if (s == NULL) + { + return NULL; + } size_t len = strlen(s) + 1; char* result = (char*)malloc(len); if (result == (char*)0) @@ -228,6 +232,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_common.h b/bcos-c-sdk/bcos_sdk_c_common.h index 00a2aafc6..cd9beefd0 100644 --- a/bcos-c-sdk/bcos_sdk_c_common.h +++ b/bcos-c-sdk/bcos_sdk_c_common.h @@ -97,18 +97,17 @@ struct bcos_sdk_c_config struct bcos_sdk_c_sm_cert_config* sm_cert_config; }; -struct bcos_sdk_c_signature_result -{ - uint8_t r[32]; - uint8_t s[32]; - uint8_t v[512]; -}; - /** * @brief create bcos_sdk_c_config in default value * @return struct bcos_sdk_c_config* */ -struct bcos_sdk_c_config* bcos_sdk_c_config_create_empty(); +struct bcos_sdk_c_config* bcos_sdk_c_config_create_empty(void); + +/** + * @brief duplicate string + * @return char* + */ +char* my_strdup(const char* s); /** * @brief create bcos_sdk_c_config @@ -174,6 +173,87 @@ void bcos_sdk_c_free(void* p); //--------------- callback end------------ + +//--------------- transaction begin--------------------------------- + +/** + * @brief: signature result + * + */ +struct bcos_sdk_c_signature_result +{ + uint8_t r[32]; + uint8_t s[32]; + uint8_t v[512]; +}; + +struct bcos_sdk_c_bytes +{ + uint8_t* buffer; + uint32_t length; +}; + +/** + * @brief: transaction data + * + */ +struct bcos_sdk_c_transaction_data +{ + int32_t version; + int64_t block_limit; + char* chain_id; + char* group_id; + char* nonce; + char* to; + char* abi; + struct bcos_sdk_c_bytes* input; +}; + +struct bcos_sdk_c_transaction_data_v1 +{ + int32_t version; + int64_t block_limit; + char* chain_id; + char* group_id; + char* nonce; + char* to; + char* abi; + struct bcos_sdk_c_bytes* input; + char* value; + char* gas_price; + int64_t gas_limit; + char* max_fee_per_gas; + char* max_priority_fee_per_gas; +}; + +/** + * @brief: transaction + * + */ +struct bcos_sdk_c_transaction +{ + struct bcos_sdk_c_transaction_data* transaction_data; + struct bcos_sdk_c_bytes* data_hash; + struct bcos_sdk_c_bytes* signature; + struct bcos_sdk_c_bytes* sender; + int64_t import_time; + int32_t attribute; + char* extra_data; +}; + +struct bcos_sdk_c_transaction_v1 +{ + struct bcos_sdk_c_transaction_data_v1* transaction_data; + struct bcos_sdk_c_bytes* data_hash; + struct bcos_sdk_c_bytes* signature; + struct bcos_sdk_c_bytes* sender; + int64_t import_time; + int32_t attribute; + char* extra_data; +}; + +//--------------- transaction end--------------------------------- + #ifdef __cplusplus } #endif diff --git a/bcos-c-sdk/bcos_sdk_c_error.h b/bcos-c-sdk/bcos_sdk_c_error.h index eac0af3f6..a6e5edf43 100644 --- a/bcos-c-sdk/bcos_sdk_c_error.h +++ b/bcos-c-sdk/bcos_sdk_c_error.h @@ -53,7 +53,7 @@ extern "C" { * * @return int */ -extern int bcos_sdk_is_last_opr_success(); +extern int bcos_sdk_is_last_opr_success(void); /** * @brief gets status of the recent sync operation @@ -61,7 +61,7 @@ extern int bcos_sdk_is_last_opr_success(); * * @return int */ -extern int bcos_sdk_get_last_error(); +extern int bcos_sdk_get_last_error(void); /** * @brief gets error message of the recent sync operation, effect if bcos_sdk_get_last_error, @@ -70,12 +70,12 @@ extern int bcos_sdk_get_last_error(); * * @return const char* */ -extern const char* bcos_sdk_get_last_error_msg(); +extern const char* bcos_sdk_get_last_error_msg(void); /** * @brief clear the last error */ -extern void bcos_sdk_clear_last_error(); +extern void bcos_sdk_clear_last_error(void); /** * @brief set the last error and error message diff --git a/bcos-c-sdk/bcos_sdk_c_uti_receipt.cpp b/bcos-c-sdk/bcos_sdk_c_uti_receipt.cpp index b86b8fc13..61b17284e 100644 --- a/bcos-c-sdk/bcos_sdk_c_uti_receipt.cpp +++ b/bcos-c-sdk/bcos_sdk_c_uti_receipt.cpp @@ -80,8 +80,7 @@ void* bcos_sdk_create_receipt_data_with_json(const char* json) { std::string errorMsg = boost::diagnostic_information(e); BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_receipt_data") << LOG_DESC("exception") - << LOG_KV("json", json) - << LOG_KV("error", errorMsg); + << LOG_KV("json", json) << LOG_KV("error", errorMsg); bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); } @@ -167,4 +166,33 @@ const char* bcos_sdk_calc_receipt_data_hash(int crypto_type, void* _receiptData) bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); } return NULL; +} + +const char* bcos_sdk_calc_receipt_data_hash_with_json(int crypto_type, const char* json) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(json, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (crypto_type == BCOS_C_SDK_ECDSA_TYPE || crypto_type == BCOS_C_SDK_SM_TYPE), + "invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto type) or " + "BCOS_C_SDK_SM_TYPE(sm crypto type)", + NULL); + + try + { + ReceiptBuilder builder; + auto transactionDataHash = builder.calculateReceiptDataHashWithJson( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, + std::string(json)); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_hash_with_json") + << LOG_DESC("exception") << LOG_KV("crypto_type", crypto_type) + << LOG_KV("json", json) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return NULL; } \ No newline at end of file diff --git a/bcos-c-sdk/bcos_sdk_c_uti_receipt.h b/bcos-c-sdk/bcos_sdk_c_uti_receipt.h index 4b9665bda..5b6cea480 100644 --- a/bcos-c-sdk/bcos_sdk_c_uti_receipt.h +++ b/bcos-c-sdk/bcos_sdk_c_uti_receipt.h @@ -52,6 +52,8 @@ void bcos_sdk_destroy_receipt_data(void* transaction_data); const char* bcos_sdk_calc_receipt_data_hash(int crypto_type, void* _receiptData); +const char* bcos_sdk_calc_receipt_data_hash_with_json(int crypto_type, const char* json); + const char* bcos_sdk_encode_receipt_data(void* receipt_data); const char* bcos_sdk_decode_receipt_data(const char* receipt_bytes); diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx.cpp b/bcos-c-sdk/bcos_sdk_c_uti_tx.cpp index cb19e3bbd..c0b4dc87e 100644 --- a/bcos-c-sdk/bcos_sdk_c_uti_tx.cpp +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx.cpp @@ -20,6 +20,7 @@ #include "bcos_sdk_c_uti_tx.h" #include "bcos_sdk_c_error.h" +#include #include #include #include @@ -33,6 +34,7 @@ using namespace bcos; using namespace bcos::cppsdk; using namespace bcos::cppsdk::utilities; + /** * @brief * @@ -53,7 +55,7 @@ void* bcos_sdk_create_transaction_data(const char* group_id, const char* chain_i // BCOS_SDK_C_PARAMS_VERIFICATION(to, NULL); BCOS_SDK_C_PARAMS_VERIFICATION(data, NULL); // BCOS_SDK_C_PARAMS_VERIFICATION(abi, NULL); - BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must >= 0", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL); try { @@ -92,8 +94,9 @@ void* bcos_sdk_create_transaction_data_with_json(const char* json) catch (const std::exception& e) { std::string errorMsg = boost::diagnostic_information(e); - BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data") << LOG_DESC("exception") - << LOG_KV("json", json) << LOG_KV("error", errorMsg); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data_with_json") + << LOG_DESC("exception") << LOG_KV("json", json) + << LOG_KV("error", errorMsg); bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); } @@ -316,44 +319,44 @@ void bcos_sdk_create_signed_transaction_ver_extra_data(void* key_pair, const cha * @brief * * @param transaction_data - * @param signed_transaction_data + * @param signature * @param transaction_data_hash * @param attribute * @return const char* */ const char* bcos_sdk_create_signed_transaction_with_signed_data(void* transaction_data, - const char* signed_transaction_data, const char* transaction_data_hash, int32_t attribute) + const char* signature, const char* transaction_data_hash, int32_t attribute) { return bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( - transaction_data, signed_transaction_data, transaction_data_hash, attribute, NULL); + transaction_data, signature, transaction_data_hash, attribute, NULL); } /** * @brief * * @param transaction_data - * @param signed_transaction_data + * @param signature * @param transaction_data_hash * @param attribute * @param extra_data * @return const char* */ const char* bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( - void* transaction_data, const char* signed_transaction_data, const char* transaction_data_hash, + void* transaction_data, const char* signature, const char* transaction_data_hash, int32_t attribute, const char* extra_data) { bcos_sdk_clear_last_error(); BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); - BCOS_SDK_C_PARAMS_VERIFICATION(signed_transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL); BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hash, NULL); try { auto builder = std::make_shared(); - auto signedBytes = builder->createSignedTransaction( - *(bcostars::TransactionData*)transaction_data, *fromHexString(signed_transaction_data), - bcos::crypto::HashType(transaction_data_hash), attribute, - extra_data ? std::string(extra_data) : std::string()); + auto signedBytes = + builder->createSignedTransaction(*(bcostars::TransactionData*)transaction_data, + *fromHexString(signature), bcos::crypto::HashType(transaction_data_hash), attribute, + extra_data ? std::string(extra_data) : std::string()); return strdup(bcos::toHexStringWithPrefix(*signedBytes).c_str()); } catch (const std::exception& e) @@ -361,7 +364,7 @@ const char* bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( std::string errorMsg = boost::diagnostic_information(e); BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data") - << LOG_DESC("exception") << LOG_KV("signed_transaction_data", signed_transaction_data) + << LOG_DESC("exception") << LOG_KV("signature", signature) << LOG_KV("transaction_data_hash", transaction_data_hash) << LOG_KV("attribute", attribute) << LOG_KV("extra_data", extra_data) << LOG_KV("error", errorMsg); @@ -370,6 +373,71 @@ const char* bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( return NULL; } +/** + * @brief Decode transaction hex string to Transaction object raw pointer + * @param transaction_bytes encoded transaction hex string + * @return Transaction object pointer + */ +void* bcos_sdk_decode_transaction(const char* transaction_bytes) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_bytes, nullptr); + try + { + TransactionBuilder builder{}; + auto transaction = builder.decodeTransaction(*fromHexString(transaction_bytes)); + return transaction.release(); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction") << LOG_DESC("exception") + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + +/** + * @brief Decode transaction hex string to Transaction object json string + * @param transaction_bytes encoded transaction hex string + * @return Transaction object json string + */ +const char* bcos_sdk_decode_transaction_to_json_obj(const char* transaction_bytes) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_bytes, nullptr); + try + { + TransactionBuilder builder{}; + const auto transaction = + builder.decodeTransactionToJsonObj(*fromHexString(transaction_bytes)); + return strdup(transaction.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction") << LOG_DESC("exception") + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + +/** + * @brief Destroy transaction object + * + * @param transaction transaction object pointer + */ +void bcos_sdk_destroy_transaction(void* transaction) +{ + if (transaction) + { + delete (bcostars::Transaction*)transaction; + transaction = nullptr; + } +} + /** * @brief * diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx.h b/bcos-c-sdk/bcos_sdk_c_uti_tx.h index a721ae6c6..8cb3f55a8 100644 --- a/bcos-c-sdk/bcos_sdk_c_uti_tx.h +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx.h @@ -81,8 +81,8 @@ const char* bcos_sdk_decode_transaction_data(const char* transaction_bytes); /** * @brief * - * @param crypto_type - * @param transaction_data + * @param crypto_type: int + * @param transaction_data: void* * @return const char* */ const char* bcos_sdk_calc_transaction_data_hash(int crypto_type, void* transaction_data); @@ -109,6 +109,7 @@ const char* bcos_sdk_sign_transaction_data_hash(void* keypair, const char* trans * @param attribute * @param tx_hash * @param signed_tx + * @return void* */ void bcos_sdk_create_signed_transaction(void* key_pair, const char* group_id, const char* chain_id, const char* to, const char* data, const char* abi, int64_t block_limit, int32_t attribute, @@ -128,6 +129,7 @@ void bcos_sdk_create_signed_transaction(void* key_pair, const char* group_id, co * @param extra_data * @param tx_hash * @param signed_tx + * @return void */ void bcos_sdk_create_signed_transaction_ver_extra_data(void* key_pair, const char* group_id, const char* chain_id, const char* to, const char* data, const char* abi, int64_t block_limit, @@ -136,29 +138,51 @@ void bcos_sdk_create_signed_transaction_ver_extra_data(void* key_pair, const cha /** * @brief * - * @param transaction_data - * @param signed_transaction_data + * @param transaction_data: void* + * @param signature * @param transaction_data_hash * @param attribute * @return const char* */ const char* bcos_sdk_create_signed_transaction_with_signed_data(void* transaction_data, - const char* signed_transaction_data, const char* transaction_data_hash, int32_t attribute); + const char* signature, const char* transaction_data_hash, int32_t attribute); /** * @brief * - * @param transaction_data - * @param signed_transaction_data + * @param transaction_data: void* + * @param signature * @param transaction_data_hash * @param attribute * @param extra_data * @return const char* */ const char* bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( - void* transaction_data, const char* signed_transaction_data, const char* transaction_data_hash, + void* transaction_data, const char* signature, const char* transaction_data_hash, int32_t attribute, const char* extra_data); + +/** + * @brief Decode transaction hex string to Transaction object raw pointer + * @param transaction_bytes encoded transaction hex string + * @return Transaction object pointer + */ +void* bcos_sdk_decode_transaction(const char* transaction_bytes); + +/** + * @brief Decode transaction hex string to Transaction object json string + * @param transaction_bytes encoded transaction hex string + * @return Transaction object json string + */ +const char* bcos_sdk_decode_transaction_to_json_obj(const char* transaction_bytes); + +/** + * @brief Destroy transaction object + * + * @param transaction transaction object pointer + */ +void bcos_sdk_destroy_transaction(void* transaction); + /** * @brief * diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp new file mode 100644 index 000000000..fa37c723d --- /dev/null +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.cpp @@ -0,0 +1,1801 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file bcos_sdk_c_util_tx_struct.cpp + * @author: lucasli + * @date 2023-05-09 + */ + +#include "bcos_sdk_c_uti_tx_struct.h" +#include "bcos_sdk_c_error.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace bcos; +using namespace bcos::cppsdk; +using namespace bcos::cppsdk::utilities; + +struct bcos_sdk_c_bytes* create_bytes_struct(uint32_t field_size, const char* field_data) +{ + bcos_sdk_clear_last_error(); + if (field_size <= 0) + { + return NULL; + } + + try + { + struct bcos_sdk_c_bytes* field_bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + uint32_t length = field_size; + uint8_t* buffer = (uint8_t*)malloc(length); + memcpy(buffer, field_data, length); + field_bytes->buffer = buffer; + field_bytes->length = length; + + return field_bytes; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("create_bytes_struct") << LOG_DESC("exception") + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_bytes* bytes_struct_copy(const struct bcos_sdk_c_bytes* bytes_struct_src) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(bytes_struct_src, NULL); + + try + { + struct bcos_sdk_c_bytes* bytes_struct = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + + uint32_t length = bytes_struct_src->length; + uint8_t* buffer = (uint8_t*)malloc(length); + memcpy(buffer, bytes_struct_src->buffer, length); + bytes_struct->buffer = buffer; + bytes_struct->length = length; + + return bytes_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bytes_struct_copy") << LOG_DESC("exception") + << LOG_KV("bytes_struct_src", bytes_struct_src) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data* transaction_data_copy( + const bcos_sdk_c_transaction_data* tx_data_src) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tx_data_src, NULL); + + try + { + struct bcos_sdk_c_transaction_data* transaction_data_struct = + (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); + transaction_data_struct->version = tx_data_src->version; + transaction_data_struct->block_limit = tx_data_src->block_limit; + transaction_data_struct->chain_id = my_strdup(tx_data_src->chain_id); + transaction_data_struct->group_id = my_strdup(tx_data_src->group_id); + transaction_data_struct->nonce = my_strdup(tx_data_src->nonce); + transaction_data_struct->to = my_strdup(tx_data_src->to); + transaction_data_struct->abi = my_strdup(tx_data_src->abi); + transaction_data_struct->input = bytes_struct_copy(tx_data_src->input); + + return transaction_data_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("transaction_data_copy") << LOG_DESC("exception") + << LOG_KV("tx_data_src", tx_data_src) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* transaction_data_copy_v1( + const bcos_sdk_c_transaction_data_v1* tx_data_src) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tx_data_src, NULL); + + try + { + struct bcos_sdk_c_transaction_data_v1* transaction_data_struct_v1 = + (struct bcos_sdk_c_transaction_data_v1*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v1)); + transaction_data_struct_v1->version = tx_data_src->version; + transaction_data_struct_v1->block_limit = tx_data_src->block_limit; + transaction_data_struct_v1->chain_id = my_strdup(tx_data_src->chain_id); + transaction_data_struct_v1->group_id = my_strdup(tx_data_src->group_id); + transaction_data_struct_v1->nonce = my_strdup(tx_data_src->nonce); + transaction_data_struct_v1->to = my_strdup(tx_data_src->to); + transaction_data_struct_v1->abi = my_strdup(tx_data_src->abi); + transaction_data_struct_v1->input = bytes_struct_copy(tx_data_src->input); + transaction_data_struct_v1->value = my_strdup(tx_data_src->value); + transaction_data_struct_v1->gas_price = my_strdup(tx_data_src->gas_price); + transaction_data_struct_v1->gas_limit = tx_data_src->gas_limit; + transaction_data_struct_v1->max_fee_per_gas = my_strdup(tx_data_src->max_fee_per_gas); + transaction_data_struct_v1->max_priority_fee_per_gas = + my_strdup(tx_data_src->max_priority_fee_per_gas); + + return transaction_data_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("transaction_data_copy_v1") << LOG_DESC("exception") + << LOG_KV("tx_data_src", tx_data_src) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief: convert tars transaction data to struct bcos_sdk_c_transaction_data + * + * @param tars_transaction_data: response error, pointer to Error::Ptr in cpp-sdk + * @return bcos_sdk_c_transaction_data*: struct bcos_sdk_c_transaction_data pointer + */ +struct bcos_sdk_c_transaction_data* convert_tars_transaction_data_to_struct( + bcostars::TransactionDataUniquePtr tars_transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tars_transaction_data, NULL); + + try + { + struct bcos_sdk_c_transaction_data* transaction_data_struct = + (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); + struct bcos_sdk_c_bytes* input_bytes = create_bytes_struct( + tars_transaction_data->input.size(), tars_transaction_data->input.data()); + + transaction_data_struct->input = input_bytes; + transaction_data_struct->version = tars_transaction_data->version; + transaction_data_struct->block_limit = tars_transaction_data->blockLimit; + transaction_data_struct->chain_id = my_strdup(tars_transaction_data->chainID.data()); + transaction_data_struct->group_id = my_strdup(tars_transaction_data->groupID.data()); + transaction_data_struct->nonce = my_strdup(tars_transaction_data->nonce.data()); + transaction_data_struct->to = my_strdup(tars_transaction_data->to.data()); + transaction_data_struct->abi = my_strdup(tars_transaction_data->abi.data()); + + return transaction_data_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_tars_transaction_data_to_struct") + << LOG_DESC("exception") + << LOG_KV("transaction data", tars_transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* convert_tars_transaction_data_to_struct_v1( + bcostars::TransactionDataUniquePtr tars_transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tars_transaction_data, NULL); + + try + { + struct bcos_sdk_c_transaction_data_v1* transaction_data_struct_v1 = + (struct bcos_sdk_c_transaction_data_v1*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v1)); + struct bcos_sdk_c_bytes* input_bytes = create_bytes_struct( + tars_transaction_data->input.size(), tars_transaction_data->input.data()); + + transaction_data_struct_v1->input = input_bytes; + transaction_data_struct_v1->version = tars_transaction_data->version; + transaction_data_struct_v1->block_limit = tars_transaction_data->blockLimit; + transaction_data_struct_v1->chain_id = my_strdup(tars_transaction_data->chainID.data()); + transaction_data_struct_v1->group_id = my_strdup(tars_transaction_data->groupID.data()); + transaction_data_struct_v1->nonce = my_strdup(tars_transaction_data->nonce.data()); + transaction_data_struct_v1->to = my_strdup(tars_transaction_data->to.data()); + transaction_data_struct_v1->abi = my_strdup(tars_transaction_data->abi.data()); + transaction_data_struct_v1->value = my_strdup(tars_transaction_data->value.data()); + transaction_data_struct_v1->gas_price = my_strdup(tars_transaction_data->gasPrice.data()); + transaction_data_struct_v1->gas_limit = tars_transaction_data->gasLimit; + transaction_data_struct_v1->max_fee_per_gas = + my_strdup(tars_transaction_data->maxFeePerGas.data()); + transaction_data_struct_v1->max_priority_fee_per_gas = + my_strdup(tars_transaction_data->maxPriorityFeePerGas.data()); + + return transaction_data_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_tars_transaction_data_to_struct_v1") + << LOG_DESC("exception") + << LOG_KV("transaction data", tars_transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + + +bcostars::TransactionDataUniquePtr convert_transaction_data_to_tars( + struct bcos_sdk_c_transaction_data* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->input, NULL); + + try + { + auto tars_transaction_data = std::make_unique(); + for (size_t i = 0; i < transaction_data->input->length; ++i) + { + tars_transaction_data->input.push_back(transaction_data->input->buffer[i]); + } + tars_transaction_data->version = (tars::Int32)transaction_data->version; + tars_transaction_data->blockLimit = (tars::Int64)transaction_data->block_limit; + tars_transaction_data->chainID = std::string(transaction_data->chain_id); + tars_transaction_data->groupID = std::string(transaction_data->group_id); + tars_transaction_data->nonce = std::string(transaction_data->nonce); + tars_transaction_data->to = std::string(transaction_data->to); + tars_transaction_data->abi = std::string(transaction_data->abi); + + return tars_transaction_data; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_transaction_data_to_tars") << LOG_DESC("exception") + << LOG_KV("transaction data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +bcostars::TransactionDataUniquePtr convert_transaction_data_to_tars_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->input, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data->value, NULL); + + try + { + auto tars_transaction_data_v1 = std::make_unique(); + tars_transaction_data_v1->input.reserve(transaction_data->input->length); + for (size_t i = 0; i < transaction_data->input->length; ++i) + { + tars_transaction_data_v1->input.push_back( + static_cast(transaction_data->input->buffer[i])); + } + tars_transaction_data_v1->version = (tars::Int32)transaction_data->version; + tars_transaction_data_v1->blockLimit = (tars::Int64)transaction_data->block_limit; + tars_transaction_data_v1->chainID = std::string(transaction_data->chain_id); + tars_transaction_data_v1->groupID = std::string(transaction_data->group_id); + tars_transaction_data_v1->nonce = std::string(transaction_data->nonce); + tars_transaction_data_v1->to = std::string(transaction_data->to); + tars_transaction_data_v1->abi = std::string(transaction_data->abi); + tars_transaction_data_v1->value = std::string(transaction_data->value); + tars_transaction_data_v1->gasPrice = std::string(transaction_data->gas_price); + tars_transaction_data_v1->gasLimit = (tars::Int64)transaction_data->gas_limit; + tars_transaction_data_v1->maxFeePerGas = std::string(transaction_data->max_fee_per_gas); + tars_transaction_data_v1->maxPriorityFeePerGas = + std::string(transaction_data->max_priority_fee_per_gas); + + return tars_transaction_data_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_transaction_data_to_tars_v1") + << LOG_DESC("exception") << LOG_KV("transaction data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +bcostars::TransactionUniquePtr convert_transaction_to_tars( + struct bcos_sdk_c_transaction* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction->data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction->signature, NULL); + + try + { + auto tars_transaction = std::make_unique(); + auto TransactionDataUniquePtr = + convert_transaction_data_to_tars(transaction->transaction_data); + tars_transaction->data = *TransactionDataUniquePtr; + for (size_t i = 0; i < transaction->data_hash->length; ++i) + { + tars_transaction->dataHash.push_back(transaction->data_hash->buffer[i]); + } + for (size_t i = 0; i < transaction->signature->length; ++i) + { + tars_transaction->signature.push_back(transaction->signature->buffer[i]); + } + if (transaction->sender) + { + for (size_t i = 0; i < transaction->sender->length; ++i) + { + tars_transaction->sender.push_back(transaction->sender->buffer[i]); + } + } + tars_transaction->importTime = (tars::Int32)transaction->import_time; + tars_transaction->attribute = (tars::Int64)transaction->attribute; + tars_transaction->extraData = std::string(transaction->extra_data); + + return tars_transaction; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_transaction_to_tars") << LOG_DESC("exception") + << LOG_KV("transaction", transaction) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +bcostars::TransactionUniquePtr convert_transaction_to_tars_v1( + struct bcos_sdk_c_transaction_v1* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction->data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction->signature, NULL); + + try + { + auto tars_transaction = std::make_unique(); + auto TransactionDataUniquePtr = + convert_transaction_data_to_tars_v1(transaction->transaction_data); + tars_transaction->data = *TransactionDataUniquePtr; + for (size_t i = 0; i < transaction->data_hash->length; ++i) + { + tars_transaction->dataHash.push_back(transaction->data_hash->buffer[i]); + } + for (size_t i = 0; i < transaction->signature->length; ++i) + { + tars_transaction->signature.push_back(transaction->signature->buffer[i]); + } + if (transaction->sender) + { + for (size_t i = 0; i < transaction->sender->length; ++i) + { + tars_transaction->sender.push_back(transaction->sender->buffer[i]); + } + } + tars_transaction->importTime = (tars::Int32)transaction->import_time; + tars_transaction->attribute = (tars::Int64)transaction->attribute; + tars_transaction->extraData = std::string(transaction->extra_data); + + return tars_transaction; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_transaction_to_tars_v1") << LOG_DESC("exception") + << LOG_KV("transaction", transaction) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction* convert_tars_transaction_to_struct( + bcostars::TransactionUniquePtr tars_transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tars_transaction, NULL); + + try + { + struct bcos_sdk_c_transaction* transaction_struct = + (struct bcos_sdk_c_transaction*)malloc(sizeof(struct bcos_sdk_c_transaction)); + struct bcos_sdk_c_bytes* data_hash_bytes = create_bytes_struct( + tars_transaction->dataHash.size(), tars_transaction->dataHash.data()); + struct bcos_sdk_c_bytes* signature_bytes = create_bytes_struct( + tars_transaction->signature.size(), tars_transaction->signature.data()); + struct bcos_sdk_c_bytes* sender_bytes = + create_bytes_struct(tars_transaction->sender.size(), tars_transaction->sender.data()); + auto transactionDataUniquePtr = + std::make_unique(tars_transaction->data); + + transaction_struct->transaction_data = + convert_tars_transaction_data_to_struct(std::move(transactionDataUniquePtr)); + transaction_struct->data_hash = data_hash_bytes; + transaction_struct->signature = signature_bytes; + transaction_struct->sender = sender_bytes; + transaction_struct->import_time = tars_transaction->importTime; + transaction_struct->attribute = tars_transaction->attribute; + transaction_struct->extra_data = my_strdup(tars_transaction->extraData.data()); + return transaction_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_tars_transaction_to_struct") + << LOG_DESC("exception") << LOG_KV("transaction", tars_transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_v1* convert_tars_transaction_to_struct_v1( + bcostars::TransactionUniquePtr tars_transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(tars_transaction, NULL); + + try + { + struct bcos_sdk_c_transaction_v1* transaction_struct_v1 = + (struct bcos_sdk_c_transaction_v1*)malloc(sizeof(struct bcos_sdk_c_transaction_v1)); + struct bcos_sdk_c_bytes* data_hash_bytes = create_bytes_struct( + tars_transaction->dataHash.size(), tars_transaction->dataHash.data()); + struct bcos_sdk_c_bytes* signature_bytes = create_bytes_struct( + tars_transaction->signature.size(), tars_transaction->signature.data()); + struct bcos_sdk_c_bytes* sender_bytes = + create_bytes_struct(tars_transaction->sender.size(), tars_transaction->sender.data()); + auto transactionDataUniquePtr = + std::make_unique(tars_transaction->data); + + transaction_struct_v1->transaction_data = + convert_tars_transaction_data_to_struct_v1(std::move(transactionDataUniquePtr)); + transaction_struct_v1->data_hash = data_hash_bytes; + transaction_struct_v1->signature = signature_bytes; + transaction_struct_v1->sender = sender_bytes; + transaction_struct_v1->import_time = tars_transaction->importTime; + transaction_struct_v1->attribute = tars_transaction->attribute; + transaction_struct_v1->extra_data = my_strdup(tars_transaction->extraData.data()); + return transaction_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("convert_tars_transaction_to_struct_v1") + << LOG_DESC("exception") << LOG_KV("transaction", tars_transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param group_id + * @param chain_id + * @param to + * @param input + * @param abi + * @param block_limit + * @return bcos_sdk_c_transaction_data*: transaction data struct pointer, return unassigned struct + * on failure according to the function called bcos_sdk_get_last_error(if create failed, return -1) + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_create_transaction_data_struct_with_hex_input( + const char* group_id, const char* chain_id, const char* to, const char* input, const char* abi, + int64_t block_limit) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((input[0] != '\0'), "input can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL); + + try + { + struct bcos_sdk_c_transaction_data* transaction_data_struct = + (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); + auto bytesInput = fromHexString(input); + TransactionBuilder builder; + std::string nonceStr = builder.generateRandomStr(); + + transaction_data_struct->version = 0; + transaction_data_struct->block_limit = block_limit; + transaction_data_struct->group_id = my_strdup(group_id); + transaction_data_struct->chain_id = my_strdup(chain_id); + transaction_data_struct->to = to ? my_strdup(to) : my_strdup(""); + transaction_data_struct->abi = abi ? my_strdup(abi) : my_strdup(""); + transaction_data_struct->nonce = my_strdup(nonceStr.data()); + transaction_data_struct->input = + create_bytes_struct(bytesInput->size(), reinterpret_cast(bytesInput->data())); + + return transaction_data_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data_struct_with_hex_input") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) + << LOG_KV("chain_id", chain_id) << LOG_KV("to", std::string(to ? to : "")) + << LOG_KV("input", input) << LOG_KV("abi", std::string(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param group_id + * @param chain_id + * @param to + * @param bytes_input + * @param abi + * @param block_limit + * @return bcos_sdk_c_transaction_data*: transaction data struct pointer, return unassigned struct + * on failure according to the function called bcos_sdk_get_last_error(if create failed, return -1) + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_create_transaction_data_struct_with_bytes( + const char* group_id, const char* chain_id, const char* to, const unsigned char* bytes_input, + uint32_t bytes_input_length, const char* abi, int64_t block_limit) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(bytes_input, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (bytes_input_length > 0), "bytes input length must > 0", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL); + + try + { + struct bcos_sdk_c_transaction_data* transaction_data_struct = + (struct bcos_sdk_c_transaction_data*)malloc(sizeof(struct bcos_sdk_c_transaction_data)); + TransactionBuilder builder; + std::string nonceStr = builder.generateRandomStr(); + + transaction_data_struct->version = 0; + transaction_data_struct->block_limit = block_limit; + transaction_data_struct->group_id = my_strdup(group_id); + transaction_data_struct->chain_id = my_strdup(chain_id); + transaction_data_struct->to = to ? my_strdup(to) : my_strdup(""); + transaction_data_struct->abi = abi ? my_strdup(abi) : my_strdup(""); + transaction_data_struct->nonce = my_strdup(nonceStr.data()); + transaction_data_struct->input = create_bytes_struct( + bytes_input_length, const_cast(reinterpret_cast(bytes_input))); + + return transaction_data_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data_struct_with_bytes") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) + << LOG_KV("chain_id", chain_id) << LOG_KV("to", std::string(to ? to : "")) + << LOG_KV("bytes_input", bytes_input) + << LOG_KV("bytes_input_length", bytes_input_length) + << LOG_KV("abi", std::string(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + */ +void bcos_sdk_destroy_transaction_data_struct(struct bcos_sdk_c_transaction_data* transaction_data) +{ + if (transaction_data == NULL) + { + return; + } + + if (transaction_data->chain_id) + { + bcos_sdk_c_free(transaction_data->chain_id); + } + + if (transaction_data->group_id) + { + bcos_sdk_c_free(transaction_data->group_id); + } + + if (transaction_data->nonce) + { + bcos_sdk_c_free(transaction_data->nonce); + } + + if (transaction_data->to) + { + bcos_sdk_c_free(transaction_data->to); + } + + if (transaction_data->abi) + { + bcos_sdk_c_free((void*)transaction_data->abi); + } + + if (transaction_data->input) + { + if (transaction_data->input->buffer) + { + bcos_sdk_c_free(transaction_data->input->buffer); + } + bcos_sdk_c_free((void*)transaction_data->input); + } + + bcos_sdk_c_free(transaction_data); +} + +/** + * @brief encode transaction data into hex format + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_data_struct_to_hex( + struct bcos_sdk_c_transaction_data* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + + try + { + auto tars_transaction_data = convert_transaction_data_to_tars(transaction_data); + TransactionBuilder builder; + auto encodedTransactionData = builder.encodeTransactionData(*tars_transaction_data); + auto hex_tx_data_str = bcos::toHexString(*encodedTransactionData); + return strdup(hex_tx_data_str->c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_data_struct_to_hex") + << LOG_DESC("exception") << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief convert transaction data into json format + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_data_struct_to_json( + struct bcos_sdk_c_transaction_data* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + + try + { + auto tars_transaction_data = convert_transaction_data_to_tars(transaction_data); + auto json_str = tars_transaction_data->writeToJsonString(); + return strdup(json_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_data_struct_to_json") + << LOG_DESC("exception") << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @param transaction_data_hex_str + * @return struct bcos_sdk_c_transaction_data* + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_decode_transaction_data_struct_from_hex( + const char* transaction_data_hex_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hex_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((transaction_data_hex_str[0] != '\0'), + "transaction_data_hex_str can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((strlen(transaction_data_hex_str) % 2 != 1), + "the length of transaction_data_hex_str must be an even number", NULL); + + try + { + TransactionBuilder builder; + auto tx_data_bytes = fromHexString(transaction_data_hex_str); + auto tars_tx_data = builder.decodeTransactionData(*tx_data_bytes); + return convert_tars_transaction_data_to_struct(std::move(tars_tx_data)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_data_struct") + << LOG_DESC("exception") << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @param transaction_data_json_str + * version:number + * groupID:string + * chainID:string + * to:string + * data:hex string + * abi:string + * blockLimit:number + * nonce:string + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_decode_transaction_data_struct_from_json( + const char* transaction_data_json_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_json_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((transaction_data_json_str[0] != '\0'), + "transaction_data_json_str can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto transactionData = + builder.createTransactionDataWithJson(std::string(transaction_data_json_str)); + + return convert_tars_transaction_data_to_struct(std::move(transactionData)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_data_struct_from_json") + << LOG_DESC("exception") + << LOG_KV("transaction_data_json_str", transaction_data_json_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param crypto_type: int + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_calc_transaction_data_struct_hash( + int crypto_type, struct bcos_sdk_c_transaction_data* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (crypto_type == BCOS_C_SDK_ECDSA_TYPE || crypto_type == BCOS_C_SDK_SM_TYPE), + "invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto type) or " + "BCOS_C_SDK_SM_TYPE(sm crypto type)", + NULL); + + try + { + auto tars_transaction_data = convert_transaction_data_to_tars(transaction_data); + TransactionBuilder builder; + auto transactionDataHash = builder.calculateTransactionDataHash( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, + *tars_transaction_data); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_struct_hash") + << LOG_DESC("exception") << LOG_KV("crypto_type", crypto_type) + << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param crypto_type: int + * @param transaction_data_hex: const char* + * @return const char* + */ +const char* bcos_sdk_calc_transaction_data_struct_hash_with_hex( + int crypto_type, const char* transaction_data_hex) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hex, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (crypto_type == BCOS_C_SDK_ECDSA_TYPE || crypto_type == BCOS_C_SDK_SM_TYPE), + "invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto type) or " + "BCOS_C_SDK_SM_TYPE(sm crypto type)", + NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hex[0] != '\0'), "transaction_data_hex can not be empty string", NULL); + + try + { + struct bcos_sdk_c_transaction_data* transaction_data_struct = + bcos_sdk_decode_transaction_data_struct_from_hex(transaction_data_hex); + auto tars_transaction_data = convert_transaction_data_to_tars(transaction_data_struct); + TransactionBuilder builder; + auto transactionDataHash = builder.calculateTransactionDataHash( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, + *tars_transaction_data); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_struct_hash_with_hex") + << LOG_DESC("exception") << LOG_KV("crypto_type", crypto_type) + << LOG_KV("transaction_data_hex", transaction_data_hex) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @param signature + * @param transaction_data_hash + * @param attribute + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_create_transaction_struct( + struct bcos_sdk_c_transaction_data* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (signature[0] != '\0'), "signature can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hash[0] != '\0'), "transaction_data_hash can not be empty string", NULL); + + try + { + struct bcos_sdk_c_transaction* transaction_struct = + (struct bcos_sdk_c_transaction*)malloc(sizeof(struct bcos_sdk_c_transaction)); + transaction_struct->transaction_data = transaction_data_copy(transaction_data); + transaction_struct->sender = NULL; + transaction_struct->import_time = 0; + transaction_struct->attribute = attribute; + transaction_struct->extra_data = extra_data ? my_strdup(extra_data) : my_strdup(""); + // signature + auto signatureWithoutHex = fromHexString(signature); + struct bcos_sdk_c_bytes* signature_bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + signature_bytes->length = signatureWithoutHex->size(); + signature_bytes->buffer = (uint8_t*)malloc(signatureWithoutHex->size()); + memcpy(signature_bytes->buffer, signatureWithoutHex->data(), signatureWithoutHex->size()); + transaction_struct->signature = signature_bytes; + // data_hash + auto dataHashArray = bcos::crypto::HashType(transaction_data_hash); + struct bcos_sdk_c_bytes* data_hash_bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + data_hash_bytes->length = dataHashArray.size(); + data_hash_bytes->buffer = (uint8_t*)malloc(dataHashArray.size()); + memcpy(data_hash_bytes->buffer, dataHashArray.data(), dataHashArray.size()); + transaction_struct->data_hash = data_hash_bytes; + + return transaction_struct; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_struct") + << LOG_DESC("exception") << LOG_KV("signature", signature) + << LOG_KV("transaction_data_hash", transaction_data_hash) + << LOG_KV("attribute", attribute) << LOG_KV("extra_data", extra_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return NULL; +} + +/** + * @brief + * + * @param transaction: struct bcos_sdk_c_transaction* + */ +void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transaction) +{ + if (transaction == NULL) + { + return; + } + + if (transaction->transaction_data) + { + bcos_sdk_destroy_transaction_data_struct(transaction->transaction_data); + } + + if (transaction->data_hash) + { + if (transaction->data_hash->buffer) + { + bcos_sdk_c_free(transaction->data_hash->buffer); + } + bcos_sdk_c_free(transaction->data_hash); + } + + if (transaction->signature) + { + if (transaction->signature->buffer) + { + bcos_sdk_c_free(transaction->signature->buffer); + } + bcos_sdk_c_free(transaction->signature); + } + + if (transaction->sender) + { + if (transaction->sender->buffer) + { + bcos_sdk_c_free(transaction->sender->buffer); + } + bcos_sdk_c_free(transaction->sender); + } + + if (transaction->extra_data) + { + bcos_sdk_c_free(transaction->extra_data); + } + + bcos_sdk_c_free(transaction); +} + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @param signature + * @param transaction_data_hash + * @param attribute + * @return const char* + */ +const char* bcos_sdk_create_encoded_transaction( + struct bcos_sdk_c_transaction_data* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (signature[0] != '\0'), "signature can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hash[0] != '\0'), "transaction_data_hash can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto tars_tx_data = convert_transaction_data_to_tars(transaction_data); + auto signedBytes = builder.createSignedTransaction(*tars_tx_data, *fromHexString(signature), + bcos::crypto::HashType(transaction_data_hash), attribute, + extra_data ? std::string(extra_data) : std::string()); + return strdup(bcos::toHexStringWithPrefix(*signedBytes).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_encoded_transaction") + << LOG_DESC("exception") << LOG_KV("signature", signature) + << LOG_KV("transaction_data_hash", transaction_data_hash) + << LOG_KV("attribute", attribute) << LOG_KV("extra_data", extra_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return NULL; +} + + +/** + * @brief encode transaction into hex format + * + * @param transaction: struct bcos_sdk_c_transaction* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_struct_to_hex(struct bcos_sdk_c_transaction* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + + try + { + auto tars_transaction = convert_transaction_to_tars(transaction); + TransactionBuilder builder; + auto encodedTransaction = builder.encodeTransaction(*tars_transaction); + auto hex_tx_str = toHexStringWithPrefix(*encodedTransaction); + return strdup(hex_tx_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_struct_to_hex") + << LOG_DESC("exception") << LOG_KV("transaction", transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief convert transaction into json format + * + * @param transaction: struct bcos_sdk_c_transaction* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_struct_to_json(struct bcos_sdk_c_transaction* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + + try + { + auto tars_transaction = convert_transaction_to_tars(transaction); + auto json_str = tars_transaction->writeToJsonString(); + return strdup(json_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_struct_to_hex") + << LOG_DESC("exception") << LOG_KV("transaction", transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param transaction_hex_str + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_decode_transaction_struct_from_hex( + const char* transaction_hex_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_hex_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_hex_str[0] != '\0'), "transaction_hex_str can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((strlen(transaction_hex_str) % 2 != 1), + "the length of transaction_hex_str must be an even number", NULL); + + try + { + TransactionBuilder builder; + auto tx_bytes = fromHexString(transaction_hex_str); + auto tars_tx = builder.decodeTransaction(*tx_bytes); + return convert_tars_transaction_to_struct(std::move(tars_tx)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_struct") + << LOG_DESC("exception") + << LOG_KV("transaction_hex_str", transaction_hex_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +/** + * @brief + * + * @param transaction_json_str + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_decode_transaction_struct_from_json( + const char* transaction_json_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_json_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_json_str[0] != '\0'), "transaction_json_str can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto transaction = builder.createTransactionWithJson(std::string(transaction_json_str)); + + return convert_tars_transaction_to_struct(std::move(transaction)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_struct_from_json") + << LOG_DESC("exception") + << LOG_KV("transaction_json_str", transaction_json_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_create_transaction_data_struct_with_hex_input_v1( + const char* group_id, const char* chain_id, const char* to, const char* input, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit, + const char* max_fee_per_gas, const char* max_priority_fee_per_gas) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((input[0] != '\0'), "input can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(value, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(gas_price, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(max_fee_per_gas, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(max_priority_fee_per_gas, NULL); + + try + { + struct bcos_sdk_c_transaction_data_v1* transaction_data_struct_v1 = + (struct bcos_sdk_c_transaction_data_v1*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v1)); + auto bytesInput = fromHexString(input); + TransactionBuilder builder; + std::string nonceStr = builder.generateRandomStr(); + + transaction_data_struct_v1->version = 1; + transaction_data_struct_v1->block_limit = block_limit; + transaction_data_struct_v1->group_id = my_strdup(group_id); + transaction_data_struct_v1->chain_id = my_strdup(chain_id); + transaction_data_struct_v1->to = to ? my_strdup(to) : my_strdup(""); + transaction_data_struct_v1->abi = abi ? my_strdup(abi) : my_strdup(""); + transaction_data_struct_v1->nonce = my_strdup(nonceStr.data()); + transaction_data_struct_v1->input = + create_bytes_struct(bytesInput->size(), reinterpret_cast(bytesInput->data())); + transaction_data_struct_v1->value = my_strdup(value); + transaction_data_struct_v1->gas_price = my_strdup(gas_price); + transaction_data_struct_v1->gas_limit = gas_limit; + transaction_data_struct_v1->max_fee_per_gas = my_strdup(max_fee_per_gas); + transaction_data_struct_v1->max_priority_fee_per_gas = my_strdup(max_priority_fee_per_gas); + + return transaction_data_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data_struct_with_hex_input_v1") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) + << LOG_KV("chain_id", chain_id) << LOG_KV("to", std::string(to ? to : "")) + << LOG_KV("input", input) << LOG_KV("abi", std::string(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) << LOG_KV("value", value) + << LOG_KV("gas_price", gas_price) << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", max_fee_per_gas) + << LOG_KV("max_priority_fee_per_gas", max_priority_fee_per_gas) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_create_transaction_data_struct_with_bytes_v1( + const char* group_id, const char* chain_id, const char* to, const unsigned char* bytes_input, + uint32_t bytes_input_length, const char* abi, int64_t block_limit, const char* value, + const char* gas_price, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(bytes_input, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (bytes_input_length > 0), "bytes input length must > 0", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(value, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(gas_price, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(max_fee_per_gas, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(max_priority_fee_per_gas, NULL); + + try + { + struct bcos_sdk_c_transaction_data_v1* transaction_data_struct_v1 = + (struct bcos_sdk_c_transaction_data_v1*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v1)); + TransactionBuilder builder; + std::string nonceStr = builder.generateRandomStr(); + + transaction_data_struct_v1->version = 1; + transaction_data_struct_v1->block_limit = block_limit; + transaction_data_struct_v1->group_id = my_strdup(group_id); + transaction_data_struct_v1->chain_id = my_strdup(chain_id); + transaction_data_struct_v1->to = to ? my_strdup(to) : my_strdup(""); + transaction_data_struct_v1->abi = abi ? my_strdup(abi) : my_strdup(""); + transaction_data_struct_v1->nonce = my_strdup(nonceStr.data()); + transaction_data_struct_v1->input = create_bytes_struct( + bytes_input_length, const_cast(reinterpret_cast(bytes_input))); + transaction_data_struct_v1->value = my_strdup(value); + transaction_data_struct_v1->gas_price = my_strdup(gas_price); + transaction_data_struct_v1->gas_limit = gas_limit; + transaction_data_struct_v1->max_fee_per_gas = my_strdup(max_fee_per_gas); + transaction_data_struct_v1->max_priority_fee_per_gas = my_strdup(max_priority_fee_per_gas); + + return transaction_data_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data_struct_with_bytes_v1") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) + << LOG_KV("chain_id", chain_id) << LOG_KV("to", std::string(to ? to : "")) + << LOG_KV("bytes_input", bytes_input) + << LOG_KV("bytes_input_length", bytes_input_length) + << LOG_KV("abi", std::string(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) << LOG_KV("value", value) + << LOG_KV("gas_price", gas_price) << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", max_fee_per_gas) + << LOG_KV("max_priority_fee_per_gas", max_priority_fee_per_gas) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +void bcos_sdk_destroy_transaction_data_struct_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data) +{ + if (transaction_data == NULL) + { + return; + } + + if (transaction_data->chain_id) + { + bcos_sdk_c_free(transaction_data->chain_id); + } + + if (transaction_data->group_id) + { + bcos_sdk_c_free(transaction_data->group_id); + } + + if (transaction_data->nonce) + { + bcos_sdk_c_free(transaction_data->nonce); + } + + if (transaction_data->to) + { + bcos_sdk_c_free(transaction_data->to); + } + + if (transaction_data->abi) + { + bcos_sdk_c_free((void*)transaction_data->abi); + } + + if (transaction_data->input) + { + if (transaction_data->input->buffer) + { + bcos_sdk_c_free(transaction_data->input->buffer); + } + bcos_sdk_c_free((void*)transaction_data->input); + } + + if (transaction_data->value) + { + bcos_sdk_c_free(transaction_data->value); + } + + if (transaction_data->gas_price) + { + bcos_sdk_c_free(transaction_data->gas_price); + } + + if (transaction_data->max_fee_per_gas) + { + bcos_sdk_c_free(transaction_data->max_fee_per_gas); + } + + if (transaction_data->max_priority_fee_per_gas) + { + bcos_sdk_c_free(transaction_data->max_priority_fee_per_gas); + } + + bcos_sdk_c_free(transaction_data); +} + +const char* bcos_sdk_encode_transaction_data_struct_to_hex_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + + try + { + auto tars_transaction_data = convert_transaction_data_to_tars_v1(transaction_data); + TransactionBuilder builder; + auto encodedTransactionData = builder.encodeTransactionData(*tars_transaction_data); + auto hex_tx_data_str = bcos::toHexString(*encodedTransactionData); + return strdup(hex_tx_data_str->c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_data_struct_to_hex_v1") + << LOG_DESC("exception") << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +const char* bcos_sdk_encode_transaction_data_struct_to_json_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + + try + { + auto tars_transaction_data_v1 = convert_transaction_data_to_tars_v1(transaction_data); + auto json_str = tars_transaction_data_v1->writeToJsonString(); + return strdup(json_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_data_struct_to_json_v1") + << LOG_DESC("exception") << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_decode_transaction_data_struct_from_hex_v1( + const char* transaction_data_hex_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hex_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((transaction_data_hex_str[0] != '\0'), + "transaction_data_hex_str can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((strlen(transaction_data_hex_str) % 2 != 1), + "the length of transaction_data_hex_str must be an even number", NULL); + + try + { + TransactionBuilder builder; + auto tx_data_bytes = fromHexString(transaction_data_hex_str); + auto tars_tx_data_v1 = builder.decodeTransactionData(*tx_data_bytes); + return convert_tars_transaction_data_to_struct_v1(std::move(tars_tx_data_v1)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_data_struct_v1") + << LOG_DESC("exception") << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_decode_transaction_data_struct_from_json_v1( + const char* transaction_data_json_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_json_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((transaction_data_json_str[0] != '\0'), + "transaction_data_json_str can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto transactionData = + builder.createTransactionDataWithJson(std::string(transaction_data_json_str)); + + return convert_tars_transaction_data_to_struct_v1(std::move(transactionData)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_data_struct_from_json_v1") + << LOG_DESC("exception") + << LOG_KV("transaction_data_json_str", transaction_data_json_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +const char* bcos_sdk_calc_transaction_data_struct_hash_v1( + int crypto_type, struct bcos_sdk_c_transaction_data_v1* transaction_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (crypto_type == BCOS_C_SDK_ECDSA_TYPE || crypto_type == BCOS_C_SDK_SM_TYPE), + "invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto type) or " + "BCOS_C_SDK_SM_TYPE(sm crypto type)", + NULL); + + try + { + auto tars_transaction_data_v1 = convert_transaction_data_to_tars_v1(transaction_data); + TransactionBuilder builder; + auto transactionDataHash = builder.calculateTransactionDataHash( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, + *tars_transaction_data_v1); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_struct_hash_v1") + << LOG_DESC("exception") << LOG_KV("crypto_type", crypto_type) + << LOG_KV("transaction_data", transaction_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +const char* bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1( + int crypto_type, const char* transaction_data_hex) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hex, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (crypto_type == BCOS_C_SDK_ECDSA_TYPE || crypto_type == BCOS_C_SDK_SM_TYPE), + "invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto type) or " + "BCOS_C_SDK_SM_TYPE(sm crypto type)", + NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hex[0] != '\0'), "transaction_data_hex can not be empty string", NULL); + + try + { + struct bcos_sdk_c_transaction_data_v1* transaction_data_struct_v1 = + bcos_sdk_decode_transaction_data_struct_from_hex_v1(transaction_data_hex); + auto tars_transaction_data_v1 = + convert_transaction_data_to_tars_v1(transaction_data_struct_v1); + TransactionBuilder builder; + auto transactionDataHash = builder.calculateTransactionDataHash( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, + *tars_transaction_data_v1); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1") + << LOG_DESC("exception") << LOG_KV("crypto_type", crypto_type) + << LOG_KV("transaction_data_hex", transaction_data_hex) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_v1* bcos_sdk_create_transaction_struct_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (signature[0] != '\0'), "signature can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hash[0] != '\0'), "transaction_data_hash can not be empty string", NULL); + + try + { + struct bcos_sdk_c_transaction_v1* transaction_struct_v1 = + (struct bcos_sdk_c_transaction_v1*)malloc(sizeof(struct bcos_sdk_c_transaction_v1)); + transaction_struct_v1->transaction_data = transaction_data_copy_v1(transaction_data); + transaction_struct_v1->sender = NULL; + transaction_struct_v1->import_time = 0; + transaction_struct_v1->attribute = attribute; + transaction_struct_v1->extra_data = my_strdup(extra_data); + // signature + auto signatureWithoutHex = fromHexString(signature); + struct bcos_sdk_c_bytes* signature_bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + signature_bytes->length = signatureWithoutHex->size(); + signature_bytes->buffer = (uint8_t*)malloc(signatureWithoutHex->size()); + memcpy(signature_bytes->buffer, signatureWithoutHex->data(), signatureWithoutHex->size()); + transaction_struct_v1->signature = signature_bytes; + // data_hash + auto dataHashArray = bcos::crypto::HashType(transaction_data_hash); + struct bcos_sdk_c_bytes* data_hash_bytes = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + data_hash_bytes->length = dataHashArray.size(); + data_hash_bytes->buffer = (uint8_t*)malloc(dataHashArray.size()); + memcpy(data_hash_bytes->buffer, dataHashArray.data(), dataHashArray.size()); + transaction_struct_v1->data_hash = data_hash_bytes; + + return transaction_struct_v1; + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_struct_v1") + << LOG_DESC("exception") << LOG_KV("signature", signature) + << LOG_KV("transaction_data_hash", transaction_data_hash) + << LOG_KV("attribute", attribute) << LOG_KV("extra_data", extra_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +void bcos_sdk_destroy_transaction_struct_v1(struct bcos_sdk_c_transaction_v1* transaction) +{ + if (transaction == NULL) + { + return; + } + + if (transaction && transaction->transaction_data) + { + bcos_sdk_destroy_transaction_data_struct_v1(transaction->transaction_data); + } + + if (transaction && transaction->data_hash) + { + if (transaction->data_hash->buffer) + { + bcos_sdk_c_free(transaction->data_hash->buffer); + } + bcos_sdk_c_free(transaction->data_hash); + } + + if (transaction && transaction->signature) + { + if (transaction->signature->buffer) + { + bcos_sdk_c_free(transaction->signature->buffer); + } + bcos_sdk_c_free(transaction->signature); + } + + if (transaction && transaction->sender) + { + if (transaction->sender->buffer) + { + bcos_sdk_c_free(transaction->sender->buffer); + } + bcos_sdk_c_free(transaction->sender); + } + + if (transaction && transaction->extra_data) + { + bcos_sdk_c_free(transaction->extra_data); + } + + bcos_sdk_c_free(transaction); +} + +const char* bcos_sdk_create_encoded_transaction_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_data_hash, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (signature[0] != '\0'), "signature can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_data_hash[0] != '\0'), "transaction_data_hash can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto tars_tx_data_v1 = convert_transaction_data_to_tars_v1(transaction_data); + auto signedBytes = builder.createSignedTransaction(*tars_tx_data_v1, + *fromHexString(signature), bcos::crypto::HashType(transaction_data_hash), attribute, + extra_data ? std::string(extra_data) : std::string()); + return strdup(bcos::toHexStringWithPrefix(*signedBytes).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_encoded_transaction_v1") + << LOG_DESC("exception") << LOG_KV("signature", signature) + << LOG_KV("transaction_data_hash", transaction_data_hash) + << LOG_KV("attribute", attribute) << LOG_KV("extra_data", extra_data) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return NULL; +} + +const char* bcos_sdk_encode_transaction_struct_to_hex_v1( + struct bcos_sdk_c_transaction_v1* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + + try + { + auto tars_transaction_v1 = convert_transaction_to_tars_v1(transaction); + TransactionBuilder builder; + auto encodedTransaction = builder.encodeTransaction(*tars_transaction_v1); + auto hex_tx_str = toHexStringWithPrefix(*encodedTransaction); + return strdup(hex_tx_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_struct_to_hex_v1") + << LOG_DESC("exception") << LOG_KV("transaction", transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +const char* bcos_sdk_encode_transaction_struct_to_json_v1( + struct bcos_sdk_c_transaction_v1* transaction) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction, NULL); + + try + { + auto tars_transaction_v1 = convert_transaction_to_tars_v1(transaction); + auto json_str = tars_transaction_v1->writeToJsonString(); + return strdup(json_str.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_encode_transaction_struct_to_json_v1") + << LOG_DESC("exception") << LOG_KV("transaction", transaction) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_v1* bcos_sdk_decode_transaction_struct_from_hex_v1( + const char* transaction_hex_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_hex_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_hex_str[0] != '\0'), "transaction_hex_str can not be empty string", NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((strlen(transaction_hex_str) % 2 != 1), + "the length of transaction_hex_str must be an even number", NULL); + + try + { + TransactionBuilder builder; + auto tx_bytes = fromHexString(transaction_hex_str); + auto tars_tx = builder.decodeTransaction(*tx_bytes); + return convert_tars_transaction_to_struct_v1(std::move(tars_tx)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_struct") + << LOG_DESC("exception") + << LOG_KV("transaction_hex_str", transaction_hex_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +struct bcos_sdk_c_transaction_v1* bcos_sdk_decode_transaction_struct_from_json_v1( + const char* transaction_json_str) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_json_str, NULL); + BCOS_SDK_C_PARAMS_VERIFY_CONDITION( + (transaction_json_str[0] != '\0'), "transaction_json_str can not be empty string", NULL); + + try + { + TransactionBuilder builder; + auto transaction = builder.createTransactionWithJson(std::string(transaction_json_str)); + + return convert_tars_transaction_to_struct_v1(std::move(transaction)); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_decode_transaction_struct_from_json_v1") + << LOG_DESC("exception") + << LOG_KV("transaction_json_str", transaction_json_str) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h new file mode 100644 index 000000000..f45bce564 --- /dev/null +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file bcos_sdk_c_util_tx_struct.h + * @author: lucasli + * @date 2023-05-08 + */ + +#ifndef __INCLUDE_BCOS_SDK_C_UTIL_TX_STRUCT__ +#define __INCLUDE_BCOS_SDK_C_UTIL_TX_STRUCT__ + +#include "bcos_sdk_c_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief + * + * @param group_id + * @param chain_id + * @param to + * @param input + * @param abi + * @param block_limit + * @return bcos_sdk_c_transaction_data*: transaction data struct pointer, return unassigned struct + * on failure according to the function called bcos_sdk_get_last_error(if create failed, return -1) + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_create_transaction_data_struct_with_hex_input( + const char* group_id, const char* chain_id, const char* to, const char* input, const char* abi, + int64_t block_limit); + +/** + * @brief + * + * @param group_id + * @param chain_id + * @param to + * @param bytes_input + * @param bytes_input_length + * @param abi + * @param block_limit + * @return bcos_sdk_c_transaction_data*: transaction data struct pointer, return unassigned struct + * on failure according to the function called bcos_sdk_get_last_error(if create failed, return -1) + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_create_transaction_data_struct_with_bytes( + const char* group_id, const char* chain_id, const char* to, const unsigned char* bytes_input, + uint32_t bytes_input_length, const char* abi, int64_t block_limit); + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + */ +void bcos_sdk_destroy_transaction_data_struct(struct bcos_sdk_c_transaction_data* transaction_data); + +/** + * @brief encode transaction data into hex format + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_data_struct_to_hex( + struct bcos_sdk_c_transaction_data* transaction_data); + +/** + * @brief convert transaction data into json format + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_data_struct_to_json( + struct bcos_sdk_c_transaction_data* transaction_data); + +/** + * @param transaction_data_hex_str + * @return struct bcos_sdk_c_transaction_data* + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_decode_transaction_data_struct_from_hex( + const char* transaction_data_hex_str); + +/** + * @param transaction_data_json_str + * version:number + * groupID:string + * chainID:string + * to:string + * data:hex string + * abi:string + * blockLimit:number + * nonce:string + * @return struct bcos_sdk_c_transaction_data* + */ +struct bcos_sdk_c_transaction_data* bcos_sdk_decode_transaction_data_struct_from_json( + const char* transaction_data_json_str); + +/** + * @brief + * + * @param crypto_type: int + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @return const char* + */ +const char* bcos_sdk_calc_transaction_data_struct_hash( + int crypto_type, struct bcos_sdk_c_transaction_data* transaction_data); + +/** + * @brief + * + * @param crypto_type: int + * @param transaction_data_hex: const char* + * @return const char* + */ +const char* bcos_sdk_calc_transaction_data_struct_hash_with_hex( + int crypto_type, const char* transaction_data_hex); + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @param signature + * @param transaction_data_hash + * @param attribute + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_create_transaction_struct( + struct bcos_sdk_c_transaction_data* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data); + +/** + * @brief + * + * @param transaction: struct bcos_sdk_c_transaction* + */ +void bcos_sdk_destroy_transaction_struct(struct bcos_sdk_c_transaction* transaction); + +/** + * @brief + * + * @param transaction_data: struct bcos_sdk_c_transaction_data* + * @param signature + * @param transaction_data_hash + * @param attribute + * @return const char* + */ +const char* bcos_sdk_create_encoded_transaction( + struct bcos_sdk_c_transaction_data* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data); + +/** + * @brief encode transaction into hex format + * + * @param transaction: struct bcos_sdk_c_transaction* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_struct_to_hex(struct bcos_sdk_c_transaction* transaction); + +/** + * @brief convert transaction into json format + * + * @param transaction: struct bcos_sdk_c_transaction* + * @return const char* + */ +const char* bcos_sdk_encode_transaction_struct_to_json(struct bcos_sdk_c_transaction* transaction); + +/** + * @brief + * + * @param transaction_hex_str + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_decode_transaction_struct_from_hex( + const char* transaction_hex_str); + +/** + * @brief + * + * @param transaction_json_str + * @return struct bcos_sdk_c_transaction* + */ +struct bcos_sdk_c_transaction* bcos_sdk_decode_transaction_struct_from_json( + const char* transaction_json_str); + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_create_transaction_data_struct_with_hex_input_v1( + const char* group_id, const char* chain_id, const char* to, const char* input, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit, + const char* max_fee_per_gas, const char* max_priority_fee_per_gas); + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_create_transaction_data_struct_with_bytes_v1( + const char* group_id, const char* chain_id, const char* to, const unsigned char* bytes_input, + uint32_t bytes_input_length, const char* abi, int64_t block_limit, const char* value, + const char* gas_price, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas); + + +void bcos_sdk_destroy_transaction_data_struct_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data); + +const char* bcos_sdk_encode_transaction_data_struct_to_hex_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data); + +const char* bcos_sdk_encode_transaction_data_struct_to_json_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data); + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_decode_transaction_data_struct_from_hex_v1( + const char* transaction_data_hex_str); + +struct bcos_sdk_c_transaction_data_v1* bcos_sdk_decode_transaction_data_struct_from_json_v1( + const char* transaction_data_json_str); + +const char* bcos_sdk_calc_transaction_data_struct_hash_v1( + int crypto_type, struct bcos_sdk_c_transaction_data_v1* transaction_data); + +const char* bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1( + int crypto_type, const char* transaction_data_hex); + +struct bcos_sdk_c_transaction_v1* bcos_sdk_create_transaction_struct_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data); + +void bcos_sdk_destroy_transaction_struct_v1(struct bcos_sdk_c_transaction_v1* transaction); + +const char* bcos_sdk_create_encoded_transaction_v1( + struct bcos_sdk_c_transaction_data_v1* transaction_data, const char* signature, + const char* transaction_data_hash, int32_t attribute, const char* extra_data); + +const char* bcos_sdk_encode_transaction_struct_to_hex_v1( + struct bcos_sdk_c_transaction_v1* transaction); + +const char* bcos_sdk_encode_transaction_struct_to_json_v1( + struct bcos_sdk_c_transaction_v1* transaction); + +struct bcos_sdk_c_transaction_v1* bcos_sdk_decode_transaction_struct_from_hex_v1( + const char* transaction_hex_str); + +struct bcos_sdk_c_transaction_v1* bcos_sdk_decode_transaction_struct_from_json_v1( + const char* transaction_json_str); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.cpp b/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.cpp new file mode 100644 index 000000000..85ba13674 --- /dev/null +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.cpp @@ -0,0 +1,342 @@ +/** + * Copyright (C) 2022 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file bcos_sdk_c_uti_tx_v1.cpp + * @author: kyonGuo + * @date 2023/11/28 + */ + +#include "bcos_sdk_c_uti_tx_v1.h" +#include "bcos_sdk_c_error.h" +#include +#include +#include +#include + +using namespace bcos; +using namespace bcos::cppsdk; +using namespace bcos::cppsdk::utilities; + +#include +#include +#include + +void* bcos_sdk_create_transaction_v1_data(const char* group_id, const char* chain_id, + const char* to, const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL) + + try + { + TransactionBuilderV1 builder; + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + auto transactionData = builder.createTransactionData(1, group_id, chain_id, to, + nonce ? nonce : "", std::move(bytesData), abi, block_limit, value ? value : "", + gas_price ? gas_price : "", gas_limit); + return transactionData.release(); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_transaction_data") << LOG_DESC("exception") + << LOG_KV("group_id", group_id) << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonoce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) + << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_price", std::string_view(gas_price ? gas_price : "")) + << LOG_KV("gas_limit", gas_limit) << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + + return NULL; +} + +void* bcos_sdk_create_eip1559_transaction_data(const char* group_id, const char* chain_id, + const char* to, const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL) + + try + { + TransactionBuilderV1 builder; + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + auto transactionData = builder.createTransactionData(1, group_id, chain_id, to, + nonce ? nonce : "", std::move(bytesData), abi, block_limit, value ? value : "", "", + gas_limit, max_fee_per_gas ? max_fee_per_gas : "", + max_priority_fee_per_gas ? max_priority_fee_per_gas : ""); + return transactionData.release(); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) + << LOG_BADGE("bcos_sdk_create_eip1559_transaction_data") << LOG_DESC("exception") + << LOG_KV("group_id", group_id) << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonoce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", std::string_view(max_fee_per_gas ? max_fee_per_gas : "")) + << LOG_KV("max_priority_fee_per_gas", + std::string_view(max_priority_fee_per_gas ? max_priority_fee_per_gas : "")) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + + +const char* bcos_sdk_calc_transaction_data_hash_with_full_fields(int crypto_type, + transaction_version version, const char* group_id, const char* chain_id, const char* to, + const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit, + const char* max_fee_per_gas, const char* max_priority_fee_per_gas) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(nonce, NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL) + + try + { + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + TransactionBuilderV1 builder; + auto transactionDataHash = builder.calculateTransactionDataHash( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, version, + group_id, chain_id, to ? to : "", nonce, std::move(bytesData), abi ? abi : "", + block_limit, value ? value : "", gas_price ? gas_price : "", gas_limit, + max_fee_per_gas ? max_fee_per_gas : "", + max_priority_fee_per_gas ? max_priority_fee_per_gas : ""); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) + << LOG_BADGE("bcos_sdk_calc_transaction_data_hash_with_full_fields") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_price", std::string_view(gas_price ? gas_price : "")) + << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", std::string_view(max_fee_per_gas ? max_fee_per_gas : "")) + << LOG_KV("max_priority_fee_per_gas", + std::string_view(max_priority_fee_per_gas ? max_priority_fee_per_gas : "")) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + +const char* bcos_sdk_calc_transaction_data_hash_with_json(int crypto_type, const char* json) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(json, NULL) + + try + { + TransactionBuilderV1 builder; + auto transactionDataHash = builder.calculateTransactionDataHashWithJson( + crypto_type == BCOS_C_SDK_ECDSA_TYPE ? CryptoType::Secp256K1 : CryptoType::SM2, json); + return strdup(bcos::toHexStringWithPrefix(transactionDataHash).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_calc_transaction_data_hash_with_json") + << LOG_DESC("exception") << LOG_KV("json", std::string_view(json)) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + +const char* bcos_sdk_create_signed_transaction_with_signature(const unsigned char* signature, + long signSize, const char* transaction_hash, transaction_version version, const char* group_id, + const char* chain_id, const char* to, const char* nonce, const unsigned char* input, + long inputSize, const char* abi, int64_t block_limit, const char* value, const char* gas_price, + int64_t gas_limit, const char* max_fee_per_gas, const char* max_priority_fee_per_gas, + int32_t attribute, const char* extra_data) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(signature, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(transaction_hash, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, NULL) + BCOS_SDK_C_PARAMS_VERIFICATION(input, NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", NULL) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", NULL) + + try + { + TransactionBuilderV1 builder; + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + auto hash = std::string_view(transaction_hash); + crypto::HashType tx_hash(fromHex(hash, hash.starts_with("0x") ? "0x" : "")); + auto sign = bytes(signature, signature + signSize * sizeof(byte)); + + auto transaction = builder.createTransaction(std::move(sign), tx_hash, attribute, version, + group_id, chain_id, to ? to : "", nonce ? nonce : "", std::move(bytesData), + abi ? abi : "", block_limit, value ? value : "", gas_price ? gas_price : "", gas_limit, + max_fee_per_gas ? max_fee_per_gas : "", + max_priority_fee_per_gas ? max_priority_fee_per_gas : "", extra_data ? extra_data : ""); + + auto bytes = builder.encodeTransaction(*transaction); + + return strdup(bcos::toHexStringWithPrefix(*bytes).c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_signed_transaction_with_signature") + << LOG_DESC("exception") << LOG_KV("signSize", signSize) + << LOG_KV("transaction_hash", transaction_hash) + << LOG_KV("group_id", group_id) << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) + << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_price", std::string_view(gas_price ? gas_price : "")) + << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", + std::string_view(max_fee_per_gas ? max_fee_per_gas : "")); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } + return nullptr; +} + +void bcos_sdk_create_signed_transaction_with_full_fields(void* key_pair, const char* group_id, + const char* chain_id, const char* to, const char* nonce, const unsigned char* input, + long inputSize, const char* abi, int64_t block_limit, const char* value, const char* gas_price, + int64_t gas_limit, int32_t attribute, const char* extra_data, char** tx_hash, char** signed_tx) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(key_pair, ) + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, ) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, ) + BCOS_SDK_C_PARAMS_VERIFICATION(input, ) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", ) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", ) + BCOS_SDK_C_PARAMS_VERIFICATION(tx_hash, ) + BCOS_SDK_C_PARAMS_VERIFICATION(signed_tx, ) + + try + { + TransactionBuilderV1 builder; + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + auto result = + builder.createSignedTransaction(*static_cast(key_pair), + attribute, 1, group_id, chain_id, to ? to : "", nonce ? nonce : "", + std::move(bytesData), abi ? abi : "", block_limit, value ? value : "", + gas_price ? gas_price : "", gas_limit, "", "", extra_data ? extra_data : ""); + *tx_hash = strdup(result.first.c_str()); + *signed_tx = strdup(result.second.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) << LOG_BADGE("bcos_sdk_create_signed_transaction_with_full_fields") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) + << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonoce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) + << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_price", std::string_view(gas_price ? gas_price : "")) + << LOG_KV("gas_limit", gas_limit) << LOG_KV("attribute", attribute) + << LOG_KV("extra_data", std::string_view(extra_data ? extra_data : "")) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } +} + +void bcos_sdk_create_signed_eip1559_transaction_with_full_fields(void* key_pair, + const char* group_id, const char* chain_id, const char* to, const char* nonce, + const unsigned char* input, long inputSize, const char* abi, int64_t block_limit, + const char* value, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas, int32_t attribute, const char* extra_data, char** tx_hash, + char** signed_tx) +{ + bcos_sdk_clear_last_error(); + BCOS_SDK_C_PARAMS_VERIFICATION(key_pair, ) + BCOS_SDK_C_PARAMS_VERIFICATION(group_id, ) + BCOS_SDK_C_PARAMS_VERIFICATION(chain_id, ) + BCOS_SDK_C_PARAMS_VERIFICATION(input, ) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((block_limit > 0), "block limit must > 0", ) + BCOS_SDK_C_PARAMS_VERIFY_CONDITION((gas_limit >= 0), "gas limit must >= 0", ) + BCOS_SDK_C_PARAMS_VERIFICATION(tx_hash, ) + BCOS_SDK_C_PARAMS_VERIFICATION(signed_tx, ) + + try + { + TransactionBuilderV1 builder; + auto bytesData = bytes(input, input + inputSize * sizeof(byte)); + auto result = builder.createSignedTransaction( + *static_cast(key_pair), attribute, 1, group_id, + chain_id, to ? to : "", nonce ? nonce : "", std::move(bytesData), abi ? abi : "", + block_limit, value ? value : "", "", gas_limit, max_fee_per_gas ? max_fee_per_gas : "", + max_priority_fee_per_gas ? max_priority_fee_per_gas : "", extra_data ? extra_data : ""); + *tx_hash = strdup(result.first.c_str()); + *signed_tx = strdup(result.second.c_str()); + } + catch (const std::exception& e) + { + std::string errorMsg = boost::diagnostic_information(e); + BCOS_LOG(WARNING) + << LOG_BADGE("bcos_sdk_create_signed_eip1559_transaction_with_full_fields") + << LOG_DESC("exception") << LOG_KV("group_id", group_id) << LOG_KV("chain_id", chain_id) + << LOG_KV("to", std::string_view(to ? to : "")) + << LOG_KV("nonoce", std::string_view(nonce ? nonce : "")) + << LOG_KV("inputSize", inputSize) << LOG_KV("abi", std::string_view(abi ? abi : "")) + << LOG_KV("block_limit", block_limit) + << LOG_KV("value", std::string_view(value ? value : "")) + << LOG_KV("gas_limit", gas_limit) + << LOG_KV("max_fee_per_gas", std::string_view(max_fee_per_gas ? max_fee_per_gas : "")) + << LOG_KV("max_priority_fee_per_gas", + std::string_view(max_priority_fee_per_gas ? max_priority_fee_per_gas : "")) + << LOG_KV("attribute", attribute) + << LOG_KV("extra_data", std::string_view(extra_data ? extra_data : "")) + << LOG_KV("error", errorMsg); + bcos_sdk_set_last_error_msg(-1, errorMsg.c_str()); + } +} diff --git a/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.h b/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.h new file mode 100644 index 000000000..20e3994f6 --- /dev/null +++ b/bcos-c-sdk/bcos_sdk_c_uti_tx_v1.h @@ -0,0 +1,214 @@ +/** + * Copyright (C) 2022 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file bcos_sdk_c_uti_tx_v1.h + * @author: kyonGuo + * @date 2023/11/28 + */ + +#ifndef BCOS_C_SDK_BCOS_SDK_C_UTI_TX_V1_H +#define BCOS_C_SDK_BCOS_SDK_C_UTI_TX_V1_H + +#include "bcos_sdk_c_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum transaction_version +{ + TRANSACTION_VERSION_0 = 0, + /* + * @brief enable (value,gasPrice,gasLimit,maxFeePerGas,maxPriorityFeePerGas) fields + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + TRANSACTION_VERSION_1 = 1, +}; + +/** + * @brief create transaction data with version 1 by default + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if empty, then will generate one + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_price gas price + * @param gas_limit gas limit + * @return void* transaction data pointer, you should release it after use + */ +void* bcos_sdk_create_transaction_v1_data(const char* group_id, const char* chain_id, + const char* to, const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit); + +/** + * @brief create eip1559 transaction data with version 1 by default + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if empty, then will generate one + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_limit gas limit + * @param max_fee_per_gas max fee per gas + * @param max_priority_fee_per_gas max priority fee per gas + * @return void* transaction data pointer, you should release it after use + */ +void* bcos_sdk_create_eip1559_transaction_data(const char* group_id, const char* chain_id, + const char* to, const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas); + +/** + * @brief create transaction data with full fields + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param crypto_type 0: keccak256, 1: sm3 + * @param version tx version, if version==1, then enable + * (value,gasPrice,gasLimit,maxFeePerGas,maxPriorityFeePerGas) fields + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce nonce, random number to avoid duplicate transactions + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_price gas price + * @param gas_limit gas limit + * @param max_fee_per_gas max fee per gas + * @param max_priority_fee_per_gas max priority fee per gas + * @return const char* transaction data hash hex string + */ +const char* bcos_sdk_calc_transaction_data_hash_with_full_fields(int crypto_type, + transaction_version version, const char* group_id, const char* chain_id, const char* to, + const char* nonce, const unsigned char* input, long inputSize, const char* abi, + int64_t block_limit, const char* value, const char* gas_price, int64_t gas_limit, + const char* max_fee_per_gas, const char* max_priority_fee_per_gas); + +/** + * @brief create transaction data with json string + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param crypto_type 0: keccak256, 1: sm3 + * @param json transaction data json string + * @return const char* transaction data hash hex string + * @throw exception if lack of some required fields, or some fields are invalid + */ +const char* bcos_sdk_calc_transaction_data_hash_with_json(int crypto_type, const char* json); + +/** + * @brief create encoded transaction data with external signature + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param signature signature bytes array, if ECDSA, it is r||s||v, if SM2, it is r||s||pk + * @param signSize signature bytes array size + * @param transaction_hash transactionData hash hex string + * @param version tx version, only support 0 and 1 now, if version==1, then enable + * (value,gasPrice,gasLimit,maxFeePerGas,maxPriorityFeePerGas) fields + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce nonce, random number to avoid duplicate transactions + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_price gas price + * @param gas_limit gas limit + * @param max_fee_per_gas max fee per gas + * @param max_priority_fee_per_gas max priority fee per gas + * @param attribute transaction attribute + * @param extra_data extra data in transaction + * @return const char* encoded transaction hex string + */ +const char* bcos_sdk_create_signed_transaction_with_signature(const unsigned char* signature, + long signSize, const char* transaction_hash, transaction_version version, const char* group_id, + const char* chain_id, const char* to, const char* nonce, const unsigned char* input, + long inputSize, const char* abi, int64_t block_limit, const char* value, const char* gas_price, + int64_t gas_limit, const char* max_fee_per_gas, const char* max_priority_fee_per_gas, + int32_t attribute, const char* extra_data); + +/** + * @brief create transaction with full fields, with version 1 by default + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param key_pair key pair pointer + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if empty, then will generate one + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_price gas price + * @param gas_limit gas limit + * @param attribute transaction attribute + * @param extra_data extra data in transaction + * @param tx_hash output transaction hash hex string + * @param signed_tx output signed transaction hex string + */ +void bcos_sdk_create_signed_transaction_with_full_fields(void* key_pair, const char* group_id, + const char* chain_id, const char* to, const char* nonce, const unsigned char* input, + long inputSize, const char* abi, int64_t block_limit, const char* value, const char* gas_price, + int64_t gas_limit, int32_t attribute, const char* extra_data, char** tx_hash, char** signed_tx); + +/** + * @brief create eip1559 transaction with full fields, with version 1 by default + * @note version 1 transaction only supported in FISCO BCOS 3.6.0 and later + * + * @param key_pair key pair pointer + * @param group_id group id + * @param chain_id chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if empty, then will generate one + * @param input encoded contract method and params, bytes array + * @param inputSize encoded contract method and params size + * @param abi contract abi, only create contract need + * @param block_limit block limit + * @param value transfer value + * @param gas_limit gas limit + * @param max_fee_per_gas max fee per gas + * @param max_priority_fee_per_gas max priority fee per gas + * @param attribute transaction attribute + * @param extra_data extra data in transaction + * @param tx_hash output transaction hash hex string + * @param signed_tx output signed transaction hex string + */ +void bcos_sdk_create_signed_eip1559_transaction_with_full_fields(void* key_pair, + const char* group_id, const char* chain_id, const char* to, const char* nonce, + const unsigned char* input, long inputSize, const char* abi, int64_t block_limit, + const char* value, int64_t gas_limit, const char* max_fee_per_gas, + const char* max_priority_fee_per_gas, int32_t attribute, const char* extra_data, char** tx_hash, + char** signed_tx); + +#ifdef __cplusplus +} +#endif +#endif // BCOS_C_SDK_BCOS_SDK_C_UTI_TX_V1_H diff --git a/bindings/java/jni/.gitignore b/bindings/java/jni/.gitignore new file mode 100644 index 000000000..f5b848482 --- /dev/null +++ b/bindings/java/jni/.gitignore @@ -0,0 +1,24 @@ +.gradle/ +.idea/ +log/ +build/ +dist/ +.vscode/ +.settings/** +java-sdk.iml + +## eclipse ## +.classpath +.project +*/.settings/** +out/ +*/dist/** +*/build/** +conf/ + +## integration test files +gradle.properties +gpg.gpg + +## macOS +.DS_Store diff --git a/bindings/java/jni/build.gradle b/bindings/java/jni/build.gradle index 41f56fa4f..84d24d28b 100644 --- a/bindings/java/jni/build.gradle +++ b/bindings/java/jni/build.gradle @@ -31,7 +31,7 @@ dependencies { archivesBaseName = 'bcos-sdk-jni' group = 'org.fisco-bcos' -version = '3.5.0' +version = '3.6.0-SNAPSHOT' // Additional attribute definition ext { diff --git a/bindings/java/jni/scripts/java2jni.sh b/bindings/java/jni/scripts/java2jni.sh index 3afbb5c06..55f7117f0 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="utilities.keypair.KeyPairJniObj utilities.tx.TransactionBuilderJniObj utilities.receipt.ReceiptBuilderJniObj utilities.signature.SignatureJniObj" +classes="BcosSDKJniObj utilities.keypair.KeyPairJniObj utilities.tx.TransactionBuilderJniObj utilities.tx.TransactionBuilderV1JniObj utilities.tx.TransactionStructBuilderJniObj utilities.receipt.ReceiptBuilderJniObj utilities.signature.SignatureJniObj" for class in ${classes} do diff --git a/bindings/java/jni/src/main/c/CMakeLists.txt b/bindings/java/jni/src/main/c/CMakeLists.txt index 0da1f5904..1b6052b1a 100644 --- a/bindings/java/jni/src/main/c/CMakeLists.txt +++ b/bindings/java/jni/src/main/c/CMakeLists.txt @@ -16,16 +16,19 @@ # limitations under the License. # ------------------------------------------------------------------------------ -set(JAVA_SDK_JNI_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake" CACHE PATH "The cmake path for the library") - -# list(APPEND CMAKE_MODULE_PATH ${BCOS_CMAKE_SCRIPTS_DIR}) -list(APPEND CMAKE_MODULE_PATH ${JAVA_SDK_JNI_CMAKE_DIR}) - # Debug, Release, RelWithDebInfo, MinSizeRel if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() +if (WIN32) + add_definitions(-D_WIN32_WINNT=0x0601) + add_definitions(-DBOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN7) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") + set(VCPKG_C_FLAGS -D_WIN32_WINNT=0x0601 -DWINVER=0x0601) + set(VCPKG_CXX_FLAGS -D_WIN32_WINNT=0x0601 -DWINVER=0x0601) +endif () + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") @@ -53,14 +56,10 @@ else() endif() add_library(${FISCO_BCOS_JNI_TARGET} SHARED ${SOURCES}) -target_link_libraries(${FISCO_BCOS_JNI_TARGET} PUBLIC wedpr-crypto::crypto wedpr-crypto::extend-crypto bcos-cpp-sdk::bcos-cpp-sdk ${BCOS_C_SDK_STATIC_TARGET}) +target_link_libraries(${FISCO_BCOS_JNI_TARGET} PUBLIC wedprcrypto::crypto wedprcrypto::zkp fiscobcos::bcos-cpp-sdk ${BCOS_C_SDK_STATIC_TARGET}) add_library(${FISCO_BCOS_JNI_STATIC_TARGET} ${SOURCES}) -target_link_libraries(${FISCO_BCOS_JNI_STATIC_TARGET} PUBLIC wedpr-crypto::crypto wedpr-crypto::extend-crypto bcos-cpp-sdk::bcos-cpp-sdk ${BCOS_C_SDK_STATIC_TARGET}) - -if(BUILD_EXEC_TEST) - add_subdirectory(test/exe) -endif() +target_link_libraries(${FISCO_BCOS_JNI_STATIC_TARGET} PUBLIC wedprcrypto::crypto wedprcrypto::zkp fiscobcos::bcos-cpp-sdk ${BCOS_C_SDK_STATIC_TARGET}) SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../resources/META-INF/native/) diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_common.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_common.h index ddb2cd618..acc0b026c 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_common.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_common.h @@ -9,6 +9,22 @@ extern "C" { #endif +#define GET_J_STRING_CONTENT(env, jstr) (env)->GetStringUTFChars((jstr), NULL) +#define GET_J_STRING_CONTENT_DEF(env, jstr, def) \ + ((jstr) == NULL ? (def) : GET_J_STRING_CONTENT((env), (jstr))) +#define CHECK_OBJECT_NOT_NULL(env, obj, ret) \ + if (NULL == (obj)) \ + { \ + THROW_JNI_EXCEPTION((env), "illegal NULL " #obj " parameter"); \ + return (ret); \ + } +#define CHECK_OBJECT_NOT_NULL_RET_VOID(env, obj) \ + if (NULL == (obj)) \ + { \ + THROW_JNI_EXCEPTION((env), "illegal NULL " #obj " parameter"); \ + return; \ + } + struct cb_context { JavaVM* jvm; @@ -21,6 +37,27 @@ jclass bcos_sdk_c_find_jclass(JNIEnv* env, const char* className); struct bcos_sdk_c_config* create_config_from_java_obj(JNIEnv* env, jobject jconfig); +// check jstring not null +inline bool checkJString(JNIEnv* env, jstring jstr) +{ + if (jstr == NULL) + { + THROW_JNI_EXCEPTION(env, "illegal NULL string parameter"); + return false; + } + return true; +} +// check jByteArray not null +inline bool checkJByteArray(JNIEnv* env, jbyteArray jbyte_array) +{ + if (jbyte_array == NULL) + { + THROW_JNI_EXCEPTION(env, "illegal NULL byteArray parameter"); + return false; + } + return true; +} + #ifdef __cplusplus } #endif diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.cpp index e498093f4..20db8c175 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.cpp @@ -14,6 +14,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_create( JNIEnv* env, jclass self, jobject jconfig) { + CHECK_OBJECT_NOT_NULL(env, jconfig, 0); (void)self; // config struct bcos_sdk_c_config* config = create_config_from_java_obj(env, jconfig); @@ -128,6 +129,33 @@ static void on_receive_block_notifier(const char* group, int64_t block_number, v // env->DeleteGlobalRef(jcallback); } + +/* + * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj + * Method: localProtocolInfo + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_localProtocolInfo( + JNIEnv* env, jobject self) +{ + void* sdk = bcos_sdk_get_native_pointer(env, self); + uint32_t info = bcos_sdk_get_local_protocol_info(sdk); + return (jint)info; +} + +/* + * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj + * Method: negotiatedProtocolInfo + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_negotiatedProtocolInfo( + JNIEnv* env, jobject self) +{ + void* sdk = bcos_sdk_get_native_pointer(env, self); + uint32_t info = bcos_sdk_get_negotiated_protocol_info(sdk); + return (jint)info; +} + /* * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj * Method: registerBlockNotifier @@ -136,6 +164,8 @@ static void on_receive_block_notifier(const char* group, int64_t block_number, v JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_registerBlockNotifier( JNIEnv* env, jobject self, jstring jgroup, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + void* sdk = bcos_sdk_get_native_pointer(env, self); if (!sdk) { diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.h index 6bbf194a1..09be572be 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_BcosSDKJniObj.h @@ -12,36 +12,56 @@ extern "C" { * Method: create * Signature: (Lorg/fisco/bcos/sdk/jni/common/JniConfig;)J */ -JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_create(JNIEnv*, jclass, jobject); +JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_create + (JNIEnv *, jclass, jobject); /* * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj * Method: start * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_start(JNIEnv*, jobject); +JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_start + (JNIEnv *, jobject); /* * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj * Method: stop * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_stop(JNIEnv*, jobject); +JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_stop + (JNIEnv *, jobject); /* * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj * Method: destroy * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_destroy(JNIEnv*, jobject); +JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_destroy + (JNIEnv *, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj + * Method: localProtocolInfo + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_localProtocolInfo + (JNIEnv *, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj + * Method: negotiatedProtocolInfo + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_negotiatedProtocolInfo + (JNIEnv *, jobject); /* * Class: org_fisco_bcos_sdk_jni_BcosSDKJniObj * Method: registerBlockNotifier * Signature: (Ljava/lang/String;Lorg/fisco/bcos/sdk/jni/BlockNotifier;)V */ -JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_registerBlockNotifier( - JNIEnv*, jobject, jstring, jobject); +JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_BcosSDKJniObj_registerBlockNotifier + (JNIEnv *, jobject, jstring, jobject); #ifdef __cplusplus } diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_amop_AmopJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_amop_AmopJniObj.cpp index d4f527140..8062d204c 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_amop_AmopJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_amop_AmopJniObj.cpp @@ -181,6 +181,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_subscribeTopic__Ljava_lang_String_2Lorg_fisco_bcos_sdk_jni_amop_AmopRequestCallback_2( JNIEnv* env, jobject self, jstring jtopic, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopic); + void* sdk = bcos_sdk_get_native_pointer(env, self); const char* topic = env->GetStringUTFChars(jtopic, 0); @@ -212,6 +214,7 @@ Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_subscribeTopic__Ljava_lang_String_2L JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_subscribeTopic__Ljava_util_Set_2( JNIEnv* env, jobject self, jobject jtopics) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopics); void* sdk = bcos_sdk_get_native_pointer(env, self); jclass setClass = env->GetObjectClass(jtopics); @@ -261,6 +264,7 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_subscribeTopic__Ljava_lang_String_2Lorg_fisco_bcos_sdk_jni_amop_AmopJniObjRequestCallback_2( JNIEnv* env, jobject self, jstring jtopic, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopic); void* sdk = bcos_sdk_get_native_pointer(env, self); const char* topic = env->GetStringUTFChars(jtopic, 0); @@ -292,6 +296,7 @@ Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_subscribeTopic__Ljava_lang_String_2L JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_unsubscribeTopic( JNIEnv* env, jobject self, jobject jtopics) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopics); void* sdk = bcos_sdk_get_native_pointer(env, self); jclass setClass = env->GetObjectClass(jtopics); @@ -363,6 +368,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_setCallback( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_sendAmopMsg( JNIEnv* env, jobject self, jstring jtopic, jbyteArray jdata, jint jtimeout, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopic); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); void* sdk = bcos_sdk_get_native_pointer(env, self); // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be @@ -399,6 +406,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_sendAmopMsg( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_broadcastAmopMsg( JNIEnv* env, jobject self, jstring jtopic, jbyteArray jdata) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtopic); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); void* sdk = bcos_sdk_get_native_pointer(env, self); const char* topic = env->GetStringUTFChars(jtopic, 0); @@ -419,6 +428,9 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_broadcastAmop JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_amop_AmopJniObj_sendResponse( JNIEnv* env, jobject self, jstring jendpoint, jstring jseq, jbyteArray jdata) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jendpoint); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jseq); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); void* sdk = bcos_sdk_get_native_pointer(env, self); const char* endpoint = env->GetStringUTFChars(jendpoint, 0); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_event_EventSubJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_event_EventSubJniObj.cpp index cb8faeec3..474885e22 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_event_EventSubJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_event_EventSubJniObj.cpp @@ -130,6 +130,9 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_event_EventSubJniObj_stop( JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_event_EventSubJniObj_subscribeEvent( JNIEnv* env, jobject self, jstring jgroup, jstring jparams, jobject jcallback) { + CHECK_OBJECT_NOT_NULL(env, jgroup, NULL); + CHECK_OBJECT_NOT_NULL(env, jparams, NULL); + void* sdk = bcos_sdk_get_native_pointer(env, self); const char* group = env->GetStringUTFChars(jgroup, 0); const char* params = env->GetStringUTFChars(jparams, 0); @@ -168,6 +171,7 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_event_EventSubJniObj_subsc JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_event_EventSubJniObj_unsubscribeEvent( JNIEnv* env, jobject self, jstring jeventId) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jeventId); void* sdk = bcos_sdk_get_native_pointer(env, self); const char* eventid = env->GetStringUTFChars(jeventId, 0); 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 36fb232cd..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 @@ -5,6 +5,7 @@ #include "bcos-c-sdk/bcos_sdk_c_rpc.h" #include "jni/org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_class_cache.h" +#include "org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_exception.h" #include #include @@ -80,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); @@ -150,6 +151,7 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_genericMethod__Ljava_lang_String_2Lorg_fisco_bcos_sdk_jni_rpc_RpcCallback_2( JNIEnv* env, jobject self, jstring jdata, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); @@ -182,6 +184,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_genericMethod__Ljava_lang_String_2Ljava_lang_String_2Lorg_fisco_bcos_sdk_jni_rpc_RpcCallback_2( JNIEnv* env, jobject self, jstring jgroup, jstring jdata, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); @@ -219,6 +223,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_genericMethod__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Lorg_fisco_bcos_sdk_jni_rpc_RpcCallback_2( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jstring jdata, jobject jcallback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); @@ -235,7 +241,7 @@ Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_genericMethod__Ljava_lang_String_2Ljav // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* data = env->GetStringUTFChars(jdata, NULL); @@ -259,12 +265,15 @@ Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_genericMethod__Ljava_lang_String_2Ljav JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_call(JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jstring jto, jstring jdata, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jto); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // to const char* to = env->GetStringUTFChars(jto, NULL); // data @@ -300,12 +309,15 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_call(JNIEnv* en JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_sendTransaction(JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jstring jdata, jboolean jproof, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jdata); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* data = env->GetStringUTFChars(jdata, NULL); // proof @@ -341,12 +353,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getTransaction( jobject self, jstring jgroup, jstring jnode, jstring jtx_hash, jboolean jproof, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtx_hash); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* tx_hash = env->GetStringUTFChars(jtx_hash, NULL); // proof @@ -382,12 +396,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getTransactionR jobject self, jstring jgroup, jstring jnode, jstring jtx_hash, jboolean jproof, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jtx_hash); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* tx_hash = env->GetStringUTFChars(jtx_hash, NULL); // proof @@ -424,12 +440,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockByHash( jobject self, jstring jgroup, jstring jnode, jstring jblock_hash, jboolean jonly_header, jboolean jonly_txhash, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jblock_hash); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* block_hash = env->GetStringUTFChars(jblock_hash, NULL); // only_header @@ -467,12 +485,13 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockByNumbe jobject self, jstring jgroup, jstring jnode, jlong jnumber, jboolean jonly_header, jboolean jonly_txhash, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // block number long block_number = static_cast(jnumber); // only_header @@ -508,12 +527,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockByNumbe JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockHashByNumber( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jlong jnumber, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -545,6 +566,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockHashByN JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockLimit( JNIEnv* env, jobject self, jstring jgroup) { + CHECK_OBJECT_NOT_NULL(env, jgroup, 0); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group @@ -563,12 +586,14 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockLimit( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockNumber( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -598,12 +623,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getBlockNumber( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getCode( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jstring jaddress, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jaddress); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* address = env->GetStringUTFChars(jaddress, NULL); @@ -635,12 +662,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getCode( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSealerList( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -669,12 +698,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSealerList( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getObserverList( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -703,12 +734,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getObserverList JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getPbftView( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface // pointer obtained from one thread, and use that pointer in another thread. @@ -736,12 +769,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getPbftView( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getPendingTxSize( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -770,12 +805,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getPendingTxSiz JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSyncStatus( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -804,12 +841,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSyncStatus( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSystemConfigByKey( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jstring jkey, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jkey); // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // data const char* key = env->GetStringUTFChars(jkey, NULL); @@ -841,12 +880,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getSystemConfig JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getTotalTransactionCount( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -875,6 +916,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getTotalTransac JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getGroupPeers( JNIEnv* env, jobject self, jstring jgroup, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group @@ -960,6 +1003,8 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getGroupList( JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getGroupInfo( JNIEnv* env, jobject self, jstring jgroup, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group @@ -1018,12 +1063,14 @@ JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getGroupInfoLis JNIEXPORT void JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcJniObj_getGroupNodeInfo( JNIEnv* env, jobject self, jstring jgroup, jstring jnode, jobject callback) { + CHECK_OBJECT_NOT_NULL_RET_VOID(env, jgroup); + // rpc obj handler void* rpc = bcos_sdk_get_native_pointer(env, self); // group const char* group = env->GetStringUTFChars(jgroup, NULL); // node - const char* node = env->GetStringUTFChars(jnode, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj.cpp index d749e4cb7..10fab0dcd 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj.cpp @@ -121,16 +121,19 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj_sendT JNIEnv* env, jclass, jlong jsdk, jlong jkeypair, jstring jgroup, jstring jnode, jstring jto, jbyteArray jdata, jstring jabi, jint jatti, jstring jextra_data, jobject jcallback) { + CHECK_OBJECT_NOT_NULL(env, jgroup, NULL); + CHECK_OBJECT_NOT_NULL(env, jdata, NULL); + void* sdk = reinterpret_cast(jsdk); void* keypair = reinterpret_cast(jkeypair); const char* group = env->GetStringUTFChars(jgroup, NULL); - const char* node = env->GetStringUTFChars(jnode, NULL); - const char* to = env->GetStringUTFChars(jto, NULL); + const char* node = jnode ? env->GetStringUTFChars(jnode, NULL) : NULL; + const char* to = jto ? env->GetStringUTFChars(jto, NULL) : NULL; jbyte* data = (jbyte*)env->GetByteArrayElements(jdata, 0); jsize len = env->GetArrayLength(jdata); - const char* abi = env->GetStringUTFChars(jabi, NULL); + const char* abi = jabi ? env->GetStringUTFChars(jabi, NULL) : NULL; int attr = jatti; - const char* extra_data = env->GetStringUTFChars(jextra_data, NULL); + const char* extra_data = jextra_data ? env->GetStringUTFChars(jextra_data, NULL) : NULL; // Note: The JNIEnv pointer, passed as the first argument to every native method, can only be // used in the thread with which it is associated. It is wrong to cache the JNIEnv interface @@ -158,6 +161,7 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_rpc_RpcServiceJniObj_sendT if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jtx_hash = env->NewStringUTF(tx_hash); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj.cpp index 5a531bf2d..63403d7a4 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj.cpp @@ -1,6 +1,7 @@ #include "org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj.h" #include "bcos-c-sdk/bcos_sdk_c_error.h" #include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_exception.h" #include @@ -19,6 +20,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createJniKeyPair__I( if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(keypair); @@ -29,9 +31,11 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createJniKeyPair__I( * Method: createHsmKeyPair * Signature: (Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createHsmKeyPair__Ljava_lang_String_2 - (JNIEnv* env, jclass, jstring jhsm_lib_path) - { +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createHsmKeyPair__Ljava_lang_String_2( + JNIEnv* env, jclass, jstring jhsm_lib_path) +{ + CHECK_OBJECT_NOT_NULL(env, jhsm_lib_path, 0); const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); void* keypair = bcos_sdk_create_hsm_keypair(hsm_lib_path); @@ -40,10 +44,11 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJni if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(keypair); - } +} /* * Class: org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj @@ -54,6 +59,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createJniKeyPair__I_3B( JNIEnv* env, jclass, jint jcrypto_type, jbyteArray jdata) { + CHECK_OBJECT_NOT_NULL(env, jdata, 0); int crypto_type = (int)jcrypto_type; jbyte* data = (jbyte*)env->GetByteArrayElements(jdata, 0); jsize len = env->GetArrayLength(jdata); @@ -62,6 +68,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createJniKeyPair__I_ if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(keypair); @@ -72,9 +79,12 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createJniKeyPair__I_ * Method: createHsmKeyPair * Signature: ([BLjava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createHsmKeyPair___3BLjava_lang_String_2 - (JNIEnv* env, jclass, jbyteArray jdata, jstring jhsm_lib_path) +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_createHsmKeyPair___3BLjava_lang_String_2( + JNIEnv* env, jclass, jbyteArray jdata, jstring jhsm_lib_path) { + CHECK_OBJECT_NOT_NULL(env, jhsm_lib_path, 0); + CHECK_OBJECT_NOT_NULL(env, jdata, 0); jbyte* data = (jbyte*)env->GetByteArrayElements(jdata, 0); const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); jsize len = env->GetArrayLength(jdata); @@ -85,6 +95,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJni if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(keypair); @@ -95,12 +106,15 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJni * Method: useHsmKeyPair * Signature: (ILjava/lang/String;Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_useHsmKeyPair - (JNIEnv* env, jclass, jint jkey_index, jstring jpass_word, jstring jhsm_lib_path) +JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_useHsmKeyPair( + JNIEnv* env, jclass, jint jkey_index, jstring jpass_word, jstring jhsm_lib_path) { + CHECK_OBJECT_NOT_NULL(env, jpass_word, 0); + CHECK_OBJECT_NOT_NULL(env, jhsm_lib_path, 0); const char* password = env->GetStringUTFChars(jpass_word, NULL); const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); - void* keypair = bcos_sdk_use_hsm_keypair_by_keyindex_and_password((unsigned int)jkey_index, password, hsm_lib_path); + void* keypair = bcos_sdk_use_hsm_keypair_by_keyindex_and_password( + (unsigned int)jkey_index, password, hsm_lib_path); env->ReleaseStringUTFChars(jpass_word, password); env->ReleaseStringUTFChars(jhsm_lib_path, hsm_lib_path); @@ -108,6 +122,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJni if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(keypair); @@ -128,6 +143,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_getJniKeyPairAddress if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring result = env->NewStringUTF(addr); @@ -150,6 +166,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_getJniKeyPairPubKey( if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring result = env->NewStringUTF(pub); @@ -172,6 +189,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_keypair_KeyPairJniObj_getJniKeyPairPrivate if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring result = env->NewStringUTF(pri); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.cpp index 330920277..8ed9eb8b3 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.cpp @@ -3,6 +3,7 @@ #include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" #include "bcos-c-sdk/bcos_sdk_c_uti_receipt.h" #include "org_fisco_bcos_sdk_exception.h" +#include "org_fisco_bcos_sdk_common.h" #include /* @@ -15,6 +16,10 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_createReceipt jclass, jstring jgas_used, jstring jcontract_address, jstring jout_put, jlong jblock_number) { + CHECK_OBJECT_NOT_NULL(env, jgas_used, 0); + CHECK_OBJECT_NOT_NULL(env, jcontract_address, 0); + CHECK_OBJECT_NOT_NULL(env, jout_put, 0); + // group id const char* gas_used = env->GetStringUTFChars(jgas_used, NULL); // chain id @@ -34,6 +39,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_createReceipt if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(receipt_data); @@ -48,6 +54,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_createReceipt JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_createReceiptDataWithJson (JNIEnv *env, jclass, jstring jjson) { + CHECK_OBJECT_NOT_NULL(env, jjson, 0); const char* json = env->GetStringUTFChars(jjson, NULL); void* receipt_data = bcos_sdk_create_receipt_data_with_json(json); @@ -55,6 +62,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBui if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(receipt_data); @@ -87,6 +95,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_encodeReceipt if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jencoded_receipt_data = env->NewStringUTF(encoded_receipt_data); @@ -108,6 +117,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_encodeReceipt JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_decodeReceiptDataToJsonObj (JNIEnv* env, jclass, jstring jreceipt_bytes) { + CHECK_OBJECT_NOT_NULL(env, jreceipt_bytes, NULL); const char* receipt_data = env->GetStringUTFChars(jreceipt_bytes, NULL); const char* receipt_data_json = bcos_sdk_decode_receipt_data(receipt_data); @@ -115,6 +125,7 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptB if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jreceipt_data_json = env->NewStringUTF(receipt_data_json); @@ -142,6 +153,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_calcReceiptDa if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jreceipt_data_hash = env->NewStringUTF(receipt_data_hash); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.h index bde36c1cd..bdab48722 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj.h @@ -55,6 +55,14 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptB JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_calcReceiptDataHash (JNIEnv *, jclass, jint, jlong); +/* + * Class: org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj + * Method: calcReceiptDataHashWithJson + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_receipt_ReceiptBuilderJniObj_calcReceiptDataHashWithJson + (JNIEnv *, jclass, jint, jstring); + #ifdef __cplusplus } #endif diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.cpp index b7d5319ea..4003b32ae 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.cpp @@ -2,6 +2,7 @@ #include "bcos-c-sdk/bcos_sdk_c_error.h" #include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" #include "bcos-c-sdk/bcos_sdk_c_uti_signature.h" +#include "org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_exception.h" #include @@ -10,26 +11,30 @@ * Method: sign * Signature: (JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jbyteArray JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj_sign - (JNIEnv* env, jclass, jlong jkeypair, jstring jtx_data_hash, jstring jhsm_lib_path) +JNIEXPORT jbyteArray JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj_sign( + JNIEnv* env, jclass, jlong jkeypair, jstring jtx_data_hash, jstring jhsm_lib_path) { - const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); - const char* tx_data_hash = env->GetStringUTFChars(jtx_data_hash, NULL); - void* keypair = reinterpret_cast(jkeypair); - struct bcos_sdk_c_signature_result sign_result = bcos_sdk_sign(keypair, tx_data_hash, hsm_lib_path); + CHECK_OBJECT_NOT_NULL(env, jtx_data_hash, NULL); + CHECK_OBJECT_NOT_NULL(env, jhsm_lib_path, NULL); + const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); + const char* tx_data_hash = env->GetStringUTFChars(jtx_data_hash, NULL); + void* keypair = reinterpret_cast(jkeypair); + struct bcos_sdk_c_signature_result sign_result = + bcos_sdk_sign(keypair, tx_data_hash, hsm_lib_path); - env->ReleaseStringUTFChars(jhsm_lib_path, hsm_lib_path); - env->ReleaseStringUTFChars(jtx_data_hash, tx_data_hash); + env->ReleaseStringUTFChars(jhsm_lib_path, hsm_lib_path); + env->ReleaseStringUTFChars(jtx_data_hash, tx_data_hash); - int operation_status = bcos_sdk_get_last_error(); - if (operation_status == -1) - { + int operation_status = bcos_sdk_get_last_error(); + if (operation_status == -1) + { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); - } + return NULL; + } - jbyte *signed_data_r = (jbyte*)sign_result.r; - jbyte *signed_data_s = (jbyte*)sign_result.s; - jbyte *signed_data_v = (jbyte*)sign_result.v; + jbyte* signed_data_r = (jbyte*)sign_result.r; + jbyte* signed_data_s = (jbyte*)sign_result.s; + jbyte* signed_data_v = (jbyte*)sign_result.v; jbyteArray jsigned_data = env->NewByteArray(576); env->SetByteArrayRegion(jsigned_data, 0, 32, signed_data_r); env->SetByteArrayRegion(jsigned_data, 32, 32, signed_data_s); @@ -43,10 +48,15 @@ JNIEXPORT jbyteArray JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_Sig * Method: verify * Signature: (I[BLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z */ -JNIEXPORT jboolean JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj_verify - (JNIEnv* env, jclass, jint jcrypto_type, jbyteArray jpub_key, jstring jtx_data_hash, jstring jsigned_data, - jstring jhsm_lib_path) +JNIEXPORT jboolean JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj_verify( + JNIEnv* env, jclass, jint jcrypto_type, jbyteArray jpub_key, jstring jtx_data_hash, + jstring jsigned_data, jstring jhsm_lib_path) { + CHECK_OBJECT_NOT_NULL(env, jpub_key, false); + CHECK_OBJECT_NOT_NULL(env, jtx_data_hash, false); + CHECK_OBJECT_NOT_NULL(env, jsigned_data, false); + CHECK_OBJECT_NOT_NULL(env, jhsm_lib_path, false); + int crypto_type = (int)jcrypto_type; jbyte* public_key = (jbyte*)env->GetByteArrayElements(jpub_key, 0); jsize pubkey_len = env->GetArrayLength(jpub_key); @@ -55,8 +65,8 @@ JNIEXPORT jboolean JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_Signa jsize signed_data_len = strlen(signed_data); const char* hsm_lib_path = env->GetStringUTFChars(jhsm_lib_path, NULL); - bool is_verify_success = bcos_sdk_verify(crypto_type, (void*)public_key, pubkey_len, tx_data_hash, - (void*)signed_data, signed_data_len, hsm_lib_path); + bool is_verify_success = bcos_sdk_verify(crypto_type, (void*)public_key, pubkey_len, + tx_data_hash, (void*)signed_data, signed_data_len, hsm_lib_path); env->ReleaseStringUTFChars(jtx_data_hash, tx_data_hash); env->ReleaseStringUTFChars(jsigned_data, signed_data); @@ -64,6 +74,7 @@ JNIEXPORT jboolean JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_Signa if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return JNI_FALSE; } return is_verify_success ? JNI_TRUE : JNI_FALSE; diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.h index 29c7bf6b2..b261e9a02 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj.h @@ -10,7 +10,7 @@ extern "C" { /* * Class: org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj * Method: sign - * Signature: (JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String; + * Signature: (JLjava/lang/String;Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_org_fisco_bcos_sdk_jni_utilities_signature_SignatureJniObj_sign (JNIEnv *, jclass, jlong, jstring, jstring); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.cpp index bf1eb7492..425d3ad8b 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.cpp +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.cpp @@ -2,6 +2,7 @@ #include "bcos-c-sdk/bcos_sdk_c_error.h" #include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" #include "bcos-c-sdk/bcos_sdk_c_uti_tx.h" +#include "org_fisco_bcos_sdk_common.h" #include "org_fisco_bcos_sdk_exception.h" #include @@ -16,16 +17,20 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransact jclass, jstring jgroup_id, jstring jchain_id, jstring jto, jstring jdata, jstring jabi, jlong jblock_limit) { + CHECK_OBJECT_NOT_NULL(env, jgroup_id, 0); + CHECK_OBJECT_NOT_NULL(env, jchain_id, 0); + CHECK_OBJECT_NOT_NULL(env, jdata, 0); + // group id const char* group_id = env->GetStringUTFChars(jgroup_id, NULL); // chain id const char* chain_id = env->GetStringUTFChars(jchain_id, NULL); - // code - const char* to = env->GetStringUTFChars(jto, NULL); + // to + const char* to = (jto == NULL) ? NULL : env->GetStringUTFChars(jto, NULL); // data const char* data = env->GetStringUTFChars(jdata, NULL); // abi - const char* abi = env->GetStringUTFChars(jabi, NULL); + const char* abi = (jabi == NULL) ? NULL : env->GetStringUTFChars(jabi, NULL); // block limit int64_t block_limit = (int64_t)jblock_limit; @@ -41,6 +46,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransact if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(transaction_data); @@ -55,6 +61,7 @@ JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransactionDataWithJson( JNIEnv* env, jclass, jstring jjson) { + CHECK_OBJECT_NOT_NULL(env, jjson, 0); const char* json = env->GetStringUTFChars(jjson, NULL); void* transaction_data = bcos_sdk_create_transaction_data_with_json(json); @@ -62,6 +69,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransact if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; } return reinterpret_cast(transaction_data); @@ -97,6 +105,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_encodeTransact if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jencoded_transaction_data = env->NewStringUTF(encoded_transaction_data); @@ -119,6 +128,8 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransactionDataToJsonObj( JNIEnv* env, jclass, jstring jtransaction_bytes) { + CHECK_OBJECT_NOT_NULL(env, jtransaction_bytes, NULL); + const char* transaction_data = env->GetStringUTFChars(jtransaction_bytes, NULL); const char* transaction_data_json = bcos_sdk_decode_transaction_data(transaction_data); @@ -126,6 +137,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransact if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jtransaction_data_json = env->NewStringUTF(transaction_data_json); @@ -153,6 +165,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_calcTransactio if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jtransaction_data_hash = env->NewStringUTF(transaction_data_hash); @@ -166,6 +179,67 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_calcTransactio return jtransaction_data_hash; } +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: decodeTransaction + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransaction( + JNIEnv* env, jclass, jstring jtransaction_bytes) +{ + CHECK_OBJECT_NOT_NULL(env, jtransaction_bytes, 0); + const char* transaction = env->GetStringUTFChars(jtransaction_bytes, NULL); + void* transaction_data = bcos_sdk_decode_transaction(transaction); + env->ReleaseStringUTFChars(jtransaction_bytes, transaction); + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; + } + return reinterpret_cast(transaction_data); +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: decodeTransactionToJsonObj + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransactionToJsonObj( + JNIEnv* env, jclass, jstring jtransaction_bytes) +{ + CHECK_OBJECT_NOT_NULL(env, jtransaction_bytes, NULL); + const char* transaction = env->GetStringUTFChars(jtransaction_bytes, NULL); + const char* transaction_json = bcos_sdk_decode_transaction_to_json_obj(transaction); + env->ReleaseStringUTFChars(jtransaction_bytes, transaction); + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + jstring jtransaction_json = env->NewStringUTF(transaction_json); + if (transaction_json) + { + free((void*)transaction_json); + transaction_json = NULL; + } + return jtransaction_json; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: destroyTransaction + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_destroyTransaction( + JNIEnv*, jclass, jlong jtransaction) +{ + void* transaction = reinterpret_cast(jtransaction); + bcos_sdk_destroy_transaction(transaction); +} + /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj * Method: signTransactionDataHash @@ -175,7 +249,8 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_signTransactionDataHash( JNIEnv* env, jclass, jlong jkeypair, jstring jtransaction_data_hash) { - // + CHECK_OBJECT_NOT_NULL(env, jtransaction_data_hash, NULL); + void* keypair = reinterpret_cast(jkeypair); // transaction_data_hash const char* transaction_data_hash = env->GetStringUTFChars(jtransaction_data_hash, NULL); @@ -187,6 +262,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_signTransactio if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jsigned_data = env->NewStringUTF(signed_data); @@ -210,6 +286,8 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr JNIEnv* env, jclass, jlong jtransaction_data, jstring jtransaction_data_signed_data, jstring jtransaction_data_hash, jint jattr) { + CHECK_OBJECT_NOT_NULL(env, jtransaction_data_signed_data, NULL); + CHECK_OBJECT_NOT_NULL(env, jtransaction_data_hash, NULL); void* transaction_data = reinterpret_cast(jtransaction_data); const char* transaction_data_signed_data = @@ -227,6 +305,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jsigned_tx = env->NewStringUTF(signed_tx); @@ -250,6 +329,10 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr JNIEnv* env, jclass, jlong jtransaction_data, jstring jtransaction_data_signed_data, jstring jtransaction_data_hash, jint jattr, jstring jextra_data) { + CHECK_OBJECT_NOT_NULL(env, jtransaction_data_signed_data, NULL); + CHECK_OBJECT_NOT_NULL(env, jtransaction_data_hash, NULL); + CHECK_OBJECT_NOT_NULL(env, jextra_data, NULL); + void* transaction_data = reinterpret_cast(jtransaction_data); const char* transaction_data_signed_data = @@ -269,6 +352,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jsigned_tx = env->NewStringUTF(signed_tx); @@ -293,6 +377,10 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr JNIEnv* env, jclass, jlong jkeypair, jstring jgroup_id, jstring jchain_id, jstring jto, jstring jdata, jstring jabi, jlong jblock_limit, jint jattr) { + CHECK_OBJECT_NOT_NULL(env, jgroup_id, NULL); + CHECK_OBJECT_NOT_NULL(env, jchain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, jdata, NULL); + // keypair void* keypair = reinterpret_cast(jkeypair); // group id @@ -300,11 +388,11 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr // chain id const char* chain_id = env->GetStringUTFChars(jchain_id, NULL); // to - const char* to = env->GetStringUTFChars(jto, NULL); + const char* to = jto ? env->GetStringUTFChars(jto, NULL) : NULL; // data const char* data = env->GetStringUTFChars(jdata, NULL); // abi - const char* abi = env->GetStringUTFChars(jabi, NULL); + const char* abi = jabi ? env->GetStringUTFChars(jabi, NULL) : NULL; // block limit int64_t block_limit = (int64_t)jblock_limit; // attr @@ -317,6 +405,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jtx_hash = env->NewStringUTF(tx_hash); @@ -375,6 +464,10 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr JNIEnv* env, jclass, jlong jkeypair, jstring jgroup_id, jstring jchain_id, jstring jto, jstring jdata, jstring jabi, jlong jblock_limit, jint jattr, jstring jextra_data) { + CHECK_OBJECT_NOT_NULL(env, jgroup_id, NULL); + CHECK_OBJECT_NOT_NULL(env, jchain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, jdata, NULL); + // keypair void* keypair = reinterpret_cast(jkeypair); // group id @@ -382,17 +475,17 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr // chain id const char* chain_id = env->GetStringUTFChars(jchain_id, NULL); // to - const char* to = env->GetStringUTFChars(jto, NULL); + const char* to = jto ? env->GetStringUTFChars(jto, NULL) : NULL; // data const char* data = env->GetStringUTFChars(jdata, NULL); // abi - const char* abi = env->GetStringUTFChars(jabi, NULL); + const char* abi = jabi ? env->GetStringUTFChars(jabi, NULL) : NULL; // block limit int64_t block_limit = (int64_t)jblock_limit; // attr int attr = (int64_t)jattr; // extra data - const char* extra_data = env->GetStringUTFChars(jextra_data, NULL); + const char* extra_data = jextra_data ? env->GetStringUTFChars(jextra_data, NULL) : NULL; char* tx_hash = NULL; char* signed_tx = NULL; @@ -401,6 +494,7 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createSignedTr if (!bcos_sdk_is_last_opr_success()) { THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; } jstring jtx_hash = env->NewStringUTF(tx_hash); diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.h index 9d584ddf5..cfff3a83f 100644 --- a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.h +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj.h @@ -22,8 +22,9 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransact * Method: createTransactionDataWithJson * Signature: (Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransactionDataWithJson - (JNIEnv *, jclass, jstring); +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_createTransactionDataWithJson( + JNIEnv*, jclass, jstring); /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj @@ -48,8 +49,9 @@ Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_encodeTransact * Method: decodeTransactionDataToJsonObj * Signature: (Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransactionDataToJsonObj - (JNIEnv *, jclass, jstring); +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransactionDataToJsonObj( + JNIEnv*, jclass, jstring); /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj @@ -60,6 +62,33 @@ JNIEXPORT jstring JNICALL Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_calcTransactionDataHash( JNIEnv*, jclass, jint, jlong); +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: decodeTransaction + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransaction( + JNIEnv*, jclass, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: decodeTransactionToJsonObj + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_decodeTransactionToJsonObj( + JNIEnv*, jclass, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj + * Method: destroyTransaction + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj_destroyTransaction( + JNIEnv*, jclass, jlong); + /* * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderJniObj * Method: signTransactionDataHash diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.cpp b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.cpp new file mode 100644 index 000000000..d8e9283ae --- /dev/null +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.cpp @@ -0,0 +1,503 @@ +/** + * Copyright (C) 2022 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.cpp + * @author: kyonGuo + * @date 2023/11/29 + */ + +#include "org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx_v1.h" +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "org_fisco_bcos_sdk_common.h" +#include + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createTransactionData + * Signature: + * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createTransactionData( + JNIEnv* env, jclass, jstring j_group_id, jstring j_chain_id, jstring j_to, jstring j_nonce, + jbyteArray j_input, jstring j_abi, jlong j_block_limit, jstring j_value, jstring j_gas_price, + jlong j_gas_limit) +{ + CHECK_OBJECT_NOT_NULL(env, j_group_id, 0); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, 0); + CHECK_OBJECT_NOT_NULL(env, j_input, 0); + + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* gas_price = GET_J_STRING_CONTENT_DEF(env, j_gas_price, NULL); + const char* nonce = GET_J_STRING_CONTENT_DEF(env, j_nonce, NULL); + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + void* transaction_data = bcos_sdk_create_transaction_v1_data(group_id, chain_id, to, nonce, + reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_price, gas_limit); + + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_gas_price, gas_price); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; + } + + return reinterpret_cast(transaction_data); +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createEIP1559TransactionData + * Signature: + * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;JLjava/lang/String;Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createEIP1559TransactionData( + JNIEnv* env, jclass, jstring j_group_id, jstring j_chain_id, jstring j_to, jstring j_nonce, + jbyteArray j_input, jstring j_abi, jlong j_block_limit, jstring j_value, jlong j_gas_limit, + jstring j_max_fee_per_gas, jstring j_max_priority_fee_per_gas) +{ + CHECK_OBJECT_NOT_NULL(env, j_group_id, 0); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, 0); + CHECK_OBJECT_NOT_NULL(env, j_input, 0); + + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* nonce = GET_J_STRING_CONTENT_DEF(env, j_nonce, NULL); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* max_fee_per_gas = GET_J_STRING_CONTENT_DEF(env, j_max_fee_per_gas, NULL); + const char* max_priority_fee_per_gas = + GET_J_STRING_CONTENT_DEF(env, j_max_priority_fee_per_gas, NULL); + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + void* transaction_data = bcos_sdk_create_eip1559_transaction_data(group_id, chain_id, to, nonce, + reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_limit, max_fee_per_gas, max_priority_fee_per_gas); + + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_max_fee_per_gas, max_fee_per_gas); + env->ReleaseStringUTFChars(j_max_priority_fee_per_gas, max_priority_fee_per_gas); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return 0; + } + + return reinterpret_cast(transaction_data); +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: calcTransactionDataHashWithFullFields + * Signature: + * (ILorg/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_calcTransactionDataHashWithFullFields( + JNIEnv* env, jclass, jint j_crypto_type, jobject j_tx_version, jstring j_group_id, + jstring j_chain_id, jstring j_to, jstring j_nonce, jbyteArray j_input, jstring j_abi, + jlong j_block_limit, jstring j_value, jstring j_gasPrice, jlong j_gas_limit, + jstring j_max_fee_per_gas, jstring j_max_priority_fee_per_gas) +{ + CHECK_OBJECT_NOT_NULL(env, j_group_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_input, NULL); + CHECK_OBJECT_NOT_NULL(env, j_nonce, NULL); + + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* nonce = GET_J_STRING_CONTENT(env, j_nonce); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* gas_price = GET_J_STRING_CONTENT_DEF(env, j_gasPrice, NULL); + const char* max_fee_per_gas = GET_J_STRING_CONTENT_DEF(env, j_max_fee_per_gas, NULL); + const char* max_priority_fee_per_gas = + GET_J_STRING_CONTENT_DEF(env, j_max_priority_fee_per_gas, NULL); + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + int crypto_type = j_crypto_type; + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + + jclass tx_version = env->GetObjectClass(j_tx_version); + jmethodID j_methodId = env->GetMethodID(tx_version, "getValue", "()I"); + int32_t ver = env->CallIntMethod(j_tx_version, j_methodId); + + const char* tx_hash = bcos_sdk_calc_transaction_data_hash_with_full_fields(crypto_type, + (transaction_version)ver, group_id, chain_id, to, nonce, + reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_price, gas_limit, max_fee_per_gas, max_priority_fee_per_gas); + + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_gasPrice, gas_price); + env->ReleaseStringUTFChars(j_max_fee_per_gas, max_fee_per_gas); + env->ReleaseStringUTFChars(j_max_priority_fee_per_gas, max_priority_fee_per_gas); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + + jstring j_transaction_data_hash = env->NewStringUTF(tx_hash); + + if (tx_hash) + { + free((void*)tx_hash); + tx_hash = NULL; + } + + return j_transaction_data_hash; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: calcTransactionDataHashWithJson + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_calcTransactionDataHashWithJson( + JNIEnv* env, jclass, jint j_crypto_type, jstring j_json) +{ + CHECK_OBJECT_NOT_NULL(env, j_json, NULL); + const char* json = env->GetStringUTFChars(j_json, NULL); + int crypto_type = (int)j_crypto_type; + + const char* tx_hash = bcos_sdk_calc_transaction_data_hash_with_json(crypto_type, json); + + env->ReleaseStringUTFChars(j_json, json); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + + jstring j_transaction_data_hash = env->NewStringUTF(tx_hash); + + if (tx_hash) + { + free((void*)tx_hash); + tx_hash = NULL; + } + + return j_transaction_data_hash; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedTransactionWithSignature + * Signature: + * ([BLjava/lang/String;Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedTransactionWithSignature( + JNIEnv* env, jclass, jbyteArray j_signature, jstring j_tx_hash, jobject j_tx_version, + jstring j_group_id, jstring j_chain_id, jstring j_to, jstring j_nonce, jbyteArray j_input, + jstring j_abi, jlong j_block_limit, jstring j_value, jstring j_gas_price, jlong j_gas_limit, + jstring j_max_fee_per_gas, jstring j_max_priority_fee_per_gas, jint j_attribute, + jstring j_extra_data) +{ + CHECK_OBJECT_NOT_NULL(env, j_signature, NULL); + CHECK_OBJECT_NOT_NULL(env, j_tx_hash, NULL); + CHECK_OBJECT_NOT_NULL(env, j_group_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_input, NULL); + CHECK_OBJECT_NOT_NULL(env, j_nonce, NULL); + + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + int32_t attribute = j_attribute; + const char* tx_hash = GET_J_STRING_CONTENT(env, j_tx_hash); + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* nonce = GET_J_STRING_CONTENT(env, j_nonce); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* gas_price = GET_J_STRING_CONTENT_DEF(env, j_gas_price, NULL); + const char* max_fee_per_gas = GET_J_STRING_CONTENT_DEF(env, j_max_fee_per_gas, NULL); + const char* max_priority_fee_per_gas = + GET_J_STRING_CONTENT_DEF(env, j_max_priority_fee_per_gas, NULL); + const char* extra_data = GET_J_STRING_CONTENT_DEF(env, j_extra_data, NULL); + jbyte* signBuffer = env->GetByteArrayElements(j_signature, NULL); + jsize signSize = env->GetArrayLength(j_signature); + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + jclass tx_version = env->GetObjectClass(j_tx_version); + jmethodID j_methodId = env->GetMethodID(tx_version, "getValue", "()I"); + int32_t ver = env->CallIntMethod(j_tx_version, j_methodId); + + const char* encodedTx = bcos_sdk_create_signed_transaction_with_signature( + reinterpret_cast(signBuffer), signSize, tx_hash, + static_cast(ver), group_id, chain_id, to, nonce, + reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_price, gas_limit, max_fee_per_gas, max_priority_fee_per_gas, attribute, extra_data); + + env->ReleaseStringUTFChars(j_tx_hash, tx_hash); + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_gas_price, gas_price); + env->ReleaseStringUTFChars(j_max_fee_per_gas, max_fee_per_gas); + env->ReleaseStringUTFChars(j_max_priority_fee_per_gas, max_priority_fee_per_gas); + env->ReleaseStringUTFChars(j_extra_data, extra_data); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + env->ReleaseByteArrayElements(j_signature, signBuffer, 0); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + + jstring encoded_tx_hex = env->NewStringUTF(encodedTx); + + if (encodedTx) + { + free((void*)encodedTx); + encodedTx = NULL; + } + + return encoded_tx_hex; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedTransactionWithFullFields + * Signature: + * (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JILjava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TxPair; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedTransactionWithFullFields( + JNIEnv* env, jclass, jlong j_key_pair, jstring j_group_id, jstring j_chain_id, jstring j_to, + jstring j_nonce, jbyteArray j_input, jstring j_abi, jlong j_block_limit, jstring j_value, + jstring j_gas_price, jlong j_gas_limit, jint j_attribute, jstring j_extra_data) +{ + CHECK_OBJECT_NOT_NULL(env, j_group_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_input, NULL); + + void* keypair = reinterpret_cast(j_key_pair); + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + int32_t attribute = j_attribute; + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* nonce = GET_J_STRING_CONTENT_DEF(env, j_nonce, NULL); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* gas_price = GET_J_STRING_CONTENT_DEF(env, j_gas_price, NULL); + const char* extra_data = GET_J_STRING_CONTENT_DEF(env, j_extra_data, NULL); + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + char* tx_hash = NULL; + char* signed_tx = NULL; + bcos_sdk_create_signed_transaction_with_full_fields(keypair, group_id, chain_id, to, nonce, + reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_price, gas_limit, attribute, extra_data, &tx_hash, &signed_tx); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + + jstring j_tx_hash = env->NewStringUTF(tx_hash); + jstring j_signed_tx = env->NewStringUTF(signed_tx); + + jclass j_txpair = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TxPair"); + if (j_txpair == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/TxPair"); + } + jmethodID txpair_mtd = + env->GetMethodID(j_txpair, "", "(Ljava/lang/String;Ljava/lang/String;)V"); + if (txpair_mtd == NULL) + { + env->FatalError("No such constructor in TxPair, constructor(String, String)"); + } + + jobject txpair = env->NewObject(j_txpair, txpair_mtd, j_tx_hash, j_signed_tx); + + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_gas_price, gas_price); + env->ReleaseStringUTFChars(j_extra_data, extra_data); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + + env->DeleteLocalRef(j_tx_hash); + env->DeleteLocalRef(j_signed_tx); + + if (tx_hash) + { + free((void*)tx_hash); + tx_hash = NULL; + } + + if (signed_tx) + { + free((void*)signed_tx); + signed_tx = NULL; + } + + return txpair; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedEIP1559TransactionWithFullFields + * Signature: + * (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JILjava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TxPair; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedEIP1559TransactionWithFullFields( + JNIEnv* env, jclass, jlong j_key_pair, jstring j_group_id, jstring j_chain_id, jstring j_to, + jstring j_nonce, jbyteArray j_input, jstring j_abi, jlong j_block_limit, jstring j_value, + jstring j_max_fee_per_gas, jstring j_max_priority_fee_per_gas, jlong j_gas_limit, + jint j_attribute, jstring j_extra_data) +{ + CHECK_OBJECT_NOT_NULL(env, j_group_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_chain_id, NULL); + CHECK_OBJECT_NOT_NULL(env, j_input, NULL); + + void* keypair = reinterpret_cast(j_key_pair); + int64_t block_limit = j_block_limit; + int64_t gas_limit = j_gas_limit; + int32_t attribute = j_attribute; + const char* group_id = GET_J_STRING_CONTENT(env, j_group_id); + const char* chain_id = GET_J_STRING_CONTENT(env, j_chain_id); + const char* to = GET_J_STRING_CONTENT_DEF(env, j_to, NULL); + const char* nonce = GET_J_STRING_CONTENT_DEF(env, j_nonce, NULL); + const char* abi = GET_J_STRING_CONTENT_DEF(env, j_abi, NULL); + const char* value = GET_J_STRING_CONTENT_DEF(env, j_value, NULL); + const char* max_fee_per_gas = GET_J_STRING_CONTENT_DEF(env, j_max_fee_per_gas, NULL); + const char* max_priority_fee_per_gas = + GET_J_STRING_CONTENT_DEF(env, j_max_priority_fee_per_gas, NULL); + const char* extra_data = GET_J_STRING_CONTENT_DEF(env, j_extra_data, NULL); + jbyte* inputBuffer = env->GetByteArrayElements(j_input, NULL); + jsize inputSize = env->GetArrayLength(j_input); + + char* tx_hash = NULL; + char* signed_tx = NULL; + bcos_sdk_create_signed_eip1559_transaction_with_full_fields(keypair, group_id, chain_id, to, + nonce, reinterpret_cast(inputBuffer), inputSize, abi, block_limit, value, + gas_limit, max_fee_per_gas, max_priority_fee_per_gas, attribute, extra_data, &tx_hash, + &signed_tx); + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return NULL; + } + + jstring j_tx_hash = env->NewStringUTF(tx_hash); + jstring j_signed_tx = env->NewStringUTF(signed_tx); + + jclass j_txpair = env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TxPair"); + if (j_txpair == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/TxPair"); + } + jmethodID txpair_mtd = + env->GetMethodID(j_txpair, "", "(Ljava/lang/String;Ljava/lang/String;)V"); + if (txpair_mtd == NULL) + { + env->FatalError("No such constructor in TxPair, constructor(String, String)"); + } + + jobject txpair = env->NewObject(j_txpair, txpair_mtd, j_tx_hash, j_signed_tx); + + env->ReleaseStringUTFChars(j_group_id, group_id); + env->ReleaseStringUTFChars(j_chain_id, chain_id); + env->ReleaseStringUTFChars(j_to, to); + env->ReleaseStringUTFChars(j_nonce, nonce); + env->ReleaseStringUTFChars(j_abi, abi); + env->ReleaseStringUTFChars(j_value, value); + env->ReleaseStringUTFChars(j_max_fee_per_gas, max_fee_per_gas); + env->ReleaseStringUTFChars(j_max_priority_fee_per_gas, max_priority_fee_per_gas); + env->ReleaseStringUTFChars(j_extra_data, extra_data); + env->ReleaseByteArrayElements(j_input, inputBuffer, 0); + + env->DeleteLocalRef(j_tx_hash); + env->DeleteLocalRef(j_signed_tx); + + if (tx_hash) + { + free((void*)tx_hash); + tx_hash = NULL; + } + + if (signed_tx) + { + free((void*)signed_tx); + signed_tx = NULL; + } + + return txpair; +} diff --git a/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.h b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.h new file mode 100644 index 000000000..bd74d5402 --- /dev/null +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj.h @@ -0,0 +1,88 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj */ + +#ifndef _Included_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj +#define _Included_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createTransactionData + * Signature: + * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createTransactionData(JNIEnv*, + jclass, jstring, jstring, jstring, jstring, jbyteArray, jstring, jlong, jstring, jstring, + jlong); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createEIP1559TransactionData + * Signature: + * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;JLjava/lang/String;Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createEIP1559TransactionData( + JNIEnv*, jclass, jstring, jstring, jstring, jstring, jbyteArray, jstring, jlong, jstring, jlong, + jstring, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: calcTransactionDataHashWithFullFields + * Signature: + * (ILorg/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_calcTransactionDataHashWithFullFields( + JNIEnv*, jclass, jint, jobject, jstring, jstring, jstring, jstring, jbyteArray, jstring, jlong, + jstring, jstring, jlong, jstring, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: calcTransactionDataHashWithJson + * Signature: (ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_calcTransactionDataHashWithJson( + JNIEnv*, jclass, jint, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedTransactionWithSignature + * Signature: + * ([BLjava/lang/String;Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedTransactionWithSignature( + JNIEnv*, jclass, jbyteArray, jstring, jobject, jstring, jstring, jstring, jstring, jbyteArray, + jstring, jlong, jstring, jstring, jlong, jstring, jstring, jint, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedTransactionWithFullFields + * Signature: + * (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;JILjava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TxPair; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedTransactionWithFullFields( + JNIEnv*, jclass, jlong, jstring, jstring, jstring, jstring, jbyteArray, jstring, jlong, jstring, + jstring, jlong, jint, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj + * Method: createSignedEIP1559TransactionWithFullFields + * Signature: + * (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JILjava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TxPair; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionBuilderV1JniObj_createSignedEIP1559TransactionWithFullFields( + JNIEnv*, jclass, jlong, jstring, jstring, jstring, jstring, jbyteArray, jstring, jlong, jstring, + jstring, jstring, jlong, jint, jstring); + +#ifdef __cplusplus +} +#endif +#endif 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 new file mode 100644 index 000000000..a3ad6e6ba --- /dev/null +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.cpp @@ -0,0 +1,1296 @@ +#include "org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h" +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h" +#include "org_fisco_bcos_sdk_common.h" +#include "org_fisco_bcos_sdk_exception.h" + + +// tx data v1: java obj => c struct +struct bcos_sdk_c_transaction_data_v1* convert_to_tx_v1_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; + } + + jclass txDataClass = env->GetObjectClass(transactionObject); + + bcos_sdk_c_transaction_data_v1* tx_data_struct = (struct bcos_sdk_c_transaction_data_v1*)malloc( + sizeof(struct bcos_sdk_c_transaction_data_v1)); + // 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) +{ + if (transactionObject == 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 = 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 + 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; +} + +// tx data: c struct => java obj +jobject convert_to_tx_data_jobject( + JNIEnv* env, const struct bcos_sdk_c_transaction_data* transactionData) +{ + if (transactionData == 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)); + + 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; +} + +// tx data v1: c struct => java obj +jobject convert_to_tx_v1_data_jobject( + JNIEnv* env, const struct bcos_sdk_c_transaction_data_v1* transactionData) +{ + if (transactionData == 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/TransactionDataV1"); + if (txDataClass == NULL) + { + env->FatalError( + "No such class, className: " + "org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1"); + } + 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 + 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) +{ + 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_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) + { + 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); + } + } + // Signature byte[] + { + if (tx_struct->signature != 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); + } + } + // Sender byte[] + { + if (tx_struct->sender != 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); + } + } + // 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 v1: c struct => java obj +jobject convert_to_tx_v1_jobject(JNIEnv* env, const struct bcos_sdk_c_transaction_v1* 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_v1_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) + { + 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); + } + } + // Signature byte[] + { + if (tx_struct->signature) + { + 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); + } + } + // Sender byte[] + { + 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) +{ + 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) + { + 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; +} + +// tx v1: java obj => c struct +struct bcos_sdk_c_transaction_v1* convert_to_tx_v1_struct(JNIEnv* env, jobject jTxObj) +{ + 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_v1* txStruct = + (struct bcos_sdk_c_transaction_v1*)malloc(sizeof(struct bcos_sdk_c_transaction_v1)); + // TransactionData + jobject javaTxDataObj = env->GetObjectField(jTxObj, transactionDataField); + struct bcos_sdk_c_transaction_data_v1* txDataStruct = + convert_to_tx_v1_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; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionDataStruct + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStruct( + JNIEnv* env, jclass, jobject jTransactionDataObj) +{ + if (jTransactionDataObj == NULL) + { + 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/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v1* tx_data_struct = + convert_to_tx_v1_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_v1(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v1(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); + } + } + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jstring jTxDataHex = env->NewStringUTF(tx_data_hex); + + if (tx_data_hex) + { + free((void*)tx_data_hex); + tx_data_hex = NULL; + } + + + return jTxDataHex; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionDataStructToJson + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStructToJson( + JNIEnv* env, jclass, jobject jTransactionDataObj) +{ + if (jTransactionDataObj == NULL) + { + 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/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v1* tx_data_struct = + convert_to_tx_v1_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_v1(tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v1(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); + } + } + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jstring jTxDataJson = env->NewStringUTF(tx_data_json); + + if (tx_data_json) + { + free((void*)tx_data_json); + tx_data_json = NULL; + } + + return jTxDataJson; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionDataStruct + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStruct( + 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* tx_data_struct = + bcos_sdk_decode_transaction_data_struct_from_hex(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_data_jobject(env, tx_data_struct); + if (jTxDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_data_jobject"); + return nullptr; + } + + // release source + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct(tx_data_struct); + } + env->ReleaseStringUTFChars(jTxDataHexStr, tx_data_hex_str); + + return jTxDataObj; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionDataStructv1 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStructV1( + 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_v1* tx_data_struct_v1 = + bcos_sdk_decode_transaction_data_struct_from_hex_v1(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_v1_data_jobject(env, tx_data_struct_v1); + if (jTxDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_v1_data_jobject"); + return nullptr; + } + + // release source + if (tx_data_struct_v1) + { + bcos_sdk_destroy_transaction_data_struct_v1(tx_data_struct_v1); + } + env->ReleaseStringUTFChars(jTxDataHexStr, tx_data_hex_str); + + return jTxDataObj; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: calcTransactionDataStructHash + * Signature: (ILorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_calcTransactionDataStructHash( + JNIEnv* env, jclass, jint jCrytpTyte, jobject jTransactionDataObj) +{ + if (jTransactionDataObj == NULL) + { + THROW_JNI_EXCEPTION(env, "transactionDataObject is nullptr"); + return NULL; + } + const char* tx_data_hash = nullptr; + int crypto_type = jCrytpTyte; + if (env->IsInstanceOf(jTransactionDataObj, + env->FindClass("org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v1* tx_data_struct = + convert_to_tx_v1_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_v1(crypto_type, tx_data_struct); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v1(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()); + return nullptr; + } + + jstring jTxDataHash = env->NewStringUTF(tx_data_hash); + + // release source + if (tx_data_hash) + { + free((void*)tx_data_hash); + tx_data_hash = NULL; + } + + return jTxDataHash; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: createEncodedTransaction + * Signature: + * (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_createEncodedTransaction( + JNIEnv* env, jclass, jobject jTxDataObj, jstring jSignature, jstring jTxDataHash, + jint jAttribute, jstring 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); + + 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/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_data_v1* tx_data_struct = + convert_to_tx_v1_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_v1( + tx_data_struct, signature, tx_data_hash, attribute, extra_data); + if (tx_data_struct) + { + bcos_sdk_destroy_transaction_data_struct_v1(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); + } + } + + + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jstring jTxStr = env->NewStringUTF(tx_str); + + // release resource + env->ReleaseStringUTFChars(jSignature, signature); + env->ReleaseStringUTFChars(jTxDataHash, tx_data_hash); + env->ReleaseStringUTFChars(jExtraData, extra_data); + if (tx_str) + { + free((void*)tx_str); + tx_str = NULL; + } + + return jTxStr; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionStruct + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStruct( + JNIEnv* env, jclass, jobject jTransactionObj) +{ + 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/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_v1* tx_struct = convert_to_tx_v1_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_v1(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct_v1(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); + } + } + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jstring jTxHex = env->NewStringUTF(tx_hex); + + // release source + if (tx_hex) + { + free((void*)tx_hex); + tx_hex = NULL; + } + + return jTxHex; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionStructToJson + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStructToJson( + JNIEnv* env, jclass, jobject jTransactionObj) +{ + 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/TransactionDataV1")) == JNI_TRUE) + { + bcos_sdk_c_transaction_v1* tx_struct = convert_to_tx_v1_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_v1(tx_struct); + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct_v1(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); + } + } + if (!bcos_sdk_is_last_opr_success()) + { + THROW_JNI_EXCEPTION(env, bcos_sdk_get_last_error_msg()); + return nullptr; + } + + jstring jTxJson = env->NewStringUTF(tx_json); + + if (tx_json) + { + free((void*)tx_json); + tx_json = NULL; + } + + return jTxJson; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionStruct + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStruct( + 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* tx_struct = + bcos_sdk_decode_transaction_struct_from_hex(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_jobject(env, tx_struct); + if (jTxObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_jobject"); + return nullptr; + } + + // release source + if (tx_struct) + { + bcos_sdk_destroy_transaction_struct(tx_struct); + } + env->ReleaseStringUTFChars(jTxHexStr, tx_hex_str); + + return jTxObj; +} + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionStructv1 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/Transactionv1; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStructV1( + 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_v1* tx_struct_v1 = + bcos_sdk_decode_transaction_struct_from_hex_v1(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_v1_jobject(env, tx_struct_v1); + if (jTxObj == NULL) + { + THROW_JNI_EXCEPTION(env, "exception in convert_to_tx_v1_jobject"); + return nullptr; + } + + // release source + if (tx_struct_v1) + { + bcos_sdk_destroy_transaction_struct_v1(tx_struct_v1); + } + 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 new file mode 100644 index 000000000..0ade4cbdc --- /dev/null +++ b/bindings/java/jni/src/main/c/jni/org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj.h @@ -0,0 +1,104 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj */ + +#ifndef _Included_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj +#define _Included_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionDataStruct + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStruct( + JNIEnv*, jclass, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionDataStructToJson + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionDataStructToJson( + JNIEnv*, jclass, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionDataStruct + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData; + */ +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: decodeTransactionDataStructV1 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionDataStructV1( + JNIEnv*, jclass, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: calcTransactionDataStructHash + * Signature: (ILorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_calcTransactionDataStructHash( + JNIEnv*, jclass, jint, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: createEncodedTransaction + * Signature: + * (Lorg/fisco/bcos/sdk/jni/utilities/tx/TransactionData;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_createEncodedTransaction( + JNIEnv*, jclass, jobject, jstring, jstring, jint, jstring); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionStruct + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStruct( + JNIEnv*, jclass, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: encodeTransactionStructToJson + * Signature: (Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_encodeTransactionStructToJson( + JNIEnv*, jclass, jobject); + +/* + * Class: org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj + * Method: decodeTransactionStruct + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction; + */ +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: decodeTransactionStructV1 + * Signature: (Ljava/lang/String;)Lorg/fisco/bcos/sdk/jni/utilities/tx/Transaction; + */ +JNIEXPORT jobject JNICALL +Java_org_fisco_bcos_sdk_jni_utilities_tx_TransactionStructBuilderJniObj_decodeTransactionStructV1( + JNIEnv*, jclass, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_ipv6_sample.ini b/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_ipv6_sample.ini deleted file mode 100644 index fc3480bc2..000000000 --- a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_ipv6_sample.ini +++ /dev/null @@ -1,29 +0,0 @@ -; common -[common] - ; thread pool size for network send/receive/handle message - thread_pool_size = 8 - ; timeout for send message(ms) - message_timeout_ms = 10000 - -; ssl -[ssl] - ; if ssl connection is disabled - disable = false - ; type: ssl or sm_ssl - type = sm_ssl - ; directory the certificates located in - ca_path=./conf - ; the ca certificate file - ca_cert=ca.crt - ; the node private key file - sdk_key=sdk.key - ; the node certificate file - sdk_cert=sdk.crt - -; connected peers -[peers] -# supported ipv4 and ipv6 - node.0=[::1]:30300 - node.1=[::1]:30304 - node.2=[::1]:30308 - node.3=[::1]:30312 \ No newline at end of file diff --git a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sample.ini b/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sample.ini deleted file mode 100644 index dae22a16b..000000000 --- a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sample.ini +++ /dev/null @@ -1,30 +0,0 @@ - -; common -[common] - ; thread pool size for network send/receive/handle message - thread_pool_size = 8 - ; timeout for send message(ms) - message_timeout_ms = 10000 - -; ssl -[ssl] - ; if ssl connection is disabled - disable = false - ; type: ssl or sm_ssl - type = ssl - ; directory the certificates located in - ca_path=./conf - ; the ca certificate file - ca_cert=ca.crt - ; the node private key file - sdk_key=sdk.key - ; the node certificate file - sdk_cert=sdk.crt - -; connected peers -[peers] -# supported ipv4 and ipv6 - node.0=127.0.0.1:30300 - node.1=127.0.0.1:30304 - node.2=127.0.0.1:30308 - node.3=127.0.0.1:30312 \ No newline at end of file diff --git a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sm_ssl_sample.ini b/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sm_ssl_sample.ini deleted file mode 100644 index c8b6beee2..000000000 --- a/bindings/java/jni/src/main/c/test/config/bcos_c_sdk_sm_ssl_sample.ini +++ /dev/null @@ -1,29 +0,0 @@ -; common -[common] - ; thread pool size for network send/receive/handle message - thread_pool_size = 8 - ; timeout for send message(ms) - message_timeout_ms = 10000 - -; ssl -[ssl] - ; if ssl connection is disabled - disable = false - ; type: ssl or sm_ssl - type = sm_ssl - ; directory the certificates located in - ca_path=./conf - ; the ca certificate file - ca_cert=ca.crt - ; the node private key file - sdk_key=sdk.key - ; the node certificate file - sdk_cert=sdk.crt - -; connected peers -[peers] -# supported ipv4 and ipv6 - node.0=127.0.0.1:30300 - node.1=127.0.0.1:30304 - node.2=127.0.0.1:30308 - node.3=127.0.0.1:30312 \ No newline at end of file diff --git a/bindings/java/jni/src/main/c/test/exe/CMakeLists.txt b/bindings/java/jni/src/main/c/test/exe/CMakeLists.txt deleted file mode 100644 index 0cc7c8aee..000000000 --- a/bindings/java/jni/src/main/c/test/exe/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") - -file(GLOB SRC_LIST "*.cpp" "*.c") -file(GLOB HEADERS "*.h") - -add_executable(get-block-number get-block-number.c) -target_link_libraries(get-block-number PRIVATE ${FISCO_BCOS_JNI_STATIC_TARGET}) - -add_executable(pub pub.c) -target_link_libraries(pub PRIVATE ${FISCO_BCOS_JNI_STATIC_TARGET}) - -add_executable(broadcast broadcast.c) -target_link_libraries(broadcast PRIVATE ${FISCO_BCOS_JNI_STATIC_TARGET}) - -add_executable(sub sub.c) -target_link_libraries(sub PRIVATE ${FISCO_BCOS_JNI_STATIC_TARGET}) - -add_executable(sdk-start sdk-start.c) -target_link_libraries(sdk-start PRIVATE ${FISCO_BCOS_JNI_STATIC_TARGET}) \ No newline at end of file diff --git a/bindings/java/jni/src/main/c/test/exe/broadcast.c b/bindings/java/jni/src/main/c/test/exe/broadcast.c deleted file mode 100644 index 74ee0e19d..000000000 --- a/bindings/java/jni/src/main/c/test/exe/broadcast.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "bcos-c-sdk/bcos_sdk_c.h" -#include "bcos-c-sdk/bcos_sdk_c_amop.h" -#include "bcos-c-sdk/bcos_sdk_c_rpc.h" -#include -#include -#include -#include - -void usage() -{ - printf("Usage: broadcast \n"); - printf("Example:\n"); - printf(" ./broadcast 127.0.0.1 20200 topic aaaaaa\n"); - exit(0); -} - -int main(int argc, char** argv) -{ - if (argc < 5) - { - usage(); - } - - char* host = argv[1]; - uint16_t port = atoi(argv[2]); - char* topic = argv[3]; - char* msg = argv[4]; - - // ini bcos_sdk_c_config - struct bcos_sdk_c_config config; - - config.heartbeat_period_ms = 10000; - config.reconnect_period_ms = 20000; - config.message_timeout_ms = 20000; - config.thread_pool_size = 4; - - struct bcos_sdk_c_endpoint ep; - ep.host = host; - ep.port = port; - - config.peers = &ep; - config.peers_count = 1; - - config.send_rpc_request_to_highest_block_node = 1; - - void* sdk = bcos_sdk_create(&config); - if (!sdk) - { - printf("bcos_sdk_create failed.\n"); - return 0; - } - - bcos_sdk_start(sdk); - - while (1) - { - sleep(5); - printf("==> broadcast, topic: %s, message: %s\n", topic, msg); - bcos_amop_broadcast(sdk, topic, (void*)msg, strlen(msg)); - } - - return 0; -} diff --git a/bindings/java/jni/src/main/c/test/exe/get-block-number.c b/bindings/java/jni/src/main/c/test/exe/get-block-number.c deleted file mode 100644 index 0e03cad51..000000000 --- a/bindings/java/jni/src/main/c/test/exe/get-block-number.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "bcos-c-sdk/bcos_sdk_c.h" -#include "bcos-c-sdk/bcos_sdk_c_rpc.h" -#include -#include -#include - -void usage() -{ - printf("Usage: get-block-number (optional)\n"); - printf("Example:\n"); - printf(" ./get-block-number 127.0.0.1 20200\n"); - printf(" ./get-block-number 127.0.0.1 20200 node0\n"); - exit(0); -} - -void callback(struct bcos_sdk_c_struct_response* resp) -{ - printf("status = %d \n", resp->error); - printf("desc = %s \n", resp->desc); - printf("data = %s \n", (char*)resp->data); - printf("size = %zu \n", resp->size); -} - -int main(int argc, char** argv) -{ - if (argc < 3) - { - usage(); - } - - char* host = argv[1]; - uint16_t port = atoi(argv[2]); - - char* node = argc > 3 ? argv[3] : ""; - - // ini bcos_sdk_c_config - struct bcos_sdk_c_config config; - - config.heartbeat_period_ms = 20000; - config.reconnect_period_ms = 20000; - config.message_timeout_ms = 20000; - config.thread_pool_size = 4; - - struct bcos_sdk_c_endpoint ep; - ep.host = host; - ep.port = port; - - config.peers = &ep; - config.peers_count = 1; - - config.send_rpc_request_to_highest_block_node = 1; - - void* sdk = bcos_sdk_create(&config); - if (!sdk) - { - printf("bcos_sdk_create failed.\n"); - return 0; - } - - bcos_sdk_start(sdk); - - printf("create sdk service.\n"); - const char* group = "group"; - - while (1) - { - sleep(5); - bcos_rpc_get_block_number(sdk, group, node, callback, sdk); - } - - return 0; -} diff --git a/bindings/java/jni/src/main/c/test/exe/pub.c b/bindings/java/jni/src/main/c/test/exe/pub.c deleted file mode 100644 index 921ef4d99..000000000 --- a/bindings/java/jni/src/main/c/test/exe/pub.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "bcos-c-sdk/bcos_sdk_c.h" -#include "bcos-c-sdk/bcos_sdk_c_amop.h" -#include "bcos-c-sdk/bcos_sdk_c_rpc.h" -#include -#include -#include -#include - -void usage() -{ - printf("Usage: pub \n"); - printf("Example:\n"); - printf(" ./pub 127.0.0.1 20200 topic aaaaaa\n"); - exit(0); -} - -void callback(struct bcos_sdk_c_struct_response* resp) -{ - printf(" ==> receive response, status: %d, data: %s\n", resp->error, (char*)resp->data); -} - -int main(int argc, char** argv) -{ - if (argc < 5) - { - usage(); - } - - char* host = argv[1]; - uint16_t port = atoi(argv[2]); - char* topic = argv[3]; - char* msg = argv[4]; - - // ini bcos_sdk_c_config - struct bcos_sdk_c_config config; - - config.heartbeat_period_ms = 10000; - config.reconnect_period_ms = 20000; - config.message_timeout_ms = 20000; - config.thread_pool_size = 4; - - struct bcos_sdk_c_endpoint ep; - ep.host = host; - ep.port = port; - - config.peers = &ep; - config.peers_count = 1; - - config.send_rpc_request_to_highest_block_node = 1; - - void* sdk = bcos_sdk_create(&config); - if (!sdk) - { - printf("bcos_sdk_create failed.\n"); - return 0; - } - - printf("start sdk service.\n"); - - bcos_sdk_start(sdk); - - while (1) - { - sleep(5); - printf("==> publish, topic: %s, message: %s\n", topic, msg); - bcos_amop_publish(sdk, topic, (void*)msg, strlen(msg), 0, callback, sdk); - } - - return 0; -} diff --git a/bindings/java/jni/src/main/c/test/exe/sdk-start.c b/bindings/java/jni/src/main/c/test/exe/sdk-start.c deleted file mode 100644 index c4c73fc81..000000000 --- a/bindings/java/jni/src/main/c/test/exe/sdk-start.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "bcos-c-sdk/bcos_sdk_c.h" -#include "bcos-c-sdk/bcos_sdk_c_rpc.h" -#include -#include -#include - -void usage() -{ - printf("Usage: sdk-start \n"); - printf("Example:\n"); - printf(" ./sdk-start 127.0.0.1 20200\n"); - exit(0); -} - -void callback(struct bcos_sdk_c_struct_response* resp) -{ - printf("status = %d \n", resp->error); - printf("desc = %s \n", resp->desc); - printf("data = %s \n", (char*)resp->data); - printf("size = %zu \n", resp->size); -} - -int main(int argc, char** argv) -{ - if (argc < 3) - { - usage(); - } - - char* host = argv[1]; - uint16_t port = atoi(argv[2]); - - // ini bcos_sdk_c_config - struct bcos_sdk_c_config config; - - config.heartbeat_period_ms = 20000; - config.reconnect_period_ms = 20000; - config.message_timeout_ms = 20000; - config.thread_pool_size = 4; - config.send_rpc_request_to_highest_block_node = 1; - - struct bcos_sdk_c_endpoint ep; - ep.host = host; - ep.port = port; - - config.peers = &ep; - config.peers_count = 1; - - void* sdk = bcos_sdk_create(&config); - if (!sdk) - { - printf("bcos_sdk_create failed.\n"); - return 0; - } - printf("create bcos sdk.\n"); - - bcos_sdk_start(sdk); - printf("start bcos sdk.\n"); - - printf("get group list.\n"); - bcos_rpc_get_group_list(sdk, callback, sdk); - - sleep(5); - bcos_sdk_stop(sdk); - printf("stop bcos sdk.\n"); - - sleep(5); - bcos_sdk_destroy(sdk); - printf("destroy bcos sdk.\n"); - - return 0; -} diff --git a/bindings/java/jni/src/main/c/test/exe/sub.c b/bindings/java/jni/src/main/c/test/exe/sub.c deleted file mode 100644 index e73d4272e..000000000 --- a/bindings/java/jni/src/main/c/test/exe/sub.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "bcos-c-sdk/bcos_sdk_c.h" -#include "bcos-c-sdk/bcos_sdk_c_amop.h" -#include "bcos-c-sdk/bcos_sdk_c_rpc.h" -#include -#include -#include - -void usage() -{ - printf("Usage: sub \n"); - printf("Example:\n"); - printf(" ./sub 127.0.0.1 20200 topic\n"); - exit(0); -} - -void sub_cb(const char* endpoint, const char* seq, struct bcos_sdk_c_struct_response* resp) -{ - printf(" ==> receive request, status: %d, data: %s\n", resp->error, (char*)resp->data); - bcos_amop_send_response(resp->context, endpoint, seq, resp->data, resp->size); -} - -int main(int argc, char** argv) -{ - if (argc < 4) - { - usage(); - } - - char* host = argv[1]; - uint16_t port = atoi(argv[2]); - const char* topic = argv[3]; - - // ini bcos_sdk_c_config - struct bcos_sdk_c_config config; - - config.heartbeat_period_ms = 10000; - config.reconnect_period_ms = 20000; - config.message_timeout_ms = 20000; - config.thread_pool_size = 4; - - struct bcos_sdk_c_endpoint ep; - ep.host = host; - ep.port = port; - - config.peers = &ep; - config.peers_count = 1; - - void* sdk = bcos_sdk_create(&config); - if (!sdk) - { - printf("bcos_sdk_create failed.\n"); - return 0; - } - - printf("start sdk service.\n"); - - printf(" ==> subscribe topic topic: %s\n", topic); - - bcos_amop_subscribe_topic_with_cb(sdk, topic, sub_cb, sdk); - - while (1) - { - sleep(5); - printf(" ==> main <== \n"); - } - - return 0; -} diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/BcosSDKJniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/BcosSDKJniObj.java index de1e31400..e356a6ba2 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/BcosSDKJniObj.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/BcosSDKJniObj.java @@ -42,7 +42,7 @@ public static BcosSDKJniObj build(JniConfig jniConfig) throws JniException { } /** - * desctroy interface + * destroy interface * * @param nativePointer */ @@ -64,6 +64,18 @@ private void setNativePointer(long nativePointer) { this.nativePointer = nativePointer; } + public static int localProtocolInfo(long nativePointer) { + BcosSDKJniObj bcosSDKJniObj = new BcosSDKJniObj(); + bcosSDKJniObj.setNativePointer(nativePointer); + return bcosSDKJniObj.localProtocolInfo(); + } + + public static int negotiatedProtocolInfo(long nativePointer) { + BcosSDKJniObj bcosSDKJniObj = new BcosSDKJniObj(); + bcosSDKJniObj.setNativePointer(nativePointer); + return bcosSDKJniObj.negotiatedProtocolInfo(); + } + // ------------------------native method list------------------------------------------- public static native long create(JniConfig config); @@ -74,6 +86,10 @@ private void setNativePointer(long nativePointer) { public native void destroy(); + public native int localProtocolInfo(); + + public native int negotiatedProtocolInfo(); + // -------------------------native method end------------------------------------------- // ------------------------ block notifier begin---------------------------------------- diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/receipt/ReceiptBuilderJniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/receipt/ReceiptBuilderJniObj.java index 6a3ca5f6c..1b2ff5554 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/receipt/ReceiptBuilderJniObj.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/receipt/ReceiptBuilderJniObj.java @@ -51,4 +51,7 @@ public static native long createReceiptData( */ public static native String calcReceiptDataHash(int cryptoType, long ReceiptData) throws JniException; + + public static native String calcReceiptDataHashWithJson(int cryptoType, String json) + throws JniException; } 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 new file mode 100644 index 000000000..a0ad0c9e2 --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/Transaction.java @@ -0,0 +1,67 @@ +package org.fisco.bcos.sdk.jni.utilities.tx; + +public class Transaction { + private TransactionData transactionData; + private byte[] dataHash; + private byte[] signature; + private byte[] sender; + private long importTime; + private int attribute; + private String extraData; + + public TransactionData getTransactionData() { + return transactionData; + } + + public void setTransactionData(TransactionData transactionData) { + this.transactionData = transactionData; + } + + public byte[] getDataHash() { + return dataHash; + } + + public void setDataHash(byte[] dataHash) { + this.dataHash = dataHash; + } + + public byte[] getSignature() { + return signature; + } + + public void setSignature(byte[] signature) { + this.signature = signature; + } + + public byte[] getSender() { + return sender; + } + + public void setSender(byte[] 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/TransactionBuilderJniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderJniObj.java index 9c08eb509..d0bea21d9 100644 --- a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderJniObj.java +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderJniObj.java @@ -56,6 +56,25 @@ public static native String decodeTransactionDataToJsonObj(String transactionDat public static native String calcTransactionDataHash(int cryptoType, long transactionData) throws JniException; + /** + * Decode transaction hex string to Transaction object raw pointer + * + * @param transactionHex encoded transaction hex string + * @return Transaction object pointer + */ + public static native long decodeTransaction(String transactionHex) throws JniException; + + /** + * Decode transaction hex string to Transaction object json string + * + * @param transactionHex encoded transaction hex string + * @return Transaction object json string + */ + public static native String decodeTransactionToJsonObj(String transactionHex) throws JniException; + + /** @param transaction Transaction pointer */ + public static native void destroyTransaction(long transaction) throws JniException; + /** * @param keyPair KeyPair pointer * @param transactionDataHash transaction data hash hex string diff --git a/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderV1JniObj.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderV1JniObj.java new file mode 100644 index 000000000..88e0499c0 --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionBuilderV1JniObj.java @@ -0,0 +1,243 @@ +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 TransactionBuilderV1JniObj extends TransactionBuilderJniObj { + + static { + JniLibLoader.loadJniLibrary(); + } + + /** + * create transaction data with version 1 by default + * + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if it is empty or null, then it + * will generate one + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasPrice gas price + * @param gasLimit gas limit + * @return void* transaction data pointer, you should release it after use, check + * `destroyTransactionData` + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native long createTransactionData( + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + String gasPrice, + long gasLimit) + throws JniException; + + /** + * create eip1559 transaction data with version 1 by default + * + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if it is empty or null, then it + * will generate one + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasLimit gas limit + * @param maxFeePerGas max fee per gas + * @param maxPriorityFeePerGas max priority fee per gas + * @return void* transaction data pointer, you should release it after use, check + * `destroyTransactionData` + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native long createEIP1559TransactionData( + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + long gasLimit, + String maxFeePerGas, + String maxPriorityFeePerGas) + throws JniException; + + /** + * create transaction data with full fields + * + * @param cryptoType 0: keccak256, 1: sm3 + * @param version tx version, if version==1, then enable + * (value,gasPrice,gasLimit,maxFeePerGas,maxPriorityFeePerGas) fields + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce nonce, random number to avoid duplicate transactions + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasPrice gas price + * @param gasLimit gas limit + * @param maxFeePerGas max fee per gas + * @param maxPriorityFeePerGas max priority fee per gas + * @return const char* transaction data hash hex string + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native String calcTransactionDataHashWithFullFields( + int cryptoType, + TransactionVersion version, + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + String gasPrice, + long gasLimit, + String maxFeePerGas, + String maxPriorityFeePerGas) + throws JniException; + + /** + * create transaction data with json string + * + * @param cryptoType 0: keccak256, 1: sm3 + * @param json transaction data json string + * @return const char* transaction data hash hex string + * @throws JniException if lack of some required fields, or some fields are invalid + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native String calcTransactionDataHashWithJson(int cryptoType, String json) + throws JniException; + + /** + * create encoded transaction data with external signature + * + * @param signature signature bytes array, if ECDSA, it is r||s||v, if SM2, it is r||s||pk + * @param txDataHash transactionData hash hex string + * @param version tx version, only support 0 and 1 now, if version==1, then enable + * (value,gasPrice,gasLimit,maxFeePerGas,maxPriorityFeePerGas) fields + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce nonce, random number to avoid duplicate transactions + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasPrice gas price + * @param gasLimit gas limit + * @param maxFeePerGas max fee per gas + * @param maxPriorityFeePerGas max priority fee per gas + * @param attribute transaction attribute + * @param extraData extra data in transaction + * @return const char* encoded transaction hex string + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native String createSignedTransactionWithSignature( + byte[] signature, + String txDataHash, + TransactionVersion version, + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + String gasPrice, + long gasLimit, + String maxFeePerGas, + String maxPriorityFeePerGas, + int attribute, + String extraData) + throws JniException; + + /** + * create transaction with full fields, with version 1 by default + * + * @param keyPair key pair pointer + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if it is empty or null, then it + * will generate one + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasPrice gas price + * @param gasLimit gas limit + * @param attribute transaction attribute + * @param extraData extra data in transaction + * @return TxPair + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native TxPair createSignedTransactionWithFullFields( + long keyPair, + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + String gasPrice, + long gasLimit, + int attribute, + String extraData) + throws JniException; + + /** + * create eip1559 transaction with full fields, with version 1 by default + * + * @param keyPair key pair pointer + * @param groupID group id + * @param chainID chain id + * @param to contract address, if it is a contract creation transaction, it can be empty + * @param nonce random number to avoid duplicate transactions, if it is empty or null, then it + * will generate one + * @param input encoded contract method and params + * @param abi contract abi, only create contract need + * @param blockLimit block limit + * @param value transfer value + * @param gasLimit gas limit + * @param maxFeePerGas max fee per gas + * @param maxPriorityFeePerGas max priority fee per gas + * @param attribute transaction attribute + * @param extraData extra data in transaction + * @return TxPair + * @apiNote version 1 transaction only supported in FISCO BCOS 3.6.0 and later + */ + public static native TxPair createSignedEIP1559TransactionWithFullFields( + long keyPair, + String groupID, + String chainID, + String to, + String nonce, + byte[] input, + String abi, + long blockLimit, + String value, + String maxFeePerGas, + String maxPriorityFeePerGas, + long gasLimit, + int attribute, + String extraData) + throws JniException; +} 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 new file mode 100644 index 000000000..50f6af128 --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionData.java @@ -0,0 +1,76 @@ +package org.fisco.bcos.sdk.jni.utilities.tx; + +public class TransactionData { + 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; + } + + 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 byte[] getInput() { + return 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/TransactionDataV1.java b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1.java new file mode 100644 index 000000000..7d3d5b55f --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionDataV1.java @@ -0,0 +1,49 @@ +package org.fisco.bcos.sdk.jni.utilities.tx; + +public class TransactionDataV1 extends TransactionData { + protected String value; + protected String gasPrice; + protected long gasLimit; + protected String maxFeePerGas; + protected String maxPriorityFeePerGas; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getGasPrice() { + return gasPrice; + } + + public void setGasPrice(String gasPrice) { + this.gasPrice = gasPrice; + } + + public long getGasLimit() { + return gasLimit; + } + + public void setGasLimit(long gasLimit) { + this.gasLimit = gasLimit; + } + + public String getMaxFeePerGas() { + return maxFeePerGas; + } + + public void setMaxFeePerGas(String maxFeePerGas) { + this.maxFeePerGas = maxFeePerGas; + } + + public String getMaxPriorityFeePerGas() { + return maxPriorityFeePerGas; + } + + public void setMaxPriorityFeePerGas(String maxPriorityFeePerGas) { + this.maxPriorityFeePerGas = maxPriorityFeePerGas; + } +} 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 new file mode 100644 index 000000000..400320b61 --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionStructBuilderJniObj.java @@ -0,0 +1,90 @@ +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 TransactionStructBuilderJniObj { + + static { + JniLibLoader.loadJniLibrary(); + } + + /** + * @param transactionData Transaction Data struct + * @return Hexed Transaction Data + */ + public static native String encodeTransactionDataStruct(TransactionData transactionData) + throws JniException; + + /** + * @param transactionData Transaction Data struct + * @return Json Transaction Data + */ + public static native String encodeTransactionDataStructToJson(TransactionData transactionData) + throws JniException; + + /** + * @param transactionDataHex transactionData hex string + * @return TxData + */ + public static native TransactionData decodeTransactionDataStruct(String transactionDataHex) + throws JniException; + + /** + * @param transactionDataHex transactionData hex string + * @return TxData + */ + public static native TransactionDataV1 decodeTransactionDataStructV1(String transactionDataHex) + throws JniException; + + /** + * @param cryptoType crypto type + * @param transactionData Transaction Data struct + * @return Hash hex string + */ + public static native String calcTransactionDataStructHash( + int cryptoType, TransactionData transactionData) throws JniException; + + /** + * @param transactionData + * @param signature + * @param transactionDataHash + * @param attribute + * @param extraData + * @return signedTransaction string + */ + public static native String createEncodedTransaction( + TransactionData transactionData, + String signature, + String transactionDataHash, + int attribute, + String extraData) + throws JniException; + + /** + * @param transaction Transaction struct + * @return Hexed Transaction + */ + public static native String encodeTransactionStruct(Transaction transaction) throws JniException; + + /** + * @param transaction Transaction struct + * @return Json Transaction + */ + public static native String encodeTransactionStructToJson(Transaction transaction) + throws JniException; + + /** + * @param transactionHex transaction hex string + * @return Tx + */ + public static native Transaction decodeTransactionStruct(String transactionHex) + throws JniException; + + /** + * @param transactionHex transaction hex string + * @return Tx + */ + public static native Transaction decodeTransactionStructV1(String transactionHex) + throws JniException; +} 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 new file mode 100644 index 000000000..ba96756f3 --- /dev/null +++ b/bindings/java/jni/src/main/java/org/fisco/bcos/sdk/jni/utilities/tx/TransactionVersion.java @@ -0,0 +1,27 @@ +package org.fisco.bcos.sdk.jni.utilities.tx; + +public enum TransactionVersion { + V0(0), + V1(1); + + private int value; + + TransactionVersion(int value) { + this.value = 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/main/resources/META-INF/native/file.list b/bindings/java/jni/src/main/resources/META-INF/native/file.list new file mode 100644 index 000000000..5e3f02a16 --- /dev/null +++ b/bindings/java/jni/src/main/resources/META-INF/native/file.list @@ -0,0 +1,7 @@ +bcos-sdk-jni.dll +bcos-sdk-jni.lib +libbcos-sdk-jni.dylib +libbcos-sdk-jni.so +libbcos-sdk-jni-aarch64.dylib +libbcos-sdk-jni-aarch64.so +libbcos-sdk-jni-static-aarch64.a \ No newline at end of file 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 new file mode 100644 index 000000000..78b605c5a --- /dev/null +++ b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStruct.java @@ -0,0 +1,232 @@ +package org.fisco.bcos.sdk.jni.test.tx; + +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; +import org.fisco.bcos.sdk.jni.common.Response; +import org.fisco.bcos.sdk.jni.rpc.RpcJniObj; +import org.fisco.bcos.sdk.jni.test.Utility; +import org.fisco.bcos.sdk.jni.utilities.keypair.KeyPairJniObj; +import org.fisco.bcos.sdk.jni.utilities.tx.*; +import org.junit.Assert; + +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"; + + /* + { + "6d4ce63c": "get()", + "4ed3885e": "set(string)" + } + + { + "299f7f9d": "get()", + "3590b49f": "set(string)" + } + */ + + 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; + } + + 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 String getBinary(boolean isSM) { + return isSM ? hwSmBIN : hwBIN; + } + + 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 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/TestTxStructV1.java b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV1.java new file mode 100644 index 000000000..5a09b7854 --- /dev/null +++ b/bindings/java/jni/src/test/java/org/fisco/bcos/sdk/jni/test/tx/TestTxStructV1.java @@ -0,0 +1,272 @@ +package org.fisco.bcos.sdk.jni.test.tx; + +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; +import org.fisco.bcos.sdk.jni.common.Response; +import org.fisco.bcos.sdk.jni.rpc.RpcJniObj; +import org.fisco.bcos.sdk.jni.test.Utility; +import org.fisco.bcos.sdk.jni.utilities.keypair.KeyPairJniObj; +import org.fisco.bcos.sdk.jni.utilities.tx.*; +import org.junit.Assert; + +public class TestTxStructV1 { + + // ------------------------------------------------------------------------------ + // ------------------------------------------------------------------------------ + + // 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"; + + /* + { + "6d4ce63c": "get()", + "4ed3885e": "set(string)" + } + + { + "299f7f9d": "get()", + "3590b49f": "set(string)" + } + */ + + 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; + } + + 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 String getBinary(boolean isSM) { + return isSM ? hwSmBIN : hwBIN; + } + + public static void Usage() { + System.out.println("Desc: test transaction struct V1 [HelloWorld set]"); + System.out.println( + "Usage: java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.jni.test.tx.TestTxStructV1"); + System.exit(0); + } + + 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(); + long blockLimit = rpcJniObj.getBlockLimit(group); + + boolean smCrypto = false; + + long keyPair = KeyPairJniObj.createJniKeyPair(smCrypto ? 1 : 0); + String jniKeyPairAddress = KeyPairJniObj.getJniKeyPairAddress(keyPair); + System.out.printf(" [test Tx Struct V1] new account, address: %s\n", jniKeyPairAddress); + + 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 TransactionDataV1 + TransactionDataV1 transactionDataStructV1 = new TransactionDataV1(); + transactionDataStructV1.setGroupId(groupID); + transactionDataStructV1.setChainId(chainID); + transactionDataStructV1.setTo(""); + transactionDataStructV1.setAbi(""); + transactionDataStructV1.setVersion(1); + transactionDataStructV1.setNonce(generateNonce()); + transactionDataStructV1.setBlockLimit(blockLimit); + transactionDataStructV1.setValue(value); + transactionDataStructV1.setGasPrice(gasPrice); + transactionDataStructV1.setGasLimit(gasLimit); + transactionDataStructV1.setMaxFeePerGas(maxFeePerGas); + transactionDataStructV1.setMaxPriorityFeePerGas(maxPriorityFeePerGas); + // input + byte[] bytesInput = fromHex(data); + transactionDataStructV1.setInput(bytesInput); + + // encode TxData to hex tx data + String txDataHex = + TransactionStructBuilderJniObj.encodeTransactionDataStruct(transactionDataStructV1); + // decode hex tx data to TxData + TransactionDataV1 decodeTransactionDataStructHex = + TransactionStructBuilderJniObj.decodeTransactionDataStructV1(txDataHex); + // TransactionDataV1 decodeTransactionDataStructHex2 = + // TransactionStructBuilderV1JniObj.decodeTransactionDataStructV1(null); + // TransactionDataV1 decodeTransactionDataStructHex3 = + // TransactionStructBuilderV1JniObj.decodeTransactionDataStructV1(""); + + // assert + Assert.assertEquals( + transactionDataStructV1.getChainId(), decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionDataStructV1.getGroupId(), decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals(transactionDataStructV1.getAbi(), decodeTransactionDataStructHex.getAbi()); + Assert.assertEquals( + transactionDataStructV1.getBlockLimit(), decodeTransactionDataStructHex.getBlockLimit()); + Assert.assertEquals( + transactionDataStructV1.getValue(), decodeTransactionDataStructHex.getValue()); + Assert.assertEquals( + transactionDataStructV1.getGasPrice(), decodeTransactionDataStructHex.getGasPrice()); + Assert.assertEquals( + transactionDataStructV1.getGasLimit(), decodeTransactionDataStructHex.getGasLimit()); + Assert.assertEquals( + transactionDataStructV1.getMaxFeePerGas(), + decodeTransactionDataStructHex.getMaxFeePerGas()); + Assert.assertEquals( + transactionDataStructV1.getMaxPriorityFeePerGas(), + decodeTransactionDataStructHex.getMaxPriorityFeePerGas()); + + // encode TxData to json tx data + String txDataJson = + TransactionStructBuilderJniObj.encodeTransactionDataStructToJson(transactionDataStructV1); + System.out.printf(" [test Tx Struct V1] txDataJson: %s\n", txDataJson); + + // calc tx data hash + String txDataHash = + TransactionStructBuilderJniObj.calcTransactionDataStructHash( + smCrypto ? 1 : 0, decodeTransactionDataStructHex); + System.out.printf(" [test Tx Struct V1] txDataHash: %s\n", txDataHash); + // signature tx data hash + String signature = TransactionBuilderJniObj.signTransactionDataHash(keyPair, txDataHash); + System.out.printf(" [test Tx Struct V1] signature: %s\n", signature); + + // construct tx + Transaction transactionStructV1 = new Transaction(); + transactionStructV1.setTransactionData(decodeTransactionDataStructHex); + transactionStructV1.setDataHash(fromHex(txDataHash)); + transactionStructV1.setSignature(fromHex(signature)); + transactionStructV1.setSender(null); + transactionStructV1.setImportTime(0); + transactionStructV1.setAttribute(0); + transactionStructV1.setExtraData(""); + // assert + Assert.assertEquals( + transactionStructV1.getTransactionData().getBlockLimit(), + decodeTransactionDataStructHex.getBlockLimit()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getGroupId(), + decodeTransactionDataStructHex.getGroupId()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getChainId(), + decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getChainId(), + decodeTransactionDataStructHex.getChainId()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getAbi(), decodeTransactionDataStructHex.getAbi()); + Assert.assertArrayEquals(transactionStructV1.getDataHash(), fromHex(txDataHash)); + Assert.assertArrayEquals(transactionStructV1.getSignature(), fromHex(signature)); + + // encode Tx to hex tx + String txHex = TransactionStructBuilderJniObj.encodeTransactionStruct(transactionStructV1); + // decode hex tx to Tx + Transaction decodeTransactionStructHex = + TransactionStructBuilderJniObj.decodeTransactionStructV1(txHex); + + // assert + Assert.assertEquals( + transactionStructV1.getTransactionData().getBlockLimit(), + decodeTransactionStructHex.getTransactionData().getBlockLimit()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getGroupId(), + decodeTransactionStructHex.getTransactionData().getGroupId()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getChainId(), + decodeTransactionStructHex.getTransactionData().getChainId()); + Assert.assertEquals( + transactionStructV1.getTransactionData().getAbi(), + decodeTransactionStructHex.getTransactionData().getAbi()); + TransactionDataV1 transactionData = + (TransactionDataV1) transactionStructV1.getTransactionData(); + TransactionDataV1 decodeTransactionData = + (TransactionDataV1) 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( + transactionStructV1.getDataHash(), decodeTransactionStructHex.getDataHash()); + Assert.assertArrayEquals( + transactionStructV1.getSignature(), decodeTransactionStructHex.getSignature()); + + // encode Tx to json tx + String txJson = + TransactionStructBuilderJniObj.encodeTransactionStructToJson(transactionStructV1); + System.out.printf(" [test Tx Struct V1] txJson: %s\n", txJson); + // create tx string + String txString = + TransactionStructBuilderJniObj.createEncodedTransaction( + decodeTransactionDataStructHex, signature, txDataHash, 0, ""); + // System.out.printf(" [test Tx Struct V1] 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 V1] finish !! "); + } +} diff --git a/cmake/CompilerSettings.cmake b/cmake/CompilerSettings.cmake index f78abd201..0356df8c3 100644 --- a/cmake/CompilerSettings.cmake +++ b/cmake/CompilerSettings.cmake @@ -16,6 +16,15 @@ # File: CompilerSettings.cmake # Function: Common cmake file for setting compilation environment variables # ------------------------------------------------------------------------------ +set(CMAKE_CXX_STANDARD 20) +set(Boost_NO_WARN_NEW_VERSIONS ON) +message(STATUS "COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}") + +# export windows dll symbol +if(WIN32) + message(STATUS "Compile on Windows") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "ON") +endif() if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) find_program(CCACHE_PROGRAM ccache) @@ -37,13 +46,15 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA add_compile_options(-Wall) add_compile_options(-pedantic) add_compile_options(-Wextra) - # add_compile_options(-Wno-unused-variable) - # add_compile_options(-Wno-unused-parameter) - # add_compile_options(-Wno-unused-function) - # add_compile_options(-Wno-missing-field-initializers) - # Disable warnings about unknown pragmas (which is enabled by -Wall). - add_compile_options(-Wno-unknown-pragmas) + + # Ignore warnings + add_compile_options(-Wno-unused-parameter) + add_compile_options(-Wno-unused-variable) + add_compile_options(-Wno-error=unknown-pragmas) + add_compile_options(-Wno-error=deprecated-declarations) add_compile_options(-fno-omit-frame-pointer) + add_compile_options(-Wno-error=strict-aliasing) + # for boost json spirit add_compile_options(-DBOOST_SPIRIT_THREADSAFE) # for tbb, TODO: https://software.intel.com/sites/default/files/managed/b2/d2/TBBRevamp.pdf @@ -89,8 +100,8 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA # Additional GCC-specific compiler settings. if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - # Check that we've got GCC 7.0 or newer. - set(GCC_MIN_VERSION "7.0") + # Check that we've got GCC 10.0 or newer. + set(GCC_MIN_VERSION "10.0") execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER ${GCC_MIN_VERSION} OR GCC_VERSION VERSION_EQUAL ${GCC_MIN_VERSION})) @@ -137,6 +148,7 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA endif() endif () elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + add_compile_definitions(NOMINMAX) # Only support visual studio 2017 and visual studio 2019 set(MSVC_MIN_VERSION "1914") # VS2017 15.7, for full-ish C++17 support @@ -155,6 +167,20 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") add_compile_options(/std:c++latest) add_compile_options(-bigobj) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + if(BUILD_SHARED_LIBS) + if(CMAKE_BUILD_TYPE MATCHES "Debug") + add_compile_options(/MDd) + else() + add_compile_options(/MD) + endif() + else () + if(CMAKE_BUILD_TYPE MATCHES "Debug") + add_compile_options(/MTd) + else() + add_compile_options(/MT) + endif () + endif () + # set(CMAKE_CXX_FLAGS_DEBUG "/MTd /DEBUG") # set(CMAKE_CXX_FLAGS_MINSIZEREL "/MT /Os") # set(CMAKE_CXX_FLAGS_RELEASE "/MT") @@ -177,4 +203,6 @@ if(APPLE) else() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ldl") endif() +message("CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") +message("CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON) diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake new file mode 100644 index 000000000..979ac212c --- /dev/null +++ b/cmake/Coverage.cmake @@ -0,0 +1,41 @@ +# ------------------------------------------------------------------------------ +# Copyright (C) 2021 FISCO BCOS. +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ +# File: Coverage.cmake +# Function: Define coverage related functions +# ------------------------------------------------------------------------------ +# REMOVE_FILE_PATTERN eg.: '/usr*' '${CMAKE_SOURCE_DIR}/deps**' '${CMAKE_SOURCE_DIR}/evmc*' ‘${CMAKE_SOURCE_DIR}/fisco-bcos*’ +function(config_coverage TARGET REMOVE_FILE_PATTERN) + find_program(LCOV_TOOL lcov) + message(STATUS "lcov tool: ${LCOV_TOOL}") + if (LCOV_TOOL) + message(STATUS "coverage dir: " ${CMAKE_BINARY_DIR}) + message(STATUS "coverage TARGET: " ${TARGET}) + message(STATUS "coverage REMOVE_FILE_PATTERN: " ${REMOVE_FILE_PATTERN}) + if (APPLE) + add_custom_target(${TARGET} + COMMAND ${LCOV_TOOL} -keep-going --ignore-errors inconsistent,source --rc lcov_branch_coverage=1 -o ${CMAKE_BINARY_DIR}/coverage.info.in -c -d ${CMAKE_BINARY_DIR}/ + COMMAND ${LCOV_TOOL} -keep-going --ignore-errors inconsistent,source --rc lcov_branch_coverage=1 -r ${CMAKE_BINARY_DIR}/coverage.info.in '*MacOS*' '/usr*' '.*vcpkg_installed*' '.*boost/*' '*test*' '*build*' '*deps*' ${REMOVE_FILE_PATTERN} -o ${CMAKE_BINARY_DIR}/coverage.info + COMMAND genhtml --keep-going --ignore-errors inconsistent,source --rc lcov_branch_coverage=1 -q -o ${CMAKE_BINARY_DIR}/CodeCoverage ${CMAKE_BINARY_DIR}/coverage.info) + else() + add_custom_target(${TARGET} + COMMAND ${LCOV_TOOL} --rc lcov_branch_coverage=1 -o ${CMAKE_BINARY_DIR}/coverage.info.in -c -d ${CMAKE_BINARY_DIR}/ + COMMAND ${LCOV_TOOL} --rc lcov_branch_coverage=1 -r ${CMAKE_BINARY_DIR}/coverage.info.in '*MacOS*' '/usr*' '*test*' '*build*' '*deps*' ${REMOVE_FILE_PATTERN} -o ${CMAKE_BINARY_DIR}/coverage.info + COMMAND genhtml --rc lcov_branch_coverage=1 -q -o ${CMAKE_BINARY_DIR}/CodeCoverage ${CMAKE_BINARY_DIR}/coverage.info) + endif() + else () + message(FATAL_ERROR "Can't find lcov tool. Please install lcov") + endif() +endfunction() \ No newline at end of file diff --git a/cmake/IncludeDirectories.cmake b/cmake/IncludeDirectories.cmake new file mode 100644 index 000000000..22bf8a1f1 --- /dev/null +++ b/cmake/IncludeDirectories.cmake @@ -0,0 +1,9 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") +message(STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}") +include_directories(${CMAKE_INSTALL_INCLUDEDIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/bcos-c-sdk) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) +include_directories(${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include) diff --git a/cmake/Options.cmake b/cmake/Options.cmake index e56cf625a..1adaa21a9 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -56,6 +56,8 @@ macro(configure_project) set(MARCH_TYPE "-march=native -mtune=native") endif() + # build jni + default_option(BUILD_JNI OFF) # unit tests default_option(TESTS OFF) # code coverage @@ -84,6 +86,7 @@ macro(print_config NAME) message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}") message("-- TARGET_PLATFORM Target platform ${CMAKE_SYSTEM_NAME} ${ARCHITECTURE}") message("-- BUILD_STATIC Build static ${BUILD_STATIC}") + message("-- BUILD_JNI Build jni ${BUILD_JNI}") message("-- COVERAGE Build code coverage ${COVERAGE}") message("-- TESTS Build tests ${TESTS}") message("-- ARCH_NATIVE Enable native code ${ARCH_NATIVE}") diff --git a/cmake/SearchTestCases.cmake b/cmake/SearchTestCases.cmake new file mode 100644 index 000000000..7750d2ae1 --- /dev/null +++ b/cmake/SearchTestCases.cmake @@ -0,0 +1,66 @@ +# ------------------------------------------------------------------------------ +# Copyright (C) 2021 FISCO BCOS. +# SPDX-License-Identifier: Apache-2.0 +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ +# File: SearchTestCases.cmake +# Function: cmake to help search test cases +# ------------------------------------------------------------------------------ +function(config_test_cases TEST_ARGS SOURCES TEST_BINARY_PATH EXCLUDE_SUITES) + foreach(file ${SOURCES}) + file(STRINGS ${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE|SUITE_END)") + set(TestSuite "DEFAULT") + set(TestSuitePath "") + foreach(test_raw ${test_list_raw}) + string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) + + #skip disabled + if (";${EXCLUDE_SUITES};" MATCHES ";${TestSuite};") + continue() + endif() + + if(test MATCHES "^SUITE .*") + + string(SUBSTRING ${test} 6 -1 TestSuite) + set(TestSuitePath "${TestSuitePath}/${TestSuite}") + + if(FASTCTEST) + if (";${EXCLUDE_SUITES};" MATCHES ";${TestSuite};") + continue() + endif() + if (NOT ";${allSuites};" MATCHES ";${TestSuite};") + string(SUBSTRING ${TestSuitePath} 1 -1 TestSuitePathFixed) + list(APPEND allSuites ${TestSuite}) + separate_arguments(TEST_ARGS) + set(TestArgs -t ${TestSuitePathFixed} -- ${TEST_ARGS}) + add_test(NAME ${TestSuitePathFixed} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${TEST_BINARY_PATH} ${TestArgs}) + endif() + endif() + elseif(test MATCHES "^CASE .*") + if(NOT FASTCTEST) + if(NOT test MATCHES "^CASE &createRandom.*") + string(SUBSTRING ${test} 5 -1 TestCase) + string(SUBSTRING ${TestSuitePath} 1 -1 TestSuitePathFixed) + separate_arguments(TEST_ARGS) + set(TestArgs -t ${TestSuitePathFixed}/${TestCase} -- ${TEST_ARGS}) + add_test(NAME ${TestSuitePathFixed}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${TEST_BINARY_PATH} ${TestArgs}) + endif() + endif() + elseif (";${test_raw};" MATCHES "BOOST_AUTO_TEST_SUITE_END()") + #encountered SUITE_END block. remove one test suite from the suite path. + string(FIND ${TestSuitePath} "/" Position REVERSE) + string(SUBSTRING ${TestSuitePath} 0 ${Position} TestSuitePath) + endif() + endforeach(test_raw) + endforeach(file) +endfunction() diff --git a/cmake/config.cmake b/cmake/config.cmake index 8ee5868d1..fb21ae64f 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -51,8 +51,8 @@ hunter_config(bcos-boostssl hunter_config(bcos-cpp-sdk VERSION 3.3.0-local - URL https://${URL_BASE}/FISCO-BCOS/bcos-cpp-sdk/archive/d47a751fe5f840fd22b38bcf9bedd61e1b1ad478.tar.gz - SHA1 debd13410b98474dc0e4d55b7b08d233999fa0e5 + URL https://${URL_BASE}/FISCO-BCOS/bcos-cpp-sdk/archive/0bb3761ae0ec02548981e78567d6ac8d2bc676c8.tar.gz + SHA1 d598a834d440df1bcfb309ce3b42069e87fe3bbb ) hunter_config(range-v3 VERSION 1.0.0 diff --git a/sample/amop/broadcast.c b/sample/amop/broadcast.c index 552477ed4..b3c46cd52 100644 --- a/sample/amop/broadcast.c +++ b/sample/amop/broadcast.c @@ -31,7 +31,7 @@ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void usage() +void usage(void) { printf("Desc: broadcast amop message by command params\n"); printf("Usage: broadcast \n"); @@ -76,13 +76,11 @@ int main(int argc, char** argv) printf(" [AMOP][Broadcast] start sdk ... \n"); - int i = 0; while (1) { printf("[AMOP][Broadcast] broadcast message, topic: %s, msg: %s\n", topic, msg); bcos_amop_broadcast(sdk, topic, (void*)msg, strlen(msg)); sleep(10); - i++; } return EXIT_SUCCESS; diff --git a/sample/amop/publish.c b/sample/amop/publish.c index 37e816e64..b84224d02 100644 --- a/sample/amop/publish.c +++ b/sample/amop/publish.c @@ -31,7 +31,7 @@ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void usage() +void usage(void) { printf("Desc: publish amop message by command params\n"); printf("Usage: publish \n"); @@ -87,7 +87,6 @@ int main(int argc, char** argv) exit(-1); } - int i = 0; while (1) { printf("[AMOP][Publish] publish message, topic: %s, msg size: %lu\n", topic, strlen(msg)); @@ -95,7 +94,6 @@ int main(int argc, char** argv) bcos_amop_publish(sdk, topic, (void*)msg, strlen(msg), 0, on_recv_amop_publish_resp, sdk); sleep(10); - i++; } return EXIT_SUCCESS; diff --git a/sample/amop/subscribe.c b/sample/amop/subscribe.c index 2bf9f2a4a..9e9bbddd7 100644 --- a/sample/amop/subscribe.c +++ b/sample/amop/subscribe.c @@ -29,7 +29,7 @@ #include //------------------------------------------------------------------------------ -void usage() +void usage(void) { printf("Desc: subscribe amop topic by command params\n"); printf("Usage: subscribe \n"); @@ -92,12 +92,10 @@ int main(int argc, char** argv) bcos_amop_subscribe_topic_with_cb(sdk, topic, on_recv_amop_subscribe_resp, sdk); - int i = 0; while (1) { printf(" Main thread running \n"); sleep(10); - i++; } return EXIT_SUCCESS; diff --git a/sample/eventsub/eventsub.c b/sample/eventsub/eventsub.c index 763ab1a87..a97f72e2c 100644 --- a/sample/eventsub/eventsub.c +++ b/sample/eventsub/eventsub.c @@ -31,7 +31,7 @@ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void usage() +void usage(void) { printf("Desc: subscribe contract events by command params\n"); printf("Usage: eventsub

[Optional]\n"); @@ -124,12 +124,10 @@ int main(int argc, char** argv) bcos_event_sub_subscribe_event(sdk, group, params, on_event_sub_callback, sdk); - int i = 0; while (1) { printf(" Main thread running "); sleep(10); - i++; } return EXIT_SUCCESS; diff --git a/sample/rpc/rpc.c b/sample/rpc/rpc.c index 0e515ffce..de2973af9 100644 --- a/sample/rpc/rpc.c +++ b/sample/rpc/rpc.c @@ -30,7 +30,7 @@ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void usage() +void usage(void) { printf("Desc: rpc methods call test\n"); printf("Usage: rpc \n"); diff --git a/sample/tx/CMakeLists.txt b/sample/tx/CMakeLists.txt index f3e389f2c..5776ef247 100644 --- a/sample/tx/CMakeLists.txt +++ b/sample/tx/CMakeLists.txt @@ -4,5 +4,11 @@ target_link_libraries(hello_sample PUBLIC ${BCOS_C_SDK_STATIC_TARGET}) add_executable(hello_sample_hsm hello_sample_hsm.c) target_link_libraries(hello_sample_hsm PUBLIC ${BCOS_C_SDK_STATIC_TARGET}) +add_executable(tx_struct_test tx_struct_test.c) +target_link_libraries(tx_struct_test PUBLIC ${BCOS_C_SDK_STATIC_TARGET}) + +add_executable(tx_struct_v1_test tx_struct_v1_test.c) +target_link_libraries(tx_struct_v1_test PUBLIC ${BCOS_C_SDK_STATIC_TARGET}) + # add_executable(tx_sign_perf tx_sign_perf.cpp) # target_link_libraries(tx_sign_perf PUBLIC ${BCOS_C_SDK_STATIC_TARGET}) \ No newline at end of file diff --git a/sample/tx/hello_sample.c b/sample/tx/hello_sample.c index cc1987295..493d44cc6 100644 --- a/sample/tx/hello_sample.c +++ b/sample/tx/hello_sample.c @@ -127,7 +127,7 @@ const char* g_hw_abi = } */ -void usage() +void usage(void) { printf("Desc: HelloWorld contract sample\n"); printf("Usage: hello_sample \n"); diff --git a/sample/tx/hello_sample_hsm.c b/sample/tx/hello_sample_hsm.c index c862e1dcb..15ded5ff3 100644 --- a/sample/tx/hello_sample_hsm.c +++ b/sample/tx/hello_sample_hsm.c @@ -128,7 +128,7 @@ const char* g_hw_abi = } */ -void usage() +void usage(void) { printf("Desc: HelloWorld contract sample with hsm key pair\n"); printf( diff --git a/sample/tx/tx_struct_test.c b/sample/tx/tx_struct_test.c new file mode 100644 index 000000000..911957ec0 --- /dev/null +++ b/sample/tx/tx_struct_test.c @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file tx_struct_test.c + * @author: lucasli + * @date 2023-04-25 + */ +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_rpc.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_abi.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include +#include +#include +#include +#include +#include + + +#ifdef _WIN32 +#include +#else +#include +#endif + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +// 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; + } +} +*/ +const char* g_hw_bin = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f72" + "6c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50" + "610107565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928260" + "1f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100" + "d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082" + "11156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe60806040" + "5234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c1461" + "00f6575b600080fd5b6100f46004803603602081101561005157600080fd5b81019080803590602001906401000000" + "0081111561006e57600080fd5b82018360208201111561008057600080fd5b80359060200191846001830284011164" + "0100000000831117156100a257600080fd5b91908080601f0160208091040260200160405190810160405280939291" + "90818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050" + "50610179565b005b6100fe610193565b60405180806020018281038252838181518152602001915080519060200190" + "80838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f1680" + "1561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8060" + "00908051906020019061018f929190610235565b5050565b6060600080546001816001161561010002031660029004" + "80601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203" + "1660029004801561022b5780601f106102005761010080835404028352916020019161022b565b8201919060005260" + "20600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b8280" + "54600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102765780" + "5160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591" + "602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760" + "008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5" + "072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; + +const char* g_hw_sm_bin = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f72" + "6c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50" + "610107565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928260" + "1f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100" + "d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082" + "11156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe60806040" + "5234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f1461" + "00be575b600080fd5b610043610179565b604051808060200182810382528381815181526020019150805190602001" + "9080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f16" + "80156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61" + "0177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f1576000" + "80fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561" + "012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380" + "828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b6060" + "60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190" + "818152602001828054600181600116156101000203166002900480156102115780601f106101e65761010080835404" + "0283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f45782" + "9003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b8280" + "54600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102765780" + "5160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591" + "602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760" + "008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe0" + "52d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; + +const char* g_hw_abi = + "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[]," + "\"name\":\"get\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]" + ",\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":" + "\"string\",\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[]," + "\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + +/* +{ + "6d4ce63c": "get()", + "4ed3885e": "set(string)" +} + +{ + "299f7f9d": "get()", + "3590b49f": "set(string)" +} +*/ + +void usage(void) +{ + printf("Desc: tx struct test sample\n"); + printf("Usage: tx_struct_test \n"); + printf("Example:\n"); + printf(" ./tx_struct_test ./config_sample.ini group0\n"); + exit(0); +} + +int convertCharToHexNumber(char hexChar) { + if (hexChar >= '0' && hexChar <= '9') + return hexChar - '0'; + if (hexChar >= 'a' && hexChar <= 'f') + return hexChar - 'a' + 10; + if (hexChar >= 'A' && hexChar <= 'F') + return hexChar - 'A' + 10; + return -1; +} + +struct bcos_sdk_c_bytes* fromHexString(const char* hexedString) { + unsigned startIndex = (strlen(hexedString) >= 2 && hexedString[0] == '0' && hexedString[1] == 'x') ? 2 : 0; + struct bcos_sdk_c_bytes* bytesData = (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + bytesData->buffer = (uint8_t*)malloc((strlen(hexedString) - startIndex + 1) / 2); + bytesData->length = 0; + + if (strlen(hexedString) % 2) { + int h = convertCharToHexNumber(hexedString[startIndex++]); + if (h == -1) { + // Handle error + free(bytesData->buffer); + free(bytesData); + return NULL; + } + bytesData->buffer[bytesData->length++] = (uint8_t)h; + } + for (unsigned i = startIndex; i < strlen(hexedString); i += 2) { + int highValue = convertCharToHexNumber(hexedString[i]); + int lowValue = convertCharToHexNumber(hexedString[i + 1]); + if (highValue == -1 || lowValue == -1) { + // Handle error + free(bytesData->buffer); + free(bytesData); + return NULL; + } + bytesData->buffer[bytesData->length++] = (uint8_t)((highValue << 4) + lowValue); + } + return bytesData; +} + +// contract address +char* contract_address = NULL; + +// callback for rpc interfaces +void on_deploy_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t deploy contract failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + const char* cflag = "contractAddress\" : \""; + // find the "contractAddress": "0xxxxx" + char* p0 = strstr((char*)resp->data, cflag); + if (p0 == NULL) + { + printf("\t cannot find the \"contractAddress\" filed, resp: %s\n", (char*)resp->data); + exit(-1); + } + + char* p1 = (char*)p0 + strlen(cflag); + char* p2 = strstr(p1, "\""); + if (p2 == NULL) + { + printf("\t cannot find the \"contractAddress\" filed, resp: %s\n", (char*)resp->data); + exit(-1); + } + + contract_address = (char*)malloc(p2 - p1 + 1); + + memcpy(contract_address, p1, p2 - p1); + contract_address[p2 - p1] = '\0'; + + printf(" [TxStructTest] contractAddress ===>>>>: %s\n", contract_address); + printf(" [TxStructTest] transaction receipt ===>>>>: %s\n", (char*)resp->data); +} + +/* resp->data 的数据结构 +{ + "id" : 2, + "jsonrpc" : "2.0", + "result" : + { + "blockNumber" : 113, + "checksumContractAddress" : "", + "contractAddress" : "", + "extraData" : "ExtraData", + "from" : "0x69df04bec1c36551be6298f7e4c2f867592a4b37", + "gasUsed" : "13063", + "hash" : "0x7d816bbde4aef3bd4c084b0887982f2c50cb9a50975a4d07328ec5fd5dd4e6e6", + "input" : "0x3590b49f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001748656c6c6f20464953434f2d42434f5320332e30212121000000000000000000", + "logEntries" : [], + "message" : "", + "output" : "0x", + "status" : 0, + "to" : "0xcd6787f79a8da1b4a607dd59c79c7c08209230c1", + "transactionHash" : "0x05424cb9f92e1f1cd9b7ebe7a7e86d628d71c67edc6cf9cadac1967d279f8017", + "version" : 0 + } +} +*/ +void on_send_tx_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t send tx failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + printf(" ===>> send tx resp: %s\n", (char*)resp->data); +} + +void on_call_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t call failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + printf(" ===>> call resp: %s\n", (char*)resp->data); +} + +int main(int argc, char** argv) +{ + if (argc < 3) + { + usage(); + } + + const char* config = argv[1]; + const char* group_id = argv[2]; + + printf("[TxStructTest] params ===>>>> \n"); + printf("\t # config: %s\n", config); + printf("\t # group_id: %s\n", group_id); + + // const char* version = bcos_sdk_version(); + // printf("\t # c-sdk version: \n%s", version); + // bcos_sdk_c_free((void*)version); + + // 1. create sdk object by config + void* sdk = bcos_sdk_create_by_config_file(config); + // check success or not + if (!bcos_sdk_is_last_opr_success()) + { + printf( + " bcos_sdk_create_by_config_file failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructTest] start sdk ... \n"); + + // 2. start bcos c sdk + bcos_sdk_start(sdk); + if (!bcos_sdk_is_last_opr_success()) + { + printf(" [TxStructTest] bcos_sdk_start failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + int sm_crypto = 0; + int wasm = 0; + + // 3. get sm_crypto of the group_id + bcos_sdk_get_group_wasm_and_crypto(sdk, group_id, &wasm, &sm_crypto); + if (!bcos_sdk_is_last_opr_success()) + { + printf(" [CallHello] bcos_sdk_group_sm_crypto failed, error: %s\n", + bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructTest] sm crypto: %d\n", sm_crypto); + // 4. get chain_id of the group_id + const char* chain_id = bcos_sdk_get_group_chain_id(sdk, group_id); + if (!bcos_sdk_is_last_opr_success()) + { + printf(" [TxStructTest] bcos_sdk_get_group_chain_id failed, error: %s\n", + bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructTest] chain id: %s\n", chain_id); + // 5. get blocklimit of the group_id + int64_t block_limit = bcos_rpc_get_block_limit(sdk, group_id); + if (block_limit < 0) + { + printf(" [TxStructTest] group not exist, group: %s\n", group_id); + exit(-1); + } + + printf(" [TxStructTest] block limit: %d\n", (int32_t)block_limit); + // 6. load or create keypair for transaction sign + void* key_pair = bcos_sdk_create_keypair(sm_crypto); + if (!key_pair) + { + printf(" [TxStructTest] create keypair failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + // printf(" [TxStructTest] bcos_sdk_get_keypair_type: %d\n", + // bcos_sdk_get_keypair_type(key_pair)); + + // 7. get account address of the keypair + const char* address = bcos_sdk_get_keypair_address(key_pair); + printf(" [TxStructTest] new account, address: %s\n", address); + + char* tx_hash = NULL; + char* signed_tx = NULL; + const char* extra_data = "ExtraData"; + + printf(" [TxStructTest] extra_data: %s\n", extra_data); + // 8. deploy HelloWorld contract + // 8.1 create signed transaction + bcos_sdk_create_signed_transaction_ver_extra_data(key_pair, group_id, chain_id, "", + sm_crypto ? g_hw_sm_bin : g_hw_bin, "", block_limit, 0, extra_data, &tx_hash, &signed_tx); + + printf(" [TxStructTest] create deploy contract transaction success, tx_hash: %s\n", tx_hash); + // 8.2 call rpc interface, send transaction + bcos_rpc_send_transaction(sdk, group_id, "", signed_tx, 0, on_deploy_resp_callback, NULL); + + // wait for async operation done, just for sample + sleep(5); + + printf(" [TxStructTest] set operation\n"); + // 9. HelloWorld set + // 9.1 abi encode params + const char* set_data = + bcos_sdk_abi_encode_method(g_hw_abi, "set", "[\"Hello FISCO-BCOS 3.0!!!\"]", sm_crypto); + // 9.2 create signed transaction + { + // 9.2.1 create transaction data with hex input + struct bcos_sdk_c_transaction_data* transaction_data = bcos_sdk_create_transaction_data_struct_with_hex_input( + group_id, chain_id, contract_address, set_data, g_hw_abi, block_limit); + // create transaction data with bytes input + struct bcos_sdk_c_bytes* input_bytes = fromHexString(set_data); + transaction_data = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, contract_address, input_bytes->buffer, input_bytes->length, g_hw_abi, block_limit); + + // 9.2.1.1 encode tx data to hex + const char* hex_tx_data = bcos_sdk_encode_transaction_data_struct_to_hex(transaction_data); + printf(" [TxStructTest] tx_data_hex: %s\n", hex_tx_data); + // 9.2.1.2 decode hex tx data + struct bcos_sdk_c_transaction_data* decode_tx_data = bcos_sdk_decode_transaction_data_struct_from_hex(hex_tx_data); + // 9.2.1.3 encode tx data to json + const char* json_tx_data = bcos_sdk_encode_transaction_data_struct_to_json(transaction_data); + printf(" [TxStructTest] tx_data_json: %s\n", json_tx_data); + // 9.2.1.4 decode json to tx data struct + decode_tx_data = bcos_sdk_decode_transaction_data_struct_from_json(json_tx_data); + + // 9.2.2 calc transaction data hash + const char* transaction_data_hash = + bcos_sdk_calc_transaction_data_struct_hash(sm_crypto, decode_tx_data); + printf(" [TxStructTest] set tx hash: %s\n", transaction_data_hash); + transaction_data_hash = bcos_sdk_calc_transaction_data_struct_hash_with_hex(sm_crypto, hex_tx_data); + printf(" [TxStructTest] set tx hash with tx_data_hex: %s\n", transaction_data_hash); + + // 9.2.3 sign transaction hash + const char* signed_hash = + bcos_sdk_sign_transaction_data_hash(key_pair, transaction_data_hash); + + // 9.2.4 create signed transaction + const char* signed_tx = bcos_sdk_create_encoded_transaction( + decode_tx_data, signed_hash, transaction_data_hash, 0, extra_data); + + // 9.2.4.1 create transaction struct + struct bcos_sdk_c_transaction* transaction = bcos_sdk_create_transaction_struct(decode_tx_data, + signed_hash, transaction_data_hash, 0, extra_data); + // 9.2.4.2 encode tx to hex + const char* hex_tx = bcos_sdk_encode_transaction_struct_to_hex(transaction); + printf(" [TxStructTest] tx_hex: %s\n", hex_tx); + // 9.2.4.3 decode hex to tx + struct bcos_sdk_c_transaction* decode_tx = bcos_sdk_decode_transaction_struct_from_hex(hex_tx); + // 9.2.4.4 encode tx to json + const char* json_tx = bcos_sdk_encode_transaction_struct_to_json(decode_tx); + printf(" [TxStructTest] tx_json: %s\n", json_tx); + // 9.2.4.5 decode json to tx + decode_tx = bcos_sdk_decode_transaction_struct_from_json(json_tx); + const char* hex_tx2 = bcos_sdk_encode_transaction_struct_to_hex(decode_tx); + + printf(" [TxStructTest] signed_tx: %s\n", signed_tx); + printf(" [TxStructTest] hex_tx: %s\n", hex_tx); + printf(" [TxStructTest] hex_tx2: %s\n", hex_tx2); + + // 9.3 call rpc interface, sendTransaction + bcos_rpc_send_transaction(sdk, group_id, "", hex_tx2, 0, on_send_tx_resp_callback, NULL); + + // wait for async operation done, just for sample + sleep(3); + + // free + if (input_bytes && input_bytes->buffer) + { + bcos_sdk_c_free(input_bytes->buffer); + } + bcos_sdk_destroy_transaction_data_struct(transaction_data); + bcos_sdk_destroy_transaction_data_struct(decode_tx_data); + bcos_sdk_destroy_transaction_struct(transaction); + bcos_sdk_destroy_transaction_struct(decode_tx); + bcos_sdk_c_free((void*)transaction_data_hash); + bcos_sdk_c_free((void*)signed_hash); + bcos_sdk_c_free((void*)signed_tx); + bcos_sdk_c_free((void*)hex_tx_data); + bcos_sdk_c_free((void*)json_tx_data); + bcos_sdk_c_free((void*)hex_tx); + bcos_sdk_c_free((void*)json_tx); + } + + // wait for async operation done, just for sample + sleep(3); + + // free chain_id + bcos_sdk_c_free((void*)chain_id); + // free tx_hash + bcos_sdk_c_free((void*)tx_hash); + // free signed_tx + bcos_sdk_c_free((void*)signed_tx); + // free address + bcos_sdk_c_free((void*)address); + if (contract_address) + { + bcos_sdk_c_free((void*)contract_address); + } + + // stop sdk + bcos_sdk_stop(sdk); + // release sdk + bcos_sdk_destroy(sdk); + // release keypair + bcos_sdk_destroy_keypair(key_pair); + + return 0; +} diff --git a/sample/tx/tx_struct_v1_test.c b/sample/tx/tx_struct_v1_test.c new file mode 100644 index 000000000..869f85bf0 --- /dev/null +++ b/sample/tx/tx_struct_v1_test.c @@ -0,0 +1,505 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file tx_struct_v1_test.c + * @author: lucasli + * @date 2023-11-29 + */ +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_rpc.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_abi.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include +#include +#include +#include +#include +#include + + +#ifdef _WIN32 +#include +#else +#include +#endif + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +// 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; + } +} +*/ +const char* g_hw_bin = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f72" + "6c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50" + "610107565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928260" + "1f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100" + "d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082" + "11156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe60806040" + "5234801561001057600080fd5b50600436106100365760003560e01c80634ed3885e1461003b5780636d4ce63c1461" + "00f6575b600080fd5b6100f46004803603602081101561005157600080fd5b81019080803590602001906401000000" + "0081111561006e57600080fd5b82018360208201111561008057600080fd5b80359060200191846001830284011164" + "0100000000831117156100a257600080fd5b91908080601f0160208091040260200160405190810160405280939291" + "90818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050" + "50610179565b005b6100fe610193565b60405180806020018281038252838181518152602001915080519060200190" + "80838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f1680" + "1561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8060" + "00908051906020019061018f929190610235565b5050565b6060600080546001816001161561010002031660029004" + "80601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203" + "1660029004801561022b5780601f106102005761010080835404028352916020019161022b565b8201919060005260" + "20600020905b81548152906001019060200180831161020e57829003601f168201915b5050505050905090565b8280" + "54600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102765780" + "5160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591" + "602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760" + "008160009055506001016102bb565b5090565b9056fea2646970667358221220b5943f43c48cc93c6d71cdcf27aee5" + "072566c88755ce9186e32ce83b24e8dc6c64736f6c634300060a0033"; + +const char* g_hw_sm_bin = + "608060405234801561001057600080fd5b506040518060400160405280600d81526020017f48656c6c6f2c20576f72" + "6c6421000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50" + "610107565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928260" + "1f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100" + "d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082" + "11156101005760008160009055506001016100e8565b5090565b90565b610310806101166000396000f3fe60806040" + "5234801561001057600080fd5b50600436106100365760003560e01c8063299f7f9d1461003b5780633590b49f1461" + "00be575b600080fd5b610043610179565b604051808060200182810382528381815181526020019150805190602001" + "9080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f16" + "80156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61" + "0177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f1576000" + "80fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561" + "012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380" + "828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b6060" + "60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190" + "818152602001828054600181600116156101000203166002900480156102115780601f106101e65761010080835404" + "0283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f45782" + "9003601f168201915b5050505050905090565b8060009080519060200190610231929190610235565b5050565b8280" + "54600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102765780" + "5160ff19168380011785556102a4565b828001600101855582156102a4579182015b828111156102a3578251825591" + "602001919060010190610288565b5b5090506102b191906102b5565b5090565b6102d791905b808211156102d35760" + "008160009055506001016102bb565b5090565b9056fea26469706673582212209871cb2bcf390d53645807cbaedfe0" + "52d739ef9cff9d84787f74c4f379e1854664736f6c634300060a0033"; + +const char* g_hw_abi = + "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[]," + "\"name\":\"get\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]" + ",\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":" + "\"string\",\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[]," + "\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + +/* +{ + "6d4ce63c": "get()", + "4ed3885e": "set(string)" +} + +{ + "299f7f9d": "get()", + "3590b49f": "set(string)" +} +*/ + +void usage(void) +{ + printf("Desc: tx struct v1 test sample\n"); + printf("Usage: tx_struct_v1_test \n"); + printf("Example:\n"); + printf(" ./tx_struct_v1_test ./config.ini group0\n"); + exit(0); +} + +int convertCharToHexNumber(char hexChar) +{ + if (hexChar >= '0' && hexChar <= '9') + return hexChar - '0'; + if (hexChar >= 'a' && hexChar <= 'f') + return hexChar - 'a' + 10; + if (hexChar >= 'A' && hexChar <= 'F') + return hexChar - 'A' + 10; + return -1; +} + +struct bcos_sdk_c_bytes* fromHexString(const char* hexedString) +{ + unsigned startIndex = + (strlen(hexedString) >= 2 && hexedString[0] == '0' && hexedString[1] == 'x') ? 2 : 0; + struct bcos_sdk_c_bytes* bytesData = + (struct bcos_sdk_c_bytes*)malloc(sizeof(struct bcos_sdk_c_bytes)); + bytesData->buffer = (uint8_t*)malloc((strlen(hexedString) - startIndex + 1) / 2); + bytesData->length = 0; + + if (strlen(hexedString) % 2) + { + int h = convertCharToHexNumber(hexedString[startIndex++]); + if (h == -1) + { + // Handle error + free(bytesData->buffer); + free(bytesData); + return NULL; + } + bytesData->buffer[bytesData->length++] = (uint8_t)h; + } + for (unsigned i = startIndex; i < strlen(hexedString); i += 2) + { + int highValue = convertCharToHexNumber(hexedString[i]); + int lowValue = convertCharToHexNumber(hexedString[i + 1]); + if (highValue == -1 || lowValue == -1) + { + // Handle error + free(bytesData->buffer); + free(bytesData); + return NULL; + } + bytesData->buffer[bytesData->length++] = (uint8_t)((highValue << 4) + lowValue); + } + return bytesData; +} + +// contract address +char* contract_address = NULL; + +// callback for rpc interfaces +void on_deploy_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t deploy contract failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + const char* cflag = "contractAddress\" : \""; + // find the "contractAddress": "0xxxxx" + char* p0 = strstr((char*)resp->data, cflag); + if (p0 == NULL) + { + printf("\t cannot find the \"contractAddress\" filed, resp: %s\n", (char*)resp->data); + exit(-1); + } + + char* p1 = (char*)p0 + strlen(cflag); + char* p2 = strstr(p1, "\""); + if (p2 == NULL) + { + printf("\t cannot find the \"contractAddress\" filed, resp: %s\n", (char*)resp->data); + exit(-1); + } + + contract_address = (char*)malloc(p2 - p1 + 1); + + memcpy(contract_address, p1, p2 - p1); + contract_address[p2 - p1] = '\0'; + + printf(" [TxStructv1Test] contractAddress ===>>>>: %s\n", contract_address); + printf(" [TxStructv1Test] transaction receipt ===>>>>: %s\n", (char*)resp->data); +} + +/* resp->data 的数据结构 +{ + "id" : 2, + "jsonrpc" : "2.0", + "result" : + { + "blockNumber" : 113, + "checksumContractAddress" : "", + "contractAddress" : "", + "extraData" : "ExtraData", + "from" : "0x69df04bec1c36551be6298f7e4c2f867592a4b37", + "gasUsed" : "13063", + "hash" : "0x7d816bbde4aef3bd4c084b0887982f2c50cb9a50975a4d07328ec5fd5dd4e6e6", + "input" : +"0x3590b49f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001748656c6c6f20464953434f2d42434f5320332e30212121000000000000000000", + "logEntries" : [], + "message" : "", + "output" : "0x", + "status" : 0, + "to" : "0xcd6787f79a8da1b4a607dd59c79c7c08209230c1", + "transactionHash" : "0x05424cb9f92e1f1cd9b7ebe7a7e86d628d71c67edc6cf9cadac1967d279f8017", + "version" : 0 + } +} +*/ +void on_send_tx_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t send tx failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + printf(" ===>> send tx resp: %s\n", (char*)resp->data); +} + +void on_call_resp_callback(struct bcos_sdk_c_struct_response* resp) +{ + if (resp->error != BCOS_SDK_C_SUCCESS) + { + printf("\t call failed, error: %d, message: %s\n", resp->error, resp->desc); + exit(-1); + } + + printf(" ===>> call resp: %s\n", (char*)resp->data); +} + +int main(int argc, char** argv) +{ + if (argc < 3) + { + usage(); + } + + const char* config = argv[1]; + const char* group_id = argv[2]; + + printf("[TxStructv1Test] params ===>>>> \n"); + printf("\t # config: %s\n", config); + printf("\t # group_id: %s\n", group_id); + + // const char* version = bcos_sdk_version(); + // printf("\t # c-sdk version: \n%s", version); + // bcos_sdk_c_free((void*)version); + + // 1. create sdk object by config + void* sdk = bcos_sdk_create_by_config_file(config); + // check success or not + if (!bcos_sdk_is_last_opr_success()) + { + printf( + " bcos_sdk_create_by_config_file failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructv1Test] start sdk ... \n"); + + // 2. start bcos c sdk + bcos_sdk_start(sdk); + if (!bcos_sdk_is_last_opr_success()) + { + printf( + " [TxStructv1Test] bcos_sdk_start failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + int sm_crypto = 0; + int wasm = 0; + + // 3. get sm_crypto of the group_id + bcos_sdk_get_group_wasm_and_crypto(sdk, group_id, &wasm, &sm_crypto); + if (!bcos_sdk_is_last_opr_success()) + { + printf(" [CallHello] bcos_sdk_group_sm_crypto failed, error: %s\n", + bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructv1Test] sm crypto: %d\n", sm_crypto); + // 4. get chain_id of the group_id + const char* chain_id = bcos_sdk_get_group_chain_id(sdk, group_id); + if (!bcos_sdk_is_last_opr_success()) + { + printf(" [TxStructv1Test] bcos_sdk_get_group_chain_id failed, error: %s\n", + bcos_sdk_get_last_error_msg()); + exit(-1); + } + + printf(" [TxStructv1Test] chain id: %s\n", chain_id); + // 5. get blocklimit of the group_id + int64_t block_limit = bcos_rpc_get_block_limit(sdk, group_id); + if (block_limit < 0) + { + printf(" [TxStructv1Test] group not exist, group: %s\n", group_id); + exit(-1); + } + + printf(" [TxStructv1Test] block limit: %d\n", (int32_t)block_limit); + // 6. load or create keypair for transaction sign + void* key_pair = bcos_sdk_create_keypair(sm_crypto); + if (!key_pair) + { + printf( + " [TxStructv1Test] create keypair failed, error: %s\n", bcos_sdk_get_last_error_msg()); + exit(-1); + } + + // printf(" [TxStructv1Test] bcos_sdk_get_keypair_type: %d\n", + // bcos_sdk_get_keypair_type(key_pair)); + + // 7. get account address of the keypair + const char* address = bcos_sdk_get_keypair_address(key_pair); + printf(" [TxStructv1Test] new account, address: %s\n", address); + + const char* extra_data = "ExtraData"; + const char* value = "33"; + const char* gasPrice = "0"; + int64_t gasLimit = 0; + const char* maxFeePerGas = "11"; + const char* maxPriorityFeePerGas = "22"; + + // printf(" [TxStructv1Test] extra_data: %s, value: %s, gasPrice: %s, gasLimit: %ld, + // maxFeePerGas: %s, maxPriorityFeePerGas: %s\n", extra_data, value, gasPrice, gasLimit, + // maxFeePerGas, maxPriorityFeePerGas); + + // 8. deploy HelloWorld contract + struct bcos_sdk_c_transaction_data_v1* transaction_data_v1_deploy = + bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, "", + sm_crypto ? g_hw_sm_bin : g_hw_bin, "", block_limit, value, gasPrice, gasLimit, + maxFeePerGas, maxPriorityFeePerGas); + const char* transaction_data_hash_deploy = + bcos_sdk_calc_transaction_data_struct_hash_v1(sm_crypto, transaction_data_v1_deploy); + const char* signed_hash_deploy = + bcos_sdk_sign_transaction_data_hash(key_pair, transaction_data_hash_deploy); + const char* signed_tx_deploy = + bcos_sdk_create_encoded_transaction_v1(transaction_data_v1_deploy, signed_hash_deploy, + transaction_data_hash_deploy, 0, extra_data); + printf(" [TxStructv1Test] create deploy contract transaction success, signed_tx_deploy: %s\n", + signed_tx_deploy); + + // call rpc interface, send transaction + bcos_rpc_send_transaction( + sdk, group_id, "", signed_tx_deploy, 0, on_deploy_resp_callback, NULL); + // wait for async operation done, just for sample + sleep(5); + + printf(" [TxStructv1Test] set operation\n"); + // 9. HelloWorld set + // 9.1 abi encode params + const char* set_data = + bcos_sdk_abi_encode_method(g_hw_abi, "set", "[\"Hello FISCO-BCOS 3.0!!!\"]", sm_crypto); + // 9.2 create signed transaction + { + // 9.2.1 create transaction data with hex input + struct bcos_sdk_c_transaction_data_v1* transaction_data_v1 = + bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, + contract_address, set_data, g_hw_abi, block_limit, value, gasPrice, gasLimit, + maxFeePerGas, maxPriorityFeePerGas); + // create transaction data with bytes input + struct bcos_sdk_c_bytes* input_bytes = fromHexString(set_data); + transaction_data_v1 = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, + chain_id, contract_address, input_bytes->buffer, input_bytes->length, g_hw_abi, + block_limit, value, gasPrice, gasLimit, maxFeePerGas, maxPriorityFeePerGas); + + // 9.2.1.1 encode tx data to hex + const char* hex_tx_data = + bcos_sdk_encode_transaction_data_struct_to_hex_v1(transaction_data_v1); + printf(" [TxStructv1Test] tx_data_hex: %s\n", hex_tx_data); + // 9.2.1.2 decode hex tx data + struct bcos_sdk_c_transaction_data_v1* decode_tx_data = + bcos_sdk_decode_transaction_data_struct_from_hex_v1(hex_tx_data); + // 9.2.1.3 encode tx data to json + const char* json_tx_data = + bcos_sdk_encode_transaction_data_struct_to_json_v1(decode_tx_data); + printf(" [TxStructv1Test] tx_data_json: %s\n", json_tx_data); + // 9.2.1.4 decode json to tx data struct + decode_tx_data = bcos_sdk_decode_transaction_data_struct_from_json_v1(json_tx_data); + + // 9.2.2 calc transaction data hash + const char* transaction_data_hash = + bcos_sdk_calc_transaction_data_struct_hash_v1(sm_crypto, decode_tx_data); + printf(" [TxStructv1Test] set tx hash: %s\n", transaction_data_hash); + transaction_data_hash = + bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(sm_crypto, hex_tx_data); + printf(" [TxStructv1Test] set tx hash with tx_data_hex: %s\n", transaction_data_hash); + + // 9.2.3 sign transaction hash + const char* signed_hash = + bcos_sdk_sign_transaction_data_hash(key_pair, transaction_data_hash); + + // 9.2.4 create signed transaction + const char* signed_tx = bcos_sdk_create_encoded_transaction_v1( + decode_tx_data, signed_hash, transaction_data_hash, 0, extra_data); + + // 9.2.4.1 create transaction struct + struct bcos_sdk_c_transaction_v1* transaction = bcos_sdk_create_transaction_struct_v1( + decode_tx_data, signed_hash, transaction_data_hash, 0, extra_data); + // 9.2.4.2 encode tx to hex + const char* hex_tx = bcos_sdk_encode_transaction_struct_to_hex_v1(transaction); + printf(" [TxStructv1Test] tx_hex: %s\n", hex_tx); + // 9.2.4.3 decode hex to tx + struct bcos_sdk_c_transaction_v1* decode_tx = + bcos_sdk_decode_transaction_struct_from_hex_v1(hex_tx); + // 9.2.4.4 encode tx to json + const char* json_tx = bcos_sdk_encode_transaction_struct_to_json_v1(decode_tx); + printf(" [TxStructv1Test] tx_json: %s\n", json_tx); + // 9.2.4.5 decode json to tx + decode_tx = bcos_sdk_decode_transaction_struct_from_json_v1(json_tx); + const char* hex_tx2 = bcos_sdk_encode_transaction_struct_to_hex_v1(decode_tx); + + printf(" [TxStructv1Test] signed_tx: %s\n", signed_tx); + printf(" [TxStructv1Test] hex_tx: %s\n", hex_tx); + printf(" [TxStructv1Test] hex_tx2: %s\n", hex_tx2); + + // 9.3 call rpc interface, sendTransaction + bcos_rpc_send_transaction(sdk, group_id, "", signed_tx, 0, on_send_tx_resp_callback, NULL); + + // wait for async operation done, just for sample + sleep(3); + + // free + if (input_bytes && input_bytes->buffer) + { + bcos_sdk_c_free(input_bytes->buffer); + } + bcos_sdk_destroy_transaction_data_struct_v1(transaction_data_v1); + bcos_sdk_destroy_transaction_data_struct_v1(decode_tx_data); + bcos_sdk_destroy_transaction_struct_v1(transaction); + bcos_sdk_destroy_transaction_struct_v1(decode_tx); + bcos_sdk_c_free((void*)transaction_data_hash); + bcos_sdk_c_free((void*)signed_hash); + bcos_sdk_c_free((void*)signed_tx); + bcos_sdk_c_free((void*)hex_tx_data); + bcos_sdk_c_free((void*)json_tx_data); + bcos_sdk_c_free((void*)hex_tx); + bcos_sdk_c_free((void*)json_tx); + } + + // wait for async operation done, just for sample + sleep(3); + + // free chain_id + bcos_sdk_c_free((void*)chain_id); + // free address + bcos_sdk_c_free((void*)address); + if (contract_address) + { + bcos_sdk_c_free((void*)contract_address); + } + + // stop sdk + bcos_sdk_stop(sdk); + // release sdk + bcos_sdk_destroy(sdk); + // release keypair + bcos_sdk_destroy_keypair(key_pair); + + return 0; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0fab5d5f1..3b710b476 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# Top-level CMake file for ut of bcos-c-sdk +# Top-level CMake file for ut of bcos-rpc # ------------------------------------------------------------------------------ # Copyright (C) 2021 FISCO BCOS. # SPDX-License-Identifier: Apache-2.0 @@ -15,14 +15,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # ------------------------------------------------------------------------------ -file(GLOB_RECURSE SOURCES "unittests/*.cpp" "unittests/*.h" "unittests/*.sol") + +file(GLOB_RECURSE SOURCES "*.cpp" "*.h") # cmake settings include(SearchTestCases) -set(TEST_BINARY_NAME test-bcos-rpc) -config_test_cases("" "${SOURCES}" bin/${TEST_BINARY_NAME} "") +set(TEST_BINARY_NAME test-bcos-c-sdk) +config_test_cases("" "${SOURCES}" ${TEST_BINARY_NAME} "") + +add_executable(${TEST_BINARY_NAME} ${SOURCES}) +target_include_directories(${TEST_BINARY_NAME} PRIVATE . ${CMAKE_SOURCE_DIR}) -# ut -# add_executable(${TEST_BINARY_NAME} ${SOURCES}) -# target_include_directories(${TEST_BINARY_NAME} PRIVATE .) -# target_link_libraries(${TEST_BINARY_NAME}) +if(BUILD_SHARED_LIBS) + target_link_libraries(${TEST_BINARY_NAME} ${BCOS_C_SDK_TARGET} Boost::log Boost::unit_test_framework) +else () + target_link_libraries(${TEST_BINARY_NAME} ${BCOS_C_SDK_STATIC_TARGET} Boost::log Boost::unit_test_framework) +endif () diff --git a/test/testMain.cpp b/test/testMain.cpp new file mode 100644 index 000000000..539a4cfb1 --- /dev/null +++ b/test/testMain.cpp @@ -0,0 +1,4 @@ +#define BOOST_TEST_MODULE bcos_c_sdk_test +#define BOOST_TEST_MAIN + +#include \ No newline at end of file diff --git a/test/testTransaction.cpp b/test/testTransaction.cpp new file mode 100644 index 000000000..f85afe626 --- /dev/null +++ b/test/testTransaction.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file testTransaction.cpp + * @author: lucasli + * @date 2023-09-12 + */ + +#include "bcos-c-sdk/bcos_sdk_c.h" +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_abi.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx.h" +#include +#include + +#include +#include + +using namespace bcos; + +struct TestTxFixture +{ +}; + +BOOST_FIXTURE_TEST_SUITE(TransactionTest, TestTxFixture) +const char* g_hw_abi = + "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[]," + "\"name\":\"get\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]" + ",\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":" + "\"string\",\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[]," + "\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + +BOOST_AUTO_TEST_CASE(testTxData) +{ + auto sm_crypto = 0; + auto group_id = "group0"; + auto chain_id = "chain0"; + int64_t block_limit = 11; + const char* extra_data = "ExtraData"; + void* key_pair = bcos_sdk_create_keypair(sm_crypto); + + const char* set_data = + bcos_sdk_abi_encode_method(g_hw_abi, "set", "[\"Hello FISCO-BCOS 3.0!!!\"]", sm_crypto); + + void* transaction_data = bcos_sdk_create_transaction_data( + group_id, chain_id, nullptr, set_data, g_hw_abi, block_limit); + + auto success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + + const char* transaction_data_hash = + bcos_sdk_calc_transaction_data_hash(sm_crypto, transaction_data); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + + const char* signed_hash = bcos_sdk_sign_transaction_data_hash(key_pair, transaction_data_hash); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + + const char* signed_tx = bcos_sdk_create_signed_transaction_with_signed_data_ver_extra_data( + transaction_data, signed_hash, transaction_data_hash, 0, extra_data); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + + void* txRaw = bcos_sdk_decode_transaction(signed_tx); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + auto tx = (bcostars::Transaction*)txRaw; + BOOST_TEST(tx->extraData == extra_data); + BOOST_TEST(tx->data.version == 0); + BOOST_TEST(tx->data.blockLimit == block_limit); + BOOST_TEST(tx->data.groupID == group_id); + BOOST_TEST(tx->data.chainID == chain_id); + BOOST_TEST(tx->data.abi == g_hw_abi); + + + bcos_sdk_destroy_transaction_data(transaction_data); + bcos_sdk_destroy_transaction(txRaw); + bcos_sdk_c_free((void*)transaction_data_hash); + bcos_sdk_c_free((void*)signed_hash); + bcos_sdk_c_free((void*)signed_tx); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/testTransactionStruct.cpp b/test/testTransactionStruct.cpp new file mode 100644 index 000000000..4d212a048 --- /dev/null +++ b/test/testTransactionStruct.cpp @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file testTransactionStruct.cpp + * @author: xingqiangbai + * @date 2023-07-06 + */ + +#include "bcos-c-sdk/bcos_sdk_c.h" +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_rpc.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_abi.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h" +#include +#include +#include + +using namespace bcos; + +struct TestTxStructFixture +{ +}; + +BOOST_FIXTURE_TEST_SUITE(TransactionStructTest, TestTxStructFixture) + +const auto input = + "0x3590b49f00000000000000000000000000000000000000000000000000000000000000200000000000000000" + "00000000000000000000000000000000000000000000001748656c6c6f20464953434f2d42434f5320332e3021" + "2121000000000000000000"; + +const char* abi_with_chinese = + "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[]," + "\"name\":\"get\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"李伟光\",\"type\":" + "\"string\"}]" + ",\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":" + "\"string\",\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[]," + "\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + +struct bcos_sdk_c_transaction_data* createTxDataStructWithHexInput() +{ + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 1; + auto txDataWithHex = bcos_sdk_create_transaction_data_struct_with_hex_input( + group_id, chain_id, to, input, abi, block_limit); + + return txDataWithHex; +} + +struct bcos_sdk_c_transaction_data* createTxDataStructWithByteInput() +{ + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 1; + auto bytesInput = fromHexString(input); + + auto txDataWithBytes = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + + return txDataWithBytes; +} + +void compareTxStruct(struct bcos_sdk_c_transaction* txStruct, + struct bcos_sdk_c_transaction_data* txDataStruct, const char* signature, const char* extraData, + int64_t attribute) +{ + // transaction_data + BOOST_TEST(txStruct != nullptr); + BOOST_TEST(txStruct->transaction_data->version == txDataStruct->version); + BOOST_TEST(txStruct->transaction_data->block_limit == txDataStruct->block_limit); + BOOST_TEST(txStruct->transaction_data->chain_id == txDataStruct->chain_id); + BOOST_TEST(txStruct->transaction_data->version == txDataStruct->version); + BOOST_TEST(txStruct->transaction_data->group_id == txDataStruct->group_id); + BOOST_TEST(txStruct->transaction_data->nonce == txDataStruct->nonce); + BOOST_TEST(txStruct->transaction_data->to == txDataStruct->to); + BOOST_TEST(txStruct->transaction_data->abi == txDataStruct->abi); + std::string txDataInputString( + reinterpret_cast(txDataStruct->input->buffer), txDataStruct->input->length); + std::string txInputString(reinterpret_cast(txStruct->transaction_data->input->buffer), + txStruct->transaction_data->input->length); + BOOST_TEST(txDataInputString == txInputString); + + // signature + std::string txStructSignatureString( + reinterpret_cast(txStruct->signature->buffer), txStruct->signature->length); + auto bytesSignature = fromHexString(signature); + std::string fromSignatureHexString(bytesSignature->begin(), bytesSignature->end()); + BOOST_TEST(fromSignatureHexString == txStructSignatureString); + + // attribute + BOOST_TEST(txStruct->attribute == attribute); + + // extra_data + BOOST_TEST(txStruct->extra_data == extraData); +} + +BOOST_AUTO_TEST_CASE(testCreateTxDataStructWithHexInput) +{ + // create transaction_data_struct failed (block_limit = 0) + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 0; + auto txData = bcos_sdk_create_transaction_data_struct_with_hex_input( + group_id, chain_id, to, input, abi, block_limit); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("block limit must > 0")); + + // create transaction_data_struct failed (input = "") + block_limit = 1; + txData = bcos_sdk_create_transaction_data_struct_with_hex_input( + group_id, chain_id, to, "", abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("input can not be empty string")); + + // create transaction_data_struct success + txData = bcos_sdk_create_transaction_data_struct_with_hex_input( + group_id, chain_id, to, input, abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + auto bytesInput = fromHexString(input); + std::string fromInputHexString(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString == fromInputHexString); + + bcos_sdk_destroy_transaction_data_struct(txData); +} + +BOOST_AUTO_TEST_CASE(testCreateTxDataStructWithByteInput) +{ + auto bytesInput = fromHexString(input); + + // create transaction_data_struct failed (block_limit = 0) + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + uint32_t bytes_input_length = 10; + int64_t block_limit = 0; + auto txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytes_input_length, abi, block_limit); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("block limit must > 0")); + + // create transaction_data_struct failed (bytes_input_length = 0) + bytes_input_length = 0; + block_limit = 1; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytes_input_length, abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("bytes input length must > 0")); + + // create transaction_data_struct failed (group_id = NULL) + group_id = nullptr; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_data_struct failed (group_id has Chinese characters) + group_id = "区块链群组1"; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + std::string fromInputHexString1(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString1( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString1 == fromInputHexString1); + + // create transaction_data_struct failed (chain_id = NULL) + chain_id = nullptr; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_data_struct failed (chain_id has Chinese characters) + chain_id = "区块链1"; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + std::string fromInputHexString2(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString2( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString2 == fromInputHexString2); + + // create transaction_data_struct failed (abi has Chinese characters) + chain_id = ""; + txData = bcos_sdk_create_transaction_data_struct_with_bytes(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi_with_chinese, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi_with_chinese); + BOOST_TEST(txData->block_limit == block_limit); + std::string fromInputHexString3(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString3( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString3 == fromInputHexString3); + + // create transaction_data_struct success + group_id = ""; + txData = bcos_sdk_create_transaction_data_struct_with_bytes( + group_id, chain_id, to, bytesInput->data(), bytesInput->size(), abi, block_limit); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + std::string fromInputHexString(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString == fromInputHexString); + + bcos_sdk_destroy_transaction_data_struct(txData); +} + +BOOST_AUTO_TEST_CASE(testEncodeDecodeTxDataStruct) +{ + auto txDataWithHex = createTxDataStructWithHexInput(); + auto txDataWithBytes = createTxDataStructWithByteInput(); + + // 1. test tx data encode decode hex + // encode to hex failed (transaction_data == NULL) + auto encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex(nullptr); + auto hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(encodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode to hex success + encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex(txDataWithHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex(txDataWithBytes); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode hex failed (transaction_data_hex_str == NULL) + auto decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex(nullptr); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode hex failed (transaction_data_hex_str == "") + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex(""); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hex_str can not be empty string")); + + // decode hex failed (the length of transaction_data_hex_str is not even number) + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex("0xabc"); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("the length of transaction_data_hex_str must be an even number")); + + // decode hex success + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex(encodedTxDataHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(decodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + BOOST_TEST(decodedTxDataHex->version == txDataWithBytes->version); + BOOST_TEST(decodedTxDataHex->group_id == txDataWithBytes->group_id); + BOOST_TEST(decodedTxDataHex->chain_id == txDataWithBytes->chain_id); + BOOST_TEST(decodedTxDataHex->to == txDataWithBytes->to); + BOOST_TEST(decodedTxDataHex->abi == txDataWithBytes->abi); + BOOST_TEST(decodedTxDataHex->block_limit == txDataWithBytes->block_limit); + BOOST_TEST(decodedTxDataHex->nonce == txDataWithBytes->nonce); + std::string txDataInputString( + reinterpret_cast(txDataWithBytes->input->buffer), txDataWithBytes->input->length); + std::string decodedHexTxDataInputString( + reinterpret_cast(decodedTxDataHex->input->buffer), decodedTxDataHex->input->length); + BOOST_TEST(txDataInputString == decodedHexTxDataInputString); + + // 2. test tx data encode decode json + // encode to json failed (transaction_data == NULL) + auto encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json(nullptr); + auto jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(encodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode to json success + encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json(txDataWithHex); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json(txDataWithBytes); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode json failed (transaction_data_json_str == NULL) + auto decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json(nullptr); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode json failed (transaction_data_json_str == "") + decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json(""); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_json_str can not be empty string")); + + // decode json success + decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json(encodedTxDataJson); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(decodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + BOOST_TEST(decodedTxDataJson->version == txDataWithBytes->version); + BOOST_TEST(decodedTxDataJson->group_id == txDataWithBytes->group_id); + BOOST_TEST(decodedTxDataJson->chain_id == txDataWithBytes->chain_id); + BOOST_TEST(decodedTxDataJson->to == txDataWithBytes->to); + BOOST_TEST(decodedTxDataJson->abi == txDataWithBytes->abi); + BOOST_TEST(decodedTxDataJson->block_limit == txDataWithBytes->block_limit); + BOOST_TEST(decodedTxDataJson->nonce == txDataWithBytes->nonce); + std::string decodedJsonTxDataInputJson( + reinterpret_cast(decodedTxDataJson->input->buffer), + decodedTxDataJson->input->length); + BOOST_TEST(txDataInputString == decodedJsonTxDataInputJson); + + bcos_sdk_destroy_transaction_data_struct(txDataWithHex); + bcos_sdk_destroy_transaction_data_struct(txDataWithBytes); + bcos_sdk_destroy_transaction_data_struct(decodedTxDataHex); + bcos_sdk_destroy_transaction_data_struct(decodedTxDataJson); +} + +BOOST_AUTO_TEST_CASE(testCalculateTxDataHash) +{ + auto txDataWithHex = createTxDataStructWithHexInput(); + auto txDataWithByte = createTxDataStructWithByteInput(); + auto encodedtxDataWithHex = bcos_sdk_encode_transaction_data_struct_to_hex(txDataWithHex); + auto encodedtxDataWithByte = bcos_sdk_encode_transaction_data_struct_to_hex(txDataWithByte); + + // 1. test cal tx data hash with struct + // calculate tx data hash failed (cryptoType not in 0,1) + auto cryptoType = 2; + auto txDataHash = bcos_sdk_calc_transaction_data_struct_hash(cryptoType, txDataWithHex); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (cryptoType is negative number) + cryptoType = -11; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash(cryptoType, txDataWithHex); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (transaction_data == NULL) + cryptoType = 1; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash(cryptoType, nullptr); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // calculate tx data hash success (txDataWithHex) + cryptoType = 1; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash(cryptoType, txDataWithHex); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txDataHash != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // calculate tx data hash success (txDataWithByte) + txDataHash = bcos_sdk_calc_transaction_data_struct_hash(cryptoType, txDataWithByte); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txDataHash != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 2. test cal tx data hash with tx_data_hex + // calculate tx data hash with hex failed (cryptoType not in 0,1) + cryptoType = 2; + auto txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (cryptoType is negative number) + cryptoType = -11; + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash with hex failed (transaction_data_hex == NULL) + cryptoType = 1; + txDataHashWithHex = bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, nullptr); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // calculate tx data hash with hex failed (transaction_data_hex == "") + txDataHashWithHex = bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, ""); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hex can not be empty string")); + + // calculate tx data hash with hex success (encodedtxDataWithHex) + cryptoType = 1; + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txDataHashWithHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // calculate tx data hash with hex success (encodedtxDataWithByte) + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex(cryptoType, encodedtxDataWithByte); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txDataHashWithHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 3. compare hash + BOOST_TEST(txDataHash == txDataHashWithHex); + + bcos_sdk_destroy_transaction_data_struct(txDataWithHex); + bcos_sdk_destroy_transaction_data_struct(txDataWithByte); +} + +BOOST_AUTO_TEST_CASE(testCreateTxStruct) +{ + auto txDataStruct = createTxDataStructWithHexInput(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + + // create transaction_struct failed (transaction_data_struct = NULL) + auto txStruct = bcos_sdk_create_transaction_struct( + nullptr, signature, transactionDataHash, attribute, extraData); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (transaction_data_hash = NULL) + txStruct = + bcos_sdk_create_transaction_struct(txDataStruct, signature, nullptr, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (signature = NULL) + txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, nullptr, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (transaction_data_hash = "") + txStruct = + bcos_sdk_create_transaction_struct(txDataStruct, signature, "", attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hash can not be empty string")); + + // create transaction_struct failed (signature = "") + txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, "", transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("signature can not be empty string")); + + // create transaction_struct success (extraData = NULL) + txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, signature, transactionDataHash, attribute, nullptr); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + compareTxStruct(txStruct, txDataStruct, signature, "", attribute); + + // create transaction_struct success + txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, signature, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + compareTxStruct(txStruct, txDataStruct, signature, extraData, attribute); + + bcos_sdk_destroy_transaction_data_struct(txDataStruct); + bcos_sdk_destroy_transaction_struct(txStruct); +} + +BOOST_AUTO_TEST_CASE(testCreateEncodedTx) +{ + auto txDataStruct = createTxDataStructWithHexInput(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + auto txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, signature, transactionDataHash, attribute, extraData); + + // 1. test bcos_sdk_create_encoded_transaction + // create encoded tx failed (transaction_data_struct = NULL) + auto encodedTx = bcos_sdk_create_encoded_transaction( + nullptr, signature, transactionDataHash, attribute, extraData); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (transaction_data_hash = NULL) + encodedTx = + bcos_sdk_create_encoded_transaction(txDataStruct, signature, nullptr, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (signature = NULL) + encodedTx = bcos_sdk_create_encoded_transaction( + txDataStruct, nullptr, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (transaction_data_hash = "") + encodedTx = + bcos_sdk_create_encoded_transaction(txDataStruct, signature, "", attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hash can not be empty string")); + + // create encoded tx failed (signature = "") + encodedTx = bcos_sdk_create_encoded_transaction( + txDataStruct, "", transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("signature can not be empty string")); + + // create encoded tx success + encodedTx = bcos_sdk_create_encoded_transaction( + txDataStruct, signature, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(encodedTx != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 2. test bcos_sdk_encode_transaction_struct_to_hex_ + // create encoded tx with tx_struct failed (transaction_struct == "") + auto encodedTxWithTxStruct = bcos_sdk_encode_transaction_struct_to_hex(nullptr); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(encodedTxWithTxStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx with tx_struct success + encodedTxWithTxStruct = bcos_sdk_encode_transaction_struct_to_hex(txStruct); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(encodedTxWithTxStruct != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 3. compare encodedTx encodedTxWithTxStruct + BOOST_TEST(encodedTx == encodedTxWithTxStruct); + + bcos_sdk_destroy_transaction_data_struct(txDataStruct); + bcos_sdk_destroy_transaction_struct(txStruct); +} + +BOOST_AUTO_TEST_CASE(testEncodeDecodeTxStruct) +{ + auto txDataStruct = createTxDataStructWithHexInput(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + + auto txStruct = bcos_sdk_create_transaction_struct( + txDataStruct, signature, transactionDataHash, attribute, extraData); + + // 1. test tx encode decode hex + // encode tx to hex failed (transaction == NULL) + auto encodedTxHex = bcos_sdk_encode_transaction_struct_to_hex(nullptr); + auto hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(encodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode tx to hex success + encodedTxHex = bcos_sdk_encode_transaction_struct_to_hex(txStruct); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode hex failed (transaction_hex_str == NULL) + auto decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex(nullptr); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode hex failed (transaction_hex_str == "") + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex(""); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_hex_str can not be empty string")); + + // decode hex failed (the length of transaction_hex_str is not even number) + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex("0xabc"); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("the length of transaction_hex_str must be an even number")); + + // decode hex success + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex(encodedTxHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == true); + BOOST_TEST(decodedTxHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + compareTxStruct(decodedTxHex, txDataStruct, signature, extraData, attribute); + + // 2. test tx encode decode json + // encode tx to json failed (transaction == NULL) + auto encodedTxJson = bcos_sdk_encode_transaction_struct_to_json(nullptr); + auto jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(encodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode tx to json success + encodedTxJson = bcos_sdk_encode_transaction_struct_to_json(txStruct); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode json failed (transaction_json_str == NULL) + auto decodedTxJson = bcos_sdk_decode_transaction_struct_from_json(nullptr); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode json failed (transaction_json_str == "") + decodedTxJson = bcos_sdk_decode_transaction_struct_from_json(""); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_json_str can not be empty string")); + + // decode json success + decodedTxJson = bcos_sdk_decode_transaction_struct_from_json(encodedTxJson); + jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(decodedTxJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + compareTxStruct(decodedTxJson, txDataStruct, signature, extraData, attribute); + + bcos_sdk_destroy_transaction_data_struct(txDataStruct); + bcos_sdk_destroy_transaction_struct(txStruct); + bcos_sdk_destroy_transaction_struct(decodedTxHex); + bcos_sdk_destroy_transaction_struct(decodedTxJson); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/testTransactionStructV1.cpp b/test/testTransactionStructV1.cpp new file mode 100644 index 000000000..c059bc7f6 --- /dev/null +++ b/test/testTransactionStructV1.cpp @@ -0,0 +1,909 @@ +/* + * Copyright (C) 2021 FISCO BCOS. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file testTransactionStructv1.cpp + * @author: lucasli + * @date 2023-12-13 + */ + +#include "bcos-c-sdk/bcos_sdk_c.h" +#include "bcos-c-sdk/bcos_sdk_c_error.h" +#include "bcos-c-sdk/bcos_sdk_c_rpc.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_abi.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_keypair.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx.h" +#include "bcos-c-sdk/bcos_sdk_c_uti_tx_struct.h" +#include +#include +#include + +using namespace bcos; + +struct TestTxStructv1Fixture +{ +}; + +BOOST_FIXTURE_TEST_SUITE(TransactionStructv1Test, TestTxStructv1Fixture) + +const auto input = + "0x3590b49f00000000000000000000000000000000000000000000000000000000000000200000000000000000" + "00000000000000000000000000000000000000000000001748656c6c6f20464953434f2d42434f5320332e3021" + "2121000000000000000000"; + +const char* abi_with_chinese = + "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[]," + "\"name\":\"get\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"李伟光\",\"type\":" + "\"string\"}]" + ",\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":" + "\"string\",\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[]," + "\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + +struct bcos_sdk_c_transaction_data_v1* createTxDataStructWithHexInputv1() +{ + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 1; + auto value = "1"; + auto gas_price = "0"; + int64_t gas_limit = 0; + auto max_fee_per_gas = "1"; + auto max_priority_fee_per_gas = "1"; + auto txDataWithHex = bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, + chain_id, to, input, abi, block_limit, value, gas_price, gas_limit, max_fee_per_gas, + max_priority_fee_per_gas); + + return txDataWithHex; +} + +struct bcos_sdk_c_transaction_data_v1* createTxDataStructWithByteInputv1() +{ + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 1; + auto value = "1"; + auto gas_price = "0"; + int64_t gas_limit = 0; + auto max_fee_per_gas = "1"; + auto max_priority_fee_per_gas = "1"; + auto bytesInput = fromHexString(input); + + auto txDataWithBytes = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, + to, bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + + return txDataWithBytes; +} + +void compareTxStruct(struct bcos_sdk_c_transaction_v1* txStruct, + struct bcos_sdk_c_transaction_data_v1* txDataStruct, const char* signature, + const char* extraData, int64_t attribute) +{ + // transaction_data + BOOST_TEST(txStruct != nullptr); + BOOST_TEST(txStruct->transaction_data->version == txDataStruct->version); + BOOST_TEST(txStruct->transaction_data->block_limit == txDataStruct->block_limit); + BOOST_TEST(txStruct->transaction_data->chain_id == txDataStruct->chain_id); + BOOST_TEST(txStruct->transaction_data->version == txDataStruct->version); + BOOST_TEST(txStruct->transaction_data->group_id == txDataStruct->group_id); + BOOST_TEST(txStruct->transaction_data->nonce == txDataStruct->nonce); + BOOST_TEST(txStruct->transaction_data->to == txDataStruct->to); + BOOST_TEST(txStruct->transaction_data->abi == txDataStruct->abi); + BOOST_TEST(txStruct->transaction_data->value == txDataStruct->value); + BOOST_TEST(txStruct->transaction_data->gas_price == txDataStruct->gas_price); + BOOST_TEST(txStruct->transaction_data->gas_limit == txDataStruct->gas_limit); + BOOST_TEST(txStruct->transaction_data->max_fee_per_gas == txDataStruct->max_fee_per_gas); + BOOST_TEST(txStruct->transaction_data->max_priority_fee_per_gas == + txDataStruct->max_priority_fee_per_gas); + std::string txDataInputString( + reinterpret_cast(txDataStruct->input->buffer), txDataStruct->input->length); + std::string txInputString(reinterpret_cast(txStruct->transaction_data->input->buffer), + txStruct->transaction_data->input->length); + BOOST_TEST(txDataInputString == txInputString); + + // signature + std::string txStructSignatureString( + reinterpret_cast(txStruct->signature->buffer), txStruct->signature->length); + auto bytesSignature = fromHexString(signature); + std::string fromSignatureHexString(bytesSignature->begin(), bytesSignature->end()); + BOOST_TEST(fromSignatureHexString == txStructSignatureString); + + // attribute + BOOST_TEST(txStruct->attribute == attribute); + + // extra_data + BOOST_TEST(txStruct->extra_data == extraData); +} + +BOOST_AUTO_TEST_CASE(testCreateTxDataStructWithHexInputv1) +{ + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + int64_t block_limit = 0; + auto value = "1"; + auto gas_price = "0"; + int64_t gas_limit = 0; + auto max_fee_per_gas = "1"; + auto max_priority_fee_per_gas = "1"; + + // create transaction_data_struct_v1 failed (block_limit = 0) + auto txData = bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, to, + input, abi, block_limit, value, gas_price, gas_limit, max_fee_per_gas, + max_priority_fee_per_gas); + auto success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("block limit must > 0")); + + // create transaction_data_struct_v1 failed (input = "") + block_limit = 1; + txData = bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, to, "", + abi, block_limit, value, gas_price, gas_limit, max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("input can not be empty string")); + + // create transaction_data_struct_v1 failed (gas_limit <0) + txData = bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, to, + input, abi, block_limit, value, gas_price, -1, max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("gas limit must >= 0")); + + // create transaction_data_struct_v1 success + txData = bcos_sdk_create_transaction_data_struct_with_hex_input_v1(group_id, chain_id, to, + input, abi, block_limit, value, gas_price, gas_limit, max_fee_per_gas, + max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + BOOST_TEST(txData->value == value); + BOOST_TEST(txData->gas_price == gas_price); + BOOST_TEST(txData->gas_limit == gas_limit); + BOOST_TEST(txData->max_fee_per_gas == max_fee_per_gas); + BOOST_TEST(txData->max_priority_fee_per_gas == max_priority_fee_per_gas); + auto bytesInput = fromHexString(input); + std::string fromInputHexString(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString == fromInputHexString); + + bcos_sdk_destroy_transaction_data_struct_v1(txData); +} + +BOOST_AUTO_TEST_CASE(testCreateTxDataStructWithByteInputv1) +{ + auto bytesInput = fromHexString(input); + auto group_id = ""; + auto chain_id = ""; + auto to = ""; + auto abi = ""; + uint32_t bytes_input_length = 10; + int64_t block_limit = 0; + auto value = "1"; + auto gas_price = "0"; + int64_t gas_limit = 0; + auto max_fee_per_gas = "1"; + auto max_priority_fee_per_gas = "1"; + + // create transaction_data_struct_v1 failed (block_limit = 0) + auto txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytes_input_length, abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + auto success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("block limit must > 0")); + + // create transaction_data_struct_v1 failed (bytes_input_length = 0) + bytes_input_length = 0; + block_limit = 1; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytes_input_length, abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("bytes input length must > 0")); + + // create transaction_data_struct_v1 failed (group_id = NULL) + group_id = nullptr; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_data_struct_v1 success (group_id has Chinese characters) + group_id = "区块链群组1"; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + BOOST_TEST(txData->value == value); + BOOST_TEST(txData->gas_price == gas_price); + BOOST_TEST(txData->gas_limit == gas_limit); + BOOST_TEST(txData->max_fee_per_gas == max_fee_per_gas); + BOOST_TEST(txData->max_priority_fee_per_gas == max_priority_fee_per_gas); + std::string fromInputHexString1(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString1( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString1 == fromInputHexString1); + + // create transaction_data_struct_v1 failed (chain_id = NULL) + chain_id = nullptr; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_data_struct_v1 success (chain_id has Chinese characters) + chain_id = "区块链1"; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + BOOST_TEST(txData->value == value); + BOOST_TEST(txData->gas_price == gas_price); + BOOST_TEST(txData->gas_limit == gas_limit); + BOOST_TEST(txData->max_fee_per_gas == max_fee_per_gas); + BOOST_TEST(txData->max_priority_fee_per_gas == max_priority_fee_per_gas); + std::string fromInputHexString2(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString2( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString2 == fromInputHexString2); + + // create transaction_data_struct_v1 success (abi has Chinese characters) + chain_id = ""; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi_with_chinese, block_limit, value, gas_price, + gas_limit, max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi_with_chinese); + BOOST_TEST(txData->block_limit == block_limit); + BOOST_TEST(txData->value == value); + BOOST_TEST(txData->gas_price == gas_price); + BOOST_TEST(txData->gas_limit == gas_limit); + BOOST_TEST(txData->max_fee_per_gas == max_fee_per_gas); + BOOST_TEST(txData->max_priority_fee_per_gas == max_priority_fee_per_gas); + std::string fromInputHexString3(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString3( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString3 == fromInputHexString3); + + // create transaction_data_struct_v1 failed (gas_limit <0) + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, -1, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txData == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("gas limit must >= 0")); + + // create transaction_data_struct_v1 success + group_id = ""; + txData = bcos_sdk_create_transaction_data_struct_with_bytes_v1(group_id, chain_id, to, + bytesInput->data(), bytesInput->size(), abi, block_limit, value, gas_price, gas_limit, + max_fee_per_gas, max_priority_fee_per_gas); + success = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(success == true); + BOOST_TEST(txData != nullptr); + BOOST_TEST(txData->group_id == group_id); + BOOST_TEST(txData->chain_id == chain_id); + BOOST_TEST(txData->to == to); + BOOST_TEST(txData->abi == abi); + BOOST_TEST(txData->block_limit == block_limit); + BOOST_TEST(txData->value == value); + BOOST_TEST(txData->gas_price == gas_price); + BOOST_TEST(txData->gas_limit == gas_limit); + BOOST_TEST(txData->max_fee_per_gas == max_fee_per_gas); + BOOST_TEST(txData->max_priority_fee_per_gas == max_priority_fee_per_gas); + std::string fromInputHexString(bytesInput->begin(), bytesInput->end()); + std::string txDataInputString( + reinterpret_cast(txData->input->buffer), txData->input->length); + BOOST_TEST(txDataInputString == fromInputHexString); + + bcos_sdk_destroy_transaction_data_struct_v1(txData); +} + +BOOST_AUTO_TEST_CASE(testEncodeDecodeTxDataStructv1) +{ + auto txDataWithHex = createTxDataStructWithHexInputv1(); + auto txDataWithBytes = createTxDataStructWithByteInputv1(); + + // 1. test tx data encode decode hex + // encode to hex failed (transaction_data == NULL) + auto encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex_v1(nullptr); + auto hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(encodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode to hex success + encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex_v1(txDataWithHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + encodedTxDataHex = bcos_sdk_encode_transaction_data_struct_to_hex_v1(txDataWithBytes); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode hex failed (transaction_data_hex_str == NULL) + auto decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex_v1(nullptr); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode hex failed (transaction_data_hex_str == "") + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex_v1(""); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hex_str can not be empty string")); + + // decode hex failed (the length of transaction_data_hex_str is not even number) + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex_v1("0xabc"); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxDataHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("the length of transaction_data_hex_str must be an even number")); + + // decode hex success + decodedTxDataHex = bcos_sdk_decode_transaction_data_struct_from_hex_v1(encodedTxDataHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(hexSuccess == true); + BOOST_TEST(decodedTxDataHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + BOOST_TEST(decodedTxDataHex->version == txDataWithBytes->version); + BOOST_TEST(decodedTxDataHex->group_id == txDataWithBytes->group_id); + BOOST_TEST(decodedTxDataHex->chain_id == txDataWithBytes->chain_id); + BOOST_TEST(decodedTxDataHex->to == txDataWithBytes->to); + BOOST_TEST(decodedTxDataHex->abi == txDataWithBytes->abi); + BOOST_TEST(decodedTxDataHex->block_limit == txDataWithBytes->block_limit); + BOOST_TEST(decodedTxDataHex->nonce == txDataWithBytes->nonce); + BOOST_TEST(decodedTxDataHex->value == txDataWithBytes->value); + BOOST_TEST(decodedTxDataHex->gas_price == txDataWithBytes->gas_price); + BOOST_TEST(decodedTxDataHex->gas_limit == txDataWithBytes->gas_limit); + BOOST_TEST(decodedTxDataHex->max_fee_per_gas == txDataWithBytes->max_fee_per_gas); + BOOST_TEST( + decodedTxDataHex->max_priority_fee_per_gas == txDataWithBytes->max_priority_fee_per_gas); + std::string txDataInputString( + reinterpret_cast(txDataWithBytes->input->buffer), txDataWithBytes->input->length); + std::string decodedHexTxDataInputString( + reinterpret_cast(decodedTxDataHex->input->buffer), decodedTxDataHex->input->length); + BOOST_TEST(txDataInputString == decodedHexTxDataInputString); + + // 2. test tx data encode decode json + // encode to json failed (transaction_data == NULL) + auto encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json_v1(nullptr); + auto jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(encodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode to json success + encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json_v1(txDataWithHex); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + encodedTxDataJson = bcos_sdk_encode_transaction_data_struct_to_json_v1(txDataWithBytes); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode json failed (transaction_data_json_str == NULL) + auto decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json_v1(nullptr); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode json failed (transaction_data_json_str == "") + decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json_v1(""); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxDataJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_json_str can not be empty string")); + + // decode json success + decodedTxDataJson = bcos_sdk_decode_transaction_data_struct_from_json_v1(encodedTxDataJson); + jsonSuccess = bcos_sdk_is_last_opr_success(); + + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(decodedTxDataJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + BOOST_TEST(decodedTxDataJson->version == txDataWithBytes->version); + BOOST_TEST(decodedTxDataJson->group_id == txDataWithBytes->group_id); + BOOST_TEST(decodedTxDataJson->chain_id == txDataWithBytes->chain_id); + BOOST_TEST(decodedTxDataJson->to == txDataWithBytes->to); + BOOST_TEST(decodedTxDataJson->abi == txDataWithBytes->abi); + BOOST_TEST(decodedTxDataJson->block_limit == txDataWithBytes->block_limit); + BOOST_TEST(decodedTxDataJson->nonce == txDataWithBytes->nonce); + BOOST_TEST(decodedTxDataHex->value == txDataWithBytes->value); + BOOST_TEST(decodedTxDataHex->gas_price == txDataWithBytes->gas_price); + BOOST_TEST(decodedTxDataHex->gas_limit == txDataWithBytes->gas_limit); + BOOST_TEST(decodedTxDataHex->max_fee_per_gas == txDataWithBytes->max_fee_per_gas); + BOOST_TEST( + decodedTxDataHex->max_priority_fee_per_gas == txDataWithBytes->max_priority_fee_per_gas); + std::string decodedJsonTxDataInputJson( + reinterpret_cast(decodedTxDataJson->input->buffer), + decodedTxDataJson->input->length); + BOOST_TEST(txDataInputString == decodedJsonTxDataInputJson); + + bcos_sdk_destroy_transaction_data_struct_v1(txDataWithHex); + bcos_sdk_destroy_transaction_data_struct_v1(txDataWithBytes); + bcos_sdk_destroy_transaction_data_struct_v1(decodedTxDataHex); + bcos_sdk_destroy_transaction_data_struct_v1(decodedTxDataJson); +} + +BOOST_AUTO_TEST_CASE(testCalculateTxDataHashv1) +{ + auto txDataWithHex = createTxDataStructWithHexInputv1(); + auto txDataWithByte = createTxDataStructWithByteInputv1(); + auto encodedtxDataWithHex = bcos_sdk_encode_transaction_data_struct_to_hex_v1(txDataWithHex); + auto encodedtxDataWithByte = bcos_sdk_encode_transaction_data_struct_to_hex_v1(txDataWithByte); + + // 1. test cal tx data hash with struct + // calculate tx data hash failed (cryptoType not in 0,1) + auto cryptoType = 2; + auto txDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(cryptoType, txDataWithHex); + auto success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (cryptoType is negative number) + cryptoType = -11; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(cryptoType, txDataWithHex); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (transaction_data == NULL) + cryptoType = 1; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(cryptoType, nullptr); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHash == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // calculate tx data hash success (txDataWithHex) + cryptoType = 1; + txDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(cryptoType, txDataWithHex); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(txDataHash != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // calculate tx data hash success (txDataWithByte) + txDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(cryptoType, txDataWithByte); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(txDataHash != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 2. test cal tx data hash with tx_data_hex + // calculate tx data hash with hex failed (cryptoType not in 0,1) + cryptoType = 2; + auto txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash failed (cryptoType is negative number) + cryptoType = -11; + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("invalid crypto type, it must be BCOS_C_SDK_ECDSA_TYPE(ecdsa crypto " + "type) or BCOS_C_SDK_SM_TYPE(sm crypto type)")); + + // calculate tx data hash with hex failed (transaction_data_hex == NULL) + cryptoType = 1; + txDataHashWithHex = bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, nullptr); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // calculate tx data hash with hex failed (transaction_data_hex == "") + txDataHashWithHex = bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, ""); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txDataHashWithHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hex can not be empty string")); + + // calculate tx data hash with hex success (encodedtxDataWithHex) + cryptoType = 1; + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, encodedtxDataWithHex); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(txDataHashWithHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // calculate tx data hash with hex success (encodedtxDataWithByte) + txDataHashWithHex = + bcos_sdk_calc_transaction_data_struct_hash_with_hex_v1(cryptoType, encodedtxDataWithByte); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(txDataHashWithHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 3. compare hash + BOOST_TEST(txDataHash == txDataHashWithHex); + + bcos_sdk_destroy_transaction_data_struct_v1(txDataWithHex); + bcos_sdk_destroy_transaction_data_struct_v1(txDataWithByte); +} + +BOOST_AUTO_TEST_CASE(testCreateTxStructv1) +{ + auto txDataStruct = createTxDataStructWithHexInputv1(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + + // create transaction_struct failed (transaction_data_struct_v1 = NULL) + auto txStruct = bcos_sdk_create_transaction_struct_v1( + nullptr, signature, transactionDataHash, attribute, extraData); + auto success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (transaction_data_hash = NULL) + txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, signature, nullptr, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (signature = NULL) + txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, nullptr, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create transaction_struct failed (transaction_data_hash = "") + txStruct = + bcos_sdk_create_transaction_struct_v1(txDataStruct, signature, "", attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hash can not be empty string")); + + // create transaction_struct failed (signature = "") + txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, "", transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(txStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("signature can not be empty string")); + + // create transaction_struct success (extraData = NULL) + txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, signature, transactionDataHash, attribute, nullptr); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + compareTxStruct(txStruct, txDataStruct, signature, "", attribute); + + // create transaction_struct success + txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, signature, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + + compareTxStruct(txStruct, txDataStruct, signature, extraData, attribute); + + bcos_sdk_destroy_transaction_data_struct_v1(txDataStruct); + bcos_sdk_destroy_transaction_struct_v1(txStruct); +} + +BOOST_AUTO_TEST_CASE(testCreateEncodedTxv1) +{ + auto txDataStruct = createTxDataStructWithHexInputv1(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + auto txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, signature, transactionDataHash, attribute, extraData); + + // 1. test bcos_sdk_create_encoded_transaction_v1 + // create encoded tx failed (transaction_data_struct_v1 = NULL) + auto encodedTx = bcos_sdk_create_encoded_transaction_v1( + nullptr, signature, transactionDataHash, attribute, extraData); + auto success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (transaction_data_hash = NULL) + encodedTx = bcos_sdk_create_encoded_transaction_v1( + txDataStruct, signature, nullptr, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (signature = NULL) + encodedTx = bcos_sdk_create_encoded_transaction_v1( + txDataStruct, nullptr, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx failed (transaction_data_hash = "") + encodedTx = + bcos_sdk_create_encoded_transaction_v1(txDataStruct, signature, "", attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_data_hash can not be empty string")); + + // create encoded tx failed (signature = "") + encodedTx = bcos_sdk_create_encoded_transaction_v1( + txDataStruct, "", transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTx == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == std::string("signature can not be empty string")); + + // create encoded tx success + encodedTx = bcos_sdk_create_encoded_transaction_v1( + txDataStruct, signature, transactionDataHash, attribute, extraData); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(encodedTx != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 2. test bcos_sdk_encode_transaction_struct_to_hex__v1 + // create encoded tx with tx_struct failed (transaction_struct == "") + auto encodedTxWithTxStruct = bcos_sdk_encode_transaction_struct_to_hex_v1(nullptr); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == false); + BOOST_TEST(encodedTxWithTxStruct == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // create encoded tx with tx_struct success + encodedTxWithTxStruct = bcos_sdk_encode_transaction_struct_to_hex_v1(txStruct); + success = bcos_sdk_is_last_opr_success(); + BOOST_TEST(success == true); + BOOST_TEST(encodedTxWithTxStruct != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // 3. compare encodedTx encodedTxWithTxStruct + BOOST_TEST(encodedTx == encodedTxWithTxStruct); + + bcos_sdk_destroy_transaction_data_struct_v1(txDataStruct); + bcos_sdk_destroy_transaction_struct_v1(txStruct); +} + +BOOST_AUTO_TEST_CASE(testEncodeDecodeTxStructv1) +{ + auto txDataStruct = createTxDataStructWithHexInputv1(); + auto transactionDataHash = bcos_sdk_calc_transaction_data_struct_hash_v1(1, txDataStruct); + void* key_pair = bcos_sdk_create_keypair(1); + auto signature = bcos_sdk_sign_transaction_data_hash(key_pair, transactionDataHash); + auto extraData = ""; + int64_t attribute = 0; + + auto txStruct = bcos_sdk_create_transaction_struct_v1( + txDataStruct, signature, transactionDataHash, attribute, extraData); + + // 1. test tx encode decode hex + // encode tx to hex failed (transaction == NULL) + auto encodedTxHex = bcos_sdk_encode_transaction_struct_to_hex_v1(nullptr); + auto hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == false); + BOOST_TEST(encodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode tx to hex success + encodedTxHex = bcos_sdk_encode_transaction_struct_to_hex_v1(txStruct); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == true); + BOOST_TEST(encodedTxHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode hex failed (transaction_hex_str == NULL) + auto decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex_v1(nullptr); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode hex failed (transaction_hex_str == "") + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex_v1(""); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_hex_str can not be empty string")); + + // decode hex failed (the length of transaction_hex_str is not even number) + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex_v1("0xabc"); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == false); + BOOST_TEST(decodedTxHex == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("the length of transaction_hex_str must be an even number")); + + // decode hex success + decodedTxHex = bcos_sdk_decode_transaction_struct_from_hex_v1(encodedTxHex); + hexSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(hexSuccess == true); + BOOST_TEST(decodedTxHex != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + compareTxStruct(decodedTxHex, txDataStruct, signature, extraData, attribute); + + // 2. test tx encode decode json + // encode tx to json failed (transaction == NULL) + auto encodedTxJson = bcos_sdk_encode_transaction_struct_to_json_v1(nullptr); + auto jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(encodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // encode tx to json success + encodedTxJson = bcos_sdk_encode_transaction_struct_to_json_v1(txStruct); + jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(encodedTxJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + // decode json failed (transaction_json_str == NULL) + auto decodedTxJson = bcos_sdk_decode_transaction_struct_from_json_v1(nullptr); + jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + + // decode json failed (transaction_json_str == "") + decodedTxJson = bcos_sdk_decode_transaction_struct_from_json_v1(""); + jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == false); + BOOST_TEST(decodedTxJson == nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == -1); + BOOST_TEST(bcos_sdk_get_last_error_msg() == + std::string("transaction_json_str can not be empty string")); + + // decode json success + decodedTxJson = bcos_sdk_decode_transaction_struct_from_json_v1(encodedTxJson); + jsonSuccess = bcos_sdk_is_last_opr_success(); + BOOST_TEST(jsonSuccess == true); + BOOST_TEST(decodedTxJson != nullptr); + BOOST_TEST(bcos_sdk_get_last_error() == 0); + + compareTxStruct(decodedTxJson, txDataStruct, signature, extraData, attribute); + + bcos_sdk_destroy_transaction_data_struct_v1(txDataStruct); + bcos_sdk_destroy_transaction_struct_v1(txStruct); + bcos_sdk_destroy_transaction_struct_v1(decodedTxHex); + bcos_sdk_destroy_transaction_struct_v1(decodedTxJson); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/vcpkg b/vcpkg new file mode 160000 index 000000000..51b14cd4e --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 51b14cd4e1230dd51c11ffeff6f7d53c61cc5297 diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 000000000..f271077e4 --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,18 @@ +{ + "registries": [ + { + "kind": "git", + "repository": "https://github.com/FISCO-BCOS/registry", + "baseline": "87805d2845731a26b5e9a80beff1cdf83331279e", + "packages": [ + "openssl", + "hsm-crypto", + "fisco-bcos-cpp-sdk", + "wedprcrypto", + "secp256k1", + "boost-uuid", + "boost-beast" + ] + } + ] +} \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000..86fe5efe4 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,114 @@ +{ + "name": "fisco-bcos-c-sdk", + "version-string": "3.6.0", + "homepage": "https://github.com/FISCO-BCOS/c-sdk", + "description": "FISCO BCOS C SDK", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + "boost-log", + "boost-beast", + "boost-uuid", + "boost-heap", + "boost-graph", + "boost-context", + "boost-property-map", + "boost-chrono", + "boost-iostreams", + "boost-thread", + "boost-test", + "boost-compute", + "boost-container-hash", + "boost-multiprecision", + "boost-program-options", + "boost-variant2", + "jsoncpp", + "openssl", + "secp256k1", + "wedprcrypto", + "zlib", + "fisco-bcos-cpp-sdk" + ], + "builtin-baseline": "51b14cd4e1230dd51c11ffeff6f7d53c61cc5297", + "overrides": [ + { + "name": "boost-log", + "version": "1.83.0" + }, + { + "name": "boost-beast", + "version": "1.83.0" + }, + { + "name": "boost-uuid", + "version": "1.83.0" + }, + { + "name": "boost-heap", + "version": "1.83.0" + }, + { + "name": "boost-graph", + "version": "1.83.0" + }, + { + "name": "boost-context", + "version": "1.80.0" + }, + { + "name": "boost-property-map", + "version": "1.83.0" + }, + { + "name": "boost-chrono", + "version": "1.83.0" + }, + { + "name": "boost-iostreams", + "version": "1.83.0" + }, + { + "name": "boost-thread", + "version": "1.83.0" + }, + { + "name": "boost-test", + "version": "1.83.0" + }, + { + "name": "boost-compute", + "version": "1.83.0" + }, + { + "name": "boost-container-hash", + "version": "1.83.0" + }, + { + "name": "boost-multiprecision", + "version": "1.83.0" + }, + { + "name": "boost-program-options", + "version": "1.83.0" + }, + { + "name": "boost-variant2", + "version": "1.83.0" + }, + { + "name": "jsoncpp", + "version": "1.9.5" + }, + { + "name": "zlib", + "version": "1.2.12", + "port-version": 1 + } + ] +} \ No newline at end of file