Browse Source

remove jdchain-samples

tags/1.6.1
liuyuanmu 2 years ago
parent
commit
e96f4b39cc
28 changed files with 0 additions and 3185 deletions
  1. +0
    -1
      pom.xml
  2. +0
    -60
      samples/README.md
  3. +0
    -81
      samples/contract-samples/pom.xml
  4. +0
    -132
      samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContract.java
  5. +0
    -233
      samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java
  6. +0
    -41
      samples/pom.xml
  7. +0
    -74
      samples/sdk-samples/pom.xml
  8. +0
    -299
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java
  9. +0
    -80
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/GatewayRunner.java
  10. +0
    -22
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/LedgerInit.java
  11. +0
    -99
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/NodeWebContext.java
  12. +0
    -59
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/PartNode.java
  13. +0
    -67
      samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/PeerServer.java
  14. +0
    -20
      samples/sdk-samples/src/main/resources/config.properties
  15. BIN
      samples/sdk-samples/src/main/resources/contract-samples-1.6.0.RELEASE.car
  16. +0
    -155
      samples/sdk-samples/src/main/resources/testnet/bftsmart.config
  17. +0
    -25
      samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-0.conf
  18. +0
    -25
      samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-1.conf
  19. +0
    -25
      samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-2.conf
  20. +0
    -25
      samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-3.conf
  21. +0
    -76
      samples/sdk-samples/src/main/resources/testnet/ledger.init
  22. +0
    -175
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java
  23. +0
    -98
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java
  24. +0
    -149
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java
  25. +0
    -133
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ParticipantSample.java
  26. +0
    -848
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java
  27. +0
    -63
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/SampleBase.java
  28. +0
    -120
      samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/UserSample.java

+ 0
- 1
pom.xml View File

@@ -15,7 +15,6 @@
<module>core</module>
<module>deploy</module>
<module>test</module>
<module>samples</module>
</modules>




+ 0
- 60
samples/README.md View File

@@ -1,60 +0,0 @@
## JD Chain Samples

本项目为`JD Chain SDK`的使用样例,开发者可以参考此项目快速上手`JD Chain SDK`,主要包括[交易发送查询](#交易发送查询),[合约开发部署](#合约开发部署)两部分。

本项目提供了基于内存的`JD Chain`四节点+网关的网络环境启动程序[TestNet](sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java),运行`TestNet`的`main`方法启动测试网络,等待日志输出:`START TESTNET SUCCESS`,网络启动成功会写入一些测试数据,可直接运行本项目提供的所有测试用例。

> `TestNet`测试网络默认会占用`8910`/`8920`/`8930`/`8940`/`8911`/`8921`/`8931`/`8941`用于共识服务,`12000`/`12010`/`12020`/`12030`用于四节点`API`服务端口,`11000`用于网关`API`服务端口,启动前请检查相关端口可用。



### 交易发送查询

相关代码放在[sdk-sample](sdk-samples/src)下。

> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[config.properties](sdk-samples/src/main/resources/config.properties)中的网关配置,用户配置等信息。

#### 交易发送

参照[UserSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/UserSample.java)实现注册用户,配置用户角色权限功能;

参照[DataAccountSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java)实现注册数据账户,存储`KV`数据功能;

参照[EventSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java)实现注册事件账户,发布事件,事件监听功能;

参照[ContractSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java)实现合约调用,非插件方式合约部署功能。

#### 数据查询

参照[QuerySample](sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java)实现对于区块链上数据查询功能。



### 合约开发部署

[contract-samples](contract-samples/src)提供了通过合约注册用户,注册数据账户,注册事件账户,设置`KV`,发布事件的简单合约样例。

> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[pom.xml](contract-samples/pom.xml)中的网关配置,用户配置等信息。

修改相关代码,确认配置正确,`contract-samples`项目目录下命令行执行:

- 合约打包
```bash
mvn clean package
```
可以生成`car`包,可以用于`SDK`方式合约部署。

- 合约部署
```bash
mvn clean deploy
```
可以直接部署合约上链。



### 了解更多

访问[JD Chain官网](http://ledger.jd.com/)查阅设计及文档。
访问[github主页](https://github.com/blockchain-jd-com)阅读`JD Chain`源码并参与社区建设。

Thanks~

+ 0
- 81
samples/contract-samples/pom.xml View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jd.blockchain</groupId>
<artifactId>jdchain-samples</artifactId>
<version>1.6.0.RELEASE</version>
</parent>

<!-- 声明为合约代码工程,编译输出扩展名为".car"合约代码 -->
<packaging>contract</packaging>
<artifactId>contract-samples</artifactId>
<name>contract-samples</name>

<dependencies>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>contract-starter</artifactId>
<version>${framework.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<optimize>false</optimize>
<debug>true</debug>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
</configuration>
</plugin>

<!-- 合约编译、打包、发布插件 -->
<plugin>
<groupId>com.jd.blockchain</groupId>
<artifactId>contract-maven-plugin</artifactId>
<version>${framework.version}</version>
<extensions>true</extensions>

<!-- 合约发布配置,不配置时请不要执行deploy阶段 -->
<configuration>
<!-- <maxCarSize>1</maxCarSize>-->
<!-- <maxCarSizeUnit>MB</maxCarSizeUnit>-->
<deployment>
<!-- 线上网关的配置,必选项 -->
<gateway>
<host>localhost</host>
<port>11000</port>
</gateway>

<!-- 账本,不填默认选择列表第一个 -->
<!-- <ledger>j5uXbSp6V9VCXxHQzp8pFGKoR9NrAkE6TUvfwWxvEVR5HK</ledger>-->

<!-- 更新已存在合约代码 -->
<!-- <contractAddress>-->
<!-- <pubKey></pubKey>-->
<!-- </contractAddress>-->

<!-- 用户信息,必选项,任何一个合约发布都需要拥有者进行签名 -->
<signer>
<pubKey>7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq</pubKey>
<privKey>177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x</privKey>
<privKeyPwd>DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY</privKeyPwd>
</signer>
</deployment>
</configuration>
</plugin>
</plugins>
</build>

</project>

+ 0
- 132
samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContract.java View File

@@ -1,132 +0,0 @@
package com.jdchain.samples.contract;

import com.jd.blockchain.contract.Contract;
import com.jd.blockchain.contract.ContractEvent;

/**
* 合约样例,提供通过合约创建用户/数据账户/事件账户,写入KV,发布事件等功能
*/
@Contract
public interface SampleContract {

// a. 创建角色,并分配权限
@ContractEvent(name = "createRoleAndPermissions")
void createRoleAndPermissions(String role, String ledgerPermissionSemicolonStr, String txPermissionSemicolonStr);

// b. 注册用户
@ContractEvent(name = "registerUserByPubKey")
void registerUserByPubKey(String pubkey);

// c. 修改用户角色
@ContractEvent(name = "modifyUserRole")
void modifyUserRole(String address, String role);

// d. 修改用户状态
@ContractEvent(name = "modifyUserState")
void modifyUserState(String userAddress, String state);

// e. 注册数据账户
//void registerDataAccount(String seed);

// f. 修改数据账户角色及mode
@ContractEvent(name = "modifyDataAccountRoleAndMode")
void modifyDataAccountRoleAndMode(String dataAccountAddress, String role, String mode);

// h. 数据账户赋值,更新值
@ContractEvent(name = "dataAccountAddress")
void setKV(String dataAccountAddress, String key, String value, String version);

// i. 注册事件账户
// String registerEventAccount(String seed)

// j. 修改事件账户角色及mode
@ContractEvent(name = "modifyEventAccountRoleAndMode")
void modifyEventAccountRoleAndMode(String eventAccountAddress, String role, String mode);

// k. 发布事件
@ContractEvent(name = "publishEventAccount")
void publishEventAccount(String eventAccountAddress, String eventName, String value, String sequence);

// l. 合约中调用合约
@ContractEvent(name = "invokeContract")
void invokeContract(String contractAddress, String method, String argDotStr);

// m. 合约中部署合约
@ContractEvent(name = "deployContract")
String deployContract(String pubkey, byte[] carBytes);

// n. 修改合约角色及mode
@ContractEvent(name = "modifyContractRoleAndMode")
void modifyContractRoleAndMode(String contractAddress, String role, String mode);

// o. 修改合约状态
@ContractEvent(name = "modifyContractState")
void modifyContractState(String contractAddress, String state);


/**
* 设置KV
*
* @param address 数据账户地址
* @param key 键
* @param value 值
* @param version 版本
*/
@ContractEvent(name = "setKVWithVersion")
void setKVWithVersion(String address, String key, String value, long version);

/**
* 设置KV,基于最新数据版本
*
* @param address 数据账户地址
* @param key 键
* @param value 值
*/
@ContractEvent(name = "setKV")
void setKV(String address, String key, String value);

/**
* 注册用户
*
* @param seed 种子,不小于32个字符
*/
@ContractEvent(name = "registerUser")
String registerUser(String seed);

/**
* 注册数据账户
*
* @param seed 种子,不小于32个字符
*/
@ContractEvent(name = "registerDataAccount")
String registerDataAccount(String seed);

/**
* 注册事件账户
*
* @param seed 种子,不小于32个字符
*/
@ContractEvent(name = "registerEventAccount")
String registerEventAccount(String seed);

/**
* 发布事件
*
* @param address 事件账户地址
* @param topic 消息名称
* @param content 内容
* @param sequence 当前消息名称下最大序号(初始为-1)
*/
@ContractEvent(name = "publishEventWithSequence")
void publishEventWithSequence(String address, String topic, String content, long sequence);

/**
* 发布事件,基于最新时间序号
*
* @param address 事件账户地址
* @param topic 消息名称
* @param content 内容
*/
@ContractEvent(name = "publishEvent")
void publishEvent(String address, String topic, String content);
}

+ 0
- 233
samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java View File

@@ -1,233 +0,0 @@
package com.jdchain.samples.contract;

import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.EventProcessingAware;
import com.jd.blockchain.crypto.*;
import com.jd.blockchain.crypto.base.DefaultCryptoEncoding;
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm;
import com.jd.blockchain.ledger.*;

import com.jd.blockchain.transaction.SimpleSecurityOperationBuilder;
import utils.Bytes;

/**
* 合约样例实现
*/
public class SampleContractImpl implements EventProcessingAware, SampleContract {

private ContractEventContext eventContext;



@Override
public void setKVWithVersion(String address, String key, String value, long version) {
eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version);
}

@Override
public void setKV(String address, String key, String value) {
// 查询最新版本,初始为-1
// 查询已提交区块数据,不包括此操作所在未提交区块的所有数据
// TypedKVEntry[] entries = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), address, key);
// 可查询包括此操作所在未提交区块的所有数据
TypedKVEntry[] entries = eventContext.getUncommittedLedger().getDataEntries(address, key);
long version = -1;
if (null != entries && entries.length > 0) {
version = entries[0].getVersion();
}
eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version);
}

@Override
public String registerUser(String seed) {
CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519");
SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);
AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());
BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());
eventContext.getLedger().users().register(keypair.getIdentity());

return keypair.getAddress().toBase58();
}

@Override
public String registerDataAccount(String seed) {
CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519");
SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);
AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());
BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());
eventContext.getLedger().dataAccounts().register(keypair.getIdentity());

return keypair.getAddress().toBase58();
}

@Override
public String registerEventAccount(String seed) {
CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519");
SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);
AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());
BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());
eventContext.getLedger().eventAccounts().register(keypair.getIdentity());

return keypair.getAddress().toBase58();
}

@Override
public void publishEventWithSequence(String address, String topic, String content, long sequence) {
eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence);
}

@Override
public void publishEvent(String address, String topic, String content) {
// 查询最新序号,初始为-1
// 查询已提交区块数据,不包括此操作所在未提交区块的所有数据
// Event event = eventContext.getLedger().getRuntimeLedger().getLatestEvent(address, topic);
// 可查询包括此操作所在未提交区块的所有数据
Event event = eventContext.getUncommittedLedger().getLatestEvent(address, topic);
long sequence = -1;
if (null != event) {
sequence = event.getSequence();
}
eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence);
}

/**
* 合约方法调用前操作
*
* @param eventContext
*/
@Override
public void beforeEvent(ContractEventContext eventContext) {
this.eventContext = eventContext;
}

/**
* 合约方法调用后操作
*
* @param eventContext
* @param error
*/
@Override
public void postEvent(ContractEventContext eventContext, Exception error) {

}

@Override
public void createRoleAndPermissions(String role, String ledgerPermissionSemicolonStr, String txPermissionSemicolonStr) {

SimpleSecurityOperationBuilder.SimpleRoleConfigurer roleConfigurer = eventContext.getLedger().security().role(role);

if(ledgerPermissionSemicolonStr != null){
for(String perm : ledgerPermissionSemicolonStr.split(";")){
LedgerPermission permission = LedgerPermission.valueOf(perm.trim().toUpperCase());
roleConfigurer.enable(permission);
}
}

if(txPermissionSemicolonStr != null){
for(String perm : txPermissionSemicolonStr.split(";")){
TransactionPermission permission = TransactionPermission.valueOf(perm.trim().toUpperCase());
roleConfigurer.enable(permission);
}
}

}

@Override
public void registerUserByPubKey(String pubkey) {
PubKey pubKey = DefaultCryptoEncoding.createPubKey(ClassicAlgorithm.ED25519.code(), Bytes.fromBase58(pubkey).toBytes());
BlockchainIdentityData identityData = new BlockchainIdentityData(pubKey);
eventContext.getLedger().users().register(identityData);
}

@Override
public void modifyUserRole(String address, String role) {
eventContext.getLedger()
.security()
.authorziation(Bytes.fromBase58(address))
.authorize(role);

}

@Override
public void modifyUserState(String userAddress, String state) {
AccountState accountState = AccountState.valueOf(state.trim().toUpperCase());
eventContext.getLedger().user(userAddress)
.state(accountState);
}

@Override
public void modifyDataAccountRoleAndMode(String dataAccountAddress, String role, String mode) {
eventContext.getLedger().dataAccount(dataAccountAddress)
.permission()
.role(role)
.mode(Integer.parseInt(mode));
}

@Override
public void setKV(String dataAccountAddress, String key, String value, String version) {
eventContext.getLedger().dataAccount(dataAccountAddress)
.setText(key, value, Integer.parseInt(version));
}

@Override
public void modifyEventAccountRoleAndMode(String eventAccountAddress, String role, String mode) {
eventContext.getLedger().eventAccount(eventAccountAddress)
.permission()
.role(role)
.mode(Integer.parseInt(mode));
}

@Override
public void publishEventAccount(String eventAccountAddress, String eventName, String value, String sequence) {
eventContext.getLedger().eventAccount(eventAccountAddress)
.publish(eventName, value, Integer.parseInt(sequence));
}

@Override
public void invokeContract(String contractAddress, String method, String argSemicolonStr) {
String[] args = argSemicolonStr.split(";");
BytesValue[] bytesValues = new BytesValue[args.length];

for(int i = 0; i < args.length; i++){
bytesValues[i] = TypedValue.fromText(args[i]);
}

eventContext.getLedger()
.contract(contractAddress)
.invoke(method, new BytesValueList() {
@Override
public BytesValue[] getValues() {
return bytesValues;
}
});
}

@Override
public String deployContract(String pubkey, byte[] carBytes) {

PubKey pubKey = KeyGenUtils.decodePubKey(pubkey);

ContractCodeDeployOperation deployOperation = eventContext.getLedger().contracts()
.deploy(new BlockchainIdentityData(pubKey), carBytes);

return deployOperation.getContractID().getAddress().toString();
}

@Override
public void modifyContractRoleAndMode(String contractAddress, String role, String mode) {
eventContext.getLedger().contract(contractAddress)
.permission()
.role(role)
.mode(Integer.parseInt(mode));
}

@Override
public void modifyContractState(String contractAddress, String state) {
AccountState accountState = AccountState.valueOf(state.trim().toUpperCase());
eventContext.getLedger().contract(contractAddress)
.state(accountState);
}



}

+ 0
- 41
samples/pom.xml View File

@@ -1,41 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jd.blockchain</groupId>
<artifactId>jdchain-samples</artifactId>
<version>1.6.0.RELEASE</version>
<packaging>pom</packaging>

<properties>
<framework.version>1.6.0.RELEASE</framework.version>
<core.version>1.6.0.RELEASE</core.version>
</properties>

<modules>
<module>sdk-samples</module>
<module>contract-samples</module>
</modules>

<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<optimize>false</optimize>
<debug>true</debug>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
</configuration>
</plugin>
</plugins>
</build>


</project>

+ 0
- 74
samples/sdk-samples/pom.xml View File

@@ -1,74 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jd.blockchain</groupId>
<artifactId>jdchain-samples</artifactId>
<version>1.6.0.RELEASE</version>
</parent>
<artifactId>sdk-samples</artifactId>
<dependencies>
<!--以下依赖用于SDK常规使用-->
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>sdk-client</artifactId>
<version>${framework.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>sdk-rpc</artifactId>
<version>${framework.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-classic</artifactId>
<version>${framework.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>ledger-model</artifactId>
<version>${framework.version}</version>
</dependency>
<!--样例程序中使用到的合约-->
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>contract-samples</artifactId>
<version>${project.version}</version>
</dependency>
<!--以下依赖用于 com.jdchain.samples.Network 中四节点网路环境初始化和启动 -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>tools-initializer</artifactId>
<version>${core.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>peer</artifactId>
<version>${core.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>gateway</artifactId>
<version>${core.version}</version>
</dependency>
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>

+ 0
- 299
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java View File

@@ -1,299 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.gateway.GatewayConfigProperties;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.LedgerInitProperties;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.ParticipantNodeState;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.client.GatewayServiceFactory;
import com.jd.blockchain.tools.initializer.DBConnectionConfig;
import com.jd.blockchain.tools.initializer.LedgerBindingConfig;
import com.jd.blockchain.tools.initializer.PresetAnswerPrompter;
import com.jd.blockchain.tools.initializer.Prompter;
import com.jdchain.samples.sdk.testnet.GatewayRunner;
import com.jdchain.samples.sdk.testnet.NodeWebContext;
import com.jdchain.samples.sdk.testnet.PartNode;
import com.jdchain.samples.sdk.testnet.PeerServer;

import utils.concurrent.ThreadInvoker;
import utils.io.FileUtils;
import utils.net.NetworkAddress;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.junit.Assert;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* 测试网络
* 初始化启动基于内存的4节点JD Chain网络
*/
public class TestNet {

// 测试网络公私钥及私钥密码信息
private static final String[] PUB_KEYS = {
"7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq",
"7VeRBsHM2nsGwP8b2ufRxz36hhNtSqjKTquzoa4WVKWty5sD",
"7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe",
"7VeRKoM5RE6iFXr214Hsiic2aoqCQ7MEU1dHQFRnjXQcReAS"};
private static final String[] PRIV_KEYS = {
"177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x",
"177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT",
"177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF",
"177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns"};
private static final String PASSWORD = "abc";

// 存储配置
private static final String[] dbConnections = {
"memory://local/0",
"memory://local/1",
"memory://local/2",
"memory://local/3"};

// 共识协议
private static final String BFTSMART_PROVIDER = "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider";

// node节点服务端口,共识节点还会占用8910/8920/8930/8940/8911/8921/8931/8941用于共识服务,可以通过修改resources/network/bftsmart.config修改
private static final int[] NODE_PORTS = {12000, 12010, 12020, 12030};

// 网关服务端口
private static final int GATEWAY_PORT = 11000;

public static void main(String[] args) {
try {
Configurator.setRootLevel(Level.OFF);

// 内存账本初始化
HashDigest ledgerHash = initLedger();

// 启动Peer节点
PeerServer[] peerNodes = peerNodeStart(ledgerHash);

// 睡20秒,等待共识节点启动成功
Thread.sleep(20000);

// 启动网关
startGateway(peerNodes);

// 睡10秒,等待网关启动成功
Thread.sleep(10000);

// 初始化样例数据
initSampleData(ledgerHash);

System.out.println(" ------------------- START NETWORK SUCCESS ------------------- ");
} catch (Exception e) {
e.printStackTrace();
System.out.println(" ------------------- START NETWORK FAILED ------------------- ");
System.exit(-1);
}
}

private static HashDigest initLedger() throws IOException {
Prompter consolePrompter = new PresetAnswerPrompter("N");
LedgerInitProperties initSetting = LedgerInitProperties.resolve(new ClassPathResource("testnet/ledger.init").getInputStream());

ParticipantNode[] participantNodes = new ParticipantNode[PUB_KEYS.length];
for (int i = 0; i < PUB_KEYS.length; i++) {
participantNodes[i] = new PartNode(i, KeyGenUtils.decodePubKey(PUB_KEYS[i]), ParticipantNodeState.CONSENSUS);
}

NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress();
NodeWebContext node0 = new NodeWebContext(0, initAddr0);

NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress();
NodeWebContext node1 = new NodeWebContext(1, initAddr1);

NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress();
NodeWebContext node2 = new NodeWebContext(2, initAddr2);

NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress();
NodeWebContext node3 = new NodeWebContext(3, initAddr3);

PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD);
PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD);
PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD);
PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD);

CountDownLatch quitLatch = new CountDownLatch(4);

DBConnectionConfig testDb0 = new DBConnectionConfig();
testDb0.setConnectionUri(dbConnections[0]);
ThreadInvoker.AsyncCallback<HashDigest> callback0 = node0.startInit(privkey0, initSetting, testDb0, consolePrompter,
quitLatch);

DBConnectionConfig testDb1 = new DBConnectionConfig();
testDb1.setConnectionUri(dbConnections[1]);
ThreadInvoker.AsyncCallback<HashDigest> callback1 = node1.startInit(privkey1, initSetting, testDb1, consolePrompter,
quitLatch);

DBConnectionConfig testDb2 = new DBConnectionConfig();
testDb2.setConnectionUri(dbConnections[2]);
ThreadInvoker.AsyncCallback<HashDigest> callback2 = node2.startInit(privkey2, initSetting, testDb2, consolePrompter,
quitLatch);

DBConnectionConfig testDb03 = new DBConnectionConfig();
testDb03.setConnectionUri(dbConnections[3]);
ThreadInvoker.AsyncCallback<HashDigest> callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter,
quitLatch);

HashDigest ledgerHash0 = callback0.waitReturn();
HashDigest ledgerHash1 = callback1.waitReturn();
HashDigest ledgerHash2 = callback2.waitReturn();
HashDigest ledgerHash3 = callback3.waitReturn();
assertNotNull(ledgerHash0);
assertEquals(ledgerHash0, ledgerHash1);
assertEquals(ledgerHash0, ledgerHash2);
assertEquals(ledgerHash0, ledgerHash3);

return ledgerHash0;
}

private static PeerServer[] peerNodeStart(HashDigest ledgerHash) {
NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", NODE_PORTS[0]);
LedgerBindingConfig bindingConfig0 = loadBindingConfig(0, ledgerHash);
PeerServer peer0 = new PeerServer(peerSrvAddr0, bindingConfig0);

NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", NODE_PORTS[1]);
LedgerBindingConfig bindingConfig1 = loadBindingConfig(1, ledgerHash);
PeerServer peer1 = new PeerServer(peerSrvAddr1, bindingConfig1);

NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", NODE_PORTS[2]);
LedgerBindingConfig bindingConfig2 = loadBindingConfig(2, ledgerHash);
PeerServer peer2 = new PeerServer(peerSrvAddr2, bindingConfig2);

NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", NODE_PORTS[3]);
LedgerBindingConfig bindingConfig3 = loadBindingConfig(3, ledgerHash);
PeerServer peer3 = new PeerServer(peerSrvAddr3, bindingConfig3);

ThreadInvoker.AsyncCallback<Object> peerStarting0 = peer0.start();
ThreadInvoker.AsyncCallback<Object> peerStarting1 = peer1.start();
ThreadInvoker.AsyncCallback<Object> peerStarting2 = peer2.start();
ThreadInvoker.AsyncCallback<Object> peerStarting3 = peer3.start();

peerStarting0.waitReturn();
peerStarting1.waitReturn();
peerStarting2.waitReturn();
peerStarting3.waitReturn();

return new PeerServer[]{peer0, peer1, peer2, peer3};
}

private static LedgerBindingConfig loadBindingConfig(int id, HashDigest ledgerHash) {
LedgerBindingConfig ledgerBindingConfig;
String newLedger = ledgerHash.toBase58();
String resourceClassPath = "testnet/ledger-binding-mem-" + id + ".conf";
String ledgerBindingUrl = TestNet.class.getResource("/") + resourceClassPath;

try {
URL url = new URL(ledgerBindingUrl);
File ledgerBindingConf = new File(url.getPath());
if (ledgerBindingConf.exists()) {
List<String> readLines = org.apache.commons.io.FileUtils.readLines(ledgerBindingConf);

List<String> writeLines = new ArrayList<>();

if (readLines != null && !readLines.isEmpty()) {
String oldLedgerLine = null;
for (String readLine : readLines) {
if (readLine.startsWith("ledger")) {
oldLedgerLine = readLine;
break;
}
}
String[] oldLedgerArray = oldLedgerLine.split("=");

String oldLedger = oldLedgerArray[1];
if (!oldLedger.equalsIgnoreCase(newLedger)) {
for (String readLine : readLines) {
String newLine = readLine.replace(oldLedger, newLedger);
writeLines.add(newLine);
}
}
if (!writeLines.isEmpty()) {
org.apache.commons.io.FileUtils.writeLines(ledgerBindingConf, writeLines);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}

ClassPathResource res = new ClassPathResource(resourceClassPath);
try (InputStream in = res.getInputStream()) {
ledgerBindingConfig = LedgerBindingConfig.resolve(in);
} catch (IOException e) {
throw new IllegalStateException(e.getMessage(), e);
}
return ledgerBindingConfig;
}

private static void startGateway(PeerServer[] peerNodes) {
GatewayConfigProperties.KeyPairConfig keyPairConfig = new GatewayConfigProperties.KeyPairConfig();
keyPairConfig.setPubKeyValue(PUB_KEYS[0]);
keyPairConfig.setPrivKeyValue(PRIV_KEYS[0]);
keyPairConfig.setPrivKeyPassword(KeyGenUtils.encodePasswordAsBase58(PASSWORD));

GatewayRunner gateway = new GatewayRunner("127.0.0.1", GATEWAY_PORT, keyPairConfig, new String[]{BFTSMART_PROVIDER}, null, peerNodes[0].getServiceAddress());

ThreadInvoker.AsyncCallback<Object> gwStarting = gateway.start();

gwStarting.waitReturn();
}

private static void initSampleData(HashDigest ledgerHash) throws IOException {
BlockchainKeypair admin = new BlockchainKeypair(KeyGenUtils.decodePubKey(PUB_KEYS[0]), KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD));
BlockchainKeypair user = new BlockchainKeypair(
KeyGenUtils.decodePubKey("7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht"),
KeyGenUtils.decodePrivKey("177gjuGapUVdLnEDAkqjQWhZxHh5jL5W6Hg1q8kbdsbk1BKht4QkmuB6dKvyJrgKTRmXSgK", "8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG"));

BlockchainService blockchainService = GatewayServiceFactory.connect(
"127.0.0.1", GATEWAY_PORT, false, admin).getBlockchainService();

TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash);
// 初始化一个用户
txTemp.users().register(user.getIdentity());
// 创建角色 MANAGER
txTemp.security().roles().configure("SAMPLE-ROLE")
.enable(LedgerPermission.WRITE_DATA_ACCOUNT)
.enable(TransactionPermission.DIRECT_OPERATION);

// 设置用户角色权限
txTemp.security().authorziations().forUser(user.getAddress()).authorize("SAMPLE-ROLE");
// 初始化一个数据账户并设置KV
txTemp.dataAccounts().register(user.getIdentity());
txTemp.dataAccount(user.getAddress()).setText("sample-key", "sample-value", -1);
// 初始化一个事件账户并发布一个事件
txTemp.eventAccounts().register(user.getIdentity());
txTemp.eventAccount(user.getAddress()).publish("sample-event", "sample-content", -1);
// 初始化一个合约
txTemp.contracts().deploy(user.getIdentity(), FileUtils.readBytes(new ClassPathResource("contract-samples-1.6.0.RELEASE.car").getFile()));

PreparedTransaction ptx = txTemp.prepare();
ptx.sign(admin);

TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

}

+ 0
- 80
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/GatewayRunner.java View File

@@ -1,80 +0,0 @@
package com.jdchain.samples.sdk.testnet;

import com.jd.blockchain.gateway.GatewayConfigProperties;
import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig;

import utils.concurrent.ThreadInvoker;
import utils.concurrent.ThreadInvoker.AsyncCallback;
import utils.net.NetworkAddress;

import com.jd.blockchain.gateway.GatewayServerBooter;

import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;

import java.util.Map;

public class GatewayRunner {

private NetworkAddress serviceAddress;

private GatewayServerBooter gatewayServer;

public GatewayRunner(String host, int port, KeyPairConfig gatewayDefaultKey, NetworkAddress... masterPeerAddresses) {
this(host, port, gatewayDefaultKey, null, null, masterPeerAddresses);
}

public GatewayRunner(String host, int port, KeyPairConfig gatewayDefaultKey, String[] providers,
Map<String, Object> otherMap, NetworkAddress... masterPeerAddresses) {
this.serviceAddress = new NetworkAddress(host, port);
GatewayConfigProperties config = new GatewayConfigProperties();

config.http().setHost(host);
config.http().setPort(port);

if (providers != null) {
for (String provider : providers) {
config.providerConfig().add(provider);
}
}

for (NetworkAddress address : masterPeerAddresses) {
config.setMasterPeerAddress(address);
}

config.keys().getDefault().setPubKeyValue(gatewayDefaultKey.getPubKeyValue());
config.keys().getDefault().setPrivKeyValue(gatewayDefaultKey.getPrivKeyValue());
config.keys().getDefault().setPrivKeyPassword(gatewayDefaultKey.getPrivKeyPassword());

if (!CollectionUtils.isEmpty(otherMap)) {
config.setDataRetrievalUrl(otherMap.get("DATA_RETRIEVAL_URL").toString());
}


//get the springConfigLocation;
ClassPathResource configResource = new ClassPathResource("application-gw.properties");
String springConfigLocation = "classPath:" + configResource.getPath();

this.gatewayServer = new GatewayServerBooter(config, springConfigLocation);
}

public AsyncCallback<Object> start() {
ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() {
@Override
protected Object invoke() throws Exception {
gatewayServer.start();
return null;
}
};

return invoker.start();
}

public void stop() {
gatewayServer.close();
}

public NetworkAddress getServiceAddress() {
return serviceAddress;
}
}

+ 0
- 22
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/LedgerInit.java View File

@@ -1,22 +0,0 @@
package com.jdchain.samples.sdk.testnet;

import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory;
import com.jd.blockchain.tools.initializer.web.InitWebSecurityConfiguration;
import com.jd.blockchain.tools.initializer.web.InitWebServerConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Configuration
@EnableConfigurationProperties
@Import(value = { InitWebServerConfiguration.class, InitWebSecurityConfiguration.class })
public class LedgerInit {

@Bean
public CompositeConnectionFactory getCompositeConnectionFactory() {
return new CompositeConnectionFactory();
}
}

+ 0
- 99
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/NodeWebContext.java View File

@@ -1,99 +0,0 @@
package com.jdchain.samples.sdk.testnet;

import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.ledger.LedgerInitProperties;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.core.LedgerInitDecision;
import com.jd.blockchain.ledger.core.LedgerInitProposal;
import com.jd.blockchain.ledger.core.LedgerManager;
import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory;
import com.jd.blockchain.tools.initializer.DBConnectionConfig;
import com.jd.blockchain.tools.initializer.LedgerInitProcess;
import com.jd.blockchain.tools.initializer.Prompter;
import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController;

import utils.concurrent.ThreadInvoker;
import utils.net.NetworkAddress;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.concurrent.CountDownLatch;

public class NodeWebContext {


private NetworkAddress serverAddress;

private DBConnectionConfig dbConnConfig;

private volatile ConfigurableApplicationContext ctx;

private volatile LedgerInitProcess initProcess;

private volatile LedgerInitializeWebController controller;

private volatile LedgerManager ledgerManager;

private volatile CompositeConnectionFactory db;

private int id;

public int getId() {
return controller.getId();
}

public TransactionContent getInitTxContent() {
return controller.getInitTxContent();
}

public LedgerInitProposal getLocalPermission() {
return controller.getLocalPermission();
}

public LedgerInitDecision getLocalDecision() {
return controller.getLocalDecision();
}

public NodeWebContext(int id, NetworkAddress serverAddress) {
this.id = id;
this.serverAddress = serverAddress;
}

public ThreadInvoker.AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting,
DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) {

ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() {
@Override
protected HashDigest invoke() throws Exception {
doStartServer();

NodeWebContext.this.dbConnConfig = dbConnConfig;
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting,
dbConnConfig, prompter);

quitLatch.countDown();
return ledgerHash;
}
};

return invoker.start();
}

public void doStartServer() {
String argServerAddress = String.format("--server.address=%s", serverAddress.getHost());
String argServerPort = String.format("--server.port=%s", serverAddress.getPort());
String nodebug = "--debug=false";
String[] innerArgs = {argServerAddress, argServerPort, nodebug};

ctx = SpringApplication.run(LedgerInit.class, innerArgs);

ctx.setId("Node-" + id);
controller = ctx.getBean(LedgerInitializeWebController.class);
ledgerManager = ctx.getBean(LedgerManager.class);
db = ctx.getBean(CompositeConnectionFactory.class);
initProcess = ctx.getBean(LedgerInitProcess.class);
}

}

+ 0
- 59
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/PartNode.java View File

@@ -1,59 +0,0 @@
package com.jdchain.samples.sdk.testnet;

import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.ParticipantNodeState;

import utils.Bytes;

public class PartNode implements ParticipantNode {

private int id;

private Bytes address;

private String name;

private PubKey pubKey;

private ParticipantNodeState participantNodeState;

public PartNode(int id, PubKey pubKey, ParticipantNodeState participantNodeState) {
this(id, id + "", pubKey, participantNodeState);
}

public PartNode(int id, String name, PubKey pubKey, ParticipantNodeState participantNodeState) {
this.id = id;
this.name = name;
this.pubKey = pubKey;
this.address = AddressEncoding.generateAddress(pubKey);
this.participantNodeState = participantNodeState;
}

@Override
public int getId() {
return id;
}

@Override
public Bytes getAddress() {
return address;
}

@Override
public String getName() {
return name;
}

@Override
public PubKey getPubKey() {
return pubKey;
}

@Override
public ParticipantNodeState getParticipantNodeState() {
return participantNodeState;
}

}

+ 0
- 67
samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/testnet/PeerServer.java View File

@@ -1,67 +0,0 @@
package com.jdchain.samples.sdk.testnet;

import com.jd.blockchain.ledger.core.LedgerManager;
import com.jd.blockchain.peer.PeerServerBooter;
import com.jd.blockchain.storage.service.DbConnectionFactory;
import com.jd.blockchain.tools.initializer.LedgerBindingConfig;

import utils.concurrent.ThreadInvoker;
import utils.net.NetworkAddress;

public class PeerServer {
private NetworkAddress serviceAddress;

private volatile PeerServerBooter booter;

private LedgerBindingConfig ledgerBindingConfig;

public DbConnectionFactory getDBConnectionFactory() {
return booter.getDBConnectionFactory();
}

public NetworkAddress getServiceAddress() {
return serviceAddress;
}

public LedgerBindingConfig getLedgerBindingConfig() {
return ledgerBindingConfig;
}

public PeerServer(NetworkAddress serviceAddress, LedgerBindingConfig ledgerBindingConfig) {
this(serviceAddress, ledgerBindingConfig, null, null);
}

public PeerServer(NetworkAddress serviceAddress, LedgerBindingConfig ledgerBindingConfig, DbConnectionFactory dbConnectionFactory) {
this(serviceAddress, ledgerBindingConfig, dbConnectionFactory, null);
}

public PeerServer(NetworkAddress serviceAddress, LedgerBindingConfig ledgerBindingConfig,
DbConnectionFactory dbConnectionFactory, LedgerManager ledgerManager) {
this.serviceAddress = serviceAddress;
this.ledgerBindingConfig = ledgerBindingConfig;
if (dbConnectionFactory == null) {
this.booter = new PeerServerBooter(ledgerBindingConfig, serviceAddress.getHost(),
serviceAddress.getPort());
} else {
this.booter = new PeerServerBooter(ledgerBindingConfig, serviceAddress.getHost(),
serviceAddress.getPort(), dbConnectionFactory, ledgerManager);
}
}

public ThreadInvoker.AsyncCallback<Object> start() {
ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() {
@Override
protected Object invoke() throws Exception {
booter.start();

return null;
}
};

return invoker.start();
}

public void stop() {
booter.close();
}
}

+ 0
- 20
samples/sdk-samples/src/main/resources/config.properties View File

@@ -1,20 +0,0 @@
# SDK Sample 相关配置,请根据实际情况进行修改

# 签名用户配置
# 公钥
pubkey=7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq
# 私钥
privkey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x
# Base58编码的私钥密码
password=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY


# 网关配置
# IP
gateway.host=localhost
# 端口
gateway.port=11000


# 账本,为空时选择网关查询到的账本列表第一个
ledger=

BIN
samples/sdk-samples/src/main/resources/contract-samples-1.6.0.RELEASE.car View File


+ 0
- 155
samples/sdk-samples/src/main/resources/testnet/bftsmart.config View File

@@ -1,155 +0,0 @@

# Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


############################################
###### Consensus Participant0 ######
############################################

system.server.0.network.host=127.0.0.1
system.server.0.network.port=8910
system.server.0.network.secure=false

############################################
###### #Consensus Participant1 ######
############################################

system.server.1.network.host=127.0.0.1
system.server.1.network.port=8920
system.server.1.network.secure=false

############################################
###### #Consensus Participant2 ######
############################################

system.server.2.network.host=127.0.0.1
system.server.2.network.port=8930
system.server.2.network.secure=false

############################################
###### Consensus Participant3 ######
############################################

system.server.3.network.host=127.0.0.1
system.server.3.network.port=8940
system.server.3.network.secure=false

############################################
####### Communication Configurations #######
############################################

#HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value)
#This parameter is not currently being used being used
#system.authentication.hmacAlgorithm = HmacSHA1

#Specify if the communication system should use a thread to send data (true or false)
system.communication.useSenderThread = true

#Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments
#and benchmarks, but must not be used in production systems.
system.communication.defaultkeys = true

############################################
### Replication Algorithm Configurations ###
############################################

#Number of servers in the group
system.servers.num = 4

#Maximum number of faulty replicas
system.servers.f = 1

#Timeout to asking for a client request
system.totalordermulticast.timeout = 5000


#Maximum batch size (in number of messages)
system.totalordermulticast.maxbatchsize = 400

#Number of nonces (for non-determinism actions) generated
system.totalordermulticast.nonces = 10

#if verification of leader-generated timestamps are increasing
#it can only be used on systems in which the network clocks
#are synchronized
system.totalordermulticast.verifyTimestamps = false

#Quantity of messages that can be stored in the receive queue of the communication system
system.communication.inQueueSize = 500000

# Quantity of messages that can be stored in the send queue of each replica
system.communication.outQueueSize = 500000

#Set to 1 if SMaRt should use signatures, set to 0 if otherwise
system.communication.useSignatures = 0

#Set to 1 if SMaRt should use MAC's, set to 0 if otherwise
system.communication.useMACs = 1

#Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise
system.debug = 0

#Print information about the replica when it is shutdown
system.shutdownhook = true

############################################
###### State Transfer Configurations #######
############################################

#Activate the state transfer protocol ('true' to activate, 'false' to de-activate)
system.totalordermulticast.state_transfer = true

#Maximum ahead-of-time message not discarded
system.totalordermulticast.highMark = 10000

#Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered)
system.totalordermulticast.revival_highMark = 10

#Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs
system.totalordermulticast.timeout_highMark = 200

############################################
###### Log and Checkpoint Configurations ###
############################################

system.totalordermulticast.log = true
system.totalordermulticast.log_parallel = false
system.totalordermulticast.log_to_disk = false
system.totalordermulticast.sync_log = false

#Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol)
system.totalordermulticast.checkpoint_period = 1000
system.totalordermulticast.global_checkpoint_period = 120000

system.totalordermulticast.checkpoint_to_disk = false
system.totalordermulticast.sync_ckp = false


############################################
###### Reconfiguration Configurations ######
############################################

#Replicas ID for the initial view, separated by a comma.
# The number of replicas in this parameter should be equal to that specified in 'system.servers.num'
system.initial.view = 0,1,2,3

#The ID of the trust third party (TTP)
system.ttp.id = 2001

#This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults
system.bft = true

#Custom View Storage;
#view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage

+ 0
- 25
samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-0.conf View File

@@ -1,25 +0,0 @@
#绑定的账本的hash列表;以逗号分隔;
ledger.bindings=6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ


#第 1 个账本[6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ]的配置;
#账本的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.name=sample-network
#账本底层数据结构;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.data.structure=MERKLE_TREE
#账本的当前共识参与方的ID;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.id=0
#账本的当前共识参与方的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.name=a.com
#账本的当前共识参与方的私钥文件的保存路径;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk-path=
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY
#账本的当前共识参与方地址
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.address=LdeP3fY7jJbNwL8CiL2wU21AF9unDWQjVEW5w
#账本的存储数据库的连接字符串;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.uri=memory://local/0
#账本的存储数据库的连接口令;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.pwd=

+ 0
- 25
samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-1.conf View File

@@ -1,25 +0,0 @@
#绑定的账本的hash列表;以逗号分隔;
ledger.bindings=6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ


#第 1 个账本[6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ]的配置;
#账本的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.name=sample-network
#账本底层数据结构;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.data.structure=MERKLE_TREE
#账本的当前共识参与方的ID;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.id=1
#账本的当前共识参与方的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.name=b.com
#账本的当前共识参与方的私钥文件的保存路径;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk-path=
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk=177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY
#账本的当前共识参与方地址
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.address=LdeNnz88dH6CA6PwkVdn3nFRibUKP3sFT2byG
#账本的存储数据库的连接字符串;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.uri=memory://local/1
#账本的存储数据库的连接口令;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.pwd=

+ 0
- 25
samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-2.conf View File

@@ -1,25 +0,0 @@
#绑定的账本的hash列表;以逗号分隔;
ledger.bindings=6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ


#第 1 个账本[6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ]的配置;
#账本的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.name=sample-network
#账本底层数据结构;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.data.structure=MERKLE_TREE
#账本的当前共识参与方的ID;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.id=2
#账本的当前共识参与方的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.name=c.com
#账本的当前共识参与方的私钥文件的保存路径;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk-path=
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk=177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY
#账本的当前共识参与方地址
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.address=LdeNmdpT4DiTwLUP9jRQhwdRBRiXeHno456vy
#账本的存储数据库的连接字符串;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.uri=memory://local/2
#账本的存储数据库的连接口令;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.pwd=

+ 0
- 25
samples/sdk-samples/src/main/resources/testnet/ledger-binding-mem-3.conf View File

@@ -1,25 +0,0 @@
#绑定的账本的hash列表;以逗号分隔;
ledger.bindings=6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ


#第 1 个账本[6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ]的配置;
#账本的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.name=sample-network
#账本底层数据结构;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.data.structure=MERKLE_TREE
#账本的当前共识参与方的ID;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.id=3
#账本的当前共识参与方的名字;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.name=d.com
#账本的当前共识参与方的私钥文件的保存路径;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk-path=
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pk=177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY
#账本的当前共识参与方地址
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.parti.address=LdeNekdXMHqyz9Qxc2jDSBnkvvZLbty6pRDdP
#账本的存储数据库的连接字符串;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.uri=memory://local/3
#账本的存储数据库的连接口令;
binding.6BCg5vgU57ykY6g2CpyUnt5ZMgdxfD1b3qXxQrRyfiXTQ.db.pwd=

+ 0
- 76
samples/sdk-samples/src/main/resources/testnet/ledger.init View File

@@ -1,76 +0,0 @@
#账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取;
ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe

#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途;
ledger.name=sample-ledger

#声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区
created-time=2019-08-01 14:26:58.069+0800

#共识服务提供者;必须;
consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider

#共识服务的参数配置;必须;
consensus.conf=classpath:testnet/bftsmart.config

#密码服务提供者列表,以英文逗点“,”分隔;必须;
crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \
com.jd.blockchain.crypto.service.sm.SMCryptoService

#账本数据底层结构,分为:MERKLE_TREE, KV两种,默认MERKLE_TREE
ledger.data.structure=MERKLE_TREE

#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置;
cons_parti.count=4

#第0个参与方的名称;
cons_parti.0.name=a.com
#第0个参与方的公钥文件路径;
cons_parti.0.pubkey-path=
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.0.pubkey=7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq
#第0个参与方的账本初始服务的主机;
cons_parti.0.initializer.host=127.0.0.1
#第0个参与方的账本初始服务的端口;
cons_parti.0.initializer.port=9800
#第0个参与方的账本初始服务是否开启安全连接;
cons_parti.0.initializer.secure=false

#第1个参与方的名称;
cons_parti.1.name=b.com
#第1个参与方的公钥文件路径;
cons_parti.1.pubkey-path=
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.1.pubkey=7VeRBsHM2nsGwP8b2ufRxz36hhNtSqjKTquzoa4WVKWty5sD
#第1个参与方的账本初始服务的主机;
cons_parti.1.initializer.host=127.0.0.1
#第1个参与方的账本初始服务的端口;
cons_parti.1.initializer.port=9810
#第1个参与方的账本初始服务是否开启安全连接;
cons_parti.1.initializer.secure=false

#第2个参与方的名称;
cons_parti.2.name=c.com
#第2个参与方的公钥文件路径;
cons_parti.2.pubkey-path=
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.2.pubkey=7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe
#第2个参与方的账本初始服务的主机;
cons_parti.2.initializer.host=127.0.0.1
#第2个参与方的账本初始服务的端口;
cons_parti.2.initializer.port=9820
#第2个参与方的账本初始服务是否开启安全连接;
cons_parti.2.initializer.secure=false

#第3个参与方的名称;
cons_parti.3.name=c.com
#第3个参与方的公钥文件路径;
cons_parti.3.pubkey-path=
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.3.pubkey=7VeRKoM5RE6iFXr214Hsiic2aoqCQ7MEU1dHQFRnjXQcReAS
#第3个参与方的账本初始服务的主机;
cons_parti.3.initializer.host=127.0.0.1
#第3个参与方的账本初始服务的端口;
cons_parti.3.initializer.port=9830
#第3个参与方的账本初始服务是否开启安全连接;
cons_parti.3.initializer.secure=false

+ 0
- 175
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java View File

@@ -1,175 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.ledger.AccountState;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.BlockchainIdentityData;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.BytesDataList;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.transaction.ContractEventSendOperationBuilder;
import com.jd.blockchain.transaction.ContractReturnValue;
import com.jd.blockchain.transaction.GenericValueHolder;
import com.jdchain.samples.contract.SampleContract;
import org.junit.Assert;
import org.junit.Test;
import utils.io.BytesUtils;
import utils.io.FileUtils;

import java.util.UUID;

/**
* 合约相关操作示例:
* 合约部署,合约调用
*/
public class ContractSample extends SampleBase {

/**
* 有两种方式部署合约:
* 1. contract-samples模块下,配置好pom里面的参数,执行 mvn clean deploy 即可
* 2. 打包contract-samples项目生成 car包,参考testDeploy测试代码部署
*/
@Test
public void testDeploy() {
// 新建交易
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.6.0.RELEASE.car"));
// 准备交易
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 有两种方式更新合约代码:
* 1. contract-samples模块下,配置好pom里面的参数,其中contractAddress设置为已部署上链合约公钥信息,执行 mvn clean deploy 即可
* 2. 打包contract-samples项目生成 car包,参考testUpdate测试代码部署
*/
@Test
public void testUpdate() {
// 新建交易
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.6.0.RELEASE.car"));
// 准备交易
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 基于动态代理方式合约调用,需要依赖合约接口
*/
@Test
public void testExecuteByProxy() {
// 新建交易
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();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());

// 获取返回值
System.out.println(userAddress.get());
}

/**
* 非动态代理方式合约调用,不需要依赖合约接口及实现
*/
@Test
public void testExecuteWithArgus() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);

ContractEventSendOperationBuilder builder = txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye");
// 运行前,填写正确的合约地址,数据账户地址等参数
// 一次交易中可调用多个(多次调用)合约方法
// 调用合约的 registerUser 方法,传入合约地址,合约方法名,合约方法参数列表
builder.invoke("registerUser",
new BytesDataList(new TypedValue[]{
TypedValue.fromText(UUID.randomUUID().toString())
})
);
// 准备交易
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());

Assert.assertEquals(1, response.getOperationResults().length);
// 解析合约方法调用返回值
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;
}
}
}

/**
* 更新合约状态
*/
@Test
public void updateContractState() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 合约状态分为:NORMAL(正常) FREEZE(冻结) REVOKE(销毁)
// 冻结合约
txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye").state(AccountState.FREEZE);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 更新合约权限
*/
@Test
public void updateDPermission() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 配置合约权限
// 如下配置表示仅有 ROLE 角色用户才有调用 LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye 权限
txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye").permission().mode(70).role("ROLE");
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}
}

+ 0
- 98
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java View File

@@ -1,98 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import org.junit.Assert;
import org.junit.Test;
import utils.Bytes;

/**
* 数据账户相关操作示例:
* 创建数据账户,写入KV数据
*/
public class DataAccountSample extends SampleBase {

/**
* 注册数据账户
*/
@Test
public void testRegisterDataAccount() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成数据账户
BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("数据账户地址:" + dataAccount.getAddress());
// 注册数据账户
txTemp.dataAccounts().register(dataAccount.getIdentity());
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 设置KV
*/
@Test
public void testSetKV() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);

// 请正确填写数据账户地址
// expVersion是针对此key的插入更新操作次数严格递增,初始为-1,再次运行本测试用例请修改该值,否则服务端将报版本冲突异常。
txTemp.dataAccount(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"))
.setText("key1", "value1", -1)
.setInt64("key2", 1, -1)
.setJSON("key3", "{}", -1)
.setBytes("key4", Bytes.fromInt(2), -1);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());

}

/**
* 注册数据账户的同时设置KV,一个事务内
*/
@Test
public void testRegisterDataAccountAndSetKV() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成数据账户
BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("数据账户地址:" + dataAccount.getAddress());
// 注册数据账户
txTemp.dataAccounts().register(dataAccount.getIdentity());
// 设置KV
txTemp.dataAccount(dataAccount.getAddress())
.setText("key", "value", -1);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 更新数据账户权限
*/
@Test
public void updateDPermission() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 配置数据账户权限
// 如下配置表示仅有 ROLE 角色用户才有写入 LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye 权限
txTemp.dataAccount("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye").permission().mode(70).role("ROLE");
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}
}

+ 0
- 149
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java View File

@@ -1,149 +0,0 @@
package com.jdchain.samples.sdk;

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.PreparedTransaction;
import com.jd.blockchain.ledger.SystemEvent;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import org.junit.Assert;
import org.junit.Test;
import utils.Bytes;
import utils.io.BytesUtils;

import java.util.concurrent.CountDownLatch;

/**
* 事件账户相关操作示例:
* 事件账户创建,事件发布,事件监听
*/
public class EventSample extends SampleBase {

/**
* 事件监听
*/
@Test
public void testEventListen() {

// 事件监听会创建子线程,为阻止子线程被直接关闭,加入等待
CountDownLatch cdl = new CountDownLatch(1);

// 监听系统事件,目前仅有新区快产生事件
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;
}
});

try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

/**
* 注册事件账户
*/
@Test
public void testRegisterEventAccount() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成事件账户
BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("事件账户地址:" + eventAccount.getAddress());
// 注册事件账户
txTemp.eventAccounts().register(eventAccount.getIdentity());
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 发布事件
*/
@Test
public void testPublishEvent() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);

// 请正确填写数据账户地址
// sequence是针对此消息name的插入更新操作次数严格递增,初始为-1,再次运行本测试用例请修改该值,否则服务端将报版本冲突异常。
txTemp.eventAccount(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"))
.publish("topic1", "content1", -1)
.publish("topic1", "content2", 0)
.publish("topic1", "content3", 1)
.publish("topic2", "content", -1)
.publish("topic3", 1, -1)
.publish("topic4", Bytes.fromInt(1), -1);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 注册事件账户的同时发布事件,一个事务内
*/
@Test
public void testRegisterEventAccountAndPublishEvent() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成事件账户
BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate();
System.out.println("事件账户地址:" + eventAccount.getAddress());
// 注册事件账户
txTemp.eventAccounts().register(eventAccount.getIdentity());
// 发布事件
txTemp.eventAccount(eventAccount.getAddress()).publish("topic", "content", -1);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 更新事件账户权限
*/
@Test
public void updateDPermission() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 配置事件账户权限
// 如下配置表示仅有 ROLE 角色用户才有写入 LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye 权限
txTemp.eventAccount("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye").permission().mode(70).role("ROLE");
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}
}

+ 0
- 133
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ParticipantSample.java View File

@@ -1,133 +0,0 @@
package com.jdchain.samples.sdk;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.junit.Assert;
import org.junit.Test;

import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.httpservice.converters.JsonResponseConverter;
import com.jd.httpservice.utils.web.WebResponse;

import utils.codec.Base58Utils;
import utils.crypto.classic.SHA256Utils;
import utils.security.ShaUtils;

/**
* 参与方节点相关操作示例:
* 注册/激活/移除参与方操作
* <p>
* 本样例无法直接运行,请用户务必参照共识节点相关操作文档步骤完成各种前置操作,然后根据实际配置修改本样例各方法内参数
*/
public class ParticipantSample extends SampleBase {

// 注册参与方
@Test
public void registerParticipant() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成用户信息
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
String pwd = Base58Utils.encode(SHA256Utils.hash("1".getBytes()));
System.out.println("参与方私钥:" + KeyGenUtils.encodePrivKey(user.getPrivKey(), pwd));
System.out.println("参与方私钥密码:" + pwd);
System.out.println("参与方公钥:" + KeyGenUtils.encodePubKey(user.getPubKey()));
System.out.println("参与方地址:" + user.getAddress());
// 注册参与方
txTemp.participants().register("new peer node", user.getIdentity());
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 激活参与方
* 执行前请确保新节点已注册,且已经参照共识节点相关操作文档创建并启动新节点!!!
* 然后根据实际情况修改请求参数
*
* @throws Exception
*/
@Test
public void activeParticipant() throws Exception {
// 新节点API服务IP和端口
String newNodeIp = "127.0.0.1";
String newNodeApiPort = "12040";
// 账本信息
String ledgerHash = ledger.toString();
// 新节点共识配置
String newNodeConsensusHost = "127.0.0.1";
String newNodeConsensusPot = "8950";
// 区块高度最新的节点API服务IP和端口,用于区块同步
String syncNodeHost = "127.0.0.1";
String syncNodePort = "12000";

// 发送POST请求执行节点激活操作
HttpPost httpPost = new HttpPost(String.format("http://%s:%s/management/delegate/activeparticipant", newNodeIp, newNodeApiPort));
List<BasicNameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("ledgerHash", ledgerHash));
params.add(new BasicNameValuePair("consensusHost", newNodeConsensusHost));
params.add(new BasicNameValuePair("consensusPort", newNodeConsensusPot));
params.add(new BasicNameValuePair("remoteManageHost", syncNodeHost));
params.add(new BasicNameValuePair("remoteManagePort", syncNodePort));
params.add(new BasicNameValuePair("shutdown", "false"));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpClient httpClient = HttpClients.createDefault();
HttpResponse response = httpClient.execute(httpPost);
JsonResponseConverter jsonConverter = new JsonResponseConverter(WebResponse.class);

WebResponse webResponse = (WebResponse) jsonConverter.getResponse(null, response.getEntity().getContent(), null);
Assert.assertTrue(webResponse.isSuccess());
}

/**
* 移除参与方
* 执行前请确保新节点已启动且出于参与共识状态!!!
* 然后根据实际情况修改请求参数
*
* @throws Exception
*/
@Test
public void removeParticipant() throws Exception {

// 待移除节点API服务IP和端口
String nodeIp = "127.0.0.1";
String nodeApiPort = "12030";
// 账本信息
String ledgerHash = ledger.toString();
// 待移除节点地址
String participantAddress = "LdeNekdXMHqyz9Qxc2jDSBnkvvZLbty6pRDdP";
// 区块高度最新的节点API服务IP和端口,用于区块同步
String syncNodeHost = "127.0.0.1";
String syncNodePort = "12000";

// 发送POST请求执行节点移除操作
HttpPost httpPost = new HttpPost(String.format("http://%s:%s/management/delegate/deactiveparticipant", nodeIp, nodeApiPort));
List<BasicNameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("ledgerHash", ledgerHash));
params.add(new BasicNameValuePair("participantAddress", participantAddress));
params.add(new BasicNameValuePair("remoteManageHost", syncNodeHost));
params.add(new BasicNameValuePair("remoteManagePort", syncNodePort));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpClient httpClient = HttpClients.createDefault();
HttpResponse response = httpClient.execute(httpPost);
JsonResponseConverter jsonConverter = new JsonResponseConverter(WebResponse.class);

WebResponse webResponse = (WebResponse) jsonConverter.getResponse(null, response.getEntity().getContent(), null);
Assert.assertTrue(webResponse.isSuccess());
}

}

+ 0
- 848
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java View File

@@ -1,848 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.contract.OnLineContractProcessor;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.ConsensusSettingsUpdateOperation;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.ledger.ContractInfo;
import com.jd.blockchain.ledger.DataAccountInfo;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.Event;
import com.jd.blockchain.ledger.EventAccountRegisterOperation;
import com.jd.blockchain.ledger.EventPublishOperation;
import com.jd.blockchain.ledger.KVDataVO;
import com.jd.blockchain.ledger.KVInfoVO;
import com.jd.blockchain.ledger.LedgerAdminInfo;
import com.jd.blockchain.ledger.LedgerBlock;
import com.jd.blockchain.ledger.LedgerInfo;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerMetadata;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.LedgerTransaction;
import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.ParticipantRegisterOperation;
import com.jd.blockchain.ledger.PrivilegeSet;
import com.jd.blockchain.ledger.RolesConfigureOperation;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionResult;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.TypedKVEntry;
import com.jd.blockchain.ledger.UserAuthorizeOperation;
import com.jd.blockchain.ledger.UserInfo;
import com.jd.blockchain.ledger.UserPrivilegeSet;
import com.jd.blockchain.ledger.UserRegisterOperation;
import org.junit.Assert;
import org.junit.Test;
import utils.Property;
import utils.codec.Base58Utils;
import utils.io.BytesUtils;

import java.util.Arrays;

/**
* 查询样例
*/
public class QuerySample extends SampleBase {

HashDigest sampleHash = Crypto.resolveAsHashDigest(Base58Utils.decode("j5sTuEAWmLWKFwXgpdUCxbQN1XmZfkQdC94UT2AqQEt7hp"));
String sampleUserAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye";
String sampleDataAccountAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye";
String sampleContractAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye";
String sampleEventAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye";
String sampleKey = "sample-key";
String sampleEvent = "sample-event";
long sampleVersion = 0;
String sampleRoleName = "SAMPLE-ROLE";

/**
* 查询账本列表
*/
@Test
public void getLedgerHashs() {
HashDigest[] digests = blockchainService.getLedgerHashs();
for (HashDigest digest : digests) {
System.out.println(digest);
}
}

/**
* 查询账本信息,区块hash,区块高度
*/
@Test
public void getLedger() {
LedgerInfo ledgerInfo = blockchainService.getLedger(ledger);
// 账本哈希
System.out.println(ledgerInfo.getHash());
// 最新区块哈希
System.out.println(ledgerInfo.getLatestBlockHash());
// 最新区块高度
System.out.println(ledgerInfo.getLatestBlockHeight());
}

/**
* 查询账本信息,元数据,参与方,账本配置等
*/
@Test
public void getLedgerAdminInfo() {
LedgerAdminInfo adminInfo = blockchainService.getLedgerAdminInfo(ledger);
System.out.println(adminInfo.getParticipantCount());
}

/**
* 查询共识参与方
*/
@Test
public void getConsensusParticipants() {
ParticipantNode[] nodes = blockchainService.getConsensusParticipants(ledger);
for (ParticipantNode node : nodes) {
System.out.println("ID: " + node.getId());
System.out.println("Address: " + node.getAddress().toString());
System.out.println("PubKey: " + node.getPubKey().toString());
System.out.println("State: " + node.getParticipantNodeState());
}
}

/**
* 查询账本的元数据
*/
@Test
public void getLedgerMetadata() {
LedgerMetadata metadata = blockchainService.getLedgerMetadata(ledger);
System.out.println(Base58Utils.encode(metadata.getSeed()));
System.out.println(metadata.getParticipantsHash().toBase58());
System.out.println(metadata.getSettingsHash().toBase58());
}

/**
* 根据高度查询区块
*/
@Test
public void getBlockByHeight() {
LedgerBlock block1 = blockchainService.getBlock(ledger, -1);
// 账本哈希
System.out.println(block1.getLedgerHash());
// 区块高度
System.out.println(block1.getHeight());
// 区块时间
System.out.println(block1.getTimestamp());
// 区块哈希
System.out.println(block1.getHash());
// 上一区块哈希
System.out.println(block1.getPreviousHash());
// 交易数据集根哈希
System.out.println(block1.getTransactionSetHash());
// 用户角色权限数据集根哈希
System.out.println(block1.getAdminAccountHash());
// 合约数据集根哈希
System.out.println(block1.getContractAccountSetHash());
// 数据账户集根哈希
System.out.println(block1.getDataAccountSetHash());
// 系统时间集根哈希
System.out.println(block1.getSystemEventSetHash());
// 用户账户集根哈希
System.out.println(block1.getUserAccountSetHash());
// 用户事件账户根哈希
System.out.println(block1.getUserEventSetHash());

LedgerBlock block2 = blockchainService.getBlock(ledger, Integer.MAX_VALUE);
Assert.assertNotNull(block1);
Assert.assertEquals(block1.getHash(), block2.getHash());
LedgerBlock block3 = blockchainService.getBlock(ledger, 0);
Assert.assertTrue(block1.getHeight() >= block3.getHeight());
}

/**
* 根据hash查询区块
*/
@Test
public void getBlockByHash() {
LedgerBlock block = blockchainService.getBlock(ledger, sampleHash);
Assert.assertNull(block);
}

/**
* 查询某一高度(包括)之前所有交易数
*/
@Test
public void getTransactionCountByHeight() {
long count = blockchainService.getTransactionCount(ledger, -1);
Assert.assertEquals(0, count);
count = blockchainService.getTransactionCount(ledger, 1);
Assert.assertNotEquals(0, count);
}

/**
* 查询某一区块(包括)之前所有交易数
*/
@Test
public void getTransactionCountByHash() {
long count = blockchainService.getTransactionCount(ledger, sampleHash);
Assert.assertEquals(0, count);
}

/**
* 查询交易总数
*/
@Test
public void getTransactionTotalCount() {
long count = blockchainService.getTransactionTotalCount(ledger);
Assert.assertNotEquals(0, count);
}

/**
* 查询某一高度(包括)之前数据账户数
*/
@Test
public void getDataAccountCountByHeight() {
long count = blockchainService.getDataAccountCount(ledger, 0);
Assert.assertEquals(0, count);
}

/**
* 查询某一区块(包括)之前数据账户数
*/
@Test
public void getDataAccountCountByHash() {
long count = blockchainService.getDataAccountCount(ledger, sampleHash);
Assert.assertEquals(0, count);
}

/**
* 查询数据账户总数
*/
@Test
public void getDataAccountTotalCount() {
long count = blockchainService.getDataAccountTotalCount(ledger);
System.out.println("Total DataAccount count: " + count);
}

/**
* 查询某一高度(包括)之前用户数
*/
@Test
public void getUserCountByHeight() {
long count = blockchainService.getUserCount(ledger, 0);
Assert.assertEquals(4, count);
}

/**
* 查询某一区块(包括)之前用户数
*/
@Test
public void getUserCountByHash() {
long count = blockchainService.getUserCount(ledger, sampleHash);
Assert.assertEquals(0, count);
}

/**
* 查询用户总数
*/
@Test
public void getUserTotalCount() {
long count = blockchainService.getUserTotalCount(ledger);
System.out.println("Total User count: " + count);
}

/**
* 查询某一高度(包括)之前合约数
*/
@Test
public void getContractCountByHeight() {
long count = blockchainService.getContractCount(ledger, 0);
Assert.assertEquals(0, count);
}

/**
* 查询某一区块(包括)之前合约数
*/
@Test
public void getContractCountByHash() {
long count = blockchainService.getContractCount(ledger, sampleHash);
Assert.assertEquals(0, count);
}

/**
* 查询合约总数
*/
@Test
public void getContractTotalCount() {
long count = blockchainService.getContractTotalCount(ledger);
System.out.println("Total Contract count: " + count);
}

/**
* 分页查询交易某一高度(包括)之前的所有交易
*/
@Test
public void getTransactionsByHeight() {
LedgerTransaction[] txs = blockchainService.getTransactions(ledger, 0, 0, 1);
Assert.assertEquals(1, txs.length);
}

/**
* 分页查询交易某一区块(包括)之前的所有交易
*/
@Test
public void getTransactionsByHash() {
LedgerTransaction[] txs = blockchainService.getTransactions(ledger,
sampleHash, 0, 1);
Assert.assertNull(txs);
}

/**
* 分页查询某一高度中的交易
*/
@Test
public void getAdditionalTransactionsByHeight() {
LedgerTransaction[] txs = blockchainService.getAdditionalTransactions(ledger, 0, 0, 1);
Assert.assertEquals(1, txs.length);
for (LedgerTransaction tx : txs) {
/**
* 交易执行结果
*/
TransactionResult result = tx.getResult();
// 交易最终状态
System.out.println(result.getExecutionState());
// 交易所在区块高度
System.out.println(result.getBlockHeight());
/**
* 交易请求解析
*/
TransactionRequest request = tx.getRequest();
// 交易哈希
System.out.println(request.getTransactionHash());
// 终端用户签名信息
DigitalSignature[] endpointSignatures = request.getEndpointSignatures();
for (DigitalSignature signature : endpointSignatures) {
// 签名
System.out.println(signature.getDigest());
// 公钥
System.out.println(signature.getPubKey());
}
// 网关签名信息
DigitalSignature[] nodeSignatures = request.getNodeSignatures();
for (DigitalSignature signature : nodeSignatures) {
// 签名
System.out.println(signature.getDigest());
// 公钥
System.out.println(signature.getPubKey());
}
// 请求内容
TransactionContent transactionContent = request.getTransactionContent();
transactionContent.getTimestamp(); // 请求时间(客户端提交上来的时间)
Operation[] operations = transactionContent.getOperations(); // 操作列表
for (Operation operation : operations) {
if (operation instanceof UserRegisterOperation) { // 注册用户
UserRegisterOperation userRegisterOperation = (UserRegisterOperation) operation;
// 地址
System.out.println(userRegisterOperation.getUserID().getAddress());
//公钥
System.out.println(userRegisterOperation.getUserID().getPubKey());
} else if (operation instanceof DataAccountRegisterOperation) { // 注册数据账户
DataAccountRegisterOperation dataAccountRegisterOperation = (DataAccountRegisterOperation) operation;
// 地址
System.out.println(dataAccountRegisterOperation.getAccountID().getAddress());
// 公钥
System.out.println(dataAccountRegisterOperation.getAccountID().getPubKey());
} else if (operation instanceof ContractCodeDeployOperation) { // 部署合约
ContractCodeDeployOperation contractCodeDeployOperation = (ContractCodeDeployOperation) operation;
// 地址
System.out.println(contractCodeDeployOperation.getContractID().getAddress());
// 公钥
System.out.println(contractCodeDeployOperation.getContractID().getPubKey());
// 合约代码
System.out.println(OnLineContractProcessor.getInstance().decompileEntranceClass(contractCodeDeployOperation.getChainCode()));
// 合约版本
System.out.println(contractCodeDeployOperation.getChainCodeVersion());
} else if (operation instanceof EventAccountRegisterOperation) { // 注册事件账户
EventAccountRegisterOperation eventAccountRegisterOperation = (EventAccountRegisterOperation) operation;
// 地址
System.out.println(eventAccountRegisterOperation.getEventAccountID().getAddress());
// 公钥
System.out.println(eventAccountRegisterOperation.getEventAccountID().getPubKey());
} else if (operation instanceof DataAccountKVSetOperation) { // 写入kv
DataAccountKVSetOperation kvSetOperation = (DataAccountKVSetOperation) operation;
// 数据账户地址
System.out.println(kvSetOperation.getAccountAddress());
// 写入kv数据
DataAccountKVSetOperation.KVWriteEntry[] kvs = kvSetOperation.getWriteSet();
for (DataAccountKVSetOperation.KVWriteEntry kv : kvs) {
// key
System.out.println(kv.getKey());
// 预期的上一个数据版本
System.out.println(kv.getExpectedVersion());
// value
BytesValue value = kv.getValue();
switch (value.getType()) {
case TEXT:
case XML:
case JSON:
System.out.println(value.getBytes().toString());
break;
case INT64:
case TIMESTAMP:
System.out.println(BytesUtils.toLong(value.getBytes().toBytes()));
break;
default: // byte[], Bytes, IMG
System.out.println(value.getBytes());
break;
}
}
} else if (operation instanceof ContractEventSendOperation) { // 调用合约
ContractEventSendOperation contractEventSendOperation = (ContractEventSendOperation) operation;
// 合约地址
System.out.println(contractEventSendOperation.getContractAddress());
// 合约方法
System.out.println(contractEventSendOperation.getEvent());
// 合约参数
for (BytesValue arg : contractEventSendOperation.getArgs().getValues()) {
switch (arg.getType()) {
case TEXT:
System.out.println(BytesUtils.toString(arg.getBytes().toBytes()));
break;
case INT64:
System.out.println(BytesUtils.toLong(arg.getBytes().toBytes()));
break;
case BOOLEAN:
System.out.println(BytesUtils.toBoolean(arg.getBytes().toBytes()[0]));
break;
case BYTES:
System.out.println(arg.getBytes().toBytes());
default:
break;
}
}
} else if (operation instanceof EventPublishOperation) { // 发布事件
EventPublishOperation eventPublishOperation = (EventPublishOperation) operation;
// 事件账户地址
System.out.println(eventPublishOperation.getEventAddress());
// 数据
EventPublishOperation.EventEntry[] events = eventPublishOperation.getEvents();
for (EventPublishOperation.EventEntry event : events) {
// topic
System.out.println(event.getName());
// 预期的上一个数据序列
System.out.println(event.getSequence());
// 内容
BytesValue value = event.getContent();
switch (value.getType()) {
case TEXT:
case XML:
case JSON:
System.out.println(value.getBytes().toString());
break;
case INT64:
case TIMESTAMP:
System.out.println(BytesUtils.toLong(value.getBytes().toBytes()));
break;
default: // byte[], Bytes, IMG
System.out.println(value.getBytes());
break;
}
}
} else if (operation instanceof ConsensusSettingsUpdateOperation) { // 更新共识信息
ConsensusSettingsUpdateOperation consensusSettingsUpdateOperation = (ConsensusSettingsUpdateOperation) operation;
Property[] properties = consensusSettingsUpdateOperation.getProperties();
for (Property property : properties) {
System.out.println(property.getName());
System.out.println(property.getValue());
}
} else if (operation instanceof LedgerInitOperation) { // 账本初始化
LedgerInitOperation ledgerInitOperation = (LedgerInitOperation) operation;
// 共识参与方的列表
ledgerInitOperation.getInitSetting().getConsensusParticipants();
// 密码算法配置
ledgerInitOperation.getInitSetting().getCryptoSetting();
// 账本的种子
ledgerInitOperation.getInitSetting().getLedgerSeed();
// ...
} else if (operation instanceof ParticipantRegisterOperation) { // 注册参与方
ParticipantRegisterOperation participantRegisterOperation = (ParticipantRegisterOperation) operation;
// 参与方地址
System.out.println(participantRegisterOperation.getParticipantID().getAddress());
// 参与方公钥
System.out.println(participantRegisterOperation.getParticipantID().getPubKey());
// 参与方名称
System.out.println(participantRegisterOperation.getParticipantName());
} else if (operation instanceof RolesConfigureOperation) { // 角色配置
RolesConfigureOperation rolesConfigureOperation = (RolesConfigureOperation) operation;
// 角色列表
RolesConfigureOperation.RolePrivilegeEntry[] roles = rolesConfigureOperation.getRoles();
for (RolesConfigureOperation.RolePrivilegeEntry role : roles) {
// 角色名称
System.out.println(role.getRoleName());
// 拥有的账本权限
System.out.println(Arrays.toString(role.getEnableLedgerPermissions()));
// 禁止的账本权限
System.out.println(Arrays.toString(role.getDisableLedgerPermissions()));
// 拥有的交易权限
System.out.println(Arrays.toString(role.getEnableTransactionPermissions()));
// 禁止的交易权限
System.out.println(Arrays.toString(role.getDisableTransactionPermissions()));
}
} else if (operation instanceof UserAuthorizeOperation) { // 权限配置
UserAuthorizeOperation userAuthorizeOperation = (UserAuthorizeOperation) operation;
// 用户角色
UserAuthorizeOperation.UserRolesEntry[] userRoles = userAuthorizeOperation.getUserRolesAuthorizations();
for (UserAuthorizeOperation.UserRolesEntry userRole : userRoles) {
// 用户地址
System.out.println(Arrays.toString(userRole.getUserAddresses()));
// 多角色权限策略
System.out.println(userRole.getPolicy());
// 授权的角色清单
System.out.println(Arrays.toString(userRole.getAuthorizedRoles()));
// 取消授权的角色清单
System.out.println(Arrays.toString(userRole.getUnauthorizedRoles()));
}
} else {
System.out.println("todo");
}
}
}
}

/**
* 分页查询某一区块中的交易
*/
@Test
public void getAdditionalTransactionsByHash() {
LedgerTransaction[] txs = blockchainService.getAdditionalTransactions(ledger, sampleHash, 0, 1);
Assert.assertNull(txs);
}

/**
* 根据交易hash查询交易详情
*/
@Test
public void getTransactionByContentHash() {
LedgerTransaction tx = blockchainService.getTransactionByContentHash(ledger, sampleHash);
Assert.assertNull(tx);
}

/**
* 根据交易hash查询交易状态
*/
@Test
public void getTransactionStateByContentHash() {
TransactionState state = blockchainService.getTransactionStateByContentHash(ledger, sampleHash);
Assert.assertNull(state);
}

/**
* 根据地址查询用户信息
*/
@Test
public void getUser() {
UserInfo user = blockchainService.getUser(ledger, sampleUserAddress);
if (null != user) {
System.out.println(user.getAddress().toString());
}
}

/**
* 根据地址查询数据账户
*/
@Test
public void getDataAccount() {
DataAccountInfo dataAccount = blockchainService.getDataAccount(ledger, sampleDataAccountAddress);
if (null != dataAccount) {
System.out.println(dataAccount.getAddress().toString());
}
}

/**
* 根据地址和键查询KV信息(只包含最高数据版本)
*/
@Test
public void getDataEntriesByKey() {
TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, sampleKey);
for (TypedKVEntry kv : kvs) {
System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue());
}
}

/**
* 根据地址和指定键及数据版本查询KV信息
*/
@Test
public void getDataEntriesWithKeyAndVersion() {
TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, new KVInfoVO(new KVDataVO[]{new KVDataVO(sampleKey, new long[]{0})}));
for (TypedKVEntry kv : kvs) {
System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue());
}
}

/**
* 查询数据账户KV总数
*/
@Test
public void getDataEntriesTotalCount() {
long count = blockchainService.getDataEntriesTotalCount(ledger, sampleDataAccountAddress);
System.out.println(count);
}

/**
* 分页查询指定数据账户KV数据
*/
@Test
public void getDataEntries() {
TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, 0, 1);
for (TypedKVEntry kv : kvs) {
System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue());
}
}

/**
* 查询合约信息
*/
@Test
public void getContract() {
ContractInfo contract = blockchainService.getContract(ledger, sampleContractAddress);
if (null != contract) {
// 合约地址
System.out.println(contract.getAddress());
// 合约代码
System.out.println(BytesUtils.toString(contract.getChainCode()));
System.out.println(OnLineContractProcessor.getInstance().decompileEntranceClass(contract.getChainCode()));
}
}

/**
* 分页查询指定系统事件名下所有消息
*/
@Test
public void getSystemEvents() {
Event[] events = blockchainService.getSystemEvents(ledger, sampleEvent, 0, 1);
Assert.assertTrue(null == events || events.length == 0);
}

/**
* 查询系统事件名总数
*/
@Test
public void getSystemEventNameTotalCount() {
long count = blockchainService.getSystemEventNameTotalCount(ledger);
Assert.assertEquals(0, count);
}

/**
* 分页查询系统事件名
*/
@Test
public void getSystemEventNames() {
String[] names = blockchainService.getSystemEventNames(ledger, 0, 1);
Assert.assertEquals(0, names.length);
}

/**
* 查询指定系统事件名最新事件
*/
@Test
public void getLatestEvent() {
Event event = blockchainService.getLatestSystemEvent(ledger, sampleEvent);
Assert.assertNull(event);
}

/**
* 获取指定系统事件名下所有事件
*/
@Test
public void getSystemEventsTotalCount() {
long count = blockchainService.getSystemEventsTotalCount(ledger, sampleEvent);
Assert.assertEquals(0, count);
}

/**
* 分页查询用户事件账户
*
* @return
*/
@Test
public void getUserEventAccounts() {
BlockchainIdentity[] ids = blockchainService.getUserEventAccounts(ledger, 0, 1);
System.out.println(ids.length);
}

/**
* 获取用户事件账户
*/
@Test
public void getUserEventAccount() {
BlockchainIdentity id = blockchainService.getUserEventAccount(ledger, sampleEventAddress);
if (null != id) {
System.out.println(id.getAddress().toString());
}
}

/**
* 获取用户事件账户总数
*/
@Test
public void getUserEventAccountTotalCount() {
long count = blockchainService.getUserEventAccountTotalCount(ledger);
System.out.println(count);
}

/**
* 获取指定用户事件账户下事件名数
*/
@Test
public void getUserEventNameTotalCount() {
long count = blockchainService.getUserEventNameTotalCount(ledger, sampleEventAddress);
System.out.println(count);
}

/**
* 分页查询指定用户事件账户下事件名
*/
@Test
public void getUserEventNames() {
String[] names = blockchainService.getUserEventNames(ledger, sampleEventAddress, 0, 1);
for (String name : names) {
System.out.println(name);
}
}

/**
* 获取指定用户事件账户指定事件名下最新事件
*/
@Test
public void getLatestUserEvent() {
Event event = blockchainService.getLatestUserEvent(ledger, sampleEventAddress, sampleEvent);
if (null != event) {
BytesValue content = event.getContent();
switch (content.getType()) {
case TEXT:
case XML:
case JSON:
System.out.println(event.getName() + ":" + event.getSequence() + ":" + content.getBytes().toUTF8String());
break;
case INT64:
case TIMESTAMP:
System.out.println(event.getName() + ":" + event.getSequence() + ":" + BytesUtils.toLong(content.getBytes().toBytes()));
break;
default: // byte[], Bytes
System.out.println(event.getName() + ":" + event.getSequence() + ":" + content.getBytes().toBase58());
break;
}
}
}

/**
* 获取指定用户事件账户指定事件名下事件总数
*/
@Test
public void getUserEventsTotalCount() {
long count = blockchainService.getUserEventsTotalCount(ledger, sampleEventAddress, sampleEvent);
System.out.println(count);
}

/**
* 分页查询指定用户事件账户指定事件名下事件
*/
@Test
public void getUserEvents() {
Event[] events = blockchainService.getUserEvents(ledger, sampleEventAddress, sampleEvent, 0, 1);
for (Event event : events) {
BytesValue content = event.getContent();
switch (content.getType()) {
case TEXT:
case XML:
case JSON:
System.out.println(event.getName() + ":" + event.getSequence() + ":" + content.getBytes().toUTF8String());
break;
case INT64:
case TIMESTAMP:
System.out.println(event.getName() + ":" + event.getSequence() + ":" + BytesUtils.toLong(content.getBytes().toBytes()));
break;
default: // byte[], Bytes
System.out.println(event.getName() + ":" + event.getSequence() + ":" + content.getBytes().toBase58());
break;
}
}
}

/**
* 获取指定版本合约
*/
@Test
public void getContractByAddressAndVersion() {
ContractInfo contract = blockchainService.getContract(ledger, sampleContractAddress, sampleVersion);
if (null != contract) {
System.out.println(contract.getAddress().toString());
System.out.println(contract.getChainCodeVersion());
System.out.println(OnLineContractProcessor.getInstance().decompileEntranceClass(contract.getChainCode()));
}
}

/**
* 分页查询用户
*/
@Test
public void getUsers() {
BlockchainIdentity[] ids = blockchainService.getUsers(ledger, 0, 1);
Assert.assertEquals(1, ids.length);
}

/**
* 分页查询数据账户
*/
@Test
public void getDataAccounts() {
BlockchainIdentity[] ids = blockchainService.getDataAccounts(ledger, 0, 1);
System.out.println(ids.length);
}

/**
* 分页查询合约账户
*/
@Test
public void getContractAccounts() {
BlockchainIdentity[] ids = blockchainService.getContractAccounts(ledger, 0, 1);
System.out.println(ids.length);
}

/**
* 查询指定角色权限信息
*/
@Test
public void getRolePrivileges() {
PrivilegeSet privilegeSet = blockchainService.getRolePrivileges(ledger, sampleRoleName);
if (null != privilegeSet) {
for (LedgerPermission ledgerpermission : privilegeSet.getLedgerPrivilege().getPrivilege()) {
System.out.println(ledgerpermission);
}
for (TransactionPermission transactionPermission : privilegeSet.getTransactionPrivilege().getPrivilege()) {
System.out.println(transactionPermission);
}
}
}

/**
* 查询指定用户权限信息
*/
@Test
public void getUserPrivileges() {
UserPrivilegeSet userPrivileges = blockchainService.getUserPrivileges(ledger, sampleUserAddress);
if (null != userPrivileges) {
for (String role : userPrivileges.getUserRole()) {
System.out.println(role);
}
for (LedgerPermission ledgerpermission : userPrivileges.getLedgerPrivilegesBitset().getPrivilege()) {
System.out.println(ledgerpermission);
}
for (TransactionPermission transactionPermission : userPrivileges.getTransactionPrivilegesBitset().getPrivilege()) {
System.out.println(transactionPermission);
}
}
}
}

+ 0
- 63
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/SampleBase.java View File

@@ -1,63 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.client.GatewayServiceFactory;

import utils.codec.Base58Utils;

import java.util.Properties;

public class SampleBase {

// 交易签名用户
protected static BlockchainKeypair userKey;
// 网关IP
protected static String gatewayHost;
// 网关端口
protected static int gatewayPort;
// 账本Hash
protected static HashDigest ledger;
// 区块链服务
protected static BlockchainService blockchainService;

static {
try {
// 读取配置文件
Properties properties = new Properties();
properties.load(SampleBase.class.getClassLoader().getResourceAsStream("config.properties"));

// 初始配置交易签名用户信息
PubKey pubKey = KeyGenUtils.decodePubKey(properties.getProperty("pubkey"));
PrivKey privKey = KeyGenUtils.decodePrivKey(properties.getProperty("privkey"), properties.getProperty("password"));
userKey = new BlockchainKeypair(pubKey, privKey);

// 读取网关配置
gatewayHost = properties.getProperty("gateway.host");
gatewayPort = Integer.parseInt(properties.getProperty("gateway.port"));

// 读取账本配置
String ledgerHash = properties.getProperty("ledger");

// 初始化区块链服务
// 此处传入 签名账户 会在提交交易前自动加上此用户的签名信息
// 此处不传入 签名账户 的话需要提交交易前手动调用签名操作,需要至少加入一个终端用户签名
blockchainService = GatewayServiceFactory.connect(gatewayHost, gatewayPort, false, userKey).getBlockchainService();

// 初始配置账本,从配置文件中读取,未设置获取账本列表第一个
if (!ledgerHash.isEmpty()) {
ledger = Crypto.resolveAsHashDigest(Base58Utils.decode(ledgerHash));
} else {
ledger = blockchainService.getLedgerHashs()[0];
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

+ 0
- 120
samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/UserSample.java View File

@@ -1,120 +0,0 @@
package com.jdchain.samples.sdk;

import com.jd.blockchain.ledger.AccountState;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import org.junit.Assert;
import org.junit.Test;
import utils.Bytes;

/**
* 用户账户相关操作示例:
* 用户注册,角色创建,权限设置
*/
public class UserSample extends SampleBase {

/**
* 注册用户
*/
@Test
public void registerUser() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成用户
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
System.out.println("用户地址:" + user.getAddress());
// 注册用户
txTemp.users().register(user.getIdentity());
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 创建角色
*/
@Test
public void createRole() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);

// 创建角色 MANAGER ,并设置可以写数据账户,能执行交易
txTemp.security().roles().configure("MANAGER")
.enable(LedgerPermission.WRITE_DATA_ACCOUNT)
.enable(TransactionPermission.DIRECT_OPERATION);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 配置角色权限
*/
@Test
public void configUserRole() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);

// 给用户设置 MANAGER 角色权限
txTemp.security().authorziations().forUser(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye")).authorize("MANAGER");
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 注册用户的同时配置角色权限,同一事务内
*/
@Test
public void testRegisterUserAndConfigRole() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 生成用户
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate();
System.out.println("用户地址:" + user.getAddress());
// 注册用户
txTemp.users().register(user.getIdentity());

// 创建角色 MANAGER
txTemp.security().roles().configure("MANAGER")
.enable(LedgerPermission.WRITE_DATA_ACCOUNT)
.enable(TransactionPermission.DIRECT_OPERATION);

// 设置用户角色权限
txTemp.security().authorziations().forUser(user.getAddress()).authorize("MANAGER");

// 交易主恩贝
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}

/**
* 更新用户状态
*/
@Test
public void updateUserState() {
// 新建交易
TransactionTemplate txTemp = blockchainService.newTransaction(ledger);
// 用户(证书)状态分为:NORMAL(正常) FREEZE(冻结) REVOKE(销毁)
// 冻结用户(证书)
txTemp.user("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye").state(AccountState.FREEZE);
// 交易准备
PreparedTransaction ptx = txTemp.prepare();
// 提交交易
TransactionResponse response = ptx.commit();
Assert.assertTrue(response.isSuccess());
}
}

Loading…
Cancel
Save