@@ -12,14 +12,17 @@ | |||
<fileSet> | |||
<directory>src/main/resources/scripts</directory> | |||
<outputDirectory>bin</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
<fileSet> | |||
<directory>src/main/resources/config</directory> | |||
<outputDirectory>config</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
<fileSet> | |||
<directory>src/main/resources/docs</directory> | |||
<outputDirectory>docs</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
</fileSets> | |||
<dependencySets> | |||
@@ -1808,6 +1808,57 @@ http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/ | |||
|type|value类型| | |||
|value|值| | |||
### 6.9 查询某数据账户键数量 | |||
``` | |||
GET /ledgers/{ledger}/accounts/address/{address}/keys/count/search?keyword={keyword} | |||
``` | |||
#### 参数 | |||
请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | |||
--- | --- | --- | --- | --- | |||
path | ledger | 是 | 所要搜索的账本,需要完整的账本哈希 | string | |||
path | address | 是 | 所要搜索的数据账户地址,需要完整的数据账户地址 | string | |||
query | keyword | 否 | 键的部分字符,空表示全部 | string | |||
#### 请求实例 | |||
``` | |||
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/count/search?keyword=j | |||
``` | |||
#### 返回实例 | |||
``` | |||
{ "data": 66, "success": true } | |||
``` | |||
说明 | |||
名称 | 说明 | |||
--- | --- | |||
data | 条件查询键总数 | |||
### 6.10 查询某数据账户键 | |||
``` | |||
GET /ledgers/{ledger}/accounts/address/{address}/keys/search?keyword={keyword}&fromIndex={start_index}&count={count} | |||
``` | |||
#### 参数 | |||
请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | |||
--- | --- | --- | --- | --- | |||
path | ledger | 是 | 所要搜索的账本,需要完整的账本哈希 | string | |||
path | address | 是 | 所要搜索的数据账户地址,需要完整的数据账户地址 | string | |||
query | keyword | 否 | 键的部分字符,空表示全部 | string | |||
query | start_index | 否 | 查询数据账户对应Key的起始序号,默认为0 | 数字 | |||
query | count | 否 | 查询返回数据账户对应Key的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集 | 数字 | |||
#### 请求实例 | |||
``` | |||
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/search?keyword=j&fromIndex=0&count=-1 | |||
``` | |||
#### 返回实例 | |||
``` | |||
{ "data": [ { "key": "jd" }, { "key": "jdchain" }], "success": true } | |||
``` | |||
说明 | |||
名称 | 说明 | |||
--- | --- | |||
key | 键 | |||
## 7 搜索 | |||
@@ -12,14 +12,17 @@ | |||
<fileSet> | |||
<directory>src/main/resources/scripts</directory> | |||
<outputDirectory>bin</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
<fileSet> | |||
<directory>src/main/resources/config</directory> | |||
<outputDirectory>config</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
<fileSet> | |||
<directory>src/main/resources/docs</directory> | |||
<outputDirectory>docs</outputDirectory> | |||
<lineEnding>unix</lineEnding> | |||
</fileSet> | |||
</fileSets> | |||
<dependencySets> | |||
@@ -1,129 +1,129 @@ | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.binaryproto.EnumContract; | |||
import com.jd.blockchain.binaryproto.EnumField; | |||
import com.jd.blockchain.consts.DataCodes; | |||
/** | |||
* 交易(事务)执行状态; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@EnumContract(code = DataCodes.ENUM_TYPE_TRANSACTION_STATE) | |||
public enum TransactionState { | |||
/** | |||
* 成功; | |||
*/ | |||
SUCCESS((byte) 0), | |||
/** | |||
* 账本错误; | |||
*/ | |||
LEDGER_ERROR((byte) 0x01), | |||
/** | |||
* 数据账户不存在; | |||
*/ | |||
DATA_ACCOUNT_DOES_NOT_EXIST((byte) 0x02), | |||
/** | |||
* 用户不存在; | |||
*/ | |||
USER_DOES_NOT_EXIST((byte) 0x03), | |||
/** | |||
* 合约不存在; | |||
*/ | |||
CONTRACT_DOES_NOT_EXIST((byte) 0x04), | |||
/** | |||
* 数据写入时版本冲突; | |||
*/ | |||
DATA_VERSION_CONFLICT((byte) 0x05), | |||
/** | |||
* 参与方不存在; | |||
*/ | |||
PARTICIPANT_DOES_NOT_EXIST((byte) 0x05), | |||
/** | |||
* 被安全策略拒绝; | |||
*/ | |||
REJECTED_BY_SECURITY_POLICY((byte) 0x10), | |||
/** | |||
* 由于在错误的账本上执行交易而被丢弃; | |||
*/ | |||
IGNORED_BY_WRONG_LEDGER((byte) 0x40), | |||
/** | |||
* 由于交易内容的验签失败而丢弃; | |||
*/ | |||
IGNORED_BY_WRONG_CONTENT_SIGNATURE((byte) 0x41), | |||
/** | |||
* 由于交易内容的验签失败而丢弃; | |||
*/ | |||
IGNORED_BY_CONFLICTING_STATE((byte) 0x42), | |||
/** | |||
* 由于交易的整体回滚而丢弃; | |||
* <p> | |||
* | |||
* 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;<br> | |||
* “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;<br> | |||
*/ | |||
IGNORED_BY_TX_FULL_ROLLBACK((byte) 0x43), | |||
/** | |||
* 由于区块的整体回滚而丢弃; | |||
* <p> | |||
* | |||
* 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;<br> | |||
* | |||
* “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;<br> | |||
*/ | |||
IGNORED_BY_BLOCK_FULL_ROLLBACK((byte) 0x44), | |||
/** | |||
* | |||
* 共识阶段加入新区块哈希预计算功能, 如果来自其他Peer的新区块哈希值不一致,本批次整体回滚 | |||
* | |||
*/ | |||
IGNORED_BY_CONSENSUS_PHASE_PRECOMPUTE_ROLLBACK((byte) 0x45), | |||
/** | |||
* 系统错误; | |||
*/ | |||
SYSTEM_ERROR((byte) 0x80), | |||
/** | |||
* 超时; | |||
*/ | |||
TIMEOUT((byte) 0x81), | |||
/** | |||
* 共识错误; | |||
*/ | |||
CONSENSUS_ERROR((byte) 0x82); | |||
@EnumField(type = PrimitiveType.INT8) | |||
public final byte CODE; | |||
private TransactionState(byte code) { | |||
this.CODE = code; | |||
} | |||
public static TransactionState valueOf(byte code) { | |||
for (TransactionState tr : values()) { | |||
if (tr.CODE == code) { | |||
return tr; | |||
} | |||
} | |||
throw new IllegalArgumentException("Unsupported transaction result code!"); | |||
} | |||
} | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.binaryproto.EnumContract; | |||
import com.jd.blockchain.binaryproto.EnumField; | |||
import com.jd.blockchain.consts.DataCodes; | |||
/** | |||
* 交易(事务)执行状态; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@EnumContract(code = DataCodes.ENUM_TYPE_TRANSACTION_STATE) | |||
public enum TransactionState { | |||
/** | |||
* 成功; | |||
*/ | |||
SUCCESS((byte) 0), | |||
/** | |||
* 账本错误; | |||
*/ | |||
LEDGER_ERROR((byte) 0x01), | |||
/** | |||
* 数据账户不存在; | |||
*/ | |||
DATA_ACCOUNT_DOES_NOT_EXIST((byte) 0x02), | |||
/** | |||
* 用户不存在; | |||
*/ | |||
USER_DOES_NOT_EXIST((byte) 0x03), | |||
/** | |||
* 合约不存在; | |||
*/ | |||
CONTRACT_DOES_NOT_EXIST((byte) 0x04), | |||
/** | |||
* 数据写入时版本冲突; | |||
*/ | |||
DATA_VERSION_CONFLICT((byte) 0x05), | |||
/** | |||
* 参与方不存在; | |||
*/ | |||
PARTICIPANT_DOES_NOT_EXIST((byte) 0x06), | |||
/** | |||
* 被安全策略拒绝; | |||
*/ | |||
REJECTED_BY_SECURITY_POLICY((byte) 0x10), | |||
/** | |||
* 由于在错误的账本上执行交易而被丢弃; | |||
*/ | |||
IGNORED_BY_WRONG_LEDGER((byte) 0x40), | |||
/** | |||
* 由于交易内容的验签失败而丢弃; | |||
*/ | |||
IGNORED_BY_WRONG_CONTENT_SIGNATURE((byte) 0x41), | |||
/** | |||
* 由于交易内容的验签失败而丢弃; | |||
*/ | |||
IGNORED_BY_CONFLICTING_STATE((byte) 0x42), | |||
/** | |||
* 由于交易的整体回滚而丢弃; | |||
* <p> | |||
* | |||
* 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;<br> | |||
* “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;<br> | |||
*/ | |||
IGNORED_BY_TX_FULL_ROLLBACK((byte) 0x43), | |||
/** | |||
* 由于区块的整体回滚而丢弃; | |||
* <p> | |||
* | |||
* 注: “整体回滚”是指把交易引入的数据更改以及交易记录本身全部都回滚;<br> | |||
* | |||
* “部分回滚”是指把交易引入的数据更改回滚了,但是交易记录本身以及相应的“交易结果({@link TransactionState})”都会提交;<br> | |||
*/ | |||
IGNORED_BY_BLOCK_FULL_ROLLBACK((byte) 0x44), | |||
/** | |||
* | |||
* 共识阶段加入新区块哈希预计算功能, 如果来自其他Peer的新区块哈希值不一致,本批次整体回滚 | |||
* | |||
*/ | |||
IGNORED_BY_CONSENSUS_PHASE_PRECOMPUTE_ROLLBACK((byte) 0x45), | |||
/** | |||
* 系统错误; | |||
*/ | |||
SYSTEM_ERROR((byte) 0x80), | |||
/** | |||
* 超时; | |||
*/ | |||
TIMEOUT((byte) 0x81), | |||
/** | |||
* 共识错误; | |||
*/ | |||
CONSENSUS_ERROR((byte) 0x82); | |||
@EnumField(type = PrimitiveType.INT8) | |||
public final byte CODE; | |||
private TransactionState(byte code) { | |||
this.CODE = code; | |||
} | |||
public static TransactionState valueOf(byte code) { | |||
for (TransactionState tr : values()) { | |||
if (tr.CODE == code) { | |||
return tr; | |||
} | |||
} | |||
throw new IllegalArgumentException("Unsupported transaction result code!"); | |||
} | |||
} |
@@ -515,7 +515,63 @@ | |||
<javadoc.opts>-Xdoclint:none</javadoc.opts> | |||
</properties> | |||
</profile> | |||
<!-- mvn repository;--> | |||
<profile> | |||
<id>sonatype-oss-release</id> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-source-plugin</artifactId> | |||
<version>2.1.2</version> | |||
<executions> | |||
<execution> | |||
<id>attach-sources</id> | |||
<goals> | |||
<goal>jar-no-fork</goal> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-javadoc-plugin</artifactId> | |||
<version>2.7</version> | |||
<executions> | |||
<execution> | |||
<id>attach-javadocs</id> | |||
<goals> | |||
<goal>jar</goal> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-gpg-plugin</artifactId> | |||
<version>1.1</version> | |||
<executions> | |||
<execution> | |||
<id>sign-artifacts</id> | |||
<phase>verify</phase> | |||
<goals> | |||
<goal>sign</goal> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</profile> | |||
</profiles> | |||
<distributionManagement> | |||
<repository> | |||
<id>sonatype-nexus-staging</id> | |||
<name>Nexus Release Repository</name> | |||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> | |||
</repository> | |||
</distributionManagement> | |||
</project> |
@@ -71,7 +71,6 @@ public class GatewayServiceFactory implements BlockchainServiceFactory, Closeabl | |||
ByteArrayObjectUtil.init(); | |||
} | |||
protected GatewayServiceFactory(ServiceEndpoint gatewayEndpoint, BlockchainKeypair userKey) { | |||
httpConnectionManager = new ServiceConnectionManager(); | |||
this.userKey = userKey; | |||
@@ -80,7 +79,7 @@ public class GatewayServiceFactory implements BlockchainServiceFactory, Closeabl | |||
TransactionService txProcSrv = createConsensusService(gatewayEndpoint); | |||
this.blockchainService = new GatewayBlockchainServiceProxy(txProcSrv, queryService); | |||
} | |||
@Override | |||
public BlockchainService getBlockchainService() { | |||
return blockchainService; | |||
@@ -107,19 +106,49 @@ public class GatewayServiceFactory implements BlockchainServiceFactory, Closeabl | |||
// factory.setMaxConnections(100); | |||
// return factory; | |||
// } | |||
/** | |||
* 连接网关节点; | |||
* | |||
* @param gatewayAddress 网关节点的网络地址; | |||
* @return 网关服务工厂的实例; | |||
*/ | |||
public static GatewayServiceFactory connect(NetworkAddress gatewayAddress) { | |||
return connect(gatewayAddress.getHost(), gatewayAddress.getPort(), gatewayAddress.isSecure(), null); | |||
} | |||
/** | |||
* 网关服务工厂的实例; | |||
* | |||
* @param gatewayAddress 网关节点的网络地址; | |||
* @param userKey 自动交易签名的用户密钥;可选参数,如果不为 null,则在提交交易时,自动以参数指定的密钥签署交易; | |||
* @return 网关服务工厂的实例; | |||
*/ | |||
public static GatewayServiceFactory connect(NetworkAddress gatewayAddress, BlockchainKeypair userKey) { | |||
return connect(gatewayAddress.getHost(), gatewayAddress.getPort(), gatewayAddress.isSecure(), userKey); | |||
} | |||
/** | |||
* 连接网关节点; | |||
* | |||
* @param gatewayHost 网关节点的地址; | |||
* @param gatewayPort 网关节点的端口; | |||
* @param secure 是否采用安全的通讯协议(HTTPS); | |||
* @return 网关服务工厂的实例; | |||
*/ | |||
public static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure) { | |||
return connect(gatewayHost, gatewayPort, secure, null); | |||
} | |||
/** | |||
* 连接网关节点; | |||
* | |||
* @param gatewayHost 网关节点的地址; | |||
* @param gatewayPort 网关节点的端口; | |||
* @param secure 是否采用安全的通讯协议(HTTPS); | |||
* @param userKey 自动交易签名的用户密钥;可选参数,如果不为 null,则在提交交易时,自动以参数指定的密钥签署交易; | |||
* @return 网关服务工厂的实例; | |||
*/ | |||
public static GatewayServiceFactory connect(String gatewayHost, int gatewayPort, boolean secure, | |||
BlockchainKeypair userKey) { | |||
// if (userKey == null) { | |||
@@ -128,8 +157,8 @@ public class GatewayServiceFactory implements BlockchainServiceFactory, Closeabl | |||
ServiceEndpoint gatewayEndpoint = new ServiceEndpoint(gatewayHost, gatewayPort, secure); | |||
GatewayServiceFactory factory = new GatewayServiceFactory(gatewayEndpoint, userKey); | |||
factory.setMaxConnections(100); | |||
//TODO: 未实现网关对用户的认证; | |||
//TODO: 未实现加载不同账本的密码算法配置; | |||
// TODO: 未实现网关对用户的认证; | |||
// TODO: 未实现加载不同账本的密码算法配置; | |||
return factory; | |||
} | |||
@@ -171,7 +200,7 @@ public class GatewayServiceFactory implements BlockchainServiceFactory, Closeabl | |||
@Override | |||
public TransactionResponse process(TransactionRequest txRequest) { | |||
TxRequestMessage reqMsg = (TxRequestMessage) txRequest; | |||
//TODO: 未实现按不同的账本的密码参数配置,采用不同的哈希算法和签名算法; | |||
// TODO: 未实现按不同的账本的密码参数配置,采用不同的哈希算法和签名算法; | |||
if (!reqMsg.containsEndpointSignature(userKey.getAddress())) { | |||
// TODO: 优化上下文对此 TransactionContent 的多次序列化带来的额外性能开销; | |||
DigitalSignature signature = SignatureUtils.sign(txRequest.getTransactionContent(), userKey); | |||
@@ -53,6 +53,7 @@ public class LedgerInitializeWeb4Nodes { | |||
System.setProperty("peer.log", path); | |||
System.setProperty("init.log", path); | |||
System.setProperty("gateway.log", path); | |||
System.setProperty("jdchain.log", path); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||