You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

sdk.md 10 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. ## SDK
  2. `JD Chain`提供了`Java`和`Go`版本的`SDK`,此处以`Java`为例,`Go`版本参照[framework-go](https://github.com/blockchain-jd-com/framework-go)
  3. `SDK`可执行示例代码参照[JD Chain Samples](https://github.com/blockchain-jd-com/jdchain/tree/master/samples)
  4. ### 1. 连接网关
  5. 通过`GatewayServiceFactory`中静态方法连接网关:
  6. ```java
  7. static GatewayServiceFactory connect(NetworkAddress gatewayAddress)
  8. static GatewayServiceFactory connect(NetworkAddress gatewayAddress, BlockchainKeypair userKey)
  9. static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure)
  10. static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure, BlockchainKeypair userKey)
  11. ```
  12. 其中`BlockchainKeypair userKey`参数用于自动签署终端用户签名,可不传,不传`userKey`时需要在提交交易前调用签名操作,添加终端账户签名信息。
  13. 通过:
  14. ```java
  15. BlockchainService blockchainService = GatewayServiceFactory.connect(gatewayHost, gatewayPort, false).getBlockchainService();
  16. ```
  17. 创建区块连服务,常规情况`BlockchainService`**单例**即可。
  18. ### 2. 调用过程
  19. #### 2.1 操作
  20. 1. 新建交易:
  21. ```java
  22. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  23. ```
  24. 2. 操作:
  25. ```java
  26. BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
  27. // 注册用户
  28. txTemp.users().register(user.getIdentity());
  29. ```
  30. > 一笔交易中可以包含多个操作,所有操作类型参照[交易](transaction.md)文档。
  31. 3. 准备交易
  32. ```java
  33. PreparedTransaction ptx = txTemp.prepare();
  34. ```
  35. 4. 终端用户签名
  36. ```java
  37. ptx.sign(userKey);
  38. ```
  39. > 若[连接网关](#1-连接网关)中传入了用户身份信息,且用户身份具备交易中包含的所有操作[权限](user.md),此处签名操作可省略。
  40. 5. 提交交易
  41. ```java
  42. TransactionResponse response = ptx.commit();
  43. ```
  44. #### 2.2 查询
  45. `BlockchainService`中包含了所有链上数据的查询方法,直接使用即可:
  46. ```java
  47. LedgerInfo ledgerInfo = blockchainService.getLedger(ledger);
  48. ```
  49. ### 3. 操作类型
  50. 按功能模块划分:`用户操作`,`数据账户操作`,`事件操作`,`合约操作`,`查询`。
  51. #### 3.1 用户操作
  52. 用户/角色/权限相关说明参照[用户](user.md)文档说明。
  53. 1. 注册用户
  54. ```java
  55. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  56. // 生成用户
  57. BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
  58. System.out.println("用户地址:" + user.getAddress());
  59. // 注册用户
  60. txTemp.users().register(user.getIdentity());
  61. PreparedTransaction ptx = txTemp.prepare();
  62. ptx.sign(adminKey);
  63. TransactionResponse response = ptx.commit();
  64. ```
  65. 2. 角色赋权
  66. ```java
  67. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  68. // 创建角色 MANAGER ,并设置可以写数据账户,能执行交易
  69. txTemp.security().roles().configure("MANAGER")
  70. .enable(LedgerPermission.WRITE_DATA_ACCOUNT)
  71. .enable(TransactionPermission.DIRECT_OPERATION);
  72. PreparedTransaction ptx = txTemp.prepare();
  73. ptx.sign(adminKey);
  74. TransactionResponse response = ptx.commit();
  75. ```
  76. 3. 用户赋权
  77. ```java
  78. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  79. // 赋予用户 user MANAGER 角色,取消 ADMIN 角色,设置多角色策略策略为合并策略
  80. txTemp.security().authorziations().forUser(user.getAddress()).authorize("MANAGER").unauthorize("ADMIN").setPolicy(RolesPolicy.UNION);
  81. PreparedTransaction ptx = txTemp.prepare();
  82. ptx.sign(adminKey);
  83. TransactionResponse response = ptx.commit();
  84. ```
  85. #### 3.2 数据账户操作
  86. 1. 创建数据账户
  87. ```java
  88. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  89. // 生成数据账户
  90. BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate();
  91. System.out.println("数据账户地址:" + dataAccount.getAddress());
  92. // 注册数据账户
  93. txTemp.dataAccounts().register(dataAccount.getIdentity());
  94. PreparedTransaction ptx = txTemp.prepare();
  95. ptx.sign(adminKey);
  96. TransactionResponse response = ptx.commit();
  97. ```
  98. 2. 写KV
  99. ```java
  100. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  101. // expVersion是针对此key的插入更新操作次数严格递增,初始为-1
  102. txTemp.dataAccount(Bytes.fromBase58("LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn")).setInt64("key2", 1024, -1);
  103. PreparedTransaction ptx = txTemp.prepare();
  104. ptx.sign(adminKey);
  105. TransactionResponse response = ptx.commit();
  106. ```
  107. #### 3.3 事件操作
  108. 1. 创建事件账户
  109. ```java
  110. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  111. // 生成事件账户
  112. BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate();
  113. System.out.println("事件账户地址:" + eventAccount.getAddress());
  114. // 注册事件账户
  115. txTemp.eventAccounts().register(eventAccount.getIdentity());
  116. PreparedTransaction ptx = txTemp.prepare();
  117. ptx.sign(adminKey);
  118. TransactionResponse response = ptx.commit();
  119. ```
  120. 2. 发布事件
  121. ```java
  122. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  123. // sequence是针对此消息name的序列严格递增,初始为-1,可通过查询事件名下最新事件获取序列参数
  124. txTemp.eventAccount(Bytes.fromBase58("LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA")).publish("topic", "content", -1);
  125. PreparedTransaction ptx = txTemp.prepare();
  126. ptx.sign(adminKey);
  127. TransactionResponse response = ptx.commit();
  128. ```
  129. 3. 监听事件
  130. ```java
  131. // 监听系统事件,目前仅有新区快产生事件
  132. blockchainService.monitorSystemEvent(ledger,
  133. SystemEvent.NEW_BLOCK_CREATED, 0, (eventMessages, eventContext) -> {
  134. for (Event eventMessage : eventMessages) {
  135. // content中存放的是当前链上最新高度
  136. System.out.println("New block:" + eventMessage.getSequence() + ":" + BytesUtils.toLong(eventMessage.getContent().getBytes().toBytes()));
  137. }
  138. });
  139. // 监听用户自定义事件
  140. blockchainService.monitorUserEvent(ledger, "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "sample-event", 0, (eventMessage, eventContext) -> {
  141. BytesValue content = eventMessage.getContent();
  142. switch (content.getType()) {
  143. case TEXT:
  144. case XML:
  145. case JSON:
  146. System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + content.getBytes().toUTF8String());
  147. break;
  148. case INT64:
  149. case TIMESTAMP:
  150. System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + BytesUtils.toLong(content.getBytes().toBytes()));
  151. break;
  152. default: // byte[], Bytes
  153. System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + content.getBytes().toBase58());
  154. break;
  155. }
  156. });
  157. ```
  158. #### 3.4 合约操作
  159. 1. 部署合约
  160. ```java
  161. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  162. // 生成合约账户
  163. BlockchainKeypair contractAccount = BlockchainKeyGenerator.getInstance().generate();
  164. System.out.println("合约地址:" + contractAccount.getAddress());
  165. // 部署合约
  166. txTemp.contracts().deploy(contractAccount.getIdentity(), FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car"));
  167. PreparedTransaction ptx = txTemp.prepare();
  168. ptx.sign(adminKey);
  169. TransactionResponse response = ptx.commit();
  170. ```
  171. 2. 升级合约
  172. ```java
  173. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  174. // 解析已存在的合约身份信息
  175. BlockchainIdentity contractIdentity = new BlockchainIdentityData(KeyGenUtils.decodePubKey("7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht"));
  176. System.out.println("合约地址:" + contractIdentity.getAddress());
  177. // 部署合约
  178. txTemp.contracts().deploy(contractIdentity, FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car"));
  179. PreparedTransaction ptx = txTemp.prepare();
  180. ptx.sign(adminKey);
  181. TransactionResponse response = ptx.commit();
  182. ```
  183. 3. 调用合约
  184. 基于动态代理方式合约调用,需要依赖合约接口:
  185. ```java
  186. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  187. // 一次交易中可调用多个(多次调用)合约方法
  188. // 调用合约的 registerUser 方法
  189. SampleContract sampleContract = txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", SampleContract.class);
  190. GenericValueHolder<String> userAddress = ContractReturnValue.decode(sampleContract.registerUser(UUID.randomUUID().toString()));
  191. PreparedTransaction ptx = txTemp.prepare();
  192. ptx.sign(adminKey);
  193. TransactionResponse response = ptx.commit();
  194. Assert.assertTrue(response.isSuccess());
  195. // 获取返回值
  196. System.out.println(userAddress.get());
  197. ```
  198. 非动态代理方式合约调用,不需要依赖合约接口及实现:
  199. ```java
  200. TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
  201. ContractEventSendOperationBuilder builder = txTemp.contract();
  202. // 一次交易中可调用多个(多次调用)合约方法
  203. // 调用合约的 registerUser 方法,传入合约地址,合约方法名,合约方法参数列表
  204. builder.send("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "registerUser",
  205. new BytesDataList(new TypedValue[]{
  206. TypedValue.fromText(UUID.randomUUID().toString())
  207. })
  208. );
  209. PreparedTransaction ptx = txTemp.prepare();
  210. ptx.sign(adminKey);
  211. TransactionResponse response = ptx.commit();
  212. Assert.assertTrue(response.isSuccess());
  213. // 解析合约方法调用返回值
  214. for (int i = 0; i < response.getOperationResults().length; i++) {
  215. BytesValue content = response.getOperationResults()[i].getResult();
  216. switch (content.getType()) {
  217. case TEXT:
  218. System.out.println(content.getBytes().toUTF8String());
  219. break;
  220. case INT64:
  221. System.out.println(BytesUtils.toLong(content.getBytes().toBytes()));
  222. break;
  223. case BOOLEAN:
  224. System.out.println(BytesUtils.toBoolean(content.getBytes().toBytes()[0]));
  225. break;
  226. default: // byte[], Bytes
  227. System.out.println(content.getBytes().toBase58());
  228. break;
  229. }
  230. }
  231. ```
  232. #### 3.5 查询
  233. 与[网关 API](api.md)所提供查询一致,参照[Query Samples](https://github.com/blockchain-jd-com/jdchain/blob/master/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java)