├── .gitignore ├── README.md ├── build.gradle ├── settings.gradle └── src └── main └── java └── party └── loveit └── eosforandroidlibrary ├── Ecc.java ├── OfflineSign.java ├── OfflineTest.java ├── Rpc.java ├── Test.java ├── ecc ├── Curve.java ├── EccTool.java ├── Ecdsa.java ├── FieldElement.java ├── Point.java └── Secp256k.java ├── ese ├── Action.java ├── DataParam.java ├── DataType.java └── Ese.java ├── rpc ├── exception │ ├── ApiError.java │ ├── ApiException.java │ ├── Error.java │ └── ErrorDetails.java ├── service │ └── RpcService.java ├── utils │ └── Generator.java └── vo │ ├── BaseVo.java │ ├── Block.java │ ├── ChainInfo.java │ ├── SignParam.java │ ├── TableRows.java │ ├── TableRowsReq.java │ ├── account │ ├── Account.java │ ├── CpuLimit.java │ ├── Key.java │ ├── NetLimit.java │ ├── Permission.java │ └── RequiredAuth.java │ └── transaction │ ├── Processed.java │ ├── Receipt.java │ ├── Transaction.java │ └── push │ ├── Tx.java │ ├── TxAction.java │ ├── TxActionAuth.java │ ├── TxExtenstions.java │ ├── TxRequest.java │ └── TxSign.java └── utils ├── Base58.java ├── ByteBuffer.java ├── ByteUtils.java ├── EException.java ├── GeneralDigest.java ├── Hex.java ├── ObjectUtils.java ├── Ripemd160.java └── Sha.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.nar 19 | *.ear 20 | *.zip 21 | *.tar.gz 22 | *.rar 23 | 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | 27 | .gradle/ 28 | .idea/ 29 | out/ 30 | build/ 31 | gradle.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EOSForJava 2 | A EOS library for Java 3 | 4 | > # support java sdk >= 6 # 5 | 6 | 7 | 中文版文档:[https://blog.csdn.net/wypeng2010/article/details/85113370](https://blog.csdn.net/wypeng2010/article/details/85113370) 8 | 9 | **- Use it** 10 | 11 | 1. first add Bip44ForJava dependencies 12 | 13 | > implementation 'party.52it:Bip44ForJava:1.0.0' 14 | 15 | 2. generate EOS 16 | 17 | ## code: ## 18 | ```java 19 | List words = Bip44Utils.generateMnemonicWords(); 20 | Log.e("TAG", "words: " + words.toString()); 21 | 22 | 23 | BigInteger pri = Bip44Utils.getPathPrivateKey(words,"m/44'/194'/0'/0/0"); 24 | Log.e("TAG", "pri1: " + pri.toString(16)); 25 | 26 | String eospk = Ecc.seedPrivate(pri); 27 | Log.e("TAG", "EOS privateKey: " + eospk); 28 | 29 | String eospuk = Ecc.privateToPublic(eospk); 30 | Log.e("TAG", "EOS publicKey: " + eospuk); 31 | 32 | ``` 33 | ## result: ## 34 | ```base 35 | 2018-12-06 14:41:26.636 976-1101/? E/TAG: words: [cluster, page, museum, protect, bronze, leg, few, guide, sport, resource, luxury, magnet] 36 | 2018-12-06 14:41:27.107 976-1101/party.loveit.eosforandroid E/TAG: pri1: b021d8432d5c473b8b9be1b943de3effedff8cf2339bcb5c29b3031cca55316 37 | 2018-12-06 14:41:27.114 976-1101/party.loveit.eosforandroid E/TAG: EOS privateKey: 5Hu8mmzA4ud8sJFJy4ha5qqiDB36CVk5rBVc6bAEEHGuhDRfaF6 38 | 2018-12-06 14:41:27.187 976-1101/party.loveit.eosforandroid E/TAG: EOS publicKey: EOS6BpNg9SebtbeCFvkt1dZTQr4293gvdvpeRo9ZnDmHAZ3guNvGz 39 | ``` 40 | 41 | 3. Specific test code 42 | 43 | ```java 44 | System.out.println("============= Custom data signature ==============="); 45 | String sign = Ecc.sign(pk,"is京東價as看到可可是是是@#¥%……&*(CVBNM《d "); 46 | System.out.println("sign :" + sign + " \n "); 47 | 48 | System.out.println("============= Transfer data serialization ==============="); 49 | String data = Ecc.parseTransferData("fromaccount", "toaccount", "10.0020 SYS", "测试123abcdo./,./!@##$%"); 50 | System.out.println("seriz data :" + data); 51 | System.out.println("transfer eq eosjs seriz " + data.equals(eosjs_transfer_seriz)+" \n "); 52 | 53 | System.out.println("============= Create account data serialization ==============="); 54 | String data1 = Ecc.parseAccountData("eosio", "espritbloc1.","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8FPooohZiiCAYXahWCQRxgXXzUbS2gNELAeYCUgGdDMbd2FHQT"); 55 | System.out.println("seriz data :" + data1); 56 | System.out.println("account eq eosjs seriz " + data1.equals(eosjs_account_seriz)); 57 | 58 | 59 | System.out.println("\n******************* Ecc End *******************\n\n\n"); 60 | 61 | System.out.println("******************* Rpc Start *******************\n"); 62 | 63 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 64 | 65 | System.out.println("============= Transfer ==============="); 66 | try { 67 | Transaction t1 = rpc.transfer("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","espritblocke", "inita","initb", "12.2821 MSP", ""); 68 | System.out.println("转账成功 = " + t1.getTransactionId()+" \n "); 69 | }catch(Exception ex) { 70 | ex.printStackTrace(); 71 | } 72 | 73 | System.out.println("============= Create an account and mortgage ==============="); 74 | try { 75 | Transaction t2 = rpc.createAccount("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","eosio","ccccc..bbbbb", "EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx", 8192l, "0.01 SYS","0.01 SYS", 0l); 76 | System.out.println("创建成功 = " + t2.getTransactionId()+" \n "); 77 | }catch(Exception ex) { 78 | ex.printStackTrace(); 79 | } 80 | System.out.println("============= Create an account without a mortgage ==============="); 81 | try { 82 | Transaction t3 = rpc.createAccount("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","eosio","bbbb..54321", "EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx", 8192l); 83 | System.out.println("创建成功 = " + t3.getTransactionId()+" \n "); 84 | }catch(Exception ex) { 85 | ex.printStackTrace(); 86 | } 87 | 88 | System.out.println("============= Proxy voting ==============="); 89 | try { 90 | List produces = new ArrayList<>(); 91 | produces.add("pppppeeeeooo"); 92 | produces.add("mdddssssddds"); 93 | produces.add("mdjddjddddds"); 94 | rpc.voteproducer("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "epskdkdsddss","iuewjdkslsdc",produces); 95 | } catch (Exception e) { 96 | e.printStackTrace(); 97 | } 98 | 99 | System.out.println("============= Turn off the token with a balance of 0 ==============="); 100 | try { 101 | rpc.close("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "合约账户", "关闭账户", "0.0000 IPOS"); 102 | }catch(ApiException e) { 103 | e.printStackTrace(); 104 | }catch(Exception ex) { 105 | ex.printStackTrace(); 106 | } 107 | System.out.println("\n******************* Rpc End *******************"); 108 | 109 | ``` 110 | 4. OfflineSign 111 | 112 | ```java 113 | public static void testOfflineCreate() { 114 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 115 | 116 | SignParam params = rpc.getOfflineSignParams(60l); 117 | 118 | OfflineSign sign = new OfflineSign(); 119 | 120 | String content = ""; 121 | try { 122 | content = sign.createAccount(params, "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "eeeeeeeeeeee", 123 | "555555555551", "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", 124 | "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", 8000l); 125 | System.out.println(content); 126 | } catch (Exception e) { 127 | e.printStackTrace(); 128 | } 129 | 130 | try { 131 | Transaction tx = rpc.pushTransaction(content); 132 | System.out.println(tx.getTransactionId()); 133 | } catch (ApiException ex) { 134 | System.out.println(ex.getError().getCode()); 135 | } catch (Exception e) { 136 | e.printStackTrace(); 137 | } 138 | } 139 | 140 | public static void testOfflineTransfer() { 141 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 142 | 143 | SignParam params = rpc.getOfflineSignParams(60l); 144 | 145 | OfflineSign sign = new OfflineSign(); 146 | 147 | String content = ""; 148 | try { 149 | content = sign.transfer(params, "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "eosio.token", 150 | "eeeeeeeeeeee", "555555555551", "372.0993 EOS", "test"); 151 | System.out.println(content); 152 | } catch (Exception e) { 153 | e.printStackTrace(); 154 | } 155 | 156 | try { 157 | Transaction tx = rpc.pushTransaction(content); 158 | System.out.println(tx.getTransactionId()); 159 | } catch (ApiException ex) { 160 | System.out.println(ex.getError().getCode()); 161 | } catch (Exception e) { 162 | e.printStackTrace(); 163 | } 164 | } 165 | ``` 166 | 167 | **- How to dependencies** 168 | 1. Maven 169 | 170 | ```base 171 | 172 | party.52it 173 | EOSForJava 174 | 1.0.0 175 | 176 | ``` 177 | 2. Gradle 178 | 179 | ```base 180 | compile 'party.52it:EOSForJava:1.0.0' 181 | 182 | or 183 | 184 | implementation 'party.52it:EOSForJava:1.0.0' 185 | 186 | ``` 187 | 3. Ivy 188 | 189 | ```base 190 | 191 | ``` 192 | 193 | 194 | 195 | 196 | **- License** 197 | 198 | Copyright 2018 52it.party 199 | 200 | Licensed under the Apache License, Version 2.0 (the "License"); 201 | you may not use this file except in compliance with the License. 202 | You may obtain a copy of the License at 203 | 204 | http://www.apache.org/licenses/LICENSE-2.0 205 | 206 | Unless required by applicable law or agreed to in writing, software 207 | distributed under the License is distributed on an "AS IS" BASIS, 208 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 209 | See the License for the specific language governing permissions and 210 | limitatio 211 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'maven-publish' 4 | id 'signing' 5 | } 6 | 7 | group 'party.52it' 8 | version '1.0.0' 9 | 10 | sourceCompatibility = 1.8 11 | 12 | tasks.withType(JavaCompile) { 13 | options.encoding = 'UTF-8' 14 | } 15 | task sourcesJar(type: Jar) { 16 | from sourceSets.main.allJava 17 | classifier = 'sources' 18 | } 19 | 20 | task javadocJar(type: Jar) { 21 | from javadoc 22 | classifier = 'javadoc' 23 | } 24 | 25 | //添加UTF-8编码否则注释可能JAVADOC文档可能生成不了 26 | javadoc { 27 | options{ 28 | encoding "UTF-8" 29 | charSet 'UTF-8' 30 | author true 31 | version true 32 | failOnError false 33 | links "http://docs.oracle.com/javase/7/docs/api" 34 | } 35 | } 36 | 37 | repositories { 38 | mavenCentral() 39 | } 40 | 41 | dependencies { 42 | testCompile group: 'junit', name: 'junit', version: '4.12' 43 | //retrofit 44 | implementation 'com.squareup.retrofit2:retrofit:2.4.0' 45 | implementation 'com.squareup.retrofit2:converter-jackson:2.4.0' 46 | implementation 'org.apache.commons:commons-lang3:3.6' 47 | } 48 | 49 | publishing{ 50 | publications{ 51 | mavenJava(MavenPublication) { 52 | from components.java 53 | artifact sourcesJar 54 | artifact javadocJar 55 | 56 | pom { 57 | name = 'EOSForJava' 58 | description = 'A EOS library for Java' 59 | url = 'https://github.com/wypeng2012/EOSForJava' 60 | licenses { 61 | license { 62 | name = 'The Apache License, Version 2.0' 63 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 64 | } 65 | } 66 | developers { 67 | developer { 68 | name = 'Jerry Wang' 69 | email = 'wypeng2012@gmail.com' 70 | organization = '52it' 71 | organizationUrl = 'https://52it.party/' 72 | } 73 | } 74 | scm { 75 | connection = 'scm:git:git@github.com:wypeng2012/EOSForJava.git' 76 | developerConnection = 'scm:git:ssh@github.com:wypeng2012/EOSForJava.git' 77 | url = 'https://github.com/wypeng2012/EOSForJava' 78 | } 79 | } 80 | } 81 | } 82 | repositories{ 83 | maven{ 84 | url "https://oss.sonatype.org/service/local/staging/deploy/maven2" 85 | credentials { 86 | username sonatypeUsername 87 | password sonatypePassword 88 | } 89 | } 90 | } 91 | } 92 | 93 | signing { 94 | sign publishing.publications.mavenJava 95 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EOSForJava' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/Ecc.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary; 2 | 3 | import java.math.BigInteger; 4 | import java.util.List; 5 | 6 | import party.loveit.eosforandroidlibrary.ecc.EccTool; 7 | import party.loveit.eosforandroidlibrary.ese.Ese; 8 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxSign; 9 | 10 | 11 | /** 12 | * Ecc,用户生成公私钥,签名,数据序列化 13 | * 14 | * @author 15 | * 16 | */ 17 | public class Ecc { 18 | 19 | /** 20 | * 通过种子生成私钥 21 | * 22 | * @param priKey 23 | * 种子 24 | * @return 25 | */ 26 | 27 | public static String seedPrivate(BigInteger priKey) { 28 | return EccTool.privateKeyFromSeed(priKey); 29 | } 30 | /** 31 | * 通过种子生成私钥 32 | * 33 | * @param seed 34 | * 种子 35 | * @return 36 | */ 37 | public static String seedPrivate(byte[] seed) { 38 | return EccTool.privateKeyFromSeed(seed); 39 | } 40 | 41 | 42 | /** 43 | * 通过私钥生成公钥 44 | * 45 | * @param privateKey 46 | * 私钥 47 | * @return 48 | */ 49 | public static String privateToPublic(String privateKey) { 50 | return EccTool.privateToPublic(privateKey); 51 | } 52 | 53 | /** 54 | * 普通数据签名 55 | * 56 | * @param privateKey 57 | * 私钥 58 | * @param data 59 | * 需要签名的数据 60 | * @return 61 | */ 62 | public static String sign(String privateKey, String data) { 63 | return EccTool.sign(privateKey, data); 64 | } 65 | 66 | /** 67 | * 交易签名 68 | * 69 | * @param privateKey 70 | * 私钥 71 | * @param sign 72 | * 需要签名的对象 73 | * @return 74 | */ 75 | public static String signTransaction(String privateKey, TxSign sign) { 76 | return EccTool.signTransaction(privateKey, sign); 77 | } 78 | 79 | /** 80 | * 转账数据序列化 81 | * 82 | * @param from 83 | * 从 84 | * @param to 85 | * 到 86 | * @param quantity 87 | * 转账金额和币种 88 | * @param memo 89 | * 备注留言 90 | * @return 91 | */ 92 | public static String parseTransferData(String from, String to, String quantity, String memo) { 93 | return Ese.parseTransferData(from, to, quantity, memo); 94 | } 95 | 96 | /** 97 | * 98 | * @param voter 99 | * @param proxy 100 | * @param producers 101 | * @return 102 | */ 103 | public static String parseVoteProducerData(String voter, String proxy, List producers) { 104 | return Ese.parseVoteProducerData(voter, proxy, producers); 105 | } 106 | 107 | /** 108 | * 创建账户数据序列化 109 | * 110 | * @param creator 111 | * 创建者 112 | * @param name 113 | * 账户名 114 | * @param onwer 115 | * onwer公钥 116 | * @param active 117 | * active公钥 118 | * @return 119 | */ 120 | public static String parseAccountData(String creator, String name, String onwer, String active) { 121 | return Ese.parseAccountData(creator, name, onwer, active); 122 | } 123 | 124 | /** 125 | * 购买ram数据序列化 126 | * 127 | * @param payer 128 | * 付款账户 129 | * @param receiver 130 | * 接收账户 131 | * @param bytes 132 | * 购买字节数量 133 | * @return 134 | */ 135 | public static String parseBuyRamData(String payer, String receiver, Long bytes) { 136 | return Ese.parseBuyRamData(payer, receiver, bytes); 137 | } 138 | 139 | /** 140 | * 抵押数据序列化 141 | * 142 | * @param from 143 | * 抵押账户 144 | * @param receiver 145 | * 接受账户 146 | * @param stakeNetQuantity 147 | * 网络抵押数量和币种 148 | * @param stakeCpuQuantity 149 | * CPU抵押数量和币种 150 | * @param transfer 151 | * 是否讲抵押资产转送给对方,0自己所有,1对方所有 152 | * @return 153 | */ 154 | public static String parseBuyRamData(String from, String receiver, String stakeNetQuantity, String stakeCpuQuantity, 155 | int transfer) { 156 | return Ese.parseDelegateData(from, receiver, stakeNetQuantity, stakeCpuQuantity, transfer); 157 | } 158 | 159 | /** 160 | * 关闭token 161 | * @param owner 162 | * @param symbol 163 | * @return 164 | */ 165 | public static String parseCloseData(String owner, String symbol) { 166 | return Ese.parseCloseData(owner, symbol); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/OfflineSign.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.ArrayList; 7 | import java.util.Date; 8 | import java.util.LinkedHashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.TimeZone; 12 | 13 | import party.loveit.eosforandroidlibrary.ese.Action; 14 | import party.loveit.eosforandroidlibrary.ese.DataParam; 15 | import party.loveit.eosforandroidlibrary.ese.DataType; 16 | import party.loveit.eosforandroidlibrary.ese.Ese; 17 | import party.loveit.eosforandroidlibrary.rpc.vo.SignParam; 18 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.Tx; 19 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxAction; 20 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxRequest; 21 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxSign; 22 | 23 | 24 | /** 25 | * 26 | * @author espritblock http://eblock.io 27 | * 28 | */ 29 | public class OfflineSign { 30 | 31 | SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 32 | 33 | public OfflineSign() { 34 | dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); 35 | } 36 | 37 | /** 38 | * 39 | * @param compression 40 | * @param pushTransaction 41 | * @param signatures 42 | * @return 43 | * @throws Exception 44 | */ 45 | public String pushTransaction(String compression, Tx pushTransaction, String[] signatures) throws Exception { 46 | ObjectMapper mapper = new ObjectMapper(); 47 | String mapJakcson = mapper.writeValueAsString(new TxRequest(compression, pushTransaction, signatures)); 48 | return mapJakcson; 49 | } 50 | 51 | /** 52 | * 离线签名转账 53 | * 54 | * @param signParam 55 | * @param pk 56 | * @param contractAccount 57 | * @param from 58 | * @param to 59 | * @param quantity 60 | * @param memo 61 | * @return 62 | * @throws Exception 63 | */ 64 | public String transfer(SignParam signParam, String pk, String contractAccount, String from, String to, 65 | String quantity, String memo) throws Exception { 66 | Tx tx = new Tx(); 67 | tx.setExpiration(signParam.getHeadBlockTime().getTime() / 1000 + signParam.getExp()); 68 | tx.setRef_block_num(signParam.getLastIrreversibleBlockNum()); 69 | tx.setRef_block_prefix(signParam.getRefBlockPrefix()); 70 | tx.setNet_usage_words(0l); 71 | tx.setMax_cpu_usage_ms(0l); 72 | tx.setDelay_sec(0l); 73 | // actions 74 | List actions = new ArrayList<>(); 75 | // data 76 | Map dataMap = new LinkedHashMap<>(); 77 | dataMap.put("from", from); 78 | dataMap.put("to", to); 79 | dataMap.put("quantity", new DataParam(quantity, DataType.asset, Action.transfer).getValue()); 80 | dataMap.put("memo", memo); 81 | // action 82 | TxAction action = new TxAction(from, contractAccount, "transfer", dataMap); 83 | actions.add(action); 84 | tx.setActions(actions); 85 | // sgin 86 | String sign = Ecc.signTransaction(pk, new TxSign(signParam.getChainId(), tx)); 87 | // data parse 88 | String data = Ecc.parseTransferData(from, to, quantity, memo); 89 | // reset data 90 | action.setData(data); 91 | // reset expiration 92 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 93 | return pushTransaction("none", tx, new String[] { sign }); 94 | } 95 | 96 | /** 97 | * 离线签名创建账户 98 | * 99 | * @param signParam 100 | * @param pk 101 | * @param creator 102 | * @param newAccount 103 | * @param owner 104 | * @param active 105 | * @param buyRam 106 | * @return 107 | * @throws Exception 108 | */ 109 | public String createAccount(SignParam signParam, String pk, String creator, String newAccount, String owner, 110 | String active, Long buyRam) throws Exception { 111 | Tx tx = new Tx(); 112 | tx.setExpiration(signParam.getHeadBlockTime().getTime() / 1000 + signParam.getExp()); 113 | tx.setRef_block_num(signParam.getLastIrreversibleBlockNum()); 114 | tx.setRef_block_prefix(signParam.getRefBlockPrefix()); 115 | tx.setNet_usage_words(0l); 116 | tx.setMax_cpu_usage_ms(0l); 117 | tx.setDelay_sec(0l); 118 | // actions 119 | List actions = new ArrayList<>(); 120 | tx.setActions(actions); 121 | // create 122 | Map createMap = new LinkedHashMap<>(); 123 | createMap.put("creator", creator); 124 | createMap.put("name", newAccount); 125 | createMap.put("owner", owner); 126 | createMap.put("active", active); 127 | TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap); 128 | actions.add(createAction); 129 | // buyrap 130 | Map buyMap = new LinkedHashMap<>(); 131 | buyMap.put("payer", creator); 132 | buyMap.put("receiver", newAccount); 133 | buyMap.put("bytes", buyRam); 134 | TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap); 135 | actions.add(buyAction); 136 | // sgin 137 | String sign = Ecc.signTransaction(pk, new TxSign(signParam.getChainId(), tx)); 138 | // data parse 139 | String accountData = Ese.parseAccountData(creator, newAccount, owner, active); 140 | createAction.setData(accountData); 141 | // data parse 142 | String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam); 143 | buyAction.setData(ramData); 144 | // reset expiration 145 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 146 | return pushTransaction("none", tx, new String[] { sign }); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/OfflineTest.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary; 2 | 3 | 4 | import party.loveit.eosforandroidlibrary.rpc.exception.ApiException; 5 | import party.loveit.eosforandroidlibrary.rpc.vo.SignParam; 6 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.Transaction; 7 | 8 | /** 9 | * 10 | * @author espritblock http://eblock.io 11 | * 12 | */ 13 | public class OfflineTest { 14 | 15 | public static void main(String[] args) { 16 | // testOfflineCreate(); 17 | testOfflineTransfer(); 18 | } 19 | 20 | public static void testOfflineCreate() { 21 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 22 | // 获取离线签名参数 23 | SignParam params = rpc.getOfflineSignParams(60l); 24 | // 离线签名 25 | OfflineSign sign = new OfflineSign(); 26 | // 交易信息 27 | String content = ""; 28 | try { 29 | content = sign.createAccount(params, "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "eeeeeeeeeeee", 30 | "555555555551", "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", 31 | "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", 8000l); 32 | System.out.println(content); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | // 广播交易 37 | try { 38 | Transaction tx = rpc.pushTransaction(content); 39 | System.out.println(tx.getTransactionId()); 40 | } catch (ApiException ex) { 41 | System.out.println(ex.getError().getCode()); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | public static void testOfflineTransfer() { 48 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 49 | // 获取离线签名参数 50 | SignParam params = rpc.getOfflineSignParams(60l); 51 | // 离线签名 52 | OfflineSign sign = new OfflineSign(); 53 | // 交易信息 54 | String content = ""; 55 | try { 56 | content = sign.transfer(params, "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "eosio.token", 57 | "eeeeeeeeeeee", "555555555551", "372.0993 EOS", "test"); 58 | System.out.println(content); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | // 广播交易 63 | try { 64 | Transaction tx = rpc.pushTransaction(content); 65 | System.out.println(tx.getTransactionId()); 66 | } catch (ApiException ex) { 67 | System.out.println(ex.getError().getCode()); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/Rpc.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.Comparator; 9 | import java.util.Date; 10 | import java.util.LinkedHashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.TimeZone; 14 | 15 | import party.loveit.eosforandroidlibrary.ese.Action; 16 | import party.loveit.eosforandroidlibrary.ese.DataParam; 17 | import party.loveit.eosforandroidlibrary.ese.DataType; 18 | import party.loveit.eosforandroidlibrary.ese.Ese; 19 | import party.loveit.eosforandroidlibrary.rpc.service.RpcService; 20 | import party.loveit.eosforandroidlibrary.rpc.utils.Generator; 21 | import party.loveit.eosforandroidlibrary.rpc.vo.Block; 22 | import party.loveit.eosforandroidlibrary.rpc.vo.ChainInfo; 23 | import party.loveit.eosforandroidlibrary.rpc.vo.SignParam; 24 | import party.loveit.eosforandroidlibrary.rpc.vo.TableRows; 25 | import party.loveit.eosforandroidlibrary.rpc.vo.TableRowsReq; 26 | import party.loveit.eosforandroidlibrary.rpc.vo.account.Account; 27 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.Transaction; 28 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.Tx; 29 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxAction; 30 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxRequest; 31 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxSign; 32 | 33 | 34 | public class Rpc { 35 | 36 | private final RpcService rpcService; 37 | 38 | SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 39 | 40 | public Rpc(String baseUrl) { 41 | dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); 42 | rpcService = Generator.createService(RpcService.class, baseUrl); 43 | } 44 | 45 | /** 46 | * 获得链信息 47 | * 48 | * @return 49 | */ 50 | public ChainInfo getChainInfo() { 51 | return Generator.executeSync(rpcService.getChainInfo()); 52 | } 53 | 54 | /** 55 | * 获得区块信息 56 | * 57 | * @param blockNumberOrId 58 | * 区块ID或者高度 59 | * @return 60 | */ 61 | public Block getBlock(String blockNumberOrId) { 62 | return Generator.executeSync(rpcService.getBlock(Collections.singletonMap("block_num_or_id", blockNumberOrId))); 63 | } 64 | 65 | /** 66 | * 获得账户信息 67 | * 68 | * @param account 69 | * 账户名称 70 | * @return 71 | */ 72 | public Account getAccount(String account) { 73 | return Generator.executeSync(rpcService.getAccount(Collections.singletonMap("account_name", account))); 74 | } 75 | 76 | /** 77 | * 获得table数据 78 | * 79 | * @param req 80 | * @return 81 | */ 82 | public TableRows getTableRows(TableRowsReq req) { 83 | return Generator.executeSync(rpcService.getTableRows(req)); 84 | } 85 | 86 | /** 87 | * 发送请求 88 | * 89 | * @param compression 90 | * 压缩 91 | * @param pushTransaction 92 | * 交易 93 | * @param signatures 94 | * 签名 95 | * @return 96 | * @throws Exception 97 | */ 98 | public Transaction pushTransaction(String compression, Tx pushTransaction, String[] signatures) throws Exception { 99 | ObjectMapper mapper = new ObjectMapper(); 100 | String mapJakcson = mapper.writeValueAsString(new TxRequest(compression, pushTransaction, signatures)); 101 | System.out.println(mapJakcson); 102 | return Generator 103 | .executeSync(rpcService.pushTransaction(new TxRequest(compression, pushTransaction, signatures))); 104 | } 105 | 106 | /** 107 | * 发送交易 108 | * 109 | * @param tx 110 | * @return 111 | * @throws Exception 112 | */ 113 | public Transaction pushTransaction(String tx) throws Exception { 114 | ObjectMapper mapper = new ObjectMapper(); 115 | TxRequest txObj = mapper.readValue(tx, TxRequest.class); 116 | return Generator.executeSync(rpcService.pushTransaction(txObj)); 117 | } 118 | 119 | /** 120 | * 获取离线签名参数 121 | * 122 | * @param exp 123 | * 过期时间秒 124 | * @return 125 | */ 126 | public SignParam getOfflineSignParams(Long exp) { 127 | SignParam params = new SignParam(); 128 | ChainInfo info = getChainInfo(); 129 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 130 | params.setChainId(info.getChainId()); 131 | params.setHeadBlockTime(info.getHeadBlockTime()); 132 | params.setLastIrreversibleBlockNum(info.getLastIrreversibleBlockNum()); 133 | params.setRefBlockPrefix(block.getRefBlockPrefix()); 134 | params.setExp(exp); 135 | return params; 136 | } 137 | 138 | /** 139 | * 转账 140 | * 141 | * @param pk 142 | * 私钥 143 | * @param contractAccount 144 | * 合约账户 145 | * @param from 146 | * 从 147 | * @param to 148 | * 到 149 | * @param quantity 150 | * 币种金额 151 | * @param memo 152 | * 留言 153 | * @return 154 | * @throws Exception 155 | */ 156 | public Transaction transfer(String pk, String contractAccount, String from, String to, String quantity, String memo) 157 | throws Exception { 158 | // get chain info 159 | ChainInfo info = getChainInfo(); 160 | // info.setChainId("cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"); 161 | // info.setLastIrreversibleBlockNum(826366l); 162 | // info.setHeadBlockTime(dateFormatter.parse("2018-08-22T09:19:01.000")); 163 | // get block info 164 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 165 | // block.setRefBlockPrefix(2919590658l); 166 | // tx 167 | Tx tx = new Tx(); 168 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 169 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 170 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 171 | tx.setNet_usage_words(0l); 172 | tx.setMax_cpu_usage_ms(0l); 173 | tx.setDelay_sec(0l); 174 | // actions 175 | List actions = new ArrayList<>(); 176 | // data 177 | Map dataMap = new LinkedHashMap<>(); 178 | dataMap.put("from", from); 179 | dataMap.put("to", to); 180 | dataMap.put("quantity", new DataParam(quantity, DataType.asset, Action.transfer).getValue()); 181 | dataMap.put("memo", memo); 182 | // action 183 | TxAction action = new TxAction(from, contractAccount, "transfer", dataMap); 184 | actions.add(action); 185 | tx.setActions(actions); 186 | // sgin 187 | String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx)); 188 | // data parse 189 | String data = Ecc.parseTransferData(from, to, quantity, memo); 190 | // reset data 191 | action.setData(data); 192 | // reset expiration 193 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 194 | return pushTransaction("none", tx, new String[] { sign }); 195 | } 196 | 197 | /** 198 | * 创建账户 199 | * 200 | * @param pk 201 | * 私钥 202 | * @param creator 203 | * 创建者 204 | * @param newAccount 205 | * 新账户 206 | * @param owner 207 | * 公钥 208 | * @param active 209 | * 公钥 210 | * @param buyRam 211 | * ram 212 | * @return 213 | * @throws Exception 214 | */ 215 | public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, 216 | Long buyRam) throws Exception { 217 | // get chain info 218 | ChainInfo info = getChainInfo(); 219 | // get block info 220 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 221 | // tx 222 | Tx tx = new Tx(); 223 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 224 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 225 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 226 | tx.setNet_usage_words(0l); 227 | tx.setMax_cpu_usage_ms(0l); 228 | tx.setDelay_sec(0l); 229 | // actions 230 | List actions = new ArrayList<>(); 231 | tx.setActions(actions); 232 | // create 233 | Map createMap = new LinkedHashMap<>(); 234 | createMap.put("creator", creator); 235 | createMap.put("name", newAccount); 236 | createMap.put("owner", owner); 237 | createMap.put("active", active); 238 | TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap); 239 | actions.add(createAction); 240 | // buyrap 241 | Map buyMap = new LinkedHashMap<>(); 242 | buyMap.put("payer", creator); 243 | buyMap.put("receiver", newAccount); 244 | buyMap.put("bytes", buyRam); 245 | TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap); 246 | actions.add(buyAction); 247 | // sgin 248 | String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx)); 249 | // data parse 250 | String accountData = Ese.parseAccountData(creator, newAccount, owner, active); 251 | createAction.setData(accountData); 252 | // data parse 253 | String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam); 254 | buyAction.setData(ramData); 255 | // reset expiration 256 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 257 | return pushTransaction("none", tx, new String[] { sign }); 258 | } 259 | 260 | /** 261 | * 创建账户 262 | * 263 | * @param pk 264 | * 私钥 265 | * @param creator 266 | * 创建者 267 | * @param newAccount 268 | * 新账户 269 | * @param owner 270 | * 公钥 271 | * @param active 272 | * 公钥 273 | * @param buyRam 274 | * 购买空间数量 275 | * @param stakeNetQuantity 276 | * 网络抵押 277 | * @param stakeCpuQuantity 278 | * cpu抵押 279 | * @param transfer 280 | * 抵押资产是否转送给对方,0自己所有,1对方所有 281 | * @return 282 | * @throws Exception 283 | */ 284 | public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, 285 | Long buyRam, String stakeNetQuantity, String stakeCpuQuantity, Long transfer) throws Exception { 286 | // get chain info 287 | ChainInfo info = getChainInfo(); 288 | // info.setChainId("cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"); 289 | // info.setLastIrreversibleBlockNum(22117l); 290 | // get block info 291 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 292 | // block.setRefBlockPrefix(3920078619l); 293 | // tx 294 | Tx tx = new Tx(); 295 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 296 | // tx.setExpiration(1528436078); 297 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 298 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 299 | tx.setNet_usage_words(0l); 300 | tx.setMax_cpu_usage_ms(0l); 301 | tx.setDelay_sec(0l); 302 | // actions 303 | List actions = new ArrayList<>(); 304 | tx.setActions(actions); 305 | // create 306 | Map createMap = new LinkedHashMap<>(); 307 | createMap.put("creator", creator); 308 | createMap.put("name", newAccount); 309 | createMap.put("owner", owner); 310 | createMap.put("active", active); 311 | TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap); 312 | actions.add(createAction); 313 | // buyrap 314 | Map buyMap = new LinkedHashMap<>(); 315 | buyMap.put("payer", creator); 316 | buyMap.put("receiver", newAccount); 317 | buyMap.put("bytes", buyRam); 318 | TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap); 319 | actions.add(buyAction); 320 | // buyrap 321 | Map delMap = new LinkedHashMap<>(); 322 | delMap.put("from", creator); 323 | delMap.put("receiver", newAccount); 324 | delMap.put("stake_net_quantity", new DataParam(stakeNetQuantity, DataType.asset, Action.delegate).getValue()); 325 | delMap.put("stake_cpu_quantity", new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate).getValue()); 326 | delMap.put("transfer", transfer); 327 | TxAction delAction = new TxAction(creator, "eosio", "delegatebw", delMap); 328 | actions.add(delAction); 329 | // // sgin 330 | String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx)); 331 | // data parse 332 | String accountData = Ese.parseAccountData(creator, newAccount, owner, active); 333 | createAction.setData(accountData); 334 | // data parse 335 | String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam); 336 | buyAction.setData(ramData); 337 | // data parse 338 | String delData = Ese.parseDelegateData(creator, newAccount, stakeNetQuantity, stakeCpuQuantity, 339 | transfer.intValue()); 340 | delAction.setData(delData); 341 | // reset expiration 342 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 343 | return pushTransaction("none", tx, new String[] { sign }); 344 | } 345 | 346 | /** 347 | * 348 | * @param pk 349 | * @param voter 350 | * @param proxy 351 | * @param producers 352 | * @return 353 | * @throws Exception 354 | */ 355 | public Transaction voteproducer(String pk,String voter,String proxy,List producers) throws Exception { 356 | final Comparator comparator = new Comparator() { 357 | @Override 358 | public int compare(String h1, String h2) { 359 | return h2.compareTo(h1); 360 | } 361 | }; 362 | //producers.sort(comparator.reversed()); 363 | Collections.sort(producers, Collections.reverseOrder(comparator)); 364 | // get chain info 365 | ChainInfo info = getChainInfo(); 366 | // get block info 367 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 368 | // tx 369 | Tx tx = new Tx(); 370 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 371 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 372 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 373 | tx.setNet_usage_words(0l); 374 | tx.setMax_cpu_usage_ms(0l); 375 | tx.setDelay_sec(0l); 376 | // actions 377 | List actions = new ArrayList<>(); 378 | // data 379 | Map dataMap = new LinkedHashMap<>(); 380 | dataMap.put("voter", voter); 381 | dataMap.put("proxy", proxy); 382 | dataMap.put("producers",producers); 383 | // action 384 | TxAction action = new TxAction(voter, "eosio", "voteproducer", dataMap); 385 | actions.add(action); 386 | tx.setActions(actions); 387 | // sgin 388 | String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx)); 389 | // data parse 390 | String data = Ecc.parseVoteProducerData(voter, proxy, producers); 391 | // reset data 392 | action.setData(data); 393 | // reset expiration 394 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 395 | return pushTransaction("none", tx, new String[] { sign }); 396 | } 397 | 398 | /** 399 | * token close 400 | * @param owner 401 | * @param symbol 402 | * @return 403 | * @throws Exception 404 | */ 405 | public Transaction close(String pk,String contract,String owner, String symbol)throws Exception { 406 | ChainInfo info = getChainInfo(); 407 | Block block = getBlock(info.getLastIrreversibleBlockNum().toString()); 408 | Tx tx = new Tx(); 409 | tx.setExpiration(info.getHeadBlockTime().getTime() / 1000 + 60); 410 | tx.setRef_block_num(info.getLastIrreversibleBlockNum()); 411 | tx.setRef_block_prefix(block.getRefBlockPrefix()); 412 | tx.setNet_usage_words(0l); 413 | tx.setMax_cpu_usage_ms(0l); 414 | tx.setDelay_sec(0l); 415 | // actions 416 | List actions = new ArrayList<>(); 417 | // data 418 | Map dataMap = new LinkedHashMap<>(); 419 | dataMap.put("close-owner", owner); 420 | dataMap.put("close-symbol", new DataParam(symbol, DataType.symbol, Action.close).getValue()); 421 | // action 422 | TxAction action = new TxAction(owner,contract,"close",dataMap); 423 | actions.add(action); 424 | tx.setActions(actions); 425 | // sgin 426 | String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx)); 427 | // data parse 428 | String data = Ecc.parseCloseData(owner, symbol); 429 | // reset data 430 | action.setData(data); 431 | // reset expiration 432 | tx.setExpiration(dateFormatter.format(new Date(1000 * Long.parseLong(tx.getExpiration().toString())))); 433 | return pushTransaction("none", tx, new String[] { sign }); 434 | } 435 | } 436 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/Test.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import party.loveit.eosforandroidlibrary.rpc.exception.ApiException; 7 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.Transaction; 8 | 9 | 10 | public class Test { 11 | 12 | static final String eosjs_transfer_seriz = "00f2d4142123e95d0000c85353840ccdb486010000000000045359530000000019e6b58be8af95313233616263646f2e2f2c2e2f214023232425"; 13 | 14 | static final String eosjs_account_seriz = "0000000000ea30550002a2f164772b5601000000010003ee4221c9c3f4f62646e3c758dbb8abaae506a559f67148a76968fa6b0f0868140100000001000000010003ba8de2f029cae85e7ca5c9f591bb17b86d750c5116cec30d94100e16e446d41501000000"; 15 | 16 | public static void main(String[] args) throws Exception{ 17 | System.out.println("******************* Ecc Start *******************\n"); 18 | 19 | 20 | System.out.println("============= 通过种子生成私钥 ==============="); 21 | String pk = Ecc.seedPrivate("adsadsadsadsadsa".getBytes("utf-8")); 22 | System.out.println("private key :" + pk +"\n"); 23 | 24 | System.out.println("============= 通过私钥生成公钥 ==============="); 25 | String pu = Ecc.privateToPublic(pk); 26 | System.out.println("public key :" + pu + " \n "); 27 | 28 | System.out.println("============= 自定义数据签名 ==============="); 29 | String sign = Ecc.sign(pk,"is京東價as看到可可是是是@#¥%……&*(CVBNM《d "); 30 | System.out.println("sign :" + sign + " \n "); 31 | 32 | System.out.println("============= 转账数据序列化 ==============="); 33 | String data = Ecc.parseTransferData("fromaccount", "toaccount", "10.0020 SYS", "测试123abcdo./,./!@##$%"); 34 | System.out.println("seriz data :" + data); 35 | System.out.println("transfer eq eosjs seriz " + data.equals(eosjs_transfer_seriz)+" \n "); 36 | 37 | System.out.println("============= 创建账户数据序列化 ==============="); 38 | String data1 = Ecc.parseAccountData("eosio", "espritbloc1.","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8FPooohZiiCAYXahWCQRxgXXzUbS2gNELAeYCUgGdDMbd2FHQT"); 39 | System.out.println("seriz data :" + data1); 40 | System.out.println("account eq eosjs seriz " + data1.equals(eosjs_account_seriz)); 41 | 42 | 43 | System.out.println("\n******************* Ecc End *******************\n\n\n"); 44 | 45 | System.out.println("******************* Rpc Start *******************\n"); 46 | 47 | Rpc rpc = new Rpc("http://47.106.221.171:8888"); 48 | 49 | System.out.println("============= 转账 ==============="); 50 | try { 51 | Transaction t1 = rpc.transfer("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","espritblocke", "inita","initb", "12.2821 MSP", ""); 52 | System.out.println("转账成功 = " + t1.getTransactionId()+" \n "); 53 | }catch(Exception ex) { 54 | ex.printStackTrace(); 55 | } 56 | 57 | System.out.println("============= 创建账户并且抵押 ==============="); 58 | try { 59 | Transaction t2 = rpc.createAccount("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","eosio","ccccc..bbbbb", "EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx", 8192l, "0.01 SYS","0.01 SYS", 0l); 60 | System.out.println("创建成功 = " + t2.getTransactionId()+" \n "); 61 | }catch(Exception ex) { 62 | ex.printStackTrace(); 63 | } 64 | System.out.println("============= 创建账户不抵押 ==============="); 65 | try { 66 | Transaction t3 = rpc.createAccount("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3","eosio","bbbb..54321", "EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx","EOS8eAX54cJtAngV2V22WZhRCW7e4sTAZz1mC5U22vp8mAGuFdMXx", 8192l); 67 | System.out.println("创建成功 = " + t3.getTransactionId()+" \n "); 68 | }catch(Exception ex) { 69 | ex.printStackTrace(); 70 | } 71 | 72 | System.out.println("============= 代理投票 ==============="); 73 | try { 74 | List produces = new ArrayList<>(); 75 | produces.add("pppppeeeeooo"); 76 | produces.add("mdddssssddds"); 77 | produces.add("mdjddjddddds"); 78 | rpc.voteproducer("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "epskdkdsddss","iuewjdkslsdc",produces); 79 | } catch (Exception e) { 80 | e.printStackTrace(); 81 | } 82 | 83 | System.out.println("============= 关闭余额为0的token ==============="); 84 | try { 85 | rpc.close("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3", "合约账户", "关闭账户", "0.0000 IPOS"); 86 | }catch(ApiException e) { 87 | e.printStackTrace(); 88 | }catch(Exception ex) { 89 | ex.printStackTrace(); 90 | } 91 | System.out.println("\n******************* Rpc End *******************"); 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/Curve.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Curve 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | public class Curve { 12 | 13 | private FieldElement a; 14 | 15 | private FieldElement b; 16 | 17 | private BigInteger q; 18 | 19 | private Point infinity; 20 | 21 | private BigInteger pOverFour; 22 | 23 | public Curve(BigInteger q, BigInteger a, BigInteger b) { 24 | this.q = q; 25 | this.a = fromBigInteger(a); 26 | this.b = fromBigInteger(b); 27 | this.infinity = new Point(this, null, null); 28 | this.pOverFour = q.add(BigInteger.ONE).shiftRight(2); 29 | } 30 | 31 | public FieldElement getA() { 32 | return a; 33 | } 34 | 35 | public FieldElement getB() { 36 | return b; 37 | } 38 | 39 | public BigInteger getQ() { 40 | return q; 41 | } 42 | 43 | public Point getInfinity() { 44 | return infinity; 45 | } 46 | 47 | public int getFieldSize() { 48 | return q.bitLength(); 49 | } 50 | 51 | public FieldElement fromBigInteger(BigInteger x) { 52 | return new FieldElement(this.q, x); 53 | } 54 | 55 | public Point pointFromX(int isOdd, BigInteger x) { 56 | FieldElement f = this.a.multiply(fromBigInteger(x)); 57 | BigInteger alpha = x.pow(3).add(f.toBigInteger()).add(this.b.toBigInteger()).mod(this.q); 58 | BigInteger beta = alpha.modPow(this.pOverFour, this.q); 59 | BigInteger y = beta; 60 | if (beta.intValue() % 2 == 0 ^ isOdd == 0) { 61 | y = this.q.subtract(y); 62 | } 63 | return new Point(this, new FieldElement(this.q, x), new FieldElement(this.q, y), false); 64 | } 65 | 66 | public Point decodePoint(byte[] encodedPoint) { 67 | Point p = null; 68 | switch (encodedPoint[0]) { 69 | case 0x00: 70 | p = getInfinity(); 71 | break; 72 | case 0x02: 73 | case 0x03: 74 | int ytilde = encodedPoint[0] & 1; 75 | byte[] i = new byte[encodedPoint.length - 1]; 76 | System.arraycopy(encodedPoint, 1, i, 0, i.length); 77 | FieldElement x = new FieldElement(this.q, new BigInteger(1, i)); 78 | FieldElement alpha = x.multiply(x.square().add(a)).add(b); 79 | FieldElement beta = alpha.sqrt(); 80 | if (beta == null) { 81 | throw new RuntimeException("Invalid compression"); 82 | } 83 | int bit0 = (beta.toBigInteger().testBit(0) ? 1 : 0); 84 | if (bit0 == ytilde) { 85 | p = new Point(this, x, beta, true); 86 | } else { 87 | p = new Point(this, x, new FieldElement(this.q, q.subtract(beta.toBigInteger())), true); 88 | } 89 | break; 90 | case 0x04: 91 | case 0x06: 92 | case 0x07: 93 | byte[] xEnc = new byte[(encodedPoint.length - 1) / 2]; 94 | byte[] yEnc = new byte[(encodedPoint.length - 1) / 2]; 95 | System.arraycopy(encodedPoint, 1, xEnc, 0, xEnc.length); 96 | System.arraycopy(encodedPoint, xEnc.length + 1, yEnc, 0, yEnc.length); 97 | p = new Point(this, new FieldElement(this.q, new BigInteger(1, xEnc)), 98 | new FieldElement(this.q, new BigInteger(1, yEnc))); 99 | break; 100 | default: 101 | throw new RuntimeException("Invalid encoding 0x" + Integer.toString(encodedPoint[0], 16)); 102 | } 103 | return p; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/EccTool.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | 5 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxSign; 6 | import party.loveit.eosforandroidlibrary.utils.Base58; 7 | import party.loveit.eosforandroidlibrary.utils.ByteBuffer; 8 | import party.loveit.eosforandroidlibrary.utils.ByteUtils; 9 | import party.loveit.eosforandroidlibrary.utils.EException; 10 | import party.loveit.eosforandroidlibrary.utils.Hex; 11 | import party.loveit.eosforandroidlibrary.utils.ObjectUtils; 12 | import party.loveit.eosforandroidlibrary.utils.Ripemd160; 13 | import party.loveit.eosforandroidlibrary.utils.Sha; 14 | 15 | 16 | /** 17 | * Ecc 18 | * 19 | * @author espritblock http://eblock.io 20 | * 21 | */ 22 | public class EccTool { 23 | 24 | public static final String address_prefix = "EOS"; 25 | 26 | public static final Secp256k secp = new Secp256k(); 27 | 28 | /** 29 | * 通过种子生成私钥 30 | * 31 | * @param priKey 种子 32 | * @return 33 | */ 34 | public static String privateKeyFromSeed(BigInteger priKey) { 35 | return seedShaPrivate(bigIntegerToBytes(priKey,32)); 36 | } 37 | 38 | /** 39 | * 40 | * @param seed 41 | * @return 42 | */ 43 | public static String privateKeyFromSeed(byte[] seed) { 44 | return seedShaPrivate(seed); 45 | } 46 | 47 | /** 48 | * seedPrivate 49 | * 50 | * @return 51 | */ 52 | private static String seedShaPrivate(byte[] seedSha) { 53 | if (seedSha == null || seedSha.length == 0) { 54 | throw new EException("seed_empty", "seed is empty"); 55 | } 56 | byte[] a = {(byte) 0x80}; 57 | byte[] b = seedSha; 58 | byte[] private_key = ByteUtils.concat(a, b); 59 | byte[] checksum = Sha.SHA256(private_key); 60 | checksum = Sha.SHA256(checksum); 61 | byte[] check = ByteUtils.copy(checksum, 0, 4); 62 | byte[] pk = ByteUtils.concat(private_key, check); 63 | return Base58.encode(pk); 64 | } 65 | 66 | /** 67 | * 68 | * @param b 69 | * @param numBytes 70 | * @return 71 | */ 72 | private static byte[] bigIntegerToBytes(BigInteger b, int numBytes) { 73 | if (b == null) { 74 | return null; 75 | } 76 | byte[] bytes = new byte[numBytes]; 77 | byte[] biBytes = b.toByteArray(); 78 | int start = (biBytes.length == numBytes + 1) ? 1 : 0; 79 | int length = Math.min(biBytes.length, numBytes); 80 | System.arraycopy(biBytes, start, bytes, numBytes - length, length); 81 | return bytes; 82 | } 83 | /** 84 | * privateKey 85 | * 86 | * @param pk 87 | * @return 88 | */ 89 | private static BigInteger privateKey(String pk) { 90 | byte[] private_wif = Base58.decode(pk); 91 | byte version = (byte) 0x80; 92 | if (private_wif[0] != version) { 93 | throw new EException("version_error", "Expected version " + 0x80 + ", instead got " + version); 94 | } 95 | byte[] private_key = ByteUtils.copy(private_wif, 0, private_wif.length - 4); 96 | byte[] new_checksum = Sha.SHA256(private_key); 97 | new_checksum = Sha.SHA256(new_checksum); 98 | new_checksum = ByteUtils.copy(new_checksum, 0, 4); 99 | byte[] last_private_key = ByteUtils.copy(private_key, 1, private_key.length - 1); 100 | BigInteger d = new BigInteger(Hex.bytesToHexString(last_private_key), 16); 101 | return d; 102 | } 103 | 104 | /** 105 | * privateToPublic 106 | * 107 | * @param pk 108 | * @return 109 | */ 110 | public static String privateToPublic(String pk) { 111 | if (pk == null || pk.length() == 0) { 112 | throw new EException("args_empty", "args is empty"); 113 | } 114 | // private key 115 | BigInteger d = privateKey(pk); 116 | // publick key 117 | Point ep = secp.G().multiply(d); 118 | byte[] pub_buf = ep.getEncoded(); 119 | byte[] csum = Ripemd160.from(pub_buf).bytes(); 120 | csum = ByteUtils.copy(csum, 0, 4); 121 | byte[] addy = ByteUtils.concat(pub_buf, csum); 122 | StringBuffer bf = new StringBuffer(address_prefix); 123 | bf.append(Base58.encode(addy)); 124 | return bf.toString(); 125 | } 126 | 127 | /** 128 | * signHash 129 | * @param pk 130 | * @param b 131 | * @return 132 | */ 133 | public static String signHash(String pk, byte[] b) { 134 | String dataSha256 = Hex.bytesToHexString(Sha.SHA256(b)); 135 | BigInteger e = new BigInteger(dataSha256, 16); 136 | int nonce = 0; 137 | int i = 0; 138 | BigInteger d = privateKey(pk); 139 | Point Q = secp.G().multiply(d); 140 | nonce = 0; 141 | Ecdsa ecd = new Ecdsa(secp); 142 | Ecdsa.SignBigInt sign; 143 | while (true) { 144 | sign = ecd.sign(dataSha256, d, nonce++); 145 | byte der[] = sign.getDer(); 146 | byte lenR = der[3]; 147 | byte lenS = der[5 + lenR]; 148 | if (lenR == 32 && lenS == 32) { 149 | i = ecd.calcPubKeyRecoveryParam(e, sign, Q); 150 | i += 4; // compressed 151 | i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) 152 | break; 153 | } 154 | } 155 | byte[] pub_buf = new byte[65]; 156 | pub_buf[0] = (byte) i; 157 | ByteUtils.copy(sign.getR().toByteArray(), 0, pub_buf, 1, sign.getR().toByteArray().length); 158 | ByteUtils.copy(sign.getS().toByteArray(), 0, pub_buf, sign.getR().toByteArray().length + 1, 159 | sign.getS().toByteArray().length); 160 | 161 | byte[] checksum = Ripemd160.from(ByteUtils.concat(pub_buf, "K1".getBytes())).bytes(); 162 | 163 | byte[] signatureString = ByteUtils.concat(pub_buf, ByteUtils.copy(checksum, 0, 4)); 164 | 165 | return "SIG_K1_" + Base58.encode(signatureString); 166 | } 167 | 168 | /** 169 | * sign string 170 | * @param pk 171 | * @param data 172 | * @return 173 | */ 174 | public static String sign(String pk, String data) { 175 | String dataSha256 = Hex.bytesToHexString(Sha.SHA256(data)); 176 | BigInteger e = new BigInteger(dataSha256, 16); 177 | int nonce = 0; 178 | int i = 0; 179 | BigInteger d = privateKey(pk); 180 | Point Q = secp.G().multiply(d); 181 | nonce = 0; 182 | Ecdsa ecd = new Ecdsa(secp); 183 | Ecdsa.SignBigInt sign; 184 | while (true) { 185 | sign = ecd.sign(dataSha256, d, nonce++); 186 | byte der[] = sign.getDer(); 187 | byte lenR = der[3]; 188 | byte lenS = der[5 + lenR]; 189 | if (lenR == 32 && lenS == 32) { 190 | i = ecd.calcPubKeyRecoveryParam(e, sign, Q); 191 | i += 4; // compressed 192 | i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) 193 | break; 194 | } 195 | } 196 | byte[] pub_buf = new byte[65]; 197 | pub_buf[0] = (byte) i; 198 | ByteUtils.copy(sign.getR().toByteArray(), 0, pub_buf, 1, sign.getR().toByteArray().length); 199 | ByteUtils.copy(sign.getS().toByteArray(), 0, pub_buf, sign.getR().toByteArray().length + 1, 200 | sign.getS().toByteArray().length); 201 | 202 | byte[] checksum = Ripemd160.from(ByteUtils.concat(pub_buf, "K1".getBytes())).bytes(); 203 | 204 | byte[] signatureString = ByteUtils.concat(pub_buf, ByteUtils.copy(checksum, 0, 4)); 205 | 206 | return "SIG_K1_" + Base58.encode(signatureString); 207 | } 208 | 209 | /** 210 | * signTransaction 211 | * @param privateKey 212 | * @param push 213 | * @return 214 | */ 215 | public static String signTransaction(String privateKey, TxSign push) { 216 | // tx 217 | ByteBuffer bf = new ByteBuffer(); 218 | ObjectUtils.writeBytes(push, bf); 219 | byte[] real = bf.getBuffer(); 220 | // append 221 | real = ByteUtils.concat(real, java.nio.ByteBuffer.allocate(33).array()); 222 | 223 | // final byte [] b = real.clone(); 224 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 225 | // for(int i=1;i<=a.length;i++) { 226 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 227 | // } 228 | return signHash(privateKey, real); 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/Ecdsa.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | 7 | import party.loveit.eosforandroidlibrary.utils.ByteUtils; 8 | import party.loveit.eosforandroidlibrary.utils.EException; 9 | import party.loveit.eosforandroidlibrary.utils.Hex; 10 | import party.loveit.eosforandroidlibrary.utils.Sha; 11 | 12 | 13 | /** 14 | * Ecdsa 15 | * 16 | * @author espritblock http://eblock.io 17 | * 18 | */ 19 | public class Ecdsa { 20 | 21 | Secp256k curve = null; 22 | 23 | public Ecdsa(Secp256k curve) { 24 | this.curve = curve; 25 | } 26 | 27 | /** 28 | * sign 29 | * 30 | * @param dataHash 31 | * @param d 32 | * @param nonce 33 | * @return 34 | */ 35 | public SignBigInt sign(String dataHash, BigInteger d, int nonce) { 36 | BigInteger n = curve.n(); 37 | SignBigInt big = new SignBigInt(); 38 | deterministicGenerateK(curve, dataHash, d, nonce, big); 39 | BigInteger N_OVER_TWO = n.shiftRight(1); 40 | if (big.getS().compareTo(N_OVER_TWO) > 0) { 41 | big.setS(n.subtract(big.getS())); 42 | } 43 | big.setDer(toDER(big)); 44 | return big; 45 | } 46 | 47 | /** 48 | * toDER 49 | * 50 | * @param big 51 | * @return 52 | */ 53 | private byte[] toDER(SignBigInt big) { 54 | byte[] rBa = big.getR().toByteArray(); 55 | byte[] sBa = big.getS().toByteArray(); 56 | ArrayList sequence = new ArrayList(); 57 | sequence.add(new Byte(((byte) 0x02))); 58 | sequence.add(new Byte(((byte) rBa.length))); 59 | for (int i = 0; i < rBa.length; i++) { 60 | sequence.add(rBa[i]); 61 | } 62 | sequence.add(new Byte(((byte) 0x02))); 63 | sequence.add(new Byte(((byte) sBa.length))); 64 | for (int i = 0; i < sBa.length; i++) { 65 | sequence.add(sBa[i]); 66 | } 67 | int len = sequence.size(); 68 | sequence.add(0, (byte) 0x30); 69 | sequence.add(1, (byte) len); 70 | byte[] bf = new byte[sequence.size()]; 71 | for (int i = 0; i < bf.length; i++) { 72 | bf[i] = sequence.get(i).byteValue(); 73 | } 74 | return bf; 75 | } 76 | 77 | private BigInteger deterministicGenerateK(Secp256k curve, String dataHash, BigInteger d, int nonce, 78 | SignBigInt big) { 79 | byte[] hash = Hex.hexStringToBytes(dataHash); 80 | if (nonce > 0) { 81 | hash = Sha.SHA256(ByteUtils.concat(hash, new byte[nonce])); 82 | } 83 | byte[] x = null; 84 | if (d.toByteArray()[0] == 0) { 85 | x = ByteUtils.copy(d.toByteArray(), 1, d.toByteArray().length - 1); 86 | } else { 87 | x = d.toByteArray(); 88 | } 89 | // int padding = d.toByteArray().length-tmp.length; 90 | // byte[] zeros = null; 91 | // if(padding>0) { 92 | // zeros = new byte[padding]; 93 | // for(int i =0;i= 0 || !check) { 136 | k = Sha.HmacSHA256(ByteUtils.concat(v, new byte[] { 0 }), k); 137 | v = Sha.HmacSHA256(v, k); 138 | v = Sha.HmacSHA256(v, k); 139 | T = new BigInteger(v); 140 | } 141 | 142 | big.setK(T); 143 | return T; 144 | } 145 | 146 | /** 147 | * checkSig 148 | * 149 | * @param k 150 | * @param d 151 | * @param e 152 | * @param big 153 | * @return 154 | */ 155 | public Boolean checkSig(BigInteger k, BigInteger d, BigInteger e, SignBigInt big) { 156 | Point Q = curve.G().multiply(k); 157 | if (Q.isInfinity()) 158 | return false; 159 | BigInteger r = Q.getX().toBigInteger().mod(curve.n()); 160 | big.setR(r); 161 | if (r.signum() == 0) 162 | return false; 163 | BigInteger s = k.modInverse(curve.n()).multiply(e.add(d.multiply(r))).mod(curve.n()); 164 | big.setS(s); 165 | if (s.signum() == 0) 166 | return false; 167 | return true; 168 | } 169 | 170 | /** 171 | * 172 | * @author espritblock http://eblock.io 173 | * 174 | */ 175 | public static class SignBigInt { 176 | private BigInteger k; 177 | private BigInteger r; 178 | private BigInteger s; 179 | private byte[] der; 180 | 181 | public BigInteger getK() { 182 | return k; 183 | } 184 | 185 | public void setK(BigInteger k) { 186 | this.k = k; 187 | } 188 | 189 | public BigInteger getR() { 190 | return r; 191 | } 192 | 193 | public void setR(BigInteger r) { 194 | this.r = r; 195 | } 196 | 197 | public BigInteger getS() { 198 | return s; 199 | } 200 | 201 | public void setS(BigInteger s) { 202 | this.s = s; 203 | } 204 | 205 | public byte[] getDer() { 206 | return der; 207 | } 208 | 209 | public void setDer(byte[] der) { 210 | this.der = der; 211 | } 212 | } 213 | 214 | public int calcPubKeyRecoveryParam(BigInteger e, SignBigInt sign, Point Q) { 215 | for (int i = 0; i < 4; i++) { 216 | Point Qprime = recoverPubKey(e, sign, i); 217 | if (Qprime.equals(Q)) { 218 | return i; 219 | } 220 | } 221 | throw new EException("sign_error", "Unable to find valid recovery factor"); 222 | } 223 | 224 | public Point recoverPubKey(BigInteger e, SignBigInt big, int i) { 225 | 226 | BigInteger n = curve.n(); 227 | Point G = curve.G(); 228 | 229 | BigInteger r = big.getR(); 230 | BigInteger s = big.getS(); 231 | 232 | if (!(r.signum() > 0 && r.compareTo(n) < 0)) { 233 | throw new EException("recover_pubkey_error", "Invalid r value"); 234 | } 235 | if (!(s.signum() > 0 && s.compareTo(n) < 0)) { 236 | throw new EException("recover_pubkey_error", "Invalid r value"); 237 | } 238 | 239 | // A set LSB signifies that the y-coordinate is odd 240 | int isYOdd = i & 1; 241 | 242 | // The more significant bit specifies whether we should use the 243 | // first or second candidate key. 244 | int isSecondKey = i >> 1; 245 | 246 | // 1.1 Let x = r + jn 247 | BigInteger x = isSecondKey == 1 ? r.add(n) : r; 248 | 249 | Point R = curve.getCurve().pointFromX(isYOdd, x); 250 | 251 | // // 1.4 Check that nR is at infinity 252 | Point nR = R.multiply(n); 253 | 254 | if (!nR.isInfinity()) { 255 | throw new EException("sign_error", "nR is not a valid curve point"); 256 | } 257 | 258 | BigInteger eNeg = e.negate().mod(n); 259 | 260 | BigInteger rInv = r.modInverse(n); 261 | 262 | Point Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); 263 | 264 | if (Q.isInfinity()) { 265 | throw new EException("sign_error", "Point is at infinity"); 266 | } 267 | 268 | return Q; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/FieldElement.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | import java.util.Random; 5 | 6 | import party.loveit.eosforandroidlibrary.utils.EException; 7 | 8 | 9 | /** 10 | * FieldElement 11 | * 12 | * @author espritblock http://eblock.io 13 | * 14 | */ 15 | public class FieldElement { 16 | 17 | private BigInteger q; 18 | 19 | private BigInteger x; 20 | 21 | private static final BigInteger TWO = BigInteger.valueOf(2); 22 | 23 | public FieldElement(BigInteger q, BigInteger x) { 24 | this.x = x; 25 | if (x.compareTo(q) >= 0) { 26 | throw new EException("error", "x value too large in field element"); 27 | } 28 | this.q = q; 29 | } 30 | 31 | public FieldElement add(FieldElement b) { 32 | return new FieldElement(q, x.add(b.toBigInteger()).mod(q)); 33 | } 34 | 35 | public FieldElement subtract(FieldElement b) { 36 | return new FieldElement(q, x.subtract(b.toBigInteger()).mod(q)); 37 | } 38 | 39 | public FieldElement multiply(FieldElement b) { 40 | return new FieldElement(q, x.multiply(b.toBigInteger()).mod(q)); 41 | } 42 | 43 | public FieldElement divide(FieldElement b) { 44 | return new FieldElement(q, x.multiply(b.toBigInteger().modInverse(q)).mod(q)); 45 | } 46 | 47 | public FieldElement negate() { 48 | return new FieldElement(q, x.negate().mod(q)); 49 | } 50 | 51 | public FieldElement square() { 52 | return new FieldElement(q, x.multiply(x).mod(q)); 53 | } 54 | 55 | public FieldElement invert() { 56 | return new FieldElement(q, x.modInverse(q)); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return this.toBigInteger().toString(16); 62 | } 63 | 64 | public FieldElement sqrt() { 65 | if (!q.testBit(0)) { 66 | throw new RuntimeException("not done yet"); 67 | } 68 | 69 | if (q.testBit(1)) { 70 | FieldElement z = new FieldElement(q, x.modPow(q.shiftRight(2).add(BigInteger.ONE), q)); 71 | return z.square().equals(this) ? z : null; 72 | } 73 | BigInteger qMinusOne = q.subtract(BigInteger.ONE); 74 | BigInteger legendreExponent = qMinusOne.shiftRight(1); 75 | if (!(x.modPow(legendreExponent, q).equals(BigInteger.ONE))) { 76 | return null; 77 | } 78 | BigInteger u = qMinusOne.shiftRight(2); 79 | BigInteger k = u.shiftLeft(1).add(BigInteger.ONE); 80 | BigInteger Q = this.x; 81 | BigInteger fourQ = Q.shiftLeft(2).mod(q); 82 | BigInteger U, V; 83 | Random rand = new Random(); 84 | do { 85 | BigInteger P; 86 | do { 87 | P = new BigInteger(q.bitLength(), rand); 88 | } while (P.compareTo(q) >= 0 89 | || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, q).equals(qMinusOne))); 90 | BigInteger[] result = lucasSequence(q, P, Q, k); 91 | U = result[0]; 92 | V = result[1]; 93 | if (V.multiply(V).mod(q).equals(fourQ)) { 94 | if (V.testBit(0)) { 95 | V = V.add(q); 96 | } 97 | V = V.shiftRight(1); 98 | return new FieldElement(q, V); 99 | } 100 | } while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); 101 | return null; 102 | } 103 | 104 | private static BigInteger[] lucasSequence(BigInteger p, BigInteger P, BigInteger Q, BigInteger k) { 105 | int n = k.bitLength(); 106 | int s = k.getLowestSetBit(); 107 | BigInteger Uh = BigInteger.ONE; 108 | BigInteger Vl = TWO; 109 | BigInteger Vh = P; 110 | BigInteger Ql = BigInteger.ONE; 111 | BigInteger Qh = BigInteger.ONE; 112 | for (int j = n - 1; j >= s + 1; --j) { 113 | Ql = Ql.multiply(Qh).mod(p); 114 | if (k.testBit(j)) { 115 | Qh = Ql.multiply(Q).mod(p); 116 | Uh = Uh.multiply(Vh).mod(p); 117 | Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 118 | Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); 119 | } else { 120 | Qh = Ql; 121 | Uh = Uh.multiply(Vl).subtract(Ql).mod(p); 122 | Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 123 | Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); 124 | } 125 | } 126 | Ql = Ql.multiply(Qh).mod(p); 127 | Qh = Ql.multiply(Q).mod(p); 128 | Uh = Uh.multiply(Vl).subtract(Ql).mod(p); 129 | Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); 130 | Ql = Ql.multiply(Qh).mod(p); 131 | for (int j = 1; j <= s; ++j) { 132 | Uh = Uh.multiply(Vl).mod(p); 133 | Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); 134 | Ql = Ql.multiply(Ql).mod(p); 135 | } 136 | return new BigInteger[] { Uh, Vl }; 137 | } 138 | 139 | public BigInteger toBigInteger() { 140 | return x; 141 | } 142 | 143 | public int getFieldSize() { 144 | return q.bitLength(); 145 | } 146 | 147 | public BigInteger getQ() { 148 | return q; 149 | } 150 | 151 | public boolean equals(Object other) { 152 | if (other == this) { 153 | return true; 154 | } 155 | if (!(other instanceof FieldElement)) { 156 | return false; 157 | } 158 | FieldElement o = (FieldElement) other; 159 | return q.equals(o.q) && x.equals(o.x); 160 | } 161 | 162 | public int hashCode() { 163 | return q.hashCode() ^ x.hashCode(); 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/Point.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Point 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | public class Point { 12 | 13 | private Curve curve; 14 | 15 | private FieldElement x; 16 | 17 | private FieldElement y; 18 | 19 | private boolean compressed; 20 | 21 | public Point(Curve curve, FieldElement x, FieldElement y, boolean compressed) { 22 | this.curve = curve; 23 | this.x = x; 24 | this.y = y; 25 | this.compressed = compressed; 26 | } 27 | 28 | public Point(Curve curve, FieldElement x, FieldElement y) { 29 | this(curve, x, y, true); 30 | } 31 | 32 | public Curve getCurve() { 33 | return curve; 34 | } 35 | 36 | public FieldElement getX() { 37 | return x; 38 | } 39 | 40 | public FieldElement getY() { 41 | return y; 42 | } 43 | 44 | public boolean isInfinity() { 45 | return x == null && y == null; 46 | } 47 | 48 | public boolean isCompressed() { 49 | return compressed; 50 | } 51 | 52 | public byte[] getEncoded() { 53 | 54 | if (this.isInfinity()) { 55 | return new byte[1]; 56 | } 57 | 58 | int length = getByteLength(x.getFieldSize()); 59 | 60 | if (compressed) { 61 | byte PC; 62 | if (this.getY().toBigInteger().testBit(0)) { 63 | PC = 0x03; 64 | } else { 65 | PC = 0x02; 66 | } 67 | byte[] X = integerToBytes(this.getX().toBigInteger(), length); 68 | byte[] PO = new byte[X.length + 1]; 69 | PO[0] = PC; 70 | System.arraycopy(X, 0, PO, 1, X.length); 71 | return PO; 72 | } else { 73 | byte[] X = integerToBytes(this.getX().toBigInteger(), length); 74 | byte[] Y = integerToBytes(this.getY().toBigInteger(), length); 75 | byte[] PO = new byte[X.length + Y.length + 1]; 76 | PO[0] = 0x04; 77 | System.arraycopy(X, 0, PO, 1, X.length); 78 | System.arraycopy(Y, 0, PO, X.length + 1, Y.length); 79 | return PO; 80 | } 81 | } 82 | 83 | public Point add(Point b) { 84 | if (this.isInfinity()) { 85 | return b; 86 | } 87 | if (b.isInfinity()) { 88 | return this; 89 | } 90 | if (this.x.equals(b.x)) { 91 | if (this.y.equals(b.y)) { 92 | return this.twice(); 93 | } 94 | return this.curve.getInfinity(); 95 | } 96 | FieldElement gamma = b.y.subtract(this.y).divide(b.x.subtract(this.x)); 97 | FieldElement x3 = gamma.square().subtract(this.x).subtract(b.x); 98 | FieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); 99 | return new Point(curve, x3, y3); 100 | } 101 | 102 | public Point twice() { 103 | if (this.isInfinity()) { 104 | return this; 105 | } 106 | if (this.y.toBigInteger().signum() == 0) { 107 | return this.curve.getInfinity(); 108 | } 109 | FieldElement TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); 110 | FieldElement THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); 111 | FieldElement gamma = this.x.square().multiply(THREE).add(curve.getA()).divide(y.multiply(TWO)); 112 | FieldElement x3 = gamma.square().subtract(this.x.multiply(TWO)); 113 | FieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); 114 | return new Point(curve, x3, y3, this.compressed); 115 | } 116 | 117 | public Point subtract(Point b) { 118 | if (b.isInfinity()) { 119 | return this; 120 | } 121 | return add(b.negate()); 122 | } 123 | 124 | public Point negate() { 125 | return new Point(curve, this.x, this.y.negate(), this.compressed); 126 | } 127 | 128 | public Point multiply(BigInteger k) { 129 | BigInteger e = k; 130 | BigInteger h = e.multiply(BigInteger.valueOf(3)); 131 | Point neg = this.negate(); 132 | Point R = this; 133 | for (int i = h.bitLength() - 2; i > 0; --i) { 134 | R = R.twice(); 135 | boolean hBit = h.testBit(i); 136 | boolean eBit = e.testBit(i); 137 | if (hBit != eBit) { 138 | R = R.add(hBit ? this : neg); 139 | } 140 | } 141 | return R; 142 | } 143 | 144 | public Point multiplyTwo(BigInteger j, Point x, BigInteger k) { 145 | int i = Math.max(j.bitLength(), k.bitLength()) - 1; 146 | Point R = this.curve.getInfinity(); 147 | Point both = this.add(x); 148 | while (i >= 0) { 149 | Boolean jBit = j.testBit(i); 150 | Boolean kBit = k.testBit(i); 151 | 152 | R = R.twice(); 153 | 154 | if (jBit) { 155 | if (kBit) { 156 | R = R.add(both); 157 | } else { 158 | R = R.add(this); 159 | } 160 | } else if (kBit) { 161 | R = R.add(x); 162 | } 163 | --i; 164 | } 165 | return R; 166 | } 167 | 168 | public static int getByteLength(int fieldSize) { 169 | return (fieldSize + 7) / 8; 170 | } 171 | 172 | public static byte[] integerToBytes(BigInteger s, int length) { 173 | byte[] bytes = s.toByteArray(); 174 | if (length < bytes.length) { 175 | byte[] tmp = new byte[length]; 176 | System.arraycopy(bytes, bytes.length - tmp.length, tmp, 0, tmp.length); 177 | return tmp; 178 | } else if (length > bytes.length) { 179 | byte[] tmp = new byte[length]; 180 | System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length); 181 | return tmp; 182 | } 183 | return bytes; 184 | } 185 | 186 | @Override 187 | public boolean equals(Object other) { 188 | if (other == this) { 189 | return true; 190 | } 191 | 192 | if (!(other instanceof Point)) { 193 | return false; 194 | } 195 | 196 | Point o = (Point) other; 197 | 198 | if (this.isInfinity()) { 199 | return o.isInfinity(); 200 | } 201 | 202 | return x.equals(o.x) && y.equals(o.y); 203 | } 204 | 205 | @Override 206 | public int hashCode() { 207 | if (this.isInfinity()) { 208 | return 0; 209 | } 210 | 211 | return x.hashCode() ^ y.hashCode(); 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ecc/Secp256k.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ecc; 2 | 3 | import java.math.BigInteger; 4 | 5 | import party.loveit.eosforandroidlibrary.utils.Hex; 6 | 7 | 8 | /** 9 | * Curve 10 | * 11 | * @author espritblock http://eblock.io 12 | * 13 | */ 14 | public class Secp256k { 15 | 16 | public static final String P = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"; 17 | public static final String A = "0"; 18 | public static final String B = "7"; 19 | public static final String N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; 20 | public static final String GX = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"; 21 | public static final String GY = "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"; 22 | 23 | private final Curve curve; 24 | 25 | private final Point G; 26 | 27 | private final BigInteger n; 28 | 29 | private final BigInteger HALF_CURVE_ORDER; 30 | 31 | public Secp256k() { 32 | n = new BigInteger(N, 16); 33 | HALF_CURVE_ORDER = n.shiftRight(1); 34 | curve = new Curve(new BigInteger(P, 16), new BigInteger(A, 16), new BigInteger(B, 16)); 35 | G = curve.decodePoint(Hex.toBytes("04" + GX + GY)); 36 | } 37 | 38 | public Point G() { 39 | return this.G; 40 | } 41 | 42 | public BigInteger n() { 43 | return this.n; 44 | } 45 | 46 | public BigInteger halfCurveOrder() { 47 | return HALF_CURVE_ORDER; 48 | } 49 | 50 | public Curve getCurve() { 51 | return curve; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ese/Action.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ese; 2 | 3 | /** 4 | * Action 5 | * 6 | * @author espritblock http://eblock.io 7 | * 8 | */ 9 | public enum Action { 10 | 11 | transfer("${precision},${quantity}@eosio.token"), account("account"), ram("ram"), delegate("${precision},${quantity}@eosio.token"), voteproducer("voteproducer"), 12 | close("${precision},${quantity}@eosio.token"); 13 | 14 | private String code; 15 | 16 | private Action(String code) { 17 | this.code = code; 18 | } 19 | 20 | public String getCode() { 21 | return code; 22 | } 23 | 24 | public void setCode(String code) { 25 | this.code = code; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ese/DataParam.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ese; 2 | 3 | 4 | import party.loveit.eosforandroidlibrary.utils.ByteUtils; 5 | import party.loveit.eosforandroidlibrary.utils.EException; 6 | 7 | /** 8 | * DataParam 9 | * 10 | * @author espritblock http://eblock.io 11 | * 12 | */ 13 | public class DataParam { 14 | 15 | public DataParam(String value, DataType type, Action action) { 16 | this.value = value; 17 | this.type = type; 18 | if (type == DataType.asset || type == DataType.symbol ) { 19 | if (action == action.transfer || action == action.delegate || action == action.close) { 20 | String vs[] = value.split(" "); 21 | if (vs.length < 2) {throw new EException("error", "quantity error");} 22 | String ammount = vs[0]; 23 | String ams [] = ammount.split("[.]"); 24 | int precision = 0; 25 | if(ams.length>1) {precision = ams[1].length();} 26 | this.value = vs[0] + " " + action.getCode().replace("${precision}",String.valueOf(precision)).replace("${quantity}", vs[1]); 27 | }else { 28 | this.value = value; 29 | } 30 | } 31 | } 32 | 33 | private String value; 34 | 35 | private DataType type; 36 | 37 | public String getValue() { 38 | return value; 39 | } 40 | 41 | public void setValue(String value) { 42 | this.value = value; 43 | } 44 | 45 | public DataType getType() { 46 | return type; 47 | } 48 | 49 | public void setType(DataType type) { 50 | this.type = type; 51 | } 52 | 53 | public byte[] seria() { 54 | if (this.type == DataType.name) { 55 | return ByteUtils.writeName(this.value); 56 | } else if (this.type == DataType.asset) { 57 | return ByteUtils.writerAsset(this.value); 58 | }else if (this.type == DataType.symbol) { 59 | return ByteUtils.writerSymbol(this.value); 60 | } else if (this.type == DataType.unit32) { 61 | return ByteUtils.writerUnit32(this.value); 62 | } else if (this.type == DataType.unit16) { 63 | return ByteUtils.writerUnit16(this.value); 64 | } else if (this.type == DataType.key) { 65 | return ByteUtils.writerKey(this.value); 66 | } else if (this.type == DataType.varint32) { 67 | return ByteUtils.writerVarint32(this.value); 68 | } else if (this.type == DataType.unit64) { 69 | return ByteUtils.writeUint64(this.value); 70 | } else { 71 | return ByteUtils.writerString(this.value); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ese/DataType.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ese; 2 | 3 | /** 4 | * DataType 5 | * 6 | * @author espritblock http://eblock.io 7 | * 8 | */ 9 | public enum DataType { 10 | 11 | name("name"), asset("asset"), string("string"), key("key"), unit16("unit16"), unit32("unit32"), varint32( 12 | "varint32"),unit64("unit64"),symbol("symbol"); 13 | 14 | private DataType(String code) { 15 | this.code = code; 16 | } 17 | 18 | private String code; 19 | 20 | public String getCode() { 21 | return code; 22 | } 23 | 24 | public void setCode(String code) { 25 | this.code = code; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/ese/Ese.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.ese; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import party.loveit.eosforandroidlibrary.utils.ByteUtils; 7 | import party.loveit.eosforandroidlibrary.utils.Hex; 8 | 9 | 10 | /** 11 | * Ese 12 | * 13 | * @author espritblock http://eblock.io 14 | * 15 | */ 16 | public class Ese { 17 | 18 | /** 19 | * parseTransferData 20 | * 21 | * @param 22 | * @return 23 | */ 24 | public static String parseTransferData(String from, String to, String quantity, String memo) { 25 | DataParam[] datas = new DataParam[] { new DataParam(from, DataType.name, Action.transfer), 26 | new DataParam(to, DataType.name, Action.transfer), 27 | new DataParam(quantity, DataType.asset, Action.transfer), 28 | new DataParam(memo, DataType.string, Action.transfer), }; 29 | byte[] allbyte = new byte[] {}; 30 | for (DataParam value : datas) { 31 | allbyte = ByteUtils.concat(allbyte, value.seria()); 32 | } 33 | // final byte [] b = allbyte.clone(); 34 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 35 | // for(int i=1;i<=a.length;i++) { 36 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 37 | // } 38 | return Hex.bytesToHexString(allbyte); 39 | } 40 | 41 | 42 | /** 43 | * parseTransferData 44 | * 45 | * @param 46 | * @return 47 | */ 48 | public static String parseVoteProducerData(String voter, String proxy, List producers) { 49 | List datas = new ArrayList(); 50 | datas.add(new DataParam(voter, DataType.name, Action.voteproducer)); 51 | datas.add(new DataParam(proxy, DataType.name, Action.voteproducer)); 52 | datas.add(new DataParam(String.valueOf(producers.size()), DataType.varint32, Action.voteproducer)); 53 | for(String producer:producers) { 54 | datas.add(new DataParam(producer, DataType.name, Action.voteproducer)); 55 | } 56 | byte[] allbyte = new byte[] {}; 57 | for (DataParam value : datas) { 58 | allbyte = ByteUtils.concat(allbyte, value.seria()); 59 | } 60 | // final byte [] b = allbyte.clone(); 61 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 62 | // for(int i=1;i<=a.length;i++) { 63 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 64 | // } 65 | return Hex.bytesToHexString(allbyte); 66 | } 67 | 68 | 69 | 70 | /** 71 | * parseTransferData 72 | * 73 | * @param 74 | * @return 75 | */ 76 | public static String parseAccountData(String creator, String name, String onwer, String active) { 77 | 78 | DataParam[] datas = new DataParam[] { 79 | // creator 80 | new DataParam(creator, DataType.name, Action.account), 81 | // name 82 | new DataParam(name, DataType.name, Action.account), 83 | // owner 84 | new DataParam(onwer, DataType.key, Action.account), 85 | // active 86 | new DataParam(active, DataType.key, Action.account), 87 | 88 | }; 89 | byte[] allbyte = new byte[] {}; 90 | for (DataParam value : datas) { 91 | allbyte = ByteUtils.concat(allbyte, value.seria()); 92 | } 93 | return Hex.bytesToHexString(allbyte); 94 | } 95 | 96 | /** 97 | * parseBuyRamData 98 | * 99 | * @param 100 | * @return 101 | */ 102 | public static String parseDelegateData(String from, String receiver, String stakeNetQuantity, 103 | String stakeCpuQuantity, int transfer) { 104 | 105 | DataParam[] datas = new DataParam[] { new DataParam(from, DataType.name, Action.delegate), 106 | new DataParam(receiver, DataType.name, Action.delegate), 107 | new DataParam(stakeNetQuantity, DataType.asset, Action.delegate), 108 | new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate), 109 | new DataParam(String.valueOf(transfer), DataType.varint32, Action.delegate) 110 | 111 | }; 112 | byte[] allbyte = new byte[] {}; 113 | for (DataParam value : datas) { 114 | allbyte = ByteUtils.concat(allbyte, value.seria()); 115 | } 116 | return Hex.bytesToHexString(allbyte); 117 | } 118 | 119 | /** 120 | * parseTransferData 121 | * 122 | * @param 123 | * @return 124 | */ 125 | public static String parseBuyRamData(String payer, String receiver, Long bytes) { 126 | 127 | DataParam[] datas = new DataParam[] { new DataParam(payer, DataType.name, Action.ram), 128 | new DataParam(receiver, DataType.name, Action.ram), 129 | new DataParam(String.valueOf(bytes), DataType.unit32, Action.ram) 130 | 131 | }; 132 | byte[] allbyte = new byte[] {}; 133 | for (DataParam value : datas) { 134 | allbyte = ByteUtils.concat(allbyte, value.seria()); 135 | } 136 | return Hex.bytesToHexString(allbyte); 137 | } 138 | 139 | /** 140 | * parseCloseData 141 | * 142 | * @param 143 | * @return 144 | */ 145 | public static String parseCloseData(String owner, String symbol) { 146 | DataParam[] datas = new DataParam[] { 147 | new DataParam(owner, DataType.name, Action.close), 148 | new DataParam(symbol, DataType.symbol, Action.close) 149 | }; 150 | byte[] allbyte = new byte[] {}; 151 | for (DataParam value : datas) { 152 | allbyte = ByteUtils.concat(allbyte, value.seria()); 153 | } 154 | return Hex.bytesToHexString(allbyte); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/exception/ApiError.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.exception; 2 | 3 | /** 4 | * 5 | * @author espritblock http://eblock.io 6 | * 7 | */ 8 | public class ApiError { 9 | 10 | private String message; 11 | 12 | private String code; 13 | 14 | private Error error; 15 | 16 | public String getMessage() { 17 | return message; 18 | } 19 | 20 | public void setMessage(String message) { 21 | this.message = message; 22 | } 23 | 24 | public String getCode() { 25 | return code; 26 | } 27 | 28 | public void setCode(String code) { 29 | this.code = code; 30 | } 31 | 32 | public Error getError() { 33 | return error; 34 | } 35 | 36 | public void setError(Error error) { 37 | this.error = error; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/exception/ApiException.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.exception; 2 | 3 | /** 4 | * 5 | * @author espritblock http://eblock.io 6 | * 7 | */ 8 | public class ApiException extends RuntimeException { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | 15 | private ApiError error; 16 | 17 | public ApiException(ApiError apiError) { 18 | this.error = apiError; 19 | } 20 | 21 | public ApiException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | public ApiError getError() { 26 | return error; 27 | } 28 | 29 | public void setError(ApiError error) { 30 | this.error = error; 31 | } 32 | 33 | @Override 34 | public String getMessage() { 35 | if (error != null) { 36 | return error.getMessage(); 37 | } 38 | return super.getMessage(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/exception/Error.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.exception; 2 | 3 | /** 4 | * 5 | * @author espritblock http://eblock.io 6 | * 7 | */ 8 | public class Error { 9 | 10 | private String code; 11 | 12 | private String name; 13 | 14 | private String what; 15 | 16 | private ErrorDetails[] details; 17 | 18 | private Error() { 19 | 20 | } 21 | 22 | public String getCode() { 23 | return code; 24 | } 25 | 26 | public void setCode(String code) { 27 | this.code = code; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public String getWhat() { 39 | return what; 40 | } 41 | 42 | public void setWhat(String what) { 43 | this.what = what; 44 | } 45 | 46 | public ErrorDetails[] getDetails() { 47 | return details; 48 | } 49 | 50 | public void setDetails(ErrorDetails[] details) { 51 | this.details = details; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/exception/ErrorDetails.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.exception; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | /** 6 | * 7 | * @author espritblock http://eblock.io 8 | * 9 | */ 10 | public class ErrorDetails { 11 | 12 | private String message; 13 | 14 | private String file; 15 | 16 | private Integer lineNumber; 17 | 18 | private String method; 19 | 20 | private ErrorDetails() { 21 | 22 | } 23 | 24 | public String getMessage() { 25 | return message; 26 | } 27 | 28 | public void setMessage(String message) { 29 | this.message = message; 30 | } 31 | 32 | public String getFile() { 33 | return file; 34 | } 35 | 36 | public void setFile(String file) { 37 | this.file = file; 38 | } 39 | 40 | public Integer getLineNumber() { 41 | return lineNumber; 42 | } 43 | 44 | @JsonProperty("line_number") 45 | public void setLineNumber(Integer lineNumber) { 46 | this.lineNumber = lineNumber; 47 | } 48 | 49 | public String getMethod() { 50 | return method; 51 | } 52 | 53 | public void setMethod(String method) { 54 | this.method = method; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/service/RpcService.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.service; 2 | 3 | import java.util.Map; 4 | 5 | 6 | import party.loveit.eosforandroidlibrary.rpc.vo.Block; 7 | import party.loveit.eosforandroidlibrary.rpc.vo.ChainInfo; 8 | import party.loveit.eosforandroidlibrary.rpc.vo.TableRows; 9 | import party.loveit.eosforandroidlibrary.rpc.vo.TableRowsReq; 10 | import party.loveit.eosforandroidlibrary.rpc.vo.account.Account; 11 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.Transaction; 12 | import party.loveit.eosforandroidlibrary.rpc.vo.transaction.push.TxRequest; 13 | import retrofit2.Call; 14 | import retrofit2.http.Body; 15 | import retrofit2.http.GET; 16 | import retrofit2.http.POST; 17 | 18 | /** 19 | * 20 | * @author espritblock http://eblock.io 21 | * 22 | */ 23 | public interface RpcService { 24 | 25 | @GET("/v1/chain/get_info") 26 | Call getChainInfo(); 27 | 28 | @POST("/v1/chain/get_block") 29 | Call getBlock(@Body Map requestFields); 30 | 31 | @POST("/v1/chain/get_account") 32 | Call getAccount(@Body Map requestFields); 33 | 34 | @POST("/v1/chain/push_transaction") 35 | Call pushTransaction(@Body TxRequest request); 36 | 37 | @POST("/v1/chain/get_table_rows") 38 | Call getTableRows(@Body TableRowsReq request); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/utils/Generator.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.utils; 2 | 3 | import java.io.IOException; 4 | import java.lang.annotation.Annotation; 5 | import okhttp3.OkHttpClient; 6 | import party.loveit.eosforandroidlibrary.rpc.exception.ApiError; 7 | import party.loveit.eosforandroidlibrary.rpc.exception.ApiException; 8 | import retrofit2.Call; 9 | import retrofit2.Response; 10 | import retrofit2.Retrofit; 11 | import retrofit2.converter.jackson.JacksonConverterFactory; 12 | 13 | public class Generator { 14 | 15 | private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 16 | 17 | private static Retrofit.Builder builder = new Retrofit.Builder() 18 | .addConverterFactory(JacksonConverterFactory.create()); 19 | 20 | private static Retrofit retrofit; 21 | 22 | public static S createService(Class serviceClass, String baseUrl) { 23 | builder.baseUrl(baseUrl); 24 | builder.client(httpClient.build()); 25 | builder.addConverterFactory(JacksonConverterFactory.create()); 26 | retrofit = builder.build(); 27 | return retrofit.create(serviceClass); 28 | } 29 | 30 | public static T executeSync(Call call) { 31 | try { 32 | Response response = call.execute(); 33 | if (response.isSuccessful()) { 34 | return response.body(); 35 | } else { 36 | ApiError apiError = getApiError(response); 37 | throw new ApiException(apiError); 38 | } 39 | } catch (IOException e) { 40 | throw new ApiException(e); 41 | } 42 | } 43 | 44 | private static ApiError getApiError(Response response) throws IOException, ApiException { 45 | return (ApiError) retrofit.responseBodyConverter(ApiError.class, new Annotation[0]).convert(response.errorBody()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/BaseVo.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | public class BaseVo { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/Block.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * 10 | * @author espritblock http://eblock.io 11 | * 12 | */ 13 | @JsonIgnoreProperties(ignoreUnknown = true) 14 | public class Block { 15 | 16 | @JsonProperty("timestamp") 17 | private Date timestamp; 18 | 19 | @JsonProperty("producer") 20 | private String producer; 21 | 22 | @JsonProperty("confirmed") 23 | private Long confirmed; 24 | 25 | @JsonProperty("previous") 26 | private String previous; 27 | 28 | @JsonProperty("transaction_mroot") 29 | private String transactionMroot; 30 | 31 | @JsonProperty("action_mroot") 32 | private String actionMroot; 33 | 34 | @JsonProperty("schedule_version") 35 | private String scheduleVersion; 36 | 37 | @JsonProperty("id") 38 | private String id; 39 | 40 | @JsonProperty("block_num") 41 | private Long blockNum; 42 | 43 | @JsonProperty("ref_block_prefix") 44 | private Long refBlockPrefix; 45 | 46 | public Block() { 47 | 48 | } 49 | 50 | public Date getTimestamp() { 51 | return timestamp; 52 | } 53 | 54 | public void setTimestamp(Date timestamp) { 55 | this.timestamp = timestamp; 56 | } 57 | 58 | public String getProducer() { 59 | return producer; 60 | } 61 | 62 | public void setProducer(String producer) { 63 | this.producer = producer; 64 | } 65 | 66 | public Long getConfirmed() { 67 | return confirmed; 68 | } 69 | 70 | public void setConfirmed(Long confirmed) { 71 | this.confirmed = confirmed; 72 | } 73 | 74 | public String getPrevious() { 75 | return previous; 76 | } 77 | 78 | public void setPrevious(String previous) { 79 | this.previous = previous; 80 | } 81 | 82 | public String getTransactionMroot() { 83 | return transactionMroot; 84 | } 85 | 86 | public void setTransactionMroot(String transactionMroot) { 87 | this.transactionMroot = transactionMroot; 88 | } 89 | 90 | public String getActionMroot() { 91 | return actionMroot; 92 | } 93 | 94 | public void setActionMroot(String actionMroot) { 95 | this.actionMroot = actionMroot; 96 | } 97 | 98 | public String getScheduleVersion() { 99 | return scheduleVersion; 100 | } 101 | 102 | public void setScheduleVersion(String scheduleVersion) { 103 | this.scheduleVersion = scheduleVersion; 104 | } 105 | 106 | public String getId() { 107 | return id; 108 | } 109 | 110 | public void setId(String id) { 111 | this.id = id; 112 | } 113 | 114 | public Long getBlockNum() { 115 | return blockNum; 116 | } 117 | 118 | public void setBlockNum(Long blockNum) { 119 | this.blockNum = blockNum; 120 | } 121 | 122 | public Long getRefBlockPrefix() { 123 | return refBlockPrefix; 124 | } 125 | 126 | public void setRefBlockPrefix(Long refBlockPrefix) { 127 | this.refBlockPrefix = refBlockPrefix; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/ChainInfo.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * 10 | * @author espritblock http://eblock.io 11 | * 12 | */ 13 | @JsonIgnoreProperties(ignoreUnknown = true) 14 | public class ChainInfo { 15 | 16 | public ChainInfo() { 17 | 18 | } 19 | 20 | @JsonProperty("server_version") 21 | private String serverVersion; 22 | 23 | @JsonProperty("chain_id") 24 | private String chainId; 25 | 26 | @JsonProperty("head_block_num") 27 | private String headBlockNum; 28 | 29 | @JsonProperty("last_irreversible_block_num") 30 | private Long lastIrreversibleBlockNum; 31 | 32 | @JsonProperty("last_irreversible_block_id") 33 | private String lastIrreversibleBlockId; 34 | 35 | @JsonProperty("head_block_id") 36 | private String headBlockId; 37 | 38 | @JsonProperty("head_block_time") 39 | private Date headBlockTime; 40 | 41 | @JsonProperty("head_block_producer") 42 | private String headBlockProducer; 43 | 44 | @JsonProperty("virtual_block_cpu_limit") 45 | private String virtualBlockCpuLimit; 46 | 47 | @JsonProperty("virtual_block_net_limit") 48 | private String virtualBlockNetLimit; 49 | 50 | @JsonProperty("block_cpu_limit") 51 | private String blockCpuLimit; 52 | 53 | @JsonProperty("block_net_limit") 54 | private String blockNetLimit; 55 | 56 | public String getServerVersion() { 57 | return serverVersion; 58 | } 59 | 60 | public void setServerVersion(String serverVersion) { 61 | this.serverVersion = serverVersion; 62 | } 63 | 64 | public String getChainId() { 65 | return chainId; 66 | } 67 | 68 | public void setChainId(String chainId) { 69 | this.chainId = chainId; 70 | } 71 | 72 | public String getHeadBlockNum() { 73 | return headBlockNum; 74 | } 75 | 76 | public void setHeadBlockNum(String headBlockNum) { 77 | this.headBlockNum = headBlockNum; 78 | } 79 | 80 | public Long getLastIrreversibleBlockNum() { 81 | return lastIrreversibleBlockNum; 82 | } 83 | 84 | public void setLastIrreversibleBlockNum(Long lastIrreversibleBlockNum) { 85 | this.lastIrreversibleBlockNum = lastIrreversibleBlockNum; 86 | } 87 | 88 | public String getLastIrreversibleBlockId() { 89 | return lastIrreversibleBlockId; 90 | } 91 | 92 | public void setLastIrreversibleBlockId(String lastIrreversibleBlockId) { 93 | this.lastIrreversibleBlockId = lastIrreversibleBlockId; 94 | } 95 | 96 | public Date getHeadBlockTime() { 97 | return headBlockTime; 98 | } 99 | 100 | public void setHeadBlockTime(Date headBlockTime) { 101 | this.headBlockTime = headBlockTime; 102 | } 103 | 104 | public String getHeadBlockProducer() { 105 | return headBlockProducer; 106 | } 107 | 108 | public void setHeadBlockProducer(String headBlockProducer) { 109 | this.headBlockProducer = headBlockProducer; 110 | } 111 | 112 | public String getVirtualBlockCpuLimit() { 113 | return virtualBlockCpuLimit; 114 | } 115 | 116 | public void setVirtualBlockCpuLimit(String virtualBlockCpuLimit) { 117 | this.virtualBlockCpuLimit = virtualBlockCpuLimit; 118 | } 119 | 120 | public String getVirtualBlockNetLimit() { 121 | return virtualBlockNetLimit; 122 | } 123 | 124 | public void setVirtualBlockNetLimit(String virtualBlockNetLimit) { 125 | this.virtualBlockNetLimit = virtualBlockNetLimit; 126 | } 127 | 128 | public String getBlockCpuLimit() { 129 | return blockCpuLimit; 130 | } 131 | 132 | public void setBlockCpuLimit(String blockCpuLimit) { 133 | this.blockCpuLimit = blockCpuLimit; 134 | } 135 | 136 | public String getBlockNetLimit() { 137 | return blockNetLimit; 138 | } 139 | 140 | public void setBlockNetLimit(String blockNetLimit) { 141 | this.blockNetLimit = blockNetLimit; 142 | } 143 | 144 | public String getHeadBlockId() { 145 | return headBlockId; 146 | } 147 | 148 | public void setHeadBlockId(String headBlockId) { 149 | this.headBlockId = headBlockId; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/SignParam.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 7 | * @author espritblock http://eblock.io 8 | * 9 | */ 10 | public class SignParam { 11 | /** 12 | * 最新区块时间 13 | */ 14 | private Date headBlockTime; 15 | /** 16 | * 链ID 17 | */ 18 | private String chainId; 19 | /** 20 | * 不可逆区块 21 | */ 22 | private Long lastIrreversibleBlockNum; 23 | /** 24 | * 上一个区块hash前缀 25 | */ 26 | private Long refBlockPrefix; 27 | /** 28 | * 过期时间 29 | */ 30 | private Long exp; 31 | 32 | public Date getHeadBlockTime() { 33 | return headBlockTime; 34 | } 35 | 36 | public void setHeadBlockTime(Date headBlockTime) { 37 | this.headBlockTime = headBlockTime; 38 | } 39 | 40 | public String getChainId() { 41 | return chainId; 42 | } 43 | 44 | public void setChainId(String chainId) { 45 | this.chainId = chainId; 46 | } 47 | 48 | public Long getLastIrreversibleBlockNum() { 49 | return lastIrreversibleBlockNum; 50 | } 51 | 52 | public void setLastIrreversibleBlockNum(Long lastIrreversibleBlockNum) { 53 | this.lastIrreversibleBlockNum = lastIrreversibleBlockNum; 54 | } 55 | 56 | public Long getRefBlockPrefix() { 57 | return refBlockPrefix; 58 | } 59 | 60 | public void setRefBlockPrefix(Long refBlockPrefix) { 61 | this.refBlockPrefix = refBlockPrefix; 62 | } 63 | 64 | public Long getExp() { 65 | return exp; 66 | } 67 | 68 | public void setExp(Long exp) { 69 | this.exp = exp; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/TableRows.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class TableRows { 10 | 11 | private Boolean more; 12 | 13 | private List rows; 14 | 15 | public Boolean getMore() { 16 | return more; 17 | } 18 | 19 | public void setMore(Boolean more) { 20 | this.more = more; 21 | } 22 | 23 | public List getRows() { 24 | return rows; 25 | } 26 | 27 | public void setRows(List rows) { 28 | this.rows = rows; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/TableRowsReq.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class TableRowsReq { 7 | 8 | private String code = "eosio"; 9 | 10 | private String scope; 11 | 12 | private String table; 13 | 14 | private Boolean json=true; 15 | 16 | private int limit = 10; 17 | 18 | public String getCode() { 19 | return code; 20 | } 21 | 22 | public void setCode(String code) { 23 | this.code = code; 24 | } 25 | 26 | public String getScope() { 27 | return scope; 28 | } 29 | 30 | public void setScope(String scope) { 31 | this.scope = scope; 32 | } 33 | 34 | public String getTable() { 35 | return table; 36 | } 37 | 38 | public void setTable(String table) { 39 | this.table = table; 40 | } 41 | 42 | public int getLimit() { 43 | return limit; 44 | } 45 | 46 | public void setLimit(int limit) { 47 | this.limit = limit; 48 | } 49 | 50 | public Boolean getJson() { 51 | return json; 52 | } 53 | 54 | public void setJson(Boolean json) { 55 | this.json = json; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/Account.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | /** 10 | * 11 | * @author espritblock http://eblock.io 12 | * 13 | */ 14 | @JsonIgnoreProperties(ignoreUnknown = true) 15 | public class Account { 16 | 17 | @JsonProperty("account_name") 18 | private String accountName; 19 | 20 | @JsonProperty("privileged") 21 | private String privileged; 22 | 23 | @JsonProperty("last_code_update") 24 | private Date lastCodeUpdate; 25 | 26 | @JsonProperty("created") 27 | private Date created; 28 | 29 | @JsonProperty("ram_quota") 30 | private Long ramQuota; 31 | 32 | @JsonProperty("net_weight") 33 | private Long netWeight; 34 | 35 | @JsonProperty("cpu_weight") 36 | private Long cpuWeight; 37 | 38 | @JsonProperty("net_limit") 39 | private NetLimit netLimit; 40 | 41 | @JsonProperty("cpu_limit") 42 | private CpuLimit cpuLimit; 43 | 44 | @JsonProperty("ram_usage") 45 | private Long ramUsage; 46 | 47 | @JsonProperty("permissions") 48 | private List permissions; 49 | 50 | public Account() { 51 | 52 | } 53 | 54 | public String getAccountName() { 55 | return accountName; 56 | } 57 | 58 | public void setAccountName(String accountName) { 59 | this.accountName = accountName; 60 | } 61 | 62 | public String getPrivileged() { 63 | return privileged; 64 | } 65 | 66 | public void setPrivileged(String privileged) { 67 | this.privileged = privileged; 68 | } 69 | 70 | public Date getLastCodeUpdate() { 71 | return lastCodeUpdate; 72 | } 73 | 74 | public void setLastCodeUpdate(Date lastCodeUpdate) { 75 | this.lastCodeUpdate = lastCodeUpdate; 76 | } 77 | 78 | public Date getCreated() { 79 | return created; 80 | } 81 | 82 | public void setCreated(Date created) { 83 | this.created = created; 84 | } 85 | 86 | public Long getRamQuota() { 87 | return ramQuota; 88 | } 89 | 90 | public void setRamQuota(Long ramQuota) { 91 | this.ramQuota = ramQuota; 92 | } 93 | 94 | public Long getNetWeight() { 95 | return netWeight; 96 | } 97 | 98 | public void setNetWeight(Long netWeight) { 99 | this.netWeight = netWeight; 100 | } 101 | 102 | public Long getCpuWeight() { 103 | return cpuWeight; 104 | } 105 | 106 | public void setCpuWeight(Long cpuWeight) { 107 | this.cpuWeight = cpuWeight; 108 | } 109 | 110 | public NetLimit getNetLimit() { 111 | return netLimit; 112 | } 113 | 114 | public void setNetLimit(NetLimit netLimit) { 115 | this.netLimit = netLimit; 116 | } 117 | 118 | public CpuLimit getCpuLimit() { 119 | return cpuLimit; 120 | } 121 | 122 | public void setCpuLimit(CpuLimit cpuLimit) { 123 | this.cpuLimit = cpuLimit; 124 | } 125 | 126 | public Long getRamUsage() { 127 | return ramUsage; 128 | } 129 | 130 | public void setRamUsage(Long ramUsage) { 131 | this.ramUsage = ramUsage; 132 | } 133 | 134 | public List getPermissions() { 135 | return permissions; 136 | } 137 | 138 | public void setPermissions(List permissions) { 139 | this.permissions = permissions; 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/CpuLimit.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * 7 | * @author espritblock http://eblock.io 8 | * 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class CpuLimit { 12 | 13 | private Long used; 14 | 15 | private Long available; 16 | 17 | private Long max; 18 | 19 | public CpuLimit() { 20 | 21 | } 22 | 23 | public Long getUsed() { 24 | return used; 25 | } 26 | 27 | public void setUsed(Long used) { 28 | this.used = used; 29 | } 30 | 31 | public Long getAvailable() { 32 | return available; 33 | } 34 | 35 | public void setAvailable(Long available) { 36 | this.available = available; 37 | } 38 | 39 | public Long getMax() { 40 | return max; 41 | } 42 | 43 | public void setMax(Long max) { 44 | this.max = max; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/Key.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * 7 | * @author espritblock http://eblock.io 8 | * 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class Key { 12 | 13 | private String key; 14 | 15 | private Long weight; 16 | 17 | public Key() { 18 | 19 | } 20 | 21 | public String getKey() { 22 | return key; 23 | } 24 | 25 | public void setKey(String key) { 26 | this.key = key; 27 | } 28 | 29 | public Long getWeight() { 30 | return weight; 31 | } 32 | 33 | public void setWeight(Long weight) { 34 | this.weight = weight; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/NetLimit.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * 7 | * @author espritblock http://eblock.io 8 | * 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class NetLimit { 12 | 13 | private Long used; 14 | 15 | private Long available; 16 | 17 | private Long max; 18 | 19 | public NetLimit() { 20 | 21 | } 22 | 23 | public Long getUsed() { 24 | return used; 25 | } 26 | 27 | public void setUsed(Long used) { 28 | this.used = used; 29 | } 30 | 31 | public Long getAvailable() { 32 | return available; 33 | } 34 | 35 | public void setAvailable(Long available) { 36 | this.available = available; 37 | } 38 | 39 | public Long getMax() { 40 | return max; 41 | } 42 | 43 | public void setMax(Long max) { 44 | this.max = max; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/Permission.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class Permission { 13 | 14 | public Permission() { 15 | 16 | } 17 | 18 | @JsonProperty("perm_name") 19 | private String permName; 20 | 21 | @JsonProperty("parent") 22 | private String parent; 23 | 24 | @JsonProperty("required_auth") 25 | private RequiredAuth requiredAuth; 26 | 27 | public String getPermName() { 28 | return permName; 29 | } 30 | 31 | public void setPermName(String permName) { 32 | this.permName = permName; 33 | } 34 | 35 | public String getParent() { 36 | return parent; 37 | } 38 | 39 | public void setParent(String parent) { 40 | this.parent = parent; 41 | } 42 | 43 | public RequiredAuth getRequiredAuth() { 44 | return requiredAuth; 45 | } 46 | 47 | public void setRequiredAuth(RequiredAuth requiredAuth) { 48 | this.requiredAuth = requiredAuth; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/account/RequiredAuth.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.account; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 9 | * @author espritblock http://eblock.io 10 | * 11 | */ 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | public class RequiredAuth { 14 | 15 | private List accounts; 16 | 17 | private List keys; 18 | 19 | private Long threshold; 20 | 21 | public List getAccounts() { 22 | return accounts; 23 | } 24 | 25 | public void setAccounts(List accounts) { 26 | this.accounts = accounts; 27 | } 28 | 29 | public List getKeys() { 30 | return keys; 31 | } 32 | 33 | public void setKeys(List keys) { 34 | this.keys = keys; 35 | } 36 | 37 | public Long getThreshold() { 38 | return threshold; 39 | } 40 | 41 | public void setThreshold(Long threshold) { 42 | this.threshold = threshold; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/Processed.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class Processed { 13 | 14 | @JsonProperty("id") 15 | private String id; 16 | 17 | @JsonProperty("receipt") 18 | private Receipt receipt; 19 | 20 | @JsonProperty("elapsed") 21 | private Long elapsed; 22 | 23 | @JsonProperty("net_usage") 24 | private Long netUsage; 25 | 26 | @JsonProperty("scheduled") 27 | private Boolean scheduled; 28 | 29 | public String getId() { 30 | return id; 31 | } 32 | 33 | public void setId(String id) { 34 | this.id = id; 35 | } 36 | 37 | public Receipt getReceipt() { 38 | return receipt; 39 | } 40 | 41 | public void setReceipt(Receipt receipt) { 42 | this.receipt = receipt; 43 | } 44 | 45 | public Long getElapsed() { 46 | return elapsed; 47 | } 48 | 49 | public void setElapsed(Long elapsed) { 50 | this.elapsed = elapsed; 51 | } 52 | 53 | public Long getNetUsage() { 54 | return netUsage; 55 | } 56 | 57 | public void setNetUsage(Long netUsage) { 58 | this.netUsage = netUsage; 59 | } 60 | 61 | public Boolean getScheduled() { 62 | return scheduled; 63 | } 64 | 65 | public void setScheduled(Boolean scheduled) { 66 | this.scheduled = scheduled; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/Receipt.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class Receipt { 13 | 14 | @JsonProperty("status") 15 | private String status; 16 | 17 | @JsonProperty("cpu_usage_us") 18 | private Long cpuUsageUs; 19 | 20 | @JsonProperty("net_usage_words") 21 | private Long netUsageWords; 22 | 23 | public String getStatus() { 24 | return status; 25 | } 26 | 27 | public void setStatus(String status) { 28 | this.status = status; 29 | } 30 | 31 | public Long getCpuUsageUs() { 32 | return cpuUsageUs; 33 | } 34 | 35 | public void setCpuUsageUs(Long cpuUsageUs) { 36 | this.cpuUsageUs = cpuUsageUs; 37 | } 38 | 39 | public Long getNetUsageWords() { 40 | return netUsageWords; 41 | } 42 | 43 | public void setNetUsageWords(Long netUsageWords) { 44 | this.netUsageWords = netUsageWords; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/Transaction.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.databind.deser.Deserializers.Base; 6 | 7 | /** 8 | * 9 | * @author espritblock http://eblock.io 10 | * 11 | */ 12 | @JsonIgnoreProperties(ignoreUnknown = true) 13 | public class Transaction extends Base { 14 | 15 | @JsonProperty("transaction_id") 16 | private String transactionId; 17 | 18 | @JsonProperty("processed") 19 | private Processed processed; 20 | 21 | public String getTransactionId() { 22 | return transactionId; 23 | } 24 | 25 | public void setTransactionId(String transactionId) { 26 | this.transactionId = transactionId; 27 | } 28 | 29 | public Processed getProcessed() { 30 | return processed; 31 | } 32 | 33 | public void setProcessed(Processed processed) { 34 | this.processed = processed; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/Tx.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 9 | 10 | 11 | /** 12 | * 13 | * @author espritblock http://eblock.io 14 | * 15 | */ 16 | @JsonIgnoreProperties(ignoreUnknown = true) 17 | public class Tx extends BaseVo { 18 | 19 | private Object expiration; 20 | 21 | private Long ref_block_num; 22 | 23 | private Long ref_block_prefix; 24 | 25 | private Long net_usage_words; 26 | 27 | private Long max_cpu_usage_ms; 28 | 29 | private Long delay_sec; 30 | 31 | private List context_free_actions = new ArrayList<>(); 32 | 33 | private List actions; 34 | 35 | private List transaction_extensions = new ArrayList<>(); 36 | 37 | public Object getExpiration() { 38 | return expiration; 39 | } 40 | 41 | public void setExpiration(Object expiration) { 42 | this.expiration = expiration; 43 | } 44 | 45 | public Long getRef_block_num() { 46 | return ref_block_num; 47 | } 48 | 49 | public void setRef_block_num(Long ref_block_num) { 50 | this.ref_block_num = ref_block_num; 51 | } 52 | 53 | public Long getRef_block_prefix() { 54 | return ref_block_prefix; 55 | } 56 | 57 | public void setRef_block_prefix(Long ref_block_prefix) { 58 | this.ref_block_prefix = ref_block_prefix; 59 | } 60 | 61 | public Long getNet_usage_words() { 62 | return net_usage_words; 63 | } 64 | 65 | public void setNet_usage_words(Long net_usage_words) { 66 | this.net_usage_words = net_usage_words; 67 | } 68 | 69 | public Long getMax_cpu_usage_ms() { 70 | return max_cpu_usage_ms; 71 | } 72 | 73 | public void setMax_cpu_usage_ms(Long max_cpu_usage_ms) { 74 | this.max_cpu_usage_ms = max_cpu_usage_ms; 75 | } 76 | 77 | public Long getDelay_sec() { 78 | return delay_sec; 79 | } 80 | 81 | public void setDelay_sec(Long delay_sec) { 82 | this.delay_sec = delay_sec; 83 | } 84 | 85 | public List getContext_free_actions() { 86 | return context_free_actions; 87 | } 88 | 89 | public void setContext_free_actions(List context_free_actions) { 90 | this.context_free_actions = context_free_actions; 91 | } 92 | 93 | public List getActions() { 94 | return actions; 95 | } 96 | 97 | public void setActions(List actions) { 98 | this.actions = actions; 99 | } 100 | 101 | public List getTransaction_extensions() { 102 | return transaction_extensions; 103 | } 104 | 105 | public void setTransaction_extensions(List transaction_extensions) { 106 | this.transaction_extensions = transaction_extensions; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/TxAction.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 7 | 8 | 9 | /** 10 | * 11 | * @author espritblock http://eblock.io 12 | * 13 | */ 14 | public class TxAction extends BaseVo { 15 | 16 | public TxAction() { 17 | 18 | } 19 | 20 | public TxAction(String actor, String account, String name, Object data) { 21 | this.account = account; 22 | this.name = name; 23 | this.data = data; 24 | this.authorization = new ArrayList<>(); 25 | this.authorization.add(new TxActionAuth(actor, "active")); 26 | } 27 | 28 | private String account; 29 | 30 | private String name; 31 | 32 | private List authorization; 33 | 34 | private Object data; 35 | 36 | public String getAccount() { 37 | return account; 38 | } 39 | 40 | public void setAccount(String account) { 41 | this.account = account; 42 | } 43 | 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | public List getAuthorization() { 53 | return authorization; 54 | } 55 | 56 | public void setAuthorization(List authorization) { 57 | this.authorization = authorization; 58 | } 59 | 60 | public Object getData() { 61 | return data; 62 | } 63 | 64 | public void setData(Object data) { 65 | this.data = data; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/TxActionAuth.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | 4 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | public class TxActionAuth extends BaseVo { 12 | 13 | public TxActionAuth() { 14 | 15 | } 16 | 17 | public TxActionAuth(String actor, String permission) { 18 | this.actor = actor; 19 | this.permission = permission; 20 | } 21 | 22 | private String actor; 23 | 24 | private String permission; 25 | 26 | public String getActor() { 27 | return actor; 28 | } 29 | 30 | public void setActor(String actor) { 31 | this.actor = actor; 32 | } 33 | 34 | public String getPermission() { 35 | return permission; 36 | } 37 | 38 | public void setPermission(String permission) { 39 | this.permission = permission; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/TxExtenstions.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 6 | 7 | 8 | /** 9 | * 10 | * @author espritblock http://eblock.io 11 | * 12 | */ 13 | @JsonIgnoreProperties(ignoreUnknown = true) 14 | public class TxExtenstions extends BaseVo { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/TxRequest.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | 4 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | public class TxRequest extends BaseVo { 12 | 13 | public TxRequest() { 14 | 15 | } 16 | 17 | public TxRequest(String compression, Tx transaction, String[] signatures) { 18 | this.compression = compression; 19 | this.transaction = transaction; 20 | this.signatures = signatures; 21 | } 22 | 23 | private String compression; 24 | 25 | private Tx transaction; 26 | 27 | private String[] signatures; 28 | 29 | public String getCompression() { 30 | return compression; 31 | } 32 | 33 | public void setCompression(String compression) { 34 | this.compression = compression; 35 | } 36 | 37 | public Tx getTransaction() { 38 | return transaction; 39 | } 40 | 41 | public void setTransaction(Tx transaction) { 42 | this.transaction = transaction; 43 | } 44 | 45 | public String[] getSignatures() { 46 | return signatures; 47 | } 48 | 49 | public void setSignatures(String[] signatures) { 50 | this.signatures = signatures; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/rpc/vo/transaction/push/TxSign.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.rpc.vo.transaction.push; 2 | 3 | 4 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 5 | 6 | /** 7 | * 8 | * @author espritblock http://eblock.io 9 | * 10 | */ 11 | public class TxSign extends BaseVo { 12 | 13 | public TxSign() { 14 | 15 | } 16 | 17 | public TxSign(String chain_id, Tx transaction) { 18 | this.chain_id = chain_id; 19 | this.transaction = transaction; 20 | } 21 | 22 | private String chain_id; 23 | 24 | private Tx transaction; 25 | 26 | public String getChain_id() { 27 | return chain_id; 28 | } 29 | 30 | public void setChain_id(String chain_id) { 31 | this.chain_id = chain_id; 32 | } 33 | 34 | public Tx getTransaction() { 35 | return transaction; 36 | } 37 | 38 | public void setTransaction(Tx transaction) { 39 | this.transaction = transaction; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/Base58.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.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/party/loveit/eosforandroidlibrary/utils/ByteBuffer.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | /** 4 | * 5 | * @author espritblock http://eblock.io 6 | * 7 | */ 8 | public class ByteBuffer { 9 | 10 | private byte[] buffer = new byte[] {}; 11 | 12 | public void concat(byte[] b) { 13 | 14 | // int[] a = IntStream.range(0, b.length).map(i -> b[i] & 0xff).toArray(); 15 | // for(int i=1;i<=a.length;i++) { 16 | // System.out.print(a[i-1]+","+((i%8==0)?"\n":"")); 17 | // } 18 | buffer = ByteUtils.concat(buffer, b); 19 | } 20 | 21 | public byte[] getBuffer() { 22 | return buffer; 23 | } 24 | 25 | public void setBuffer(byte[] buffer) { 26 | this.buffer = buffer; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/ByteUtils.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | import java.math.BigInteger; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | /** 8 | * 9 | * @author espritblock http://eblock.io 10 | * 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 | * 44 | * @return 45 | */ 46 | public static byte[] copy(byte[] src, int start, int length) { 47 | byte[] c = new byte[length]; 48 | System.arraycopy(src, start, c, 0, length); 49 | return c; 50 | } 51 | 52 | /** 53 | * copy 54 | * 55 | * @param 56 | * @param 57 | * @return 58 | */ 59 | public static byte[] copy(byte[] src, int start, byte[] dest, int dstart, int length) { 60 | System.arraycopy(src, start, dest, dstart, length); 61 | return dest; 62 | } 63 | 64 | /** 65 | * LongToBytes 66 | * 67 | * @param 68 | * @return 69 | */ 70 | public static int[] LongToBytes(Long n) { 71 | ByteBuffer hi = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.BIG_ENDIAN).putLong(n); 72 | byte[] buf = hi.array(); 73 | int[] a = new int[buf.length]; 74 | for (int i = 0; i< buf.length; i++){ 75 | a[i] = buf[i] & 0xff; 76 | } 77 | //int[] a = IntStream.range(0, buf.length).map(i -> buf[i] & 0xff).toArray(); 78 | return a; 79 | } 80 | 81 | /** 82 | * 83 | * @param value 84 | * @return 85 | */ 86 | public static String stringToAscii(String value) { 87 | StringBuffer sbu = new StringBuffer(); 88 | char[] chars = value.toCharArray(); 89 | for (int i = 0; i < chars.length; i++) { 90 | if (i != chars.length - 1) { 91 | sbu.append((int) chars[i]); 92 | } else { 93 | sbu.append((int) chars[i]); 94 | } 95 | } 96 | return sbu.toString(); 97 | } 98 | 99 | /** 100 | * writerUnit32 101 | * 102 | * @param value 103 | * @return 104 | */ 105 | public static byte[] writerUnit32(String value) { 106 | 107 | Long l = Long.parseLong(value); 108 | if (l > Integer.MAX_VALUE) { 109 | byte[] b = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(l).array(); 110 | int j = 0; 111 | for (int i = b.length - 1; i >= 0; i--) { 112 | if (b[i] == (byte) 0) { 113 | j++; 114 | } else { 115 | break; 116 | } 117 | } 118 | return ByteUtils.copy(b, 0, b.length - j); 119 | } else { 120 | return ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(Integer.parseInt(value)) 121 | .array(); 122 | } 123 | } 124 | 125 | /** 126 | * writerUnit16 127 | * 128 | * @param value 129 | * @return 130 | */ 131 | public static byte[] writerUnit16(String value) { 132 | long vl = Long.parseLong(value); 133 | return new byte[] { (byte) (vl & 0x00FF), (byte) ((vl & 0xFF00) >>> 8) }; 134 | } 135 | 136 | /** 137 | * writerUnit8 138 | * 139 | * @param value 140 | * @return 141 | */ 142 | public static byte[] writerUnit8(String value) { 143 | long vl = Long.parseLong(value); 144 | return new byte[] { (byte) (vl & 0x00FF) }; 145 | } 146 | 147 | /** 148 | * writerVarint32 149 | * 150 | * @param v 151 | * @return 152 | */ 153 | public static byte[] writerVarint32(String v) { 154 | long value = Long.parseLong(v); 155 | byte[] a = new byte[] {}; 156 | value >>>= 0; 157 | while (value >= 0x80) { 158 | long b = (value & 0x7f) | 0x80; 159 | a = ByteUtils.concat(a, new byte[] { (byte) b }); 160 | value >>>= 7; 161 | } 162 | a = ByteUtils.concat(a, new byte[] { (byte) value }); 163 | return a; 164 | } 165 | 166 | /** 167 | * writerAsset 168 | * 169 | * @param v 170 | * @return 171 | */ 172 | public static byte[] writerAsset(String v) { 173 | String _value[] = v.split(" "); 174 | String amount = _value[0]; 175 | if(amount==null || !amount.matches("^[0-9]+(.[0-9]+)?$")){ 176 | throw new EException("amount_error", "amount error"); 177 | } 178 | String sym = _value[1]; 179 | String precision = sym.split(",")[0]; 180 | String symbol = sym.split(",")[1].split("@")[0]; 181 | String[] part = amount.split("[.]"); 182 | 183 | int pad = Integer.parseInt(precision); 184 | StringBuffer bf = new StringBuffer(part[0] + "."); 185 | if (part.length > 1) { 186 | if(part[1].length()>pad) { 187 | throw new EException("precision_error", "precision max "+pad); 188 | } 189 | pad = Integer.parseInt(precision) - part[1].length(); 190 | bf.append(part[1]); 191 | } 192 | // ���Ȳ�0 193 | for (int i = 0; i < pad; i++) { 194 | bf.append("0"); 195 | } 196 | String asset = precision + "," + symbol; 197 | // amount 198 | amount = bf.toString().replace(".", ""); 199 | ByteBuffer ammount = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN) 200 | .putLong(Long.parseLong(amount)); 201 | 202 | // asset 203 | StringBuffer padStr = new StringBuffer(); 204 | for (int i = 0; i < (7 - symbol.length()); i++) { 205 | padStr.append("\0"); 206 | } 207 | char c = (char) Integer.parseInt(precision); 208 | asset = c + symbol + padStr; 209 | ByteBuffer ba = ByteBuffer.wrap(asset.getBytes()); 210 | return ByteUtils.concat(ammount.array(), ba.array()); 211 | } 212 | 213 | /** 214 | * writerAsset 215 | * 216 | * @param v 217 | * @return 218 | */ 219 | public static byte[] writerSymbol(String v) { 220 | String _value[] = v.split(" "); 221 | String amount = _value[0]; 222 | if(amount==null || !amount.matches("^[0-9]+(.[0-9]+)?$")){ 223 | throw new EException("amount_error", "amount error"); 224 | } 225 | String sym = _value[1]; 226 | String precision = sym.split(",")[0]; 227 | String symbol = sym.split(",")[1].split("@")[0]; 228 | String[] part = amount.split("[.]"); 229 | 230 | int pad = Integer.parseInt(precision); 231 | StringBuffer bf = new StringBuffer(part[0] + "."); 232 | if (part.length > 1) { 233 | if(part[1].length()>pad) { 234 | throw new EException("precision_error", "precision max "+pad); 235 | } 236 | pad = Integer.parseInt(precision) - part[1].length(); 237 | bf.append(part[1]); 238 | } 239 | // ���Ȳ�0 240 | for (int i = 0; i < pad; i++) { 241 | bf.append("0"); 242 | } 243 | String asset = precision + "," + symbol; 244 | // amount 245 | // amount = bf.toString().replace(".", ""); 246 | // ByteBuffer ammount = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN) 247 | // .putLong(Long.parseLong(amount)); 248 | 249 | // asset 250 | StringBuffer padStr = new StringBuffer(); 251 | for (int i = 0; i < (7 - symbol.length()); i++) { 252 | padStr.append("\0"); 253 | } 254 | char c = (char) Integer.parseInt(precision); 255 | asset = c + symbol + padStr; 256 | ByteBuffer ba = ByteBuffer.wrap(asset.getBytes()); 257 | return ba.array(); 258 | } 259 | 260 | /** 261 | * writerAccount 262 | * 263 | * @param v 264 | * @return 265 | */ 266 | public static byte[] writeName(String v) { 267 | StringBuffer bitstr = new StringBuffer(); 268 | for (int i = 0; i <= 12; i++) { 269 | int c = i < v.length() ? ByteUtils.charidx(v.charAt(i)) : 0; 270 | int bitlen = i < 12 ? 5 : 4; 271 | String bits = Integer.toBinaryString(c); 272 | if (bits.length() > bitlen) { 273 | throw new EException("", "Invalid name " + v); 274 | } 275 | StringBuffer sb = new StringBuffer(""); 276 | for (int j = 0; j < bitlen - bits.length(); j++) { 277 | sb.append("0"); 278 | } 279 | bits = sb + bits; 280 | bitstr.append(bits); 281 | } 282 | BigInteger lv = new BigInteger(bitstr.toString(), 2); 283 | StringBuffer leHex = new StringBuffer(); 284 | int bytes[] = ByteUtils.LongToBytes(lv.longValue()); 285 | for (int i = 0; i < bytes.length; i++) { 286 | int b = bytes[i]; 287 | String n = Integer.toHexString(b); 288 | leHex.append(n.length() == 1 ? "0" : "").append(n); 289 | } 290 | BigInteger ulName = new BigInteger(leHex.toString(), 16); 291 | return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(ulName.longValue()).array(); 292 | } 293 | 294 | /** 295 | * charCount 296 | * 297 | * @return 298 | */ 299 | private static long charCount(String v) { 300 | long c = 0; 301 | for (char cp : v.toCharArray()) { 302 | if (cp < 0x80) { 303 | c += 1; 304 | } else if (cp < 0x800) { 305 | c += 2; 306 | } else if (cp < 0x10000) { 307 | c += 3; 308 | } else { 309 | c += 4; 310 | } 311 | } 312 | return c; 313 | } 314 | 315 | /** 316 | * writerString 317 | * 318 | * @param v 319 | * @return 320 | */ 321 | public static byte[] writerString(String v) { 322 | long value = charCount(v); 323 | byte[] a = new byte[] {}; 324 | value >>>= 0; 325 | while (value >= 0x80) { 326 | long b = (value & 0x7f) | 0x80; 327 | a = ByteUtils.concat(a, new byte[] { (byte) b }); 328 | value >>>= 7; 329 | } 330 | a = ByteUtils.concat(a, new byte[] { (byte) value }); 331 | for (char c : v.toCharArray()) { 332 | a = ByteUtils.concat(a, decodeChar(c)); 333 | } 334 | return a; 335 | } 336 | 337 | /** 338 | * decodeChar 339 | * 340 | * @param ca 341 | * @return 342 | */ 343 | private static byte[] decodeChar(char ca) { 344 | long cp = (long) ca; 345 | if (cp < 0x80) { 346 | long a = cp & 0x7F; 347 | return new byte[] { (byte) a }; 348 | } else if (cp < 0x800) { 349 | long a = ((cp >> 6) & 0x1F) | 0xC0; 350 | long b = (cp & 0x3F) | 0x80; 351 | return new byte[] { (byte) a, (byte) b }; 352 | } else if (cp < 0x10000) { 353 | long a = ((cp >> 12) & 0x0F) | 0xE0; 354 | long b = ((cp >> 6) & 0x3F) | 0x80; 355 | long c = (cp & 0x3F) | 0x80; 356 | return new byte[] { (byte) a, (byte) b, (byte) c }; 357 | } else { 358 | long a = ((cp >> 18) & 0x07) | 0xF0; 359 | long b = ((cp >> 12) & 0x3F) | 0x80; 360 | long c = ((cp >> 6) & 0x3F) | 0x80; 361 | long d = (cp & 0x3F) | 0x80; 362 | return new byte[] { (byte) a, (byte) b, (byte) c, (byte) d }; 363 | } 364 | } 365 | 366 | /** 367 | * writerKey 368 | * 369 | * @param v 370 | * @return 371 | */ 372 | private static byte[] writerKeyStr(String v) { 373 | v = v.replace("EOS", ""); 374 | byte[] b = Base58.decode(v); 375 | b = ByteBuffer.allocate(b.length).order(ByteOrder.BIG_ENDIAN).put(b).array(); 376 | byte[] key = ByteUtils.copy(b, 0, b.length - 4); 377 | return key; 378 | } 379 | 380 | /** 381 | * writerKey 382 | * 383 | * @param key 384 | */ 385 | public static byte[] writerKey(String key) { 386 | party.loveit.eosforandroidlibrary.utils.ByteBuffer bf = new party.loveit.eosforandroidlibrary.utils.ByteBuffer (); 387 | bf.concat(writerUnit32("1")); 388 | bf.concat(writerVarint32("1")); 389 | bf.concat(writerVarint32("0")); 390 | bf.concat(writerKeyStr(key)); 391 | bf.concat(writerUnit16("1")); 392 | bf.concat(writerVarint32("0")); 393 | bf.concat(writerVarint32("0")); 394 | return bf.getBuffer(); 395 | } 396 | 397 | public static byte[] writeUint64(String v) { 398 | return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(Long.parseLong(v)).array(); 399 | } 400 | 401 | } 402 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/EException.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | /** 4 | * exception 5 | * 6 | * @author espritblock http://eblock.io 7 | * 8 | */ 9 | public class EException extends RuntimeException { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | public EException(String code, String msg) { 14 | this.code = code; 15 | this.msg = msg; 16 | } 17 | 18 | private String code; 19 | 20 | private String msg; 21 | 22 | public String getCode() { 23 | return code; 24 | } 25 | 26 | public void setCode(String code) { 27 | this.code = code; 28 | } 29 | 30 | public String getMsg() { 31 | return msg; 32 | } 33 | 34 | public void setMsg(String msg) { 35 | this.msg = msg; 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/GeneralDigest.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 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/party/loveit/eosforandroidlibrary/utils/Hex.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | /** 4 | * Hex 5 | * 6 | * @author espritblock http://eblock.io 7 | * 8 | */ 9 | public class Hex { 10 | 11 | /** 12 | * toBytes 13 | * 14 | * @param 15 | * @return 16 | */ 17 | public static byte[] toBytes(String hex) { 18 | if (hex == null || hex.length() % 2 != 0) { 19 | throw new EException("args_eroor", "args is error"); 20 | } 21 | char[] hbyte = hex.toCharArray(); 22 | int length = hbyte.length / 2; 23 | byte[] raw = new byte[length]; 24 | for (int i = 0; i < length; i++) { 25 | int high = Character.digit(hbyte[i * 2], 16); 26 | int low = Character.digit(hbyte[i * 2 + 1], 16); 27 | if (high < 0 || low < 0) { 28 | throw new RuntimeException("Invalid hex digit " + hbyte[i * 2] + hbyte[i * 2 + 1]); 29 | } 30 | int value = (high << 4) | low; 31 | if (value > 127) 32 | value -= 256; 33 | raw[i] = (byte) value; 34 | } 35 | return raw; 36 | } 37 | 38 | /** 39 | * bytesToHexString 40 | * 41 | * @param src 42 | * @return 43 | */ 44 | public static String bytesToHexString(byte[] src) { 45 | StringBuilder stringBuilder = new StringBuilder(""); 46 | if (src == null || src.length <= 0) { 47 | return null; 48 | } 49 | for (int i = 0; i < src.length; i++) { 50 | int v = src[i] & 0xFF; 51 | String hv = Integer.toHexString(v); 52 | if (hv.length() < 2) { 53 | stringBuilder.append(0); 54 | } 55 | stringBuilder.append(hv); 56 | } 57 | return stringBuilder.toString(); 58 | } 59 | 60 | /** 61 | * hexStringToBytes 62 | * 63 | * @param hexString 64 | * @return 65 | */ 66 | public static byte[] hexStringToBytes(String hexString) { 67 | if (hexString == null || hexString.equals("")) { 68 | return null; 69 | } 70 | hexString = hexString.toUpperCase(); 71 | int length = hexString.length() / 2; 72 | char[] hexChars = hexString.toCharArray(); 73 | byte[] d = new byte[length]; 74 | for (int i = 0; i < length; i++) { 75 | int pos = i * 2; 76 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); 77 | } 78 | return d; 79 | } 80 | 81 | private static byte charToByte(char c) { 82 | return (byte) "0123456789ABCDEF".indexOf(c); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.HashMap; 6 | import java.util.LinkedHashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import party.loveit.eosforandroidlibrary.rpc.vo.BaseVo; 11 | 12 | 13 | public class ObjectUtils { 14 | 15 | private static Object getFieldValueByName(String fieldName, Object o) { 16 | try { 17 | String firstLetter = fieldName.substring(0, 1).toUpperCase(); 18 | String getter = "get" + firstLetter + fieldName.substring(1); 19 | Method method = o.getClass().getMethod(getter, new Class[] {}); 20 | Object value = method.invoke(o, new Object[] {}); 21 | return value; 22 | } catch (Exception e) { 23 | return null; 24 | } 25 | } 26 | 27 | /** 28 | * Bean2Map 29 | * 30 | * @param obj 31 | * @return 32 | */ 33 | public static Map Bean2Map(Object obj) { 34 | if (obj == null) { 35 | return null; 36 | } 37 | Map map = new LinkedHashMap<>(); 38 | Field[] fields = obj.getClass().getDeclaredFields(); 39 | for (int i = 0; i < fields.length; i++) { 40 | map.put(fields[i].getName(), getFieldValueByName(fields[i].getName(), obj)); 41 | } 42 | return map; 43 | } 44 | 45 | public static void writeBytes(Object vo, ByteBuffer bf) { 46 | Map params = null; 47 | if (vo instanceof Map) { 48 | params = (Map) vo; 49 | } else { 50 | params = Bean2Map(vo); 51 | } 52 | Map objMap = new LinkedHashMap<>(); 53 | for (String key : params.keySet()) { 54 | Object obj = params.get(key); 55 | if (obj instanceof BaseVo || obj instanceof List || obj instanceof Map) { 56 | if ("authorization".equals(key)) { 57 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 58 | for (Object ob : (List) obj) { 59 | writeBytes(ob, bf); 60 | } 61 | } else if ("data".equals(key)) { 62 | ByteBuffer databf = new ByteBuffer(); 63 | writeBytes(obj, databf); 64 | bf.concat(ByteUtils.writerVarint32(String.valueOf(databf.getBuffer().length))); 65 | bf.concat(databf.getBuffer()); 66 | } else if ("transaction_extensions".equals(key)) { 67 | 68 | } else { 69 | objMap.put(key, obj); 70 | } 71 | } else { 72 | if ("chain_id".equals(key)) { 73 | bf.concat(Hex.hexStringToBytes(obj.toString())); 74 | } else if ("expiration".equals(key)) { 75 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 76 | } else if ("ref_block_num".equals(key)) { 77 | bf.concat(ByteUtils.writerUnit16(obj.toString())); 78 | } else if ("ref_block_prefix".equals(key)) { 79 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 80 | } else if ("net_usage_words".equals(key)) { 81 | bf.concat(ByteUtils.writerVarint32(obj.toString())); 82 | } else if ("max_cpu_usage_ms".equals(key)) { 83 | bf.concat(ByteUtils.writerUnit8(obj.toString())); 84 | } else if ("delay_sec".equals(key)) { 85 | bf.concat(ByteUtils.writerVarint32(obj.toString())); 86 | } else if ("account".equals(key)) { 87 | bf.concat(ByteUtils.writeName(obj.toString())); 88 | } else if ("name".equals(key)) { 89 | bf.concat(ByteUtils.writeName(obj.toString())); 90 | } else if ("actor".equals(key)) { 91 | bf.concat(ByteUtils.writeName(obj.toString())); 92 | } else if ("permission".equals(key)) { 93 | bf.concat(ByteUtils.writeName(obj.toString())); 94 | } else if ("from".equals(key)) { 95 | bf.concat(ByteUtils.writeName(obj.toString())); 96 | } else if ("to".equals(key)) { 97 | bf.concat(ByteUtils.writeName(obj.toString())); 98 | } else if ("quantity".equals(key)) { 99 | bf.concat(ByteUtils.writerAsset(obj.toString())); 100 | } else if ("memo".equals(key)) { 101 | bf.concat(ByteUtils.writerString(obj.toString())); 102 | } else if ("creator".equals(key)) { 103 | bf.concat(ByteUtils.writeName(obj.toString())); 104 | } else if ("owner".equals(key)) { 105 | bf.concat(ByteUtils.writerKey(obj.toString())); 106 | } else if ("active".equals(key)) { 107 | bf.concat(ByteUtils.writerKey(obj.toString())); 108 | } else if ("payer".equals(key)) { 109 | bf.concat(ByteUtils.writeName(obj.toString())); 110 | } else if ("receiver".equals(key)) { 111 | bf.concat(ByteUtils.writeName(obj.toString())); 112 | } else if ("bytes".equals(key)) { 113 | bf.concat(ByteUtils.writerUnit32(obj.toString())); 114 | } else if ("stake_net_quantity".equals(key)) { 115 | bf.concat(ByteUtils.writerAsset(obj.toString())); 116 | } else if ("stake_cpu_quantity".equals(key)) { 117 | bf.concat(ByteUtils.writerAsset(obj.toString())); 118 | } else if ("transfer".equals(key)) { 119 | bf.concat(ByteUtils.writerUnit8(obj.toString())); 120 | }else if ("voter".equals(key)) { 121 | bf.concat(ByteUtils.writeName(obj.toString())); 122 | }else if ("proxy".equals(key)) { 123 | bf.concat(ByteUtils.writeName(obj.toString())); 124 | }else if ("producer".equals(key)) { 125 | bf.concat(ByteUtils.writeName(obj.toString())); 126 | }else if ("close-owner".equals(key)) { 127 | bf.concat(ByteUtils.writeName(obj.toString())); 128 | }else if ("close-symbol".equals(key)) { 129 | bf.concat(ByteUtils.writerSymbol(obj.toString())); 130 | } 131 | } 132 | } 133 | for (String key : objMap.keySet()) { 134 | Object obj = params.get(key); 135 | if ("context_free_actions".equals(key)) { 136 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 137 | for (Object ob : (List) obj) { 138 | writeBytes(ob, bf); 139 | } 140 | } else if ("actions".equals(key)) { 141 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 142 | for (Object ob : (List) obj) { 143 | writeBytes(ob, bf); 144 | } 145 | }else if ("producers".equals(key)) { 146 | bf.concat(ByteUtils.writerVarint32(String.valueOf(((List) obj).size()))); 147 | for (Object ob : (List) obj) { 148 | Map mp = new HashMap<>(); 149 | mp.put("producer", ob); 150 | writeBytes(mp, bf); 151 | } 152 | }else { 153 | writeBytes(obj, bf); 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/party/loveit/eosforandroidlibrary/utils/Ripemd160.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 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/party/loveit/eosforandroidlibrary/utils/Sha.java: -------------------------------------------------------------------------------- 1 | package party.loveit.eosforandroidlibrary.utils; 2 | 3 | import java.security.InvalidKeyException; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | 7 | import javax.crypto.Mac; 8 | import javax.crypto.spec.SecretKeySpec; 9 | 10 | /** 11 | * SHA 12 | * 13 | * @author espritblock http://eblock.io 14 | * 15 | */ 16 | public class Sha { 17 | 18 | public static final String SHA256 = "SHA-256"; 19 | 20 | /** 21 | * sha256 22 | * 23 | * @param text 24 | * @return 25 | */ 26 | public static byte[] SHA256(final String text) { 27 | if (text == null || text.length() == 0) { 28 | throw new EException("args_empty", "args is empty"); 29 | } 30 | try { 31 | MessageDigest messageDigest = MessageDigest.getInstance(SHA256); 32 | messageDigest.update(text.getBytes("utf8")); 33 | byte byteBuffer[] = messageDigest.digest(); 34 | return byteBuffer; 35 | } catch (NoSuchAlgorithmException e) { 36 | e.printStackTrace(); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | return null; 41 | } 42 | 43 | /** 44 | * sha256 45 | * 46 | * @param 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 | --------------------------------------------------------------------------------