JD Chain提供了Java和Go版本的SDK,此处以Java为例,Go版本参照framework-go
SDK可执行示例代码参照JD Chain Samples
通过GatewayServiceFactory中静态方法连接网关:
static GatewayServiceFactory connect(NetworkAddress gatewayAddress)
static GatewayServiceFactory connect(NetworkAddress gatewayAddress, BlockchainKeypair userKey)
static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure)
static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure, BlockchainKeypair userKey)
其中BlockchainKeypair userKey参数用于自动签署终端用户签名,可不传,不传userKey时需要在提交交易前调用签名操作,添加终端账户签名信息。
通过:
BlockchainService blockchainService = GatewayServiceFactory.connect(gatewayHost, gatewayPort, false).getBlockchainService();
创建区块连服务,常规情况BlockchainService单例即可。
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
// 注册用户
txTemp.users().register(user.getIdentity());
一笔交易中可以包含多个操作,所有操作类型参照交易文档。
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(userKey);
TransactionResponse response = ptx.commit();
BlockchainService中包含了所有链上数据的查询方法,直接使用即可:
LedgerInfo ledgerInfo = blockchainService.getLedger(ledger);
按功能模块划分:用户操作,数据账户操作,事件操作,合约操作,查询。
用户/角色/权限相关说明参照用户文档说明。
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成用户
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
System.out.println("用户地址:" + user.getAddress());
// 注册用户
txTemp.users().register(user.getIdentity());
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 创建角色 MANAGER ,并设置可以写数据账户,能执行交易
txTemp.security().roles().configure("MANAGER")
.enable(LedgerPermission.WRITE_DATA_ACCOUNT)
.enable(TransactionPermission.DIRECT_OPERATION);
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 赋予用户 user MANAGER 角色,取消 ADMIN 角色,设置多角色策略策略为合并策略
txTemp.security().authorziations().forUser(user.getAddress()).authorize("MANAGER").unauthorize("ADMIN").setPolicy(RolesPolicy.UNION);
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成数据账户
BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("数据账户地址:" + dataAccount.getAddress());
// 注册数据账户
txTemp.dataAccounts().register(dataAccount.getIdentity());
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// expVersion是针对此key的插入更新操作次数严格递增,初始为-1
txTemp.dataAccount(Bytes.fromBase58("LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn")).setInt64("key2", 1024, -1);
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成事件账户
BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("事件账户地址:" + eventAccount.getAddress());
// 注册事件账户
txTemp.eventAccounts().register(eventAccount.getIdentity());
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// sequence是针对此消息name的序列严格递增,初始为-1,可通过查询事件名下最新事件获取序列参数
txTemp.eventAccount(Bytes.fromBase58("LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA")).publish("topic", "content", -1);
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
// 监听系统事件,目前仅有新区快产生事件
blockchainService.monitorSystemEvent(ledger,
SystemEvent.NEW_BLOCK_CREATED, 0, (eventMessages, eventContext) -> {
for (Event eventMessage : eventMessages) {
// content中存放的是当前链上最新高度
System.out.println("New block:" + eventMessage.getSequence() + ":" + BytesUtils.toLong(eventMessage.getContent().getBytes().toBytes()));
}
});
// 监听用户自定义事件
blockchainService.monitorUserEvent(ledger, "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "sample-event", 0, (eventMessage, eventContext) -> {
BytesValue content = eventMessage.getContent();
switch (content.getType()) {
case TEXT:
case XML:
case JSON:
System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + content.getBytes().toUTF8String());
break;
case INT64:
case TIMESTAMP:
System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + BytesUtils.toLong(content.getBytes().toBytes()));
break;
default: // byte[], Bytes
System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + content.getBytes().toBase58());
break;
}
});
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成合约账户
BlockchainKeypair contractAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("合约地址:" + contractAccount.getAddress());
// 部署合约
txTemp.contracts().deploy(contractAccount.getIdentity(), FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car"));
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 解析已存在的合约身份信息
BlockchainIdentity contractIdentity = new BlockchainIdentityData(KeyGenUtils.decodePubKey("7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht"));
System.out.println("合约地址:" + contractIdentity.getAddress());
// 部署合约
txTemp.contracts().deploy(contractIdentity, FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car"));
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
基于动态代理方式合约调用,需要依赖合约接口:
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 一次交易中可调用多个(多次调用)合约方法
// 调用合约的 registerUser 方法
SampleContract sampleContract = txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", SampleContract.class);
GenericValueHolder<String> userAddress = ContractReturnValue.decode(sampleContract.registerUser(UUID.randomUUID().toString()));
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
// 获取返回值
System.out.println(userAddress.get());
非动态代理方式合约调用,不需要依赖合约接口及实现:
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
ContractEventSendOperationBuilder builder = txTemp.contract();
// 一次交易中可调用多个(多次调用)合约方法
// 调用合约的 registerUser 方法,传入合约地址,合约方法名,合约方法参数列表
builder.send("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "registerUser",
new BytesDataList(new TypedValue[]{
TypedValue.fromText(UUID.randomUUID().toString())
})
);
PreparedTransaction ptx = txTemp.prepare();
ptx.sign(adminKey);
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
// 解析合约方法调用返回值
for (int i = 0; i < response.getOperationResults().length; i++) {
BytesValue content = response.getOperationResults()[i].getResult();
switch (content.getType()) {
case TEXT:
System.out.println(content.getBytes().toUTF8String());
break;
case INT64:
System.out.println(BytesUtils.toLong(content.getBytes().toBytes()));
break;
case BOOLEAN:
System.out.println(BytesUtils.toBoolean(content.getBytes().toBytes()[0]));
break;
default: // byte[], Bytes
System.out.println(content.getBytes().toBase58());
break;
}
}
与网关 API所提供查询一致,参照Query Samples