├── .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