0 java库jeos
目前EOS方面比较成熟的开源Java SDK非常少,个人推荐一个比较好用的java库jeos,地址https://github.com/adyliu/jeos。在gradle中添加这个库:
compile group: 'io.jafka', name: 'jeos', version: '0.9.14'
1 jeos使用
最简单的用来访问EOS节点的代码:
public class TestEOS {
public static String url_wallet = "http://192.168.1.57:18888";
public static String url_chain = "http://192.168.1.57:8888";
public static EosApi client;
public static void main(String[] args) throws Exception{
BasicConfigurator.configure();
client = EosApiFactory.create(url_wallet, url_chain, url_chain);
ChainInfo info = client.getChainInfo();
System.out.println("chain info:"+info);
}
}
2 查询余额
static void getBalance(String token,String account){
List<String> ret = client.getCurrencyBalance(token,account,"SYS");
System.out.println("account balance:"+ret);
}
3 在线签名转账
配置keosd服务
使用在线转账功能需要先开启keosd钱包服务,keosd的目录在~/eosio-wallet,该文件夹下的config.ini中的http-server-address配置了keosd的服务端口。修改该端口为:
http-server-address = 0.0.0.0:18888
然后启动keosd服务:
~/eosio-wallet$ keosd
在线转账代码
static void transfer(String token,String from,String to,String money) throws Exception {
ObjectMapper mapper = EosApiServiceGenerator.getMapper();
// ① pack transfer data
TransferArg transferArg = new TransferArg(from, to, money, "我是中国人");
AbiJsonToBin data = client.abiJsonToBin(token, "transfer", transferArg);
System.out.println("bin= " + data.getBinargs());
// ② get the latest block info
Block block = client.getBlock(client.getChainInfo().getHeadBlockId());
System.out.println("blockNum=" + block.getBlockNum());
// ③ create the authorization
List<TransactionAuthorization> authorizations = Arrays.asList(new TransactionAuthorization(from, "active"));
// ④ build the all actions
List<TransactionAction> actions = Arrays.asList(//
new TransactionAction(token, "transfer", authorizations, data.getBinargs())//
);
// ⑤ build the packed transaction
PackedTransaction packedTransaction = new PackedTransaction();
packedTransaction.setRefBlockPrefix(block.getRefBlockPrefix());
packedTransaction.setRefBlockNum(block.getBlockNum());
// expired after 3 minutes
String expiration = ZonedDateTime.now(ZoneId.of("GMT")).plusMinutes(3).truncatedTo(ChronoUnit.SECONDS).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
packedTransaction.setExpiration(LocalDateTime.parse(expiration));
packedTransaction.setRegion("0");
packedTransaction.setMaxNetUsageWords(0);
packedTransaction.setMaxCpuUsageMs(0);
packedTransaction.setActions(actions);
// ⑥ unlock the creator's wallet
try {
client.unlockWallet("default", "PW5JECR3XedNovw8w8cPmYBe52eH51buki4rVVHUwunWFeJNco4Vd");
} catch (EosApiException ex) {
System.err.println(ex.getMessage());
}
// ⑦ sign the transaction
SignedPackedTransaction signedPackedTransaction = client.signTransaction(packedTransaction, //
Arrays.asList("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"), //
"38dc6e87bb9f6b33a21dd56b9f2c24813d83c71009077279c8d746fbd0eaf09d");
System.out.println("signedPackedTransaction=" + mapper.writeValueAsString(signedPackedTransaction));
System.out.println("\n--------------------------------\n");
// ⑧ push the signed transaction
PushedTransaction pushedTransaction = client.pushTransaction("none", signedPackedTransaction);
System.out.println("pushedTransaction=" + mapper.writeValueAsString(pushedTransaction));
}
调用方法:
transfer("eosio.token","acca","accb","100.0000 SYS");
3 查询交易
static void getTransaction(String id){//id是交易id
Object ret = client.getTransaction(new TransactionRequest(id));
System.out.print(ret);
}
4 查询区块
static void getBlock(String blockNumber){
Block block = client.getBlock(blockNumber);
System.out.print(block);
}
5 查询账户
static void getAccount(String accountName){
Account account = client.getAccount(accountName);
System.out.println(account);
}
6 查询交易记录
//查询account第index条action
static void getActions(String acount,int index){
Actions actions = client.getActions(acount,index,0);
System.out.print(actions);
}
cleos里面查询账户eosio.token交易记录的命令是:
~/eosjsPro$ cleos get actions eosio.token
# seq when contract::action => receiver trx id... args
================================================================================================================
# 0 2018-12-08T07:43:51.500 eosio::setcode => eosio 0b822752... {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"00...
# 1 2018-12-08T07:43:51.500 eosio::setabi => eosio 0b822752... {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e...
# 2 2018-12-08T07:47:04.500 eosio.token::create => eosio.token be62a688... {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"}...
# 3 2018-12-08T07:50:56.000 eosio.token::issue => eosio.token 7f758c76... {"to":"acca","quantity":"10000.0000 SYS","memo":"memo"}...
# 4 2018-12-08T07:50:56.000 eosio.token::transfer => eosio.token 7f758c76... {"from":"eosio","to":"acca","quantity":"10000.0000 SYS","mem...
# 5 2018-12-08T09:54:09.000 eosio.token::transfer => eosio.token b02a88ab... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 6 2018-12-08T09:54:43.500 eosio.token::transfer => eosio.token efedcbc8... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 7 2018-12-12T05:58:52.500 eosio.token::transfer => eosio.token 49edc3d6... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 8 2018-12-12T08:57:20.000 eosio.token::transfer => eosio.token feddbb36... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 9 2018-12-12T09:05:10.000 eosio.token::transfer => eosio.token 52fa5580... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 10 2018-12-12T09:06:08.500 eosio.token::transfer => eosio.token 6b5160ac... {"from":"acca","to":"accb","quantity":"100.0000 SYS","memo":...
# 11 2018-12-12T09:46:26.500 eosio::newaccount => eosio 2019cc1b... {"creator":"eosio.token","name":"accnew","owner":{"threshold...
# 12 2018-12-12T09:46:26.500 eosio::buyrambytes => eosio 2019cc1b... "00a6823403ea3055000000007035113200200000"...
# 13 2018-12-12T09:46:26.500 eosio::delegatebw => eosio 2019cc1b... "00a6823403ea30550000000070351132102700000000000004444556000...
而SDK中的查询action的方法是:
Actions getActions(String accountName, Integer pos, Integer offset);
pos是第几条记录,offset的意义是从pos位置起查询pos+1条记录。所以要查询第pos条记录,就将offset设置为0。
7 离线签名交易
离线签名交易使用账户私钥来离线签名交易,然后再将签名好的交易发布到eos链上。使用离线签名只需要用户的私钥,不需要在本地运行keosd钱包服务。
static void transferOffline() throws Exception{
// --- get the current state of blockchain
EosApi eosApi = EosApiFactory.create(url_chain);
SignArg arg = eosApi.getSignArg(120);
System.out.println(eosApi.getObjectMapper().writeValueAsString(arg));
// --- sign the transation of token tansfer
String privateKey = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3";//replace the real private key
String from1 = "acca";
String to1 = "accb";
String quantity = "100.0000 SYS";
String memo = "sent by eos sdk";
LocalApi localApi = EosApiFactory.createLocalApi();
PushTransactionRequest req = localApi.transfer(arg, privateKey, from1, to1, quantity, memo);
System.out.println(localApi.getObjectMapper().writeValueAsString(req));
// --- push the signed-transaction to the blockchain
PushedTransaction pts = eosApi.pushTransaction(req);
System.out.println(localApi.getObjectMapper().writeValueAsString(pts));
}
8 调用智能合约
假设在eos链上账户acchello发布了一个hello合约,合约中有一个hi方法:
void hi( account_name user ) {
print( "Hello, ", name{user} );
}
下面函数使用jeos来调用hello合约的hi方法:
static void callContract() throws Exception{
// --- get the current state of blockchain
EosApi eosApi = EosApiFactory.create(url_chain);
SignArg arg = eosApi.getSignArg(120);
System.out.println(eosApi.getObjectMapper().writeValueAsString(arg));
// --- sign the transation of token tansfer
String privateKey = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3";//replace the real private key
String from = "acchello";
LocalApi localApi = EosApiFactory.createLocalApi();
//PushTransactionRequest req = localApi.transfer(arg, privateKey, from1, to1, quantity, memo);
// ① pack transfer data
String name = "testname";
Raw raw = new Raw();
raw.packName(name);
String transferData = raw.toHex();
//
// ③ create the authorization
List<TransactionAuthorization> authorizations = Arrays.asList(new TransactionAuthorization(from, "active"));
// ④ build the all actions
List<TransactionAction> actions = Arrays.asList(//
new TransactionAction("acchello", "hi", authorizations, transferData)//
);
// ⑤ build the packed transaction
PackedTransaction packedTransaction = new PackedTransaction();
packedTransaction.setExpiration(arg.getHeadBlockTime().plusSeconds(arg.getExpiredSecond()));
packedTransaction.setRefBlockNum(arg.getLastIrreversibleBlockNum());
packedTransaction.setRefBlockPrefix(arg.getRefBlockPrefix());
packedTransaction.setMaxNetUsageWords(0);
packedTransaction.setMaxCpuUsageMs(0);
packedTransaction.setDelaySec(0);
packedTransaction.setActions(actions);
String hash = sign(privateKey, arg, packedTransaction);
PushTransactionRequest req = new PushTransactionRequest();
req.setTransaction(packedTransaction);
req.setSignatures(Arrays.asList(hash));
System.out.println(localApi.getObjectMapper().writeValueAsString(req));
// --- push the signed-transaction to the blockchain
PushedTransaction pts = eosApi.pushTransaction(req);
System.out.println(localApi.getObjectMapper().writeValueAsString(pts));
}