| @@ -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(); | |||
| } | |||