├── .gitignore ├── Changelog.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── release_note.txt ├── sider.yml ├── src └── main │ ├── java │ └── com │ │ └── webank │ │ └── webase │ │ └── transaction │ │ ├── Application.java │ │ ├── base │ │ ├── BaseController.java │ │ ├── ConstantCode.java │ │ ├── ConstantProperties.java │ │ ├── ResponseEntity.java │ │ ├── RetCode.java │ │ ├── VersionProperties.java │ │ └── exception │ │ │ ├── BaseException.java │ │ │ └── ExceptionsHandler.java │ │ ├── config │ │ ├── MyComplexShardingAlgorithm.java │ │ ├── RestTemplateConfig.java │ │ ├── SwaggerConfig.java │ │ ├── TableInitConfig.java │ │ ├── ThreadConfig.java │ │ └── Web3Config.java │ │ ├── contract │ │ ├── ContractController.java │ │ ├── ContractMapper.java │ │ ├── ContractService.java │ │ └── entity │ │ │ ├── CompileInfo.java │ │ │ ├── DeployInfoDto.java │ │ │ └── ReqDeployInfo.java │ │ ├── gm │ │ └── EncryptTypeController.java │ │ ├── job │ │ ├── DataflowJobConfig.java │ │ ├── DeployHandleDataflowJob.java │ │ ├── JobRegistryCenterConfig.java │ │ └── TransHandleDataflowJob.java │ │ ├── keystore │ │ ├── KeyStoreController.java │ │ ├── KeyStoreService.java │ │ └── entity │ │ │ ├── EncodeInfo.java │ │ │ ├── KeyStoreInfo.java │ │ │ ├── SignInfo.java │ │ │ └── SignType.java │ │ ├── scheduler │ │ ├── ScheduleService.java │ │ └── SchedulerConfig.java │ │ ├── trans │ │ ├── TransController.java │ │ ├── TransMapper.java │ │ ├── TransService.java │ │ └── entity │ │ │ ├── ReqTransCallInfo.java │ │ │ ├── ReqTransSendInfo.java │ │ │ └── TransInfoDto.java │ │ ├── util │ │ ├── CommonUtils.java │ │ ├── ContractAbiUtil.java │ │ ├── ContractTypeUtil.java │ │ ├── JsonUtils.java │ │ └── LogUtils.java │ │ └── version │ │ └── VersionController.java │ └── resources │ ├── application.properties │ ├── log4j2.xml │ ├── mapper │ ├── ContractMapper.xml │ └── StatelessTransMapper.xml │ └── swagger │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── index.html │ ├── swagger-ui-bundle.js │ ├── swagger-ui-bundle.js.map │ ├── swagger-ui-standalone-preset.js │ ├── swagger-ui-standalone-preset.js.map │ ├── swagger-ui.css │ ├── swagger-ui.css.map │ ├── swagger-ui.js │ └── swagger-ui.js.map ├── start.sh ├── status.sh └── stop.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | *.class 4 | 5 | 6 | # Package Files # 7 | *.war 8 | *.ear 9 | 10 | ### Gradle template 11 | .gradle 12 | /build 13 | gradle.properties 14 | .project 15 | 16 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 17 | !gradle-wrapper.jar 18 | 19 | # Cache of project 20 | .gradletasknamecache 21 | 22 | # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 23 | # gradle/wrapper/gradle-wrapper.properties 24 | 25 | .idea 26 | *.iml 27 | 28 | # OS X 29 | .DS_Store 30 | 31 | /target 32 | /out 33 | /log 34 | /dist 35 | *.crt 36 | *.key 37 | 38 | application-test.properties 39 | 40 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | ### v1.4.1 2 | 3 | (2020-09-25) 4 | 5 | **Fix** 6 | 7 | - 多活时分库分表空指针 8 | - 升级依赖包:spring:4.3.28.RELEASE;elasticjob:3.0.0-alpha;zookeeper :3.6.2;web3sdk:2.5.1 9 | 10 | **兼容性** 11 | 12 | - 支持FISCO-BCOS v2.0.0-rc1 版本 13 | - 支持FISCO-BCOS v2.0.0-rc2 版本 14 | - 支持FISCO-BCOS v2.0.0-rc3 版本 15 | - 支持FISCO-BCOS v2.0.0 及以上版本 16 | - WeBASE-Sign v1.4.0+ 17 | 18 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 19 | 20 | ### v1.4.0 21 | 22 | (2020-08-06) 23 | 24 | 25 | **Add** 26 | 27 | - 增加返回 Version 版本接口 28 | 29 | **兼容性** 30 | 31 | - 支持FISCO-BCOS v2.0.0-rc1 版本 32 | - 支持FISCO-BCOS v2.0.0-rc2 版本 33 | - 支持FISCO-BCOS v2.0.0-rc3 版本 34 | - 支持FISCO-BCOS v2.0.0 及以上版本 35 | - WeBASE-Sign v1.4.0+ 36 | 37 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 38 | 39 | 40 | ### v1.3.2 41 | 42 | (2020-06-17) 43 | 44 | **Fix** 45 | - 移除Fastjson,替换为Jackson 2.11.0; web3sdk升级为2.4.1 46 | - 升级依赖包:spring: 4.3.27; log4j: 2.13.3; slf4j: 1.7.30; 47 | 48 | **兼容性** 49 | 50 | - 支持FISCO-BCOS v2.0.0-rc1 版本 51 | - 支持FISCO-BCOS v2.0.0-rc2 版本 52 | - 支持FISCO-BCOS v2.0.0-rc3 版本 53 | - 支持FISCO-BCOS v2.0.0 及以上版本 54 | - WeBASE-Sign v1.3.0+ 55 | 56 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 57 | 58 | ### v1.3.1 59 | 60 | (2020-06-01) 61 | 62 | **Add** 63 | - 引入fisco-solcJ jar包,支持自动切换国密后台编译 64 | 65 | **兼容性** 66 | 67 | - 支持FISCO-BCOS v2.0.0-rc1 版本 68 | - 支持FISCO-BCOS v2.0.0-rc2 版本 69 | - 支持FISCO-BCOS v2.0.0-rc3 版本 70 | - 支持FISCO-BCOS v2.0.0 及以上版本 71 | - WeBASE-Sign v1.3.0+ 72 | 73 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 74 | 75 | ### v1.3.0 76 | 77 | (2020-04-29) 78 | 79 | **Add** 80 | - 使用签名服务进行交易签名时,传入`Integer userId`改为`String signUserId`(国密或非国密由对应user的加密类型决定) 81 | 82 | **Fix** 83 | - 升级fastjson, jackson, log4j 84 | 85 | **兼容性** 86 | 87 | - 支持FISCO-BCOS v2.0.0-rc1 版本 88 | - 支持FISCO-BCOS v2.0.0-rc2 版本 89 | - 支持FISCO-BCOS v2.0.0-rc3 版本 90 | - 支持FISCO-BCOS v2.0.0 及以上版本 91 | - WeBASE-Sign v1.3.0 92 | 93 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 94 | 95 | ### v1.2.2 96 | 97 | (2020-01-02) 98 | 99 | **Add** 100 | 101 | - 支持国密 102 | - 发送交易、部署合约(sm2, sm3, solc-gm) 103 | - 新增`/encrypt`接口判断国密 104 | - 新增查询接口支持查询部署信息与交易信息 105 | 106 | **Fix** 107 | 108 | - 优化:支持sdk线程池可配置 109 | - 优化:web3sdk升级至v2.2.0 110 | - 优化:start.sh启动脚本优化 111 | - 优化:CommonUtils的`SignatureData`序列化支持国密 112 | 113 | 114 | **兼容性** 115 | 116 | - 支持FISCO-BCOS v2.0.0-rc1 版本 117 | - 支持FISCO-BCOS v2.0.0-rc2 版本 118 | - 支持FISCO-BCOS v2.0.0-rc3 版本 119 | - 支持FISCO-BCOS v2.0.0 及以上版本 120 | - WeBASE-Sign v1.2.2 121 | 122 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 123 | 124 | 125 | ### v1.2.0 126 | 127 | (2019-09-30) 128 | 129 | **Add** 130 | 131 | - 分库分表 132 | - 支持删除数据 133 | 134 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 135 | 136 | 137 | 138 | ### v1.1.0 139 | 140 | (2019-09-12) 141 | 142 | **Fix** 143 | 144 | - bugfix:调用WeBASE-Sign时签名用户地址不一致 145 | - bugfix:方法调用时校验方法名是否存在 146 | - 优化:调用WeBASE-Sign时支持传入用户编号 147 | - 优化:启停脚本通过程序名和端口校验进程 148 | 149 | **兼容性** 150 | 151 | - 支持FISCO-BCOS v2.0.0-rc1 版本 152 | - 支持FISCO-BCOS v2.0.0-rc2 版本 153 | - 支持FISCO-BCOS v2.0.0-rc3 版本 154 | - 支持FISCO-BCOS v2.0.0 及以上版本 155 | - WeBASE-Sign V1.1.0 156 | 157 | 详细了解,请阅读[**技术文档**](https://webasedoc.readthedocs.io/zh_CN/latest/)。 158 | 159 | 160 | 161 | ### V1.0.0 162 | 163 | (2019-06-27) 164 | 165 | **Add** 166 | 167 | 1. 适配FISCO-BCOS 2.0.0版本 168 | 2. 支持多群组功能 169 | 3. 支持合约编译,合约部署,合约调用 170 | 4. 可以查询交易的event和output 171 | 5. 缓存无状态交易,轮询上链 172 | 6. 支持本地配置私钥或随机私钥签名 173 | 7. 支持单机或集群部署 174 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 交易服务 2 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://webasedoc.readthedocs.io/zh_CN/latest/docs/WeBASE/CONTRIBUTING.html) 3 | [![CodeFactor](https://www.codefactor.io/repository/github/webankblockchain/webase-transaction/badge)](https://www.codefactor.io/repository/github/webankblockchain/webase-transaction) 4 | [![Code Lines](https://tokei.rs/b1/github/WeBankBlockchain/WeBASE-Transaction?category=code)](https://github.com/WeBankBlockchain/WeBASE-Transaction) 5 | [![license](http://img.shields.io/badge/license-Apache%20v2-blue.svg)](http://www.apache.org/licenses/) 6 | [![GitHub (pre-)release](https://img.shields.io/github/release/WeBankBlockchain/WeBASE-Transaction/all.svg)](https://github.com/WeBankBlockchain/WeBASE-Transaction/releases) 7 | 8 | ## 简介 9 | WeBASE-Transaction是交易上链代理子系统。主要接收无状态交易请求,缓存到数据库中,再异步上链。本系统可大幅提升吞吐量,解决区块链的tps瓶颈。 详细介绍请查看[WeBASE-Transaction在线文档](https://webasedoc.readthedocs.io/zh_CN/latest/docs/WeBASE-Transaction/index.html) 10 | 11 | ## 贡献说明 12 | 请阅读我们的贡献文档,了解如何贡献代码,并提交你的贡献。 13 | 14 | 希望在您的参与下,WeBASE会越来越好! 15 | 16 | ## 社区 17 | 联系我们:webase@webank.com 18 | 19 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | version '1.0' 2 | 3 | apply plugin: 'maven' 4 | apply plugin: 'java' 5 | apply plugin: 'idea' 6 | apply plugin: 'eclipse' 7 | 8 | sourceCompatibility = 1.8 9 | targetCompatibility = 1.8 10 | 11 | [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' 12 | 13 | // In this section you declare where to find the dependencies of your project 14 | repositories { 15 | maven { url "http://maven.aliyun.com/nexus/content/groups/public/"} 16 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 17 | maven { url 'https://dl.bintray.com/ethereum/maven/'} 18 | mavenLocal() 19 | mavenCentral() 20 | } 21 | 22 | 23 | def spring_boot_version="1.5.22.RELEASE" 24 | List spring_boot =[ 25 | "org.springframework.boot:spring-boot-starter-web:$spring_boot_version", 26 | "org.springframework.boot:spring-boot-starter-jdbc:$spring_boot_version", 27 | "org.springframework.boot:spring-boot-autoconfigure:$spring_boot_version", 28 | "org.springframework.boot:spring-boot-configuration-processor:$spring_boot_version", 29 | ] 30 | 31 | // cover old version 32 | def spring_version="4.3.28.RELEASE" 33 | List spring =[ 34 | "org.springframework:spring-web:$spring_version", 35 | "org.springframework:spring-webmvc:$spring_version", 36 | "org.springframework:spring-jdbc:$spring_version" 37 | ] 38 | 39 | List mysql = [ 40 | 'mysql:mysql-connector-java:8.0.22', 41 | 'org.mybatis:mybatis:3.2.8', 42 | 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1' 43 | ] 44 | 45 | List swagger = [ 46 | 'io.springfox:springfox-swagger2:2.8.0', 47 | 'io.springfox:springfox-swagger-ui:2.8.0' 48 | ] 49 | 50 | def log4j_version="2.15.0" 51 | List log4j = [ 52 | "org.apache.logging.log4j:log4j-api:$log4j_version", 53 | "org.apache.logging.log4j:log4j-core:$log4j_version", 54 | "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version", 55 | "org.apache.logging.log4j:log4j-web:$log4j_version" 56 | ] 57 | 58 | List elasticjob = [ 59 | 'org.apache.shardingsphere.elasticjob:elasticjob-lite-core:3.0.0-alpha', 60 | 'io.shardingsphere:sharding-jdbc-spring-boot-starter:3.1.0' 61 | ] 62 | 63 | List zookeeper = [ 64 | 'org.apache.zookeeper:zookeeper:3.6.2', 65 | 'com.github.sgroschupf:zkclient:0.1' 66 | ] 67 | 68 | 69 | List jaxb = [ 70 | "javax.xml.bind:jaxb-api:2.3.0", 71 | "com.sun.xml.bind:jaxb-impl:2.3.0", 72 | "com.sun.xml.bind:jaxb-core:2.3.0", 73 | "javax.activation:activation:1.1.1" 74 | ] 75 | 76 | def jackson_version = "2.11.0" 77 | List jackson = [ 78 | "com.fasterxml.jackson.core:jackson-databind:$jackson_version", 79 | "com.fasterxml.jackson.core:jackson-annotations:$jackson_version", 80 | "com.fasterxml.jackson.core:jackson-core:$jackson_version", 81 | "com.fasterxml.jackson.module:jackson-module-parameter-names:$jackson_version", 82 | "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$jackson_version", 83 | "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version", 84 | ] 85 | 86 | 87 | // cover old version 88 | def tomcat_version = "8.5.56" 89 | List tomcat = [ 90 | "org.apache.tomcat.embed:tomcat-embed-core:$tomcat_version", 91 | "org.apache.tomcat.embed:tomcat-embed-el:$tomcat_version", 92 | "org.apache.tomcat.embed:tomcat-embed-websocket:$tomcat_version", 93 | "org.apache.tomcat:tomcat-jdbc:$tomcat_version", 94 | "org.apache.tomcat:tomcat-juli:$tomcat_version" 95 | ] 96 | 97 | dependencies { 98 | 99 | compile spring_boot,spring,mysql,swagger,log4j,elasticjob,zookeeper,jaxb,jackson,tomcat 100 | compile ('org.fisco-bcos:web3sdk:2.6.2') { 101 | exclude group: 'org.ethereum', module: 'solcJ-all' 102 | } 103 | 104 | // support guomi/ecdsa same time, support solcJ-0.5.2 105 | compile "org.fisco-bcos:solcJ:0.4.25-rc1" 106 | compile "org.slf4j:jcl-over-slf4j:1.7.30" 107 | compile "org.apache.commons:commons-lang3:3.6" 108 | compile "commons-io:commons-io:2.4" 109 | compile 'com.alibaba:druid:1.1.23' 110 | compile 'org.projectlombok:lombok:1.18.2' 111 | annotationProcessor 'org.projectlombok:lombok:1.18.2' 112 | } 113 | 114 | configurations { 115 | all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' 116 | all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12' 117 | all*.exclude group: 'log4j', module: 'log4j' 118 | all*.exclude group: 'com.mchange', module: '*' 119 | } 120 | 121 | sourceSets { 122 | main { 123 | java { 124 | srcDir 'src/main/java' 125 | } 126 | resources { 127 | srcDir 'src/main/resources' 128 | } 129 | } 130 | } 131 | 132 | clean { 133 | delete 'dist' 134 | delete 'build' 135 | delete 'log' 136 | delete 'temp' 137 | } 138 | 139 | jar { 140 | destinationDir file('dist/apps') 141 | archiveName project.name + '.jar' 142 | exclude '**/*.xml' 143 | exclude '**/*.properties' 144 | 145 | doLast { 146 | copy { 147 | from file('src/main/resources/') 148 | into 'dist/conf_template' 149 | } 150 | copy { 151 | from file('script/') 152 | into 'dist/script' 153 | } 154 | copy { 155 | from configurations.runtime 156 | into 'dist/lib' 157 | } 158 | copy { 159 | from file('.').listFiles().findAll{File f -> (f.name.endsWith('.sh') || f.name.endsWith('.env'))} 160 | into 'dist' 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeBASE-Transaction/38ea7176d3a6d95e517888a1f3b9e36f7f88621f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /release_note.txt: -------------------------------------------------------------------------------- 1 | v1.4.0 2 | -------------------------------------------------------------------------------- /sider.yml: -------------------------------------------------------------------------------- 1 | linter: 2 | pmd_java: 3 | dir: src 4 | encoding: Shift_JIS 5 | min_priority: 2 6 | checkstyle: 7 | config: google 8 | dir: src 9 | ignore: 10 | - warning 11 | - info -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction; 16 | 17 | import lombok.extern.slf4j.Slf4j; 18 | import org.mybatis.spring.annotation.MapperScan; 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 22 | 23 | /** 24 | * Startup class. 25 | * 26 | */ 27 | @Slf4j 28 | @EnableSwagger2 29 | @SpringBootApplication 30 | @MapperScan("com.webank.webase.transaction") 31 | public class Application { 32 | 33 | public static void main(String[] args) { 34 | SpringApplication.run(Application.class, args); 35 | log.info("main run success..."); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/BaseController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | import com.webank.webase.transaction.util.JsonUtils; 18 | 19 | import com.webank.webase.transaction.base.exception.BaseException; 20 | import java.util.List; 21 | import lombok.extern.slf4j.Slf4j; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.springframework.validation.BindingResult; 24 | import org.springframework.validation.ObjectError; 25 | 26 | /** 27 | * BaseController. 28 | * 29 | */ 30 | @Slf4j 31 | public abstract class BaseController { 32 | /** 33 | * Parameters check Result handle. 34 | * 35 | * @param bindingResult checkResult 36 | */ 37 | protected ResponseEntity checkParamResult(BindingResult bindingResult) throws BaseException { 38 | if (!bindingResult.hasErrors()) { 39 | return null; 40 | } 41 | 42 | String errorMsg = getParamValidFaildMessage(bindingResult); 43 | if (StringUtils.isBlank(errorMsg)) { 44 | log.warn("OnWarning:param exception. errorMsg is empty"); 45 | throw new BaseException(ConstantCode.PARAM_VAILD_FAIL); 46 | } 47 | 48 | RetCode retCode = null; 49 | try { 50 | retCode = JsonUtils.toJavaObject(errorMsg, RetCode.class); 51 | if (retCode == null) { 52 | log.error("json parse error"); 53 | } 54 | } catch (Exception ex) { 55 | log.warn("OnWarning:retCodeJson convert error"); 56 | throw new BaseException(ConstantCode.PARAM_VAILD_FAIL); 57 | } 58 | 59 | throw new BaseException(retCode); 60 | } 61 | 62 | /** 63 | * Parameters check message format. 64 | * 65 | * @param bindingResult checkResult 66 | * @return 67 | */ 68 | private String getParamValidFaildMessage(BindingResult bindingResult) { 69 | List errorList = bindingResult.getAllErrors(); 70 | log.info("errorList:{}", JsonUtils.toJSONString(errorList)); 71 | if (errorList == null) { 72 | log.warn("onWarning:errorList is empty!"); 73 | return null; 74 | } 75 | 76 | ObjectError objectError = errorList.get(0); 77 | if (objectError == null) { 78 | log.warn("onWarning:objectError is empty!"); 79 | return null; 80 | } 81 | return objectError.getDefaultMessage(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/ConstantCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | /** 18 | * ConstantCode. 19 | * 20 | */ 21 | public interface ConstantCode { 22 | // return success 23 | RetCode RET_SUCCEED = RetCode.mark(0, "success"); 24 | 25 | // paramaters check 26 | String GROUP_ID_IS_EMPTY = "{\"code\":203001,\"msg\":\"group id cannot be empty\"}"; 27 | String UUID_IS_EMPTY = "{\"code\":203002,\"msg\":\"uuid cannot be empty\"}"; 28 | String SIGN_TYPE_IS_EMPTY = "{\"code\":203003,\"msg\":\"sign type cannot be empty\"}"; 29 | String CONTRACT_BIN_IS_EMPTY = "{\"code\":203004,\"msg\":\"contract bin cannot be empty\"}"; 30 | String CONTRACT_ABI_IS_EMPTY = "{\"code\":203005,\"msg\":\"contract abi cannot be empty\"}"; 31 | String CONTRACT_ADDRESS_IS_EMPTY = 32 | "{\"code\":203006,\"msg\":\"contract address cannot be empty\"}"; 33 | String FUNCTION_NAME_IS_EMPTY = "{\"code\":203007,\"msg\":\"function name cannot be empty\"}"; 34 | 35 | // general error 36 | RetCode UUID_IS_EXISTS = RetCode.mark(303001, "uuid is already exists"); 37 | RetCode GET_SIGN_DATA_ERROR = RetCode.mark(303002, "get sign data from sign service error"); 38 | RetCode IN_FUNCPARAM_ERROR = RetCode.mark(303003, "contract funcParam is error"); 39 | RetCode SIGN_TYPE_ERROR = RetCode.mark(303004, "sign type is not exists"); 40 | RetCode CONTRACT_ABI_EMPTY = RetCode.mark(303005, "contract abi is empty"); 41 | RetCode FUNCTION_NOT_CONSTANT = RetCode.mark(303006, "request function can not be constant"); 42 | RetCode FUNCTION_MUST_CONSTANT = RetCode.mark(303007, "query function must be constant"); 43 | RetCode TRANSACTION_QUERY_FAILED = RetCode.mark(303008, "query data from chain failed"); 44 | RetCode FILE_IS_EMPTY = RetCode.mark(303009, "file cannot be empty"); 45 | RetCode NOT_A_ZIP_FILE = RetCode.mark(303010, "it is not a zip file"); 46 | RetCode CONTRACT_NOT_DEPLOED = RetCode.mark(303011, "contract has not been deployed"); 47 | RetCode CONTRACT_COMPILE_ERROR = RetCode.mark(303012, "contract compile error"); 48 | RetCode NODE_REQUEST_FAILED = RetCode.mark(303013, "node request failed"); 49 | RetCode EVENT_NOT_EXISTS = RetCode.mark(303014, "there is not event"); 50 | RetCode TRANS_NOT_SENT = RetCode.mark(303015, "trans has not been sent to the chain"); 51 | RetCode ADDRESS_ABI_EMPTY = RetCode.mark(303016, 52 | "if deploy uuid is empty, contract address and contract abi cannot be empty"); 53 | RetCode TRANS_OUTPUT_EMPTY = RetCode.mark(303017, "trans output is empty"); 54 | RetCode TRANS_NOT_EXIST = RetCode.mark(303018, "trans is not exists"); 55 | RetCode GROUPID_NOT_CONFIGURED = 56 | RetCode.mark(303019, "request group id has not been configured"); 57 | RetCode SIGN_USERID_EMPTY = 58 | RetCode.mark(303020, "signUserId cannot be empty while sign type is 2"); 59 | RetCode SIGN_USERID_ERROR = RetCode.mark(303021, "signUserId check failed"); 60 | RetCode FUNCTION_NOT_EXISTS = RetCode.mark(303022, "function is not exists"); 61 | RetCode DATA_NOT_EXISTS = RetCode.mark(303023, "data is not exists"); 62 | 63 | // system error 64 | RetCode SYSTEM_ERROR = RetCode.mark(103001, "system error"); 65 | RetCode PARAM_VAILD_FAIL = RetCode.mark(103002, "param valid fail"); 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/ConstantProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | import java.math.BigInteger; 18 | import lombok.Data; 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | import org.springframework.context.annotation.Configuration; 21 | 22 | /** 23 | * ConstantProperties. 24 | * 25 | */ 26 | @Data 27 | @Configuration 28 | @ConfigurationProperties(prefix = ConstantProperties.CONSTANT_PREFIX) 29 | public class ConstantProperties { 30 | public static final BigInteger GAS_PRICE = new BigInteger("100000000"); 31 | public static final BigInteger GAS_LIMIT = new BigInteger("100000000"); 32 | public static final BigInteger INITIAL_WEI_VALUE = new BigInteger("0"); 33 | 34 | public static final String TYPE_CONSTRUCTOR = "constructor"; 35 | public static final String TYPE_FUNCTION = "function"; 36 | public static final String TYPE_EVENT = "event"; 37 | 38 | // monitor business log format 39 | public static final String MONITOR_BUSINESS_FORMAT = 40 | "[{\"CODE\":\"%s\",\"COST_TIME\":\"{}\",\"RES_CODE\":\"0\"}][{}]"; 41 | public static final String CODE_BUSINESS_10001 = 42 | String.format(MONITOR_BUSINESS_FORMAT, "10001"); 43 | public static final String MSG_BUSINESS_10001 = "deploy_transaction"; 44 | public static final String CODE_BUSINESS_10002 = 45 | String.format(MONITOR_BUSINESS_FORMAT, "10002"); 46 | public static final String MSG_BUSINESS_10002 = "stateless_transaction"; 47 | public static final String CODE_BUSINESS_10003 = 48 | String.format(MONITOR_BUSINESS_FORMAT, "10003"); 49 | public static final String MSG_BUSINESS_10003 = "repetitive_deploy_uuid"; 50 | public static final String CODE_BUSINESS_10004 = 51 | String.format(MONITOR_BUSINESS_FORMAT, "10004"); 52 | public static final String MSG_BUSINESS_10004 = "repetitive_stateless_uuid"; 53 | 54 | // monitor abnormal log format 55 | public static final String MONITOR_ABNORMAL_FORMAT = 56 | "[{\"CODE\":\"%s\",\"RES_CODE\":\"1\"}][{}]"; 57 | public static final String CODE_ABNORMAL_S0001 = 58 | String.format(MONITOR_ABNORMAL_FORMAT, "S2001"); 59 | public static final String MSG_ABNORMAL_S0001 = "deploy_to_chain_exception"; 60 | public static final String CODE_ABNORMAL_S0002 = 61 | String.format(MONITOR_ABNORMAL_FORMAT, "S2002"); 62 | public static final String MSG_ABNORMAL_S0002 = "stateless_to_chain_exception"; 63 | public static final String CODE_ABNORMAL_S0003 = 64 | String.format(MONITOR_ABNORMAL_FORMAT, "S2003"); 65 | public static final String MSG_ABNORMAL_S0003 = "deploy_request_arrive_limit"; 66 | public static final String CODE_ABNORMAL_S0004 = 67 | String.format(MONITOR_ABNORMAL_FORMAT, "S2004"); 68 | public static final String MSG_ABNORMAL_S0004 = "stateless_request_arrive_limit"; 69 | public static final String CODE_ABNORMAL_S0005 = 70 | String.format(MONITOR_ABNORMAL_FORMAT, "S2005"); 71 | public static final String MSG_ABNORMAL_S0005 = "request_sign_server_exception"; 72 | 73 | // constant configuration from file 74 | public static final String CONSTANT_PREFIX = "constant"; 75 | private String signServer = "127.0.0.1:5004"; 76 | private String privateKey = "edf02a4a69b14ee6b1650a95de71d5f50496ef62ae4213026bd8d6651d030995"; 77 | private String cronTrans = "0/1 * * * * ?"; 78 | private int requestCountMax = 6; 79 | private int selectCount = 10; 80 | private int intervalTime = 600; 81 | private int sleepTime = 30; 82 | private int transMaxWait = 20; 83 | private boolean ifDeleteData = false; 84 | private String cronDeleteData = "0 0 1 * * ?"; 85 | private int keepDays = 360; 86 | private boolean ifDistributedTask = false; 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/ResponseEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | import lombok.Data; 18 | 19 | /** 20 | * ResponseEntity. 21 | * 22 | */ 23 | @Data 24 | public class ResponseEntity { 25 | private int code; 26 | private String message; 27 | private Object data; 28 | 29 | public ResponseEntity() {} 30 | 31 | public ResponseEntity(int code) { 32 | this.code = code; 33 | } 34 | 35 | public ResponseEntity(RetCode rsc) { 36 | this.code = rsc.getCode(); 37 | this.message = rsc.getMsg(); 38 | } 39 | 40 | /** 41 | * constructor. 42 | * 43 | * @param rsc not null 44 | * @param obj result 45 | */ 46 | public ResponseEntity(RetCode rsc, Object obj) { 47 | this.code = rsc.getCode(); 48 | this.message = rsc.getMsg(); 49 | this.data = obj; 50 | } 51 | 52 | /** 53 | * constructor. 54 | * 55 | * @param code not null 56 | * @param message not null 57 | * @param obj result 58 | */ 59 | public ResponseEntity(int code, String message, Object obj) { 60 | this.code = code; 61 | this.message = message; 62 | this.data = obj; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/RetCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | import lombok.Data; 18 | 19 | /** 20 | * RetCode. 21 | * 22 | */ 23 | @Data 24 | public class RetCode { 25 | private Integer code; 26 | private String msg; 27 | 28 | public RetCode() {} 29 | 30 | public RetCode(int code, String msg) { 31 | this.code = code; 32 | this.msg = msg; 33 | } 34 | 35 | public static RetCode mark(int code, String msg) { 36 | return new RetCode(code, msg); 37 | } 38 | 39 | public static RetCode mark(Integer code) { 40 | return new RetCode(code, null); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "RetCode [code=" + code + ", msg=" + msg + "]"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/VersionProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2020 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base; 16 | 17 | import lombok.Data; 18 | import org.springframework.beans.factory.annotation.Value; 19 | import org.springframework.stereotype.Component; 20 | 21 | /** 22 | * load 'version' in .yml 23 | */ 24 | @Data 25 | @Component 26 | public class VersionProperties { 27 | 28 | @Value("${version}") 29 | private String version; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/exception/BaseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base.exception; 16 | 17 | import com.webank.webase.transaction.base.RetCode; 18 | 19 | /** 20 | * BaseException. 21 | * 22 | */ 23 | public class BaseException extends Exception { 24 | 25 | private static final long serialVersionUID = 1L; 26 | private RetCode retCode; 27 | 28 | public BaseException(RetCode retCode) { 29 | super(retCode.getMsg()); 30 | this.retCode = retCode; 31 | } 32 | 33 | public BaseException(int code, String msg) { 34 | super(msg); 35 | this.retCode = new RetCode(code, msg); 36 | } 37 | 38 | public RetCode getRetCode() { 39 | return retCode; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/base/exception/ExceptionsHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.base.exception; 16 | 17 | import com.fasterxml.jackson.core.JsonProcessingException; 18 | import com.fasterxml.jackson.databind.ObjectMapper; 19 | import com.webank.webase.transaction.base.ConstantCode; 20 | import com.webank.webase.transaction.base.ResponseEntity; 21 | import com.webank.webase.transaction.base.RetCode; 22 | import java.util.Optional; 23 | import lombok.extern.slf4j.Slf4j; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.web.bind.annotation.ControllerAdvice; 26 | import org.springframework.web.bind.annotation.ExceptionHandler; 27 | import org.springframework.web.bind.annotation.ResponseBody; 28 | 29 | /** 30 | * ExceptionsHandler. 31 | * 32 | */ 33 | @ControllerAdvice 34 | @Slf4j 35 | public class ExceptionsHandler { 36 | @Autowired 37 | ObjectMapper mapper; 38 | 39 | /** 40 | * BaseException Handler. 41 | * 42 | * @param baseException e 43 | * @return 44 | */ 45 | @ResponseBody 46 | @ExceptionHandler(value = BaseException.class) 47 | public ResponseEntity myExceptionHandler(BaseException baseException) throws Exception { 48 | log.warn("catch business exception", baseException); 49 | RetCode retCode = Optional.ofNullable(baseException).map(BaseException::getRetCode) 50 | .orElse(ConstantCode.SYSTEM_ERROR); 51 | 52 | ResponseEntity rep = new ResponseEntity(retCode); 53 | log.warn("business exception return:{}", mapper.writeValueAsString(rep)); 54 | return rep; 55 | } 56 | 57 | /** 58 | * Exception Handler. 59 | * 60 | * @param exc e 61 | * @return 62 | */ 63 | @ResponseBody 64 | @ExceptionHandler(value = Exception.class) 65 | public ResponseEntity exceptionHandler(Exception exc) { 66 | log.info("catch exception", exc); 67 | RetCode retCode = ConstantCode.SYSTEM_ERROR; 68 | ResponseEntity rep = new ResponseEntity(retCode); 69 | try { 70 | log.warn("exceptionHandler system exception return:{}", mapper.writeValueAsString(rep)); 71 | } catch (JsonProcessingException ex) { 72 | log.warn("exceptionHandler system exception"); 73 | } 74 | return rep; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/MyComplexShardingAlgorithm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import com.webank.webase.transaction.util.JsonUtils; 18 | import io.shardingsphere.api.algorithm.sharding.ListShardingValue; 19 | import io.shardingsphere.api.algorithm.sharding.ShardingValue; 20 | import io.shardingsphere.api.algorithm.sharding.complex.ComplexKeysShardingAlgorithm; 21 | import java.util.ArrayList; 22 | import java.util.Calendar; 23 | import java.util.Collection; 24 | import java.util.Date; 25 | import java.util.Iterator; 26 | import java.util.List; 27 | import lombok.extern.slf4j.Slf4j; 28 | 29 | /** 30 | * ComplexShardingAlgorithm. 31 | * 32 | */ 33 | @Slf4j 34 | public class MyComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm { 35 | @Override 36 | public Collection doSharding(Collection collection, 37 | Collection shardingValues) { 38 | log.debug("collection:" + JsonUtils.toJSONString(collection) + ",shardingValues:" 39 | + JsonUtils.toJSONString(shardingValues)); 40 | // table sharding by id and gmt_create 41 | Collection idValues = getLongShardingValue(shardingValues, "id"); 42 | Collection gmtValues = getDateShardingValue(shardingValues, "gmt_create"); 43 | List shardingSuffix = new ArrayList<>(); 44 | for (Long idValue : idValues) { 45 | for (Date gmtValue : gmtValues) { 46 | Calendar cld = Calendar.getInstance(); 47 | cld.setTime(gmtValue); 48 | int year = cld.get(Calendar.YEAR); 49 | String suffix = "_" + year + "_" + idValue % 2; 50 | collection.forEach(x -> { 51 | if (x.endsWith(suffix)) { 52 | shardingSuffix.add(x); 53 | } 54 | }); 55 | } 56 | } 57 | 58 | return shardingSuffix; 59 | } 60 | 61 | private Collection getLongShardingValue(Collection shardingValues, 62 | final String key) { 63 | Collection valueSet = new ArrayList<>(); 64 | Iterator iterator = shardingValues.iterator(); 65 | while (iterator.hasNext()) { 66 | ShardingValue next = iterator.next(); 67 | if (next instanceof ListShardingValue) { 68 | ListShardingValue value = (ListShardingValue) next; 69 | if (value.getColumnName().equals(key)) { 70 | return value.getValues(); 71 | } 72 | } 73 | } 74 | return valueSet; 75 | } 76 | 77 | private Collection getDateShardingValue(Collection shardingValues, 78 | final String key) { 79 | Collection valueSet = new ArrayList<>(); 80 | Iterator iterator = shardingValues.iterator(); 81 | while (iterator.hasNext()) { 82 | ShardingValue next = iterator.next(); 83 | if (next instanceof ListShardingValue) { 84 | ListShardingValue value = (ListShardingValue) next; 85 | if (value.getColumnName().equals(key)) { 86 | return value.getValues(); 87 | } 88 | } 89 | } 90 | return valueSet; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/RestTemplateConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import lombok.Data; 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.http.client.ClientHttpRequestFactory; 21 | import org.springframework.http.client.SimpleClientHttpRequestFactory; 22 | import org.springframework.web.client.RestTemplate; 23 | 24 | /** 25 | * RestTemplateConfig. 26 | * 27 | */ 28 | @Data 29 | @Configuration 30 | public class RestTemplateConfig { 31 | /** 32 | * new RestTemplate. 33 | * 34 | * @param factory object 35 | * @return 36 | */ 37 | @Bean 38 | public RestTemplate restTemplate(ClientHttpRequestFactory factory) { 39 | return new RestTemplate(factory); 40 | } 41 | 42 | /** 43 | * init httpRequestFactory. 44 | * 45 | * @return 46 | */ 47 | @Bean 48 | public ClientHttpRequestFactory simpleClientHttpRequestFactory() { 49 | SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); 50 | factory.setReadTimeout(20000); 51 | factory.setConnectTimeout(5000); 52 | return factory; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import com.google.common.collect.Lists; 18 | import java.util.HashSet; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import springfox.documentation.builders.ApiInfoBuilder; 22 | import springfox.documentation.builders.RequestHandlerSelectors; 23 | import springfox.documentation.service.ApiInfo; 24 | import springfox.documentation.spi.DocumentationType; 25 | import springfox.documentation.spring.web.plugins.Docket; 26 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 27 | 28 | /** 29 | * SwaggerConfig. 30 | * 31 | */ 32 | @Configuration 33 | @EnableSwagger2 34 | public class SwaggerConfig { 35 | /** 36 | * set documentation. 37 | * 38 | * @return 39 | */ 40 | @Bean 41 | public Docket documentation() { 42 | return new Docket(DocumentationType.SWAGGER_2).select() 43 | .apis(RequestHandlerSelectors.basePackage("com.webank.webase.transaction")).build() 44 | .protocols(new HashSet(Lists.newArrayList("http"))).pathMapping("/") 45 | .apiInfo(apiInfo()).enable(true); 46 | } 47 | 48 | /** 49 | * set api info. 50 | * 51 | * @return 52 | */ 53 | private ApiInfo apiInfo() { 54 | return new ApiInfoBuilder().title("API document").description("transaction api") 55 | .version("1.0").build(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/TableInitConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import com.webank.webase.transaction.contract.ContractMapper; 18 | import com.webank.webase.transaction.trans.TransMapper; 19 | import lombok.Data; 20 | import org.springframework.beans.factory.InitializingBean; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | /** 25 | * table init. 26 | * 27 | */ 28 | @Data 29 | @Configuration 30 | public class TableInitConfig implements InitializingBean { 31 | @Autowired 32 | private ContractMapper contractMapper; 33 | @Autowired 34 | private TransMapper transMapper; 35 | 36 | @Override 37 | public void afterPropertiesSet() throws Exception { 38 | contractMapper.createTbDeployTrans(); 39 | transMapper.createTbStatelessTrans(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/ThreadConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import java.util.concurrent.ThreadPoolExecutor.AbortPolicy; 18 | import lombok.Data; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.scheduling.annotation.EnableAsync; 22 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 23 | 24 | /** 25 | * transaction ThreadPoolTaskExecutor configure. 26 | * 27 | */ 28 | @Data 29 | @EnableAsync 30 | @Configuration 31 | public class ThreadConfig { 32 | /** 33 | * set ThreadPoolTaskExecutor. 34 | * 35 | * @return 36 | */ 37 | @Bean 38 | public ThreadPoolTaskExecutor transExecutor() { 39 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 40 | executor.setCorePoolSize(50); 41 | executor.setMaxPoolSize(100); 42 | executor.setQueueCapacity(500); 43 | executor.setKeepAliveSeconds(60); 44 | executor.setRejectedExecutionHandler(new AbortPolicy()); 45 | executor.setThreadNamePrefix("transExecutor-"); 46 | executor.initialize(); 47 | return executor; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/config/Web3Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.config; 16 | 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.concurrent.ThreadPoolExecutor.AbortPolicy; 20 | 21 | import org.fisco.bcos.channel.client.Service; 22 | import org.fisco.bcos.channel.handler.ChannelConnections; 23 | import org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig; 24 | import org.fisco.bcos.web3j.crypto.EncryptType; 25 | import org.fisco.bcos.web3j.protocol.Web3j; 26 | import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService; 27 | import org.springframework.boot.context.properties.ConfigurationProperties; 28 | import org.springframework.context.annotation.Bean; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.context.annotation.DependsOn; 31 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 32 | 33 | import lombok.Data; 34 | import lombok.extern.slf4j.Slf4j; 35 | 36 | /** 37 | * init web3sdk. 38 | * 39 | */ 40 | @Data 41 | @Slf4j 42 | @Configuration 43 | @ConfigurationProperties(prefix = "sdk") 44 | public class Web3Config { 45 | private String orgName; 46 | private int timeout = 10000; 47 | private int corePoolSize = 100; 48 | private int maxPoolSize = 500; 49 | private int queueCapacity = 500; 50 | private int keepAlive = 60; 51 | private GroupChannelConnectionsConfig groupConfig; 52 | // 0: standard, 1: guomi 53 | private int encryptType; 54 | 55 | /** 56 | * init web3j. 57 | * 58 | * @return 59 | */ 60 | @Bean 61 | @DependsOn("encryptType") 62 | public HashMap web3j() throws Exception { 63 | HashMap web3jMap = new HashMap(); 64 | 65 | List channelConnectList = groupConfig.getAllChannelConnections(); 66 | for (ChannelConnections connect : channelConnectList) { 67 | int groupId = connect.getGroupId(); 68 | log.info("init groupId:{}", groupId); 69 | // set groupId 70 | Service service = new Service(); 71 | service.setOrgID(orgName); 72 | service.setThreadPool(sdkThreadPool()); 73 | service.setAllChannelConnections(groupConfig); 74 | service.setGroupId(groupId); 75 | service.run(); 76 | ChannelEthereumService channelEthereumService = new ChannelEthereumService(); 77 | channelEthereumService.setTimeout(timeout); 78 | channelEthereumService.setChannelService(service); 79 | Web3j web3j = Web3j.build(channelEthereumService, groupId); 80 | web3j.getGroupList().send().getGroupList(); 81 | web3jMap.put(groupId, web3j); 82 | } 83 | return web3jMap; 84 | } 85 | 86 | /** 87 | * set sdk threadPool. 88 | * 89 | * @return 90 | */ 91 | @Bean 92 | public ThreadPoolTaskExecutor sdkThreadPool() { 93 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 94 | executor.setCorePoolSize(corePoolSize); 95 | executor.setMaxPoolSize(maxPoolSize); 96 | executor.setQueueCapacity(queueCapacity); 97 | executor.setKeepAliveSeconds(keepAlive); 98 | executor.setRejectedExecutionHandler(new AbortPolicy()); 99 | executor.setThreadNamePrefix("sdkThreadPool-"); 100 | executor.initialize(); 101 | return executor; 102 | } 103 | 104 | /** 105 | * set sdk's encrypt type: 0: standard, 1: guomi sdk switch ecdsa to sm2, sha to sm3. 106 | */ 107 | @Bean(name = "encryptType") 108 | public EncryptType EncryptType() { 109 | return new EncryptType(encryptType); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/ContractController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract; 16 | 17 | import com.webank.webase.transaction.util.JsonUtils; 18 | import com.webank.webase.transaction.base.BaseController; 19 | import com.webank.webase.transaction.base.ResponseEntity; 20 | import com.webank.webase.transaction.base.exception.BaseException; 21 | import com.webank.webase.transaction.contract.entity.ReqDeployInfo; 22 | import io.swagger.annotations.Api; 23 | import io.swagger.annotations.ApiOperation; 24 | import io.swagger.annotations.ApiParam; 25 | import java.io.IOException; 26 | import javax.validation.Valid; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.validation.BindingResult; 30 | import org.springframework.web.bind.annotation.GetMapping; 31 | import org.springframework.web.bind.annotation.PathVariable; 32 | import org.springframework.web.bind.annotation.PostMapping; 33 | import org.springframework.web.bind.annotation.RequestBody; 34 | import org.springframework.web.bind.annotation.RequestMapping; 35 | import org.springframework.web.bind.annotation.RequestParam; 36 | import org.springframework.web.bind.annotation.RestController; 37 | import org.springframework.web.multipart.MultipartFile; 38 | 39 | /** 40 | * ContractController. 41 | * 42 | */ 43 | @Api(value = "/contract", tags = "contract interface") 44 | @Slf4j 45 | @RestController 46 | @RequestMapping(value = "/contract") 47 | public class ContractController extends BaseController { 48 | @Autowired 49 | ContractService contractService; 50 | 51 | /** 52 | * contract compile. 53 | * 54 | * @param file file 55 | * @return 56 | */ 57 | @ApiOperation(value = "contract compile", notes = "contract compile") 58 | @PostMapping("/compile") 59 | public ResponseEntity compile( 60 | @ApiParam(value = "contract zip file", 61 | required = true) @RequestParam("file") MultipartFile file) 62 | throws BaseException, IOException { 63 | return contractService.compile(file); 64 | } 65 | 66 | /** 67 | * contract deploy. 68 | * 69 | * @param deployInfo parameter 70 | * @param result checkResult 71 | * @return 72 | */ 73 | @ApiOperation(value = "contract deploy", notes = "contract deploy") 74 | @PostMapping("/deploy") 75 | public ResponseEntity deploy(@Valid @RequestBody ReqDeployInfo deployInfo, BindingResult result) 76 | throws BaseException { 77 | log.info("deploy start. deployInfo:{}", JsonUtils.toJSONString(deployInfo)); 78 | checkParamResult(result); 79 | return contractService.deploy(deployInfo); 80 | } 81 | 82 | /** 83 | * get contract address. 84 | * 85 | * @param groupId id 86 | * @param uuidDeploy uuid 87 | * @return 88 | */ 89 | @ApiOperation(value = "getAddress", notes = "get contract address") 90 | @GetMapping("/address/{groupId}/{uuidDeploy}") 91 | public ResponseEntity getAddress(@PathVariable("groupId") int groupId, 92 | @PathVariable("uuidDeploy") String uuidDeploy) throws BaseException { 93 | return contractService.getAddress(groupId, uuidDeploy); 94 | } 95 | 96 | /** 97 | * get deploy event. 98 | * 99 | * @param groupId id 100 | * @param uuidDeploy uuid 101 | * @return 102 | */ 103 | @ApiOperation(value = "getEvent", notes = "get deploy event") 104 | @GetMapping("/event/{groupId}/{uuidDeploy}") 105 | public ResponseEntity getEvent(@PathVariable("groupId") int groupId, 106 | @PathVariable("uuidDeploy") String uuidDeploy) throws BaseException { 107 | return contractService.getEvent(groupId, uuidDeploy); 108 | } 109 | 110 | /** 111 | * get deploy info. 112 | * 113 | * @param groupId id 114 | * @param uuidDeploy uuid 115 | * @return 116 | */ 117 | @ApiOperation(value = "getDeployInfo", notes = "get deploy info") 118 | @GetMapping("/deployInfo/{groupId}/{uuidDeploy}") 119 | public ResponseEntity getDeployInfo(@PathVariable("groupId") int groupId, 120 | @PathVariable("uuidDeploy") String uuidDeploy) throws BaseException { 121 | return contractService.getDeployInfo(groupId, uuidDeploy); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/ContractMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract; 16 | 17 | import com.webank.webase.transaction.contract.entity.DeployInfoDto; 18 | import java.util.Date; 19 | import java.util.List; 20 | import org.apache.ibatis.annotations.Param; 21 | import org.springframework.stereotype.Service; 22 | 23 | /** 24 | * ContractMapper. 25 | * 26 | */ 27 | @Service 28 | public interface ContractMapper { 29 | 30 | void createTbDeployTrans(); 31 | 32 | void insertDeployInfo(DeployInfoDto deployInfoDto); 33 | 34 | DeployInfoDto selectDeployInfo(@Param("groupId") int groupId, 35 | @Param("uuidDeploy") String uuidDeploy); 36 | 37 | String selectContractAddress(@Param("groupId") int groupId, 38 | @Param("uuidDeploy") String uuidDeploy); 39 | 40 | String selectTxHash(@Param("groupId") int groupId, @Param("uuidDeploy") String uuidDeploy); 41 | 42 | String selectContractAbi(@Param("groupId") int groupId, @Param("uuidDeploy") String uuidDeploy); 43 | 44 | int selectStatus(@Param("id") Long id, @Param("gmtCreate") Date gmtCreate); 45 | 46 | List selectUnStatTrans(@Param("requestCountMax") int requestCountMax, 47 | @Param("selectCount") int selectCount, @Param("intervalTime") int intervalTime); 48 | 49 | List selectUnStatTransByJob(@Param("requestCountMax") int requestCountMax, 50 | @Param("selectCount") int selectCount, @Param("intervalTime") int intervalTime, 51 | @Param("shardingTotalCount") int shardingTotalCount, 52 | @Param("shardingItem") int shardingItem); 53 | 54 | void updateRequestCount(@Param("id") Long id, @Param("requestCount") int requestCount, 55 | @Param("gmtCreate") Date gmtCreate); 56 | 57 | void updateHandleStatus(DeployInfoDto deployInfoDto); 58 | 59 | void deletePartData(@Param(value = "keepDays") int keepDays); 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/ContractService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract; 16 | 17 | import com.webank.webase.transaction.base.ConstantCode; 18 | import com.webank.webase.transaction.base.ConstantProperties; 19 | import com.webank.webase.transaction.base.ResponseEntity; 20 | import com.webank.webase.transaction.base.exception.BaseException; 21 | import com.webank.webase.transaction.contract.entity.CompileInfo; 22 | import com.webank.webase.transaction.contract.entity.DeployInfoDto; 23 | import com.webank.webase.transaction.contract.entity.ReqDeployInfo; 24 | import com.webank.webase.transaction.keystore.KeyStoreService; 25 | import com.webank.webase.transaction.keystore.entity.SignType; 26 | import com.webank.webase.transaction.trans.TransService; 27 | import com.webank.webase.transaction.util.CommonUtils; 28 | import com.webank.webase.transaction.util.ContractAbiUtil; 29 | import com.webank.webase.transaction.util.JsonUtils; 30 | import com.webank.webase.transaction.util.LogUtils; 31 | import java.io.File; 32 | import java.io.IOException; 33 | import java.util.ArrayList; 34 | import java.util.Date; 35 | import java.util.List; 36 | import java.util.Map; 37 | import java.util.concurrent.CompletableFuture; 38 | import java.util.concurrent.RejectedExecutionException; 39 | import java.util.concurrent.TimeUnit; 40 | import lombok.extern.slf4j.Slf4j; 41 | import org.apache.commons.lang3.StringUtils; 42 | import org.fisco.bcos.web3j.abi.FunctionEncoder; 43 | import org.fisco.bcos.web3j.abi.datatypes.Type; 44 | import org.fisco.bcos.web3j.crypto.EncryptType; 45 | import org.fisco.bcos.web3j.protocol.Web3j; 46 | import org.fisco.bcos.web3j.protocol.core.methods.response.AbiDefinition; 47 | import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt; 48 | import org.fisco.solc.compiler.CompilationResult; 49 | import org.fisco.solc.compiler.SolidityCompiler; 50 | import org.fisco.solc.compiler.CompilationResult.ContractMetadata; 51 | import org.springframework.beans.factory.annotation.Autowired; 52 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 53 | import org.springframework.stereotype.Service; 54 | import org.springframework.web.multipart.MultipartFile; 55 | 56 | import static org.fisco.solc.compiler.SolidityCompiler.Options.ABI; 57 | import static org.fisco.solc.compiler.SolidityCompiler.Options.BIN; 58 | /** 59 | * ContractService. 60 | * 61 | */ 62 | @Slf4j 63 | @Service 64 | public class ContractService { 65 | @Autowired 66 | Map web3jMap; 67 | @Autowired 68 | TransService transService; 69 | @Autowired 70 | private ContractMapper contractMapper; 71 | @Autowired 72 | private ThreadPoolTaskExecutor transExecutor; 73 | @Autowired 74 | private ConstantProperties properties; 75 | @Autowired 76 | private KeyStoreService keyStoreService; 77 | 78 | /** 79 | * contract compile. 80 | * 81 | * @param zipFile file 82 | * @return 83 | */ 84 | public ResponseEntity compile(MultipartFile zipFile) throws BaseException, IOException { 85 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 86 | String path = new File("temp").getAbsolutePath(); 87 | // clear temp folder 88 | CommonUtils.deleteFiles(path); 89 | // unzip 90 | CommonUtils.unZipFiles(zipFile, path); 91 | // get sol files 92 | File solFileList = new File(path); 93 | File[] solFiles = solFileList.listFiles(); 94 | if (solFiles == null || solFiles.length == 0) { 95 | return response; 96 | } 97 | 98 | // whether use guomi to compile, 1-guomi, 0-ecdsa 99 | boolean useSM2 = EncryptType.encryptType == 1; 100 | List compileInfos = new ArrayList<>(); 101 | for (File solFile : solFiles) { 102 | if (!solFile.getName().endsWith(".sol")) { 103 | continue; 104 | } 105 | String contractName = 106 | solFile.getName().substring(0, solFile.getName().lastIndexOf(".")); 107 | // compile 108 | SolidityCompiler.Result res = 109 | SolidityCompiler.compile(solFile, useSM2, true, ABI, BIN); 110 | // check result 111 | if (res.isFailed()) { 112 | log.warn("compile fail. contract:{} compile error. {}", contractName, res.getErrors()); 113 | throw new BaseException(ConstantCode.CONTRACT_COMPILE_ERROR.getCode(), res.getErrors()); 114 | } 115 | // parse result 116 | CompilationResult result = CompilationResult.parse(res.getOutput()); 117 | List contracts = result.getContracts(); 118 | if (contracts.size() > 0) { 119 | CompileInfo compileInfo = new CompileInfo(); 120 | compileInfo.setContractName(contractName); 121 | compileInfo.setContractBin(result.getContract(contractName).bin); 122 | compileInfo 123 | .setContractAbi(JsonUtils.toJavaObjectList(result.getContract(contractName).abi, Object.class)); 124 | compileInfos.add(compileInfo); 125 | } 126 | } 127 | response.setData(compileInfos); 128 | return response; 129 | } 130 | 131 | /** 132 | * contract deploy. 133 | * 134 | * @param req parameter 135 | * @return 136 | */ 137 | public ResponseEntity deploy(ReqDeployInfo req) throws BaseException { 138 | long startTime = System.currentTimeMillis(); 139 | // check groupId 140 | int groupId = req.getGroupId(); 141 | if (!transService.checkGroupId(groupId)) { 142 | log.warn("deploy fail. groupId:{} has not been configured", groupId); 143 | throw new BaseException(ConstantCode.GROUPID_NOT_CONFIGURED); 144 | } 145 | // check deploy uuid 146 | String uuid = req.getUuidDeploy(); 147 | DeployInfoDto deployInfos = contractMapper.selectDeployInfo(groupId, uuid); 148 | if (deployInfos != null) { 149 | log.error("deploy groupId:{} uuid:{} is exists", groupId, uuid); 150 | long endTime = System.currentTimeMillis(); 151 | LogUtils.monitorBusinessLogger().info(ConstantProperties.CODE_BUSINESS_10003, 152 | endTime - startTime, ConstantProperties.MSG_BUSINESS_10003); 153 | throw new BaseException(ConstantCode.UUID_IS_EXISTS); 154 | } 155 | // check sign type 156 | if (!SignType.isInclude(req.getSignType())) { 157 | log.warn("deploy fail. signType:{} is not existed", req.getSignType()); 158 | throw new BaseException(ConstantCode.SIGN_TYPE_ERROR); 159 | } 160 | // check sign user id 161 | if (SignType.CLOUDCALL.getValue() == req.getSignType()) { 162 | String signUserId = req.getSignUserId(); 163 | if (StringUtils.isBlank(signUserId)) { 164 | log.warn("deploy fail. sign user id is empty"); 165 | throw new BaseException(ConstantCode.SIGN_USERID_EMPTY); 166 | } else { 167 | boolean result = keyStoreService.checkSignUserId(signUserId); 168 | if (!result) { 169 | throw new BaseException(ConstantCode.SIGN_USERID_ERROR); 170 | } 171 | } 172 | } 173 | // check parameters 174 | String contractAbi = JsonUtils.toJSONString(req.getContractAbi()); 175 | List params = req.getFuncParam(); 176 | AbiDefinition abiDefinition = ContractAbiUtil.getAbiDefinition(contractAbi); 177 | List funcInputTypes = ContractAbiUtil.getFuncInputType(abiDefinition); 178 | if (funcInputTypes.size() != params.size()) { 179 | log.warn("deploy fail. funcInputTypes:{}, params:{}", funcInputTypes, params); 180 | throw new BaseException(ConstantCode.IN_FUNCPARAM_ERROR); 181 | } 182 | // check input format 183 | ContractAbiUtil.inputFormat(funcInputTypes, params); 184 | // insert db 185 | DeployInfoDto deployInfoDto = new DeployInfoDto(); 186 | deployInfoDto.setGroupId(groupId); 187 | deployInfoDto.setUuidDeploy(uuid); 188 | deployInfoDto.setContractBin(req.getContractBin()); 189 | deployInfoDto.setContractAbi(contractAbi); 190 | deployInfoDto.setFuncParam(JsonUtils.toJSONString(params)); 191 | deployInfoDto.setSignType(req.getSignType()); 192 | deployInfoDto.setSignUserId(req.getSignUserId()); 193 | deployInfoDto.setGmtCreate(new Date()); 194 | contractMapper.insertDeployInfo(deployInfoDto); 195 | 196 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 197 | log.info("deploy end. groupId:{} uuid:{}", groupId, uuid); 198 | long endTime = System.currentTimeMillis(); 199 | LogUtils.monitorBusinessLogger().info(ConstantProperties.CODE_BUSINESS_10001, 200 | endTime - startTime, ConstantProperties.MSG_BUSINESS_10001); 201 | return response; 202 | } 203 | 204 | /** 205 | * get contract Address. 206 | * 207 | * @param groupId groupId 208 | * @param uuidDeploy uuid 209 | * @return 210 | */ 211 | public ResponseEntity getAddress(int groupId, String uuidDeploy) throws BaseException { 212 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 213 | // check if contract has been deployed 214 | String contractAddress = contractMapper.selectContractAddress(groupId, uuidDeploy); 215 | if (StringUtils.isBlank(contractAddress)) { 216 | log.warn("getAddress fail. contract has not been deployed uuidDeploy:{}.", uuidDeploy); 217 | throw new BaseException(ConstantCode.CONTRACT_NOT_DEPLOED); 218 | } 219 | response.setData(contractAddress); 220 | return response; 221 | } 222 | 223 | /** 224 | * get getDeployInfo. 225 | * 226 | * @param groupId groupId 227 | * @param uuidDeploy uuid 228 | * @return 229 | */ 230 | public ResponseEntity getDeployInfo(int groupId, String uuidDeploy) throws BaseException { 231 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 232 | // check if contract has been deployed 233 | DeployInfoDto deployInfo = contractMapper.selectDeployInfo(groupId, uuidDeploy); 234 | if (deployInfo == null) { 235 | log.warn("getDeployInfo fail. data not exists uuidDeploy:{}.", uuidDeploy); 236 | throw new BaseException(ConstantCode.DATA_NOT_EXISTS); 237 | } 238 | response.setData(deployInfo); 239 | return response; 240 | } 241 | 242 | /** 243 | * get contract Event. 244 | * 245 | * @param groupId groupId 246 | * @param uuidDeploy uuid 247 | * @return 248 | */ 249 | public ResponseEntity getEvent(int groupId, String uuidDeploy) throws BaseException { 250 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 251 | // check if contract has been deployed 252 | String transHash = contractMapper.selectTxHash(groupId, uuidDeploy); 253 | if (StringUtils.isBlank(transHash)) { 254 | log.warn("getEvent fail. contract has not been deployed uuidDeploy:{}.", uuidDeploy); 255 | throw new BaseException(ConstantCode.CONTRACT_NOT_DEPLOED); 256 | } 257 | String contractAbi = contractMapper.selectContractAbi(groupId, uuidDeploy); 258 | if (StringUtils.isBlank(contractAbi)) { 259 | log.warn("getEvent fail. uuidDeploy:{} abi is not exists", uuidDeploy); 260 | throw new BaseException(ConstantCode.CONTRACT_ABI_EMPTY); 261 | } 262 | List abiList = ContractAbiUtil.getEventAbiDefinitions(contractAbi); 263 | if (abiList.isEmpty()) { 264 | log.warn("getEvent fail. uuidDeploy:{} event is not exists", uuidDeploy); 265 | throw new BaseException(ConstantCode.EVENT_NOT_EXISTS); 266 | } 267 | try { 268 | // get TransactionReceipt 269 | TransactionReceipt receipt = web3jMap.get(groupId).getTransactionReceipt(transHash) 270 | .send().getTransactionReceipt().get(); 271 | Object result = ContractAbiUtil.receiptParse(receipt, abiList); 272 | response.setData(result); 273 | } catch (IOException e) { 274 | log.error("getEvent getTransactionReceipt fail. transHash:{} ", transHash); 275 | throw new BaseException(ConstantCode.NODE_REQUEST_FAILED); 276 | } 277 | return response; 278 | } 279 | 280 | /** 281 | * handleDeployInfo. 282 | * 283 | * @param deployInfoList deployInfoList 284 | */ 285 | public void handleDeployInfo(List deployInfoList) { 286 | for (DeployInfoDto deployInfoDto : deployInfoList) { 287 | try { 288 | Thread.sleep(properties.getSleepTime()); 289 | transExecutor.execute(new Runnable() { 290 | @Override 291 | public void run() { 292 | deploySend(deployInfoDto); 293 | } 294 | }); 295 | } catch (RejectedExecutionException e) { 296 | log.error("schedule threadPool is full", e); 297 | } catch (InterruptedException e) { 298 | log.error("schedule InterruptedException", e); 299 | Thread.currentThread().interrupt(); 300 | } 301 | } 302 | } 303 | 304 | /** 305 | * deploySend. 306 | * 307 | * @param deployInfoDto deployInfoDto 308 | */ 309 | public void deploySend(DeployInfoDto deployInfoDto) { 310 | log.debug("deploySend deployInfoDto:{}", JsonUtils.toJSONString(deployInfoDto)); 311 | Long id = deployInfoDto.getId(); 312 | log.info("deploySend id:{}", id); 313 | int groupId = deployInfoDto.getGroupId(); 314 | int requestCount = deployInfoDto.getRequestCount(); 315 | int signType = deployInfoDto.getSignType(); 316 | try { 317 | // check status 318 | int status = contractMapper.selectStatus(id, deployInfoDto.getGmtCreate()); 319 | if (status == 1) { 320 | log.info("deploySend id:{} has successed.", id); 321 | return; 322 | } 323 | // requestCount + 1 324 | contractMapper.updateRequestCount(id, requestCount + 1, deployInfoDto.getGmtCreate()); 325 | // check requestCount 326 | if (requestCount == properties.getRequestCountMax()) { 327 | log.warn("deploySend id:{} has reached limit:{}", id, 328 | properties.getRequestCountMax()); 329 | LogUtils.monitorAbnormalLogger().error(ConstantProperties.CODE_ABNORMAL_S0003, 330 | ConstantProperties.MSG_ABNORMAL_S0003); 331 | return; 332 | } 333 | 334 | String contractAbi = deployInfoDto.getContractAbi(); 335 | String contractBin = deployInfoDto.getContractBin(); 336 | List params = JsonUtils.toJavaObjectList(deployInfoDto.getFuncParam(), Object.class); 337 | 338 | // get function abi 339 | AbiDefinition abiDefinition = ContractAbiUtil.getAbiDefinition(contractAbi); 340 | List funcInputTypes = ContractAbiUtil.getFuncInputType(abiDefinition); 341 | // Constructor encode 342 | String encodedConstructor = ""; 343 | if (funcInputTypes.size() > 0) { 344 | List finalInputs = ContractAbiUtil.inputFormat(funcInputTypes, params); 345 | encodedConstructor = FunctionEncoder.encodeConstructor(finalInputs); 346 | } 347 | // data sign 348 | String data = contractBin + encodedConstructor; 349 | String signMsg = transService.signMessage(groupId, signType, 350 | deployInfoDto.getSignUserId(), "", data); 351 | if (StringUtils.isBlank(signMsg)) { 352 | return; 353 | } 354 | // send transaction 355 | final CompletableFuture transFuture = new CompletableFuture<>(); 356 | transService.sendMessage(groupId, signMsg, transFuture); 357 | TransactionReceipt receipt = 358 | transFuture.get(properties.getTransMaxWait(), TimeUnit.SECONDS); 359 | deployInfoDto.setContractAddress(receipt.getContractAddress()); 360 | deployInfoDto.setTransHash(receipt.getTransactionHash()); 361 | deployInfoDto.setReceiptStatus(receipt.isStatusOK()); 362 | if (receipt.isStatusOK()) { 363 | deployInfoDto.setHandleStatus(1); 364 | } 365 | contractMapper.updateHandleStatus(deployInfoDto); 366 | } catch (Exception e) { 367 | log.error("fail deploySend id:{}", id, e); 368 | LogUtils.monitorAbnormalLogger().error(ConstantProperties.CODE_ABNORMAL_S0001, 369 | ConstantProperties.MSG_ABNORMAL_S0001); 370 | } 371 | } 372 | 373 | /** 374 | * delete contract deploy data. 375 | */ 376 | public void deleteDataSchedule() { 377 | contractMapper.deletePartData(properties.getKeepDays()); 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/entity/CompileInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract.entity; 16 | 17 | import java.util.List; 18 | import lombok.Data; 19 | 20 | /** 21 | * contract compile info. 22 | * 23 | */ 24 | @Data 25 | public class CompileInfo { 26 | private String contractName; 27 | private String contractBin; 28 | private List contractAbi; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/entity/DeployInfoDto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract.entity; 16 | 17 | import java.util.Date; 18 | import lombok.Data; 19 | 20 | /** 21 | * DeployInfoDto. 22 | * 23 | */ 24 | @Data 25 | public class DeployInfoDto { 26 | private Long id; 27 | private int groupId; 28 | private String uuidDeploy; 29 | private String contractBin; 30 | private String contractAbi; 31 | private String contractAddress; 32 | private String funcParam; 33 | private int signType; 34 | private String signUserId; 35 | private int requestCount; 36 | private int handleStatus = 0; 37 | private String transHash; 38 | private boolean receiptStatus; 39 | private Date gmtCreate; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/contract/entity/ReqDeployInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.contract.entity; 16 | 17 | import com.webank.webase.transaction.base.ConstantCode; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.Data; 22 | import org.hibernate.validator.constraints.NotBlank; 23 | import org.hibernate.validator.constraints.NotEmpty; 24 | 25 | /** 26 | * contract deploy request parameters. 27 | * 28 | */ 29 | @Data 30 | public class ReqDeployInfo { 31 | @NotNull(message = ConstantCode.GROUP_ID_IS_EMPTY) 32 | private Integer groupId; 33 | @NotBlank(message = ConstantCode.UUID_IS_EMPTY) 34 | private String uuidDeploy; 35 | @NotNull(message = ConstantCode.SIGN_TYPE_IS_EMPTY) 36 | private Integer signType; 37 | private String signUserId; 38 | @NotBlank(message = ConstantCode.CONTRACT_BIN_IS_EMPTY) 39 | private String contractBin; 40 | @NotEmpty(message = ConstantCode.CONTRACT_ABI_IS_EMPTY) 41 | private List contractAbi; 42 | private List funcParam = new ArrayList<>(); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/gm/EncryptTypeController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.gm; 16 | 17 | import com.webank.webase.transaction.base.ConstantCode; 18 | import com.webank.webase.transaction.base.ResponseEntity; 19 | import io.swagger.annotations.Api; 20 | import lombok.extern.slf4j.Slf4j; 21 | import org.fisco.bcos.web3j.crypto.EncryptType; 22 | import org.springframework.web.bind.annotation.GetMapping; 23 | import org.springframework.web.bind.annotation.RequestMapping; 24 | import org.springframework.web.bind.annotation.RestController; 25 | 26 | /** 27 | * return encrypt type to web 0 is standard, 1 is guomi 28 | */ 29 | @Api(value = "/encrypt", tags = "encrypt type interface(standard/guomi)") 30 | @Slf4j 31 | @RestController 32 | @RequestMapping(value = "encrypt") 33 | public class EncryptTypeController { 34 | @GetMapping("") 35 | public ResponseEntity getEncryptType() { 36 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 37 | int encrypt = EncryptType.encryptType; 38 | log.info("getEncryptType:{}", encrypt); 39 | response.setData(encrypt); 40 | return response; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/job/DataflowJobConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.job; 16 | 17 | import javax.annotation.Resource; 18 | 19 | import org.apache.shardingsphere.elasticjob.api.JobConfiguration; 20 | import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap; 21 | import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter; 22 | import org.springframework.beans.factory.InitializingBean; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Value; 25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 26 | import org.springframework.boot.context.properties.ConfigurationProperties; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.transaction.annotation.EnableTransactionManagement; 29 | 30 | import com.webank.webase.transaction.util.CommonUtils; 31 | 32 | import io.shardingsphere.core.keygen.DefaultKeyGenerator; 33 | import lombok.Data; 34 | 35 | /** 36 | * DataflowJobConfig. 37 | * 38 | */ 39 | @Data 40 | @Configuration 41 | @ConditionalOnProperty(value = {"constant.ifDistributedTask"}, havingValue = "true", matchIfMissing = false) 42 | @EnableTransactionManagement(proxyTargetClass = true) 43 | @ConfigurationProperties(prefix = "job.dataflow") 44 | public class DataflowJobConfig implements InitializingBean { 45 | 46 | @Resource 47 | private CoordinatorRegistryCenter regCenter; 48 | @Autowired 49 | private DeployHandleDataflowJob deployHandleDataflowJob; 50 | @Autowired 51 | private TransHandleDataflowJob transHandleDataflowJob; 52 | 53 | private int shardingTotalCount; 54 | @Value("${constant.cronTrans}") 55 | private String cronMonitor; 56 | 57 | static { 58 | DefaultKeyGenerator.setWorkerId(CommonUtils.getWorkerId()); 59 | } 60 | 61 | @Override 62 | public void afterPropertiesSet() throws Exception { 63 | ScheduleJobBootstrap deploySchedule = new ScheduleJobBootstrap(regCenter, deployHandleDataflowJob, 64 | deployDataflowConfig()); 65 | deploySchedule.schedule(); 66 | ScheduleJobBootstrap transSchedule = new ScheduleJobBootstrap(regCenter, transHandleDataflowJob, 67 | transDataflowConfig()); 68 | transSchedule.schedule(); 69 | } 70 | 71 | /** 72 | * deployDataflowConfig. 73 | * 74 | * @return 75 | */ 76 | private JobConfiguration deployDataflowConfig() { 77 | JobConfiguration jobConfiguration = JobConfiguration 78 | .newBuilder(DeployHandleDataflowJob.class.getName(), shardingTotalCount).cron(cronMonitor).build(); 79 | return jobConfiguration; 80 | } 81 | 82 | /** 83 | * transDataflowConfig. 84 | * 85 | * @return 86 | */ 87 | private JobConfiguration transDataflowConfig() { 88 | JobConfiguration jobConfiguration = JobConfiguration 89 | .newBuilder(TransHandleDataflowJob.class.getName(), shardingTotalCount).cron(cronMonitor).build(); 90 | return jobConfiguration; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/job/DeployHandleDataflowJob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.job; 16 | 17 | import java.util.Iterator; 18 | import java.util.List; 19 | 20 | import org.apache.shardingsphere.elasticjob.api.ShardingContext; 21 | import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 25 | import org.springframework.stereotype.Component; 26 | 27 | import com.webank.webase.transaction.base.ConstantProperties; 28 | import com.webank.webase.transaction.contract.ContractMapper; 29 | import com.webank.webase.transaction.contract.ContractService; 30 | import com.webank.webase.transaction.contract.entity.DeployInfoDto; 31 | 32 | import lombok.extern.slf4j.Slf4j; 33 | 34 | /** 35 | * DeployHandleDataflowJob. 36 | * 37 | */ 38 | @Slf4j 39 | @Component 40 | @ConditionalOnProperty(value = {"constant.ifDistributedTask"}, havingValue = "true", matchIfMissing = false) 41 | public class DeployHandleDataflowJob implements DataflowJob { 42 | @Autowired 43 | ContractService contractService; 44 | @Autowired 45 | private ContractMapper contractMapper; 46 | @Autowired 47 | private ConstantProperties properties; 48 | 49 | @Value("${job.dataflow.shardingTotalCount}") 50 | private int shardingTotalCount; 51 | 52 | @Override 53 | public List fetchData(ShardingContext context) { 54 | log.debug("deploy fetchData item:{}", context.getShardingItem()); 55 | // query untreated data 56 | List deployInfoList = contractMapper.selectUnStatTrans( 57 | properties.getRequestCountMax(), properties.getSelectCount() * shardingTotalCount, 58 | properties.getIntervalTime()); 59 | Iterator iterator = deployInfoList.iterator(); 60 | while (iterator.hasNext()) { 61 | if (iterator.next().getId() % shardingTotalCount != context.getShardingItem()) { 62 | iterator.remove(); 63 | } 64 | } 65 | return deployInfoList; 66 | } 67 | 68 | @Override 69 | public void processData(ShardingContext shardingContext, List deployInfoList) { 70 | contractService.handleDeployInfo(deployInfoList); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/job/JobRegistryCenterConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.job; 16 | 17 | import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter; 18 | import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration; 19 | import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter; 20 | import org.springframework.beans.factory.annotation.Value; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | /** 27 | * ZookeeperRegistryCenter. 28 | * 29 | */ 30 | @Configuration 31 | @ConditionalOnProperty(value = {"constant.ifDistributedTask"}, havingValue = "true", matchIfMissing = false) 32 | @ConditionalOnExpression("'${job.regCenter.serverLists}'.length() > 0") 33 | public class JobRegistryCenterConfig { 34 | 35 | @Bean(initMethod = "init") 36 | public CoordinatorRegistryCenter regCenter( 37 | @Value("${job.regCenter.serverLists}") final String serverLists, 38 | @Value("${job.regCenter.namespace}") final String namespace) { 39 | return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverLists, namespace)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/job/TransHandleDataflowJob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.job; 16 | 17 | import java.util.Iterator; 18 | import java.util.List; 19 | 20 | import org.apache.shardingsphere.elasticjob.api.ShardingContext; 21 | import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 25 | import org.springframework.stereotype.Component; 26 | 27 | import com.webank.webase.transaction.base.ConstantProperties; 28 | import com.webank.webase.transaction.trans.TransMapper; 29 | import com.webank.webase.transaction.trans.TransService; 30 | import com.webank.webase.transaction.trans.entity.TransInfoDto; 31 | 32 | import lombok.extern.slf4j.Slf4j; 33 | 34 | /** 35 | * TransHandleDataflowJob. 36 | * 37 | */ 38 | @Slf4j 39 | @Component 40 | @ConditionalOnProperty(value = {"constant.ifDistributedTask"}, havingValue = "true", matchIfMissing = false) 41 | public class TransHandleDataflowJob implements DataflowJob { 42 | @Autowired 43 | TransService transService; 44 | @Autowired 45 | private TransMapper transMapper; 46 | @Autowired 47 | private ConstantProperties properties; 48 | 49 | @Value("${job.dataflow.shardingTotalCount}") 50 | private int shardingTotalCount; 51 | 52 | @Override 53 | public List fetchData(ShardingContext context) { 54 | log.debug("trans fetchData item:{}", context.getShardingItem()); 55 | // query untreated data 56 | List transInfoList = transMapper.selectUnStatTrans( 57 | properties.getRequestCountMax(), properties.getSelectCount() * shardingTotalCount, 58 | properties.getIntervalTime()); 59 | Iterator iterator = transInfoList.iterator(); 60 | while (iterator.hasNext()) { 61 | if (iterator.next().getId() % shardingTotalCount != context.getShardingItem()) { 62 | iterator.remove(); 63 | } 64 | } 65 | return transInfoList; 66 | } 67 | 68 | @Override 69 | public void processData(ShardingContext shardingContext, List transInfoList) { 70 | transService.handleTransInfo(transInfoList); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/KeyStoreController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore; 16 | 17 | import com.webank.webase.transaction.base.BaseController; 18 | import com.webank.webase.transaction.base.ConstantCode; 19 | import com.webank.webase.transaction.base.ResponseEntity; 20 | import com.webank.webase.transaction.base.exception.BaseException; 21 | import io.swagger.annotations.Api; 22 | import io.swagger.annotations.ApiOperation; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.web.bind.annotation.GetMapping; 25 | import org.springframework.web.bind.annotation.RequestMapping; 26 | import org.springframework.web.bind.annotation.RestController; 27 | 28 | /** 29 | * KeyStoreController. 30 | * 31 | */ 32 | @Api(value = "/key", tags = "keystore interface") 33 | @RestController 34 | @RequestMapping(value = "/key") 35 | public class KeyStoreController extends BaseController { 36 | @Autowired 37 | private KeyStoreService keyStoreService; 38 | 39 | /** 40 | * get user Address. 41 | * 42 | * @return 43 | */ 44 | @ApiOperation(value = "get address", notes = "get user address") 45 | @GetMapping("/address") 46 | public ResponseEntity getAddress() throws BaseException { 47 | ResponseEntity response = new ResponseEntity(ConstantCode.RET_SUCCEED); 48 | response.setData(keyStoreService.getAddress()); 49 | return response; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/KeyStoreService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore; 16 | 17 | import com.webank.webase.transaction.util.JsonUtils; 18 | import com.webank.webase.transaction.base.ConstantCode; 19 | import com.webank.webase.transaction.base.ConstantProperties; 20 | import com.webank.webase.transaction.base.ResponseEntity; 21 | import com.webank.webase.transaction.base.exception.BaseException; 22 | import com.webank.webase.transaction.keystore.entity.EncodeInfo; 23 | import com.webank.webase.transaction.keystore.entity.KeyStoreInfo; 24 | import com.webank.webase.transaction.keystore.entity.SignInfo; 25 | import com.webank.webase.transaction.util.CommonUtils; 26 | import com.webank.webase.transaction.util.LogUtils; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.fisco.bcos.web3j.crypto.Credentials; 29 | import org.fisco.bcos.web3j.crypto.ECKeyPair; 30 | import org.fisco.bcos.web3j.crypto.Keys; 31 | import org.fisco.bcos.web3j.crypto.gm.GenCredential; 32 | import org.fisco.bcos.web3j.utils.Numeric; 33 | import org.springframework.beans.factory.annotation.Autowired; 34 | import org.springframework.http.HttpEntity; 35 | import org.springframework.http.HttpHeaders; 36 | import org.springframework.stereotype.Service; 37 | import org.springframework.web.client.RestTemplate; 38 | 39 | /** 40 | * KeyStoreService. 41 | * 42 | */ 43 | @Slf4j 44 | @Service 45 | public class KeyStoreService { 46 | @Autowired 47 | RestTemplate restTemplate; 48 | @Autowired 49 | private ConstantProperties properties; 50 | 51 | private static final int PUBLIC_KEY_LENGTH_IN_HEX = 128; 52 | private static final String SIGN_ADDSIGN_URL = "http://%s/WeBASE-Sign/sign"; 53 | private static final String SIGN_USERINFO_URL = "http://%s/WeBASE-Sign/user/%s/userInfo"; 54 | 55 | /** 56 | * get KeyStoreInfo. 57 | * 58 | * @return 59 | */ 60 | public KeyStoreInfo getKey() throws BaseException { 61 | try { 62 | ECKeyPair keyPair = Keys.createEcKeyPair(); 63 | String publicKey = Numeric.toHexStringWithPrefixZeroPadded(keyPair.getPublicKey(), 64 | PUBLIC_KEY_LENGTH_IN_HEX); 65 | String privateKey = Numeric.toHexStringNoPrefix(keyPair.getPrivateKey()); 66 | String address = "0x" + Keys.getAddress(publicKey); 67 | 68 | KeyStoreInfo keyStoreInfo = new KeyStoreInfo(); 69 | keyStoreInfo.setPublicKey(publicKey); 70 | keyStoreInfo.setPrivateKey(privateKey); 71 | keyStoreInfo.setAddress(address); 72 | 73 | return keyStoreInfo; 74 | } catch (Exception e) { 75 | log.error("createEcKeyPair fail."); 76 | throw new BaseException(ConstantCode.SYSTEM_ERROR); 77 | } 78 | } 79 | 80 | /** 81 | * get user Address. 82 | * 83 | * @return 84 | */ 85 | public String getAddress() throws BaseException { 86 | try { 87 | String privateKey = properties.getPrivateKey(); 88 | Credentials credentials = GenCredential.create(privateKey); 89 | return credentials.getAddress(); 90 | } catch (Exception e) { 91 | log.error("getAddress fail."); 92 | throw new BaseException(ConstantCode.SYSTEM_ERROR); 93 | } 94 | } 95 | 96 | /** 97 | * get random Address. 98 | * 99 | * @return 100 | */ 101 | public String getRandomAddress() throws BaseException { 102 | try { 103 | Credentials credentials = GenCredential.create(); 104 | return credentials.getAddress(); 105 | } catch (Exception e) { 106 | log.error("getRandomAddress fail."); 107 | throw new BaseException(ConstantCode.SYSTEM_ERROR); 108 | } 109 | } 110 | 111 | /** 112 | * getSignDatd from webase-sign service. 113 | * 114 | * @param params params 115 | * @return 116 | */ 117 | public String getSignData(EncodeInfo params) { 118 | try { 119 | SignInfo signInfo = new SignInfo(); 120 | String url = String.format(SIGN_ADDSIGN_URL, properties.getSignServer()); 121 | log.info("getSignData url:{}", url); 122 | HttpHeaders headers = CommonUtils.buildHeaders(); 123 | HttpEntity formEntity = 124 | new HttpEntity(JsonUtils.toJSONString(params), headers); 125 | ResponseEntity response = 126 | restTemplate.postForObject(url, formEntity, ResponseEntity.class); 127 | log.info("getSignData response:{}", JsonUtils.toJSONString(response)); 128 | if (response.getCode() == 0) { 129 | signInfo = CommonUtils.object2JavaBean(response.getData(), SignInfo.class); 130 | } 131 | return signInfo.getSignDataStr(); 132 | } catch (Exception e) { 133 | log.error("getSignData exception", e); 134 | LogUtils.monitorAbnormalLogger().error(ConstantProperties.CODE_ABNORMAL_S0005, 135 | ConstantProperties.MSG_ABNORMAL_S0005); 136 | } 137 | return null; 138 | } 139 | 140 | /** 141 | * checkSignUserId. 142 | * 143 | * @param signUserId business id of user in sign 144 | * @return 145 | */ 146 | public boolean checkSignUserId(String signUserId) { 147 | try { 148 | String url = String.format(SIGN_USERINFO_URL, properties.getSignServer(), signUserId); 149 | log.info("checkSignUserId url:{}", url); 150 | ResponseEntity response = restTemplate.getForObject(url, ResponseEntity.class); 151 | log.info("checkSignUserId response:{}", JsonUtils.toJSONString(response)); 152 | if (response.getCode() == 0) { 153 | return true; 154 | } 155 | } catch (Exception e) { 156 | log.error("checkSignUserId exception", e); 157 | } 158 | return false; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/entity/EncodeInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore.entity; 16 | 17 | import lombok.Data; 18 | 19 | /** 20 | * EncodeInfo. 21 | * 22 | */ 23 | @Data 24 | public class EncodeInfo { 25 | private String signUserId; 26 | private String encodedDataStr; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/entity/KeyStoreInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore.entity; 16 | 17 | import lombok.Data; 18 | 19 | /** 20 | * KeyStoreInfo. 21 | * 22 | */ 23 | @Data 24 | public class KeyStoreInfo { 25 | private String publicKey; 26 | private String privateKey; 27 | private String address; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/entity/SignInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore.entity; 16 | 17 | import lombok.Data; 18 | 19 | /** 20 | * SignInfo. 21 | * 22 | */ 23 | @Data 24 | public class SignInfo { 25 | private String signDataStr; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/keystore/entity/SignType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.keystore.entity; 16 | 17 | /** 18 | * SignType. 19 | * 20 | */ 21 | public enum SignType { 22 | LOCALCONFIG(0), LOCALRANDOM(1), CLOUDCALL(2); 23 | 24 | private int value; 25 | 26 | private SignType(int value) { 27 | this.value = value; 28 | } 29 | 30 | public int getValue() { 31 | return value; 32 | } 33 | 34 | /** 35 | * isInclude. 36 | * 37 | * @param key value 38 | * @return 39 | */ 40 | public static boolean isInclude(int key) { 41 | boolean include = false; 42 | for (SignType e : SignType.values()) { 43 | if (e.getValue() == key) { 44 | include = true; 45 | break; 46 | } 47 | } 48 | return include; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/scheduler/ScheduleService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.scheduler; 16 | 17 | import com.webank.webase.transaction.base.ConstantProperties; 18 | import com.webank.webase.transaction.contract.ContractMapper; 19 | import com.webank.webase.transaction.contract.ContractService; 20 | import com.webank.webase.transaction.contract.entity.DeployInfoDto; 21 | import com.webank.webase.transaction.trans.TransMapper; 22 | import com.webank.webase.transaction.trans.TransService; 23 | import com.webank.webase.transaction.trans.entity.TransInfoDto; 24 | import java.util.List; 25 | import lombok.extern.slf4j.Slf4j; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.scheduling.annotation.Async; 28 | import org.springframework.stereotype.Service; 29 | 30 | /** 31 | * ScheduleService. 32 | * 33 | */ 34 | @Slf4j 35 | @Service 36 | public class ScheduleService { 37 | @Autowired 38 | private TransMapper transMapper; 39 | @Autowired 40 | private ContractMapper contractMapper; 41 | @Autowired 42 | private TransService transService; 43 | @Autowired 44 | private ContractService contractService; 45 | @Autowired 46 | private ConstantProperties properties; 47 | 48 | /** 49 | * deploySchedule. 50 | */ 51 | public synchronized void deploySchedule() { 52 | log.debug("deploySchedule start..."); 53 | List deployInfoList = 54 | contractMapper.selectUnStatTrans(properties.getRequestCountMax(), 55 | properties.getSelectCount(), properties.getIntervalTime()); 56 | contractService.handleDeployInfo(deployInfoList); 57 | } 58 | 59 | /** 60 | * transSchedule. 61 | */ 62 | public synchronized void transSchedule() { 63 | log.debug("transSchedule start..."); 64 | List transInfoList = 65 | transMapper.selectUnStatTrans(properties.getRequestCountMax(), 66 | properties.getSelectCount(), properties.getIntervalTime()); 67 | transService.handleTransInfo(transInfoList); 68 | } 69 | 70 | /** 71 | * deleteDataSchedule. 72 | */ 73 | @Async 74 | public void deleteDataSchedule() { 75 | log.debug("deleteDataSchedule start..."); 76 | contractService.deleteDataSchedule(); 77 | transService.deleteDataSchedule(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/scheduler/SchedulerConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.scheduler; 16 | 17 | import com.webank.webase.transaction.base.ConstantProperties; 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.scheduling.annotation.EnableScheduling; 20 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 21 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 22 | import org.springframework.scheduling.support.CronTrigger; 23 | import org.springframework.stereotype.Component; 24 | 25 | /** 26 | * SchedulerConfig. 27 | * 28 | */ 29 | @Component 30 | @EnableScheduling 31 | public class SchedulerConfig implements SchedulingConfigurer { 32 | @Autowired 33 | private ScheduleService scheduleService; 34 | @Autowired 35 | private ConstantProperties constants; 36 | 37 | @Override 38 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 39 | if (constants.isIfDeleteData()) { 40 | taskRegistrar.addTriggerTask(() -> scheduleService.deleteDataSchedule(), 41 | (context) -> new CronTrigger(constants.getCronDeleteData()) 42 | .nextExecutionTime(context)); 43 | } 44 | if (!constants.isIfDistributedTask()) { 45 | taskRegistrar.addTriggerTask(() -> scheduleService.deploySchedule(), 46 | (context) -> new CronTrigger(constants.getCronTrans()) 47 | .nextExecutionTime(context)); 48 | taskRegistrar.addTriggerTask(() -> scheduleService.transSchedule(), 49 | (context) -> new CronTrigger(constants.getCronTrans()) 50 | .nextExecutionTime(context)); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/trans/TransController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.trans; 16 | 17 | import com.webank.webase.transaction.util.JsonUtils; 18 | import com.webank.webase.transaction.base.BaseController; 19 | import com.webank.webase.transaction.base.ResponseEntity; 20 | import com.webank.webase.transaction.base.exception.BaseException; 21 | import com.webank.webase.transaction.trans.entity.ReqTransCallInfo; 22 | import com.webank.webase.transaction.trans.entity.ReqTransSendInfo; 23 | import io.swagger.annotations.Api; 24 | import io.swagger.annotations.ApiOperation; 25 | import javax.validation.Valid; 26 | import lombok.extern.slf4j.Slf4j; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.validation.BindingResult; 29 | import org.springframework.web.bind.annotation.GetMapping; 30 | import org.springframework.web.bind.annotation.PathVariable; 31 | import org.springframework.web.bind.annotation.PostMapping; 32 | import org.springframework.web.bind.annotation.RequestBody; 33 | import org.springframework.web.bind.annotation.RequestMapping; 34 | import org.springframework.web.bind.annotation.RestController; 35 | 36 | /** 37 | * Transaction Controller. 38 | * 39 | */ 40 | @Api(value = "/trans", tags = "transaction interface") 41 | @Slf4j 42 | @RestController 43 | @RequestMapping(value = "/trans") 44 | public class TransController extends BaseController { 45 | @Autowired 46 | TransService transService; 47 | 48 | /** 49 | * transaction send. 50 | * 51 | * @param transSendInfo parameter 52 | * @param result checkResult 53 | * @return 54 | */ 55 | @ApiOperation(value = "transaction send", notes = "transaction send") 56 | @PostMapping("/send") 57 | public ResponseEntity send(@Valid @RequestBody ReqTransSendInfo transSendInfo, 58 | BindingResult result) throws BaseException { 59 | log.info("transSend start. transSendInfo:{}", JsonUtils.toJSONString(transSendInfo)); 60 | checkParamResult(result); 61 | return transService.save(transSendInfo); 62 | } 63 | 64 | /** 65 | * transaction call. 66 | * 67 | * @param transCallInfo parameter 68 | * @param result checkResult 69 | * @return 70 | */ 71 | @ApiOperation(value = "transaction call", notes = "transaction call") 72 | @PostMapping("/call") 73 | public ResponseEntity call(@Valid @RequestBody ReqTransCallInfo transCallInfo, 74 | BindingResult result) throws BaseException { 75 | log.info("call start. transCallInfo:{}", JsonUtils.toJSONString(transCallInfo)); 76 | checkParamResult(result); 77 | return transService.call(transCallInfo); 78 | } 79 | 80 | /** 81 | * get transaction event. 82 | * 83 | * @param groupId id 84 | * @param uuidStateless uuid 85 | * @return 86 | */ 87 | @ApiOperation(value = "getEvent", notes = "get transaction event") 88 | @GetMapping("/event/{groupId}/{uuidStateless}") 89 | public ResponseEntity getEvent(@PathVariable("groupId") int groupId, 90 | @PathVariable("uuidStateless") String uuidStateless) throws BaseException { 91 | return transService.getEvent(groupId, uuidStateless); 92 | } 93 | 94 | /** 95 | * get transaction output. 96 | * 97 | * @param groupId id 98 | * @param uuidStateless uuid 99 | * @return 100 | */ 101 | @ApiOperation(value = "getOutput", notes = "get transaction output") 102 | @GetMapping("/output/{groupId}/{uuidStateless}") 103 | public ResponseEntity getOutput(@PathVariable("groupId") int groupId, 104 | @PathVariable("uuidStateless") String uuidStateless) throws BaseException { 105 | return transService.getOutput(groupId, uuidStateless); 106 | } 107 | 108 | /** 109 | * get transaction info. 110 | * 111 | * @param groupId id 112 | * @param uuidStateless uuid 113 | * @return 114 | */ 115 | @ApiOperation(value = "getTransInfo", notes = "get transaction info") 116 | @GetMapping("/transInfo/{groupId}/{uuidStateless}") 117 | public ResponseEntity getTransInfo(@PathVariable("groupId") int groupId, 118 | @PathVariable("uuidStateless") String uuidStateless) throws BaseException { 119 | return transService.getTransInfo(groupId, uuidStateless); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/trans/TransMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.trans; 16 | 17 | import com.webank.webase.transaction.trans.entity.TransInfoDto; 18 | import java.util.Date; 19 | import java.util.List; 20 | import org.apache.ibatis.annotations.Param; 21 | import org.springframework.stereotype.Service; 22 | 23 | /** 24 | * TransMapper. 25 | * 26 | */ 27 | @Service 28 | public interface TransMapper { 29 | 30 | void createTbStatelessTrans(); 31 | 32 | void insertTransInfo(TransInfoDto transInfoDto); 33 | 34 | TransInfoDto selectTransInfo(@Param("groupId") int groupId, 35 | @Param("uuidStateless") String uuidStateless); 36 | 37 | int selectStatus(@Param("id") Long id, @Param("gmtCreate") Date gmtCreate); 38 | 39 | List selectUnStatTrans(@Param("requestCountMax") int requestCountMax, 40 | @Param("selectCount") int selectCount, @Param("intervalTime") int intervalTime); 41 | 42 | List selectUnStatTransByJob(@Param("requestCountMax") int requestCountMax, 43 | @Param("selectCount") int selectCount, @Param("intervalTime") int intervalTime, 44 | @Param("shardingTotalCount") int shardingTotalCount, 45 | @Param("shardingItem") int shardingItem); 46 | 47 | void updateRequestCount(@Param("id") Long id, @Param("requestCount") int requestCount, 48 | @Param("gmtCreate") Date gmtCreate); 49 | 50 | void updateHandleStatus(TransInfoDto transInfoDto); 51 | 52 | void deletePartData(@Param(value = "keepDays") int keepDays); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/trans/entity/ReqTransCallInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.trans.entity; 16 | 17 | import com.webank.webase.transaction.base.ConstantCode; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.Data; 22 | import org.hibernate.validator.constraints.NotBlank; 23 | 24 | /** 25 | * transaction call request parameters. 26 | * 27 | */ 28 | @Data 29 | public class ReqTransCallInfo { 30 | @NotNull(message = ConstantCode.GROUP_ID_IS_EMPTY) 31 | private int groupId; 32 | private String uuidDeploy; 33 | private List contractAbi = new ArrayList<>(); 34 | private String contractAddress; 35 | @NotBlank(message = ConstantCode.FUNCTION_NAME_IS_EMPTY) 36 | private String funcName; 37 | private List funcParam = new ArrayList<>(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/trans/entity/ReqTransSendInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.trans.entity; 16 | 17 | import com.webank.webase.transaction.base.ConstantCode; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.Data; 22 | import org.hibernate.validator.constraints.NotBlank; 23 | 24 | /** 25 | * transaction send request parameters. 26 | * 27 | */ 28 | @Data 29 | public class ReqTransSendInfo { 30 | @NotNull(message = ConstantCode.GROUP_ID_IS_EMPTY) 31 | private Integer groupId; 32 | @NotBlank(message = ConstantCode.UUID_IS_EMPTY) 33 | private String uuidStateless; 34 | private String uuidDeploy; 35 | @NotNull(message = ConstantCode.SIGN_TYPE_IS_EMPTY) 36 | private Integer signType; 37 | private String signUserId; 38 | private List contractAbi = new ArrayList<>(); 39 | private String contractAddress; 40 | @NotBlank(message = ConstantCode.FUNCTION_NAME_IS_EMPTY) 41 | private String funcName; 42 | private List funcParam = new ArrayList<>(); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/trans/entity/TransInfoDto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.trans.entity; 16 | 17 | import java.util.Date; 18 | import lombok.Data; 19 | 20 | /** 21 | * TransInfoDto. 22 | * 23 | */ 24 | @Data 25 | public class TransInfoDto { 26 | private Long id; 27 | private int groupId; 28 | private String uuidStateless; 29 | private String uuidDeploy; 30 | private String contractAbi; 31 | private String contractAddress; 32 | private String funcName; 33 | private String funcParam; 34 | private int signType; 35 | private String signUserId; 36 | private int requestCount; 37 | private int handleStatus = 0; 38 | private String transHash; 39 | private String transOutput; 40 | private boolean receiptStatus; 41 | private Date gmtCreate; 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/util/CommonUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.util; 16 | 17 | import java.io.Closeable; 18 | import java.io.File; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | import java.net.InetAddress; 24 | import java.net.UnknownHostException; 25 | import java.util.Enumeration; 26 | import java.util.Random; 27 | import java.util.zip.ZipEntry; 28 | import java.util.zip.ZipFile; 29 | 30 | import org.fisco.bcos.web3j.crypto.EncryptType; 31 | import org.fisco.bcos.web3j.crypto.Sign.SignatureData; 32 | import org.fisco.bcos.web3j.utils.Numeric; 33 | import org.springframework.http.HttpHeaders; 34 | import org.springframework.http.MediaType; 35 | import org.springframework.web.multipart.MultipartFile; 36 | 37 | import com.webank.webase.transaction.base.ConstantCode; 38 | import com.webank.webase.transaction.base.exception.BaseException; 39 | 40 | import lombok.extern.slf4j.Slf4j; 41 | 42 | /** 43 | * CommonUtils. 44 | * 45 | */ 46 | @Slf4j 47 | public class CommonUtils { 48 | 49 | public static final int publicKeyLength_64 = 64; 50 | 51 | /** 52 | * unZipFiles. 53 | * 54 | * @param zipFile 55 | * file 56 | * @param path 57 | * path 58 | */ 59 | public static void unZipFiles(MultipartFile zipFile, String path) throws IOException, BaseException { 60 | if (zipFile.isEmpty()) { 61 | throw new BaseException(ConstantCode.FILE_IS_EMPTY); 62 | } 63 | if (!path.endsWith(File.separator)) { 64 | path = path + File.separator; 65 | } 66 | String fileName = zipFile.getOriginalFilename(); 67 | int pos = fileName.lastIndexOf("."); 68 | String extName = fileName.substring(pos + 1).toLowerCase(); 69 | if (!extName.equals("zip")) { 70 | throw new BaseException(ConstantCode.NOT_A_ZIP_FILE); 71 | } 72 | File file = new File(path + fileName); 73 | if (!file.getParentFile().exists()) { 74 | file.getParentFile().mkdirs(); 75 | } 76 | zipFile.transferTo(file); 77 | ZipFile zf = null; 78 | try { 79 | zf = new ZipFile(file); 80 | for (Enumeration entries = zf.entries(); entries.hasMoreElements();) { 81 | ZipEntry entry = (ZipEntry) entries.nextElement(); 82 | String zipEntryName = entry.getName(); 83 | if (!zipEntryName.endsWith(".sol")) { 84 | continue; 85 | } 86 | InputStream inputStream = null; 87 | OutputStream outputStream = null; 88 | try { 89 | inputStream = zf.getInputStream(entry); 90 | String outPath = (path + zipEntryName).replaceAll("\\*", "/"); 91 | log.info("unZipFiles outPath:{}", cleanString(outPath)); 92 | 93 | outputStream = new FileOutputStream(cleanString(outPath)); 94 | byte[] buf1 = new byte[1024]; 95 | int len; 96 | while ((len = inputStream.read(buf1)) > 0) { 97 | outputStream.write(buf1, 0, len); 98 | } 99 | outputStream.flush(); 100 | } catch (IOException e) { 101 | System.out.println("unZipFiles IOException:" + e.toString()); 102 | } finally { 103 | close(outputStream); 104 | close(inputStream); 105 | } 106 | } 107 | } catch (IOException e) { 108 | System.out.println("unZipFiles IOException:" + e.toString()); 109 | } finally { 110 | close(zf); 111 | } 112 | if (file.exists()) { 113 | file.delete(); 114 | } 115 | } 116 | 117 | private static String cleanString(String str) { 118 | if (str == null) { 119 | return null; 120 | } 121 | String cleanString = ""; 122 | for (int i = 0; i < str.length(); ++i) { 123 | cleanString += cleanChar(str.charAt(i)); 124 | } 125 | return cleanString; 126 | } 127 | 128 | private static char cleanChar(char value) { 129 | // 0 - 9 130 | for (int i = 48; i < 58; ++i) { 131 | if (value == i) { 132 | return (char) i; 133 | } 134 | } 135 | // 'A' - 'Z' 136 | for (int i = 65; i < 91; ++i) { 137 | if (value == i) { 138 | return (char) i; 139 | } 140 | } 141 | // 'a' - 'z' 142 | for (int i = 97; i < 123; ++i) { 143 | if (value == i) { 144 | return (char) i; 145 | } 146 | } 147 | // other valid characters 148 | switch (value) { 149 | case '\\': 150 | return '\\'; 151 | case '/': 152 | return '/'; 153 | case ':': 154 | return ':'; 155 | case '.': 156 | return '.'; 157 | case '-': 158 | return '-'; 159 | case '_': 160 | return '_'; 161 | default: 162 | return ' '; 163 | } 164 | } 165 | 166 | /** 167 | * close Closeable. 168 | * 169 | * @param closeable 170 | * object 171 | */ 172 | private static void close(Closeable closeable) { 173 | if (closeable != null) { 174 | try { 175 | closeable.close(); 176 | } catch (IOException e) { 177 | System.out.println("close IOException:" + e.toString()); 178 | } 179 | } 180 | } 181 | 182 | /** 183 | * buildHeaders. 184 | * 185 | * @return 186 | */ 187 | public static HttpHeaders buildHeaders() { 188 | HttpHeaders headers = new HttpHeaders(); 189 | MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); 190 | headers.setContentType(type); 191 | headers.add("Accept", MediaType.APPLICATION_JSON.toString()); 192 | return headers; 193 | } 194 | 195 | /** 196 | * stringToSignatureData. 19/12/24 support guomi: add byte[] pub in 197 | * signatureData 198 | * 199 | * @param signatureData 200 | * signatureData 201 | * @return 202 | */ 203 | public static SignatureData stringToSignatureData(String signatureData) { 204 | byte[] byteArr = Numeric.hexStringToByteArray(signatureData); 205 | byte[] signR = new byte[32]; 206 | System.arraycopy(byteArr, 1, signR, 0, signR.length); 207 | byte[] signS = new byte[32]; 208 | System.arraycopy(byteArr, 1 + signR.length, signS, 0, signS.length); 209 | if (EncryptType.encryptType == 1) { 210 | byte[] pub = new byte[64]; 211 | System.arraycopy(byteArr, 1 + signR.length + signS.length, pub, 0, pub.length); 212 | return new SignatureData(byteArr[0], signR, signS, pub); 213 | } else { 214 | return new SignatureData(byteArr[0], signR, signS); 215 | } 216 | } 217 | 218 | /** 219 | * signatureDataToString. 19/12/24 support guomi: add byte[] pub in 220 | * signatureData 221 | * 222 | * @param signatureData 223 | * signatureData 224 | */ 225 | public static String signatureDataToString(SignatureData signatureData) { 226 | byte[] byteArr; 227 | if (EncryptType.encryptType == 1) { 228 | byteArr = new byte[1 + signatureData.getR().length + signatureData.getS().length + publicKeyLength_64]; 229 | byteArr[0] = signatureData.getV(); 230 | System.arraycopy(signatureData.getR(), 0, byteArr, 1, signatureData.getR().length); 231 | System.arraycopy(signatureData.getS(), 0, byteArr, signatureData.getR().length + 1, 232 | signatureData.getS().length); 233 | System.arraycopy(signatureData.getPub(), 0, byteArr, 234 | signatureData.getS().length + signatureData.getR().length + 1, signatureData.getPub().length); 235 | } else { 236 | byteArr = new byte[1 + signatureData.getR().length + signatureData.getS().length]; 237 | byteArr[0] = signatureData.getV(); 238 | System.arraycopy(signatureData.getR(), 0, byteArr, 1, signatureData.getR().length); 239 | System.arraycopy(signatureData.getS(), 0, byteArr, signatureData.getR().length + 1, 240 | signatureData.getS().length); 241 | } 242 | return Numeric.toHexString(byteArr, 0, byteArr.length, false); 243 | } 244 | 245 | /** 246 | * Object to JavaBean. 247 | * 248 | * @param obj 249 | * obj 250 | * @param clazz 251 | * clazz 252 | * @return 253 | */ 254 | public static T object2JavaBean(Object obj, Class clazz) { 255 | if (obj == null || clazz == null) { 256 | log.warn("Object2JavaBean. obj or clazz null"); 257 | return null; 258 | } 259 | String jsonStr = JsonUtils.toJSONString(obj); 260 | return JsonUtils.toJavaObject(jsonStr, clazz); 261 | } 262 | 263 | /** 264 | * delete single File. 265 | * 266 | * @param filePath 267 | * filePath 268 | * @return 269 | */ 270 | public static boolean deleteFile(String filePath) { 271 | boolean flag = false; 272 | File file = new File(filePath); 273 | if (file.isFile() && file.exists()) { 274 | file.delete(); 275 | flag = true; 276 | } 277 | return flag; 278 | } 279 | 280 | /** 281 | * delete Files. 282 | * 283 | * @param path 284 | * path 285 | * @return 286 | */ 287 | public static boolean deleteFiles(String path) { 288 | if (!path.endsWith(File.separator)) { 289 | path = path + File.separator; 290 | } 291 | File dirFile = new File(path); 292 | if (!dirFile.exists() || !dirFile.isDirectory()) { 293 | return false; 294 | } 295 | boolean flag = true; 296 | File[] files = dirFile.listFiles(); 297 | if (files == null) { 298 | return false; 299 | } 300 | for (int i = 0; i < files.length; i++) { 301 | if (files[i].isFile()) { 302 | flag = deleteFile(files[i].getAbsolutePath()); 303 | if (!flag) { 304 | break; 305 | } 306 | } else { 307 | flag = deleteFiles(files[i].getAbsolutePath()); 308 | if (!flag) { 309 | break; 310 | } 311 | } 312 | } 313 | if (!flag) { 314 | return false; 315 | } 316 | return true; 317 | } 318 | 319 | public static Long getWorkerId() { 320 | InetAddress address; 321 | try { 322 | address = InetAddress.getLocalHost(); 323 | } catch (final UnknownHostException e) { 324 | log.warn("Cannot get LocalHost InetAddress, please check your network!"); 325 | return (long) new Random().nextInt(100); 326 | } 327 | log.info("getWorkerId. address:{}", address); 328 | byte[] ipAddressByteArray = address.getAddress(); 329 | Long workerId = Long.valueOf(((ipAddressByteArray[ipAddressByteArray.length - 2] & 0B11) << Byte.SIZE) 330 | + (ipAddressByteArray[ipAddressByteArray.length - 1] & 0xFF)); 331 | return workerId; 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/util/ContractAbiUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.util; 16 | 17 | import com.webank.webase.transaction.base.ConstantProperties; 18 | import com.webank.webase.transaction.base.exception.BaseException; 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | import org.fisco.bcos.web3j.abi.EventValues; 28 | import org.fisco.bcos.web3j.abi.TypeReference; 29 | import org.fisco.bcos.web3j.abi.datatypes.DynamicArray; 30 | import org.fisco.bcos.web3j.abi.datatypes.Event; 31 | import org.fisco.bcos.web3j.abi.datatypes.Type; 32 | import org.fisco.bcos.web3j.protocol.core.methods.response.AbiDefinition; 33 | import org.fisco.bcos.web3j.protocol.core.methods.response.AbiDefinition.NamedType; 34 | import org.fisco.bcos.web3j.protocol.core.methods.response.Log; 35 | import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt; 36 | import org.fisco.bcos.web3j.tx.Contract; 37 | 38 | /** 39 | * ContractAbiUtil. 40 | * 41 | */ 42 | public class ContractAbiUtil { 43 | 44 | /** 45 | * saveSolFile. 46 | * 47 | * @param toolDir path 48 | * @param contractName name 49 | * @param contractArr content 50 | */ 51 | public static void saveSolFile(String toolDir, String contractName, byte[] contractArr) 52 | throws IOException { 53 | File file = new File(""); 54 | if (file.exists()) { 55 | file.delete(); 56 | file.createNewFile(); 57 | } else { 58 | file.createNewFile(); 59 | } 60 | 61 | FileOutputStream outputStream = null; 62 | try { 63 | outputStream = new FileOutputStream(file); 64 | outputStream.write(contractArr); 65 | outputStream.flush(); 66 | } catch (IOException e) { 67 | System.out.println("saveSolFile IOException:" + e.toString()); 68 | throw e; 69 | } finally { 70 | try { 71 | if (outputStream != null) { 72 | outputStream.close(); 73 | } 74 | } catch (IOException ex) { 75 | System.out.println("saveSolFile IOException:" + ex.toString()); 76 | } 77 | } 78 | return; 79 | } 80 | 81 | /** 82 | * get constructor abi info. 83 | * 84 | * @param contractAbi contractAbi 85 | * @return 86 | */ 87 | public static AbiDefinition getAbiDefinition(String contractAbi) { 88 | List abiArr = JsonUtils.toJavaObjectList(contractAbi, AbiDefinition.class); 89 | AbiDefinition result = null; 90 | for (AbiDefinition abiDefinition : abiArr) { 91 | if (ConstantProperties.TYPE_CONSTRUCTOR.equals(abiDefinition.getType())) { 92 | result = abiDefinition; 93 | break; 94 | } 95 | } 96 | return result; 97 | } 98 | 99 | /** 100 | * get function abi info. 101 | * 102 | * @param name name 103 | * @param contractAbi contractAbi 104 | * @return 105 | */ 106 | public static AbiDefinition getAbiDefinition(String name, String contractAbi) { 107 | List abiArr = JsonUtils.toJavaObjectList(contractAbi, AbiDefinition.class); 108 | AbiDefinition result = null; 109 | for (AbiDefinition abiDefinition : abiArr) { 110 | if (ConstantProperties.TYPE_FUNCTION.equals(abiDefinition.getType()) 111 | && name.equals(abiDefinition.getName())) { 112 | result = abiDefinition; 113 | break; 114 | } 115 | } 116 | return result; 117 | } 118 | 119 | /** 120 | * get event abi info. 121 | * 122 | * @param contractAbi contractAbi 123 | * @return 124 | */ 125 | public static List getEventAbiDefinitions(String contractAbi) { 126 | List abiArr = JsonUtils.toJavaObjectList(contractAbi, AbiDefinition.class); 127 | List result = new ArrayList<>(); 128 | for (AbiDefinition abiDefinition : abiArr) { 129 | if (ConstantProperties.TYPE_EVENT.equals(abiDefinition.getType())) { 130 | result.add(abiDefinition); 131 | } 132 | } 133 | return result; 134 | } 135 | 136 | /** 137 | * getFuncInputType. 138 | * 139 | * @param abiDefinition abiDefinition 140 | * @return 141 | */ 142 | public static List getFuncInputType(AbiDefinition abiDefinition) { 143 | List inputList = new ArrayList<>(); 144 | if (abiDefinition != null) { 145 | List inputs = abiDefinition.getInputs(); 146 | for (NamedType input : inputs) { 147 | inputList.add(input.getType()); 148 | } 149 | } 150 | return inputList; 151 | } 152 | 153 | /** 154 | * getFuncOutputType. 155 | * 156 | * @param abiDefinition abiDefinition 157 | * @return 158 | */ 159 | public static List getFuncOutputType(AbiDefinition abiDefinition) { 160 | List outputList = new ArrayList<>(); 161 | List outputs = abiDefinition.getOutputs(); 162 | for (NamedType output : outputs) { 163 | outputList.add(output.getType()); 164 | } 165 | return outputList; 166 | } 167 | 168 | /** 169 | * input parameter format. 170 | * 171 | * @param funcInputTypes list 172 | * @param params list 173 | * @return 174 | */ 175 | public static List inputFormat(List funcInputTypes, List params) 176 | throws BaseException { 177 | List finalInputs = new ArrayList<>(); 178 | for (int i = 0; i < funcInputTypes.size(); i++) { 179 | Class inputType = null; 180 | Object input = null; 181 | if (funcInputTypes.get(i).contains("[") 182 | && funcInputTypes.get(i).contains("]")) { 183 | List arrList = 184 | new ArrayList<>(Arrays.asList(params.get(i).toString().split(","))); 185 | inputType = ContractTypeUtil.getType( 186 | funcInputTypes.get(i).substring(0, funcInputTypes.get(i).indexOf("["))); 187 | List arrParams = new ArrayList<>(); 188 | for (int j = 0; j < arrList.size(); j++) { 189 | input = ContractTypeUtil.parseByType( 190 | funcInputTypes.get(i).substring(0, funcInputTypes.get(i).indexOf("[")), 191 | arrList.get(j).toString()); 192 | arrParams.add(ContractTypeUtil.encodeString(input.toString(), inputType)); 193 | } 194 | finalInputs.add(new DynamicArray<>(arrParams)); 195 | } else { 196 | inputType = ContractTypeUtil.getType(funcInputTypes.get(i)); 197 | input = ContractTypeUtil.parseByType(funcInputTypes.get(i), 198 | params.get(i).toString()); 199 | finalInputs.add(ContractTypeUtil.encodeString(input.toString(), inputType)); 200 | } 201 | } 202 | return finalInputs; 203 | } 204 | 205 | /** 206 | * output parameter format. 207 | * 208 | * @param funOutputTypes list 209 | * @return 210 | */ 211 | public static List> outputFormat(List funOutputTypes) 212 | throws BaseException { 213 | List> finalOutputs = new ArrayList<>(); 214 | for (int i = 0; i < funOutputTypes.size(); i++) { 215 | Class outputType = null; 216 | TypeReference typeReference = null; 217 | if (funOutputTypes.get(i).contains("[") 218 | && funOutputTypes.get(i).contains("]")) { 219 | typeReference = ContractTypeUtil.getArrayType( 220 | funOutputTypes.get(i).substring(0, funOutputTypes.get(i).indexOf("["))); 221 | } else { 222 | outputType = ContractTypeUtil.getType(funOutputTypes.get(i)); 223 | typeReference = TypeReference.create(outputType); 224 | } 225 | finalOutputs.add(typeReference); 226 | } 227 | return finalOutputs; 228 | } 229 | 230 | /** 231 | * ethCall Result Parse. 232 | * 233 | * @param funOutputTypes list 234 | * @param typeList list 235 | * @return 236 | */ 237 | public static Object callResultParse(List funOutputTypes, List typeList) 238 | throws BaseException { 239 | if (funOutputTypes.size() == typeList.size()) { 240 | List result = new ArrayList<>(); 241 | for (int i = 0; i < funOutputTypes.size(); i++) { 242 | Class outputType = null; 243 | Object value = null; 244 | if (funOutputTypes.get(i).contains("[") 245 | && funOutputTypes.get(i).contains("]")) { 246 | List values = new ArrayList<>(); 247 | List results = (List) typeList.get(i).getValue(); 248 | for (int j = 0; j < results.size(); j++) { 249 | outputType = ContractTypeUtil.getType(funOutputTypes.get(i).substring(0, 250 | funOutputTypes.get(i).indexOf("["))); 251 | value = ContractTypeUtil.decodeResult(results.get(j), outputType); 252 | values.add(value); 253 | } 254 | result.add(values); 255 | } else { 256 | outputType = ContractTypeUtil.getType(funOutputTypes.get(i)); 257 | value = ContractTypeUtil.decodeResult(typeList.get(i), outputType); 258 | result.add(value); 259 | } 260 | } 261 | return JsonUtils.toJavaObject(JsonUtils.toJSONString(result), Object.class); 262 | } 263 | return null; 264 | } 265 | 266 | /** 267 | * receiptParse. 268 | * 269 | * @param receipt info 270 | * @param abiList info 271 | * @return 272 | */ 273 | public static Object receiptParse(TransactionReceipt receipt, List abiList) 274 | throws BaseException { 275 | Map resultMap = new HashMap<>(); 276 | List logList = receipt.getLogs(); 277 | for (AbiDefinition abiDefinition : abiList) { 278 | String eventName = abiDefinition.getName(); 279 | List funcInputTypes = getFuncInputType(abiDefinition); 280 | List> finalOutputs = outputFormat(funcInputTypes); 281 | Event event = new Event(eventName, finalOutputs); 282 | Object result = null; 283 | for (Log logInfo : logList) { 284 | EventValues eventValues = Contract.staticExtractEventParameters(event, logInfo); 285 | if (eventValues != null) { 286 | result = callResultParse(funcInputTypes, eventValues.getNonIndexedValues()); 287 | break; 288 | } 289 | } 290 | if (result != null) { 291 | resultMap.put(eventName, result); 292 | } 293 | } 294 | return resultMap; 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/util/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.webank.webase.transaction.util; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude.Include; 4 | import com.fasterxml.jackson.core.JsonParser.Feature; 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.core.type.TypeReference; 7 | import com.fasterxml.jackson.databind.DeserializationFeature; 8 | import com.fasterxml.jackson.databind.JavaType; 9 | import com.fasterxml.jackson.databind.JsonNode; 10 | import com.fasterxml.jackson.databind.ObjectMapper; 11 | import com.fasterxml.jackson.databind.SerializationFeature; 12 | import java.io.IOException; 13 | import java.text.SimpleDateFormat; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.apache.commons.lang3.StringUtils; 16 | 17 | import java.util.LinkedHashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | import java.util.function.Supplier; 21 | 22 | /** 23 | * Jackson Util 24 | * edit by marsli from hujkay 25 | */ 26 | @Slf4j 27 | public class JsonUtils { 28 | private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss"; 29 | /** 30 | * 设置一些通用的属性 31 | */ 32 | private static final ThreadLocal OBJECT_MAPPER = ThreadLocal.withInitial(() -> { 33 | ObjectMapper objectMapper = new ObjectMapper(); 34 | // 如果存在未知属性,则忽略不报错 35 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 36 | objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 37 | // 允许key没有双引号 38 | objectMapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 39 | // 允许key有单引号 40 | objectMapper.configure(Feature.ALLOW_SINGLE_QUOTES, true); 41 | // 属性值为null的不参与序列化 42 | // objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 43 | objectMapper.setSerializationInclusion(Include.ALWAYS); 44 | // timestamp 45 | objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 46 | // date format 47 | objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT)); 48 | return objectMapper; 49 | }); 50 | 51 | public static String toJSONString(Object obj) { 52 | return obj != null ? toJSONString(obj, () -> "") : ""; 53 | } 54 | 55 | public static String toJSONString(Object obj, Supplier defaultSupplier) { 56 | try { 57 | return obj != null ? OBJECT_MAPPER.get().writeValueAsString(obj) : defaultSupplier.get(); 58 | } catch (Throwable e) { 59 | log.error(String.format("toJSONString %s", obj != null ? obj.toString() : "null"), e); 60 | } 61 | return defaultSupplier.get(); 62 | } 63 | 64 | public static T toJavaObject(String value, Class tClass) { 65 | return StringUtils.isNotBlank(value) ? toJavaObject(value, tClass, () -> null) : null; 66 | } 67 | 68 | public static T toJavaObject(Object obj, Class tClass) { 69 | return obj != null ? toJavaObject(toJSONString(obj), tClass, () -> null) : null; 70 | } 71 | 72 | public static T toJavaObject(String value, Class tClass, Supplier defaultSupplier) { 73 | try { 74 | if (StringUtils.isBlank(value)) { 75 | return defaultSupplier.get(); 76 | } 77 | return OBJECT_MAPPER.get().readValue(value, tClass); 78 | } catch (Throwable e) { 79 | log.error(String.format("toJavaObject exception: \n %s\n %s", value, tClass), e); 80 | } 81 | return defaultSupplier.get(); 82 | } 83 | 84 | public static List toJavaObjectList(String value, Class tClass) { 85 | return StringUtils.isNotBlank(value) ? toJavaObjectList(value, tClass, () -> null) : null; 86 | } 87 | 88 | public static List toJavaObjectList(Object obj, Class tClass) { 89 | return obj != null ? toJavaObjectList(toJSONString(obj), tClass, () -> null) : null; 90 | } 91 | 92 | public static List toJavaObjectList(String value, Class tClass, Supplier> defaultSupplier) { 93 | try { 94 | if (StringUtils.isBlank(value)) { 95 | return defaultSupplier.get(); 96 | } 97 | JavaType javaType = OBJECT_MAPPER.get().getTypeFactory().constructParametricType(List.class, tClass); 98 | return OBJECT_MAPPER.get().readValue(value, javaType); 99 | } catch (Throwable e) { 100 | log.error(String.format("toJavaObjectList exception \n%s\n%s", value, tClass), e); 101 | } 102 | return defaultSupplier.get(); 103 | } 104 | 105 | // 简单地直接用json复制或者转换(Cloneable) 106 | public static T jsonCopy(Object obj, Class tClass) { 107 | return obj != null ? toJavaObject(toJSONString(obj), tClass) : null; 108 | } 109 | 110 | public static Map toMap(String value) { 111 | return StringUtils.isNotBlank(value) ? toMap(value, () -> null) : null; 112 | } 113 | 114 | public static Map toMap(Object value) { 115 | return value != null ? toMap(value, () -> null) : null; 116 | } 117 | 118 | public static Map toMap(Object value, Supplier> defaultSupplier) { 119 | if (value == null) { 120 | return defaultSupplier.get(); 121 | } 122 | try { 123 | if (value instanceof Map) { 124 | return (Map) value; 125 | } 126 | } catch (Exception e) { 127 | log.error("fail to convert" + toJSONString(value), e); 128 | } 129 | return toMap(toJSONString(value), defaultSupplier); 130 | } 131 | 132 | public static Map toMap(String value, Supplier> defaultSupplier) { 133 | if (StringUtils.isBlank(value)) { 134 | return defaultSupplier.get(); 135 | } 136 | try { 137 | return toJavaObject(value, LinkedHashMap.class); 138 | } catch (Exception e) { 139 | log.error(String.format("toMap exception\n%s", value), e); 140 | } 141 | return defaultSupplier.get(); 142 | } 143 | 144 | 145 | public static List toList(String value) { 146 | return StringUtils.isNotBlank(value) ? toList(value, () -> null) : null; 147 | } 148 | 149 | public static List toList(Object value) { 150 | return value != null ? toList(value, () -> null) : null; 151 | } 152 | 153 | public static List toList(String value, Supplier> defaultSuppler) { 154 | if (StringUtils.isBlank(value)) { 155 | return defaultSuppler.get(); 156 | } 157 | try { 158 | return toJavaObject(value, List.class); 159 | } catch (Exception e) { 160 | log.error("toList exception\n" + value, e); 161 | } 162 | return defaultSuppler.get(); 163 | } 164 | 165 | public static List toList(Object value, Supplier> defaultSuppler) { 166 | if (value == null) { 167 | return defaultSuppler.get(); 168 | } 169 | if (value instanceof List) { 170 | return (List) value; 171 | } 172 | return toList(toJSONString(value), defaultSuppler); 173 | } 174 | 175 | /* author: clk */ 176 | 177 | public static boolean isJson(String str) { 178 | try { 179 | OBJECT_MAPPER.get().readTree(str); 180 | return true; 181 | } catch (IOException e) { 182 | return false; 183 | } 184 | } 185 | 186 | public static JsonNode stringToJsonNode(String str) { 187 | try { 188 | return OBJECT_MAPPER.get().readTree(str); 189 | } catch (IOException e) { 190 | log.error("Parse String to JsonNode error : {}", e.getMessage()); 191 | return null; 192 | } 193 | } 194 | 195 | public static String objToString(T obj) { 196 | if (obj == null) { 197 | return null; 198 | } 199 | try { 200 | return obj instanceof String ? (String) obj 201 | : OBJECT_MAPPER.get().writerWithDefaultPrettyPrinter().writeValueAsString(obj); 202 | } catch (JsonProcessingException e) { 203 | log.error("Parse Object to String error : {}", e.getMessage()); 204 | return null; 205 | } 206 | } 207 | 208 | @SuppressWarnings("unchecked") 209 | public static T stringToObj(String str, Class clazz) { 210 | if (StringUtils.isEmpty(str) || clazz == null) { 211 | return null; 212 | } 213 | try { 214 | return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.get().readValue(str, clazz); 215 | } catch (Exception e) { 216 | log.error("Parse String to Object error : {}", e.getMessage()); 217 | return null; 218 | } 219 | } 220 | 221 | @SuppressWarnings("unchecked") 222 | public static T stringToObj(String str, TypeReference typeReference) { 223 | if (StringUtils.isEmpty(str) || typeReference == null) { 224 | return null; 225 | } 226 | try { 227 | return (T) (typeReference.getType().equals(String.class) ? str 228 | : OBJECT_MAPPER.get().readValue(str, typeReference)); 229 | } catch (IOException e) { 230 | log.error("Parse String to Object error", e); 231 | return null; 232 | } 233 | } 234 | 235 | public static T stringToObj(String str, Class collectionClazz, 236 | Class... elementClazzes) { 237 | JavaType javaType = OBJECT_MAPPER.get().getTypeFactory() 238 | .constructParametricType(collectionClazz, elementClazzes); 239 | try { 240 | return OBJECT_MAPPER.get().readValue(str, javaType); 241 | } catch (IOException e) { 242 | log.error("Parse String to Object error : {}" + e.getMessage()); 243 | return null; 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/util/LogUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.util; 16 | 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | /** 21 | * LogUtils. 22 | */ 23 | public class LogUtils { 24 | 25 | private static final Logger MONITORBUSINESS = LoggerFactory.getLogger("monitorBusiness"); 26 | 27 | private static final Logger MONITORABNORMAL = LoggerFactory.getLogger("monitorAbnormal"); 28 | 29 | public static Logger monitorBusinessLogger() { 30 | return MONITORBUSINESS; 31 | } 32 | 33 | public static Logger monitorAbnormalLogger() { 34 | return MONITORABNORMAL; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/webank/webase/transaction/version/VersionController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2020 the original author or authors. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | *

7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | *

9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.webank.webase.transaction.version; 16 | 17 | import com.webank.webase.transaction.base.VersionProperties; 18 | import io.swagger.annotations.Api; 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.web.bind.annotation.GetMapping; 22 | import org.springframework.web.bind.annotation.RequestMapping; 23 | import org.springframework.web.bind.annotation.RestController; 24 | 25 | /** 26 | * return version of local server 27 | */ 28 | @Api(value = "/version", tags = "server version") 29 | @Slf4j 30 | @RestController 31 | @RequestMapping("version") 32 | public class VersionController { 33 | 34 | @Autowired 35 | private VersionProperties versionProperties; 36 | 37 | /** 38 | * return version 39 | * @return 40 | */ 41 | @GetMapping() 42 | public String getServerVersion() { 43 | return versionProperties.getVersion(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ################################### Basic Configuration ################################### 2 | # 后台服务的版本 3 | version=v1.4.0 4 | # 工程服务端口,端口被占用则修改 5 | server.port=5003 6 | server.context-path=/WeBASE-Transaction 7 | mybatis.mapper-locations=classpath:mapper/*.xml 8 | logging.config=classpath:log4j2.xml 9 | 10 | ################################### web3sdk Configuration ################################### 11 | # 机构名 12 | sdk.orgName=webank 13 | sdk.timeout=10000 14 | # 线程池配置 15 | sdk.corePoolSize=100 16 | sdk.maxPoolSize=500 17 | sdk.queueCapacity=500 18 | sdk.keepAlive=60 19 | # 群组信息,可配置多群组和多节点 20 | # 群组id(下同) 21 | sdk.groupConfig.allChannelConnections[0].groupId=1 22 | # 连接节点的ip和channelPort(下同) 23 | sdk.groupConfig.allChannelConnections[0].connectionsStr[0]=127.0.0.1:20200 24 | sdk.groupConfig.allChannelConnections[0].connectionsStr[1]=127.0.0.1:20201 25 | sdk.groupConfig.allChannelConnections[1].groupId=2 26 | sdk.groupConfig.allChannelConnections[1].connectionsStr[0]=127.0.0.1:20200 27 | sdk.groupConfig.allChannelConnections[1].connectionsStr[1]=127.0.0.1:20201 28 | # 切换非国密与国密 0: standard, 1: guomi 29 | sdk.encryptType=0 30 | ################################### constant Configuration ################################### 31 | # WeBASE-Sign签名服务ip端口,使用本签名方式(signType=2)则对应修改 32 | constant.signServer=127.0.0.1:5004 33 | # 本地配置私钥进行签名,使用本签名方式(signType=0)则对应修改 34 | constant.privateKey=edf02a4a69b14ee6b1650a95de71d5f50496ef62ae4213026bd8d6651d030995 35 | constant.cronTrans=0/1 * * * * ? 36 | constant.requestCountMax=6 37 | constant.selectCount=10 38 | constant.intervalTime=600 39 | constant.sleepTime=50 40 | # 是否删除数据 41 | constant.ifDeleteData=false 42 | constant.cronDeleteData=0 0 1 * * ? 43 | constant.keepDays=360 44 | # 使用分布式任务部署多活(true-是,false-否) 45 | constant.ifDistributedTask=false 46 | 47 | ################################### elastic-job 分布式任务 ################################### 48 | # 部署多活的话需配置zookeeper,支持集群 49 | job.regCenter.serverLists=127.0.0.1:2181 50 | # zookeeper命名空间 51 | job.regCenter.namespace=elasticjob-transaction 52 | # 分片数(如多活3个的话可分成3片) 53 | job.dataflow.shardingTotalCount=3 54 | 55 | ################################### 数据源配置 ################################### 56 | # * 说明:本工程使用Sharding-JDBC分库分表,支持单一数据源,也支持多库多表。 57 | # * 单库单表:配置单个数据源,将分库策略和分表策略注释或删除 58 | # * 多库多表:配置多数据源,以群组分库,以年份分表,用户自定义每年分成几个表(注:分表策略的路由字段不可修改[id,gmt_create]) 59 | # * 样例:以两个数据源为例(数据库需事先创建),每张表根据年分表,每年再分成两个子表,以2020和2021年的表为例 60 | 61 | # 配置所有的数据源,如此处定义了ds0,ds1两个数据源,对应两个库 62 | sharding.jdbc.datasource.names=ds0,ds1 63 | 64 | # 定义数据源ds0,配置数据库连接信息 65 | sharding.jdbc.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource 66 | sharding.jdbc.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver 67 | sharding.jdbc.datasource.ds0.url=jdbc:mysql://127.0.0.1:3306/webasetransaction0?autoReconnect=true&useSSL=false&serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=UTF-8 68 | sharding.jdbc.datasource.ds0.username=dbUsername 69 | sharding.jdbc.datasource.ds0.password=dbPassword 70 | 71 | # 定义数据源ds1,配置数据库连接信息 72 | sharding.jdbc.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource 73 | sharding.jdbc.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver 74 | sharding.jdbc.datasource.ds1.url=jdbc:mysql://127.0.0.1:3306/webasetransaction1?autoReconnect=true&useSSL=false&serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=UTF-8 75 | sharding.jdbc.datasource.ds1.username=dbUsername 76 | sharding.jdbc.datasource.ds1.password=dbPassword 77 | 78 | # 定义数据库分片策略,如此处以群组id取模2来路由到ds0或ds1 79 | sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=group_id 80 | sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds$->{group_id % 2} 81 | 82 | # 定义tb_deploy_transaction的分表策略,如此处以创建时间的年份和自增id取模2来路由到子表 83 | sharding.jdbc.config.sharding.tables.tb_deploy_transaction.actual-data-nodes=ds$->{0..1}.tb_deploy_transaction_$->{2020..2021}_$->{0..1} 84 | sharding.jdbc.config.sharding.tables.tb_deploy_transaction.table-strategy.complex.sharding-columns=id,gmt_create 85 | sharding.jdbc.config.sharding.tables.tb_deploy_transaction.table-strategy.complex.algorithm-class-name=com.webank.webase.transaction.config.MyComplexShardingAlgorithm 86 | sharding.jdbc.config.sharding.tables.tb_deploy_transaction.key-generator-column-name=id 87 | 88 | # 定义tb_stateless_transaction的分表策略,如此处以创建时间的年份和自增id取模2来路由到子表 89 | sharding.jdbc.config.sharding.tables.tb_stateless_transaction.actual-data-nodes=ds$->{0..1}.tb_stateless_transaction_$->{2023..2027}_$->{0..1} 90 | sharding.jdbc.config.sharding.tables.tb_stateless_transaction.table-strategy.complex.sharding-columns=id,gmt_create 91 | sharding.jdbc.config.sharding.tables.tb_stateless_transaction.table-strategy.complex.algorithm-class-name=com.webank.webase.transaction.config.MyComplexShardingAlgorithm 92 | sharding.jdbc.config.sharding.tables.tb_stateless_transaction.key-generator-column-name=id 93 | 94 | sharding.jdbc.config.props.sql.show=false 95 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ./log 5 | 6 | 7 | 8 | 10 | 11 | 12 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /src/main/resources/mapper/ContractMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | CREATE TABLE IF NOT EXISTS tb_deploy_transaction ( 7 | id bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增编号', 8 | group_id int(11) NOT NULL COMMENT '群组编号', 9 | uuid_deploy varchar(64) NOT NULL COMMENT '部署交易业务流水号', 10 | contract_bin mediumtext NOT NULL COMMENT '合约bin', 11 | contract_abi mediumtext NOT NULL COMMENT '合约abi', 12 | contract_address varchar(64) COMMENT '合约地址', 13 | func_param text COMMENT '构造方法的入参json', 14 | sign_type tinyint(4) DEFAULT '0' COMMENT '签名 类型(0-本地配置私钥,1-本地随机私钥,2-调用签名服务)', 15 | sign_user_id varchar(64) COMMENT '调用签名服务的用户uuid编号', 16 | request_count tinyint(4) DEFAULT '0' COMMENT '请求次数', 17 | handle_status tinyint(4) DEFAULT '0' COMMENT '处理状态(0-待处理,1-处理成功)', 18 | trans_hash varchar(128) COMMENT '交易hash值', 19 | receipt_status tinyint(1) DEFAULT NULL COMMENT '交易回执状态(0-异常,1-正常)', 20 | gmt_create timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 21 | gmt_modify datetime NOT NULL COMMENT '修改时间', 22 | PRIMARY KEY (id), 23 | KEY idx_gu (group_id,uuid_deploy), 24 | KEY idx_hs (handle_status), 25 | KEY idx_gc (gmt_create) 26 | ) COMMENT='部署交易信息表' ENGINE=InnoDB CHARSET=utf8; 27 | 28 | 29 | 30 | id, 31 | group_id as groupId, 32 | contract_abi as contractAbi, 33 | contract_bin as contractBin, 34 | contract_address as contractAddress, 35 | func_param as funcParam, 36 | request_count as requestCount, 37 | sign_type as signType, 38 | sign_user_id as signUserId, 39 | gmt_create as gmtCreate 40 | 41 | 42 | 43 | id, 44 | group_id as groupId, 45 | uuid_deploy as uuidDeploy, 46 | contract_bin as contractBin, 47 | contract_abi as contractAbi, 48 | contract_address as contractAddress, 49 | func_param as funcParam, 50 | sign_type as signType, 51 | sign_user_id as signUserId, 52 | request_count as requestCount, 53 | handle_status as handleStatus, 54 | trans_hash as transHash, 55 | receipt_status as receiptStatus, 56 | gmt_create as gmtCreate 57 | 58 | 59 | 60 | insert into tb_deploy_transaction( 61 | `group_id`, 62 | `uuid_deploy`, 63 | `contract_bin`, 64 | `contract_abi`, 65 | `func_param`, 66 | `sign_type`, 67 | `sign_user_id`, 68 | `gmt_create`, 69 | `gmt_modify` 70 | ) values ( 71 | #{groupId}, 72 | #{uuidDeploy}, 73 | #{contractBin}, 74 | #{contractAbi}, 75 | #{funcParam}, 76 | #{signType}, 77 | #{signUserId}, 78 | #{gmtCreate}, 79 | DATE_SUB(NOW(),INTERVAL 1 DAY) 80 | ) 81 | 82 | 83 | 90 | 91 | 97 | 98 | 104 | 105 | 111 | 112 | 118 | 119 | 129 | 130 | 141 | 142 | 143 | update tb_deploy_transaction 144 | set request_count=#{requestCount}, 145 | gmt_modify=NOW() 146 | where id = #{id} 147 | and gmt_create = #{gmtCreate} 148 | 149 | 150 | 151 | update tb_deploy_transaction 152 | set contract_address = #{contractAddress}, 153 | trans_hash = #{transHash}, 154 | receipt_status = #{receiptStatus}, 155 | handle_status = #{handleStatus}, 156 | gmt_modify = NOW() 157 | where id = #{id} 158 | and gmt_create = #{gmtCreate} 159 | 160 | 161 | 162 | delete from tb_deploy_transaction 163 | = #{keepDays} 165 | ]]> 166 | 167 | -------------------------------------------------------------------------------- /src/main/resources/mapper/StatelessTransMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | CREATE TABLE IF NOT EXISTS tb_stateless_transaction ( 7 | id bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增编号', 8 | group_id int(11) NOT NULL COMMENT '群组编号', 9 | uuid_stateless varchar(64) NOT NULL COMMENT '合约无状态交易业务流水号', 10 | uuid_deploy varchar(64) COMMENT '部署交易业务流水号', 11 | contract_abi mediumtext NOT NULL COMMENT '合约abi', 12 | contract_address varchar(64) NOT NULL COMMENT '合约地址', 13 | func_name varchar(32) NOT NULL COMMENT '调用的合约方法名', 14 | func_param text COMMENT '合约方法的入参json', 15 | sign_type tinyint(4) DEFAULT '0' COMMENT '签名 类型(0-本地配置私钥,1-本地随机私钥,2-调用签名服务)', 16 | sign_user_id varchar(64) COMMENT '调用签名服务的用户编号', 17 | request_count tinyint(4) DEFAULT '0' COMMENT '请求次数', 18 | handle_status tinyint(4) DEFAULT '0' COMMENT '处理状态(0-待处理,1-处理成功)', 19 | trans_hash varchar(128) COMMENT '交易hash值', 20 | trans_output text COMMENT '交易返回值', 21 | receipt_status tinyint(1) DEFAULT NULL COMMENT '交易回执状态(0-异常,1-正常)', 22 | gmt_create timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 23 | gmt_modify datetime NOT NULL COMMENT '修改时间', 24 | PRIMARY KEY (id), 25 | KEY idx_gu (group_id,uuid_stateless), 26 | KEY idx_hs (handle_status), 27 | KEY idx_gc (gmt_create) 28 | ) COMMENT='合约无状态交易请求信息表' ENGINE=InnoDB CHARSET=utf8; 29 | 30 | 31 | 32 | id, 33 | group_id as groupId, 34 | contract_abi as contractAbi, 35 | contract_address as contractAddress, 36 | func_name as funcName, 37 | func_param as funcParam, 38 | request_count as requestCount, 39 | sign_type as signType, 40 | sign_user_id as signUserId, 41 | gmt_create as gmtCreate 42 | 43 | 44 | 45 | id, 46 | group_id as groupId, 47 | uuid_stateless as uuidStateless, 48 | uuid_deploy as uuidDeploy, 49 | contract_abi as contractAbi, 50 | contract_address as contractAddress, 51 | func_name as funcName, 52 | func_param as funcParam, 53 | sign_type as signType, 54 | sign_user_id as signUserId, 55 | request_count as requestCount, 56 | handle_status as handleStatus, 57 | trans_hash as transHash, 58 | trans_output as transOutput, 59 | receipt_status as receiptStatus, 60 | gmt_create as gmtCreate 61 | 62 | 63 | 64 | insert into tb_stateless_transaction( 65 | `group_id`, 66 | `uuid_stateless`, 67 | `uuid_deploy`, 68 | `contract_address`, 69 | `contract_abi`, 70 | `func_name`, 71 | `func_param`, 72 | `sign_type`, 73 | `sign_user_id`, 74 | `gmt_create`, 75 | `gmt_modify` 76 | ) values ( 77 | #{groupId}, 78 | #{uuidStateless}, 79 | #{uuidDeploy}, 80 | #{contractAddress}, 81 | #{contractAbi}, 82 | #{funcName}, 83 | #{funcParam}, 84 | #{signType}, 85 | #{signUserId}, 86 | #{gmtCreate}, 87 | DATE_SUB(NOW(),INTERVAL 1 DAY) 88 | ) 89 | 90 | 91 | 98 | 99 | 105 | 106 | 116 | 117 | 128 | 129 | 130 | update tb_stateless_transaction 131 | set request_count=#{requestCount}, 132 | gmt_modify=NOW() 133 | where id = #{id} 134 | and gmt_create = #{gmtCreate} 135 | 136 | 137 | 138 | update tb_stateless_transaction 139 | set trans_hash = #{transHash}, 140 | trans_output = #{transOutput}, 141 | receipt_status = #{receiptStatus}, 142 | handle_status = #{handleStatus}, 143 | gmt_modify = NOW() 144 | where id = #{id} 145 | and gmt_create = #{gmtCreate} 146 | 147 | 148 | 149 | DELETE FROM tb_stateless_transaction 150 | = #{keepDays} 152 | ]]> 153 | 154 | -------------------------------------------------------------------------------- /src/main/resources/swagger/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeBASE-Transaction/38ea7176d3a6d95e517888a1f3b9e36f7f88621f/src/main/resources/swagger/favicon-16x16.png -------------------------------------------------------------------------------- /src/main/resources/swagger/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeBASE-Transaction/38ea7176d3a6d95e517888a1f3b9e36f7f88621f/src/main/resources/swagger/favicon-32x32.png -------------------------------------------------------------------------------- /src/main/resources/swagger/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 31 | 32 | 33 | 34 |

35 | 36 | 37 | 38 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/resources/swagger/swagger-ui.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""} -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | APP_MAIN=com.webank.webase.transaction.Application 4 | CLASSPATH='conf/:apps/*:lib/*' 5 | CURRENT_DIR=`pwd` 6 | LOG_DIR=${CURRENT_DIR}/log 7 | CONF_DIR=${CURRENT_DIR}/conf 8 | 9 | SERVER_PORT=$(cat $CONF_DIR/application.properties| grep "server.port" | awk -F'=' '{print $2}'| sed 's/\r//') 10 | if [ ${SERVER_PORT}"" = "" ];then 11 | echo "$CONF_DIR/application.properties server port has not been configured" 12 | exit -1 13 | fi 14 | 15 | if [ ${JAVA_HOME}"" = "" ];then 16 | echo "JAVA_HOME has not been configured" 17 | exit -1 18 | fi 19 | 20 | mkdir -p log 21 | 22 | startWaitTime=30 23 | processPid=0 24 | processStatus=0 25 | checkProcess(){ 26 | server_pid=`ps aux | grep java | grep $CURRENT_DIR | grep $APP_MAIN | awk '{print $2}'` 27 | if [ -n "$server_pid" ]; then 28 | processPid=$server_pid 29 | processStatus=1 30 | else 31 | processPid=0 32 | processStatus=0 33 | fi 34 | } 35 | 36 | JAVA_OPTS=" -Dfile.encoding=UTF-8" 37 | JAVA_OPTS+=" -Xmx256m -Xms256m -Xmn128m -Xss512k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m" 38 | JAVA_OPTS+=" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_DIR}/heap_error.log" 39 | 40 | start(){ 41 | checkProcess 42 | echo "===============================================================================================" 43 | if [ $processStatus == 1 ]; then 44 | echo "Server $APP_MAIN Port $SERVER_PORT is running PID($processPid)" 45 | echo "===============================================================================================" 46 | else 47 | echo -n "Server $APP_MAIN Port $SERVER_PORT ..." 48 | nohup $JAVA_HOME/bin/java -Djdk.tls.namedGroups="secp256k1" $JAVA_OPTS -cp $CLASSPATH $APP_MAIN >> $LOG_DIR/transaction.out 2>&1 & 49 | 50 | count=1 51 | result=0 52 | while [ $count -lt $startWaitTime ] ; do 53 | checkProcess 54 | if [ $processPid -ne 0 ]; then 55 | result=1 56 | break 57 | fi 58 | let count++ 59 | echo -n "." 60 | sleep 1 61 | done 62 | 63 | if [ $result -ne 0 ]; then 64 | echo "PID($processPid) [Starting]. Please check message through the log file (default path:./log/)." 65 | echo "===============================================================================================" 66 | else 67 | echo "[Failed]. Please check message through the log file (default path:./log/)." 68 | echo "===============================================================================================" 69 | fi 70 | fi 71 | } 72 | 73 | start 74 | -------------------------------------------------------------------------------- /status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | APP_MAIN=com.webank.webase.transaction.Application 4 | CURRENT_DIR=`pwd` 5 | CONF_DIR=${CURRENT_DIR}/conf 6 | 7 | SERVER_PORT=$(cat $CONF_DIR/application.properties| grep "server.port" | awk -F'=' '{print $2}'| sed 's/\r//') 8 | if [ ${SERVER_PORT}"" = "" ];then 9 | echo "$CONF_DIR/application.properties server port has not been configured" 10 | exit -1 11 | fi 12 | 13 | processPid=0 14 | checkProcess(){ 15 | server_pid=`ps aux | grep java | grep $CURRENT_DIR | grep $APP_MAIN | awk '{print $2}'` 16 | if [ -n "$server_pid" ]; then 17 | processPid=$server_pid 18 | else 19 | processPid=0 20 | fi 21 | } 22 | 23 | status(){ 24 | checkProcess 25 | echo "===============================================================================================" 26 | if [ $processPid -ne 0 ]; then 27 | echo "Server $APP_MAIN Port $SERVER_PORT is running PID($processPid)" 28 | echo "===============================================================================================" 29 | else 30 | echo "Server $APP_MAIN Port $SERVER_PORT is not running" 31 | echo "===============================================================================================" 32 | fi 33 | } 34 | 35 | status 36 | -------------------------------------------------------------------------------- /stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | APP_MAIN=com.webank.webase.transaction.Application 4 | CURRENT_DIR=`pwd` 5 | CONF_DIR=${CURRENT_DIR}/conf 6 | 7 | SERVER_PORT=$(cat $CONF_DIR/application.properties| grep "server.port" | awk -F'=' '{print $2}'| sed 's/\r//') 8 | if [ ${SERVER_PORT}"" = "" ];then 9 | echo "$CONF_DIR/application.properties server port has not been configured" 10 | exit -1 11 | fi 12 | 13 | processPid=0 14 | checkProcess(){ 15 | server_pid=`ps aux | grep java | grep $CURRENT_DIR | grep $APP_MAIN | awk '{print $2}'` 16 | if [ -n "$server_pid" ]; then 17 | processPid=$server_pid 18 | else 19 | processPid=0 20 | fi 21 | } 22 | 23 | stop(){ 24 | checkProcess 25 | echo "===============================================================================================" 26 | if [ $processPid -ne 0 ]; then 27 | echo -n "Stopping Server $APP_MAIN Port $SERVER_PORT PID($processPid)..." 28 | kill -9 $processPid 29 | if [ $? -eq 0 ]; then 30 | echo "[Success]" 31 | echo "===============================================================================================" 32 | else 33 | echo "[Failed]" 34 | echo "===============================================================================================" 35 | fi 36 | else 37 | echo "Server $APP_MAIN Port $SERVER_PORT is not running" 38 | echo "===============================================================================================" 39 | fi 40 | } 41 | 42 | stop --------------------------------------------------------------------------------