From db82a8244ac52c9fdacfabbea6080523fa440867 Mon Sep 17 00:00:00 2001 From: imuge Date: Tue, 21 Jul 2020 18:11:10 +0800 Subject: [PATCH] event sample and doc --- .../src/main/resources/docs/api_doc_cn_1.4.MD | 358 +++++++++++++++++++++ .../src/main/resources/docs/code_example.MD | 357 ++++++++++++++++++++ .../jd/blockchain/sdk/samples/SDK_Event_Demo.java | 105 ++++++ 3 files changed, 820 insertions(+) create mode 100644 deploy/deploy-gateway/src/main/resources/docs/code_example.MD create mode 100644 samples/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Event_Demo.java diff --git a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD b/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD index 017b97d2..c7185bcc 100644 --- a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD +++ b/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD @@ -2132,3 +2132,361 @@ http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts |address.value|合约地址| |pubKey.value|合约公钥| |rootHash|合约根Hash| + +## 9 用户自定义事件 + +### 9.1 获取事件账户列表 + +```http +GET /ledgers/{ledger}/events/user/accounts?fromIndex={start_index}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|query|start_index|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts?fromIndex=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data":[ + { + "address":{ + "value":"LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" + }, + "pubKey":{ + "value":"7VeRBi3xDfT1E11vFs9q5Q9gFo23RR7SoobPzivqxw9Uubzq" + } + } + ], + "success":true +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey.value|账户公钥| + +### 9.2 获取事件账户 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|address|账户地址|是|事件账户地址|字符串| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1 +``` + +#### 返回实例 + +```json +{ + "data":[ + { + "address":{ + "value":"LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" + }, + "pubKey":{ + "value":"7VeRBi3xDfT1E11vFs9q5Q9gFo23RR7SoobPzivqxw9Uubzq" + } + } + ], + "success":true +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey.value|账户公钥| + +### 9.3 获取事件账户总数 + +```http +GET /ledgers/{ledger}/events/user/accounts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件账户数量| + +### 9.4 获取事件名数量 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/count +``` + +#### 返回实例 + +```json +{ + "data": 2, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件名数量| + +### 9.5 获取事件名列表 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names?fromIndex={start_index}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|query|start_index|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names?fromIndex=0&count=100 +``` + +#### 返回实例 + +```json +{ + "data": ["test1", "test2"], + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件名数量数组| + +### 9.6 获取最新事件 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/latest +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1/latest +``` + +#### 返回实例 + +```json +{ + "data": { + "sequence": 0, + "transactionSource": { + "value": "j5rENX3rsdEgi5toeNUUv7ycUUivjNxAUb9Fme6oLCU851" + }, + "blockHeight": 10, + "contractSource": "", + "eventAccount": { + "value": "LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" + }, + "name": "test1", + "content": { + "nil": false, + "bytes": { + "value": "Ctt6Eur" + }, + "type": "TEXT", + "value": "imuge" + } + }, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|sequence|事件序列| +|transactionSource.value|交易哈希| +|blockHeight|时间产生区块高度| +|contractSource|合约地址| +|eventAccount.value|事件账户地址| +|name|事件名| +|content.nil|事件内容是否为空| +|content.bytes.value|事件内容字节| +|content.type|事件内容类型| +|content.value|事件内容| + +### 9.7 获取事件数量 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件数量| + +### 9.8 获取事件列表 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}?fromSequence={from_sequence}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| +|query|from_sequence|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1?fromSequenct=0&count=100 +``` + +#### 返回实例 + +```json +{ + "data": [{ + "sequence": 0, + "transactionSource": { + "value": "j5rENX3rsdEgi5toeNUUv7ycUUivjNxAUb9Fme6oLCU851" + }, + "blockHeight": 10, + "contractSource": "", + "eventAccount": { + "value": "LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" + }, + "name": "test1", + "content": { + "nil": false, + "bytes": { + "value": "Ctt6Eur" + }, + "type": "TEXT", + "value": "imuge" + } + }], + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件列表| +|sequence|事件序列| +|transactionSource.value|交易哈希| +|blockHeight|时间产生区块高度| +|contractSource|合约地址| +|eventAccount.value|事件账户地址| +|name|事件名| +|content.nil|事件内容是否为空| +|content.bytes.value|事件内容字节| +|content.type|事件内容类型| +|content.value|事件内容| \ No newline at end of file diff --git a/deploy/deploy-gateway/src/main/resources/docs/code_example.MD b/deploy/deploy-gateway/src/main/resources/docs/code_example.MD new file mode 100644 index 00000000..49157dc4 --- /dev/null +++ b/deploy/deploy-gateway/src/main/resources/docs/code_example.MD @@ -0,0 +1,357 @@ +# 1. maven坐标 +```java + + com.jd.blockchain + sdk-client + ${ledger.version} + + + com.jd.blockchain + contract-starter + ${ledger.version} + + + com.jd.blockchain + crypto-classic + ${ledger.version} + + + + com.jd.blockchain + crypto-sm + ${ledger.version} + +``` +# 2. 数据快速上链 +## 2.1. 服务连接 + +```java + //创建服务代理 + public BlockchainKeypair CLIENT_CERT = BlockchainKeyGenerator.getInstance().generate(); + final String GATEWAY_IP = "127.0.0.1"; + final int GATEWAY_PORT = 80; + final boolean SECURE = false; + GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IP, GATEWAY_PORT, SECURE, + CLIENT_CERT); + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + HashDigest[] ledgerHashs = service.getLedgerHashs(); + // 获取当前账本Hash + HashDigest ledgerHash = ledgerHashs[0]; +``` +## 2.2. 用户注册 +```java + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + // 在本地定义注册账号的 TX; + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); + + txTemp.users().register(user.getIdentity()); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + // 提交交易; + prepTx.commit(); +``` +## 2.3. 数据账户注册 +```java + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + // 在本地定义注册账号的 TX; + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); + + txTemp.dataAccounts().register(dataAccount.getIdentity()); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + + // 提交交易; + prepTx.commit(); +``` +## 2.4. 写入数据 +```java + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + + // 在本地定义注册账号的 TX; + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + + // -------------------------------------- + // 将商品信息写入到指定的账户中; + // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; + String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; + txTemp.dataAccount(commodityDataAccount).setText("ASSET_CODE", "value1", -1); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + + String txHash = Base64Utils.encodeToUrlSafeString(prepTx.getHash().toBytes()); + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + + // 提交交易; + prepTx.commit(); +``` +## 2.5. 查询数据 + +> 注:详细的查询可参考模块sdk-samples中SDK_GateWay_Query_Test_相关测试用例 + +```java + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + + // 查询区块信息; + // 区块高度; + long ledgerNumber = service.getLedger(ledgerHash).getLatestBlockHeight(); + // 最新区块; + LedgerBlock latestBlock = service.getBlock(ledgerHash, ledgerNumber); + // 区块中的交易的数量; + long txCount = service.getTransactionCount(ledgerHash, latestBlock.getHash()); + // 获取交易列表; + LedgerTransaction[] txList = service.getTransactions(ledgerHash, ledgerNumber, 0, 100); + // 遍历交易列表 + for (LedgerTransaction ledgerTransaction : txList) { + TransactionContent txContent = ledgerTransaction.getTransactionContent(); + Operation[] operations = txContent.getOperations(); + if (operations != null && operations.length > 0) { + for (Operation operation : operations) { + operation = ClientResolveUtil.read(operation); + // 操作类型:数据账户注册操作 + if (operation instanceof DataAccountRegisterOperation) { + DataAccountRegisterOperation daro = (DataAccountRegisterOperation) operation; + BlockchainIdentity blockchainIdentity = daro.getAccountID(); + } + // 操作类型:用户注册操作 + else if (operation instanceof UserRegisterOperation) { + UserRegisterOperation uro = (UserRegisterOperation) operation; + BlockchainIdentity blockchainIdentity = uro.getUserID(); + } + // 操作类型:账本注册操作 + else if (operation instanceof LedgerInitOperation) { + + LedgerInitOperation ledgerInitOperation = (LedgerInitOperation)operation; + LedgerInitSetting ledgerInitSetting = ledgerInitOperation.getInitSetting(); + + ParticipantNode[] participantNodes = ledgerInitSetting.getConsensusParticipants(); + } + // 操作类型:合约发布操作 + else if (operation instanceof ContractCodeDeployOperation) { + ContractCodeDeployOperation ccdo = (ContractCodeDeployOperation) operation; + BlockchainIdentity blockchainIdentity = ccdo.getContractID(); + } + // 操作类型:合约执行操作 + else if (operation instanceof ContractEventSendOperation) { + ContractEventSendOperation ceso = (ContractEventSendOperation) operation; + } + // 操作类型:KV存储操作 + else if (operation instanceof DataAccountKVSetOperation) { + DataAccountKVSetOperation.KVWriteEntry[] kvWriteEntries = + ((DataAccountKVSetOperation) operation).getWriteSet(); + if (kvWriteEntries != null && kvWriteEntries.length > 0) { + for (DataAccountKVSetOperation.KVWriteEntry kvWriteEntry : kvWriteEntries) { + BytesValue bytesValue = kvWriteEntry.getValue(); + DataType dataType = bytesValue.getType(); + Object showVal = ClientResolveUtil.readValueByBytesValue(bytesValue); + System.out.println("writeSet.key=" + kvWriteEntry.getKey()); + System.out.println("writeSet.value=" + showVal); + System.out.println("writeSet.type=" + dataType); + System.out.println("writeSet.version=" + kvWriteEntry.getExpectedVersion()); + } + } + } + } + } + } + + // 根据交易的 hash 获得交易;注:客户端生成 PrepareTransaction 时得到交易hash; + HashDigest txHash = txList[0].getTransactionContent().getHash(); + Transaction tx = service.getTransactionByContentHash(ledgerHash, txHash); + // 获取数据; + String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; + String[] objKeys = new String[] { "x001", "x002" }; + TypedKVEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, objKeys); + + long payloadVersion = kvData[0].getVersion(); + + // 获取数据账户下所有的KV列表 + TypedKVEntry[] kvDatas = service.getDataEntries(ledgerHash, commerceAccount, 0, 100); + if (kvData != null && kvData.length > 0) { + for (TypedKVEntry kvDatum : kvDatas) { + System.out.println("kvData.key=" + kvDatum.getKey()); + System.out.println("kvData.version=" + kvDatum.getVersion()); + System.out.println("kvData.type=" + kvDatum.getType()); + System.out.println("kvData.value=" + kvDatum.getValue()); + } + } +``` + +## 2.6. 合约发布 + +```java + + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + + // 在本地定义TX模板 + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + + // 合约内容读取 + byte[] contractBytes = FileUtils.readBytes(new File("CONTRACT_FILE")); + + // 生成用户 + BlockchainKeypair contractKeyPair = BlockchainKeyGenerator.getInstance().generate(); + + // 发布合约 + txTemp.contracts().deploy(contractKeyPair.getIdentity(), contractBytes); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + + // 提交交易; + TransactionResponse transactionResponse = prepTx.commit(); + + assertTrue(transactionResponse.isSuccess()); + + // 打印合约地址 + System.out.println(contractKeyPair.getIdentity().getAddress().toBase58()); +``` + +## 2.7. 合约执行 + +```java + + // 创建服务代理; + BlockchainService service = serviceFactory.getBlockchainService(); + + // 在本地定义TX模板 + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + + // 合约地址 + String contractAddress = ""; + + // 使用接口方式调用合约 + TransferContract transferContract = txTemp.contract(contractAddress, TransferContract.class); + + // 使用decode方式调用合约内部方法(create方法) + // 返回GenericValueHolder可通过get方法获取结果,但get方法需要在commit调用后执行 + String address = "address"; + String account = "fill account"; + long money = 100000000L; + GenericValueHolder result = ContractReturnValue.decode(transferContract.create(address, account, money)); + + PreparedTransaction ptx = txTemp.prepare(); + + ptx.sign(CLIENT_CERT); + + TransactionResponse transactionResponse = ptx.commit(); + + String cotractExecResult = result.get(); + + // TransactionResponse也提供了可供查询结果的接口 + OperationResult[] operationResults = transactionResponse.getOperationResults(); + + // 通过OperationResult获取结果 + for (int i = 0; i < operationResults.length; i++) { + OperationResult opResult = operationResults[i]; + System.out.printf("Operation[%s].result = %s \r\n", + opResult.getIndex(), BytesValueEncoding.decode(opResult.getResult())); + } +``` + +## 2.8. 事件账户注册 +```java + BlockchainService service = serviceFactory.getBlockchainService(); + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + + BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate(); + txTemp.eventAccounts().register(eventAccount.getIdentity()); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + + // 提交交易; + prepTx.commit(); +``` +## 2.9. 事件发布 +```java + BlockchainService service = serviceFactory.getBlockchainService(); + TransactionTemplate txTemp = service.newTransaction(ledgerHash); + + // 发布事件到指定的账户中; + String eventAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; + txTemp.eventAccount(eventAccount).publish("event_name", "string", -1) + .publish("event_name", 0, 0) + .publish("event_name", "bytes".getBytes(), 1); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + + // 使用私钥进行签名; + prepTx.sign(CLIENT_CERT); + + // 提交交易; + prepTx.commit(); +``` + +## 2.10. 事件监听 + +- 系统事件 +> 目前仅支持新区块产生事件 +```java + EventListenerHandle handler = blockchainService.monitorUserEvent(ledgerHash, eventAccount.getAddress().toBase58(), eventName, 0, new UserEventListener() { + @Override + public void onEvent(Event eventMessage, EventContext eventContext) { + BytesValue content = eventMessage.getContent(); + switch (content.getType()) { + case TEXT: + case XML: + case JSON: + System.out.println(content.getBytes().toUTF8String()); + break; + case INT64: + case TIMESTAMP: + System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); + break; + default: + break; + } + + // 关闭监听的两种方式:1 + eventContext.getHandle().cancel(); + } + }); + + // 关闭监听的两种方式:2 + handler.cancel(); +``` + +- 用户自定义事件 +```java + EventListenerHandle handler = blockchainService.monitorSystemEvent(ledgerHash, SystemEvent.NEW_BLOCK_CREATED, 0, new SystemEventListener() { + @Override + public void onEvents(Event[] eventMessages, EventContext eventContext) { + for (Event eventMessage : eventMessages) { + BytesValue content = eventMessage.getContent(); + // content中存放的是当前链上最新高度 + System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); + } + + // 关闭监听的两种方式:1 + eventContext.getHandle().cancel(); + } + }); + + // 关闭监听的两种方式:2 + handler.cancel(); +``` \ No newline at end of file diff --git a/samples/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Event_Demo.java b/samples/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Event_Demo.java new file mode 100644 index 00000000..f4d85dbe --- /dev/null +++ b/samples/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Event_Demo.java @@ -0,0 +1,105 @@ +package com.jd.blockchain.sdk.samples; + +import com.jd.blockchain.ledger.BlockchainKeyGenerator; +import com.jd.blockchain.ledger.BlockchainKeypair; +import com.jd.blockchain.ledger.BytesValue; +import com.jd.blockchain.ledger.Event; +import com.jd.blockchain.ledger.SystemEvent; +import com.jd.blockchain.ledger.TransactionTemplate; +import com.jd.blockchain.sdk.EventContext; +import com.jd.blockchain.sdk.EventListenerHandle; +import com.jd.blockchain.sdk.SystemEventListener; +import com.jd.blockchain.sdk.SystemEventPoint; +import com.jd.blockchain.sdk.UserEventListener; +import com.jd.blockchain.sdk.UserEventPoint; +import com.jd.blockchain.utils.io.BytesUtils; + +public class SDK_Event_Demo extends SDK_Base_Demo { + + // 注册事件账户 + private BlockchainKeypair createEventAccount() { + BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate(); + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + txTpl.eventAccounts().register(eventAccount.getIdentity()); + commit(txTpl); + return eventAccount; + } + + /** + * 发布事件 + * + * @param eventAccount 事件账户 + */ + private void publishEvent(BlockchainKeypair eventAccount) { + TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); + // sequence传递当前事件名链上最新序号,不存在时传-1 + Event event = blockchainService.getLatestEvent(ledgerHash, eventAccount.getAddress().toBase58(), "name"); + long sequence = null != event ? event.getSequence() : -1; + txTpl.eventAccount(eventAccount.getAddress()).publish("name", "bytes".getBytes(), sequence); + txTpl.eventAccount(eventAccount.getAddress()).publish("name", "string", sequence + 1); + txTpl.eventAccount(eventAccount.getAddress()).publish("name", 0, sequence + 2); + txTpl.eventAccount(eventAccount.getAddress()).publish("name", 1l, sequence + 3); + txTpl.eventAccount(eventAccount.getAddress()).publishXML("name", "", sequence + 4); + txTpl.eventAccount(eventAccount.getAddress()).publishJSON("name", "{}", sequence + 5); + txTpl.eventAccount(eventAccount.getAddress()).publishImage("name", "img".getBytes(), sequence + 6); + txTpl.eventAccount(eventAccount.getAddress()).publishTimestamp("name", System.currentTimeMillis(), sequence + 7); + commit(txTpl); + } + + /** + * 监听用户自定义事件 + * + * @param eventAccount 事件账户 + * @param eventName 事件名 + */ + private void monitorUserEvent(BlockchainKeypair eventAccount, String eventName) { + EventListenerHandle handler = blockchainService.monitorUserEvent(ledgerHash, eventAccount.getAddress().toBase58(), eventName, 0, new UserEventListener() { + @Override + public void onEvent(Event eventMessage, EventContext eventContext) { + BytesValue content = eventMessage.getContent(); + switch (content.getType()) { + case TEXT: + case XML: + case JSON: + System.out.println(content.getBytes().toUTF8String()); + break; + case INT64: + case TIMESTAMP: + System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); + break; + default: + break; + } + + // 关闭监听的两种方式:1 + eventContext.getHandle().cancel(); + } + }); + + // 关闭监听的两种方式:2 + handler.cancel(); + } + + /** + * 监听新区块生成事件 + */ + private void monitorNewBlockCreatedEvent() { + EventListenerHandle handler = blockchainService.monitorSystemEvent(ledgerHash, SystemEvent.NEW_BLOCK_CREATED, 0, new SystemEventListener() { + @Override + public void onEvents(Event[] eventMessages, EventContext eventContext) { + for (Event eventMessage : eventMessages) { + BytesValue content = eventMessage.getContent(); + // content中存放的是当前链上最新高度 + System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); + } + + // 关闭监听的两种方式:1 + eventContext.getHandle().cancel(); + } + }); + + // 关闭监听的两种方式:2 + handler.cancel(); + } + +}