├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main └── java └── com └── develop └── wallet ├── BuildConfig.java ├── SimpleWalletListener.java ├── Test.java ├── Wallet.java ├── WalletListener.java ├── WalletManager.java └── eos ├── Rpc.java ├── api ├── RpcService.java ├── exception │ ├── ApiError.java │ ├── ApiException.java │ ├── Error.java │ └── ErrorDetails.java └── http │ └── Generator.java ├── crypto ├── Curve.java ├── FieldElement.java ├── Point.java ├── Secp256k.java ├── digest │ ├── GeneralDigest.java │ ├── Ripemd160.java │ └── Sha.java └── utils │ ├── Base58.java │ ├── ByteBuffer.java │ └── ByteUtils.java ├── model ├── BaseVo.java ├── Block.java ├── ChainInfo.java ├── JsonToBin.java ├── JsonToBinReq.java ├── SignParam.java ├── TableRows.java ├── TableRowsReq.java ├── Transfer.java ├── UpTransfer.java ├── account │ ├── Account.java │ ├── CpuLimit.java │ ├── Key.java │ ├── NetLimit.java │ ├── Permission.java │ └── RequiredAuth.java └── transaction │ ├── Processed.java │ ├── Receipt.java │ ├── Transaction.java │ └── push │ ├── BaseTx.java │ ├── FieldAnnotation.java │ ├── Tx.java │ ├── TxAction.java │ ├── TxActionAuth.java │ ├── TxExtenstions.java │ ├── TxRequest.java │ └── TxSign.java └── utils ├── EException.java ├── EccTool.java ├── Ecdsa.java ├── EosUtils.java ├── Hex.java ├── ObjectUtils.java └── ese ├── Action.java ├── DataParam.java ├── DataType.java └── Ese.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /.gradle 25 | /.idea 26 | /out 27 | /build 28 | /local.properties 29 | *.iml 30 | -------------------------------------------------------------------------------- /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 | # wallet-eos 2 | wallet-eos EOS钱包 助记词 私钥 转账 3 | 4 | ## 生成助记词 私钥 公钥 5 | ``` Java 6 | // 生成助记词 7 | String mnemonic = MnemonicUtils.generateMnemonic(); 8 | System.out.println("mnemonic:"+ mnemonic); 9 | 10 | // 生成种子 11 | byte[] seed = MnemonicUtils.generateSeed(mnemonic, ""); 12 | System.out.println("seed:"+ Numeric.toHexString(seed)); 13 | 14 | // bip44 bip32 私钥 15 | byte[] privateKeyBytes = KeyPairUtils.generatePrivateKey(seed, KeyPairUtils.CoinTypes.EOS); 16 | System.out.println("privateKeyBytes:"+ Numeric.toHexString(privateKeyBytes)); 17 | 18 | // 生成EOS私钥 19 | String pk = EccTool.privateKeyFromSeed(privateKeyBytes); 20 | System.out.println("private key :" + pk); 21 | 22 | // 生成EOS公钥 23 | String pu = EccTool.privateToPublic(pk); 24 | System.out.println("public key :" + pu); 25 | 26 | ``` 27 | 28 | mnemonic:unfair raccoon electric valve session fish catch near industry increase pipe nominee
29 | seed:0xb1c8816b33c7a42afe2f41bbe83d197962eb31de1cbc8ce647c64bf30a803dda859207d2a0cc098229f7874692dee7e3a82af3cfc6b2fe9ec2af32291183cd73
30 | privateKeyBytes:0xc41e9c899be9e822e918b0206709c24f56ae174a6244676eb71c024cd4a0ad2a
31 | private key :5JQ5H8ktrPeHyGU4gmEDUTK7jM8Te2QXc4J1NzeQk6ZinASQvCT
32 | public key :EOS8EzuaoP3kELe2WorLyMwKRD3KNypJzGomXTjg6dB1tGEGitgKt
33 | 34 | 35 | ``` Java 36 | String accountA = "a1111111111a", accountB = "a1111111111b"; 37 | String privateKeyA = "5JVubbh5s6RP5zunU8TVEdhQKBTY4BNkbsxP2abbjCQi4HqpUvG", privateKeyB = "5JbZ4RyKGqNNrhRzyDVjRdERbjZMJfe1XTnsLqqB1hXZCLH5Mgd"; 38 | 39 | // 随机生成EOS账号 40 | String account = EosUtils.generateAccount(); 41 | System.out.println("account :" + account + ", eos = " + EosUtils.isEosAccount(account)); 42 | 43 | // 查询系统代币总额 44 | WalletManager.querySupplys(); 45 | 46 | // 生成EOS账号(随机) 47 | WalletManager.generateWalletAddress(); 48 | 49 | // 生成EOS账号 50 | WalletManager.generateWalletAddress("a1111111111b"); 51 | 52 | // 查询账号 53 | WalletManager.queryAccount(accountA); 54 | 55 | WalletManager.queryAccount(accountB); 56 | 57 | // 转账 58 | WalletManager.transfer(accountA, privateKeyA, accountB, "1.0000 SYS", "xxx"); 59 | 60 | WalletManager.up(accountA, privateKeyA, accountB, "1.0000 SYS"); 61 | ``` -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | group 'com.lgann.develop' 6 | version '1.0.0' 7 | 8 | compileJava { 9 | sourceCompatibility = '1.8' 10 | targetCompatibility = '1.8' 11 | } 12 | 13 | repositories { 14 | jcenter() 15 | mavenCentral() 16 | } 17 | 18 | 19 | dependencies { 20 | testCompile 'junit:junit:4.12' 21 | compile 'com.lgann.develop:mnemonic-sdk:1.0.0' 22 | 23 | compile 'com.squareup.retrofit2:converter-jackson:2.0.2' 24 | compile 'com.squareup.retrofit2:retrofit:2.0.2' 25 | compile 'com.squareup.okhttp3:logging-interceptor:3.1.2' 26 | 27 | compile 'org.bouncycastle:bcprov-jdk15on:1.59' 28 | } 29 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Oct 09 16:06:36 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'wallet-eos' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/BuildConfig.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | public class BuildConfig { 4 | public static final boolean DEBUG = true; 5 | // Fields from build type: debug 6 | public static final String EOS_CREATOR_ACCOUNT = "eosio.token"; 7 | public static final String EOS_CREATOR_PRIVATE_KEY = "5K1WUspYE58mmbz4rTtdto8NRVoTXePCqR69muiA5u7pqfkShBi"; 8 | public static final String EOS_URL = "http://192.168.1.138"; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/SimpleWalletListener.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | /** 4 | * @author Angus 5 | */ 6 | public class SimpleWalletListener implements WalletListener { 7 | @Override 8 | public void onSendTransaction(String hash) { 9 | 10 | } 11 | 12 | @Override 13 | public void onQueryTokenBalance(String balance) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/Test.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | import com.develop.mnemonic.KeyPairUtils; 4 | import com.develop.mnemonic.MnemonicUtils; 5 | import com.develop.mnemonic.utils.Numeric; 6 | import com.develop.wallet.eos.utils.EccTool; 7 | import com.develop.wallet.eos.utils.EosUtils; 8 | 9 | /** 10 | * @author Angus 11 | */ 12 | public class Test { 13 | 14 | public static final void main(String[] args) { 15 | 16 | // 生成助记词 17 | String mnemonic = MnemonicUtils.generateMnemonic(); 18 | System.out.println("mnemonic:" + mnemonic); 19 | 20 | // 生成种子 21 | byte[] seed = MnemonicUtils.generateSeed(mnemonic, ""); 22 | System.out.println("seed:" + Numeric.toHexString(seed)); 23 | 24 | // bip44 bip32 私钥 25 | byte[] privateKeyBytes = KeyPairUtils.generatePrivateKey(seed, KeyPairUtils.CoinTypes.EOS); 26 | System.out.println("privateKeyBytes:" + Numeric.toHexString(privateKeyBytes)); 27 | 28 | // 生成EOS私钥 29 | String pk = EccTool.privateKeyFromSeed(privateKeyBytes); 30 | System.out.println("private key :" + pk); 31 | 32 | // 生成EOS公钥 33 | String pu = EccTool.privateToPublic(pk); 34 | System.out.println("public key :" + pu); 35 | 36 | ///////////////////////////////////////////////////////////////////// 37 | String accountA = "a1111111111a", accountB = "a1111111111b"; 38 | String privateKeyA = "5JVubbh5s6RP5zunU8TVEdhQKBTY4BNkbsxP2abbjCQi4HqpUvG", privateKeyB = "5JbZ4RyKGqNNrhRzyDVjRdERbjZMJfe1XTnsLqqB1hXZCLH5Mgd"; 39 | 40 | // 随机生成EOS账号 41 | String account = EosUtils.generateAccount(); 42 | System.out.println("account :" + account + ", eos = " + EosUtils.isEosAccount(account)); 43 | 44 | // 查询系统代币总额 45 | WalletManager.querySupplys(); 46 | 47 | // 生成EOS账号(随机) 48 | WalletManager.generateWalletAddress(); 49 | 50 | // 生成EOS账号 51 | WalletManager.generateWalletAddress("a1111111111b"); 52 | 53 | // 查询账号 54 | WalletManager.queryAccount(accountA); 55 | 56 | WalletManager.queryAccount(accountB); 57 | 58 | // 转账 59 | WalletManager.transfer(accountA, privateKeyA, accountB, "1.0000 SYS", "xxx"); 60 | 61 | WalletManager.up(accountA, privateKeyA, accountB, "1.0000 SYS"); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/Wallet.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | /** 4 | * @author Angus 5 | */ 6 | public class Wallet { 7 | private String mnemonic; 8 | private String address; 9 | private String privateKey; 10 | private String publicKey; 11 | private String keystore; 12 | 13 | public Wallet(String mnemonic, String address) { 14 | this.mnemonic = mnemonic; 15 | this.address = address; 16 | } 17 | 18 | public Wallet(String mnemonic, String address, String privateKey, String publicKey) { 19 | this.mnemonic = mnemonic; 20 | this.address = address; 21 | this.privateKey = privateKey; 22 | this.publicKey = publicKey; 23 | } 24 | 25 | public Wallet(String mnemonic, String address, String privateKey, String publicKey, String keystore) { 26 | this(mnemonic, address, privateKey, publicKey); 27 | this.keystore = keystore; 28 | } 29 | 30 | public String getMnemonic() { 31 | return mnemonic; 32 | } 33 | 34 | public void setMnemonic(String mnemonic) { 35 | this.mnemonic = mnemonic; 36 | } 37 | 38 | public String getAddress() { 39 | return address; 40 | } 41 | 42 | public void setAddress(String address) { 43 | this.address = address; 44 | } 45 | 46 | public String getPrivateKey() { 47 | return privateKey; 48 | } 49 | 50 | public void setPrivateKey(String privateKey) { 51 | this.privateKey = privateKey; 52 | } 53 | 54 | public String getPublicKey() { 55 | return publicKey; 56 | } 57 | 58 | public void setPublicKey(String publicKey) { 59 | this.publicKey = publicKey; 60 | } 61 | 62 | public String getKeystore() { 63 | return keystore; 64 | } 65 | 66 | public void setKeystore(String keystore) { 67 | this.keystore = keystore; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/WalletListener.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | /** 4 | * @author Angus 5 | */ 6 | public interface WalletListener { 7 | /** 8 | * 转账 9 | * 10 | * @param hash 11 | */ 12 | void onSendTransaction(String hash); 13 | 14 | /** 15 | * 余额 16 | * 17 | * @param balance 18 | */ 19 | void onQueryTokenBalance(String balance); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/WalletManager.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet; 2 | 3 | import com.develop.mnemonic.KeyPairUtils; 4 | import com.develop.mnemonic.MnemonicUtils; 5 | import com.develop.wallet.eos.Rpc; 6 | import com.develop.wallet.eos.api.exception.ApiException; 7 | import com.develop.wallet.eos.model.TableRows; 8 | import com.develop.wallet.eos.model.TableRowsReq; 9 | import com.develop.wallet.eos.model.transaction.Transaction; 10 | import com.develop.wallet.eos.utils.EccTool; 11 | import com.develop.wallet.eos.utils.EosUtils; 12 | 13 | 14 | /** 15 | * @author Angus 16 | */ 17 | public class WalletManager { 18 | public static boolean DEBUG = BuildConfig.DEBUG; 19 | 20 | /** 21 | * 区块链服务器地址 22 | */ 23 | public static String URL = BuildConfig.EOS_URL; 24 | 25 | private static Rpc rpc; 26 | 27 | public static Rpc getRpc() { 28 | if (rpc == null) { 29 | rpc = new Rpc(URL); 30 | } 31 | return rpc; 32 | } 33 | 34 | /** 35 | * 生成账号,随机生成 36 | */ 37 | public static Wallet generateWalletAddress() { 38 | String account = EosUtils.generateAccount(); 39 | log("random generate account : " + account); 40 | return generateWalletAddress(account); 41 | } 42 | 43 | /** 44 | * 生成账号 45 | * 46 | * @param account 47 | * @return 48 | */ 49 | public static Wallet generateWalletAddress(String account) { 50 | try { 51 | String mnemonic = MnemonicUtils.generateMnemonic(); 52 | byte[] seed = KeyPairUtils.generatePrivateKey(mnemonic, KeyPairUtils.CoinTypes.EOS); 53 | String privateKey = EccTool.privateKeyFromSeed(seed); 54 | String publicKey = EccTool.privateToPublic(privateKey); 55 | 56 | Transaction results = getRpc().createAccount(BuildConfig.EOS_CREATOR_PRIVATE_KEY, BuildConfig.EOS_CREATOR_ACCOUNT, account, publicKey, publicKey, null/*81921L*/); 57 | log("generate success transactionId = " + results.getTransactionId()); 58 | 59 | log(String.format("generateWalletAddress: mnemonic = %s, account = %s, privateKey = %s, publicKey = %s", mnemonic, account, privateKey, publicKey)); 60 | return new Wallet(mnemonic, account, publicKey, publicKey); 61 | } catch (ApiException ae) { 62 | // {"code":500,"message":"Internal Service Error","error":{"code":3050000,"name":"action_validate_exception","what":"action exception","details":[{"message":"Cannot create account named abc12345222a, as that name is already taken","file":"eosio_contract.cpp","line_number":91,"method":"apply_eosio_newaccount"},{"message":"","file":"eosio_contract.cpp","line_number":120,"method":"apply_eosio_newaccount"},{"message":"","file":"apply_context.cpp","line_number":60,"method":"exec_one"}]}} 63 | log(String.format("code = %s, message = %s", ae.getError().getError().getCode(), ae.getError().getError().getDetails()[0].getMessage())); 64 | } catch (Exception e) { 65 | e.printStackTrace(); 66 | } 67 | return null; 68 | } 69 | 70 | /** 71 | * 通过助记词获取私钥 72 | * 73 | * @param mnemonic 74 | */ 75 | public static String generatePrivateKey(String mnemonic) { 76 | byte[] seed = KeyPairUtils.generatePrivateKey(mnemonic, KeyPairUtils.CoinTypes.EOS); 77 | String privateKey = EccTool.privateKeyFromSeed(seed); 78 | log(String.format("generatePrivateKey: mnemonic = %s, privateKey = %s", mnemonic, privateKey)); 79 | return privateKey; 80 | } 81 | 82 | /** 83 | * 查询账号的余额 84 | */ 85 | public static void queryAccount(String account) { 86 | // {"rows":[{"balance":"800.0970 SYS","uppower":"800.0970 SYS","upvote":"800.0970 SYS","upvalue":"0.0000 SYS"}],"more":false} 87 | try { 88 | TableRows mTableRows = getRpc().getTableRows(new TableRowsReq(BuildConfig.EOS_CREATOR_ACCOUNT, account, "accounts")); 89 | } catch (ApiException ae) { 90 | log(String.format("code = %s, message = %s", ae.getError().getError().getCode(), ae.getError().getError().getDetails()[0].getMessage())); 91 | } catch (Exception e) { 92 | e.printStackTrace(); 93 | } 94 | return; 95 | } 96 | 97 | /** 98 | * 查询系统代币总额 99 | */ 100 | public static void querySupplys() { 101 | // {"rows":[{"totalrealsupply":"8865.4694 SYS"}],"more":false} 102 | try { 103 | TableRows mTableRows = getRpc().getTableRows(new TableRowsReq(BuildConfig.EOS_CREATOR_ACCOUNT, BuildConfig.EOS_CREATOR_ACCOUNT, "realsupplys")); 104 | String totalrealsupply = EosUtils.getBalance(mTableRows.getRowValue("totalrealsupply")); 105 | log("totalrealsupply = " + totalrealsupply); 106 | } catch (ApiException ae) { 107 | log(String.format("code = %s, message = %s", ae.getError().getError().getCode(), ae.getError().getError().getDetails()[0].getMessage())); 108 | } catch (Exception e) { 109 | e.printStackTrace(); 110 | } 111 | } 112 | 113 | /** 114 | * 转账 115 | * 116 | * @param fromAccount 117 | * @param fromPrivateKey 118 | * @param toAccount 119 | * @param quantity 120 | * @param memo 121 | */ 122 | public static void transfer(String fromAccount, String fromPrivateKey, String toAccount, String quantity, String memo) { 123 | try { 124 | /** 125 | * {"transaction_id":"f9c09e7584432228394323199909b93ea11820d47f011ee1bf33a1210d4b74ba", 126 | * "processed":{"id":"f9c09e7584432228394323199909b93ea11820d47f011ee1bf33a1210d4b74ba", 127 | * "receipt":{"status":"executed","cpu_usage_us":10675,"net_usage_words":16},"elapsed":10675,"net_usage":128,"scheduled":false, 128 | * "action_traces":[{"receipt":{"receiver":"eosio.token","act_digest":"c7bb8180f1bf92cac749c92a1f0184b47be6dbdc3f89790eb4ff037872d65de2","global_sequence":1166405, 129 | * "recv_sequence":704,"auth_sequence":[["a1111111111a",5]],"code_sequence":2,"abi_sequence":2}, 130 | * "act":{"account":"eosio.token","name":"transfer","authorization":[{"actor":"a1111111111a","permission":"active"}], 131 | * "data":{"from":"a1111111111a","to":"a1111111111b","quantity":"1.0000 SYS","memo":"xxx"},"hex_data":"604208218410423070420821841042301027000000000000045359530000000003787878"}, 132 | * "elapsed":7607,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"f9c09e7584432228394323199909b93ea11820d47f011ee1bf33a1210d4b74ba", 133 | * "inline_traces":[{"receipt":{"receiver":"a1111111111a","act_digest":"c7bb8180f1bf92cac749c92a1f0184b47be6dbdc3f89790eb4ff037872d65de2","global_sequence":1166406,"recv_sequence":3, 134 | * "auth_sequence":[["a1111111111a",6]],"code_sequence":2,"abi_sequence":2},"act":{"account":"eosio.token","name":"transfer", 135 | * "authorization":[{"actor":"a1111111111a","permission":"active"}], 136 | * "data":{"from":"a1111111111a","to":"a1111111111b","quantity":"1.0000 SYS","memo":"xxx"}, 137 | * "hex_data":"604208218410423070420821841042301027000000000000045359530000000003787878"},"elapsed":94,"cpu_usage":0,"console":"","total_cpu_usage":0, 138 | * "trx_id":"f9c09e7584432228394323199909b93ea11820d47f011ee1bf33a1210d4b74ba","inline_traces":[]},{"receipt":{"receiver":"a1111111111b", 139 | * "act_digest":"c7bb8180f1bf92cac749c92a1f0184b47be6dbdc3f89790eb4ff037872d65de2","global_sequence":1166407,"recv_sequence":2, 140 | * "auth_sequence":[["a1111111111a",7]],"code_sequence":2,"abi_sequence":2},"act":{"account":"eosio.token","name":"transfer", 141 | * "authorization":[{"actor":"a1111111111a","permission":"active"}],"data":{"from":"a1111111111a","to":"a1111111111b","quantity":"1.0000 SYS","memo":"xxx"}, 142 | * "hex_data":"604208218410423070420821841042301027000000000000045359530000000003787878"},"elapsed":118,"cpu_usage":0,"console":"", 143 | * "total_cpu_usage":0,"trx_id":"f9c09e7584432228394323199909b93ea11820d47f011ee1bf33a1210d4b74ba","inline_traces":[]}]}],"except":null}} 144 | */ 145 | Transaction results = getRpc().transfer(fromPrivateKey, BuildConfig.EOS_CREATOR_ACCOUNT, fromAccount, toAccount, quantity, memo); 146 | log("transfer success transactionId = " + results.getTransactionId()); 147 | } catch (ApiException ae) { 148 | log(String.format("code = %s, message = %s", ae.getError().getError().getCode(), ae.getError().getError().getDetails()[0].getMessage())); 149 | } catch (Exception e) { 150 | e.printStackTrace(); 151 | } 152 | } 153 | 154 | /** 155 | * up 156 | * 157 | * @param fromAccount 158 | * @param fromPrivateKey 159 | * @param toAccount 160 | * @param value 161 | */ 162 | public static void up(String fromAccount, String fromPrivateKey, String toAccount, String value) { 163 | try { 164 | /** 165 | * {"transaction_id":"7f5164d82d5d1444d55f5cc804e2cfee4c6e8be00276045f1c1a5abb12908bb7", 166 | * "processed":{"id":"7f5164d82d5d1444d55f5cc804e2cfee4c6e8be00276045f1c1a5abb12908bb7", 167 | * "receipt":{"status":"executed","cpu_usage_us":9513,"net_usage_words":16},"elapsed":9513,"net_usage":128,"scheduled":false, 168 | * "action_traces":[{"receipt":{"receiver":"eosio.token","act_digest":"4bc3c9cf2669dfdeabb61ded8637a07e5dc4ccc0124e0f5485c6f5df00a1573e","global_sequence":1166290, 169 | * "recv_sequence":703,"auth_sequence":[["a1111111111a",4]],"code_sequence":2,"abi_sequence":2}, 170 | * "act":{"account":"eosio.token","name":"up","authorization":[{"actor":"a1111111111a","permission":"active"}], 171 | * "data":{"upfrom":"a1111111111a","upto":"a1111111111b","value":"1.0000 SYS"},"hex_data":"6042082184104230704208218410423010270000000000000453595300000000"}, 172 | * "elapsed":7434,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"7f5164d82d5d1444d55f5cc804e2cfee4c6e8be00276045f1c1a5abb12908bb7","inline_traces":[]}],"except":null}} 173 | */ 174 | // 175 | Transaction results = getRpc().up(fromPrivateKey, BuildConfig.EOS_CREATOR_ACCOUNT, fromAccount, toAccount, value); 176 | log("up success transactionId = " + results.getTransactionId()); 177 | } catch (ApiException ae) { 178 | log(String.format("code = %s, message = %s", ae.getError().getError().getCode(), ae.getError().getError().getDetails()[0].getMessage())); 179 | } catch (Exception e) { 180 | e.printStackTrace(); 181 | } 182 | } 183 | 184 | private static void log(String message) { 185 | if (DEBUG) { 186 | System.out.println("WalletManager->" + message); 187 | // Log.i("wallet", "WalletManager->" + message); 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/Rpc.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos; 2 | 3 | import com.develop.wallet.BuildConfig; 4 | import com.develop.wallet.eos.api.RpcService; 5 | import com.develop.wallet.eos.api.http.Generator; 6 | import com.develop.wallet.eos.model.*; 7 | import com.develop.wallet.eos.model.account.Account; 8 | import com.develop.wallet.eos.model.transaction.Transaction; 9 | import com.develop.wallet.eos.model.transaction.push.Tx; 10 | import com.develop.wallet.eos.model.transaction.push.TxAction; 11 | import com.develop.wallet.eos.model.transaction.push.TxRequest; 12 | import com.develop.wallet.eos.model.transaction.push.TxSign; 13 | import com.develop.wallet.eos.utils.EccTool; 14 | import com.develop.wallet.eos.utils.ese.Action; 15 | import com.develop.wallet.eos.utils.ese.DataParam; 16 | import com.develop.wallet.eos.utils.ese.DataType; 17 | import com.develop.wallet.eos.utils.ese.Ese; 18 | import com.fasterxml.jackson.databind.ObjectMapper; 19 | 20 | import java.text.SimpleDateFormat; 21 | import java.util.*; 22 | 23 | 24 | public class Rpc { 25 | 26 | private final RpcService rpcService; 27 | private boolean DEBUG = BuildConfig.DEBUG; 28 | 29 | SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 30 | 31 | public Rpc(String baseUrl) { 32 | dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); 33 | rpcService = Generator.createService(RpcService.class, baseUrl, DEBUG); 34 | } 35 | 36 | /** 37 | * 获得链信息 38 | * 39 | * @return 40 | */ 41 | public ChainInfo getChainInfo() { 42 | return Generator.executeSync(rpcService.getChainInfo()); 43 | } 44 | 45 | /** 46 | * 获得区块信息 47 | * 48 | * @param blockNumberOrId 区块ID或者高度 49 | * @return 50 | */ 51 | public Block getBlock(String blockNumberOrId) { 52 | return Generator.executeSync(rpcService.getBlock(Collections.singletonMap("block_num_or_id", blockNumberOrId))); 53 | } 54 | 55 | /** 56 | * 获得账户信息 57 | * 58 | * @param account 账户名称 59 | * @return 60 | */ 61 | public Account getAccount(String account) { 62 | return Generator.executeSync(rpcService.getAccount(Collections.singletonMap("account_name", account))); 63 | } 64 | 65 | /** 66 | * 获得table数据 67 | * 68 | * @param req 69 | * @return 70 | */ 71 | public TableRows getTableRows(TableRowsReq req) { 72 | return Generator.executeSync(rpcService.getTableRows(req)); 73 | } 74 | 75 | public JsonToBin abiJsonToBin(JsonToBinReq req) { 76 | return Generator.executeSync(rpcService.abiJsonToBin(req)); 77 | } 78 | 79 | /** 80 | * 发送请求 81 | * 82 | * @param compression 压缩 83 | * @param pushTransaction 交易 84 | * @param signatures 签名 85 | * @return 86 | * @throws Exception 87 | */ 88 | public Transaction pushTransaction(String compression, Tx pushTransaction, String[] signatures) throws Exception { 89 | // ObjectMapper mapper = new ObjectMapper(); 90 | // String mapJakcson = mapper.writeValueAsString(new TxRequest(compression, pushTransaction, signatures)); 91 | // System.out.println(mapJakcson); 92 | return Generator 93 | .executeSync(rpcService.pushTransaction(new TxRequest(compression, pushTransaction, signatures))); 94 | } 95 | 96 | /** 97 | * 发送交易 98 | * 99 | * @param tx 100 | * @return 101 | * @throws Exception 102 | */ 103 | public Transaction pushTransaction(String tx) throws Exception { 104 | ObjectMapper mapper = new ObjectMapper(); 105 | TxRequest txObj = mapper.readValue(tx, TxRequest.class); 106 | return Generator.executeSync(rpcService.pushTransaction(txObj)); 107 | } 108 | 109 | /** 110 | * 获取离线签名参数 111 | * 112 | * @param exp 过期时间秒 113 | * @return 114 | */ 115 | public SignParam getOfflineSignParams(Long exp) { 116 | SignParam params = new SignParam(); 117 | ChainInfo info = getChainInfo(); 118 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 119 | params.setChainId(info.getChainId()); 120 | params.setHeadBlockTime(info.getHeadBlockTime()); 121 | params.setLastIrreversibleBlockNum(info.getLastIrreversibleBlockNum()); 122 | params.setRefBlockPrefix(block.getRefBlockPrefix()); 123 | params.setExp(exp); 124 | return params; 125 | } 126 | 127 | /** 128 | * 转账 129 | * 130 | * @param pk 私钥 131 | * @param contractAccount 合约账户 132 | * @param from 从 133 | * @param to 到 134 | * @param quantity 币种金额 135 | * @param memo 留言 136 | * @return 137 | * @throws Exception 138 | */ 139 | public Transaction transfer(String pk, String contractAccount, String from, String to, String quantity, String memo) 140 | throws Exception { 141 | // get chain info 142 | ChainInfo info = getChainInfo(); 143 | // get block info 144 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 145 | // tx 146 | Tx tx = new Tx(); 147 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 148 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 149 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 150 | tx.setNet_usage_words(0l); 151 | tx.setMax_cpu_usage_ms(0l); 152 | tx.setDelay_sec(0l); 153 | // actions 154 | List actions = new ArrayList<>(); 155 | // data 156 | Map dataMap = new LinkedHashMap<>(); 157 | dataMap.put("from", from); 158 | dataMap.put("to", to); 159 | dataMap.put("quantity", new DataParam(quantity, DataType.asset, Action.transfer).getValue()); 160 | dataMap.put("memo", memo); 161 | // action 162 | TxAction action = new TxAction(from, contractAccount, "transfer", dataMap); 163 | actions.add(action); 164 | tx.setActions(actions); 165 | // sgin 166 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 167 | // data parse 168 | String data = EccTool.parseTransferData(from, to, quantity, memo); 169 | // reset data 170 | action.setData(data); 171 | // reset expiration 172 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 173 | return pushTransaction("none", tx, new String[]{sign}); 174 | } 175 | 176 | 177 | public Transaction up(String pk, String contractAccount, String from, String to, String value) 178 | throws Exception { 179 | // get chain info 180 | ChainInfo info = getChainInfo(); 181 | // get block info 182 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 183 | // tx 184 | Tx tx = new Tx(); 185 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 186 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 187 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 188 | tx.setNet_usage_words(0l); 189 | tx.setMax_cpu_usage_ms(0l); 190 | tx.setDelay_sec(0l); 191 | // actions 192 | List actions = new ArrayList<>(); 193 | // data 194 | Map dataMap = new LinkedHashMap<>(); 195 | dataMap.put("upfrom", from); 196 | dataMap.put("upto", to); 197 | dataMap.put("value", new DataParam(value, DataType.asset, Action.up).getValue()); 198 | // action 199 | TxAction action = new TxAction(from, contractAccount, "up", dataMap); 200 | actions.add(action); 201 | tx.setActions(actions); 202 | // sgin 203 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 204 | // data parse 205 | String data = EccTool.parseUpData(from, to, value); 206 | // reset data 207 | action.setData(data); 208 | // reset expiration 209 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 210 | return pushTransaction("none", tx, new String[]{sign}); 211 | } 212 | 213 | /** 214 | * 创建账户 215 | * 216 | * @param pk 私钥 217 | * @param creator 创建者 218 | * @param newAccount 新账户 219 | * @param owner 公钥 220 | * @param active 公钥 221 | * @param buyRam ram 222 | * @return 223 | * @throws Exception 224 | */ 225 | public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, 226 | Long buyRam) throws Exception { 227 | // get chain info 228 | ChainInfo info = getChainInfo(); 229 | // get block info 230 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 231 | // tx 232 | Tx tx = new Tx(); 233 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 234 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 235 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 236 | tx.setNet_usage_words(0l); 237 | tx.setMax_cpu_usage_ms(0l); 238 | tx.setDelay_sec(0l); 239 | // actions 240 | List actions = new ArrayList<>(); 241 | tx.setActions(actions); 242 | // create 243 | Map createMap = new LinkedHashMap<>(); 244 | createMap.put("creator", creator); 245 | createMap.put("name", newAccount); 246 | createMap.put("owner", owner); 247 | createMap.put("active", active); 248 | TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap); 249 | actions.add(createAction); 250 | 251 | TxAction buyAction = null; 252 | if (buyRam != null && buyRam > 0) { 253 | // buyrap 254 | Map buyMap = new LinkedHashMap<>(); 255 | buyMap.put("payer", creator); 256 | buyMap.put("receiver", newAccount); 257 | buyMap.put("bytes", buyRam); 258 | buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap); 259 | actions.add(buyAction); 260 | } 261 | // sgin 262 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 263 | // data parse 264 | String accountData = Ese.parseAccountData(creator, newAccount, owner, active); 265 | createAction.setData(accountData); 266 | // data parse 267 | if (buyAction != null) { 268 | String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam); 269 | buyAction.setData(ramData); 270 | } 271 | // reset expiration 272 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 273 | return pushTransaction("none", tx, new String[]{sign}); 274 | } 275 | 276 | /** 277 | * 创建账户 278 | * 279 | * @param pk 私钥 280 | * @param creator 创建者 281 | * @param newAccount 新账户 282 | * @param owner 公钥 283 | * @param active 公钥 284 | * @param buyRam 购买空间数量 285 | * @param stakeNetQuantity 网络抵押 286 | * @param stakeCpuQuantity cpu抵押 287 | * @param transfer 抵押资产是否转送给对方,0自己所有,1对方所有 288 | * @return 289 | * @throws Exception 290 | */ 291 | public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, 292 | Long buyRam, String stakeNetQuantity, String stakeCpuQuantity, Long transfer) throws Exception { 293 | // get chain info 294 | ChainInfo info = getChainInfo(); 295 | // get block info 296 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 297 | // tx 298 | Tx tx = new Tx(); 299 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 300 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 301 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 302 | tx.setNet_usage_words(0l); 303 | tx.setMax_cpu_usage_ms(0l); 304 | tx.setDelay_sec(0l); 305 | // actions 306 | List actions = new ArrayList<>(); 307 | tx.setActions(actions); 308 | // create 309 | Map createMap = new LinkedHashMap<>(); 310 | createMap.put("creator", creator); 311 | createMap.put("name", newAccount); 312 | createMap.put("owner", owner); 313 | createMap.put("active", active); 314 | TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap); 315 | actions.add(createAction); 316 | // buyrap 317 | Map buyMap = new LinkedHashMap<>(); 318 | buyMap.put("payer", creator); 319 | buyMap.put("receiver", newAccount); 320 | buyMap.put("bytes", buyRam); 321 | TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap); 322 | actions.add(buyAction); 323 | // buyrap 324 | Map delMap = new LinkedHashMap<>(); 325 | delMap.put("from", creator); 326 | delMap.put("receiver", newAccount); 327 | delMap.put("stake_net_quantity", new DataParam(stakeNetQuantity, DataType.asset, Action.delegate).getValue()); 328 | delMap.put("stake_cpu_quantity", new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate).getValue()); 329 | delMap.put("transfer", transfer); 330 | TxAction delAction = new TxAction(creator, "eosio", "delegatebw", delMap); 331 | actions.add(delAction); 332 | // // sgin 333 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 334 | // data parse 335 | String accountData = Ese.parseAccountData(creator, newAccount, owner, active); 336 | createAction.setData(accountData); 337 | // data parse 338 | String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam); 339 | buyAction.setData(ramData); 340 | // data parse 341 | String delData = Ese.parseDelegateData(creator, newAccount, stakeNetQuantity, stakeCpuQuantity, 342 | transfer.intValue()); 343 | delAction.setData(delData); 344 | // reset expiration 345 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 346 | return pushTransaction("none", tx, new String[]{sign}); 347 | } 348 | 349 | /** 350 | * @param pk 351 | * @param voter 352 | * @param proxy 353 | * @param producers 354 | * @return 355 | * @throws Exception 356 | */ 357 | public Transaction voteproducer(String pk, String voter, String proxy, List producers) throws Exception { 358 | Comparator comparator = (h1, h2) -> h2.compareTo(h1); 359 | producers.sort(comparator.reversed()); 360 | // get chain info 361 | ChainInfo info = getChainInfo(); 362 | // get block info 363 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 364 | // tx 365 | Tx tx = new Tx(); 366 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 367 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 368 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 369 | tx.setNet_usage_words(0l); 370 | tx.setMax_cpu_usage_ms(0l); 371 | tx.setDelay_sec(0l); 372 | // actions 373 | List actions = new ArrayList<>(); 374 | // data 375 | Map dataMap = new LinkedHashMap<>(); 376 | dataMap.put("voter", voter); 377 | dataMap.put("proxy", proxy); 378 | dataMap.put("producers", producers); 379 | // action 380 | TxAction action = new TxAction(voter, "eosio", "voteproducer", dataMap); 381 | actions.add(action); 382 | tx.setActions(actions); 383 | // sgin 384 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 385 | // data parse 386 | String data = EccTool.parseVoteProducerData(voter, proxy, producers); 387 | // reset data 388 | action.setData(data); 389 | // reset expiration 390 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 391 | return pushTransaction("none", tx, new String[]{sign}); 392 | } 393 | 394 | /** 395 | * token close 396 | * 397 | * @param owner 398 | * @param symbol 399 | * @return 400 | * @throws Exception 401 | */ 402 | public Transaction close(String pk, String contract, String owner, String symbol) throws Exception { 403 | ChainInfo info = getChainInfo(); 404 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 405 | Tx tx = new Tx(); 406 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 407 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 408 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 409 | tx.setNet_usage_words(0l); 410 | tx.setMax_cpu_usage_ms(0l); 411 | tx.setDelay_sec(0l); 412 | // actions 413 | List actions = new ArrayList<>(); 414 | // data 415 | Map dataMap = new LinkedHashMap<>(); 416 | dataMap.put("close-owner", owner); 417 | dataMap.put("close-symbol", new DataParam(symbol, DataType.symbol, Action.close).getValue()); 418 | // action 419 | TxAction action = new TxAction(owner, contract, "close", dataMap); 420 | actions.add(action); 421 | tx.setActions(actions); 422 | // sgin 423 | String sign = EccTool.signTransaction(pk, new TxSign(info.getChainId(), tx)); 424 | // data parse 425 | String data = EccTool.parseCloseData(owner, symbol); 426 | // reset data 427 | action.setData(data); 428 | // reset expiration 429 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 430 | return pushTransaction("none", tx, new String[]{sign}); 431 | } 432 | } 433 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/RpcService.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api; 2 | 3 | import com.develop.wallet.eos.model.*; 4 | import com.develop.wallet.eos.model.account.Account; 5 | import com.develop.wallet.eos.model.transaction.Transaction; 6 | import com.develop.wallet.eos.model.transaction.push.TxRequest; 7 | import retrofit2.Call; 8 | import retrofit2.http.Body; 9 | import retrofit2.http.GET; 10 | import retrofit2.http.POST; 11 | 12 | import java.util.Map; 13 | 14 | /** 15 | * @author espritblock http://eblock.io 16 | */ 17 | public interface RpcService { 18 | 19 | @GET("/v1/chain/get_info") 20 | Call getChainInfo(); 21 | 22 | @POST("/v1/chain/get_block") 23 | Call getBlock(@Body Map requestFields); 24 | 25 | @POST("/v1/chain/get_account") 26 | Call getAccount(@Body Map requestFields); 27 | 28 | @POST("/v1/chain/push_transaction") 29 | Call pushTransaction(@Body TxRequest request); 30 | 31 | @POST("/v1/chain/get_table_rows") 32 | Call getTableRows(@Body TableRowsReq request); 33 | 34 | @POST("/v1/chain/abi_json_to_bin") 35 | Call abiJsonToBin(@Body JsonToBinReq request); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/exception/ApiError.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api.exception; 2 | 3 | 4 | /** 5 | * @author espritblock http://eblock.io 6 | */ 7 | public class ApiError { 8 | 9 | private String message; 10 | 11 | private String code; 12 | 13 | private Error error; 14 | 15 | public String getMessage() { 16 | return message; 17 | } 18 | 19 | public void setMessage(String message) { 20 | this.message = message; 21 | } 22 | 23 | public String getCode() { 24 | return code; 25 | } 26 | 27 | public void setCode(String code) { 28 | this.code = code; 29 | } 30 | 31 | public Error getError() { 32 | return error; 33 | } 34 | 35 | public void setError(Error error) { 36 | this.error = error; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/exception/ApiException.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api.exception; 2 | 3 | /** 4 | * @author espritblock http://eblock.io 5 | */ 6 | public class ApiException extends RuntimeException { 7 | 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = 1L; 12 | 13 | private ApiError error; 14 | 15 | public ApiException(ApiError apiError) { 16 | this.error = apiError; 17 | } 18 | 19 | public ApiException(Throwable cause) { 20 | super(cause); 21 | } 22 | 23 | public ApiError getError() { 24 | return error; 25 | } 26 | 27 | public void setError(ApiError error) { 28 | this.error = error; 29 | } 30 | 31 | @Override 32 | public String getMessage() { 33 | if (error != null) { 34 | return error.getMessage(); 35 | } 36 | return super.getMessage(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/exception/Error.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api.exception; 2 | 3 | /** 4 | * @author espritblock http://eblock.io 5 | */ 6 | public class Error { 7 | 8 | private String code; 9 | 10 | private String name; 11 | 12 | private String what; 13 | 14 | private ErrorDetails[] details; 15 | 16 | private Error() { 17 | 18 | } 19 | 20 | public String getCode() { 21 | return code; 22 | } 23 | 24 | public void setCode(String code) { 25 | this.code = code; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public String getWhat() { 37 | return what; 38 | } 39 | 40 | public void setWhat(String what) { 41 | this.what = what; 42 | } 43 | 44 | public ErrorDetails[] getDetails() { 45 | return details; 46 | } 47 | 48 | public void setDetails(ErrorDetails[] details) { 49 | this.details = details; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/exception/ErrorDetails.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api.exception; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | /** 6 | * @author espritblock http://eblock.io 7 | */ 8 | public class ErrorDetails { 9 | 10 | private String message; 11 | 12 | private String file; 13 | 14 | private Integer lineNumber; 15 | 16 | private String method; 17 | 18 | private ErrorDetails() { 19 | 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | 30 | public String getFile() { 31 | return file; 32 | } 33 | 34 | public void setFile(String file) { 35 | this.file = file; 36 | } 37 | 38 | public Integer getLineNumber() { 39 | return lineNumber; 40 | } 41 | 42 | @JsonProperty("line_number") 43 | public void setLineNumber(Integer lineNumber) { 44 | this.lineNumber = lineNumber; 45 | } 46 | 47 | public String getMethod() { 48 | return method; 49 | } 50 | 51 | public void setMethod(String method) { 52 | this.method = method; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/api/http/Generator.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.api.http; 2 | 3 | import com.develop.wallet.eos.api.exception.ApiError; 4 | import com.develop.wallet.eos.api.exception.ApiException; 5 | import okhttp3.OkHttpClient; 6 | import okhttp3.logging.HttpLoggingInterceptor; 7 | import retrofit2.Call; 8 | import retrofit2.Response; 9 | import retrofit2.Retrofit; 10 | import retrofit2.converter.jackson.JacksonConverterFactory; 11 | 12 | import java.io.IOException; 13 | import java.lang.annotation.Annotation; 14 | 15 | public class Generator { 16 | 17 | private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 18 | 19 | private static Retrofit.Builder builder = new Retrofit.Builder() 20 | .addConverterFactory(JacksonConverterFactory.create()); 21 | 22 | private static Retrofit retrofit; 23 | 24 | public static S createService(Class serviceClass, String baseUrl, boolean logDebug) { 25 | if (logDebug) { 26 | // Log信息拦截器 27 | HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); 28 | loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 29 | //设置 Debug Log 模式 30 | httpClient.addInterceptor(loggingInterceptor); 31 | } 32 | 33 | builder.baseUrl(baseUrl); 34 | builder.client(httpClient.build()); 35 | builder.addConverterFactory(JacksonConverterFactory.create()); 36 | retrofit = builder.build(); 37 | return retrofit.create(serviceClass); 38 | } 39 | 40 | public static T executeSync(Call call) { 41 | try { 42 | Response response = call.execute(); 43 | if (response.isSuccessful()) { 44 | return response.body(); 45 | } else { 46 | ApiError apiError = getApiError(response); 47 | throw new ApiException(apiError); 48 | } 49 | } catch (IOException e) { 50 | throw new ApiException(e); 51 | } 52 | } 53 | 54 | private static ApiError getApiError(Response response) throws IOException, ApiException { 55 | return (ApiError) retrofit.responseBodyConverter(ApiError.class, new Annotation[0]).convert(response.errorBody()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/Curve.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Curve 7 | * 8 | * @author espritblock http://eblock.io 9 | */ 10 | public class Curve { 11 | 12 | private FieldElement a; 13 | 14 | private FieldElement b; 15 | 16 | private BigInteger q; 17 | 18 | private Point infinity; 19 | 20 | private BigInteger pOverFour; 21 | 22 | public Curve(BigInteger q, BigInteger a, BigInteger b) { 23 | this.q = q; 24 | this.a = fromBigInteger(a); 25 | this.b = fromBigInteger(b); 26 | this.infinity = new Point(this, null, null); 27 | this.pOverFour = q.add(BigInteger.ONE).shiftRight(2); 28 | } 29 | 30 | public FieldElement getA() { 31 | return a; 32 | } 33 | 34 | public FieldElement getB() { 35 | return b; 36 | } 37 | 38 | public BigInteger getQ() { 39 | return q; 40 | } 41 | 42 | public Point getInfinity() { 43 | return infinity; 44 | } 45 | 46 | public int getFieldSize() { 47 | return q.bitLength(); 48 | } 49 | 50 | public FieldElement fromBigInteger(BigInteger x) { 51 | return new FieldElement(this.q, x); 52 | } 53 | 54 | public Point pointFromX(int isOdd, BigInteger x) { 55 | FieldElement f = this.a.multiply(fromBigInteger(x)); 56 | BigInteger alpha = x.pow(3).add(f.toBigInteger()).add(this.b.toBigInteger()).mod(this.q); 57 | BigInteger beta = alpha.modPow(this.pOverFour, this.q); 58 | BigInteger y = beta; 59 | if (beta.intValue() % 2 == 0 ^ isOdd == 0) { 60 | y = this.q.subtract(y); 61 | } 62 | return new Point(this, new FieldElement(this.q, x), new FieldElement(this.q, y), false); 63 | } 64 | 65 | public Point decodePoint(byte[] encodedPoint) { 66 | Point p = null; 67 | switch (encodedPoint[0]) { 68 | case 0x00: 69 | p = getInfinity(); 70 | break; 71 | case 0x02: 72 | case 0x03: 73 | int ytilde = encodedPoint[0] & 1; 74 | byte[] i = new byte[encodedPoint.length - 1]; 75 | System.arraycopy(encodedPoint, 1, i, 0, i.length); 76 | FieldElement x = new FieldElement(this.q, new BigInteger(1, i)); 77 | FieldElement alpha = x.multiply(x.square().add(a)).add(b); 78 | FieldElement beta = alpha.sqrt(); 79 | if (beta == null) { 80 | throw new RuntimeException("Invalid compression"); 81 | } 82 | int bit0 = (beta.toBigInteger().testBit(0) ? 1 : 0); 83 | if (bit0 == ytilde) { 84 | p = new Point(this, x, beta, true); 85 | } else { 86 | p = new Point(this, x, new FieldElement(this.q, q.subtract(beta.toBigInteger())), true); 87 | } 88 | break; 89 | case 0x04: 90 | case 0x06: 91 | case 0x07: 92 | byte[] xEnc = new byte[(encodedPoint.length - 1) / 2]; 93 | byte[] yEnc = new byte[(encodedPoint.length - 1) / 2]; 94 | System.arraycopy(encodedPoint, 1, xEnc, 0, xEnc.length); 95 | System.arraycopy(encodedPoint, xEnc.length + 1, yEnc, 0, yEnc.length); 96 | p = new Point(this, new FieldElement(this.q, new BigInteger(1, xEnc)), 97 | new FieldElement(this.q, new BigInteger(1, yEnc))); 98 | break; 99 | default: 100 | throw new RuntimeException("Invalid encoding 0x" + Integer.toString(encodedPoint[0], 16)); 101 | } 102 | return p; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/FieldElement.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto; 2 | 3 | import com.develop.wallet.eos.utils.EException; 4 | 5 | import java.math.BigInteger; 6 | import java.util.Random; 7 | 8 | 9 | /** 10 | * FieldElement 11 | * 12 | * @author espritblock http://eblock.io 13 | */ 14 | public class FieldElement { 15 | 16 | private BigInteger q; 17 | 18 | private BigInteger x; 19 | 20 | private static final BigInteger TWO = BigInteger.valueOf(2); 21 | 22 | public FieldElement(BigInteger q, BigInteger x) { 23 | this.x = x; 24 | if (x.compareTo(q) >= 0) { 25 | throw new EException("error", "x value too large in field element"); 26 | } 27 | this.q = q; 28 | } 29 | 30 | public FieldElement add(FieldElement b) { 31 | return new FieldElement(q, x.add(b.toBigInteger()).mod(q)); 32 | } 33 | 34 | public FieldElement subtract(FieldElement b) { 35 | return new FieldElement(q, x.subtract(b.toBigInteger()).mod(q)); 36 | } 37 | 38 | public FieldElement multiply(FieldElement b) { 39 | return new FieldElement(q, x.multiply(b.toBigInteger()).mod(q)); 40 | } 41 | 42 | public FieldElement divide(FieldElement b) { 43 | return new FieldElement(q, x.multiply(b.toBigInteger().modInverse(q)).mod(q)); 44 | } 45 | 46 | public FieldElement negate() { 47 | return new FieldElement(q, x.negate().mod(q)); 48 | } 49 | 50 | public FieldElement square() { 51 | return new FieldElement(q, x.multiply(x).mod(q)); 52 | } 53 | 54 | public FieldElement invert() { 55 | return new FieldElement(q, x.modInverse(q)); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return this.toBigInteger().toString(16); 61 | } 62 | 63 | public FieldElement sqrt() { 64 | if (!q.testBit(0)) { 65 | throw new RuntimeException("not done yet"); 66 | } 67 | 68 | if (q.testBit(1)) { 69 | FieldElement z = new FieldElement(q, x.modPow(q.shiftRight(2).add(BigInteger.ONE), q)); 70 | return z.square().equals(this) ? z : null; 71 | } 72 | BigInteger qMinusOne = q.subtract(BigInteger.ONE); 73 | BigInteger legendreExponent = qMinusOne.shiftRight(1); 74 | if (!(x.modPow(legendreExponent, q).equals(BigInteger.ONE))) { 75 | return null; 76 | } 77 | BigInteger u = qMinusOne.shiftRight(2); 78 | BigInteger k = u.shiftLeft(1).add(BigInteger.ONE); 79 | BigInteger Q = this.x; 80 | BigInteger fourQ = Q.shiftLeft(2).mod(q); 81 | BigInteger U, V; 82 | Random rand = new Random(); 83 | do { 84 | BigInteger P; 85 | do { 86 | P = new BigInteger(q.bitLength(), rand); 87 | } while (P.compareTo(q) >= 0 88 | || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, q).equals(qMinusOne))); 89 | BigInteger[] result = lucasSequence(q, P, Q, k); 90 | U = result[0]; 91 | V = result[1]; 92 | if (V.multiply(V).mod(q).equals(fourQ)) { 93 | if (V.testBit(0)) { 94 | V = V.add(q); 95 | } 96 | V = V.shiftRight(1); 97 | return new FieldElement(q, V); 98 | } 99 | } while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); 100 | return null; 101 | } 102 | 103 | private static BigInteger[] lucasSequence(BigInteger p, BigInteger P, BigInteger Q, BigInteger k) { 104 | int n = k.bitLength(); 105 | int s = k.getLowestSetBit(); 106 | BigInteger Uh = BigInteger.ONE; 107 | BigInteger Vl = TWO; 108 | BigInteger Vh = P; 109 | BigInteger Ql = BigInteger.ONE; 110 | BigInteger Qh = BigInteger.ONE; 111 | for (int j = n - 1; j >= s + 1; --j) { 112 | Ql = Ql.multiply(Qh).mod(p); 113 | if (k.testBit(j)) { 114 | Qh = Ql.multiply(Q).mod(p); 115 | Uh = Uh.multiply(Vh).mod(p); 116 | Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 117 | Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); 118 | } else { 119 | Qh = Ql; 120 | Uh = Uh.multiply(Vl).subtract(Ql).mod(p); 121 | Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 122 | Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); 123 | } 124 | } 125 | Ql = Ql.multiply(Qh).mod(p); 126 | Qh = Ql.multiply(Q).mod(p); 127 | Uh = Uh.multiply(Vl).subtract(Ql).mod(p); 128 | Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 129 | Ql = Ql.multiply(Qh).mod(p); 130 | for (int j = 1; j <= s; ++j) { 131 | Uh = Uh.multiply(Vl).mod(p); 132 | Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); 133 | Ql = Ql.multiply(Ql).mod(p); 134 | } 135 | return new BigInteger[]{Uh, Vl}; 136 | } 137 | 138 | public BigInteger toBigInteger() { 139 | return x; 140 | } 141 | 142 | public int getFieldSize() { 143 | return q.bitLength(); 144 | } 145 | 146 | public BigInteger getQ() { 147 | return q; 148 | } 149 | 150 | public boolean equals(Object other) { 151 | if (other == this) { 152 | return true; 153 | } 154 | if (!(other instanceof FieldElement)) { 155 | return false; 156 | } 157 | FieldElement o = (FieldElement) other; 158 | return q.equals(o.q) && x.equals(o.x); 159 | } 160 | 161 | public int hashCode() { 162 | return q.hashCode() ^ x.hashCode(); 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/Point.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Point 7 | * 8 | * @author espritblock http://eblock.io 9 | */ 10 | public class Point { 11 | 12 | private Curve curve; 13 | 14 | private FieldElement x; 15 | 16 | private FieldElement y; 17 | 18 | private boolean compressed; 19 | 20 | public Point(Curve curve, FieldElement x, FieldElement y, boolean compressed) { 21 | this.curve = curve; 22 | this.x = x; 23 | this.y = y; 24 | this.compressed = compressed; 25 | } 26 | 27 | public Point(Curve curve, FieldElement x, FieldElement y) { 28 | this(curve, x, y, true); 29 | } 30 | 31 | public Curve getCurve() { 32 | return curve; 33 | } 34 | 35 | public FieldElement getX() { 36 | return x; 37 | } 38 | 39 | public FieldElement getY() { 40 | return y; 41 | } 42 | 43 | public boolean isInfinity() { 44 | return x == null && y == null; 45 | } 46 | 47 | public boolean isCompressed() { 48 | return compressed; 49 | } 50 | 51 | public byte[] getEncoded() { 52 | 53 | if (this.isInfinity()) { 54 | return new byte[1]; 55 | } 56 | 57 | int length = getByteLength(x.getFieldSize()); 58 | 59 | if (compressed) { 60 | byte PC; 61 | if (this.getY().toBigInteger().testBit(0)) { 62 | PC = 0x03; 63 | } else { 64 | PC = 0x02; 65 | } 66 | byte[] X = integerToBytes(this.getX().toBigInteger(), length); 67 | byte[] PO = new byte[X.length + 1]; 68 | PO[0] = PC; 69 | System.arraycopy(X, 0, PO, 1, X.length); 70 | return PO; 71 | } else { 72 | byte[] X = integerToBytes(this.getX().toBigInteger(), length); 73 | byte[] Y = integerToBytes(this.getY().toBigInteger(), length); 74 | byte[] PO = new byte[X.length + Y.length + 1]; 75 | PO[0] = 0x04; 76 | System.arraycopy(X, 0, PO, 1, X.length); 77 | System.arraycopy(Y, 0, PO, X.length + 1, Y.length); 78 | return PO; 79 | } 80 | } 81 | 82 | public Point add(Point b) { 83 | if (this.isInfinity()) { 84 | return b; 85 | } 86 | if (b.isInfinity()) { 87 | return this; 88 | } 89 | if (this.x.equals(b.x)) { 90 | if (this.y.equals(b.y)) { 91 | return this.twice(); 92 | } 93 | return this.curve.getInfinity(); 94 | } 95 | FieldElement gamma = b.y.subtract(this.y).divide(b.x.subtract(this.x)); 96 | FieldElement x3 = gamma.square().subtract(this.x).subtract(b.x); 97 | FieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); 98 | return new Point(curve, x3, y3); 99 | } 100 | 101 | public Point twice() { 102 | if (this.isInfinity()) { 103 | return this; 104 | } 105 | if (this.y.toBigInteger().signum() == 0) { 106 | return this.curve.getInfinity(); 107 | } 108 | FieldElement TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); 109 | FieldElement THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); 110 | FieldElement gamma = this.x.square().multiply(THREE).add(curve.getA()).divide(y.multiply(TWO)); 111 | FieldElement x3 = gamma.square().subtract(this.x.multiply(TWO)); 112 | FieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); 113 | return new Point(curve, x3, y3, this.compressed); 114 | } 115 | 116 | public Point subtract(Point b) { 117 | if (b.isInfinity()) { 118 | return this; 119 | } 120 | return add(b.negate()); 121 | } 122 | 123 | public Point negate() { 124 | return new Point(curve, this.x, this.y.negate(), this.compressed); 125 | } 126 | 127 | public Point multiply(BigInteger k) { 128 | BigInteger e = k; 129 | BigInteger h = e.multiply(BigInteger.valueOf(3)); 130 | Point neg = this.negate(); 131 | Point R = this; 132 | for (int i = h.bitLength() - 2; i > 0; --i) { 133 | R = R.twice(); 134 | boolean hBit = h.testBit(i); 135 | boolean eBit = e.testBit(i); 136 | if (hBit != eBit) { 137 | R = R.add(hBit ? this : neg); 138 | } 139 | } 140 | return R; 141 | } 142 | 143 | public Point multiplyTwo(BigInteger j, Point x, BigInteger k) { 144 | int i = Math.max(j.bitLength(), k.bitLength()) - 1; 145 | Point R = this.curve.getInfinity(); 146 | Point both = this.add(x); 147 | while (i >= 0) { 148 | Boolean jBit = j.testBit(i); 149 | Boolean kBit = k.testBit(i); 150 | 151 | R = R.twice(); 152 | 153 | if (jBit) { 154 | if (kBit) { 155 | R = R.add(both); 156 | } else { 157 | R = R.add(this); 158 | } 159 | } else if (kBit) { 160 | R = R.add(x); 161 | } 162 | --i; 163 | } 164 | return R; 165 | } 166 | 167 | public static int getByteLength(int fieldSize) { 168 | return (fieldSize + 7) / 8; 169 | } 170 | 171 | public static byte[] integerToBytes(BigInteger s, int length) { 172 | byte[] bytes = s.toByteArray(); 173 | if (length < bytes.length) { 174 | byte[] tmp = new byte[length]; 175 | System.arraycopy(bytes, bytes.length - tmp.length, tmp, 0, tmp.length); 176 | return tmp; 177 | } else if (length > bytes.length) { 178 | byte[] tmp = new byte[length]; 179 | System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length); 180 | return tmp; 181 | } 182 | return bytes; 183 | } 184 | 185 | @Override 186 | public boolean equals(Object other) { 187 | if (other == this) { 188 | return true; 189 | } 190 | 191 | if (!(other instanceof Point)) { 192 | return false; 193 | } 194 | 195 | Point o = (Point) other; 196 | 197 | if (this.isInfinity()) { 198 | return o.isInfinity(); 199 | } 200 | 201 | return x.equals(o.x) && y.equals(o.y); 202 | } 203 | 204 | @Override 205 | public int hashCode() { 206 | if (this.isInfinity()) { 207 | return 0; 208 | } 209 | 210 | return x.hashCode() ^ y.hashCode(); 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/Secp256k.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto; 2 | 3 | import com.develop.wallet.eos.utils.Hex; 4 | 5 | import java.math.BigInteger; 6 | 7 | 8 | /** 9 | * Curve 10 | * 11 | * @author espritblock http://eblock.io 12 | */ 13 | public class Secp256k { 14 | 15 | public static final String P = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"; 16 | public static final String A = "0"; 17 | public static final String B = "7"; 18 | public static final String N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; 19 | public static final String GX = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"; 20 | public static final String GY = "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"; 21 | 22 | private final Curve curve; 23 | 24 | private final Point G; 25 | 26 | private final BigInteger n; 27 | 28 | private final BigInteger HALF_CURVE_ORDER; 29 | 30 | public Secp256k() { 31 | n = new BigInteger(N, 16); 32 | HALF_CURVE_ORDER = n.shiftRight(1); 33 | curve = new Curve(new BigInteger(P, 16), new BigInteger(A, 16), new BigInteger(B, 16)); 34 | G = curve.decodePoint(Hex.toBytes("04" + GX + GY)); 35 | } 36 | 37 | public Point G() { 38 | return this.G; 39 | } 40 | 41 | public BigInteger n() { 42 | return this.n; 43 | } 44 | 45 | public BigInteger halfCurveOrder() { 46 | return HALF_CURVE_ORDER; 47 | } 48 | 49 | public Curve getCurve() { 50 | return curve; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/digest/GeneralDigest.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.digest; 2 | 3 | public abstract class GeneralDigest { 4 | private static final int BYTE_LENGTH = 64; 5 | private byte[] xBuf; 6 | private int xBufOff; 7 | 8 | private long byteCount; 9 | 10 | /** 11 | * Standard constructor 12 | */ 13 | protected GeneralDigest() { 14 | xBuf = new byte[4]; 15 | xBufOff = 0; 16 | } 17 | 18 | /** 19 | * Copy constructor. We are using copy constructors in place of the 20 | * Object.clone() interface as this interface is not supported by J2ME. 21 | */ 22 | protected GeneralDigest(GeneralDigest t) { 23 | xBuf = new byte[t.xBuf.length]; 24 | System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); 25 | 26 | xBufOff = t.xBufOff; 27 | byteCount = t.byteCount; 28 | } 29 | 30 | public void update(byte in) { 31 | xBuf[xBufOff++] = in; 32 | 33 | if (xBufOff == xBuf.length) { 34 | processWord(xBuf, 0); 35 | xBufOff = 0; 36 | } 37 | 38 | byteCount++; 39 | } 40 | 41 | public void update(byte[] in, int inOff, int len) { 42 | // 43 | // fill the current word 44 | // 45 | while ((xBufOff != 0) && (len > 0)) { 46 | update(in[inOff]); 47 | 48 | inOff++; 49 | len--; 50 | } 51 | 52 | // 53 | // process whole words. 54 | // 55 | while (len > xBuf.length) { 56 | processWord(in, inOff); 57 | 58 | inOff += xBuf.length; 59 | len -= xBuf.length; 60 | byteCount += xBuf.length; 61 | } 62 | 63 | // 64 | // load in the remainder. 65 | // 66 | while (len > 0) { 67 | update(in[inOff]); 68 | 69 | inOff++; 70 | len--; 71 | } 72 | } 73 | 74 | public void finish() { 75 | long bitLength = (byteCount << 3); 76 | 77 | // 78 | // add the pad bytes. 79 | // 80 | update((byte) 128); 81 | 82 | while (xBufOff != 0) { 83 | update((byte) 0); 84 | } 85 | 86 | processLength(bitLength); 87 | 88 | processBlock(); 89 | } 90 | 91 | public void reset() { 92 | byteCount = 0; 93 | 94 | xBufOff = 0; 95 | for (int i = 0; i < xBuf.length; i++) { 96 | xBuf[i] = 0; 97 | } 98 | } 99 | 100 | public int getByteLength() { 101 | return BYTE_LENGTH; 102 | } 103 | 104 | protected abstract void processWord(byte[] in, int inOff); 105 | 106 | protected abstract void processLength(long bitLength); 107 | 108 | protected abstract void processBlock(); 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/digest/Ripemd160.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.digest; 2 | 3 | public class Ripemd160 { 4 | 5 | final private byte[] mDigestBytes; 6 | 7 | public Ripemd160(byte[] digest) { 8 | mDigestBytes = digest; 9 | } 10 | 11 | public static Ripemd160 from(byte[] data) { 12 | 13 | return Ripemd160.from(data, 0, (data != null) ? data.length : 0); 14 | } 15 | 16 | public static Ripemd160 from(byte[] data, int startOffset, int length) { 17 | Digest digest = new Digest(); 18 | digest.update(data, startOffset, length); 19 | 20 | byte[] result = new byte[Digest.DIGEST_LENGTH]; 21 | digest.doFinal(result, 0); 22 | 23 | return new Ripemd160(result); 24 | } 25 | 26 | public byte[] bytes() { 27 | return mDigestBytes; 28 | } 29 | 30 | public static class Digest extends GeneralDigest { 31 | static final int DIGEST_LENGTH = 20; 32 | 33 | private int H0, H1, H2, H3, H4; // IV's 34 | 35 | private int[] X = new int[16]; 36 | private int xOff; 37 | 38 | /** 39 | * Standard constructor 40 | */ 41 | public Digest() { 42 | reset(); 43 | } 44 | 45 | protected void processWord(byte[] in, int inOff) { 46 | X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16) 47 | | ((in[inOff + 3] & 0xff) << 24); 48 | 49 | if (xOff == 16) { 50 | processBlock(); 51 | } 52 | } 53 | 54 | protected void processLength(long bitLength) { 55 | if (xOff > 14) { 56 | processBlock(); 57 | } 58 | 59 | X[14] = (int) (bitLength & 0xffffffff); 60 | X[15] = (int) (bitLength >>> 32); 61 | } 62 | 63 | private void unpackWord(int word, byte[] out, int outOff) { 64 | out[outOff] = (byte) word; 65 | out[outOff + 1] = (byte) (word >>> 8); 66 | out[outOff + 2] = (byte) (word >>> 16); 67 | out[outOff + 3] = (byte) (word >>> 24); 68 | } 69 | 70 | public int doFinal(byte[] out, int outOff) { 71 | finish(); 72 | 73 | unpackWord(H0, out, outOff); 74 | unpackWord(H1, out, outOff + 4); 75 | unpackWord(H2, out, outOff + 8); 76 | unpackWord(H3, out, outOff + 12); 77 | unpackWord(H4, out, outOff + 16); 78 | 79 | reset(); 80 | 81 | return DIGEST_LENGTH; 82 | } 83 | 84 | /** 85 | * reset the chaining variables to the IV values. 86 | */ 87 | public void reset() { 88 | super.reset(); 89 | 90 | H0 = 0x67452301; 91 | H1 = 0xefcdab89; 92 | H2 = 0x98badcfe; 93 | H3 = 0x10325476; 94 | H4 = 0xc3d2e1f0; 95 | 96 | xOff = 0; 97 | 98 | for (int i = 0; i != X.length; i++) { 99 | X[i] = 0; 100 | } 101 | } 102 | 103 | /* 104 | * rotate int x left n bits. 105 | */ 106 | private int RL(int x, int n) { 107 | return (x << n) | (x >>> (32 - n)); 108 | } 109 | 110 | /* 111 | * f1,f2,f3,f4,f5 are the basic Digest functions. 112 | */ 113 | 114 | /* 115 | * rounds 0-15 116 | */ 117 | private int f1(int x, int y, int z) { 118 | return x ^ y ^ z; 119 | } 120 | 121 | /* 122 | * rounds 16-31 123 | */ 124 | private int f2(int x, int y, int z) { 125 | return (x & y) | (~x & z); 126 | } 127 | 128 | /* 129 | * rounds 32-47 130 | */ 131 | private int f3(int x, int y, int z) { 132 | return (x | ~y) ^ z; 133 | } 134 | 135 | /* 136 | * rounds 48-63 137 | */ 138 | private int f4(int x, int y, int z) { 139 | return (x & z) | (y & ~z); 140 | } 141 | 142 | /* 143 | * rounds 64-79 144 | */ 145 | private int f5(int x, int y, int z) { 146 | return x ^ (y | ~z); 147 | } 148 | 149 | protected void processBlock() { 150 | int a, aa; 151 | int b, bb; 152 | int c, cc; 153 | int d, dd; 154 | int e, ee; 155 | 156 | a = aa = H0; 157 | b = bb = H1; 158 | c = cc = H2; 159 | d = dd = H3; 160 | e = ee = H4; 161 | 162 | // 163 | // Rounds 1 - 16 164 | // 165 | // left 166 | a = RL(a + f1(b, c, d) + X[0], 11) + e; 167 | c = RL(c, 10); 168 | e = RL(e + f1(a, b, c) + X[1], 14) + d; 169 | b = RL(b, 10); 170 | d = RL(d + f1(e, a, b) + X[2], 15) + c; 171 | a = RL(a, 10); 172 | c = RL(c + f1(d, e, a) + X[3], 12) + b; 173 | e = RL(e, 10); 174 | b = RL(b + f1(c, d, e) + X[4], 5) + a; 175 | d = RL(d, 10); 176 | a = RL(a + f1(b, c, d) + X[5], 8) + e; 177 | c = RL(c, 10); 178 | e = RL(e + f1(a, b, c) + X[6], 7) + d; 179 | b = RL(b, 10); 180 | d = RL(d + f1(e, a, b) + X[7], 9) + c; 181 | a = RL(a, 10); 182 | c = RL(c + f1(d, e, a) + X[8], 11) + b; 183 | e = RL(e, 10); 184 | b = RL(b + f1(c, d, e) + X[9], 13) + a; 185 | d = RL(d, 10); 186 | a = RL(a + f1(b, c, d) + X[10], 14) + e; 187 | c = RL(c, 10); 188 | e = RL(e + f1(a, b, c) + X[11], 15) + d; 189 | b = RL(b, 10); 190 | d = RL(d + f1(e, a, b) + X[12], 6) + c; 191 | a = RL(a, 10); 192 | c = RL(c + f1(d, e, a) + X[13], 7) + b; 193 | e = RL(e, 10); 194 | b = RL(b + f1(c, d, e) + X[14], 9) + a; 195 | d = RL(d, 10); 196 | a = RL(a + f1(b, c, d) + X[15], 8) + e; 197 | c = RL(c, 10); 198 | 199 | // right 200 | aa = RL(aa + f5(bb, cc, dd) + X[5] + 0x50a28be6, 8) + ee; 201 | cc = RL(cc, 10); 202 | ee = RL(ee + f5(aa, bb, cc) + X[14] + 0x50a28be6, 9) + dd; 203 | bb = RL(bb, 10); 204 | dd = RL(dd + f5(ee, aa, bb) + X[7] + 0x50a28be6, 9) + cc; 205 | aa = RL(aa, 10); 206 | cc = RL(cc + f5(dd, ee, aa) + X[0] + 0x50a28be6, 11) + bb; 207 | ee = RL(ee, 10); 208 | bb = RL(bb + f5(cc, dd, ee) + X[9] + 0x50a28be6, 13) + aa; 209 | dd = RL(dd, 10); 210 | aa = RL(aa + f5(bb, cc, dd) + X[2] + 0x50a28be6, 15) + ee; 211 | cc = RL(cc, 10); 212 | ee = RL(ee + f5(aa, bb, cc) + X[11] + 0x50a28be6, 15) + dd; 213 | bb = RL(bb, 10); 214 | dd = RL(dd + f5(ee, aa, bb) + X[4] + 0x50a28be6, 5) + cc; 215 | aa = RL(aa, 10); 216 | cc = RL(cc + f5(dd, ee, aa) + X[13] + 0x50a28be6, 7) + bb; 217 | ee = RL(ee, 10); 218 | bb = RL(bb + f5(cc, dd, ee) + X[6] + 0x50a28be6, 7) + aa; 219 | dd = RL(dd, 10); 220 | aa = RL(aa + f5(bb, cc, dd) + X[15] + 0x50a28be6, 8) + ee; 221 | cc = RL(cc, 10); 222 | ee = RL(ee + f5(aa, bb, cc) + X[8] + 0x50a28be6, 11) + dd; 223 | bb = RL(bb, 10); 224 | dd = RL(dd + f5(ee, aa, bb) + X[1] + 0x50a28be6, 14) + cc; 225 | aa = RL(aa, 10); 226 | cc = RL(cc + f5(dd, ee, aa) + X[10] + 0x50a28be6, 14) + bb; 227 | ee = RL(ee, 10); 228 | bb = RL(bb + f5(cc, dd, ee) + X[3] + 0x50a28be6, 12) + aa; 229 | dd = RL(dd, 10); 230 | aa = RL(aa + f5(bb, cc, dd) + X[12] + 0x50a28be6, 6) + ee; 231 | cc = RL(cc, 10); 232 | 233 | // 234 | // Rounds 16-31 235 | // 236 | // left 237 | e = RL(e + f2(a, b, c) + X[7] + 0x5a827999, 7) + d; 238 | b = RL(b, 10); 239 | d = RL(d + f2(e, a, b) + X[4] + 0x5a827999, 6) + c; 240 | a = RL(a, 10); 241 | c = RL(c + f2(d, e, a) + X[13] + 0x5a827999, 8) + b; 242 | e = RL(e, 10); 243 | b = RL(b + f2(c, d, e) + X[1] + 0x5a827999, 13) + a; 244 | d = RL(d, 10); 245 | a = RL(a + f2(b, c, d) + X[10] + 0x5a827999, 11) + e; 246 | c = RL(c, 10); 247 | e = RL(e + f2(a, b, c) + X[6] + 0x5a827999, 9) + d; 248 | b = RL(b, 10); 249 | d = RL(d + f2(e, a, b) + X[15] + 0x5a827999, 7) + c; 250 | a = RL(a, 10); 251 | c = RL(c + f2(d, e, a) + X[3] + 0x5a827999, 15) + b; 252 | e = RL(e, 10); 253 | b = RL(b + f2(c, d, e) + X[12] + 0x5a827999, 7) + a; 254 | d = RL(d, 10); 255 | a = RL(a + f2(b, c, d) + X[0] + 0x5a827999, 12) + e; 256 | c = RL(c, 10); 257 | e = RL(e + f2(a, b, c) + X[9] + 0x5a827999, 15) + d; 258 | b = RL(b, 10); 259 | d = RL(d + f2(e, a, b) + X[5] + 0x5a827999, 9) + c; 260 | a = RL(a, 10); 261 | c = RL(c + f2(d, e, a) + X[2] + 0x5a827999, 11) + b; 262 | e = RL(e, 10); 263 | b = RL(b + f2(c, d, e) + X[14] + 0x5a827999, 7) + a; 264 | d = RL(d, 10); 265 | a = RL(a + f2(b, c, d) + X[11] + 0x5a827999, 13) + e; 266 | c = RL(c, 10); 267 | e = RL(e + f2(a, b, c) + X[8] + 0x5a827999, 12) + d; 268 | b = RL(b, 10); 269 | 270 | // right 271 | ee = RL(ee + f4(aa, bb, cc) + X[6] + 0x5c4dd124, 9) + dd; 272 | bb = RL(bb, 10); 273 | dd = RL(dd + f4(ee, aa, bb) + X[11] + 0x5c4dd124, 13) + cc; 274 | aa = RL(aa, 10); 275 | cc = RL(cc + f4(dd, ee, aa) + X[3] + 0x5c4dd124, 15) + bb; 276 | ee = RL(ee, 10); 277 | bb = RL(bb + f4(cc, dd, ee) + X[7] + 0x5c4dd124, 7) + aa; 278 | dd = RL(dd, 10); 279 | aa = RL(aa + f4(bb, cc, dd) + X[0] + 0x5c4dd124, 12) + ee; 280 | cc = RL(cc, 10); 281 | ee = RL(ee + f4(aa, bb, cc) + X[13] + 0x5c4dd124, 8) + dd; 282 | bb = RL(bb, 10); 283 | dd = RL(dd + f4(ee, aa, bb) + X[5] + 0x5c4dd124, 9) + cc; 284 | aa = RL(aa, 10); 285 | cc = RL(cc + f4(dd, ee, aa) + X[10] + 0x5c4dd124, 11) + bb; 286 | ee = RL(ee, 10); 287 | bb = RL(bb + f4(cc, dd, ee) + X[14] + 0x5c4dd124, 7) + aa; 288 | dd = RL(dd, 10); 289 | aa = RL(aa + f4(bb, cc, dd) + X[15] + 0x5c4dd124, 7) + ee; 290 | cc = RL(cc, 10); 291 | ee = RL(ee + f4(aa, bb, cc) + X[8] + 0x5c4dd124, 12) + dd; 292 | bb = RL(bb, 10); 293 | dd = RL(dd + f4(ee, aa, bb) + X[12] + 0x5c4dd124, 7) + cc; 294 | aa = RL(aa, 10); 295 | cc = RL(cc + f4(dd, ee, aa) + X[4] + 0x5c4dd124, 6) + bb; 296 | ee = RL(ee, 10); 297 | bb = RL(bb + f4(cc, dd, ee) + X[9] + 0x5c4dd124, 15) + aa; 298 | dd = RL(dd, 10); 299 | aa = RL(aa + f4(bb, cc, dd) + X[1] + 0x5c4dd124, 13) + ee; 300 | cc = RL(cc, 10); 301 | ee = RL(ee + f4(aa, bb, cc) + X[2] + 0x5c4dd124, 11) + dd; 302 | bb = RL(bb, 10); 303 | 304 | // 305 | // Rounds 32-47 306 | // 307 | // left 308 | d = RL(d + f3(e, a, b) + X[3] + 0x6ed9eba1, 11) + c; 309 | a = RL(a, 10); 310 | c = RL(c + f3(d, e, a) + X[10] + 0x6ed9eba1, 13) + b; 311 | e = RL(e, 10); 312 | b = RL(b + f3(c, d, e) + X[14] + 0x6ed9eba1, 6) + a; 313 | d = RL(d, 10); 314 | a = RL(a + f3(b, c, d) + X[4] + 0x6ed9eba1, 7) + e; 315 | c = RL(c, 10); 316 | e = RL(e + f3(a, b, c) + X[9] + 0x6ed9eba1, 14) + d; 317 | b = RL(b, 10); 318 | d = RL(d + f3(e, a, b) + X[15] + 0x6ed9eba1, 9) + c; 319 | a = RL(a, 10); 320 | c = RL(c + f3(d, e, a) + X[8] + 0x6ed9eba1, 13) + b; 321 | e = RL(e, 10); 322 | b = RL(b + f3(c, d, e) + X[1] + 0x6ed9eba1, 15) + a; 323 | d = RL(d, 10); 324 | a = RL(a + f3(b, c, d) + X[2] + 0x6ed9eba1, 14) + e; 325 | c = RL(c, 10); 326 | e = RL(e + f3(a, b, c) + X[7] + 0x6ed9eba1, 8) + d; 327 | b = RL(b, 10); 328 | d = RL(d + f3(e, a, b) + X[0] + 0x6ed9eba1, 13) + c; 329 | a = RL(a, 10); 330 | c = RL(c + f3(d, e, a) + X[6] + 0x6ed9eba1, 6) + b; 331 | e = RL(e, 10); 332 | b = RL(b + f3(c, d, e) + X[13] + 0x6ed9eba1, 5) + a; 333 | d = RL(d, 10); 334 | a = RL(a + f3(b, c, d) + X[11] + 0x6ed9eba1, 12) + e; 335 | c = RL(c, 10); 336 | e = RL(e + f3(a, b, c) + X[5] + 0x6ed9eba1, 7) + d; 337 | b = RL(b, 10); 338 | d = RL(d + f3(e, a, b) + X[12] + 0x6ed9eba1, 5) + c; 339 | a = RL(a, 10); 340 | 341 | // right 342 | dd = RL(dd + f3(ee, aa, bb) + X[15] + 0x6d703ef3, 9) + cc; 343 | aa = RL(aa, 10); 344 | cc = RL(cc + f3(dd, ee, aa) + X[5] + 0x6d703ef3, 7) + bb; 345 | ee = RL(ee, 10); 346 | bb = RL(bb + f3(cc, dd, ee) + X[1] + 0x6d703ef3, 15) + aa; 347 | dd = RL(dd, 10); 348 | aa = RL(aa + f3(bb, cc, dd) + X[3] + 0x6d703ef3, 11) + ee; 349 | cc = RL(cc, 10); 350 | ee = RL(ee + f3(aa, bb, cc) + X[7] + 0x6d703ef3, 8) + dd; 351 | bb = RL(bb, 10); 352 | dd = RL(dd + f3(ee, aa, bb) + X[14] + 0x6d703ef3, 6) + cc; 353 | aa = RL(aa, 10); 354 | cc = RL(cc + f3(dd, ee, aa) + X[6] + 0x6d703ef3, 6) + bb; 355 | ee = RL(ee, 10); 356 | bb = RL(bb + f3(cc, dd, ee) + X[9] + 0x6d703ef3, 14) + aa; 357 | dd = RL(dd, 10); 358 | aa = RL(aa + f3(bb, cc, dd) + X[11] + 0x6d703ef3, 12) + ee; 359 | cc = RL(cc, 10); 360 | ee = RL(ee + f3(aa, bb, cc) + X[8] + 0x6d703ef3, 13) + dd; 361 | bb = RL(bb, 10); 362 | dd = RL(dd + f3(ee, aa, bb) + X[12] + 0x6d703ef3, 5) + cc; 363 | aa = RL(aa, 10); 364 | cc = RL(cc + f3(dd, ee, aa) + X[2] + 0x6d703ef3, 14) + bb; 365 | ee = RL(ee, 10); 366 | bb = RL(bb + f3(cc, dd, ee) + X[10] + 0x6d703ef3, 13) + aa; 367 | dd = RL(dd, 10); 368 | aa = RL(aa + f3(bb, cc, dd) + X[0] + 0x6d703ef3, 13) + ee; 369 | cc = RL(cc, 10); 370 | ee = RL(ee + f3(aa, bb, cc) + X[4] + 0x6d703ef3, 7) + dd; 371 | bb = RL(bb, 10); 372 | dd = RL(dd + f3(ee, aa, bb) + X[13] + 0x6d703ef3, 5) + cc; 373 | aa = RL(aa, 10); 374 | 375 | // 376 | // Rounds 48-63 377 | // 378 | // left 379 | c = RL(c + f4(d, e, a) + X[1] + 0x8f1bbcdc, 11) + b; 380 | e = RL(e, 10); 381 | b = RL(b + f4(c, d, e) + X[9] + 0x8f1bbcdc, 12) + a; 382 | d = RL(d, 10); 383 | a = RL(a + f4(b, c, d) + X[11] + 0x8f1bbcdc, 14) + e; 384 | c = RL(c, 10); 385 | e = RL(e + f4(a, b, c) + X[10] + 0x8f1bbcdc, 15) + d; 386 | b = RL(b, 10); 387 | d = RL(d + f4(e, a, b) + X[0] + 0x8f1bbcdc, 14) + c; 388 | a = RL(a, 10); 389 | c = RL(c + f4(d, e, a) + X[8] + 0x8f1bbcdc, 15) + b; 390 | e = RL(e, 10); 391 | b = RL(b + f4(c, d, e) + X[12] + 0x8f1bbcdc, 9) + a; 392 | d = RL(d, 10); 393 | a = RL(a + f4(b, c, d) + X[4] + 0x8f1bbcdc, 8) + e; 394 | c = RL(c, 10); 395 | e = RL(e + f4(a, b, c) + X[13] + 0x8f1bbcdc, 9) + d; 396 | b = RL(b, 10); 397 | d = RL(d + f4(e, a, b) + X[3] + 0x8f1bbcdc, 14) + c; 398 | a = RL(a, 10); 399 | c = RL(c + f4(d, e, a) + X[7] + 0x8f1bbcdc, 5) + b; 400 | e = RL(e, 10); 401 | b = RL(b + f4(c, d, e) + X[15] + 0x8f1bbcdc, 6) + a; 402 | d = RL(d, 10); 403 | a = RL(a + f4(b, c, d) + X[14] + 0x8f1bbcdc, 8) + e; 404 | c = RL(c, 10); 405 | e = RL(e + f4(a, b, c) + X[5] + 0x8f1bbcdc, 6) + d; 406 | b = RL(b, 10); 407 | d = RL(d + f4(e, a, b) + X[6] + 0x8f1bbcdc, 5) + c; 408 | a = RL(a, 10); 409 | c = RL(c + f4(d, e, a) + X[2] + 0x8f1bbcdc, 12) + b; 410 | e = RL(e, 10); 411 | 412 | // right 413 | cc = RL(cc + f2(dd, ee, aa) + X[8] + 0x7a6d76e9, 15) + bb; 414 | ee = RL(ee, 10); 415 | bb = RL(bb + f2(cc, dd, ee) + X[6] + 0x7a6d76e9, 5) + aa; 416 | dd = RL(dd, 10); 417 | aa = RL(aa + f2(bb, cc, dd) + X[4] + 0x7a6d76e9, 8) + ee; 418 | cc = RL(cc, 10); 419 | ee = RL(ee + f2(aa, bb, cc) + X[1] + 0x7a6d76e9, 11) + dd; 420 | bb = RL(bb, 10); 421 | dd = RL(dd + f2(ee, aa, bb) + X[3] + 0x7a6d76e9, 14) + cc; 422 | aa = RL(aa, 10); 423 | cc = RL(cc + f2(dd, ee, aa) + X[11] + 0x7a6d76e9, 14) + bb; 424 | ee = RL(ee, 10); 425 | bb = RL(bb + f2(cc, dd, ee) + X[15] + 0x7a6d76e9, 6) + aa; 426 | dd = RL(dd, 10); 427 | aa = RL(aa + f2(bb, cc, dd) + X[0] + 0x7a6d76e9, 14) + ee; 428 | cc = RL(cc, 10); 429 | ee = RL(ee + f2(aa, bb, cc) + X[5] + 0x7a6d76e9, 6) + dd; 430 | bb = RL(bb, 10); 431 | dd = RL(dd + f2(ee, aa, bb) + X[12] + 0x7a6d76e9, 9) + cc; 432 | aa = RL(aa, 10); 433 | cc = RL(cc + f2(dd, ee, aa) + X[2] + 0x7a6d76e9, 12) + bb; 434 | ee = RL(ee, 10); 435 | bb = RL(bb + f2(cc, dd, ee) + X[13] + 0x7a6d76e9, 9) + aa; 436 | dd = RL(dd, 10); 437 | aa = RL(aa + f2(bb, cc, dd) + X[9] + 0x7a6d76e9, 12) + ee; 438 | cc = RL(cc, 10); 439 | ee = RL(ee + f2(aa, bb, cc) + X[7] + 0x7a6d76e9, 5) + dd; 440 | bb = RL(bb, 10); 441 | dd = RL(dd + f2(ee, aa, bb) + X[10] + 0x7a6d76e9, 15) + cc; 442 | aa = RL(aa, 10); 443 | cc = RL(cc + f2(dd, ee, aa) + X[14] + 0x7a6d76e9, 8) + bb; 444 | ee = RL(ee, 10); 445 | 446 | // 447 | // Rounds 64-79 448 | // 449 | // left 450 | b = RL(b + f5(c, d, e) + X[4] + 0xa953fd4e, 9) + a; 451 | d = RL(d, 10); 452 | a = RL(a + f5(b, c, d) + X[0] + 0xa953fd4e, 15) + e; 453 | c = RL(c, 10); 454 | e = RL(e + f5(a, b, c) + X[5] + 0xa953fd4e, 5) + d; 455 | b = RL(b, 10); 456 | d = RL(d + f5(e, a, b) + X[9] + 0xa953fd4e, 11) + c; 457 | a = RL(a, 10); 458 | c = RL(c + f5(d, e, a) + X[7] + 0xa953fd4e, 6) + b; 459 | e = RL(e, 10); 460 | b = RL(b + f5(c, d, e) + X[12] + 0xa953fd4e, 8) + a; 461 | d = RL(d, 10); 462 | a = RL(a + f5(b, c, d) + X[2] + 0xa953fd4e, 13) + e; 463 | c = RL(c, 10); 464 | e = RL(e + f5(a, b, c) + X[10] + 0xa953fd4e, 12) + d; 465 | b = RL(b, 10); 466 | d = RL(d + f5(e, a, b) + X[14] + 0xa953fd4e, 5) + c; 467 | a = RL(a, 10); 468 | c = RL(c + f5(d, e, a) + X[1] + 0xa953fd4e, 12) + b; 469 | e = RL(e, 10); 470 | b = RL(b + f5(c, d, e) + X[3] + 0xa953fd4e, 13) + a; 471 | d = RL(d, 10); 472 | a = RL(a + f5(b, c, d) + X[8] + 0xa953fd4e, 14) + e; 473 | c = RL(c, 10); 474 | e = RL(e + f5(a, b, c) + X[11] + 0xa953fd4e, 11) + d; 475 | b = RL(b, 10); 476 | d = RL(d + f5(e, a, b) + X[6] + 0xa953fd4e, 8) + c; 477 | a = RL(a, 10); 478 | c = RL(c + f5(d, e, a) + X[15] + 0xa953fd4e, 5) + b; 479 | e = RL(e, 10); 480 | b = RL(b + f5(c, d, e) + X[13] + 0xa953fd4e, 6) + a; 481 | d = RL(d, 10); 482 | 483 | // right 484 | bb = RL(bb + f1(cc, dd, ee) + X[12], 8) + aa; 485 | dd = RL(dd, 10); 486 | aa = RL(aa + f1(bb, cc, dd) + X[15], 5) + ee; 487 | cc = RL(cc, 10); 488 | ee = RL(ee + f1(aa, bb, cc) + X[10], 12) + dd; 489 | bb = RL(bb, 10); 490 | dd = RL(dd + f1(ee, aa, bb) + X[4], 9) + cc; 491 | aa = RL(aa, 10); 492 | cc = RL(cc + f1(dd, ee, aa) + X[1], 12) + bb; 493 | ee = RL(ee, 10); 494 | bb = RL(bb + f1(cc, dd, ee) + X[5], 5) + aa; 495 | dd = RL(dd, 10); 496 | aa = RL(aa + f1(bb, cc, dd) + X[8], 14) + ee; 497 | cc = RL(cc, 10); 498 | ee = RL(ee + f1(aa, bb, cc) + X[7], 6) + dd; 499 | bb = RL(bb, 10); 500 | dd = RL(dd + f1(ee, aa, bb) + X[6], 8) + cc; 501 | aa = RL(aa, 10); 502 | cc = RL(cc + f1(dd, ee, aa) + X[2], 13) + bb; 503 | ee = RL(ee, 10); 504 | bb = RL(bb + f1(cc, dd, ee) + X[13], 6) + aa; 505 | dd = RL(dd, 10); 506 | aa = RL(aa + f1(bb, cc, dd) + X[14], 5) + ee; 507 | cc = RL(cc, 10); 508 | ee = RL(ee + f1(aa, bb, cc) + X[0], 15) + dd; 509 | bb = RL(bb, 10); 510 | dd = RL(dd + f1(ee, aa, bb) + X[3], 13) + cc; 511 | aa = RL(aa, 10); 512 | cc = RL(cc + f1(dd, ee, aa) + X[9], 11) + bb; 513 | ee = RL(ee, 10); 514 | bb = RL(bb + f1(cc, dd, ee) + X[11], 11) + aa; 515 | dd = RL(dd, 10); 516 | 517 | dd += c + H1; 518 | H1 = H2 + d + ee; 519 | H2 = H3 + e + aa; 520 | H3 = H4 + a + bb; 521 | H4 = H0 + b + cc; 522 | H0 = dd; 523 | 524 | // 525 | // reset the offset and clean out the word buffer. 526 | // 527 | xOff = 0; 528 | for (int i = 0; i != X.length; i++) { 529 | X[i] = 0; 530 | } 531 | } 532 | } 533 | } 534 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/digest/Sha.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.digest; 2 | 3 | 4 | import com.develop.wallet.eos.utils.EException; 5 | 6 | import javax.crypto.Mac; 7 | import javax.crypto.spec.SecretKeySpec; 8 | import java.security.InvalidKeyException; 9 | import java.security.MessageDigest; 10 | import java.security.NoSuchAlgorithmException; 11 | 12 | /** 13 | * SHA 14 | * 15 | * @author espritblock http://eblock.io 16 | */ 17 | public class Sha { 18 | 19 | public static final String SHA256 = "SHA-256"; 20 | 21 | /** 22 | * sha256 23 | * 24 | * @param text 25 | * @return 26 | */ 27 | public static byte[] SHA256(final String text) { 28 | if (text == null || text.length() == 0) { 29 | throw new EException("args_empty", "args is empty"); 30 | } 31 | try { 32 | MessageDigest messageDigest = MessageDigest.getInstance(SHA256); 33 | messageDigest.update(text.getBytes("utf8")); 34 | byte byteBuffer[] = messageDigest.digest(); 35 | return byteBuffer; 36 | } catch (NoSuchAlgorithmException e) { 37 | e.printStackTrace(); 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | return null; 42 | } 43 | 44 | /** 45 | * sha256 46 | * 47 | * @return 48 | */ 49 | public static byte[] SHA256(final byte[] b) { 50 | if (b == null || b.length == 0) { 51 | throw new EException("args_empty", "args is empty"); 52 | } 53 | try { 54 | MessageDigest messageDigest = MessageDigest.getInstance(SHA256); 55 | messageDigest.update(b); 56 | byte byteBuffer[] = messageDigest.digest(); 57 | return byteBuffer; 58 | } catch (NoSuchAlgorithmException e) { 59 | e.printStackTrace(); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | return null; 64 | } 65 | 66 | /** 67 | * HMACSHA256 68 | * 69 | * @param data 70 | * @param key 71 | * @return 72 | */ 73 | public static byte[] HmacSHA256(byte[] data, byte[] key) { 74 | try { 75 | SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256"); 76 | Mac mac = Mac.getInstance("HmacSHA256"); 77 | mac.init(signingKey); 78 | return mac.doFinal(data); 79 | } catch (NoSuchAlgorithmException e) { 80 | e.printStackTrace(); 81 | } catch (InvalidKeyException e) { 82 | e.printStackTrace(); 83 | } 84 | return null; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/utils/Base58.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.utils; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.math.BigInteger; 5 | 6 | public class Base58 { 7 | 8 | public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); 9 | 10 | private static final int[] INDEXES = new int[128]; 11 | 12 | static { 13 | for (int i = 0; i < INDEXES.length; i++) { 14 | INDEXES[i] = -1; 15 | } 16 | for (int i = 0; i < ALPHABET.length; i++) { 17 | INDEXES[ALPHABET[i]] = i; 18 | } 19 | } 20 | 21 | /** 22 | * encode 23 | * 24 | * @param input 25 | * @return 26 | */ 27 | public static String encode(byte[] input) { 28 | if (input.length == 0) { 29 | return ""; 30 | } 31 | input = copyOfRange(input, 0, input.length); 32 | int zeroCount = 0; 33 | while (zeroCount < input.length && input[zeroCount] == 0) { 34 | ++zeroCount; 35 | } 36 | byte[] temp = new byte[input.length * 2]; 37 | int j = temp.length; 38 | int startAt = zeroCount; 39 | while (startAt < input.length) { 40 | byte mod = divmod58(input, startAt); 41 | if (input[startAt] == 0) { 42 | ++startAt; 43 | } 44 | temp[--j] = (byte) ALPHABET[mod]; 45 | } 46 | while (j < temp.length && temp[j] == ALPHABET[0]) { 47 | ++j; 48 | } 49 | while (--zeroCount >= 0) { 50 | temp[--j] = (byte) ALPHABET[0]; 51 | } 52 | byte[] output = copyOfRange(temp, j, temp.length); 53 | try { 54 | return new String(output, "US-ASCII"); 55 | } catch (UnsupportedEncodingException e) { 56 | throw new RuntimeException(e); // Cannot happen. 57 | } 58 | } 59 | 60 | /** 61 | * decode 62 | * 63 | * @param input 64 | * @return 65 | * @throws IllegalArgumentException 66 | */ 67 | public static byte[] decode(String input) throws IllegalArgumentException { 68 | if (input.length() == 0) { 69 | return new byte[0]; 70 | } 71 | byte[] input58 = new byte[input.length()]; 72 | for (int i = 0; i < input.length(); ++i) { 73 | char c = input.charAt(i); 74 | int digit58 = -1; 75 | if (c >= 0 && c < 128) { 76 | digit58 = INDEXES[c]; 77 | } 78 | if (digit58 < 0) { 79 | throw new IllegalArgumentException("Illegal character " + c + " at " + i); 80 | } 81 | input58[i] = (byte) digit58; 82 | } 83 | int zeroCount = 0; 84 | while (zeroCount < input58.length && input58[zeroCount] == 0) { 85 | ++zeroCount; 86 | } 87 | byte[] temp = new byte[input.length()]; 88 | int j = temp.length; 89 | int startAt = zeroCount; 90 | while (startAt < input58.length) { 91 | byte mod = divmod256(input58, startAt); 92 | if (input58[startAt] == 0) { 93 | ++startAt; 94 | } 95 | temp[--j] = mod; 96 | } 97 | while (j < temp.length && temp[j] == 0) { 98 | ++j; 99 | } 100 | return copyOfRange(temp, j - zeroCount, temp.length); 101 | } 102 | 103 | /** 104 | * decodeToBigInteger 105 | * 106 | * @param input 107 | * @return 108 | * @throws IllegalArgumentException 109 | */ 110 | public static BigInteger decodeToBigInteger(String input) throws IllegalArgumentException { 111 | return new BigInteger(1, decode(input)); 112 | } 113 | 114 | /** 115 | * divmod58 116 | * 117 | * @param number 118 | * @param startAt 119 | * @return 120 | */ 121 | private static byte divmod58(byte[] number, int startAt) { 122 | int remainder = 0; 123 | for (int i = startAt; i < number.length; i++) { 124 | int digit256 = (int) number[i] & 0xFF; 125 | int temp = remainder * 256 + digit256; 126 | number[i] = (byte) (temp / 58); 127 | remainder = temp % 58; 128 | } 129 | return (byte) remainder; 130 | } 131 | 132 | /** 133 | * divmod256 134 | * 135 | * @param number58 136 | * @param startAt 137 | * @return 138 | */ 139 | private static byte divmod256(byte[] number58, int startAt) { 140 | int remainder = 0; 141 | for (int i = startAt; i < number58.length; i++) { 142 | int digit58 = (int) number58[i] & 0xFF; 143 | int temp = remainder * 58 + digit58; 144 | number58[i] = (byte) (temp / 256); 145 | remainder = temp % 256; 146 | } 147 | return (byte) remainder; 148 | } 149 | 150 | /** 151 | * copyOfRange 152 | * 153 | * @param source 154 | * @param from 155 | * @param to 156 | * @return 157 | */ 158 | private static byte[] copyOfRange(byte[] source, int from, int to) { 159 | byte[] range = new byte[to - from]; 160 | System.arraycopy(source, from, range, 0, range.length); 161 | return range; 162 | } 163 | } -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/utils/ByteBuffer.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.utils; 2 | 3 | /** 4 | * @author espritblock http://eblock.io 5 | */ 6 | public class ByteBuffer { 7 | 8 | private byte[] buffer = new byte[]{}; 9 | 10 | public void concat(byte[] b) { 11 | 12 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 13 | // for(int i=1;i<=a.length;i++) { 14 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 15 | // } 16 | buffer = ByteUtils.concat(buffer, b); 17 | } 18 | 19 | public byte[] getBuffer() { 20 | return buffer; 21 | } 22 | 23 | public void setBuffer(byte[] buffer) { 24 | this.buffer = buffer; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/crypto/utils/ByteUtils.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.crypto.utils; 2 | 3 | import com.develop.wallet.eos.utils.EException; 4 | 5 | import java.math.BigInteger; 6 | import java.nio.ByteBuffer; 7 | import java.nio.ByteOrder; 8 | 9 | /** 10 | * @author espritblock http://eblock.io 11 | */ 12 | public class ByteUtils { 13 | 14 | static String charmap = ".12345abcdefghijklmnopqrstuvwxyz"; 15 | 16 | /** 17 | * charidx 18 | * 19 | * @param c 20 | * @return 21 | */ 22 | public static int charidx(char c) { 23 | return charmap.indexOf(c); 24 | } 25 | 26 | /** 27 | * concat 28 | * 29 | * @param a 30 | * @param b 31 | * @return 32 | */ 33 | public static byte[] concat(byte[] a, byte[] b) { 34 | byte[] c = new byte[a.length + b.length]; 35 | System.arraycopy(a, 0, c, 0, a.length); 36 | System.arraycopy(b, 0, c, a.length, b.length); 37 | return c; 38 | } 39 | 40 | /** 41 | * copy 42 | * 43 | * @return 44 | */ 45 | public static byte[] copy(byte[] src, int start, int length) { 46 | byte[] c = new byte[length]; 47 | System.arraycopy(src, start, c, 0, length); 48 | return c; 49 | } 50 | 51 | /** 52 | * copy 53 | * 54 | * @return 55 | */ 56 | public static byte[] copy(byte[] src, int start, byte[] dest, int dstart, int length) { 57 | System.arraycopy(src, start, dest, dstart, length); 58 | return dest; 59 | } 60 | 61 | /** 62 | * LongToBytes 63 | * 64 | * @return 65 | */ 66 | public static int[] LongToBytes(Long n) { 67 | ByteBuffer hi = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.BIG_ENDIAN).putLong(n); 68 | byte[] buf = hi.array(); 69 | // for java 8 70 | // int[] a = IntStream.range(0, buf.length).map(i -> buf[i] & 0xff).toArray(); 71 | int[] a = new int[buf.length]; 72 | for (int i = 0; i < buf.length; i++) { 73 | a[i] = buf[i] & 0xFF; 74 | } 75 | return a; 76 | } 77 | 78 | /** 79 | * @param value 80 | * @return 81 | */ 82 | public static String stringToAscii(String value) { 83 | StringBuffer sbu = new StringBuffer(); 84 | char[] chars = value.toCharArray(); 85 | for (int i = 0; i < chars.length; i++) { 86 | if (i != chars.length - 1) { 87 | sbu.append((int) chars[i]); 88 | } else { 89 | sbu.append((int) chars[i]); 90 | } 91 | } 92 | return sbu.toString(); 93 | } 94 | 95 | /** 96 | * writerUnit32 97 | * 98 | * @param value 99 | * @return 100 | */ 101 | public static byte[] writerUnit32(String value) { 102 | 103 | Long l = Long.parseLong(value); 104 | if (l > Integer.MAX_VALUE) { 105 | byte[] b = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(l).array(); 106 | int j = 0; 107 | for (int i = b.length - 1; i >= 0; i--) { 108 | if (b[i] == (byte) 0) { 109 | j++; 110 | } else { 111 | break; 112 | } 113 | } 114 | return ByteUtils.copy(b, 0, b.length - j); 115 | } else { 116 | return ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(Integer.parseInt(value)) 117 | .array(); 118 | } 119 | } 120 | 121 | /** 122 | * writerUnit16 123 | * 124 | * @param value 125 | * @return 126 | */ 127 | public static byte[] writerUnit16(String value) { 128 | long vl = Long.parseLong(value); 129 | return new byte[]{(byte) (vl & 0x00FF), (byte) ((vl & 0xFF00) >>> 8)}; 130 | } 131 | 132 | /** 133 | * writerUnit8 134 | * 135 | * @param value 136 | * @return 137 | */ 138 | public static byte[] writerUnit8(String value) { 139 | long vl = Long.parseLong(value); 140 | return new byte[]{(byte) (vl & 0x00FF)}; 141 | } 142 | 143 | /** 144 | * writerVarint32 145 | * 146 | * @param v 147 | * @return 148 | */ 149 | public static byte[] writerVarint32(String v) { 150 | long value = Long.parseLong(v); 151 | byte[] a = new byte[]{}; 152 | value >>>= 0; 153 | while (value >= 0x80) { 154 | long b = (value & 0x7f) | 0x80; 155 | a = ByteUtils.concat(a, new byte[]{(byte) b}); 156 | value >>>= 7; 157 | } 158 | a = ByteUtils.concat(a, new byte[]{(byte) value}); 159 | return a; 160 | } 161 | 162 | /** 163 | * writerAsset 164 | * 165 | * @param v 166 | * @return 167 | */ 168 | public static byte[] writerAsset(String v) { 169 | String _value[] = v.split(" "); 170 | String amount = _value[0]; 171 | if (amount == null || !amount.matches("^[0-9]+(.[0-9]+)?$")) { 172 | throw new EException("amount_error", "amount error"); 173 | } 174 | String sym = _value[1]; 175 | String precision = sym.split(",")[0]; 176 | String symbol = sym.split(",")[1].split("@")[0]; 177 | String[] part = amount.split("[.]"); 178 | 179 | int pad = Integer.parseInt(precision); 180 | StringBuffer bf = new StringBuffer(part[0] + "."); 181 | if (part.length > 1) { 182 | if (part[1].length() > pad) { 183 | throw new EException("precision_error", "precision max " + pad); 184 | } 185 | pad = Integer.parseInt(precision) - part[1].length(); 186 | bf.append(part[1]); 187 | } 188 | // ���Ȳ�0 189 | for (int i = 0; i < pad; i++) { 190 | bf.append("0"); 191 | } 192 | String asset = precision + "," + symbol; 193 | // amount 194 | amount = bf.toString().replace(".", ""); 195 | ByteBuffer ammount = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN) 196 | .putLong(Long.parseLong(amount)); 197 | 198 | // asset 199 | StringBuffer padStr = new StringBuffer(); 200 | for (int i = 0; i < (7 - symbol.length()); i++) { 201 | padStr.append("\0"); 202 | } 203 | char c = (char) Integer.parseInt(precision); 204 | asset = c + symbol + padStr; 205 | ByteBuffer ba = ByteBuffer.wrap(asset.getBytes()); 206 | return ByteUtils.concat(ammount.array(), ba.array()); 207 | } 208 | 209 | /** 210 | * writerAsset 211 | * 212 | * @param v 213 | * @return 214 | */ 215 | public static byte[] writerSymbol(String v) { 216 | String _value[] = v.split(" "); 217 | String amount = _value[0]; 218 | if (amount == null || !amount.matches("^[0-9]+(.[0-9]+)?$")) { 219 | throw new EException("amount_error", "amount error"); 220 | } 221 | String sym = _value[1]; 222 | String precision = sym.split(",")[0]; 223 | String symbol = sym.split(",")[1].split("@")[0]; 224 | String[] part = amount.split("[.]"); 225 | 226 | int pad = Integer.parseInt(precision); 227 | StringBuffer bf = new StringBuffer(part[0] + "."); 228 | if (part.length > 1) { 229 | if (part[1].length() > pad) { 230 | throw new EException("precision_error", "precision max " + pad); 231 | } 232 | pad = Integer.parseInt(precision) - part[1].length(); 233 | bf.append(part[1]); 234 | } 235 | // ���Ȳ�0 236 | for (int i = 0; i < pad; i++) { 237 | bf.append("0"); 238 | } 239 | String asset = precision + "," + symbol; 240 | // amount 241 | // amount = bf.toString().replace(".", ""); 242 | // ByteBuffer ammount = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN) 243 | // .putLong(Long.parseLong(amount)); 244 | 245 | // asset 246 | StringBuffer padStr = new StringBuffer(); 247 | for (int i = 0; i < (7 - symbol.length()); i++) { 248 | padStr.append("\0"); 249 | } 250 | char c = (char) Integer.parseInt(precision); 251 | asset = c + symbol + padStr; 252 | ByteBuffer ba = ByteBuffer.wrap(asset.getBytes()); 253 | return ba.array(); 254 | } 255 | 256 | /** 257 | * writerAccount 258 | * 259 | * @param v 260 | * @return 261 | */ 262 | public static byte[] writeName(String v) { 263 | StringBuffer bitstr = new StringBuffer(); 264 | for (int i = 0; i <= 12; i++) { 265 | int c = i < v.length() ? ByteUtils.charidx(v.charAt(i)) : 0; 266 | int bitlen = i < 12 ? 5 : 4; 267 | String bits = Integer.toBinaryString(c); 268 | if (bits.length() > bitlen) { 269 | throw new EException("", "Invalid name " + v); 270 | } 271 | StringBuffer sb = new StringBuffer(""); 272 | for (int j = 0; j < bitlen - bits.length(); j++) { 273 | sb.append("0"); 274 | } 275 | bits = sb + bits; 276 | bitstr.append(bits); 277 | } 278 | BigInteger lv = new BigInteger(bitstr.toString(), 2); 279 | StringBuffer leHex = new StringBuffer(); 280 | int bytes[] = ByteUtils.LongToBytes(lv.longValue()); 281 | for (int i = 0; i < bytes.length; i++) { 282 | int b = bytes[i]; 283 | String n = Integer.toHexString(b); 284 | leHex.append(n.length() == 1 ? "0" : "").append(n); 285 | } 286 | BigInteger ulName = new BigInteger(leHex.toString(), 16); 287 | return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(ulName.longValue()).array(); 288 | } 289 | 290 | /** 291 | * charCount 292 | * 293 | * @return 294 | */ 295 | private static long charCount(String v) { 296 | long c = 0; 297 | for (char cp : v.toCharArray()) { 298 | if (cp < 0x80) { 299 | c += 1; 300 | } else if (cp < 0x800) { 301 | c += 2; 302 | } else if (cp < 0x10000) { 303 | c += 3; 304 | } else { 305 | c += 4; 306 | } 307 | } 308 | return c; 309 | } 310 | 311 | /** 312 | * writerString 313 | * 314 | * @param v 315 | * @return 316 | */ 317 | public static byte[] writerString(String v) { 318 | long value = charCount(v); 319 | byte[] a = new byte[]{}; 320 | value >>>= 0; 321 | while (value >= 0x80) { 322 | long b = (value & 0x7f) | 0x80; 323 | a = ByteUtils.concat(a, new byte[]{(byte) b}); 324 | value >>>= 7; 325 | } 326 | a = ByteUtils.concat(a, new byte[]{(byte) value}); 327 | for (char c : v.toCharArray()) { 328 | a = ByteUtils.concat(a, decodeChar(c)); 329 | } 330 | return a; 331 | } 332 | 333 | /** 334 | * decodeChar 335 | * 336 | * @param ca 337 | * @return 338 | */ 339 | private static byte[] decodeChar(char ca) { 340 | long cp = (long) ca; 341 | if (cp < 0x80) { 342 | long a = cp & 0x7F; 343 | return new byte[]{(byte) a}; 344 | } else if (cp < 0x800) { 345 | long a = ((cp >> 6) & 0x1F) | 0xC0; 346 | long b = (cp & 0x3F) | 0x80; 347 | return new byte[]{(byte) a, (byte) b}; 348 | } else if (cp < 0x10000) { 349 | long a = ((cp >> 12) & 0x0F) | 0xE0; 350 | long b = ((cp >> 6) & 0x3F) | 0x80; 351 | long c = (cp & 0x3F) | 0x80; 352 | return new byte[]{(byte) a, (byte) b, (byte) c}; 353 | } else { 354 | long a = ((cp >> 18) & 0x07) | 0xF0; 355 | long b = ((cp >> 12) & 0x3F) | 0x80; 356 | long c = ((cp >> 6) & 0x3F) | 0x80; 357 | long d = (cp & 0x3F) | 0x80; 358 | return new byte[]{(byte) a, (byte) b, (byte) c, (byte) d}; 359 | } 360 | } 361 | 362 | /** 363 | * writerKey 364 | * 365 | * @param v 366 | * @return 367 | */ 368 | private static byte[] writerKeyStr(String v) { 369 | v = v.replace("EOS", ""); 370 | byte[] b = Base58.decode(v); 371 | b = ByteBuffer.allocate(b.length).order(ByteOrder.BIG_ENDIAN).put(b).array(); 372 | byte[] key = ByteUtils.copy(b, 0, b.length - 4); 373 | return key; 374 | } 375 | 376 | /** 377 | * writerKey 378 | * 379 | * @param key 380 | */ 381 | public static byte[] writerKey(String key) { 382 | com.develop.wallet.eos.crypto.utils.ByteBuffer bf = new com.develop.wallet.eos.crypto.utils.ByteBuffer(); 383 | bf.concat(writerUnit32("1")); 384 | bf.concat(writerVarint32("1")); 385 | bf.concat(writerVarint32("0")); 386 | bf.concat(writerKeyStr(key)); 387 | bf.concat(writerUnit16("1")); 388 | bf.concat(writerVarint32("0")); 389 | bf.concat(writerVarint32("0")); 390 | return bf.getBuffer(); 391 | } 392 | 393 | public static byte[] writeUint64(String v) { 394 | return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(Long.parseLong(v)).array(); 395 | } 396 | 397 | } 398 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/BaseVo.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | public class BaseVo { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/Block.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author espritblock http://eblock.io 10 | */ 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class Block { 13 | 14 | @JsonProperty("timestamp") 15 | private Date timestamp; 16 | 17 | @JsonProperty("producer") 18 | private String producer; 19 | 20 | @JsonProperty("confirmed") 21 | private Long confirmed; 22 | 23 | @JsonProperty("previous") 24 | private String previous; 25 | 26 | @JsonProperty("transaction_mroot") 27 | private String transactionMroot; 28 | 29 | @JsonProperty("action_mroot") 30 | private String actionMroot; 31 | 32 | @JsonProperty("schedule_version") 33 | private String scheduleVersion; 34 | 35 | @JsonProperty("id") 36 | private String id; 37 | 38 | @JsonProperty("block_num") 39 | private Long blockNum; 40 | 41 | @JsonProperty("ref_block_prefix") 42 | private Long refBlockPrefix; 43 | 44 | public Block() { 45 | 46 | } 47 | 48 | public Date getTimestamp() { 49 | return timestamp; 50 | } 51 | 52 | public void setTimestamp(Date timestamp) { 53 | this.timestamp = timestamp; 54 | } 55 | 56 | public String getProducer() { 57 | return producer; 58 | } 59 | 60 | public void setProducer(String producer) { 61 | this.producer = producer; 62 | } 63 | 64 | public Long getConfirmed() { 65 | return confirmed; 66 | } 67 | 68 | public void setConfirmed(Long confirmed) { 69 | this.confirmed = confirmed; 70 | } 71 | 72 | public String getPrevious() { 73 | return previous; 74 | } 75 | 76 | public void setPrevious(String previous) { 77 | this.previous = previous; 78 | } 79 | 80 | public String getTransactionMroot() { 81 | return transactionMroot; 82 | } 83 | 84 | public void setTransactionMroot(String transactionMroot) { 85 | this.transactionMroot = transactionMroot; 86 | } 87 | 88 | public String getActionMroot() { 89 | return actionMroot; 90 | } 91 | 92 | public void setActionMroot(String actionMroot) { 93 | this.actionMroot = actionMroot; 94 | } 95 | 96 | public String getScheduleVersion() { 97 | return scheduleVersion; 98 | } 99 | 100 | public void setScheduleVersion(String scheduleVersion) { 101 | this.scheduleVersion = scheduleVersion; 102 | } 103 | 104 | public String getId() { 105 | return id; 106 | } 107 | 108 | public void setId(String id) { 109 | this.id = id; 110 | } 111 | 112 | public Long getBlockNum() { 113 | return blockNum; 114 | } 115 | 116 | public void setBlockNum(Long blockNum) { 117 | this.blockNum = blockNum; 118 | } 119 | 120 | public Long getRefBlockPrefix() { 121 | return refBlockPrefix; 122 | } 123 | 124 | public void setRefBlockPrefix(Long refBlockPrefix) { 125 | this.refBlockPrefix = refBlockPrefix; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/ChainInfo.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.text.DateFormat; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Calendar; 9 | import java.util.Date; 10 | 11 | /** 12 | * @author espritblock http://eblock.io 13 | */ 14 | @JsonIgnoreProperties(ignoreUnknown = true) 15 | public class ChainInfo { 16 | 17 | public ChainInfo() { 18 | 19 | } 20 | 21 | @JsonProperty("server_version") 22 | private String serverVersion; 23 | 24 | @JsonProperty("chain_id") 25 | private String chainId; 26 | 27 | @JsonProperty("head_block_num") 28 | private String headBlockNum; 29 | 30 | @JsonProperty("last_irreversible_block_num") 31 | private Long lastIrreversibleBlockNum; 32 | 33 | @JsonProperty("last_irreversible_block_id") 34 | private String lastIrreversibleBlockId; 35 | 36 | @JsonProperty("head_block_id") 37 | private String headBlockId; 38 | 39 | @JsonProperty("head_block_time") 40 | private Date headBlockTime; 41 | 42 | @JsonProperty("head_block_producer") 43 | private String headBlockProducer; 44 | 45 | @JsonProperty("virtual_block_cpu_limit") 46 | private String virtualBlockCpuLimit; 47 | 48 | @JsonProperty("virtual_block_net_limit") 49 | private String virtualBlockNetLimit; 50 | 51 | @JsonProperty("block_cpu_limit") 52 | private String blockCpuLimit; 53 | 54 | @JsonProperty("block_net_limit") 55 | private String blockNetLimit; 56 | 57 | public String getServerVersion() { 58 | return serverVersion; 59 | } 60 | 61 | public void setServerVersion(String serverVersion) { 62 | this.serverVersion = serverVersion; 63 | } 64 | 65 | public String getChainId() { 66 | return chainId; 67 | } 68 | 69 | public void setChainId(String chainId) { 70 | this.chainId = chainId; 71 | } 72 | 73 | public String getHeadBlockNum() { 74 | return headBlockNum; 75 | } 76 | 77 | public void setHeadBlockNum(String headBlockNum) { 78 | this.headBlockNum = headBlockNum; 79 | } 80 | 81 | public Long getLastIrreversibleBlockNum() { 82 | return lastIrreversibleBlockNum; 83 | } 84 | 85 | public void setLastIrreversibleBlockNum(Long lastIrreversibleBlockNum) { 86 | this.lastIrreversibleBlockNum = lastIrreversibleBlockNum; 87 | } 88 | 89 | public String getLastIrreversibleBlockId() { 90 | return lastIrreversibleBlockId; 91 | } 92 | 93 | public void setLastIrreversibleBlockId(String lastIrreversibleBlockId) { 94 | this.lastIrreversibleBlockId = lastIrreversibleBlockId; 95 | } 96 | 97 | public Date getHeadBlockTime() { 98 | return headBlockTime; 99 | } 100 | 101 | public void setHeadBlockTime(Date headBlockTime) { 102 | this.headBlockTime = headBlockTime; 103 | } 104 | 105 | public String getHeadBlockProducer() { 106 | return headBlockProducer; 107 | } 108 | 109 | public void setHeadBlockProducer(String headBlockProducer) { 110 | this.headBlockProducer = headBlockProducer; 111 | } 112 | 113 | public String getVirtualBlockCpuLimit() { 114 | return virtualBlockCpuLimit; 115 | } 116 | 117 | public void setVirtualBlockCpuLimit(String virtualBlockCpuLimit) { 118 | this.virtualBlockCpuLimit = virtualBlockCpuLimit; 119 | } 120 | 121 | public String getVirtualBlockNetLimit() { 122 | return virtualBlockNetLimit; 123 | } 124 | 125 | public void setVirtualBlockNetLimit(String virtualBlockNetLimit) { 126 | this.virtualBlockNetLimit = virtualBlockNetLimit; 127 | } 128 | 129 | public String getBlockCpuLimit() { 130 | return blockCpuLimit; 131 | } 132 | 133 | public void setBlockCpuLimit(String blockCpuLimit) { 134 | this.blockCpuLimit = blockCpuLimit; 135 | } 136 | 137 | public String getBlockNetLimit() { 138 | return blockNetLimit; 139 | } 140 | 141 | public void setBlockNetLimit(String blockNetLimit) { 142 | this.blockNetLimit = blockNetLimit; 143 | } 144 | 145 | public String getHeadBlockId() { 146 | return headBlockId; 147 | } 148 | 149 | public void setHeadBlockId(String headBlockId) { 150 | this.headBlockId = headBlockId; 151 | } 152 | 153 | public Date getTimeAfterHeadBlockTime(int diffInMilSec) { 154 | DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 155 | try { 156 | Date date = headBlockTime; 157 | 158 | Calendar c = Calendar.getInstance(); 159 | c.setTime(date); 160 | c.add(Calendar.MILLISECOND, diffInMilSec); 161 | date = c.getTime(); 162 | 163 | return date; 164 | 165 | } catch (Exception e) { 166 | e.printStackTrace(); 167 | return null; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/JsonToBin.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class JsonToBin { 10 | 11 | private String binargs; 12 | 13 | private List required_scope; 14 | 15 | private List required_auth; 16 | 17 | public String getBinargs() { 18 | return binargs == null ? "" : binargs; 19 | } 20 | 21 | public void setBinargs(String binargs) { 22 | this.binargs = binargs; 23 | } 24 | 25 | public List getRequired_scope() { 26 | if (required_scope == null) { 27 | return new ArrayList<>(); 28 | } 29 | return required_scope; 30 | } 31 | 32 | public void setRequired_scope(List required_scope) { 33 | this.required_scope = required_scope; 34 | } 35 | 36 | public List getRequired_auth() { 37 | if (required_auth == null) { 38 | return new ArrayList<>(); 39 | } 40 | return required_auth; 41 | } 42 | 43 | public void setRequired_auth(List required_auth) { 44 | this.required_auth = required_auth; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/JsonToBinReq.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class JsonToBinReq { 7 | private String code; 8 | 9 | private String action; 10 | 11 | private UpTransfer args; 12 | 13 | public JsonToBinReq(String code, String action, UpTransfer args) { 14 | this.code = code; 15 | this.action = action; 16 | this.args = args; 17 | } 18 | 19 | public String getCode() { 20 | return code; 21 | } 22 | 23 | public void setCode(String code) { 24 | this.code = code; 25 | } 26 | 27 | public String getAction() { 28 | return action; 29 | } 30 | 31 | public void setAction(String action) { 32 | this.action = action; 33 | } 34 | 35 | public UpTransfer getArgs() { 36 | return args; 37 | } 38 | 39 | public void setArgs(UpTransfer args) { 40 | this.args = args; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/SignParam.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * @author espritblock http://eblock.io 7 | */ 8 | public class SignParam { 9 | /** 10 | * 最新区块时间 11 | */ 12 | private Date headBlockTime; 13 | /** 14 | * 链ID 15 | */ 16 | private String chainId; 17 | /** 18 | * 不可逆区块 19 | */ 20 | private Long lastIrreversibleBlockNum; 21 | /** 22 | * 上一个区块hash前缀 23 | */ 24 | private Long refBlockPrefix; 25 | /** 26 | * 过期时间 27 | */ 28 | private Long exp; 29 | 30 | public Date getHeadBlockTime() { 31 | return headBlockTime; 32 | } 33 | 34 | public void setHeadBlockTime(Date headBlockTime) { 35 | this.headBlockTime = headBlockTime; 36 | } 37 | 38 | public String getChainId() { 39 | return chainId; 40 | } 41 | 42 | public void setChainId(String chainId) { 43 | this.chainId = chainId; 44 | } 45 | 46 | public Long getLastIrreversibleBlockNum() { 47 | return lastIrreversibleBlockNum; 48 | } 49 | 50 | public void setLastIrreversibleBlockNum(Long lastIrreversibleBlockNum) { 51 | this.lastIrreversibleBlockNum = lastIrreversibleBlockNum; 52 | } 53 | 54 | public Long getRefBlockPrefix() { 55 | return refBlockPrefix; 56 | } 57 | 58 | public void setRefBlockPrefix(Long refBlockPrefix) { 59 | this.refBlockPrefix = refBlockPrefix; 60 | } 61 | 62 | public Long getExp() { 63 | return exp; 64 | } 65 | 66 | public void setExp(Long exp) { 67 | this.exp = exp; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/TableRows.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class TableRows { 10 | 11 | private Boolean more; 12 | 13 | private List rows; 14 | 15 | public Boolean getMore() { 16 | return more; 17 | } 18 | 19 | public void setMore(Boolean more) { 20 | this.more = more; 21 | } 22 | 23 | public List getRows() { 24 | return rows; 25 | } 26 | 27 | public void setRows(List rows) { 28 | this.rows = rows; 29 | } 30 | 31 | public String getRowValue(String key) { 32 | if (rows != null && !rows.isEmpty()) { 33 | Object obj = rows.get(0).get(key); 34 | if (obj != null) { 35 | return obj.toString(); 36 | } 37 | } 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/TableRowsReq.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class TableRowsReq { 7 | 8 | private String code = "eosio"; 9 | 10 | private String scope; 11 | 12 | private String table; 13 | 14 | private Boolean json = true; 15 | 16 | private int limit = 10; 17 | 18 | public TableRowsReq(String code, String scope, String table) { 19 | this.code = code; 20 | this.scope = scope; 21 | this.table = table; 22 | } 23 | 24 | public String getCode() { 25 | return code; 26 | } 27 | 28 | public void setCode(String code) { 29 | this.code = code; 30 | } 31 | 32 | public String getScope() { 33 | return scope; 34 | } 35 | 36 | public void setScope(String scope) { 37 | this.scope = scope; 38 | } 39 | 40 | public String getTable() { 41 | return table; 42 | } 43 | 44 | public void setTable(String table) { 45 | this.table = table; 46 | } 47 | 48 | public int getLimit() { 49 | return limit; 50 | } 51 | 52 | public void setLimit(int limit) { 53 | this.limit = limit; 54 | } 55 | 56 | public Boolean getJson() { 57 | return json; 58 | } 59 | 60 | public void setJson(Boolean json) { 61 | this.json = json; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/Transfer.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author Angus 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class Transfer { 10 | 11 | /** 12 | * quantity : 6.0000 EOS 13 | * memo : 恭喜发财,大吉大利 14 | * from : lucan222 15 | * to : eosio.token 16 | */ 17 | 18 | private String quantity; 19 | private String memo; 20 | private String from; 21 | private String to; 22 | 23 | public Transfer(String quantity, String memo, String from, String to) { 24 | this.quantity = quantity; 25 | this.memo = memo; 26 | this.from = from; 27 | this.to = to; 28 | } 29 | 30 | public String getQuantity() { 31 | return quantity; 32 | } 33 | 34 | public void setQuantity(String quantity) { 35 | this.quantity = quantity; 36 | } 37 | 38 | public String getMemo() { 39 | return memo; 40 | } 41 | 42 | public void setMemo(String memo) { 43 | this.memo = memo; 44 | } 45 | 46 | public String getFrom() { 47 | return from; 48 | } 49 | 50 | public void setFrom(String from) { 51 | this.from = from; 52 | } 53 | 54 | public String getTo() { 55 | return to; 56 | } 57 | 58 | public void setTo(String to) { 59 | this.to = to; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/UpTransfer.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author Angus 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class UpTransfer { 10 | 11 | private String upfrom; 12 | private String upto; 13 | private String value; 14 | 15 | public UpTransfer(String upfrom, String upto, String value) { 16 | this.upfrom = upfrom; 17 | this.upto = upto; 18 | this.value = value; 19 | } 20 | 21 | public String getUpfrom() { 22 | return upfrom; 23 | } 24 | 25 | public void setUpfrom(String upfrom) { 26 | this.upfrom = upfrom; 27 | } 28 | 29 | public String getUpto() { 30 | return upto; 31 | } 32 | 33 | public void setUpto(String upto) { 34 | this.upto = upto; 35 | } 36 | 37 | public String getValue() { 38 | return value; 39 | } 40 | 41 | public void setValue(String value) { 42 | this.value = value; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/Account.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | /** 10 | * @author espritblock http://eblock.io 11 | */ 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | public class Account { 14 | 15 | @JsonProperty("account_name") 16 | private String accountName; 17 | 18 | @JsonProperty("privileged") 19 | private String privileged; 20 | 21 | @JsonProperty("last_code_update") 22 | private Date lastCodeUpdate; 23 | 24 | @JsonProperty("created") 25 | private Date created; 26 | 27 | @JsonProperty("ram_quota") 28 | private Long ramQuota; 29 | 30 | @JsonProperty("net_weight") 31 | private Long netWeight; 32 | 33 | @JsonProperty("cpu_weight") 34 | private Long cpuWeight; 35 | 36 | @JsonProperty("net_limit") 37 | private NetLimit netLimit; 38 | 39 | @JsonProperty("cpu_limit") 40 | private CpuLimit cpuLimit; 41 | 42 | @JsonProperty("ram_usage") 43 | private Long ramUsage; 44 | 45 | @JsonProperty("permissions") 46 | private List permissions; 47 | 48 | public Account() { 49 | 50 | } 51 | 52 | public String getAccountName() { 53 | return accountName; 54 | } 55 | 56 | public void setAccountName(String accountName) { 57 | this.accountName = accountName; 58 | } 59 | 60 | public String getPrivileged() { 61 | return privileged; 62 | } 63 | 64 | public void setPrivileged(String privileged) { 65 | this.privileged = privileged; 66 | } 67 | 68 | public Date getLastCodeUpdate() { 69 | return lastCodeUpdate; 70 | } 71 | 72 | public void setLastCodeUpdate(Date lastCodeUpdate) { 73 | this.lastCodeUpdate = lastCodeUpdate; 74 | } 75 | 76 | public Date getCreated() { 77 | return created; 78 | } 79 | 80 | public void setCreated(Date created) { 81 | this.created = created; 82 | } 83 | 84 | public Long getRamQuota() { 85 | return ramQuota; 86 | } 87 | 88 | public void setRamQuota(Long ramQuota) { 89 | this.ramQuota = ramQuota; 90 | } 91 | 92 | public Long getNetWeight() { 93 | return netWeight; 94 | } 95 | 96 | public void setNetWeight(Long netWeight) { 97 | this.netWeight = netWeight; 98 | } 99 | 100 | public Long getCpuWeight() { 101 | return cpuWeight; 102 | } 103 | 104 | public void setCpuWeight(Long cpuWeight) { 105 | this.cpuWeight = cpuWeight; 106 | } 107 | 108 | public NetLimit getNetLimit() { 109 | return netLimit; 110 | } 111 | 112 | public void setNetLimit(NetLimit netLimit) { 113 | this.netLimit = netLimit; 114 | } 115 | 116 | public CpuLimit getCpuLimit() { 117 | return cpuLimit; 118 | } 119 | 120 | public void setCpuLimit(CpuLimit cpuLimit) { 121 | this.cpuLimit = cpuLimit; 122 | } 123 | 124 | public Long getRamUsage() { 125 | return ramUsage; 126 | } 127 | 128 | public void setRamUsage(Long ramUsage) { 129 | this.ramUsage = ramUsage; 130 | } 131 | 132 | public List getPermissions() { 133 | return permissions; 134 | } 135 | 136 | public void setPermissions(List permissions) { 137 | this.permissions = permissions; 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/CpuLimit.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author espritblock http://eblock.io 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class CpuLimit { 10 | 11 | private Long used; 12 | 13 | private Long available; 14 | 15 | private Long max; 16 | 17 | public CpuLimit() { 18 | 19 | } 20 | 21 | public Long getUsed() { 22 | return used; 23 | } 24 | 25 | public void setUsed(Long used) { 26 | this.used = used; 27 | } 28 | 29 | public Long getAvailable() { 30 | return available; 31 | } 32 | 33 | public void setAvailable(Long available) { 34 | this.available = available; 35 | } 36 | 37 | public Long getMax() { 38 | return max; 39 | } 40 | 41 | public void setMax(Long max) { 42 | this.max = max; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/Key.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author espritblock http://eblock.io 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class Key { 10 | 11 | private String key; 12 | 13 | private Long weight; 14 | 15 | public Key() { 16 | 17 | } 18 | 19 | public String getKey() { 20 | return key; 21 | } 22 | 23 | public void setKey(String key) { 24 | this.key = key; 25 | } 26 | 27 | public Long getWeight() { 28 | return weight; 29 | } 30 | 31 | public void setWeight(Long weight) { 32 | this.weight = weight; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/NetLimit.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @author espritblock http://eblock.io 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class NetLimit { 10 | 11 | private Long used; 12 | 13 | private Long available; 14 | 15 | private Long max; 16 | 17 | public NetLimit() { 18 | 19 | } 20 | 21 | public Long getUsed() { 22 | return used; 23 | } 24 | 25 | public void setUsed(Long used) { 26 | this.used = used; 27 | } 28 | 29 | public Long getAvailable() { 30 | return available; 31 | } 32 | 33 | public void setAvailable(Long available) { 34 | this.available = available; 35 | } 36 | 37 | public Long getMax() { 38 | return max; 39 | } 40 | 41 | public void setMax(Long max) { 42 | this.max = max; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/Permission.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * @author espritblock http://eblock.io 8 | */ 9 | @JsonIgnoreProperties(ignoreUnknown = true) 10 | public class Permission { 11 | 12 | public Permission() { 13 | 14 | } 15 | 16 | @JsonProperty("perm_name") 17 | private String permName; 18 | 19 | @JsonProperty("parent") 20 | private String parent; 21 | 22 | @JsonProperty("required_auth") 23 | private RequiredAuth requiredAuth; 24 | 25 | public String getPermName() { 26 | return permName; 27 | } 28 | 29 | public void setPermName(String permName) { 30 | this.permName = permName; 31 | } 32 | 33 | public String getParent() { 34 | return parent; 35 | } 36 | 37 | public void setParent(String parent) { 38 | this.parent = parent; 39 | } 40 | 41 | public RequiredAuth getRequiredAuth() { 42 | return requiredAuth; 43 | } 44 | 45 | public void setRequiredAuth(RequiredAuth requiredAuth) { 46 | this.requiredAuth = requiredAuth; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/account/RequiredAuth.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author espritblock http://eblock.io 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class RequiredAuth { 12 | 13 | private List accounts; 14 | 15 | private List keys; 16 | 17 | private Long threshold; 18 | 19 | public List getAccounts() { 20 | return accounts; 21 | } 22 | 23 | public void setAccounts(List accounts) { 24 | this.accounts = accounts; 25 | } 26 | 27 | public List getKeys() { 28 | return keys; 29 | } 30 | 31 | public void setKeys(List keys) { 32 | this.keys = keys; 33 | } 34 | 35 | public Long getThreshold() { 36 | return threshold; 37 | } 38 | 39 | public void setThreshold(Long threshold) { 40 | this.threshold = threshold; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/Processed.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * @author espritblock http://eblock.io 8 | */ 9 | @JsonIgnoreProperties(ignoreUnknown = true) 10 | public class Processed { 11 | 12 | @JsonProperty("id") 13 | private String id; 14 | 15 | @JsonProperty("receipt") 16 | private Receipt receipt; 17 | 18 | @JsonProperty("elapsed") 19 | private Long elapsed; 20 | 21 | @JsonProperty("net_usage") 22 | private Long netUsage; 23 | 24 | @JsonProperty("scheduled") 25 | private Boolean scheduled; 26 | 27 | public String getId() { 28 | return id; 29 | } 30 | 31 | public void setId(String id) { 32 | this.id = id; 33 | } 34 | 35 | public Receipt getReceipt() { 36 | return receipt; 37 | } 38 | 39 | public void setReceipt(Receipt receipt) { 40 | this.receipt = receipt; 41 | } 42 | 43 | public Long getElapsed() { 44 | return elapsed; 45 | } 46 | 47 | public void setElapsed(Long elapsed) { 48 | this.elapsed = elapsed; 49 | } 50 | 51 | public Long getNetUsage() { 52 | return netUsage; 53 | } 54 | 55 | public void setNetUsage(Long netUsage) { 56 | this.netUsage = netUsage; 57 | } 58 | 59 | public Boolean getScheduled() { 60 | return scheduled; 61 | } 62 | 63 | public void setScheduled(Boolean scheduled) { 64 | this.scheduled = scheduled; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/Receipt.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * @author espritblock http://eblock.io 8 | */ 9 | @JsonIgnoreProperties(ignoreUnknown = true) 10 | public class Receipt { 11 | 12 | @JsonProperty("status") 13 | private String status; 14 | 15 | @JsonProperty("cpu_usage_us") 16 | private Long cpuUsageUs; 17 | 18 | @JsonProperty("net_usage_words") 19 | private Long netUsageWords; 20 | 21 | public String getStatus() { 22 | return status; 23 | } 24 | 25 | public void setStatus(String status) { 26 | this.status = status; 27 | } 28 | 29 | public Long getCpuUsageUs() { 30 | return cpuUsageUs; 31 | } 32 | 33 | public void setCpuUsageUs(Long cpuUsageUs) { 34 | this.cpuUsageUs = cpuUsageUs; 35 | } 36 | 37 | public Long getNetUsageWords() { 38 | return netUsageWords; 39 | } 40 | 41 | public void setNetUsageWords(Long netUsageWords) { 42 | this.netUsageWords = netUsageWords; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/Transaction.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.databind.deser.Deserializers.Base; 6 | 7 | /** 8 | * @author espritblock http://eblock.io 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class Transaction extends Base { 12 | 13 | @JsonProperty("transaction_id") 14 | private String transactionId; 15 | 16 | @JsonProperty("processed") 17 | private Processed processed; 18 | 19 | public String getTransactionId() { 20 | return transactionId; 21 | } 22 | 23 | public void setTransactionId(String transactionId) { 24 | this.transactionId = transactionId; 25 | } 26 | 27 | public Processed getProcessed() { 28 | return processed; 29 | } 30 | 31 | public void setProcessed(Processed processed) { 32 | this.processed = processed; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/BaseTx.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | import com.develop.wallet.eos.model.BaseVo; 4 | 5 | public class BaseTx extends BaseVo { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/FieldAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Transaction signature serialization order 10 | * 11 | * @author Angus 12 | */ 13 | @Target(ElementType.FIELD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface FieldAnnotation { 16 | 17 | /** 18 | * field order 19 | * 20 | * @return 21 | */ 22 | int order(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/Tx.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * @author espritblock http://eblock.io 11 | */ 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | public class Tx extends BaseTx { 14 | @FieldAnnotation(order = 1) 15 | private Object expiration; 16 | @FieldAnnotation(order = 2) 17 | private Long ref_block_num; 18 | @FieldAnnotation(order = 3) 19 | private Long ref_block_prefix; 20 | @FieldAnnotation(order = 4) 21 | private Long net_usage_words; 22 | @FieldAnnotation(order = 5) 23 | private Long max_cpu_usage_ms; 24 | @FieldAnnotation(order = 6) 25 | private Long delay_sec; 26 | @FieldAnnotation(order = 7) 27 | private List context_free_actions = new ArrayList<>(); 28 | @FieldAnnotation(order = 8) 29 | private List actions; 30 | @FieldAnnotation(order = 9) 31 | private List transaction_extensions = new ArrayList<>(); 32 | 33 | public Object getExpiration() { 34 | return expiration; 35 | } 36 | 37 | public void setExpiration(Object expiration) { 38 | this.expiration = expiration; 39 | } 40 | 41 | public Long getRef_block_num() { 42 | return ref_block_num; 43 | } 44 | 45 | public void setRef_block_num(Long ref_block_num) { 46 | this.ref_block_num = ref_block_num; 47 | } 48 | 49 | public Long getRef_block_prefix() { 50 | return ref_block_prefix; 51 | } 52 | 53 | public void setRef_block_prefix(Long ref_block_prefix) { 54 | this.ref_block_prefix = ref_block_prefix; 55 | } 56 | 57 | public Long getNet_usage_words() { 58 | return net_usage_words; 59 | } 60 | 61 | public void setNet_usage_words(Long net_usage_words) { 62 | this.net_usage_words = net_usage_words; 63 | } 64 | 65 | public Long getMax_cpu_usage_ms() { 66 | return max_cpu_usage_ms; 67 | } 68 | 69 | public void setMax_cpu_usage_ms(Long max_cpu_usage_ms) { 70 | this.max_cpu_usage_ms = max_cpu_usage_ms; 71 | } 72 | 73 | public Long getDelay_sec() { 74 | return delay_sec; 75 | } 76 | 77 | public void setDelay_sec(Long delay_sec) { 78 | this.delay_sec = delay_sec; 79 | } 80 | 81 | public List getContext_free_actions() { 82 | return context_free_actions; 83 | } 84 | 85 | public void setContext_free_actions(List context_free_actions) { 86 | this.context_free_actions = context_free_actions; 87 | } 88 | 89 | public List getActions() { 90 | return actions; 91 | } 92 | 93 | public void setActions(List actions) { 94 | this.actions = actions; 95 | } 96 | 97 | public List getTransaction_extensions() { 98 | return transaction_extensions; 99 | } 100 | 101 | public void setTransaction_extensions(List transaction_extensions) { 102 | this.transaction_extensions = transaction_extensions; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/TxAction.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * @author espritblock http://eblock.io 11 | */ 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | public class TxAction extends BaseTx { 14 | @FieldAnnotation(order = 1) 15 | private String account; 16 | @FieldAnnotation(order = 2) 17 | private String name; 18 | @FieldAnnotation(order = 3) 19 | private List authorization; 20 | @FieldAnnotation(order = 4) 21 | private Object data; 22 | 23 | public TxAction() { 24 | 25 | } 26 | 27 | public TxAction(String actor, String account, String name, Object data) { 28 | this.account = account; 29 | this.name = name; 30 | this.data = data; 31 | this.authorization = new ArrayList<>(); 32 | this.authorization.add(new TxActionAuth(actor, "active")); 33 | } 34 | 35 | public String getAccount() { 36 | return account; 37 | } 38 | 39 | public void setAccount(String account) { 40 | this.account = account; 41 | } 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | 51 | public List getAuthorization() { 52 | return authorization; 53 | } 54 | 55 | public void setAuthorization(List authorization) { 56 | this.authorization = authorization; 57 | } 58 | 59 | public Object getData() { 60 | return data; 61 | } 62 | 63 | public void setData(Object data) { 64 | this.data = data; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/TxActionAuth.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | /** 4 | * @author espritblock http://eblock.io 5 | */ 6 | public class TxActionAuth extends BaseTx { 7 | @FieldAnnotation(order = 1) 8 | private String actor; 9 | @FieldAnnotation(order = 2) 10 | private String permission; 11 | 12 | public TxActionAuth() { 13 | 14 | } 15 | 16 | public TxActionAuth(String actor, String permission) { 17 | this.actor = actor; 18 | this.permission = permission; 19 | } 20 | 21 | public String getActor() { 22 | return actor; 23 | } 24 | 25 | public void setActor(String actor) { 26 | this.actor = actor; 27 | } 28 | 29 | public String getPermission() { 30 | return permission; 31 | } 32 | 33 | public void setPermission(String permission) { 34 | this.permission = permission; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/TxExtenstions.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | 6 | /** 7 | * @author espritblock http://eblock.io 8 | */ 9 | @JsonIgnoreProperties(ignoreUnknown = true) 10 | public class TxExtenstions extends BaseTx { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/TxRequest.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | 4 | import com.develop.wallet.eos.model.BaseVo; 5 | 6 | /** 7 | * @author espritblock http://eblock.io 8 | */ 9 | public class TxRequest extends BaseVo { 10 | private String compression; 11 | 12 | private Tx transaction; 13 | 14 | private String[] signatures; 15 | 16 | public TxRequest() { 17 | 18 | } 19 | 20 | public TxRequest(String compression, Tx transaction, String[] signatures) { 21 | this.compression = compression; 22 | this.transaction = transaction; 23 | this.signatures = signatures; 24 | } 25 | 26 | public String getCompression() { 27 | return compression; 28 | } 29 | 30 | public void setCompression(String compression) { 31 | this.compression = compression; 32 | } 33 | 34 | public Tx getTransaction() { 35 | return transaction; 36 | } 37 | 38 | public void setTransaction(Tx transaction) { 39 | this.transaction = transaction; 40 | } 41 | 42 | public String[] getSignatures() { 43 | return signatures; 44 | } 45 | 46 | public void setSignatures(String[] signatures) { 47 | this.signatures = signatures; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/model/transaction/push/TxSign.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.model.transaction.push; 2 | 3 | 4 | /** 5 | * @author espritblock http://eblock.io 6 | */ 7 | public class TxSign extends BaseTx { 8 | @FieldAnnotation(order = 1) 9 | private String chain_id; 10 | @FieldAnnotation(order = 2) 11 | private Tx transaction; 12 | 13 | public TxSign() { 14 | 15 | } 16 | 17 | public TxSign(String chain_id, Tx transaction) { 18 | this.chain_id = chain_id; 19 | this.transaction = transaction; 20 | } 21 | 22 | public String getChain_id() { 23 | return chain_id; 24 | } 25 | 26 | public void setChain_id(String chain_id) { 27 | this.chain_id = chain_id; 28 | } 29 | 30 | public Tx getTransaction() { 31 | return transaction; 32 | } 33 | 34 | public void setTransaction(Tx transaction) { 35 | this.transaction = transaction; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/EException.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | /** 4 | * exception 5 | * 6 | * @author espritblock http://eblock.io 7 | */ 8 | public class EException extends RuntimeException { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | public EException(String code, String msg) { 13 | this.code = code; 14 | this.msg = msg; 15 | } 16 | 17 | private String code; 18 | 19 | private String msg; 20 | 21 | public String getCode() { 22 | return code; 23 | } 24 | 25 | public void setCode(String code) { 26 | this.code = code; 27 | } 28 | 29 | public String getMsg() { 30 | return msg; 31 | } 32 | 33 | public void setMsg(String msg) { 34 | this.msg = msg; 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/EccTool.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | import com.develop.wallet.eos.crypto.Point; 4 | import com.develop.wallet.eos.crypto.Secp256k; 5 | import com.develop.wallet.eos.crypto.digest.Ripemd160; 6 | import com.develop.wallet.eos.crypto.digest.Sha; 7 | import com.develop.wallet.eos.crypto.utils.Base58; 8 | import com.develop.wallet.eos.crypto.utils.ByteBuffer; 9 | import com.develop.wallet.eos.crypto.utils.ByteUtils; 10 | import com.develop.wallet.eos.model.transaction.push.TxSign; 11 | import com.develop.wallet.eos.utils.ese.Ese; 12 | 13 | import java.math.BigInteger; 14 | import java.util.List; 15 | 16 | 17 | /** 18 | * Ecc 19 | * 20 | * @author espritblock http://eblock.io 21 | */ 22 | public class EccTool { 23 | 24 | public static final String address_prefix = "EOS"; 25 | 26 | public static final Secp256k secp = new Secp256k(); 27 | 28 | /** 29 | * 通过种子生成私钥 30 | * 31 | * @param seed 种子 32 | * @return 33 | */ 34 | public static String privateKeyFromSeed(String seed) { 35 | return seedShaPrivate(Sha.SHA256(seed)); 36 | } 37 | 38 | public static String privateKeyFromSeed(byte[] seed) { 39 | return seedShaPrivate(Sha.SHA256(seed)); 40 | } 41 | 42 | /** 43 | * seedPrivate 44 | * 45 | * @return 46 | */ 47 | private static String seedShaPrivate(byte[] seedSha) { 48 | byte[] a = {(byte) 0x80}; 49 | byte[] b = new BigInteger(seedSha).toByteArray(); 50 | byte[] private_key = ByteUtils.concat(a, b); 51 | byte[] checksum = Sha.SHA256(private_key); 52 | checksum = Sha.SHA256(checksum); 53 | byte[] check = ByteUtils.copy(checksum, 0, 4); 54 | byte[] pk = ByteUtils.concat(private_key, check); 55 | return Base58.encode(pk); 56 | } 57 | 58 | 59 | /** 60 | * privateKey 61 | * 62 | * @param pk 63 | * @return 64 | */ 65 | private static BigInteger privateKey(String pk) { 66 | byte[] private_wif = Base58.decode(pk); 67 | byte version = (byte) 0x80; 68 | if (private_wif[0] != version) { 69 | throw new EException("version_error", "Expected version " + 0x80 + ", instead got " + version); 70 | } 71 | byte[] private_key = ByteUtils.copy(private_wif, 0, private_wif.length - 4); 72 | byte[] new_checksum = Sha.SHA256(private_key); 73 | new_checksum = Sha.SHA256(new_checksum); 74 | new_checksum = ByteUtils.copy(new_checksum, 0, 4); 75 | byte[] last_private_key = ByteUtils.copy(private_key, 1, private_key.length - 1); 76 | BigInteger d = new BigInteger(Hex.bytesToHexString(last_private_key), 16); 77 | return d; 78 | } 79 | 80 | /** 81 | * 通过私钥生成公钥 82 | * 83 | * @param pk 私钥 84 | * @return 85 | */ 86 | public static String privateToPublic(String pk) { 87 | if (pk == null || pk.length() == 0) { 88 | throw new EException("args_empty", "args is empty"); 89 | } 90 | // private key 91 | BigInteger d = privateKey(pk); 92 | // publick key 93 | Point ep = secp.G().multiply(d); 94 | byte[] pub_buf = ep.getEncoded(); 95 | byte[] csum = Ripemd160.from(pub_buf).bytes(); 96 | csum = ByteUtils.copy(csum, 0, 4); 97 | byte[] addy = ByteUtils.concat(pub_buf, csum); 98 | StringBuffer bf = new StringBuffer(address_prefix); 99 | bf.append(Base58.encode(addy)); 100 | return bf.toString(); 101 | } 102 | 103 | /** 104 | * signHash 105 | * 106 | * @param pk 107 | * @param b 108 | * @return 109 | */ 110 | public static String signHash(String pk, byte[] b) { 111 | String dataSha256 = Hex.bytesToHexString(Sha.SHA256(b)); 112 | BigInteger e = new BigInteger(dataSha256, 16); 113 | int nonce = 0; 114 | int i = 0; 115 | BigInteger d = privateKey(pk); 116 | Point Q = secp.G().multiply(d); 117 | nonce = 0; 118 | Ecdsa ecd = new Ecdsa(secp); 119 | Ecdsa.SignBigInt sign; 120 | while (true) { 121 | sign = ecd.sign(dataSha256, d, nonce++); 122 | byte der[] = sign.getDer(); 123 | byte lenR = der[3]; 124 | byte lenS = der[5 + lenR]; 125 | if (lenR == 32 && lenS == 32) { 126 | i = ecd.calcPubKeyRecoveryParam(e, sign, Q); 127 | i += 4; // compressed 128 | i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) 129 | break; 130 | } 131 | } 132 | byte[] pub_buf = new byte[65]; 133 | pub_buf[0] = (byte) i; 134 | ByteUtils.copy(sign.getR().toByteArray(), 0, pub_buf, 1, sign.getR().toByteArray().length); 135 | ByteUtils.copy(sign.getS().toByteArray(), 0, pub_buf, sign.getR().toByteArray().length + 1, 136 | sign.getS().toByteArray().length); 137 | 138 | byte[] checksum = Ripemd160.from(ByteUtils.concat(pub_buf, "K1".getBytes())).bytes(); 139 | 140 | byte[] signatureString = ByteUtils.concat(pub_buf, ByteUtils.copy(checksum, 0, 4)); 141 | 142 | return "SIG_K1_" + Base58.encode(signatureString); 143 | } 144 | 145 | /** 146 | * 普通数据签名 147 | * 148 | * @param pk 私钥 149 | * @param data 需要签名的数据 150 | * @return 151 | */ 152 | public static String sign(String pk, String data) { 153 | String dataSha256 = Hex.bytesToHexString(Sha.SHA256(data)); 154 | BigInteger e = new BigInteger(dataSha256, 16); 155 | int nonce = 0; 156 | int i = 0; 157 | BigInteger d = privateKey(pk); 158 | Point Q = secp.G().multiply(d); 159 | nonce = 0; 160 | Ecdsa ecd = new Ecdsa(secp); 161 | Ecdsa.SignBigInt sign; 162 | while (true) { 163 | sign = ecd.sign(dataSha256, d, nonce++); 164 | byte der[] = sign.getDer(); 165 | byte lenR = der[3]; 166 | byte lenS = der[5 + lenR]; 167 | if (lenR == 32 && lenS == 32) { 168 | i = ecd.calcPubKeyRecoveryParam(e, sign, Q); 169 | i += 4; // compressed 170 | i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) 171 | break; 172 | } 173 | } 174 | byte[] pub_buf = new byte[65]; 175 | pub_buf[0] = (byte) i; 176 | ByteUtils.copy(sign.getR().toByteArray(), 0, pub_buf, 1, sign.getR().toByteArray().length); 177 | ByteUtils.copy(sign.getS().toByteArray(), 0, pub_buf, sign.getR().toByteArray().length + 1, 178 | sign.getS().toByteArray().length); 179 | 180 | byte[] checksum = Ripemd160.from(ByteUtils.concat(pub_buf, "K1".getBytes())).bytes(); 181 | 182 | byte[] signatureString = ByteUtils.concat(pub_buf, ByteUtils.copy(checksum, 0, 4)); 183 | 184 | return "SIG_K1_" + Base58.encode(signatureString); 185 | } 186 | 187 | /** 188 | * 交易签名 189 | * 190 | * @param privateKey 私钥 191 | * @param push 需要签名的对象 192 | * @return 193 | */ 194 | public static String signTransaction(String privateKey, TxSign push) { 195 | // tx 196 | ByteBuffer bf = new ByteBuffer(); 197 | ObjectUtils.writeBytes(push, bf); 198 | byte[] real = bf.getBuffer(); 199 | // append 200 | real = ByteUtils.concat(real, java.nio.ByteBuffer.allocate(33).array()); 201 | 202 | // final byte [] b = real.clone(); 203 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 204 | // for(int i=1;i<=a.length;i++) { 205 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 206 | // } 207 | return signHash(privateKey, real); 208 | } 209 | 210 | /** 211 | * 转账数据序列化 212 | * 213 | * @param from 从 214 | * @param to 到 215 | * @param quantity 转账金额和币种 216 | * @param memo 备注留言 217 | * @return 218 | */ 219 | public static String parseTransferData(String from, String to, String quantity, String memo) { 220 | return Ese.parseTransferData(from, to, quantity, memo); 221 | } 222 | 223 | /** 224 | * up 序列化 225 | * 226 | * @param from 227 | * @param to 228 | * @param quantity 229 | * @return 230 | */ 231 | public static String parseUpData(String from, String to, String quantity) { 232 | return Ese.parseUpData(from, to, quantity); 233 | } 234 | 235 | /** 236 | * @param voter 237 | * @param proxy 238 | * @param producers 239 | * @return 240 | */ 241 | public static String parseVoteProducerData(String voter, String proxy, List producers) { 242 | return Ese.parseVoteProducerData(voter, proxy, producers); 243 | } 244 | 245 | /** 246 | * 创建账户数据序列化 247 | * 248 | * @param creator 创建者 249 | * @param name 账户名 250 | * @param onwer onwer公钥 251 | * @param active active公钥 252 | * @return 253 | */ 254 | public static String parseAccountData(String creator, String name, String onwer, String active) { 255 | return Ese.parseAccountData(creator, name, onwer, active); 256 | } 257 | 258 | /** 259 | * 购买ram数据序列化 260 | * 261 | * @param payer 付款账户 262 | * @param receiver 接收账户 263 | * @param bytes 购买字节数量 264 | * @return 265 | */ 266 | public static String parseBuyRamData(String payer, String receiver, Long bytes) { 267 | return Ese.parseBuyRamData(payer, receiver, bytes); 268 | } 269 | 270 | /** 271 | * 抵押数据序列化 272 | * 273 | * @param from 抵押账户 274 | * @param receiver 接受账户 275 | * @param stakeNetQuantity 网络抵押数量和币种 276 | * @param stakeCpuQuantity CPU抵押数量和币种 277 | * @param transfer 是否讲抵押资产转送给对方,0自己所有,1对方所有 278 | * @return 279 | */ 280 | public static String parseBuyRamData(String from, String receiver, String stakeNetQuantity, String stakeCpuQuantity, 281 | int transfer) { 282 | return Ese.parseDelegateData(from, receiver, stakeNetQuantity, stakeCpuQuantity, transfer); 283 | } 284 | 285 | /** 286 | * 关闭token 287 | * 288 | * @param owner 289 | * @param symbol 290 | * @return 291 | */ 292 | public static String parseCloseData(String owner, String symbol) { 293 | return Ese.parseCloseData(owner, symbol); 294 | } 295 | 296 | } 297 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/Ecdsa.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | import com.develop.wallet.eos.crypto.Point; 4 | import com.develop.wallet.eos.crypto.Secp256k; 5 | import com.develop.wallet.eos.crypto.digest.Sha; 6 | import com.develop.wallet.eos.crypto.utils.ByteUtils; 7 | 8 | import java.math.BigInteger; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | 12 | 13 | /** 14 | * Ecdsa 15 | * 16 | * @author espritblock http://eblock.io 17 | */ 18 | public class Ecdsa { 19 | 20 | Secp256k curve = null; 21 | 22 | public Ecdsa(Secp256k curve) { 23 | this.curve = curve; 24 | } 25 | 26 | /** 27 | * sign 28 | * 29 | * @param dataHash 30 | * @param d 31 | * @param nonce 32 | * @return 33 | */ 34 | public SignBigInt sign(String dataHash, BigInteger d, int nonce) { 35 | BigInteger n = curve.n(); 36 | SignBigInt big = new SignBigInt(); 37 | deterministicGenerateK(curve, dataHash, d, nonce, big); 38 | BigInteger N_OVER_TWO = n.shiftRight(1); 39 | if (big.getS().compareTo(N_OVER_TWO) > 0) { 40 | big.setS(n.subtract(big.getS())); 41 | } 42 | big.setDer(toDER(big)); 43 | return big; 44 | } 45 | 46 | /** 47 | * toDER 48 | * 49 | * @param big 50 | * @return 51 | */ 52 | private byte[] toDER(SignBigInt big) { 53 | byte[] rBa = big.getR().toByteArray(); 54 | byte[] sBa = big.getS().toByteArray(); 55 | ArrayList sequence = new ArrayList(); 56 | sequence.add(new Byte(((byte) 0x02))); 57 | sequence.add(new Byte(((byte) rBa.length))); 58 | for (int i = 0; i < rBa.length; i++) { 59 | sequence.add(rBa[i]); 60 | } 61 | sequence.add(new Byte(((byte) 0x02))); 62 | sequence.add(new Byte(((byte) sBa.length))); 63 | for (int i = 0; i < sBa.length; i++) { 64 | sequence.add(sBa[i]); 65 | } 66 | int len = sequence.size(); 67 | sequence.add(0, (byte) 0x30); 68 | sequence.add(1, (byte) len); 69 | byte[] bf = new byte[sequence.size()]; 70 | for (int i = 0; i < bf.length; i++) { 71 | bf[i] = sequence.get(i).byteValue(); 72 | } 73 | return bf; 74 | } 75 | 76 | private BigInteger deterministicGenerateK(Secp256k curve, String dataHash, BigInteger d, int nonce, 77 | SignBigInt big) { 78 | byte[] hash = Hex.hexStringToBytes(dataHash); 79 | if (nonce > 0) { 80 | hash = Sha.SHA256(ByteUtils.concat(hash, new byte[nonce])); 81 | } 82 | byte[] x = null; 83 | if (d.toByteArray()[0] == 0) { 84 | x = ByteUtils.copy(d.toByteArray(), 1, d.toByteArray().length - 1); 85 | } else { 86 | x = d.toByteArray(); 87 | } 88 | // int padding = d.toByteArray().length-tmp.length; 89 | // byte[] zeros = null; 90 | // if(padding>0) { 91 | // zeros = new byte[padding]; 92 | // for(int i =0;i= 0 || !check) { 135 | k = Sha.HmacSHA256(ByteUtils.concat(v, new byte[]{0}), k); 136 | v = Sha.HmacSHA256(v, k); 137 | v = Sha.HmacSHA256(v, k); 138 | T = new BigInteger(v); 139 | } 140 | 141 | big.setK(T); 142 | return T; 143 | } 144 | 145 | /** 146 | * checkSig 147 | * 148 | * @param k 149 | * @param d 150 | * @param e 151 | * @param big 152 | * @return 153 | */ 154 | public Boolean checkSig(BigInteger k, BigInteger d, BigInteger e, SignBigInt big) { 155 | Point Q = curve.G().multiply(k); 156 | if (Q.isInfinity()) 157 | return false; 158 | BigInteger r = Q.getX().toBigInteger().mod(curve.n()); 159 | big.setR(r); 160 | if (r.signum() == 0) 161 | return false; 162 | BigInteger s = k.modInverse(curve.n()).multiply(e.add(d.multiply(r))).mod(curve.n()); 163 | big.setS(s); 164 | if (s.signum() == 0) 165 | return false; 166 | return true; 167 | } 168 | 169 | /** 170 | * @author espritblock http://eblock.io 171 | */ 172 | public static class SignBigInt { 173 | private BigInteger k; 174 | private BigInteger r; 175 | private BigInteger s; 176 | private byte[] der; 177 | 178 | public BigInteger getK() { 179 | return k; 180 | } 181 | 182 | public void setK(BigInteger k) { 183 | this.k = k; 184 | } 185 | 186 | public BigInteger getR() { 187 | return r; 188 | } 189 | 190 | public void setR(BigInteger r) { 191 | this.r = r; 192 | } 193 | 194 | public BigInteger getS() { 195 | return s; 196 | } 197 | 198 | public void setS(BigInteger s) { 199 | this.s = s; 200 | } 201 | 202 | public byte[] getDer() { 203 | return der; 204 | } 205 | 206 | public void setDer(byte[] der) { 207 | this.der = der; 208 | } 209 | } 210 | 211 | public int calcPubKeyRecoveryParam(BigInteger e, SignBigInt sign, Point Q) { 212 | for (int i = 0; i < 4; i++) { 213 | Point Qprime = recoverPubKey(e, sign, i); 214 | if (Qprime.equals(Q)) { 215 | return i; 216 | } 217 | } 218 | throw new EException("sign_error", "Unable to find valid recovery factor"); 219 | } 220 | 221 | public Point recoverPubKey(BigInteger e, SignBigInt big, int i) { 222 | 223 | BigInteger n = curve.n(); 224 | Point G = curve.G(); 225 | 226 | BigInteger r = big.getR(); 227 | BigInteger s = big.getS(); 228 | 229 | if (!(r.signum() > 0 && r.compareTo(n) < 0)) { 230 | throw new EException("recover_pubkey_error", "Invalid r value"); 231 | } 232 | if (!(s.signum() > 0 && s.compareTo(n) < 0)) { 233 | throw new EException("recover_pubkey_error", "Invalid r value"); 234 | } 235 | 236 | // A set LSB signifies that the y-coordinate is odd 237 | int isYOdd = i & 1; 238 | 239 | // The more significant bit specifies whether we should use the 240 | // first or second candidate key. 241 | int isSecondKey = i >> 1; 242 | 243 | // 1.1 Let x = r + jn 244 | BigInteger x = isSecondKey == 1 ? r.add(n) : r; 245 | 246 | Point R = curve.getCurve().pointFromX(isYOdd, x); 247 | 248 | // // 1.4 Check that nR is at infinity 249 | Point nR = R.multiply(n); 250 | 251 | if (!nR.isInfinity()) { 252 | throw new EException("sign_error", "nR is not a valid curve point"); 253 | } 254 | 255 | BigInteger eNeg = e.negate().mod(n); 256 | 257 | BigInteger rInv = r.modInverse(n); 258 | 259 | Point Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); 260 | 261 | if (Q.isInfinity()) { 262 | throw new EException("sign_error", "Point is at infinity"); 263 | } 264 | 265 | return Q; 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/EosUtils.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | import java.util.Random; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * eos 9 | * 10 | * @author Angus 11 | */ 12 | public class EosUtils { 13 | public static final String NUMBERS_AND_LETTERS = "12345abcdefghijklmnopqrstuvwxyz"; 14 | public static final String LOWER_CASE_LETTERS = "abcdefghijklmnopqrstuvwxyz"; 15 | 16 | /** 17 | * 随机生成一个eos账号 18 | * 19 | * @return 20 | */ 21 | public static String generateAccount() { 22 | StringBuilder sBuilder = new StringBuilder(); 23 | sBuilder.append(getRandom(LOWER_CASE_LETTERS, 1)); 24 | sBuilder.append(getRandom(NUMBERS_AND_LETTERS, 11)); 25 | return sBuilder.toString(); 26 | } 27 | 28 | /** 29 | * eos账号名 30 | * 31 | * @param eosAccount the eos name 32 | * @return boolean 33 | */ 34 | public static boolean isEosAccount(String eosAccount) { 35 | String strPattern = "^[a-z]{1}[1-5a-z]{11}$"; 36 | Pattern p = Pattern.compile(strPattern); 37 | Matcher m = p.matcher(eosAccount); 38 | return m.matches(); 39 | } 40 | 41 | public static String getRandom(String source, int length) { 42 | return (source == null || source.equals("")) ? null : getRandom(source.toCharArray(), length); 43 | } 44 | 45 | public static String getRandom(char[] sourceChar, int length) { 46 | if (sourceChar == null || sourceChar.length == 0 || length < 0) { 47 | return null; 48 | } 49 | 50 | StringBuilder str = new StringBuilder(length); 51 | Random random = new Random(); 52 | for (int i = 0; i < length; i++) { 53 | str.append(sourceChar[random.nextInt(sourceChar.length)]); 54 | } 55 | return str.toString(); 56 | } 57 | 58 | /** 59 | * 获取余额数值 60 | * 61 | * @param value "8865.4694 SYS" 62 | * @return 63 | */ 64 | public static String getBalance(String value) { 65 | if (value == null || value.equals("")) { 66 | return ""; 67 | } 68 | String vs[] = value.split(" "); 69 | if (vs.length == 2) { 70 | return vs[0]; 71 | } 72 | return ""; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/Hex.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | /** 4 | * Hex 5 | * 6 | * @author espritblock http://eblock.io 7 | */ 8 | public class Hex { 9 | 10 | /** 11 | * toBytes 12 | * 13 | * @return 14 | */ 15 | public static byte[] toBytes(String hex) { 16 | if (hex == null || hex.length() % 2 != 0) { 17 | throw new EException("args_eroor", "args is error"); 18 | } 19 | char[] hbyte = hex.toCharArray(); 20 | int length = hbyte.length / 2; 21 | byte[] raw = new byte[length]; 22 | for (int i = 0; i < length; i++) { 23 | int high = Character.digit(hbyte[i * 2], 16); 24 | int low = Character.digit(hbyte[i * 2 + 1], 16); 25 | if (high < 0 || low < 0) { 26 | throw new RuntimeException("Invalid hex digit " + hbyte[i * 2] + hbyte[i * 2 + 1]); 27 | } 28 | int value = (high << 4) | low; 29 | if (value > 127) 30 | value -= 256; 31 | raw[i] = (byte) value; 32 | } 33 | return raw; 34 | } 35 | 36 | /** 37 | * bytesToHexString 38 | * 39 | * @param src 40 | * @return 41 | */ 42 | public static String bytesToHexString(byte[] src) { 43 | StringBuilder stringBuilder = new StringBuilder(""); 44 | if (src == null || src.length <= 0) { 45 | return null; 46 | } 47 | for (int i = 0; i < src.length; i++) { 48 | int v = src[i] & 0xFF; 49 | String hv = Integer.toHexString(v); 50 | if (hv.length() < 2) { 51 | stringBuilder.append(0); 52 | } 53 | stringBuilder.append(hv); 54 | } 55 | return stringBuilder.toString(); 56 | } 57 | 58 | /** 59 | * hexStringToBytes 60 | * 61 | * @param hexString 62 | * @return 63 | */ 64 | public static byte[] hexStringToBytes(String hexString) { 65 | if (hexString == null || hexString.equals("")) { 66 | return null; 67 | } 68 | hexString = hexString.toUpperCase(); 69 | int length = hexString.length() / 2; 70 | char[] hexChars = hexString.toCharArray(); 71 | byte[] d = new byte[length]; 72 | for (int i = 0; i < length; i++) { 73 | int pos = i * 2; 74 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); 75 | } 76 | return d; 77 | } 78 | 79 | private static byte charToByte(char c) { 80 | return (byte) "0123456789ABCDEF".indexOf(c); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils; 2 | 3 | import com.develop.wallet.eos.crypto.utils.ByteBuffer; 4 | import com.develop.wallet.eos.crypto.utils.ByteUtils; 5 | import com.develop.wallet.eos.model.BaseVo; 6 | import com.develop.wallet.eos.model.transaction.push.BaseTx; 7 | import com.develop.wallet.eos.model.transaction.push.FieldAnnotation; 8 | 9 | import java.lang.reflect.Field; 10 | import java.lang.reflect.Method; 11 | import java.util.*; 12 | 13 | 14 | public class ObjectUtils { 15 | 16 | private static Object getFieldValueByName(String fieldName, Object o) { 17 | try { 18 | String firstLetter = fieldName.substring(0, 1).toUpperCase(); 19 | String getter = "get" + firstLetter + fieldName.substring(1); 20 | Method method = o.getClass().getMethod(getter, new Class[]{}); 21 | Object value = method.invoke(o, new Object[]{}); 22 | return value; 23 | } catch (Exception e) { 24 | return null; 25 | } 26 | } 27 | 28 | /** 29 | * Bean2Map 30 | * 31 | * @param obj 32 | * @return 33 | */ 34 | public static Map Bean2Map(Object obj) { 35 | if (obj == null) { 36 | return null; 37 | } 38 | Map map = new LinkedHashMap<>(); 39 | Field[] fields = obj.getClass().getDeclaredFields(); 40 | // The Android client access to the order of the different lead to signature mistakes 41 | if (obj instanceof BaseTx) { 42 | List list = getOrderedField(fields); 43 | for (int i = 0; i < list.size(); i++) { 44 | map.put(list.get(i).getName(), getFieldValueByName(list.get(i).getName(), obj)); 45 | } 46 | } else { 47 | for (int i = 0; i < fields.length; i++) { 48 | map.put(fields[i].getName(), getFieldValueByName(fields[i].getName(), obj)); 49 | } 50 | } 51 | return map; 52 | } 53 | 54 | private static List getOrderedField(Field[] fields) { 55 | List fieldList = new ArrayList<>(); 56 | // Filter Field with annotations 57 | for (Field f : fields) { 58 | if (f.getAnnotation(FieldAnnotation.class) != null) { 59 | fieldList.add(f); 60 | } 61 | } 62 | 63 | // // for java 1.8 64 | // fieldList.sort(Comparator.comparingInt( 65 | // m -> m.getAnnotation(FieldAnnotation.class).order() 66 | // )); 67 | 68 | Collections.sort(fieldList, new Comparator() { 69 | 70 | @Override 71 | public int compare(Field o1, Field o2) { 72 | int i = o1.getAnnotation(FieldAnnotation.class).order() - o2.getAnnotation(FieldAnnotation.class).order(); 73 | return i; 74 | } 75 | }); 76 | return fieldList; 77 | } 78 | 79 | public static void writeBytes(Object vo, ByteBuffer bf) { 80 | Map params = null; 81 | if (vo instanceof Map) { 82 | params = (Map) vo; 83 | } else { 84 | params = Bean2Map(vo); 85 | } 86 | Map objMap = new LinkedHashMap<>(); 87 | for (String key : params.keySet()) { 88 | Object obj = params.get(key); 89 | if (obj instanceof BaseVo || obj instanceof List || obj instanceof Map) { 90 | if ("authorization".equals(key)) { 91 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 92 | for (Object ob : (List) obj) { 93 | writeBytes(ob, bf); 94 | } 95 | } else if ("data".equals(key)) { 96 | ByteBuffer databf = new ByteBuffer(); 97 | writeBytes(obj, databf); 98 | bf.concat(ByteUtils.writerVarint32(String.valueOf(databf.getBuffer().length))); 99 | bf.concat(databf.getBuffer()); 100 | } else if ("transaction_extensions".equals(key)) { 101 | 102 | } else { 103 | objMap.put(key, obj); 104 | } 105 | } else { 106 | if ("chain_id".equals(key)) { 107 | bf.concat(Hex.hexStringToBytes(obj.toString())); 108 | } else if ("expiration".equals(key)) { 109 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 110 | } else if ("ref_block_num".equals(key)) { 111 | bf.concat(ByteUtils.writerUnit16(obj.toString())); 112 | } else if ("ref_block_prefix".equals(key)) { 113 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 114 | } else if ("net_usage_words".equals(key)) { 115 | bf.concat(ByteUtils.writerVarint32(obj.toString())); 116 | } else if ("max_cpu_usage_ms".equals(key)) { 117 | bf.concat(ByteUtils.writerUnit8(obj.toString())); 118 | } else if ("delay_sec".equals(key)) { 119 | bf.concat(ByteUtils.writerVarint32(obj.toString())); 120 | } else if ("account".equals(key)) { 121 | bf.concat(ByteUtils.writeName(obj.toString())); 122 | } else if ("name".equals(key)) { 123 | bf.concat(ByteUtils.writeName(obj.toString())); 124 | } else if ("actor".equals(key)) { 125 | bf.concat(ByteUtils.writeName(obj.toString())); 126 | } else if ("permission".equals(key)) { 127 | bf.concat(ByteUtils.writeName(obj.toString())); 128 | } else if ("from".equals(key)) { 129 | bf.concat(ByteUtils.writeName(obj.toString())); 130 | } else if ("to".equals(key)) { 131 | bf.concat(ByteUtils.writeName(obj.toString())); 132 | } else if ("quantity".equals(key)) { 133 | bf.concat(ByteUtils.writerAsset(obj.toString())); 134 | } else if ("memo".equals(key)) { 135 | bf.concat(ByteUtils.writerString(obj.toString())); 136 | } else if ("creator".equals(key)) { 137 | bf.concat(ByteUtils.writeName(obj.toString())); 138 | } else if ("owner".equals(key)) { 139 | bf.concat(ByteUtils.writerKey(obj.toString())); 140 | } else if ("active".equals(key)) { 141 | bf.concat(ByteUtils.writerKey(obj.toString())); 142 | } else if ("payer".equals(key)) { 143 | bf.concat(ByteUtils.writeName(obj.toString())); 144 | } else if ("receiver".equals(key)) { 145 | bf.concat(ByteUtils.writeName(obj.toString())); 146 | } else if ("bytes".equals(key)) { 147 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 148 | } else if ("stake_net_quantity".equals(key)) { 149 | bf.concat(ByteUtils.writerAsset(obj.toString())); 150 | } else if ("stake_cpu_quantity".equals(key)) { 151 | bf.concat(ByteUtils.writerAsset(obj.toString())); 152 | } else if ("transfer".equals(key)) { 153 | bf.concat(ByteUtils.writerUnit8(obj.toString())); 154 | } else if ("voter".equals(key)) { 155 | bf.concat(ByteUtils.writeName(obj.toString())); 156 | } else if ("proxy".equals(key)) { 157 | bf.concat(ByteUtils.writeName(obj.toString())); 158 | } else if ("producer".equals(key)) { 159 | bf.concat(ByteUtils.writeName(obj.toString())); 160 | } else if ("close-owner".equals(key)) { 161 | bf.concat(ByteUtils.writeName(obj.toString())); 162 | } else if ("close-symbol".equals(key)) { 163 | bf.concat(ByteUtils.writerSymbol(obj.toString())); 164 | } else if ("upfrom".equals(key)) { 165 | bf.concat(ByteUtils.writeName(obj.toString())); 166 | } else if ("upto".equals(key)) { 167 | bf.concat(ByteUtils.writeName(obj.toString())); 168 | } else if ("value".equals(key)) { 169 | bf.concat(ByteUtils.writerAsset(obj.toString())); 170 | } 171 | } 172 | } 173 | for (String key : objMap.keySet()) { 174 | Object obj = params.get(key); 175 | if ("context_free_actions".equals(key)) { 176 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 177 | for (Object ob : (List) obj) { 178 | writeBytes(ob, bf); 179 | } 180 | } else if ("actions".equals(key)) { 181 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 182 | for (Object ob : (List) obj) { 183 | writeBytes(ob, bf); 184 | } 185 | } else if ("producers".equals(key)) { 186 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 187 | for (Object ob : (List) obj) { 188 | Map mp = new HashMap<>(); 189 | mp.put("producer", ob); 190 | writeBytes(mp, bf); 191 | } 192 | } else { 193 | writeBytes(obj, bf); 194 | } 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/ese/Action.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils.ese; 2 | 3 | /** 4 | * Action 5 | * 6 | * @author espritblock http://eblock.io 7 | */ 8 | public enum Action { 9 | 10 | transfer("${precision},${quantity}@eosio.token"), account("account"), ram("ram"), delegate("${precision},${quantity}@eosio.token"), voteproducer("voteproducer"), 11 | close("${precision},${quantity}@eosio.token"), up("${precision},${value}@eosio.token"), 12 | ; 13 | 14 | private String code; 15 | 16 | private Action(String code) { 17 | this.code = code; 18 | } 19 | 20 | public String getCode() { 21 | return code; 22 | } 23 | 24 | public void setCode(String code) { 25 | this.code = code; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/ese/DataParam.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils.ese; 2 | 3 | 4 | import com.develop.wallet.eos.crypto.utils.ByteUtils; 5 | import com.develop.wallet.eos.utils.EException; 6 | 7 | /** 8 | * DataParam 9 | * 10 | * @author espritblock http://eblock.io 11 | */ 12 | public class DataParam { 13 | 14 | public DataParam(String value, DataType type, Action action) { 15 | this.value = value; 16 | this.type = type; 17 | if (type == DataType.asset || type == DataType.symbol) { 18 | if (action == action.up) { 19 | String vs[] = value.split(" "); 20 | if (vs.length < 2) { 21 | throw new EException("error", "quantity error"); 22 | } 23 | String ammount = vs[0]; 24 | String ams[] = ammount.split("[.]"); 25 | int precision = 0; 26 | if (ams.length > 1) { 27 | precision = ams[1].length(); 28 | } 29 | this.value = vs[0] + " " + action.getCode().replace("${precision}", String.valueOf(precision)).replace("${value}", vs[1]); 30 | } else if (action == action.transfer || action == action.delegate || action == action.close) { 31 | String vs[] = value.split(" "); 32 | if (vs.length < 2) { 33 | throw new EException("error", "quantity error"); 34 | } 35 | String ammount = vs[0]; 36 | String ams[] = ammount.split("[.]"); 37 | int precision = 0; 38 | if (ams.length > 1) { 39 | precision = ams[1].length(); 40 | } 41 | this.value = vs[0] + " " + action.getCode().replace("${precision}", String.valueOf(precision)).replace("${quantity}", vs[1]); 42 | } else { 43 | this.value = value; 44 | } 45 | } 46 | } 47 | 48 | private String value; 49 | 50 | private DataType type; 51 | 52 | public String getValue() { 53 | return value; 54 | } 55 | 56 | public void setValue(String value) { 57 | this.value = value; 58 | } 59 | 60 | public DataType getType() { 61 | return type; 62 | } 63 | 64 | public void setType(DataType type) { 65 | this.type = type; 66 | } 67 | 68 | public byte[] seria() { 69 | if (this.type == DataType.name) { 70 | return ByteUtils.writeName(this.value); 71 | } else if (this.type == DataType.asset) { 72 | return ByteUtils.writerAsset(this.value); 73 | } else if (this.type == DataType.symbol) { 74 | return ByteUtils.writerSymbol(this.value); 75 | } else if (this.type == DataType.unit32) { 76 | return ByteUtils.writerUnit32(this.value); 77 | } else if (this.type == DataType.unit16) { 78 | return ByteUtils.writerUnit16(this.value); 79 | } else if (this.type == DataType.key) { 80 | return ByteUtils.writerKey(this.value); 81 | } else if (this.type == DataType.varint32) { 82 | return ByteUtils.writerVarint32(this.value); 83 | } else if (this.type == DataType.unit64) { 84 | return ByteUtils.writeUint64(this.value); 85 | } else { 86 | return ByteUtils.writerString(this.value); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/ese/DataType.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils.ese; 2 | 3 | /** 4 | * DataType 5 | * 6 | * @author espritblock http://eblock.io 7 | */ 8 | public enum DataType { 9 | 10 | name("name"), asset("asset"), string("string"), key("key"), unit16("unit16"), unit32("unit32"), varint32( 11 | "varint32"), unit64("unit64"), symbol("symbol"); 12 | 13 | private DataType(String code) { 14 | this.code = code; 15 | } 16 | 17 | private String code; 18 | 19 | public String getCode() { 20 | return code; 21 | } 22 | 23 | public void setCode(String code) { 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/develop/wallet/eos/utils/ese/Ese.java: -------------------------------------------------------------------------------- 1 | package com.develop.wallet.eos.utils.ese; 2 | 3 | import com.develop.wallet.eos.crypto.utils.ByteUtils; 4 | import com.develop.wallet.eos.utils.Hex; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * Ese 12 | * 13 | * @author espritblock http://eblock.io 14 | */ 15 | public class Ese { 16 | 17 | /** 18 | * parseTransferData 19 | * 20 | * @return 21 | */ 22 | public static String parseTransferData(String from, String to, String quantity, String memo) { 23 | DataParam[] datas = new DataParam[]{new DataParam(from, DataType.name, Action.transfer), 24 | new DataParam(to, DataType.name, Action.transfer), 25 | new DataParam(quantity, DataType.asset, Action.transfer), 26 | new DataParam(memo, DataType.string, Action.transfer),}; 27 | byte[] allbyte = new byte[]{}; 28 | for (DataParam value : datas) { 29 | allbyte = ByteUtils.concat(allbyte, value.seria()); 30 | } 31 | // final byte [] b = allbyte.clone(); 32 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 33 | // for(int i=1;i<=a.length;i++) { 34 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 35 | // } 36 | return Hex.bytesToHexString(allbyte); 37 | } 38 | 39 | public static String parseUpData(String upfrom, String upto, String value) { 40 | DataParam[] datas = new DataParam[]{new DataParam(upfrom, DataType.name, Action.up), 41 | new DataParam(upto, DataType.name, Action.up), 42 | new DataParam(value, DataType.asset, Action.up)}; 43 | byte[] allbyte = new byte[]{}; 44 | for (DataParam dataParam : datas) { 45 | allbyte = ByteUtils.concat(allbyte, dataParam.seria()); 46 | } 47 | // final byte [] b = allbyte.clone(); 48 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 49 | // for(int i=1;i<=a.length;i++) { 50 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 51 | // } 52 | return Hex.bytesToHexString(allbyte); 53 | } 54 | 55 | 56 | /** 57 | * parseTransferData 58 | * 59 | * @return 60 | */ 61 | public static String parseVoteProducerData(String voter, String proxy, List producers) { 62 | List datas = new ArrayList(); 63 | datas.add(new DataParam(voter, DataType.name, Action.voteproducer)); 64 | datas.add(new DataParam(proxy, DataType.name, Action.voteproducer)); 65 | datas.add(new DataParam(String.valueOf(producers.size()), DataType.varint32, Action.voteproducer)); 66 | for (String producer : producers) { 67 | datas.add(new DataParam(producer, DataType.name, Action.voteproducer)); 68 | } 69 | byte[] allbyte = new byte[]{}; 70 | for (DataParam value : datas) { 71 | allbyte = ByteUtils.concat(allbyte, value.seria()); 72 | } 73 | // final byte [] b = allbyte.clone(); 74 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 75 | // for(int i=1;i<=a.length;i++) { 76 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 77 | // } 78 | return Hex.bytesToHexString(allbyte); 79 | } 80 | 81 | 82 | /** 83 | * parseTransferData 84 | * 85 | * @return 86 | */ 87 | public static String parseAccountData(String creator, String name, String onwer, String active) { 88 | 89 | DataParam[] datas = new DataParam[]{ 90 | // creator 91 | new DataParam(creator, DataType.name, Action.account), 92 | // name 93 | new DataParam(name, DataType.name, Action.account), 94 | // owner 95 | new DataParam(onwer, DataType.key, Action.account), 96 | // active 97 | new DataParam(active, DataType.key, Action.account), 98 | 99 | }; 100 | byte[] allbyte = new byte[]{}; 101 | for (DataParam value : datas) { 102 | allbyte = ByteUtils.concat(allbyte, value.seria()); 103 | } 104 | return Hex.bytesToHexString(allbyte); 105 | } 106 | 107 | /** 108 | * parseBuyRamData 109 | * 110 | * @return 111 | */ 112 | public static String parseDelegateData(String from, String receiver, String stakeNetQuantity, 113 | String stakeCpuQuantity, int transfer) { 114 | 115 | DataParam[] datas = new DataParam[]{new DataParam(from, DataType.name, Action.delegate), 116 | new DataParam(receiver, DataType.name, Action.delegate), 117 | new DataParam(stakeNetQuantity, DataType.asset, Action.delegate), 118 | new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate), 119 | new DataParam(String.valueOf(transfer), DataType.varint32, Action.delegate) 120 | 121 | }; 122 | byte[] allbyte = new byte[]{}; 123 | for (DataParam value : datas) { 124 | allbyte = ByteUtils.concat(allbyte, value.seria()); 125 | } 126 | return Hex.bytesToHexString(allbyte); 127 | } 128 | 129 | /** 130 | * parseTransferData 131 | * 132 | * @return 133 | */ 134 | public static String parseBuyRamData(String payer, String receiver, Long bytes) { 135 | 136 | DataParam[] datas = new DataParam[]{new DataParam(payer, DataType.name, Action.ram), 137 | new DataParam(receiver, DataType.name, Action.ram), 138 | new DataParam(String.valueOf(bytes), DataType.unit32, Action.ram) 139 | 140 | }; 141 | byte[] allbyte = new byte[]{}; 142 | for (DataParam value : datas) { 143 | allbyte = ByteUtils.concat(allbyte, value.seria()); 144 | } 145 | return Hex.bytesToHexString(allbyte); 146 | } 147 | 148 | /** 149 | * parseCloseData 150 | * 151 | * @return 152 | */ 153 | public static String parseCloseData(String owner, String symbol) { 154 | DataParam[] datas = new DataParam[]{ 155 | new DataParam(owner, DataType.name, Action.close), 156 | new DataParam(symbol, DataType.symbol, Action.close) 157 | }; 158 | byte[] allbyte = new byte[]{}; 159 | for (DataParam value : datas) { 160 | allbyte = ByteUtils.concat(allbyte, value.seria()); 161 | } 162 | return Hex.bytesToHexString(allbyte); 163 | } 164 | } 165 | --------------------------------------------------------------------------------