Browse Source

all: LF;

tags/1.1.3
zhaoguangwei 4 years ago
parent
commit
58a19e473b
100 changed files with 7740 additions and 7740 deletions
  1. +66
    -66
      source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java
  2. +25
    -25
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ActionMessage.java
  3. +18
    -18
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ConsensusSecurityException.java
  4. +12
    -12
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ConsensusService.java
  5. +35
    -35
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/OrderedAction.java
  6. +22
    -22
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/UnorderedAction.java
  7. +49
    -49
      source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/action/ActionResponseData.java
  8. +18
    -18
      source/contract/pom.xml
  9. +65
    -65
      source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/AddressEncoding.java
  10. +24
    -24
      source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/AddressVersion.java
  11. +24
    -24
      source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoKey.java
  12. +28
    -28
      source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/PrivKey.java
  13. +14
    -14
      source/gateway/src/main/java/com/jd/blockchain/gateway/GatewayConfiguration.java
  14. +177
    -177
      source/gateway/src/main/java/com/jd/blockchain/gateway/GatewayServerBooter.java
  15. +17
    -17
      source/gateway/src/main/java/com/jd/blockchain/gateway/web/GatewayWebSecurityConfigurer.java
  16. +30
    -30
      source/gateway/src/main/resources/gateway.conf
  17. +31
    -31
      source/gateway/src/test/java/test/com/jd/blockchain/gateway/data/HashDigestDeserializer.java
  18. +27
    -27
      source/gateway/src/test/java/test/com/jd/blockchain/gateway/data/HashDigestSerializer.java
  19. +72
    -72
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java
  20. +130
    -130
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java
  21. +233
    -233
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java
  22. +112
    -112
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java
  23. +480
    -480
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminDataset.java
  24. +410
    -410
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java
  25. +739
    -739
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java
  26. +10
    -10
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Node.java
  27. +72
    -72
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java
  28. +21
    -21
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Peer.java
  29. +84
    -84
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java
  30. +120
    -120
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java
  31. +42
    -42
      source/ledger/ledger-model/pom.xml
  32. +14
    -14
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/Contract.java
  33. +14
    -14
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractEvent.java
  34. +15
    -15
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventHandle.java
  35. +33
    -33
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java
  36. +83
    -83
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainEventType.java
  37. +216
    -216
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainIdentityData.java
  38. +40
    -40
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainKeyGenerator.java
  39. +46
    -46
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainKeypair.java
  40. +23
    -23
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CodeDeployOperation.java
  41. +31
    -31
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractCodeDeployOperation.java
  42. +32
    -32
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountKVSetOperation.java
  43. +26
    -26
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountRegisterOperation.java
  44. +185
    -185
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java
  45. +27
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataVersionConflictException.java
  46. +15
    -15
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DigitalSignature.java
  47. +30
    -30
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/EndpointRequest.java
  48. +46
    -46
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashAlgorithm.java
  49. +37
    -37
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashObject.java
  50. +59
    -59
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Ledger.java
  51. +323
    -323
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerImpl.java
  52. +13
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerInitOperation.java
  53. +67
    -67
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MagicNumber.java
  54. +22
    -22
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/NodeRequest.java
  55. +27
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/OperationArgument.java
  56. +68
    -68
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java
  57. +39
    -39
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/RolesConfigureOperation.java
  58. +21
    -21
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/SignatureInfo.java
  59. +37
    -37
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/StateOpType.java
  60. +54
    -54
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java
  61. +51
    -51
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionBuilder.java
  62. +81
    -81
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRequestBuilder.java
  63. +67
    -67
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionResponse.java
  64. +16
    -16
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java
  65. +27
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionTemplate.java
  66. +57
    -57
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAuthorizeOperation.java
  67. +29
    -29
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfoSetOperation.java
  68. +13
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserRegisterOperation.java
  69. +26
    -26
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/setting/GatewayIncomingSetting.java
  70. +358
    -358
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
  71. +330
    -330
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java
  72. +41
    -41
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOpTemplate.java
  73. +19
    -19
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOperationBuilder.java
  74. +14
    -14
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOperationBuilderImpl.java
  75. +24
    -24
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilder.java
  76. +21
    -21
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java
  77. +44
    -44
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java
  78. +65
    -65
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java
  79. +151
    -151
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java
  80. +88
    -88
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java
  81. +34
    -34
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOpTemplate.java
  82. +14
    -14
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOperationBuilder.java
  83. +15
    -15
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOperationBuilderImpl.java
  84. +116
    -116
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DigitalSignatureBlob.java
  85. +26
    -26
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOpTemplate.java
  86. +17
    -17
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOperationBuilder.java
  87. +13
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOperationBuilderImpl.java
  88. +38
    -38
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/NewLedgerOpBlob.java
  89. +25
    -25
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java
  90. +30
    -30
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PubKeyData.java
  91. +139
    -139
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/RolesConfigureOpTemplate.java
  92. +19
    -19
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/SecurityOperationBuilder.java
  93. +27
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/SignatureEncoding.java
  94. +10
    -10
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TransactionService.java
  95. +106
    -106
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java
  96. +385
    -385
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestMessage.java
  97. +86
    -86
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java
  98. +111
    -111
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java
  99. +130
    -130
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorizeOpTemplate.java
  100. +27
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserRegisterOpTemplate.java

+ 66
- 66
source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/PrimitiveType.java View File

@@ -1,66 +1,66 @@
package com.jd.blockchain.binaryproto;
/**
* 键值操作的数据类型;
*
* @author huanghaiquan
*
*/
public enum PrimitiveType {
/**
* 空;
*/
NIL(BaseType.NIL),
/**
* 布尔型;
*/
BOOLEAN(BaseType.BOOLEAN),
/**
* 8位的整数:
*/
INT8(BaseType.INT8),
/**
* 16位整数;
*/
INT16(BaseType.INT16),
/**
* 32位整数;
*/
INT32(BaseType.INT32),
/**
* 64位整数;
*/
INT64(BaseType.INT64),
/**
* 文本;
*/
TEXT(BaseType.TEXT),
/**
* 二进制数据;
*/
BYTES(BaseType.BYTES);
public final byte CODE;
private PrimitiveType(byte code) {
this.CODE = code;
}
public static PrimitiveType valueOf(byte code) {
for (PrimitiveType dataType : PrimitiveType.values()) {
if (dataType.CODE == code) {
return dataType;
}
}
throw new IllegalArgumentException("Code[" + code + "] not suppported by PrimitiveType!");
}
}
package com.jd.blockchain.binaryproto;
/**
* 键值操作的数据类型;
*
* @author huanghaiquan
*
*/
public enum PrimitiveType {
/**
* 空;
*/
NIL(BaseType.NIL),
/**
* 布尔型;
*/
BOOLEAN(BaseType.BOOLEAN),
/**
* 8位的整数:
*/
INT8(BaseType.INT8),
/**
* 16位整数;
*/
INT16(BaseType.INT16),
/**
* 32位整数;
*/
INT32(BaseType.INT32),
/**
* 64位整数;
*/
INT64(BaseType.INT64),
/**
* 文本;
*/
TEXT(BaseType.TEXT),
/**
* 二进制数据;
*/
BYTES(BaseType.BYTES);
public final byte CODE;
private PrimitiveType(byte code) {
this.CODE = code;
}
public static PrimitiveType valueOf(byte code) {
for (PrimitiveType dataType : PrimitiveType.values()) {
if (dataType.CODE == code) {
return dataType;
}
}
throw new IllegalArgumentException("Code[" + code + "] not suppported by PrimitiveType!");
}
}

+ 25
- 25
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ActionMessage.java View File

@@ -1,25 +1,25 @@
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author huanghaiquan
*
*/
@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionMessage {
/**
* 请求参数转换器;
* <p>
* 指定一个 {@link BinaryMessageConverter} 接口的实现类;
*
* @return
*/
Class<?> converter();
}
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author huanghaiquan
*
*/
@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionMessage {
/**
* 请求参数转换器;
* <p>
* 指定一个 {@link BinaryMessageConverter} 接口的实现类;
*
* @return
*/
Class<?> converter();
}

+ 18
- 18
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ConsensusSecurityException.java View File

@@ -1,18 +1,18 @@
package com.jd.blockchain.consensus;
public class ConsensusSecurityException extends Exception{
private static final long serialVersionUID = -164820276123627155L;
public ConsensusSecurityException() {
}
public ConsensusSecurityException(String message) {
super(message);
}
public ConsensusSecurityException(String message, Throwable cause) {
super(message, cause);
}
}
package com.jd.blockchain.consensus;
public class ConsensusSecurityException extends Exception{
private static final long serialVersionUID = -164820276123627155L;
public ConsensusSecurityException() {
}
public ConsensusSecurityException(String message) {
super(message);
}
public ConsensusSecurityException(String message, Throwable cause) {
super(message, cause);
}
}

+ 12
- 12
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/ConsensusService.java View File

@@ -1,12 +1,12 @@
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ConsensusService {
}
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ConsensusService {
}

+ 35
- 35
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/OrderedAction.java View File

@@ -1,35 +1,35 @@
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标识一个共识方法调用模式为“有序的消息调用”;
*
* @author huanghaiquan
*
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface OrderedAction {
/**
* 请求分组的索引器;<br>
*
* 指定一个 {@link GroupIndexer} 接口的实现类,用于根据请求消息列表来生成共识的分组ID;
* @return
*/
Class<?> groupIndexer() ;
/**
* 回复消息转换器;
* <p>
* 指定一个 {@link BinaryMessageConverter} 接口的实现类;
*
* @return
*/
Class<?> responseConverter();
}
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标识一个共识方法调用模式为“有序的消息调用”;
*
* @author huanghaiquan
*
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface OrderedAction {
/**
* 请求分组的索引器;<br>
*
* 指定一个 {@link GroupIndexer} 接口的实现类,用于根据请求消息列表来生成共识的分组ID;
* @return
*/
Class<?> groupIndexer() ;
/**
* 回复消息转换器;
* <p>
* 指定一个 {@link BinaryMessageConverter} 接口的实现类;
*
* @return
*/
Class<?> responseConverter();
}

+ 22
- 22
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/UnorderedAction.java View File

@@ -1,22 +1,22 @@
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author huanghaiquan
*
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface UnorderedAction {
/**
* 请求分组的索引器;<br>
*
* 指定一个 {@link GroupIndexer} 接口的实现类,用于根据请求消息列表来生成共识的分组ID;
* @return
*/
Class<?> groupIndexer() ;
}
package com.jd.blockchain.consensus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author huanghaiquan
*
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface UnorderedAction {
/**
* 请求分组的索引器;<br>
*
* 指定一个 {@link GroupIndexer} 接口的实现类,用于根据请求消息列表来生成共识的分组ID;
* @return
*/
Class<?> groupIndexer() ;
}

+ 49
- 49
source/consensus/consensus-framework/src/main/java/com/jd/blockchain/consensus/action/ActionResponseData.java View File

@@ -1,49 +1,49 @@
package com.jd.blockchain.consensus.action;
public class ActionResponseData implements ActionResponse {
private byte[] message;
private boolean error = false;
private String errorMessage;
private String errorType;
@Override
public byte[] getMessage() {
return message;
}
public void setMessage(byte[] message) {
this.message = message;
}
@Override
public boolean getError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
@Override
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public String getErrorType() {
return errorType;
}
public void setErrorType(String errorType) {
this.errorType = errorType;
}
}
package com.jd.blockchain.consensus.action;
public class ActionResponseData implements ActionResponse {
private byte[] message;
private boolean error = false;
private String errorMessage;
private String errorType;
@Override
public byte[] getMessage() {
return message;
}
public void setMessage(byte[] message) {
this.message = message;
}
@Override
public boolean getError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
@Override
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public String getErrorType() {
return errorType;
}
public void setErrorType(String errorType) {
this.errorType = errorType;
}
}

+ 18
- 18
source/contract/pom.xml View File

@@ -1,19 +1,19 @@
<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-root</artifactId>
<version>1.1.2.RELEASE</version>
</parent>
<artifactId>contract</artifactId>
<packaging>pom</packaging>
<modules>
<module>contract-framework</module>
<module>contract-jvm</module>
<module>contract-maven-plugin</module>
<module>contract-samples</module>
</modules>
<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-root</artifactId>
<version>1.1.2.RELEASE</version>
</parent>
<artifactId>contract</artifactId>
<packaging>pom</packaging>
<modules>
<module>contract-framework</module>
<module>contract-jvm</module>
<module>contract-maven-plugin</module>
<module>contract-samples</module>
</modules>
</project>

+ 65
- 65
source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/AddressEncoding.java View File

@@ -1,65 +1,65 @@
package com.jd.blockchain.crypto;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.BytesEncoding;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.NumberMask;
import com.jd.blockchain.utils.security.RipeMD160Utils;
import com.jd.blockchain.utils.security.ShaUtils;
public class AddressEncoding {
/**
* 将区块链地址写入到输出流;<br>
*
* 现将地址按 Base58 解码为字节数组,并将字节数组以 {@link BytesEncoding} 的方式写入输出流;<br>
*
* 如果指定的地址为 null,则仅写入空字节数组;注:此种情况下,输出流并不是完全没有写入,而是实际上会被写入一个表示内容长度为 0 的头部字节;<br>
*
* @param address
* 要写入的区块链地址;
* @param out
* 输出流;
* @return 写入的地址的字节数;如果指定地址为 null,则返回值为写入的头部字节数;;
*/
public static int writeAddress(Bytes address, OutputStream out) {
return address.writeTo(out);
}
/**
* 从流中读取区块链地址;
*
* @param in
* @return
* @throws IOException
*/
public static Bytes readAddress(InputStream in) throws IOException {
byte[] bytesAddress = BytesEncoding.read(NumberMask.TINY, in);
if (bytesAddress.length == 0) {
return null;
}
return new Bytes(bytesAddress);
}
/**
* 从公钥生成地址;
*
* @param pubKey
* @return
*/
public static Bytes generateAddress(PubKey pubKey) {
byte[] h1Bytes = ShaUtils.hash_256(pubKey.getRawKeyBytes());
byte[] h2Bytes = RipeMD160Utils.hash(h1Bytes);
byte[] xBytes = BytesUtils.concat(new byte[] { AddressVersion.V1.CODE}, BytesUtils.toBytes(pubKey.getAlgorithm()), h2Bytes);
byte[] checksum = Arrays.copyOf(ShaUtils.hash_256(ShaUtils.hash_256(xBytes)), 4);
byte[] addressBytes = BytesUtils.concat(xBytes, checksum);
return new Bytes(addressBytes);
}
}
package com.jd.blockchain.crypto;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.BytesEncoding;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.NumberMask;
import com.jd.blockchain.utils.security.RipeMD160Utils;
import com.jd.blockchain.utils.security.ShaUtils;
public class AddressEncoding {
/**
* 将区块链地址写入到输出流;<br>
*
* 现将地址按 Base58 解码为字节数组,并将字节数组以 {@link BytesEncoding} 的方式写入输出流;<br>
*
* 如果指定的地址为 null,则仅写入空字节数组;注:此种情况下,输出流并不是完全没有写入,而是实际上会被写入一个表示内容长度为 0 的头部字节;<br>
*
* @param address
* 要写入的区块链地址;
* @param out
* 输出流;
* @return 写入的地址的字节数;如果指定地址为 null,则返回值为写入的头部字节数;;
*/
public static int writeAddress(Bytes address, OutputStream out) {
return address.writeTo(out);
}
/**
* 从流中读取区块链地址;
*
* @param in
* @return
* @throws IOException
*/
public static Bytes readAddress(InputStream in) throws IOException {
byte[] bytesAddress = BytesEncoding.read(NumberMask.TINY, in);
if (bytesAddress.length == 0) {
return null;
}
return new Bytes(bytesAddress);
}
/**
* 从公钥生成地址;
*
* @param pubKey
* @return
*/
public static Bytes generateAddress(PubKey pubKey) {
byte[] h1Bytes = ShaUtils.hash_256(pubKey.getRawKeyBytes());
byte[] h2Bytes = RipeMD160Utils.hash(h1Bytes);
byte[] xBytes = BytesUtils.concat(new byte[] { AddressVersion.V1.CODE}, BytesUtils.toBytes(pubKey.getAlgorithm()), h2Bytes);
byte[] checksum = Arrays.copyOf(ShaUtils.hash_256(ShaUtils.hash_256(xBytes)), 4);
byte[] addressBytes = BytesUtils.concat(xBytes, checksum);
return new Bytes(addressBytes);
}
}

+ 24
- 24
source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/AddressVersion.java View File

@@ -1,24 +1,24 @@
package com.jd.blockchain.crypto;
/**
* The version of Blockchain Address generation rule; <br>
*
*
*
* @author huanghaiquan
*
*/
public enum AddressVersion {
V1((byte) 0x91);
// Note: Implementor can only add new enum items, cann't remove or modify
// existing enum items;
public final byte CODE;
AddressVersion(byte code) {
CODE = code;
}
}
package com.jd.blockchain.crypto;
/**
* The version of Blockchain Address generation rule; <br>
*
*
*
* @author huanghaiquan
*
*/
public enum AddressVersion {
V1((byte) 0x91);
// Note: Implementor can only add new enum items, cann't remove or modify
// existing enum items;
public final byte CODE;
AddressVersion(byte code) {
CODE = code;
}
}

+ 24
- 24
source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoKey.java View File

@@ -1,25 +1,25 @@
package com.jd.blockchain.crypto;
/**
* 密钥;
*
* @author huanghaiquan
*
*/
public interface CryptoKey extends CryptoBytes {
/**
* 密钥的类型;
* @return
*/
CryptoKeyType getKeyType();
/**
* 原始的密钥数据;
*
* @return
*/
byte[] getRawKeyBytes();
package com.jd.blockchain.crypto;
/**
* 密钥;
*
* @author huanghaiquan
*
*/
public interface CryptoKey extends CryptoBytes {
/**
* 密钥的类型;
* @return
*/
CryptoKeyType getKeyType();
/**
* 原始的密钥数据;
*
* @return
*/
byte[] getRawKeyBytes();
}

+ 28
- 28
source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/PrivKey.java View File

@@ -1,29 +1,29 @@
package com.jd.blockchain.crypto;
/**
* 私钥;
*
* @author huanghaiquan
*
*/
public class PrivKey extends BaseCryptoKey {
private static final long serialVersionUID = 6265440395252295646L;
public PrivKey(short algorithm, byte[] rawCryptoBytes) {
super(algorithm, rawCryptoBytes, CryptoKeyType.PRIVATE);
}
public PrivKey(CryptoAlgorithm algorithm, byte[] rawCryptoBytes) {
super(algorithm, rawCryptoBytes, CryptoKeyType.PRIVATE);
}
public PrivKey(byte[] cryptoBytes) {
super(cryptoBytes);
}
@Override
public CryptoKeyType getKeyType() {
return CryptoKeyType.PRIVATE;
}
package com.jd.blockchain.crypto;
/**
* 私钥;
*
* @author huanghaiquan
*
*/
public class PrivKey extends BaseCryptoKey {
private static final long serialVersionUID = 6265440395252295646L;
public PrivKey(short algorithm, byte[] rawCryptoBytes) {
super(algorithm, rawCryptoBytes, CryptoKeyType.PRIVATE);
}
public PrivKey(CryptoAlgorithm algorithm, byte[] rawCryptoBytes) {
super(algorithm, rawCryptoBytes, CryptoKeyType.PRIVATE);
}
public PrivKey(byte[] cryptoBytes) {
super(cryptoBytes);
}
@Override
public CryptoKeyType getKeyType() {
return CryptoKeyType.PRIVATE;
}
}

+ 14
- 14
source/gateway/src/main/java/com/jd/blockchain/gateway/GatewayConfiguration.java View File

@@ -1,14 +1,14 @@
package com.jd.blockchain.gateway;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@EnableAutoConfiguration
@EnableConfigurationProperties
@SpringBootApplication
@ComponentScan
public class GatewayConfiguration {
}
package com.jd.blockchain.gateway;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@EnableAutoConfiguration
@EnableConfigurationProperties
@SpringBootApplication
@ComponentScan
public class GatewayConfiguration {
}

+ 177
- 177
source/gateway/src/main/java/com/jd/blockchain/gateway/GatewayServerBooter.java View File

@@ -1,178 +1,178 @@
package com.jd.blockchain.gateway;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.ClassPathResource;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.gateway.web.BlockBrowserController;
import com.jd.blockchain.utils.ArgumentSet;
import com.jd.blockchain.utils.ArgumentSet.ArgEntry;
import com.jd.blockchain.utils.BaseConstant;
import com.jd.blockchain.utils.ConsoleUtils;
public class GatewayServerBooter {
private static final String DEFAULT_GATEWAY_PROPS = "application-gw.properties";
// 当前参与方在初始化配置中的参与方列表的编号;
private static final String HOST_ARG = "-c";
//sp;针对spring.config.location这个参数进行包装;
private static final String SPRING_CF_LOCATION = BaseConstant.SPRING_CF_LOCATION;
// 是否输出调试信息;
private static final String DEBUG_OPT = "-debug";
public static void main(String[] args) {
boolean debug = false;
try {
ArgumentSet arguments = ArgumentSet.resolve(args, ArgumentSet.setting().prefix(HOST_ARG, SPRING_CF_LOCATION).option(DEBUG_OPT));
debug = arguments.hasOption(DEBUG_OPT);
ArgEntry argHost = arguments.getArg(HOST_ARG);
String configFile = argHost == null ? null : argHost.getValue();
GatewayConfigProperties configProps;
if (configFile == null) {
ConsoleUtils.info("Load build-in default configuration ...");
ClassPathResource configResource = new ClassPathResource("gateway.conf");
try (InputStream in = configResource.getInputStream()) {
configProps = GatewayConfigProperties.resolve(in);
}
} else {
ConsoleUtils.info("Load configuration ...");
configProps = GatewayConfigProperties.resolve(argHost.getValue());
}
//spring config location;
String springConfigLocation=null;
ArgumentSet.ArgEntry spConfigLocation = arguments.getArg(SPRING_CF_LOCATION);
if (spConfigLocation != null) {
springConfigLocation = spConfigLocation.getValue();
}else {
//if no the config file, then should tip as follows. but it's not a good feeling, so we create it by inputStream;
ConsoleUtils.info("no param:-sp, format: -sp /x/xx.properties, use the default application-gw.properties ");
ClassPathResource configResource = new ClassPathResource(DEFAULT_GATEWAY_PROPS);
InputStream in = configResource.getInputStream();
// 将文件写入至config目录下
String configPath = bootPath() + "config" + File.separator + DEFAULT_GATEWAY_PROPS;
File targetFile = new File(configPath);
// 先将原来文件删除再Copy
if (targetFile.exists()) {
FileUtils.forceDelete(targetFile);
}
FileUtils.copyInputStreamToFile(in, targetFile);
springConfigLocation = "file:" + targetFile.getAbsolutePath();
}
// 启动服务器;
ConsoleUtils.info("Starting web server......");
GatewayServerBooter booter = new GatewayServerBooter(configProps,springConfigLocation);
booter.start();
ConsoleUtils.info("Peer[%s] is connected success!", configProps.masterPeerAddress().toString());
} catch (Exception e) {
ConsoleUtils.error("Error!! %s", e.getMessage());
if (debug) {
e.printStackTrace();
}
}
}
private volatile ConfigurableApplicationContext appCtx;
private GatewayConfigProperties config;
private AsymmetricKeypair defaultKeyPair;
private String springConfigLocation;
public GatewayServerBooter(GatewayConfigProperties config, String springConfigLocation) {
this.config = config;
this.springConfigLocation = springConfigLocation;
String base58Pwd = config.keys().getDefault().getPrivKeyPassword();
if (base58Pwd == null || base58Pwd.length() == 0) {
base58Pwd = KeyGenUtils.readPasswordString();
}
// 加载密钥;
PubKey pubKey = KeyGenUtils.decodePubKey(config.keys().getDefault().getPubKeyValue());
PrivKey privKey = null;
String base58PrivKey = config.keys().getDefault().getPrivKeyValue();
if (base58PrivKey == null) {
//注:GatewayConfigProperties 确保了 PrivKeyValue 和 PrivKeyPath 必有其一;
privKey = KeyGenUtils.readPrivKey(config.keys().getDefault().getPrivKeyPath(), base58Pwd);
} else {
privKey = KeyGenUtils.decodePrivKey(base58PrivKey, base58Pwd);
}
defaultKeyPair = new AsymmetricKeypair(pubKey, privKey);
}
public synchronized void start() {
if (this.appCtx != null) {
throw new IllegalStateException("Gateway server is running already.");
}
this.appCtx = startServer(config.http().getHost(), config.http().getPort(), springConfigLocation,
config.http().getContextPath());
ConsoleUtils.info("\r\n\r\nStart connecting to peer ....");
BlockBrowserController blockBrowserController = appCtx.getBean(BlockBrowserController.class);
blockBrowserController.setDataRetrievalUrl(config.dataRetrievalUrl());
blockBrowserController.setSchemaRetrievalUrl(config.getSchemaRetrievalUrl());
PeerConnector peerConnector = appCtx.getBean(PeerConnector.class);
peerConnector.connect(config.masterPeerAddress(), defaultKeyPair, config.providerConfig().getProviders());
ConsoleUtils.info("Peer[%s] is connected success!", config.masterPeerAddress().toString());
}
public synchronized void close() {
if (this.appCtx == null) {
return;
}
this.appCtx.close();
}
private static ConfigurableApplicationContext startServer(String host, int port, String springConfigLocation, String contextPath) {
List<String> argList = new ArrayList<String>();
argList.add(String.format("--server.address=%s", host));
argList.add(String.format("--server.port=%s", port));
if(springConfigLocation != null){
argList.add(String.format("--spring.config.location=%s", springConfigLocation));
}
if (contextPath != null) {
argList.add(String.format("--server.context-path=%s", contextPath));
}
String[] args = argList.toArray(new String[argList.size()]);
// 启动服务器;
ConfigurableApplicationContext appCtx = SpringApplication.run(GatewayConfiguration.class, args);
return appCtx;
}
private static String bootPath() throws Exception {
URL url = GatewayServerBooter.class.getProtectionDomain().getCodeSource().getLocation();
String currPath = java.net.URLDecoder.decode(url.getPath(), "UTF-8");
// 处理打包至SpringBoot问题
if (currPath.contains("!/")) {
currPath = currPath.substring(5, currPath.indexOf("!/"));
}
if (currPath.endsWith(".jar")) {
currPath = currPath.substring(0, currPath.lastIndexOf("/") + 1);
}
System.out.printf("Current Project Boot Path = %s \r\n", currPath);
return new File(currPath).getParent() + File.separator;
}
package com.jd.blockchain.gateway;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.ClassPathResource;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.KeyGenUtils;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.gateway.web.BlockBrowserController;
import com.jd.blockchain.utils.ArgumentSet;
import com.jd.blockchain.utils.ArgumentSet.ArgEntry;
import com.jd.blockchain.utils.BaseConstant;
import com.jd.blockchain.utils.ConsoleUtils;
public class GatewayServerBooter {
private static final String DEFAULT_GATEWAY_PROPS = "application-gw.properties";
// 当前参与方在初始化配置中的参与方列表的编号;
private static final String HOST_ARG = "-c";
//sp;针对spring.config.location这个参数进行包装;
private static final String SPRING_CF_LOCATION = BaseConstant.SPRING_CF_LOCATION;
// 是否输出调试信息;
private static final String DEBUG_OPT = "-debug";
public static void main(String[] args) {
boolean debug = false;
try {
ArgumentSet arguments = ArgumentSet.resolve(args, ArgumentSet.setting().prefix(HOST_ARG, SPRING_CF_LOCATION).option(DEBUG_OPT));
debug = arguments.hasOption(DEBUG_OPT);
ArgEntry argHost = arguments.getArg(HOST_ARG);
String configFile = argHost == null ? null : argHost.getValue();
GatewayConfigProperties configProps;
if (configFile == null) {
ConsoleUtils.info("Load build-in default configuration ...");
ClassPathResource configResource = new ClassPathResource("gateway.conf");
try (InputStream in = configResource.getInputStream()) {
configProps = GatewayConfigProperties.resolve(in);
}
} else {
ConsoleUtils.info("Load configuration ...");
configProps = GatewayConfigProperties.resolve(argHost.getValue());
}
//spring config location;
String springConfigLocation=null;
ArgumentSet.ArgEntry spConfigLocation = arguments.getArg(SPRING_CF_LOCATION);
if (spConfigLocation != null) {
springConfigLocation = spConfigLocation.getValue();
}else {
//if no the config file, then should tip as follows. but it's not a good feeling, so we create it by inputStream;
ConsoleUtils.info("no param:-sp, format: -sp /x/xx.properties, use the default application-gw.properties ");
ClassPathResource configResource = new ClassPathResource(DEFAULT_GATEWAY_PROPS);
InputStream in = configResource.getInputStream();
// 将文件写入至config目录下
String configPath = bootPath() + "config" + File.separator + DEFAULT_GATEWAY_PROPS;
File targetFile = new File(configPath);
// 先将原来文件删除再Copy
if (targetFile.exists()) {
FileUtils.forceDelete(targetFile);
}
FileUtils.copyInputStreamToFile(in, targetFile);
springConfigLocation = "file:" + targetFile.getAbsolutePath();
}
// 启动服务器;
ConsoleUtils.info("Starting web server......");
GatewayServerBooter booter = new GatewayServerBooter(configProps,springConfigLocation);
booter.start();
ConsoleUtils.info("Peer[%s] is connected success!", configProps.masterPeerAddress().toString());
} catch (Exception e) {
ConsoleUtils.error("Error!! %s", e.getMessage());
if (debug) {
e.printStackTrace();
}
}
}
private volatile ConfigurableApplicationContext appCtx;
private GatewayConfigProperties config;
private AsymmetricKeypair defaultKeyPair;
private String springConfigLocation;
public GatewayServerBooter(GatewayConfigProperties config, String springConfigLocation) {
this.config = config;
this.springConfigLocation = springConfigLocation;
String base58Pwd = config.keys().getDefault().getPrivKeyPassword();
if (base58Pwd == null || base58Pwd.length() == 0) {
base58Pwd = KeyGenUtils.readPasswordString();
}
// 加载密钥;
PubKey pubKey = KeyGenUtils.decodePubKey(config.keys().getDefault().getPubKeyValue());
PrivKey privKey = null;
String base58PrivKey = config.keys().getDefault().getPrivKeyValue();
if (base58PrivKey == null) {
//注:GatewayConfigProperties 确保了 PrivKeyValue 和 PrivKeyPath 必有其一;
privKey = KeyGenUtils.readPrivKey(config.keys().getDefault().getPrivKeyPath(), base58Pwd);
} else {
privKey = KeyGenUtils.decodePrivKey(base58PrivKey, base58Pwd);
}
defaultKeyPair = new AsymmetricKeypair(pubKey, privKey);
}
public synchronized void start() {
if (this.appCtx != null) {
throw new IllegalStateException("Gateway server is running already.");
}
this.appCtx = startServer(config.http().getHost(), config.http().getPort(), springConfigLocation,
config.http().getContextPath());
ConsoleUtils.info("\r\n\r\nStart connecting to peer ....");
BlockBrowserController blockBrowserController = appCtx.getBean(BlockBrowserController.class);
blockBrowserController.setDataRetrievalUrl(config.dataRetrievalUrl());
blockBrowserController.setSchemaRetrievalUrl(config.getSchemaRetrievalUrl());
PeerConnector peerConnector = appCtx.getBean(PeerConnector.class);
peerConnector.connect(config.masterPeerAddress(), defaultKeyPair, config.providerConfig().getProviders());
ConsoleUtils.info("Peer[%s] is connected success!", config.masterPeerAddress().toString());
}
public synchronized void close() {
if (this.appCtx == null) {
return;
}
this.appCtx.close();
}
private static ConfigurableApplicationContext startServer(String host, int port, String springConfigLocation, String contextPath) {
List<String> argList = new ArrayList<String>();
argList.add(String.format("--server.address=%s", host));
argList.add(String.format("--server.port=%s", port));
if(springConfigLocation != null){
argList.add(String.format("--spring.config.location=%s", springConfigLocation));
}
if (contextPath != null) {
argList.add(String.format("--server.context-path=%s", contextPath));
}
String[] args = argList.toArray(new String[argList.size()]);
// 启动服务器;
ConfigurableApplicationContext appCtx = SpringApplication.run(GatewayConfiguration.class, args);
return appCtx;
}
private static String bootPath() throws Exception {
URL url = GatewayServerBooter.class.getProtectionDomain().getCodeSource().getLocation();
String currPath = java.net.URLDecoder.decode(url.getPath(), "UTF-8");
// 处理打包至SpringBoot问题
if (currPath.contains("!/")) {
currPath = currPath.substring(5, currPath.indexOf("!/"));
}
if (currPath.endsWith(".jar")) {
currPath = currPath.substring(0, currPath.lastIndexOf("/") + 1);
}
System.out.printf("Current Project Boot Path = %s \r\n", currPath);
return new File(currPath).getParent() + File.separator;
}
}

+ 17
- 17
source/gateway/src/main/java/com/jd/blockchain/gateway/web/GatewayWebSecurityConfigurer.java View File

@@ -1,17 +1,17 @@
package com.jd.blockchain.gateway.web;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class GatewayWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
http.csrf().disable();
}
}
package com.jd.blockchain.gateway.web;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class GatewayWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
http.csrf().disable();
}
}

+ 30
- 30
source/gateway/src/main/resources/gateway.conf View File

@@ -1,31 +1,31 @@
#网关的HTTP服务地址;
http.host=0.0.0.0
#网关的HTTP服务端口;
http.port=8081
#网关的HTTP服务上下文路径,可选;
#http.context-path=
#共识节点的服务地址(与该网关节点连接的Peer节点的IP地址);
peer.host=127.0.0.1
#共识节点的服务端口(与该网关节点连接的Peer节点的端口);
peer.port=12000
#共识节点的服务是否启用安全证书;
peer.secure=false
#共识节点的服务提供解析器
#BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider
#简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider
peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider
#数据检索服务对应URL,格式:http://{ip}:{port},例如:http://127.0.0.1:10001
#若该值不配置或配置不正确,则浏览器模糊查询部分无法正常显示
data.retrieval.url=http://127.0.0.1:10001
schema.retrieval.url=http://192.168.151.39:8082
#默认公钥的内容(Base58编码数据);
keys.default.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9
#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一;
keys.default.privkey-path=
#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一;
keys.default.privkey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x
#默认私钥的解码密码;
#网关的HTTP服务地址;
http.host=0.0.0.0
#网关的HTTP服务端口;
http.port=8081
#网关的HTTP服务上下文路径,可选;
#http.context-path=
#共识节点的服务地址(与该网关节点连接的Peer节点的IP地址);
peer.host=127.0.0.1
#共识节点的服务端口(与该网关节点连接的Peer节点的端口);
peer.port=12000
#共识节点的服务是否启用安全证书;
peer.secure=false
#共识节点的服务提供解析器
#BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider
#简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider
peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider
#数据检索服务对应URL,格式:http://{ip}:{port},例如:http://127.0.0.1:10001
#若该值不配置或配置不正确,则浏览器模糊查询部分无法正常显示
data.retrieval.url=http://127.0.0.1:10001
schema.retrieval.url=http://192.168.151.39:8082
#默认公钥的内容(Base58编码数据);
keys.default.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9
#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一;
keys.default.privkey-path=
#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一;
keys.default.privkey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x
#默认私钥的解码密码;
keys.default.privkey-password=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY

+ 31
- 31
source/gateway/src/test/java/test/com/jd/blockchain/gateway/data/HashDigestDeserializer.java View File

@@ -1,31 +1,31 @@
package test.com.jd.blockchain.gateway.data;
import java.lang.reflect.Type;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.utils.codec.Base58Utils;
public class HashDigestDeserializer implements ObjectDeserializer{
public static final HashDigestDeserializer INSTANCE = new HashDigestDeserializer();
@SuppressWarnings("unchecked")
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
if (type instanceof Class && HashDigest.class.isAssignableFrom((Class<?>) type)) {
String base58Str = parser.parseObject(String.class);
byte[] hashBytes = Base58Utils.decode(base58Str);
return (T) new HashDigest(hashBytes);
}
return (T) parser.parse(fieldName);
}
@Override
public int getFastMatchToken() {
return JSONToken.LBRACE;
}
}
package test.com.jd.blockchain.gateway.data;
import java.lang.reflect.Type;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.utils.codec.Base58Utils;
public class HashDigestDeserializer implements ObjectDeserializer{
public static final HashDigestDeserializer INSTANCE = new HashDigestDeserializer();
@SuppressWarnings("unchecked")
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
if (type instanceof Class && HashDigest.class.isAssignableFrom((Class<?>) type)) {
String base58Str = parser.parseObject(String.class);
byte[] hashBytes = Base58Utils.decode(base58Str);
return (T) new HashDigest(hashBytes);
}
return (T) parser.parse(fieldName);
}
@Override
public int getFastMatchToken() {
return JSONToken.LBRACE;
}
}

+ 27
- 27
source/gateway/src/test/java/test/com/jd/blockchain/gateway/data/HashDigestSerializer.java View File

@@ -1,27 +1,27 @@
package test.com.jd.blockchain.gateway.data;
import java.io.IOException;
import java.lang.reflect.Type;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.jd.blockchain.crypto.HashDigest;
public class HashDigestSerializer implements ObjectSerializer {
public static HashDigestSerializer INSTANCE = new HashDigestSerializer();
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
HashDigest hash = (HashDigest) object;
out.writeString(hash.toBase58());
}
}
package test.com.jd.blockchain.gateway.data;
import java.io.IOException;
import java.lang.reflect.Type;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.jd.blockchain.crypto.HashDigest;
public class HashDigestSerializer implements ObjectSerializer {
public static HashDigestSerializer INSTANCE = new HashDigestSerializer();
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
HashDigest hash = (HashDigest) object;
out.writeString(hash.toBase58());
}
}

+ 72
- 72
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java View File

@@ -1,73 +1,73 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.ContractInfo;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.utils.Bytes;
public class ContractAccount extends AccountDecorator implements ContractInfo {
private static final String CONTRACT_INFO_PREFIX = "INFO" + LedgerConsts.KEY_SEPERATOR;
private static final String CHAIN_CODE_KEY = "CHAIN-CODE";
public ContractAccount(CompositeAccount mklAccount) {
super(mklAccount);
}
@Override
public Bytes getAddress() {
return getID().getAddress();
}
@Override
public PubKey getPubKey() {
return getID().getPubKey();
}
// public MerkleProof getChaincodeProof() {
// return getHeaders().getProof(CHAIN_CODE_KEY);
// }
//
// public MerkleProof getPropertyProof(Bytes key) {
// return getHeaders().getProof(encodePropertyKey(key));
// }
public long setChaincode(byte[] chaincode, long version) {
TypedValue bytesValue = TypedValue.fromBytes(chaincode);
return getHeaders().setValue(CHAIN_CODE_KEY, bytesValue, version);
}
public byte[] getChainCode() {
return getHeaders().getValue(CHAIN_CODE_KEY).getBytes().toBytes();
}
public byte[] getChainCode(long version) {
return getHeaders().getValue(CHAIN_CODE_KEY, version).getBytes().toBytes();
}
public long getChaincodeVersion() {
return getHeaders().getVersion(CHAIN_CODE_KEY);
}
public long setProperty(String key, String value, long version) {
TypedValue bytesValue = TypedValue.fromText(value);
return getHeaders().setValue(encodePropertyKey(key), bytesValue, version);
}
public String getProperty(String key) {
BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key));
return TypedValue.wrap(bytesValue).stringValue();
}
public String getProperty(String key, long version) {
BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key), version);
return TypedValue.wrap(bytesValue).stringValue();
}
private String encodePropertyKey(String key) {
return CONTRACT_INFO_PREFIX.concat(key);
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.ContractInfo;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.utils.Bytes;
public class ContractAccount extends AccountDecorator implements ContractInfo {
private static final String CONTRACT_INFO_PREFIX = "INFO" + LedgerConsts.KEY_SEPERATOR;
private static final String CHAIN_CODE_KEY = "CHAIN-CODE";
public ContractAccount(CompositeAccount mklAccount) {
super(mklAccount);
}
@Override
public Bytes getAddress() {
return getID().getAddress();
}
@Override
public PubKey getPubKey() {
return getID().getPubKey();
}
// public MerkleProof getChaincodeProof() {
// return getHeaders().getProof(CHAIN_CODE_KEY);
// }
//
// public MerkleProof getPropertyProof(Bytes key) {
// return getHeaders().getProof(encodePropertyKey(key));
// }
public long setChaincode(byte[] chaincode, long version) {
TypedValue bytesValue = TypedValue.fromBytes(chaincode);
return getHeaders().setValue(CHAIN_CODE_KEY, bytesValue, version);
}
public byte[] getChainCode() {
return getHeaders().getValue(CHAIN_CODE_KEY).getBytes().toBytes();
}
public byte[] getChainCode(long version) {
return getHeaders().getValue(CHAIN_CODE_KEY, version).getBytes().toBytes();
}
public long getChaincodeVersion() {
return getHeaders().getVersion(CHAIN_CODE_KEY);
}
public long setProperty(String key, String value, long version) {
TypedValue bytesValue = TypedValue.fromText(value);
return getHeaders().setValue(encodePropertyKey(key), bytesValue, version);
}
public String getProperty(String key) {
BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key));
return TypedValue.wrap(bytesValue).stringValue();
}
public String getProperty(String key, long version) {
BytesValue bytesValue = getHeaders().getValue(encodePropertyKey(key), version);
return TypedValue.wrap(bytesValue).stringValue();
}
private String encodePropertyKey(String key) {
return CONTRACT_INFO_PREFIX.concat(key);
}
}

+ 130
- 130
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java View File

@@ -1,131 +1,131 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class ContractAccountSet implements Transactional, ContractAccountQuery {
private MerkleAccountSet accountSet;
public ContractAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy);
}
public ContractAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage,
readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
/**
* 返回合约总数;
*
* @return
*/
@Override
public long getTotal() {
return accountSet.getTotal();
}
@Override
public MerkleProof getProof(Bytes address) {
return accountSet.getProof(address);
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
@Override
public ContractAccount getAccount(Bytes address) {
CompositeAccount accBase = accountSet.getAccount(address);
return new ContractAccount(accBase);
}
@Override
public ContractAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
@Override
public ContractAccount getAccount(Bytes address, long version) {
CompositeAccount accBase = accountSet.getAccount(address, version);
return new ContractAccount(accBase);
}
/**
* 部署一项新的合约链码;
*
* @param address 合约账户地址;
* @param pubKey 合约账户公钥;
* @param addressSignature 地址签名;合约账户的私钥对地址的签名;
* @param chaincode 链码内容;
* @return 合约账户;
*/
public ContractAccount deploy(Bytes address, PubKey pubKey, DigitalSignature addressSignature, byte[] chaincode) {
// TODO: 校验和记录合约地址签名;
CompositeAccount accBase = accountSet.register(address, pubKey);
ContractAccount contractAcc = new ContractAccount(accBase);
contractAcc.setChaincode(chaincode, -1);
return contractAcc;
}
/**
* 更新指定账户的链码;
*
* @param address 合约账户地址;
* @param chaincode 链码内容;
* @param version 链码版本;
* @return 返回链码的新版本号;
*/
public long update(Bytes address, byte[] chaincode, long version) {
CompositeAccount accBase = accountSet.getAccount(address);
ContractAccount contractAcc = new ContractAccount(accBase);
return contractAcc.setChaincode(chaincode, version);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class ContractAccountSet implements Transactional, ContractAccountQuery {
private MerkleAccountSet accountSet;
public ContractAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy);
}
public ContractAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage,
readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
/**
* 返回合约总数;
*
* @return
*/
@Override
public long getTotal() {
return accountSet.getTotal();
}
@Override
public MerkleProof getProof(Bytes address) {
return accountSet.getProof(address);
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
@Override
public ContractAccount getAccount(Bytes address) {
CompositeAccount accBase = accountSet.getAccount(address);
return new ContractAccount(accBase);
}
@Override
public ContractAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
@Override
public ContractAccount getAccount(Bytes address, long version) {
CompositeAccount accBase = accountSet.getAccount(address, version);
return new ContractAccount(accBase);
}
/**
* 部署一项新的合约链码;
*
* @param address 合约账户地址;
* @param pubKey 合约账户公钥;
* @param addressSignature 地址签名;合约账户的私钥对地址的签名;
* @param chaincode 链码内容;
* @return 合约账户;
*/
public ContractAccount deploy(Bytes address, PubKey pubKey, DigitalSignature addressSignature, byte[] chaincode) {
// TODO: 校验和记录合约地址签名;
CompositeAccount accBase = accountSet.register(address, pubKey);
ContractAccount contractAcc = new ContractAccount(accBase);
contractAcc.setChaincode(chaincode, -1);
return contractAcc;
}
/**
* 更新指定账户的链码;
*
* @param address 合约账户地址;
* @param chaincode 链码内容;
* @param version 链码版本;
* @return 返回链码的新版本号;
*/
public long update(Bytes address, byte[] chaincode, long version) {
CompositeAccount accBase = accountSet.getAccount(address);
ContractAccount contractAcc = new ContractAccount(accBase);
return contractAcc.setChaincode(chaincode, version);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
}

+ 233
- 233
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java View File

@@ -1,234 +1,234 @@
package com.jd.blockchain.ledger.core;
public class DataAccount extends AccountDecorator {
public DataAccount(CompositeAccount mklAccount) {
super(mklAccount);
}
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, BytesValue value, long version) {
// return super.getDataset().setValue(key, value, version);
// }
//
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, String value, long version) {
// BytesValue bytesValue = TypedValue.fromText(value);
// return baseAccount.setValue(key, bytesValue, version);
// }
//
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, byte[] value, long version) {
// BytesValue bytesValue = TypedValue.fromBytes(value);
// return baseAccount.setValue(key, bytesValue, version);
// }
//
// /**
// * Return the latest version entry associated the specified key; If the key
// * doesn't exist, then return -1;
// *
// * @param key
// * @return
// */
// public long getDataVersion(String key) {
// return baseAccount.getVersion(Bytes.fromString(key));
// }
//
// /**
// * Return the latest version entry associated the specified key; If the key
// * doesn't exist, then return -1;
// *
// * @param key
// * @return
// */
// public long getDataVersion(Bytes key) {
// return baseAccount.getVersion(key);
// }
//
// /**
// * return the latest version's value;
// *
// * @param key
// * @return return null if not exist;
// */
// public BytesValue getBytes(String key) {
// return baseAccount.getValue(Bytes.fromString(key));
// }
//
// /**
// * return the latest version's value;
// *
// * @param key
// * @return return null if not exist;
// */
// public BytesValue getBytes(Bytes key) {
// return baseAccount.getValue(key);
// }
//
// /**
// * return the specified version's value;
// *
// * @param key
// * @param version
// * @return return null if not exist;
// */
// public BytesValue getBytes(String key, long version) {
// return baseAccount.getValue(Bytes.fromString(key), version);
// }
//
// /**
// * return the specified version's value;
// *
// * @param key
// * @param version
// * @return return null if not exist;
// */
// public BytesValue getBytes(Bytes key, long version) {
// return baseAccount.getValue(key, version);
// }
// /**
// * @param key
// * @param version
// * @return
// */
// public KVDataEntry getDataEntry(String key, long version) {
// return getDataEntry(Bytes.fromString(key), version);
// }
//
// /**
// * @param key
// * @param version
// * @return
// */
// public KVDataEntry getDataEntry(Bytes key, long version) {
// BytesValue value = baseAccount.getValue(key, version);
// if (value == null) {
// return new KVDataObject(key.toUTF8String(), -1, null);
// }else {
// return new KVDataObject(key.toUTF8String(), version, value);
// }
// }
//
// /**
// * return the specified index's KVDataEntry;
// *
// * @param fromIndex
// * @param count
// * @return return null if not exist;
// */
//
// public KVDataEntry[] getDataEntries(int fromIndex, int count) {
// if (count == 0 || getDataEntriesTotalCount() == 0) {
// return null;
// }
//
// if (count == -1 || count > getDataEntriesTotalCount()) {
// fromIndex = 0;
// count = (int)getDataEntriesTotalCount();
// }
//
// if (fromIndex < 0 || fromIndex > getDataEntriesTotalCount() - 1) {
// fromIndex = 0;
// }
//
// KVDataEntry[] kvDataEntries = new KVDataEntry[count];
// byte[] value;
// String key;
// long ver;
// for (int i = 0; i < count; i++) {
// value = baseAccount.dataset.getValuesAtIndex(fromIndex);
// key = baseAccount.dataset.getKeyAtIndex(fromIndex);
// ver = baseAccount.dataset.getVersion(key);
// BytesValue decodeData = BinaryProtocol.decode(value);
// kvDataEntries[i] = new KVDataObject(key, ver, decodeData);
// fromIndex++;
// }
//
// return kvDataEntries;
// }
//
// /**
// * return the dataAccount's kv total count;
// *
// * @param
// * @param
// * @return return total count;
// */
// public long getDataEntriesTotalCount() {
// if(baseAccount == null){
// return 0;
// }
// return baseAccount.dataset.getDataCount();
// }
package com.jd.blockchain.ledger.core;
public class DataAccount extends AccountDecorator {
public DataAccount(CompositeAccount mklAccount) {
super(mklAccount);
}
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, BytesValue value, long version) {
// return super.getDataset().setValue(key, value, version);
// }
//
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, String value, long version) {
// BytesValue bytesValue = TypedValue.fromText(value);
// return baseAccount.setValue(key, bytesValue, version);
// }
//
// /**
// * Create or update the value associated the specified key if the version
// * checking is passed.<br>
// *
// * The value of the key will be updated only if it's latest version equals the
// * specified version argument. <br>
// * If the key doesn't exist, the version checking will be ignored, and key will
// * be created with a new sequence number as id. <br>
// * It also could specify the version argument to -1 to ignore the version
// * checking.
// * <p>
// * If updating is performed, the version of the key increase by 1. <br>
// * If creating is performed, the version of the key initialize by 0. <br>
// *
// * @param key The key of data;
// * @param value The value of data;
// * @param version The expected version of the key.
// * @return The new version of the key. <br>
// * If the key is new created success, then return 0; <br>
// * If the key is updated success, then return the new version;<br>
// * If this operation fail by version checking or other reason, then
// * return -1;
// */
// public long setBytes(Bytes key, byte[] value, long version) {
// BytesValue bytesValue = TypedValue.fromBytes(value);
// return baseAccount.setValue(key, bytesValue, version);
// }
//
// /**
// * Return the latest version entry associated the specified key; If the key
// * doesn't exist, then return -1;
// *
// * @param key
// * @return
// */
// public long getDataVersion(String key) {
// return baseAccount.getVersion(Bytes.fromString(key));
// }
//
// /**
// * Return the latest version entry associated the specified key; If the key
// * doesn't exist, then return -1;
// *
// * @param key
// * @return
// */
// public long getDataVersion(Bytes key) {
// return baseAccount.getVersion(key);
// }
//
// /**
// * return the latest version's value;
// *
// * @param key
// * @return return null if not exist;
// */
// public BytesValue getBytes(String key) {
// return baseAccount.getValue(Bytes.fromString(key));
// }
//
// /**
// * return the latest version's value;
// *
// * @param key
// * @return return null if not exist;
// */
// public BytesValue getBytes(Bytes key) {
// return baseAccount.getValue(key);
// }
//
// /**
// * return the specified version's value;
// *
// * @param key
// * @param version
// * @return return null if not exist;
// */
// public BytesValue getBytes(String key, long version) {
// return baseAccount.getValue(Bytes.fromString(key), version);
// }
//
// /**
// * return the specified version's value;
// *
// * @param key
// * @param version
// * @return return null if not exist;
// */
// public BytesValue getBytes(Bytes key, long version) {
// return baseAccount.getValue(key, version);
// }
// /**
// * @param key
// * @param version
// * @return
// */
// public KVDataEntry getDataEntry(String key, long version) {
// return getDataEntry(Bytes.fromString(key), version);
// }
//
// /**
// * @param key
// * @param version
// * @return
// */
// public KVDataEntry getDataEntry(Bytes key, long version) {
// BytesValue value = baseAccount.getValue(key, version);
// if (value == null) {
// return new KVDataObject(key.toUTF8String(), -1, null);
// }else {
// return new KVDataObject(key.toUTF8String(), version, value);
// }
// }
//
// /**
// * return the specified index's KVDataEntry;
// *
// * @param fromIndex
// * @param count
// * @return return null if not exist;
// */
//
// public KVDataEntry[] getDataEntries(int fromIndex, int count) {
// if (count == 0 || getDataEntriesTotalCount() == 0) {
// return null;
// }
//
// if (count == -1 || count > getDataEntriesTotalCount()) {
// fromIndex = 0;
// count = (int)getDataEntriesTotalCount();
// }
//
// if (fromIndex < 0 || fromIndex > getDataEntriesTotalCount() - 1) {
// fromIndex = 0;
// }
//
// KVDataEntry[] kvDataEntries = new KVDataEntry[count];
// byte[] value;
// String key;
// long ver;
// for (int i = 0; i < count; i++) {
// value = baseAccount.dataset.getValuesAtIndex(fromIndex);
// key = baseAccount.dataset.getKeyAtIndex(fromIndex);
// ver = baseAccount.dataset.getVersion(key);
// BytesValue decodeData = BinaryProtocol.decode(value);
// kvDataEntries[i] = new KVDataObject(key, ver, decodeData);
// fromIndex++;
// }
//
// return kvDataEntries;
// }
//
// /**
// * return the dataAccount's kv total count;
// *
// * @param
// * @param
// * @return return total count;
// */
// public long getDataEntriesTotalCount() {
// if(baseAccount == null){
// return 0;
// }
// return baseAccount.dataset.getDataCount();
// }
}

+ 112
- 112
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java View File

@@ -1,113 +1,113 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class DataAccountSet implements Transactional, DataAccountQuery {
private MerkleAccountSet accountSet;
public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy);
}
public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage,
readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
@Override
public long getTotal() {
return accountSet.getTotal();
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
/**
* 返回账户的存在性证明;
*/
@Override
public MerkleProof getProof(Bytes address) {
return accountSet.getProof(address);
}
public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) {
// TODO: 未实现对地址签名的校验和记录;
CompositeAccount accBase = accountSet.register(address, pubKey);
return new DataAccount(accBase);
}
@Override
public DataAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
/**
* 返回数据账户; <br>
* 如果不存在,则返回 null;
*
* @param address
* @return
*/
@Override
public DataAccount getAccount(Bytes address) {
CompositeAccount accBase = accountSet.getAccount(address);
if (accBase == null) {
return null;
}
return new DataAccount(accBase);
}
@Override
public DataAccount getAccount(Bytes address, long version) {
CompositeAccount accBase = accountSet.getAccount(address, version);
return new DataAccount(accBase);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class DataAccountSet implements Transactional, DataAccountQuery {
private MerkleAccountSet accountSet;
public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy);
}
public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage,
readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
@Override
public long getTotal() {
return accountSet.getTotal();
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
/**
* 返回账户的存在性证明;
*/
@Override
public MerkleProof getProof(Bytes address) {
return accountSet.getProof(address);
}
public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) {
// TODO: 未实现对地址签名的校验和记录;
CompositeAccount accBase = accountSet.register(address, pubKey);
return new DataAccount(accBase);
}
@Override
public DataAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
/**
* 返回数据账户; <br>
* 如果不存在,则返回 null;
*
* @param address
* @return
*/
@Override
public DataAccount getAccount(Bytes address) {
CompositeAccount accBase = accountSet.getAccount(address);
if (accBase == null) {
return null;
}
return new DataAccount(accBase);
}
@Override
public DataAccount getAccount(Bytes address, long version) {
CompositeAccount accBase = accountSet.getAccount(address, version);
return new DataAccount(accBase);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
}

+ 480
- 480
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminDataset.java View File

@@ -1,481 +1,481 @@
package com.jd.blockchain.ledger.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.HashFunction;
import com.jd.blockchain.ledger.LedgerAdminSettings;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.LedgerInitSetting;
import com.jd.blockchain.ledger.LedgerMetadata;
import com.jd.blockchain.ledger.LedgerMetadata_V2;
import com.jd.blockchain.ledger.LedgerSettings;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.RolePrivilegeSettings;
import com.jd.blockchain.ledger.UserAuthorizationSettings;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class LedgerAdminDataset implements Transactional, LedgerAdminDataQuery, LedgerAdminSettings {
static {
DataContractRegistry.register(LedgerMetadata.class);
DataContractRegistry.register(LedgerMetadata_V2.class);
}
private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminDataset.class);
public static final String LEDGER_META_PREFIX = "MTA" + LedgerConsts.KEY_SEPERATOR;
public static final String LEDGER_PARTICIPANT_PREFIX = "PAR" + LedgerConsts.KEY_SEPERATOR;
public static final String LEDGER_SETTING_PREFIX = "SET" + LedgerConsts.KEY_SEPERATOR;
public static final String ROLE_PRIVILEGE_PREFIX = "RPV" + LedgerConsts.KEY_SEPERATOR;
public static final String USER_ROLE_PREFIX = "URO" + LedgerConsts.KEY_SEPERATOR;
private final Bytes metaPrefix;
private final Bytes settingPrefix;
private LedgerMetadata_V2 origMetadata;
private LedgerMetadataInfo metadata;
/**
* 原来的账本设置;
*
* <br>
* 对 LedgerMetadata 修改的新配置不能立即生效,需要达成共识后,在下一次区块计算中才生效;
*/
private LedgerSettings previousSettings;
private HashDigest previousSettingHash;
/**
* 账本的参与节点;
*/
private ParticipantDataset participants;
/**
* “角色-权限”数据集;
*/
private RolePrivilegeDataset rolePrivileges;
/**
* “用户-角色”数据集;
*/
private UserRoleDataset userRoles;
/**
* 账本参数配置;
*/
private LedgerSettings settings;
private ExPolicyKVStorage storage;
private HashDigest adminDataHash;
private boolean readonly;
private boolean updated;
public HashDigest getHash() {
return adminDataHash;
}
public boolean isReadonly() {
return readonly;
}
void setReadonly() {
this.readonly = true;
}
public LedgerSettings getPreviousSetting() {
return previousSettings;
}
@Override
public RolePrivilegeSettings getRolePrivileges() {
return rolePrivileges;
}
@Override
public UserAuthorizationSettings getAuthorizations() {
return userRoles;
}
@Override
public LedgerAdminSettings getAdminInfo() {
return this;
}
/**
* 初始化账本的管理账户;
*
* <br>
*
* 只在新建账本时调用此方法;
*
* @param ledgerSeed
* @param settings
* @param partiList
* @param exPolicyStorage
* @param versioningStorage
*/
public LedgerAdminDataset(LedgerInitSetting initSetting, String keyPrefix, ExPolicyKVStorage exPolicyStorage,
VersioningKVStorage versioningStorage) {
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX);
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX);
ParticipantNode[] parties = initSetting.getConsensusParticipants();
if (parties.length == 0) {
throw new LedgerException("No participant!");
}
// 初始化元数据;
this.metadata = new LedgerMetadataInfo();
this.metadata.setSeed(initSetting.getLedgerSeed());
// 新配置;
this.settings = new LedgerConfiguration(initSetting.getConsensusProvider(), initSetting.getConsensusSettings(),
initSetting.getCryptoSetting());
this.previousSettings = new LedgerConfiguration(settings);
this.previousSettingHash = null;
this.adminDataHash = null;
// 基于原配置初始化参与者列表;
String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX;
this.participants = new ParticipantDataset(previousSettings.getCryptoSetting(), partiPrefix, exPolicyStorage,
versioningStorage);
for (ParticipantNode p : parties) {
this.participants.addConsensusParticipant(p);
}
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX;
this.rolePrivileges = new RolePrivilegeDataset(this.settings.getCryptoSetting(), rolePrivilegePrefix,
exPolicyStorage, versioningStorage);
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX;
this.userRoles = new UserRoleDataset(this.settings.getCryptoSetting(), userRolePrefix, exPolicyStorage,
versioningStorage);
// 初始化其它属性;
this.storage = exPolicyStorage;
this.readonly = false;
}
public LedgerAdminDataset(HashDigest adminAccountHash, String keyPrefix, ExPolicyKVStorage kvStorage,
VersioningKVStorage versioningKVStorage, boolean readonly) {
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX);
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX);
this.storage = kvStorage;
this.readonly = readonly;
this.origMetadata = loadAndVerifyMetadata(adminAccountHash);
this.metadata = new LedgerMetadataInfo(origMetadata);
this.settings = loadAndVerifySettings(metadata.getSettingsHash());
// 复制记录一份配置作为上一个区块的原始配置,该实例仅供读取,不做修改,也不会回写到存储;
this.previousSettings = new LedgerConfiguration(settings);
this.previousSettingHash = metadata.getSettingsHash();
this.adminDataHash = adminAccountHash;
String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX;
this.participants = new ParticipantDataset(metadata.getParticipantsHash(), previousSettings.getCryptoSetting(),
partiPrefix, kvStorage, versioningKVStorage, readonly);
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX;
this.rolePrivileges = new RolePrivilegeDataset(metadata.getRolePrivilegesHash(),
previousSettings.getCryptoSetting(), rolePrivilegePrefix, kvStorage, versioningKVStorage, readonly);
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX;
this.userRoles = new UserRoleDataset(metadata.getUserRolesHash(), previousSettings.getCryptoSetting(),
userRolePrefix, kvStorage, versioningKVStorage, readonly);
}
private LedgerSettings loadAndVerifySettings(HashDigest settingsHash) {
if (settingsHash == null) {
return null;
}
Bytes key = encodeSettingsKey(settingsHash);
byte[] bytes = storage.get(key);
HashFunction hashFunc = Crypto.getHashFunction(settingsHash.getAlgorithm());
if (!hashFunc.verify(settingsHash, bytes)) {
String errorMsg = "Verification of the hash for ledger setting failed! --[HASH=" + key + "]";
LOGGER.error(errorMsg);
throw new LedgerException(errorMsg);
}
return deserializeSettings(bytes);
}
private LedgerSettings deserializeSettings(byte[] bytes) {
return BinaryProtocol.decode(bytes);
}
private byte[] serializeSetting(LedgerSettings setting) {
return BinaryProtocol.encode(setting, LedgerSettings.class);
}
private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) {
Bytes key = encodeMetadataKey(adminAccountHash);
byte[] bytes = storage.get(key);
HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm());
if (!hashFunc.verify(adminAccountHash, bytes)) {
String errorMsg = "Verification of the hash for ledger metadata failed! --[HASH=" + key + "]";
LOGGER.error(errorMsg);
throw new LedgerException(errorMsg);
}
return deserializeMetadata(bytes);
}
private Bytes encodeSettingsKey(HashDigest settingsHash) {
return settingPrefix.concat(settingsHash);
}
private Bytes encodeMetadataKey(HashDigest metadataHash) {
// return LEDGER_META_PREFIX + metadataHash;
// return metaPrefix + metadataHash;
return metaPrefix.concat(metadataHash);
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata()
*/
@Override
public LedgerMetadata_V2 getMetadata() {
return metadata;
}
// /**
// * 返回原来的账本配置;
// *
// * <br>
// * 此方法总是返回从上一个区块加载的账本配置,即时调用 {@link #setLedgerSetting(LedgerSettings)} 做出了新的更改;
// *
// * @return
// */
// public LedgerSettings getPreviousSetting() {
// return previousSettings;
// }
/**
* 返回当前设置的账本配置;
*
* @return
*/
@Override
public LedgerSettings getSettings() {
return settings;
}
/**
* 更新账本配置;
*
* @param ledgerSetting
*/
public void setLedgerSetting(LedgerSettings ledgerSetting) {
if (readonly) {
throw new IllegalArgumentException("This merkle dataset is readonly!");
}
settings = ledgerSetting;
updated = true;
}
@Override
public long getParticipantCount() {
return participants.getParticipantCount();
}
@Override
public ParticipantNode[] getParticipants() {
return participants.getParticipants();
}
@Override
public ParticipantDataset getParticipantDataset() {
return participants;
}
/**
* 加入新的参与方; 如果指定的参与方已经存在,则引发 LedgerException 异常;
*
* @param participant
*/
public void addParticipant(ParticipantNode participant) {
participants.addConsensusParticipant(participant);
}
/**
* 更新参与方的状态参数;
*
* @param participant
*/
public void updateParticipant(ParticipantNode participant) {
participants.updateConsensusParticipant(participant);
}
@Override
public boolean isUpdated() {
return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated();
}
@Override
public void commit() {
if (!isUpdated()) {
return;
}
// 计算并更新参与方集合的根哈希;
participants.commit();
metadata.setParticipantsHash(participants.getRootHash());
// 计算并更新角色权限集合的根哈希;
rolePrivileges.commit();
metadata.setRolePrivilegesHash(rolePrivileges.getRootHash());
// 计算并更新用户角色授权集合的根哈希;
userRoles.commit();
metadata.setUserRolesHash(userRoles.getRootHash());
// 当前区块上下文的密码参数设置的哈希函数;
HashFunction hashFunc = Crypto.getHashFunction(previousSettings.getCryptoSetting().getHashAlgorithm());
// 计算并更新参数配置的哈希;
if (settings == null) {
throw new LedgerException("Missing ledger settings!");
}
byte[] settingsBytes = serializeSetting(settings);
HashDigest settingsHash = hashFunc.hash(settingsBytes);
metadata.setSettingsHash(settingsHash);
if (previousSettingHash == null || !previousSettingHash.equals(settingsHash)) {
Bytes settingsKey = encodeSettingsKey(settingsHash);
boolean nx = storage.set(settingsKey, settingsBytes, ExPolicy.NOT_EXISTING);
if (!nx) {
String base58MetadataHash = settingsHash.toBase58();
// 有可能发生了并发写入冲突,不同的节点都向同一个存储服务器上写入数据;
String errMsg = "Ledger metadata already exist! --[MetadataHash=" + base58MetadataHash + "]";
LOGGER.warn(errMsg);
throw new LedgerException(errMsg);
}
}
// 基于之前的密码配置来计算元数据的哈希;
byte[] metadataBytes = serializeMetadata(metadata);
HashDigest metadataHash = hashFunc.hash(metadataBytes);
if (adminDataHash == null || !adminDataHash.equals(metadataHash)) {
// update modify;
// String base58MetadataHash = metadataHash.toBase58();
// String metadataKey = encodeMetadataKey(base58MetadataHash);
Bytes metadataKey = encodeMetadataKey(metadataHash);
boolean nx = storage.set(metadataKey, metadataBytes, ExPolicy.NOT_EXISTING);
if (!nx) {
String base58MetadataHash = metadataHash.toBase58();
// 有可能发生了并发写入冲突,不同的节点都向同一个存储服务器上写入数据;
String errMsg = "Ledger metadata already exist! --[MetadataHash=" + base58MetadataHash + "]";
LOGGER.warn(errMsg);
throw new LedgerException(errMsg);
}
adminDataHash = metadataHash;
}
updated = false;
}
private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) {
return BinaryProtocol.decode(bytes);
}
private byte[] serializeMetadata(LedgerMetadataInfo config) {
return BinaryProtocol.encode(config, LedgerMetadata_V2.class);
}
@Override
public void cancel() {
if (!isUpdated()) {
return;
}
participants.cancel();
metadata =origMetadata == null ? new LedgerMetadataInfo() : new LedgerMetadataInfo(origMetadata);
}
public static class LedgerMetadataInfo implements LedgerMetadata_V2 {
private byte[] seed;
// private LedgerSetting setting;
private HashDigest participantsHash;
private HashDigest settingsHash;
private HashDigest rolePrivilegesHash;
private HashDigest userRolesHash;
public LedgerMetadataInfo() {
}
public LedgerMetadataInfo(LedgerMetadata_V2 metadata) {
this.seed = metadata.getSeed();
this.participantsHash = metadata.getParticipantsHash();
this.settingsHash = metadata.getSettingsHash();
this.rolePrivilegesHash = metadata.getRolePrivilegesHash();
this.userRolesHash = metadata.getUserRolesHash();
}
@Override
public byte[] getSeed() {
return seed;
}
@Override
public HashDigest getSettingsHash() {
return settingsHash;
}
@Override
public HashDigest getParticipantsHash() {
return participantsHash;
}
@Override
public HashDigest getRolePrivilegesHash() {
return rolePrivilegesHash;
}
@Override
public HashDigest getUserRolesHash() {
return userRolesHash;
}
public void setSeed(byte[] seed) {
this.seed = seed;
}
public void setSettingsHash(HashDigest settingHash) {
this.settingsHash = settingHash;
}
public void setParticipantsHash(HashDigest participantsHash) {
this.participantsHash = participantsHash;
}
public void setRolePrivilegesHash(HashDigest rolePrivilegesHash) {
this.rolePrivilegesHash = rolePrivilegesHash;
}
public void setUserRolesHash(HashDigest userRolesHash) {
this.userRolesHash = userRolesHash;
}
}
package com.jd.blockchain.ledger.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.HashFunction;
import com.jd.blockchain.ledger.LedgerAdminSettings;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.LedgerInitSetting;
import com.jd.blockchain.ledger.LedgerMetadata;
import com.jd.blockchain.ledger.LedgerMetadata_V2;
import com.jd.blockchain.ledger.LedgerSettings;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.RolePrivilegeSettings;
import com.jd.blockchain.ledger.UserAuthorizationSettings;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
public class LedgerAdminDataset implements Transactional, LedgerAdminDataQuery, LedgerAdminSettings {
static {
DataContractRegistry.register(LedgerMetadata.class);
DataContractRegistry.register(LedgerMetadata_V2.class);
}
private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminDataset.class);
public static final String LEDGER_META_PREFIX = "MTA" + LedgerConsts.KEY_SEPERATOR;
public static final String LEDGER_PARTICIPANT_PREFIX = "PAR" + LedgerConsts.KEY_SEPERATOR;
public static final String LEDGER_SETTING_PREFIX = "SET" + LedgerConsts.KEY_SEPERATOR;
public static final String ROLE_PRIVILEGE_PREFIX = "RPV" + LedgerConsts.KEY_SEPERATOR;
public static final String USER_ROLE_PREFIX = "URO" + LedgerConsts.KEY_SEPERATOR;
private final Bytes metaPrefix;
private final Bytes settingPrefix;
private LedgerMetadata_V2 origMetadata;
private LedgerMetadataInfo metadata;
/**
* 原来的账本设置;
*
* <br>
* 对 LedgerMetadata 修改的新配置不能立即生效,需要达成共识后,在下一次区块计算中才生效;
*/
private LedgerSettings previousSettings;
private HashDigest previousSettingHash;
/**
* 账本的参与节点;
*/
private ParticipantDataset participants;
/**
* “角色-权限”数据集;
*/
private RolePrivilegeDataset rolePrivileges;
/**
* “用户-角色”数据集;
*/
private UserRoleDataset userRoles;
/**
* 账本参数配置;
*/
private LedgerSettings settings;
private ExPolicyKVStorage storage;
private HashDigest adminDataHash;
private boolean readonly;
private boolean updated;
public HashDigest getHash() {
return adminDataHash;
}
public boolean isReadonly() {
return readonly;
}
void setReadonly() {
this.readonly = true;
}
public LedgerSettings getPreviousSetting() {
return previousSettings;
}
@Override
public RolePrivilegeSettings getRolePrivileges() {
return rolePrivileges;
}
@Override
public UserAuthorizationSettings getAuthorizations() {
return userRoles;
}
@Override
public LedgerAdminSettings getAdminInfo() {
return this;
}
/**
* 初始化账本的管理账户;
*
* <br>
*
* 只在新建账本时调用此方法;
*
* @param ledgerSeed
* @param settings
* @param partiList
* @param exPolicyStorage
* @param versioningStorage
*/
public LedgerAdminDataset(LedgerInitSetting initSetting, String keyPrefix, ExPolicyKVStorage exPolicyStorage,
VersioningKVStorage versioningStorage) {
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX);
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX);
ParticipantNode[] parties = initSetting.getConsensusParticipants();
if (parties.length == 0) {
throw new LedgerException("No participant!");
}
// 初始化元数据;
this.metadata = new LedgerMetadataInfo();
this.metadata.setSeed(initSetting.getLedgerSeed());
// 新配置;
this.settings = new LedgerConfiguration(initSetting.getConsensusProvider(), initSetting.getConsensusSettings(),
initSetting.getCryptoSetting());
this.previousSettings = new LedgerConfiguration(settings);
this.previousSettingHash = null;
this.adminDataHash = null;
// 基于原配置初始化参与者列表;
String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX;
this.participants = new ParticipantDataset(previousSettings.getCryptoSetting(), partiPrefix, exPolicyStorage,
versioningStorage);
for (ParticipantNode p : parties) {
this.participants.addConsensusParticipant(p);
}
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX;
this.rolePrivileges = new RolePrivilegeDataset(this.settings.getCryptoSetting(), rolePrivilegePrefix,
exPolicyStorage, versioningStorage);
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX;
this.userRoles = new UserRoleDataset(this.settings.getCryptoSetting(), userRolePrefix, exPolicyStorage,
versioningStorage);
// 初始化其它属性;
this.storage = exPolicyStorage;
this.readonly = false;
}
public LedgerAdminDataset(HashDigest adminAccountHash, String keyPrefix, ExPolicyKVStorage kvStorage,
VersioningKVStorage versioningKVStorage, boolean readonly) {
this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX);
this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX);
this.storage = kvStorage;
this.readonly = readonly;
this.origMetadata = loadAndVerifyMetadata(adminAccountHash);
this.metadata = new LedgerMetadataInfo(origMetadata);
this.settings = loadAndVerifySettings(metadata.getSettingsHash());
// 复制记录一份配置作为上一个区块的原始配置,该实例仅供读取,不做修改,也不会回写到存储;
this.previousSettings = new LedgerConfiguration(settings);
this.previousSettingHash = metadata.getSettingsHash();
this.adminDataHash = adminAccountHash;
String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX;
this.participants = new ParticipantDataset(metadata.getParticipantsHash(), previousSettings.getCryptoSetting(),
partiPrefix, kvStorage, versioningKVStorage, readonly);
String rolePrivilegePrefix = keyPrefix + ROLE_PRIVILEGE_PREFIX;
this.rolePrivileges = new RolePrivilegeDataset(metadata.getRolePrivilegesHash(),
previousSettings.getCryptoSetting(), rolePrivilegePrefix, kvStorage, versioningKVStorage, readonly);
String userRolePrefix = keyPrefix + USER_ROLE_PREFIX;
this.userRoles = new UserRoleDataset(metadata.getUserRolesHash(), previousSettings.getCryptoSetting(),
userRolePrefix, kvStorage, versioningKVStorage, readonly);
}
private LedgerSettings loadAndVerifySettings(HashDigest settingsHash) {
if (settingsHash == null) {
return null;
}
Bytes key = encodeSettingsKey(settingsHash);
byte[] bytes = storage.get(key);
HashFunction hashFunc = Crypto.getHashFunction(settingsHash.getAlgorithm());
if (!hashFunc.verify(settingsHash, bytes)) {
String errorMsg = "Verification of the hash for ledger setting failed! --[HASH=" + key + "]";
LOGGER.error(errorMsg);
throw new LedgerException(errorMsg);
}
return deserializeSettings(bytes);
}
private LedgerSettings deserializeSettings(byte[] bytes) {
return BinaryProtocol.decode(bytes);
}
private byte[] serializeSetting(LedgerSettings setting) {
return BinaryProtocol.encode(setting, LedgerSettings.class);
}
private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) {
Bytes key = encodeMetadataKey(adminAccountHash);
byte[] bytes = storage.get(key);
HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm());
if (!hashFunc.verify(adminAccountHash, bytes)) {
String errorMsg = "Verification of the hash for ledger metadata failed! --[HASH=" + key + "]";
LOGGER.error(errorMsg);
throw new LedgerException(errorMsg);
}
return deserializeMetadata(bytes);
}
private Bytes encodeSettingsKey(HashDigest settingsHash) {
return settingPrefix.concat(settingsHash);
}
private Bytes encodeMetadataKey(HashDigest metadataHash) {
// return LEDGER_META_PREFIX + metadataHash;
// return metaPrefix + metadataHash;
return metaPrefix.concat(metadataHash);
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata()
*/
@Override
public LedgerMetadata_V2 getMetadata() {
return metadata;
}
// /**
// * 返回原来的账本配置;
// *
// * <br>
// * 此方法总是返回从上一个区块加载的账本配置,即时调用 {@link #setLedgerSetting(LedgerSettings)} 做出了新的更改;
// *
// * @return
// */
// public LedgerSettings getPreviousSetting() {
// return previousSettings;
// }
/**
* 返回当前设置的账本配置;
*
* @return
*/
@Override
public LedgerSettings getSettings() {
return settings;
}
/**
* 更新账本配置;
*
* @param ledgerSetting
*/
public void setLedgerSetting(LedgerSettings ledgerSetting) {
if (readonly) {
throw new IllegalArgumentException("This merkle dataset is readonly!");
}
settings = ledgerSetting;
updated = true;
}
@Override
public long getParticipantCount() {
return participants.getParticipantCount();
}
@Override
public ParticipantNode[] getParticipants() {
return participants.getParticipants();
}
@Override
public ParticipantDataset getParticipantDataset() {
return participants;
}
/**
* 加入新的参与方; 如果指定的参与方已经存在,则引发 LedgerException 异常;
*
* @param participant
*/
public void addParticipant(ParticipantNode participant) {
participants.addConsensusParticipant(participant);
}
/**
* 更新参与方的状态参数;
*
* @param participant
*/
public void updateParticipant(ParticipantNode participant) {
participants.updateConsensusParticipant(participant);
}
@Override
public boolean isUpdated() {
return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated();
}
@Override
public void commit() {
if (!isUpdated()) {
return;
}
// 计算并更新参与方集合的根哈希;
participants.commit();
metadata.setParticipantsHash(participants.getRootHash());
// 计算并更新角色权限集合的根哈希;
rolePrivileges.commit();
metadata.setRolePrivilegesHash(rolePrivileges.getRootHash());
// 计算并更新用户角色授权集合的根哈希;
userRoles.commit();
metadata.setUserRolesHash(userRoles.getRootHash());
// 当前区块上下文的密码参数设置的哈希函数;
HashFunction hashFunc = Crypto.getHashFunction(previousSettings.getCryptoSetting().getHashAlgorithm());
// 计算并更新参数配置的哈希;
if (settings == null) {
throw new LedgerException("Missing ledger settings!");
}
byte[] settingsBytes = serializeSetting(settings);
HashDigest settingsHash = hashFunc.hash(settingsBytes);
metadata.setSettingsHash(settingsHash);
if (previousSettingHash == null || !previousSettingHash.equals(settingsHash)) {
Bytes settingsKey = encodeSettingsKey(settingsHash);
boolean nx = storage.set(settingsKey, settingsBytes, ExPolicy.NOT_EXISTING);
if (!nx) {
String base58MetadataHash = settingsHash.toBase58();
// 有可能发生了并发写入冲突,不同的节点都向同一个存储服务器上写入数据;
String errMsg = "Ledger metadata already exist! --[MetadataHash=" + base58MetadataHash + "]";
LOGGER.warn(errMsg);
throw new LedgerException(errMsg);
}
}
// 基于之前的密码配置来计算元数据的哈希;
byte[] metadataBytes = serializeMetadata(metadata);
HashDigest metadataHash = hashFunc.hash(metadataBytes);
if (adminDataHash == null || !adminDataHash.equals(metadataHash)) {
// update modify;
// String base58MetadataHash = metadataHash.toBase58();
// String metadataKey = encodeMetadataKey(base58MetadataHash);
Bytes metadataKey = encodeMetadataKey(metadataHash);
boolean nx = storage.set(metadataKey, metadataBytes, ExPolicy.NOT_EXISTING);
if (!nx) {
String base58MetadataHash = metadataHash.toBase58();
// 有可能发生了并发写入冲突,不同的节点都向同一个存储服务器上写入数据;
String errMsg = "Ledger metadata already exist! --[MetadataHash=" + base58MetadataHash + "]";
LOGGER.warn(errMsg);
throw new LedgerException(errMsg);
}
adminDataHash = metadataHash;
}
updated = false;
}
private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) {
return BinaryProtocol.decode(bytes);
}
private byte[] serializeMetadata(LedgerMetadataInfo config) {
return BinaryProtocol.encode(config, LedgerMetadata_V2.class);
}
@Override
public void cancel() {
if (!isUpdated()) {
return;
}
participants.cancel();
metadata =origMetadata == null ? new LedgerMetadataInfo() : new LedgerMetadataInfo(origMetadata);
}
public static class LedgerMetadataInfo implements LedgerMetadata_V2 {
private byte[] seed;
// private LedgerSetting setting;
private HashDigest participantsHash;
private HashDigest settingsHash;
private HashDigest rolePrivilegesHash;
private HashDigest userRolesHash;
public LedgerMetadataInfo() {
}
public LedgerMetadataInfo(LedgerMetadata_V2 metadata) {
this.seed = metadata.getSeed();
this.participantsHash = metadata.getParticipantsHash();
this.settingsHash = metadata.getSettingsHash();
this.rolePrivilegesHash = metadata.getRolePrivilegesHash();
this.userRolesHash = metadata.getUserRolesHash();
}
@Override
public byte[] getSeed() {
return seed;
}
@Override
public HashDigest getSettingsHash() {
return settingsHash;
}
@Override
public HashDigest getParticipantsHash() {
return participantsHash;
}
@Override
public HashDigest getRolePrivilegesHash() {
return rolePrivilegesHash;
}
@Override
public HashDigest getUserRolesHash() {
return userRolesHash;
}
public void setSeed(byte[] seed) {
this.seed = seed;
}
public void setSettingsHash(HashDigest settingHash) {
this.settingsHash = settingHash;
}
public void setParticipantsHash(HashDigest participantsHash) {
this.participantsHash = participantsHash;
}
public void setRolePrivilegesHash(HashDigest rolePrivilegesHash) {
this.rolePrivilegesHash = rolePrivilegesHash;
}
public void setUserRolesHash(HashDigest userRolesHash) {
this.userRolesHash = userRolesHash;
}
}
}

+ 410
- 410
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java View File

@@ -1,411 +1,411 @@
package com.jd.blockchain.ledger.core;
import java.util.HashMap;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.BlockchainIdentityData;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.ledger.MerkleSnapshot;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.DataEntry;
import com.jd.blockchain.utils.Transactional;
public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<CompositeAccount> {
static {
DataContractRegistry.register(MerkleSnapshot.class);
DataContractRegistry.register(BlockchainIdentity.class);
}
private final Bytes keyPrefix;
/**
* 账户根哈希的数据集;
*/
private MerkleDataSet merkleDataset;
/**
* The cache of latest version accounts, including accounts getting by querying
* and by new regiestering ;
*
*/
// TODO:未考虑大数据量时,由于缺少过期策略,会导致内存溢出的问题;
private Map<Bytes, InnerMerkleAccount> latestAccountsCache = new HashMap<>();
private ExPolicyKVStorage baseExStorage;
private VersioningKVStorage baseVerStorage;
private CryptoSetting cryptoSetting;
private volatile boolean updated;
private AccountAccessPolicy accessPolicy;
public boolean isReadonly() {
return merkleDataset.isReadonly();
}
void setReadonly() {
merkleDataset.setReadonly();
}
public MerkleAccountSet(CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
this(null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy);
}
public MerkleAccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
this.keyPrefix = keyPrefix;
this.cryptoSetting = cryptoSetting;
this.baseExStorage = exStorage;
this.baseVerStorage = verStorage;
this.merkleDataset = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, this.baseExStorage,
this.baseVerStorage, readonly);
this.accessPolicy = accessPolicy;
}
@Override
public HashDigest getRootHash() {
return merkleDataset.getRootHash();
}
@Override
public MerkleProof getProof(Bytes key) {
return merkleDataset.getProof(key);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
DataEntry<Bytes, byte[]>[] results = merkleDataset.getLatestDataEntries(fromIndex, count);
BlockchainIdentity[] ids = new BlockchainIdentity[results.length];
for (int i = 0; i < results.length; i++) {
InnerMerkleAccount account = createAccount(results[i].getKey(), new HashDigest(results[i].getValue()),
results[i].getVersion(), true);
ids[i] = account.getID();
}
return ids;
}
/**
* 返回账户的总数量;
*
* @return
*/
public long getTotal() {
return merkleDataset.getDataCount();
}
@Override
public CompositeAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
/**
* 返回最新版本的 Account;
*
* @param address
* @return
*/
@Override
public CompositeAccount getAccount(Bytes address) {
return this.getAccount(address, -1);
}
/**
* 账户是否存在;<br>
*
* 如果指定的账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过
* {@link #commit()} 方法),此方法对该账户仍然返回 false;
*
* @param address
* @return
*/
public boolean contains(Bytes address) {
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null) {
// 无论是新注册未提交的,还是缓存已提交的账户实例,都认为是存在;
return true;
}
long latestVersion = merkleDataset.getVersion(address);
return latestVersion > -1;
}
/**
* 返回指定账户的版本; <br>
* 如果账户已经注册,则返回该账户的最新版本,值大于等于 0; <br>
* 如果账户不存在,则返回 -1;<br>
* 如果账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过 {@link #commit()}
* 方法),则返回 -1; <br>
*
* @param address
* @return
*/
public long getVersion(Bytes address) {
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null) {
// 已注册尚未提交,也返回 -1;
return acc.getVersion();
}
return merkleDataset.getVersion(address);
}
/**
* 返回指定版本的 Account;
*
* 只有最新版本的账户才能可写的,其它都是只读;
*
* @param address 账户地址;
* @param version 账户版本;如果指定为 -1,则返回最新版本;
* @return
*/
public CompositeAccount getAccount(Bytes address, long version) {
version = version < 0 ? -1 : version;
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null && version == -1) {
return acc;
} else if (acc != null && acc.getVersion() == version) {
return acc;
}
long latestVersion = merkleDataset.getVersion(address);
if (latestVersion < 0) {
// Not exist;
return null;
}
if (version > latestVersion) {
return null;
}
// 如果是不存在的,或者刚刚新增未提交的账户,则前面一步查询到的 latestVersion 小于 0, 代码不会执行到此;
if (acc != null && acc.getVersion() != latestVersion) {
// 当执行到此处时,并且缓冲列表中缓存了最新的版本,
// 如果当前缓存的最新账户的版本和刚刚从存储中检索得到的最新版本不一致,可能存在外部的并发更新,这超出了系统设计的逻辑;
// TODO:如果是今后扩展至集群方案时,这种不一致的原因可能是由其它集群节点实例执行了更新,这种情况下,最好是放弃旧缓存,并重新加载和缓存最新版本;
// by huanghaiquan at 2018-9-2 23:03:00;
throw new IllegalStateException("The latest version in cache is not equals the latest version in storage! "
+ "Mybe some asynchronzing updating are performed out of current server.");
}
// Now, be sure that "acc == null", so get account from storage;
// Set readonly for the old version account;
boolean readonly = (version > -1 && version < latestVersion) || isReadonly();
long qVersion = version == -1 ? latestVersion : version;
// load account from storage;
acc = loadAccount(address, readonly, qVersion);
if (acc == null) {
return null;
}
if (!readonly) {
// cache the latest version witch enable reading and writing;
// readonly version of account not necessary to be cached;
latestAccountsCache.put(address, acc);
}
return acc;
}
public CompositeAccount register(Bytes address, PubKey pubKey) {
return register(new BlockchainIdentityData(address, pubKey));
}
/**
* 注册一个新账户; <br>
*
* 如果账户已经存在,则会引发 {@link LedgerException} 异常; <br>
*
* 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常;
*
* @param address 区块链地址;
* @param pubKey 公钥;
* @return 注册成功的账户对象;
*/
public CompositeAccount register(BlockchainIdentity accountId) {
if (isReadonly()) {
throw new IllegalArgumentException("This AccountSet is readonly!");
}
Bytes address = accountId.getAddress();
PubKey pubKey = accountId.getPubKey();
verifyAddressEncoding(address, pubKey);
InnerMerkleAccount cachedAcc = latestAccountsCache.get(address);
if (cachedAcc != null) {
if (cachedAcc.getVersion() < 0) {
// 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化;
return cachedAcc;
}
// 相同的账户已经存在;
throw new LedgerException("The registering account already exist!");
}
long version = merkleDataset.getVersion(address);
if (version >= 0) {
throw new LedgerException("The registering account already exist!");
}
if (!accessPolicy.checkRegistering(address, pubKey)) {
throw new LedgerException("Account Registering was rejected for the access policy!");
}
Bytes prefix = keyPrefix.concat(address);
InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix);
latestAccountsCache.put(address, acc);
updated = true;
return acc;
}
private void verifyAddressEncoding(Bytes address, PubKey pubKey) {
Bytes chAddress = AddressEncoding.generateAddress(pubKey);
if (!chAddress.equals(address)) {
throw new LedgerException("The registering Address mismatch the specified PubKey!");
}
}
private InnerMerkleAccount createInstance(BlockchainIdentity header, CryptoSetting cryptoSetting, Bytes keyPrefix) {
return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage);
}
/**
* 加载指定版本的账户;
*
* @param address 账户地址;
* @param readonly 是否只读;
* @param version 账户的版本;大于等于 0 ;
* @return
*/
private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) {
byte[] rootHashBytes = merkleDataset.getValue(address, version);
if (rootHashBytes == null) {
return null;
}
HashDigest rootHash = new HashDigest(rootHashBytes);
return createAccount(address, rootHash, version, readonly);
}
private InnerMerkleAccount createAccount(Bytes address, HashDigest rootHash, long version, boolean readonly) {
// prefix;
Bytes prefix = keyPrefix.concat(address);
return new InnerMerkleAccount(address, version, rootHash, cryptoSetting, prefix, baseExStorage, baseVerStorage,
readonly);
}
// TODO:优化:区块链身份(地址+公钥)与其Merkle树根哈希分开独立存储;
// 不必作为一个整块,避免状态数据写入时频繁重写公钥,尤其某些算法的公钥可能很大;
/**
* 保存账户的根哈希,返回账户的新版本;
*
* @param account
* @return
*/
private long saveAccount(InnerMerkleAccount account) {
// 提交更改,更新哈希;
account.commit();
return account.getVersion();
}
@Override
public boolean isUpdated() {
return updated;
}
@Override
public void commit() {
if (!updated) {
return;
}
try {
for (InnerMerkleAccount acc : latestAccountsCache.values()) {
// updated or new created;
if (acc.isUpdated() || acc.getVersion() < 0) {
saveAccount(acc);
}
}
merkleDataset.commit();
} finally {
updated = false;
latestAccountsCache.clear();
}
}
@Override
public void cancel() {
if (!updated) {
return;
}
Bytes[] addresses = new Bytes[latestAccountsCache.size()];
latestAccountsCache.keySet().toArray(addresses);
for (Bytes address : addresses) {
InnerMerkleAccount acc = latestAccountsCache.remove(address);
// cancel;
if (acc.isUpdated()) {
acc.cancel();
}
}
updated = false;
}
/**
* 内部实现的账户,监听和同步账户数据的变更;
*
* @author huanghaiquan
*
*/
private class InnerMerkleAccount extends MerkleAccount {
private long version;
public InnerMerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) {
super(accountID, cryptoSetting, keyPrefix, exStorage, verStorage);
this.version = -1;
}
public InnerMerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting,
Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) {
super(address, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly);
this.version = version;
}
@Override
protected void onUpdated(String key, TypedValue value, long expectedVersion, long newVersion) {
updated = true;
}
@Override
protected void onCommited(HashDigest previousRootHash, HashDigest newRootHash) {
long newVersion = merkleDataset.setValue(this.getAddress(), newRootHash.toBytes(), version);
if (newVersion < 0) {
// Update fail;
throw new LedgerException("Account updating fail! --[Address=" + this.getAddress() + "]");
}
this.version = newVersion;
}
public long getVersion() {
return version;
}
}
package com.jd.blockchain.ledger.core;
import java.util.HashMap;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.BlockchainIdentityData;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.ledger.MerkleSnapshot;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.DataEntry;
import com.jd.blockchain.utils.Transactional;
public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<CompositeAccount> {
static {
DataContractRegistry.register(MerkleSnapshot.class);
DataContractRegistry.register(BlockchainIdentity.class);
}
private final Bytes keyPrefix;
/**
* 账户根哈希的数据集;
*/
private MerkleDataSet merkleDataset;
/**
* The cache of latest version accounts, including accounts getting by querying
* and by new regiestering ;
*
*/
// TODO:未考虑大数据量时,由于缺少过期策略,会导致内存溢出的问题;
private Map<Bytes, InnerMerkleAccount> latestAccountsCache = new HashMap<>();
private ExPolicyKVStorage baseExStorage;
private VersioningKVStorage baseVerStorage;
private CryptoSetting cryptoSetting;
private volatile boolean updated;
private AccountAccessPolicy accessPolicy;
public boolean isReadonly() {
return merkleDataset.isReadonly();
}
void setReadonly() {
merkleDataset.setReadonly();
}
public MerkleAccountSet(CryptoSetting cryptoSetting, Bytes keyPrefix, ExPolicyKVStorage exStorage,
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
this(null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy);
}
public MerkleAccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, Bytes keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
this.keyPrefix = keyPrefix;
this.cryptoSetting = cryptoSetting;
this.baseExStorage = exStorage;
this.baseVerStorage = verStorage;
this.merkleDataset = new MerkleDataSet(rootHash, cryptoSetting, keyPrefix, this.baseExStorage,
this.baseVerStorage, readonly);
this.accessPolicy = accessPolicy;
}
@Override
public HashDigest getRootHash() {
return merkleDataset.getRootHash();
}
@Override
public MerkleProof getProof(Bytes key) {
return merkleDataset.getProof(key);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
DataEntry<Bytes, byte[]>[] results = merkleDataset.getLatestDataEntries(fromIndex, count);
BlockchainIdentity[] ids = new BlockchainIdentity[results.length];
for (int i = 0; i < results.length; i++) {
InnerMerkleAccount account = createAccount(results[i].getKey(), new HashDigest(results[i].getValue()),
results[i].getVersion(), true);
ids[i] = account.getID();
}
return ids;
}
/**
* 返回账户的总数量;
*
* @return
*/
public long getTotal() {
return merkleDataset.getDataCount();
}
@Override
public CompositeAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
/**
* 返回最新版本的 Account;
*
* @param address
* @return
*/
@Override
public CompositeAccount getAccount(Bytes address) {
return this.getAccount(address, -1);
}
/**
* 账户是否存在;<br>
*
* 如果指定的账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过
* {@link #commit()} 方法),此方法对该账户仍然返回 false;
*
* @param address
* @return
*/
public boolean contains(Bytes address) {
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null) {
// 无论是新注册未提交的,还是缓存已提交的账户实例,都认为是存在;
return true;
}
long latestVersion = merkleDataset.getVersion(address);
return latestVersion > -1;
}
/**
* 返回指定账户的版本; <br>
* 如果账户已经注册,则返回该账户的最新版本,值大于等于 0; <br>
* 如果账户不存在,则返回 -1;<br>
* 如果账户已经注册(通过 {@link #register(String, PubKey)} 方法),但尚未提交(通过 {@link #commit()}
* 方法),则返回 -1; <br>
*
* @param address
* @return
*/
public long getVersion(Bytes address) {
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null) {
// 已注册尚未提交,也返回 -1;
return acc.getVersion();
}
return merkleDataset.getVersion(address);
}
/**
* 返回指定版本的 Account;
*
* 只有最新版本的账户才能可写的,其它都是只读;
*
* @param address 账户地址;
* @param version 账户版本;如果指定为 -1,则返回最新版本;
* @return
*/
public CompositeAccount getAccount(Bytes address, long version) {
version = version < 0 ? -1 : version;
InnerMerkleAccount acc = latestAccountsCache.get(address);
if (acc != null && version == -1) {
return acc;
} else if (acc != null && acc.getVersion() == version) {
return acc;
}
long latestVersion = merkleDataset.getVersion(address);
if (latestVersion < 0) {
// Not exist;
return null;
}
if (version > latestVersion) {
return null;
}
// 如果是不存在的,或者刚刚新增未提交的账户,则前面一步查询到的 latestVersion 小于 0, 代码不会执行到此;
if (acc != null && acc.getVersion() != latestVersion) {
// 当执行到此处时,并且缓冲列表中缓存了最新的版本,
// 如果当前缓存的最新账户的版本和刚刚从存储中检索得到的最新版本不一致,可能存在外部的并发更新,这超出了系统设计的逻辑;
// TODO:如果是今后扩展至集群方案时,这种不一致的原因可能是由其它集群节点实例执行了更新,这种情况下,最好是放弃旧缓存,并重新加载和缓存最新版本;
// by huanghaiquan at 2018-9-2 23:03:00;
throw new IllegalStateException("The latest version in cache is not equals the latest version in storage! "
+ "Mybe some asynchronzing updating are performed out of current server.");
}
// Now, be sure that "acc == null", so get account from storage;
// Set readonly for the old version account;
boolean readonly = (version > -1 && version < latestVersion) || isReadonly();
long qVersion = version == -1 ? latestVersion : version;
// load account from storage;
acc = loadAccount(address, readonly, qVersion);
if (acc == null) {
return null;
}
if (!readonly) {
// cache the latest version witch enable reading and writing;
// readonly version of account not necessary to be cached;
latestAccountsCache.put(address, acc);
}
return acc;
}
public CompositeAccount register(Bytes address, PubKey pubKey) {
return register(new BlockchainIdentityData(address, pubKey));
}
/**
* 注册一个新账户; <br>
*
* 如果账户已经存在,则会引发 {@link LedgerException} 异常; <br>
*
* 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常;
*
* @param address 区块链地址;
* @param pubKey 公钥;
* @return 注册成功的账户对象;
*/
public CompositeAccount register(BlockchainIdentity accountId) {
if (isReadonly()) {
throw new IllegalArgumentException("This AccountSet is readonly!");
}
Bytes address = accountId.getAddress();
PubKey pubKey = accountId.getPubKey();
verifyAddressEncoding(address, pubKey);
InnerMerkleAccount cachedAcc = latestAccountsCache.get(address);
if (cachedAcc != null) {
if (cachedAcc.getVersion() < 0) {
// 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化;
return cachedAcc;
}
// 相同的账户已经存在;
throw new LedgerException("The registering account already exist!");
}
long version = merkleDataset.getVersion(address);
if (version >= 0) {
throw new LedgerException("The registering account already exist!");
}
if (!accessPolicy.checkRegistering(address, pubKey)) {
throw new LedgerException("Account Registering was rejected for the access policy!");
}
Bytes prefix = keyPrefix.concat(address);
InnerMerkleAccount acc = createInstance(accountId, cryptoSetting, prefix);
latestAccountsCache.put(address, acc);
updated = true;
return acc;
}
private void verifyAddressEncoding(Bytes address, PubKey pubKey) {
Bytes chAddress = AddressEncoding.generateAddress(pubKey);
if (!chAddress.equals(address)) {
throw new LedgerException("The registering Address mismatch the specified PubKey!");
}
}
private InnerMerkleAccount createInstance(BlockchainIdentity header, CryptoSetting cryptoSetting, Bytes keyPrefix) {
return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage);
}
/**
* 加载指定版本的账户;
*
* @param address 账户地址;
* @param readonly 是否只读;
* @param version 账户的版本;大于等于 0 ;
* @return
*/
private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) {
byte[] rootHashBytes = merkleDataset.getValue(address, version);
if (rootHashBytes == null) {
return null;
}
HashDigest rootHash = new HashDigest(rootHashBytes);
return createAccount(address, rootHash, version, readonly);
}
private InnerMerkleAccount createAccount(Bytes address, HashDigest rootHash, long version, boolean readonly) {
// prefix;
Bytes prefix = keyPrefix.concat(address);
return new InnerMerkleAccount(address, version, rootHash, cryptoSetting, prefix, baseExStorage, baseVerStorage,
readonly);
}
// TODO:优化:区块链身份(地址+公钥)与其Merkle树根哈希分开独立存储;
// 不必作为一个整块,避免状态数据写入时频繁重写公钥,尤其某些算法的公钥可能很大;
/**
* 保存账户的根哈希,返回账户的新版本;
*
* @param account
* @return
*/
private long saveAccount(InnerMerkleAccount account) {
// 提交更改,更新哈希;
account.commit();
return account.getVersion();
}
@Override
public boolean isUpdated() {
return updated;
}
@Override
public void commit() {
if (!updated) {
return;
}
try {
for (InnerMerkleAccount acc : latestAccountsCache.values()) {
// updated or new created;
if (acc.isUpdated() || acc.getVersion() < 0) {
saveAccount(acc);
}
}
merkleDataset.commit();
} finally {
updated = false;
latestAccountsCache.clear();
}
}
@Override
public void cancel() {
if (!updated) {
return;
}
Bytes[] addresses = new Bytes[latestAccountsCache.size()];
latestAccountsCache.keySet().toArray(addresses);
for (Bytes address : addresses) {
InnerMerkleAccount acc = latestAccountsCache.remove(address);
// cancel;
if (acc.isUpdated()) {
acc.cancel();
}
}
updated = false;
}
/**
* 内部实现的账户,监听和同步账户数据的变更;
*
* @author huanghaiquan
*
*/
private class InnerMerkleAccount extends MerkleAccount {
private long version;
public InnerMerkleAccount(BlockchainIdentity accountID, CryptoSetting cryptoSetting, Bytes keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) {
super(accountID, cryptoSetting, keyPrefix, exStorage, verStorage);
this.version = -1;
}
public InnerMerkleAccount(Bytes address, long version, HashDigest dataRootHash, CryptoSetting cryptoSetting,
Bytes keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) {
super(address, dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly);
this.version = version;
}
@Override
protected void onUpdated(String key, TypedValue value, long expectedVersion, long newVersion) {
updated = true;
}
@Override
protected void onCommited(HashDigest previousRootHash, HashDigest newRootHash) {
long newVersion = merkleDataset.setValue(this.getAddress(), newRootHash.toBytes(), version);
if (newVersion < 0) {
// Update fail;
throw new LedgerException("Account updating fail! --[Address=" + this.getAddress() + "]");
}
this.version = newVersion;
}
public long getVersion() {
return version;
}
}
}

+ 739
- 739
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataSet.java
File diff suppressed because it is too large
View File


+ 10
- 10
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Node.java View File

@@ -1,11 +1,11 @@
package com.jd.blockchain.ledger.core;
public class Node {
public Node(){
}
package com.jd.blockchain.ledger.core;
public class Node {
public Node(){
}
}

+ 72
- 72
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ParticipantCertData.java View File

@@ -1,73 +1,73 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.ledger.ParticipantNodeState;
/**
* 参与方证书数据对象;
*
* @author huanghaiquan
*
*/
public class ParticipantCertData implements ParticipantNode {
private int id;
private Bytes address;
private String name;
private PubKey pubKey;
private ParticipantNodeState participantNodeState;
public ParticipantCertData() {
}
public ParticipantCertData(ParticipantNode participantNode) {
this.id = participantNode.getId();
this.address = participantNode.getAddress();
this.name = participantNode.getName();
this.pubKey = participantNode.getPubKey();
this.participantNodeState = participantNode.getParticipantNodeState();
}
public ParticipantCertData(Bytes address, String name, PubKey pubKey, ParticipantNodeState participantNodeState) {
this.address = address;
this.name = name;
this.pubKey = pubKey;
this.participantNodeState = participantNodeState;
}
@Override
public Bytes getAddress() {
return address;
}
@Override
public String getName() {
return name;
}
@Override
public PubKey getPubKey() {
return pubKey;
}
@Override
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public ParticipantNodeState getParticipantNodeState() {
return participantNodeState;
}
public void setParticipantNodeState(ParticipantNodeState participantNodeState) {
this.participantNodeState = participantNodeState;
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.ledger.ParticipantNodeState;
/**
* 参与方证书数据对象;
*
* @author huanghaiquan
*
*/
public class ParticipantCertData implements ParticipantNode {
private int id;
private Bytes address;
private String name;
private PubKey pubKey;
private ParticipantNodeState participantNodeState;
public ParticipantCertData() {
}
public ParticipantCertData(ParticipantNode participantNode) {
this.id = participantNode.getId();
this.address = participantNode.getAddress();
this.name = participantNode.getName();
this.pubKey = participantNode.getPubKey();
this.participantNodeState = participantNode.getParticipantNodeState();
}
public ParticipantCertData(Bytes address, String name, PubKey pubKey, ParticipantNodeState participantNodeState) {
this.address = address;
this.name = name;
this.pubKey = pubKey;
this.participantNodeState = participantNodeState;
}
@Override
public Bytes getAddress() {
return address;
}
@Override
public String getName() {
return name;
}
@Override
public PubKey getPubKey() {
return pubKey;
}
@Override
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public ParticipantNodeState getParticipantNodeState() {
return participantNodeState;
}
public void setParticipantNodeState(ParticipantNodeState participantNodeState) {
this.participantNodeState = participantNodeState;
}
}

+ 21
- 21
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/Peer.java View File

@@ -1,22 +1,22 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.ledger.ParticipantNode;
/**
* @author hhq
* @version 1.0
* @created 14-6��-2018 12:13:33
*/
public class Peer extends Node {
public ParticipantNode m_Participant;
public Peer(){
}
public void finalize() throws Throwable {
super.finalize();
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.ledger.ParticipantNode;
/**
* @author hhq
* @version 1.0
* @created 14-6��-2018 12:13:33
*/
public class Peer extends Node {
public ParticipantNode m_Participant;
public Peer(){
}
public void finalize() throws Throwable {
super.finalize();
}
}

+ 84
- 84
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java View File

@@ -1,85 +1,85 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.ledger.UserInfo;
import com.jd.blockchain.utils.Bytes;
/**
* 用户账户;
*
* @author huanghaiquan
*
*/
public class UserAccount extends AccountDecorator implements UserInfo { // implements UserInfo {
private static final String USER_INFO_PREFIX = "PROP" + LedgerConsts.KEY_SEPERATOR;
private static final String DATA_PUB_KEY = "DATA-PUBKEY";
public UserAccount(CompositeAccount baseAccount) {
super(baseAccount);
}
private PubKey dataPubKey;
@Override
public Bytes getAddress() {
return getID().getAddress();
}
@Override
public PubKey getPubKey() {
return getID().getPubKey();
}
@Override
public PubKey getDataPubKey() {
if (dataPubKey == null) {
BytesValue pkBytes = getHeaders().getValue(DATA_PUB_KEY);
if (pkBytes == null) {
return null;
}
dataPubKey = new PubKey(pkBytes.getBytes().toBytes());
}
return dataPubKey;
}
public void setDataPubKey(PubKey pubKey) {
long version = getHeaders().getVersion(DATA_PUB_KEY);
setDataPubKey(pubKey, version);
}
public void setDataPubKey(PubKey pubKey, long version) {
TypedValue value = TypedValue.fromPubKey(dataPubKey);
long newVersion = getHeaders().setValue(DATA_PUB_KEY, value, version);
if (newVersion > -1) {
dataPubKey = pubKey;
} else {
throw new LedgerException("Data public key was updated failed!");
}
}
public long setProperty(String key, String value, long version) {
return getHeaders().setValue(encodePropertyKey(key), TypedValue.fromText(value), version);
}
public String getProperty(String key) {
BytesValue value = getHeaders().getValue(encodePropertyKey(key));
return value == null ? null : value.getBytes().toUTF8String();
}
public String getProperty(String key, long version) {
BytesValue value = getHeaders().getValue(encodePropertyKey(key), version);
return value == null ? null : value.getBytes().toUTF8String();
}
private String encodePropertyKey(String key) {
return USER_INFO_PREFIX+key;
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.ledger.UserInfo;
import com.jd.blockchain.utils.Bytes;
/**
* 用户账户;
*
* @author huanghaiquan
*
*/
public class UserAccount extends AccountDecorator implements UserInfo { // implements UserInfo {
private static final String USER_INFO_PREFIX = "PROP" + LedgerConsts.KEY_SEPERATOR;
private static final String DATA_PUB_KEY = "DATA-PUBKEY";
public UserAccount(CompositeAccount baseAccount) {
super(baseAccount);
}
private PubKey dataPubKey;
@Override
public Bytes getAddress() {
return getID().getAddress();
}
@Override
public PubKey getPubKey() {
return getID().getPubKey();
}
@Override
public PubKey getDataPubKey() {
if (dataPubKey == null) {
BytesValue pkBytes = getHeaders().getValue(DATA_PUB_KEY);
if (pkBytes == null) {
return null;
}
dataPubKey = new PubKey(pkBytes.getBytes().toBytes());
}
return dataPubKey;
}
public void setDataPubKey(PubKey pubKey) {
long version = getHeaders().getVersion(DATA_PUB_KEY);
setDataPubKey(pubKey, version);
}
public void setDataPubKey(PubKey pubKey, long version) {
TypedValue value = TypedValue.fromPubKey(dataPubKey);
long newVersion = getHeaders().setValue(DATA_PUB_KEY, value, version);
if (newVersion > -1) {
dataPubKey = pubKey;
} else {
throw new LedgerException("Data public key was updated failed!");
}
}
public long setProperty(String key, String value, long version) {
return getHeaders().setValue(encodePropertyKey(key), TypedValue.fromText(value), version);
}
public String getProperty(String key) {
BytesValue value = getHeaders().getValue(encodePropertyKey(key));
return value == null ? null : value.getBytes().toUTF8String();
}
public String getProperty(String key, long version) {
BytesValue value = getHeaders().getValue(encodePropertyKey(key), version);
return value == null ? null : value.getBytes().toUTF8String();
}
private String encodePropertyKey(String key) {
return USER_INFO_PREFIX+key;
}
}

+ 120
- 120
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java View File

@@ -1,121 +1,121 @@
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
/**
* @author huanghaiquan
*
*/
public class UserAccountSet implements Transactional, UserAccountQuery {
private MerkleAccountSet accountSet;
public UserAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage simpleStorage,
VersioningKVStorage versioningStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(keyPrefix), simpleStorage, versioningStorage,
accessPolicy);
}
public UserAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(keyPrefix), exStorage,
verStorage, readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
/**
* 返回用户总数;
*
* @return
*/
@Override
public long getTotal() {
return accountSet.getTotal();
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
@Override
public MerkleProof getProof(Bytes key) {
return accountSet.getProof(key);
}
@Override
public UserAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
@Override
public UserAccount getAccount(Bytes address) {
CompositeAccount baseAccount = accountSet.getAccount(address);
return new UserAccount(baseAccount);
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
@Override
public UserAccount getAccount(Bytes address, long version) {
CompositeAccount baseAccount = accountSet.getAccount(address, version);
return new UserAccount(baseAccount);
}
/**
* 注册一个新用户; <br>
*
* 如果用户已经存在,则会引发 {@link LedgerException} 异常; <br>
*
* 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常;
*
* @param address 区块链地址;
* @param pubKey 公钥;
* @return 注册成功的用户对象;
*/
public UserAccount register(Bytes address, PubKey pubKey) {
CompositeAccount baseAccount = accountSet.register(address, pubKey);
return new UserAccount(baseAccount);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
package com.jd.blockchain.ledger.core;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.LedgerException;
import com.jd.blockchain.ledger.MerkleProof;
import com.jd.blockchain.storage.service.ExPolicyKVStorage;
import com.jd.blockchain.storage.service.VersioningKVStorage;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.Transactional;
/**
* @author huanghaiquan
*
*/
public class UserAccountSet implements Transactional, UserAccountQuery {
private MerkleAccountSet accountSet;
public UserAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage simpleStorage,
VersioningKVStorage versioningStorage, AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(cryptoSetting, Bytes.fromString(keyPrefix), simpleStorage, versioningStorage,
accessPolicy);
}
public UserAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix,
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
AccountAccessPolicy accessPolicy) {
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, Bytes.fromString(keyPrefix), exStorage,
verStorage, readonly, accessPolicy);
}
@Override
public BlockchainIdentity[] getHeaders(int fromIndex, int count) {
return accountSet.getHeaders(fromIndex, count);
}
/**
* 返回用户总数;
*
* @return
*/
@Override
public long getTotal() {
return accountSet.getTotal();
}
public boolean isReadonly() {
return accountSet.isReadonly();
}
void setReadonly() {
accountSet.setReadonly();
}
@Override
public HashDigest getRootHash() {
return accountSet.getRootHash();
}
@Override
public MerkleProof getProof(Bytes key) {
return accountSet.getProof(key);
}
@Override
public UserAccount getAccount(String address) {
return getAccount(Bytes.fromBase58(address));
}
@Override
public UserAccount getAccount(Bytes address) {
CompositeAccount baseAccount = accountSet.getAccount(address);
return new UserAccount(baseAccount);
}
@Override
public boolean contains(Bytes address) {
return accountSet.contains(address);
}
@Override
public UserAccount getAccount(Bytes address, long version) {
CompositeAccount baseAccount = accountSet.getAccount(address, version);
return new UserAccount(baseAccount);
}
/**
* 注册一个新用户; <br>
*
* 如果用户已经存在,则会引发 {@link LedgerException} 异常; <br>
*
* 如果指定的地址和公钥不匹配,则会引发 {@link LedgerException} 异常;
*
* @param address 区块链地址;
* @param pubKey 公钥;
* @return 注册成功的用户对象;
*/
public UserAccount register(Bytes address, PubKey pubKey) {
CompositeAccount baseAccount = accountSet.register(address, pubKey);
return new UserAccount(baseAccount);
}
@Override
public boolean isUpdated() {
return accountSet.isUpdated();
}
@Override
public void commit() {
accountSet.commit();
}
@Override
public void cancel() {
accountSet.cancel();
}
}

+ 42
- 42
source/ledger/ledger-model/pom.xml View File

@@ -1,43 +1,43 @@
<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>ledger</artifactId>
<version>1.1.2.RELEASE</version>
</parent>
<artifactId>ledger-model</artifactId>
<dependencies>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>utils-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>utils-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>binary-proto</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-framework</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-classic</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<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>ledger</artifactId>
<version>1.1.2.RELEASE</version>
</parent>
<artifactId>ledger-model</artifactId>
<dependencies>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>utils-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>utils-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>binary-proto</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-framework</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-classic</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

+ 14
- 14
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/Contract.java View File

@@ -1,14 +1,14 @@
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Contract {
String name() default "";
}
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Contract {
String name() default "";
}

+ 14
- 14
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractEvent.java View File

@@ -1,14 +1,14 @@
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ContractEvent {
String name() default "";
}
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ContractEvent {
String name() default "";
}

+ 15
- 15
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventHandle.java View File

@@ -1,15 +1,15 @@
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandle {
}
package com.jd.blockchain.contract;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandle {
}

+ 33
- 33
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockRollbackException.java View File

@@ -1,33 +1,33 @@
package com.jd.blockchain.ledger;
public class BlockRollbackException extends LedgerException {
private static final long serialVersionUID = 3583192000738807503L;
private TransactionState state;
public BlockRollbackException(String message) {
this(TransactionState.SYSTEM_ERROR, message);
}
public BlockRollbackException(TransactionState state, String message) {
super(message);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public BlockRollbackException(String message, Throwable cause) {
this(TransactionState.SYSTEM_ERROR, message, cause);
}
public BlockRollbackException(TransactionState state, String message, Throwable cause) {
super(message, cause);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public TransactionState getState() {
return state;
}
}
package com.jd.blockchain.ledger;
public class BlockRollbackException extends LedgerException {
private static final long serialVersionUID = 3583192000738807503L;
private TransactionState state;
public BlockRollbackException(String message) {
this(TransactionState.SYSTEM_ERROR, message);
}
public BlockRollbackException(TransactionState state, String message) {
super(message);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public BlockRollbackException(String message, Throwable cause) {
this(TransactionState.SYSTEM_ERROR, message, cause);
}
public BlockRollbackException(TransactionState state, String message, Throwable cause) {
super(message, cause);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public TransactionState getState() {
return state;
}
}

+ 83
- 83
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainEventType.java View File

@@ -1,83 +1,83 @@
package com.jd.blockchain.ledger;
/**
* 区块链事件类型;<p>
*
* 每一种事件类型都包含一个事件码;<p>
*
* 在一次事件消息中,可以包含多种事件,而且事件之间具有嵌套关系;<br>
*
* 例如:<p>
*
* 一个区块生成事件 {@link #BLOCK_GENERATED} 含了交易提交事件
* {@link #TRANSACTION_COMMITED};<p>
*
* 交易提交事件 {@link #TRANSACTION_COMMITED} 必然包含账户更新事件 {@link #ACCOUNT_UPDATED};<p>
*
* 更进一步,账户更新事件 {@link #ACCOUNT_UPDATED} 也必然包含了权限更新事件
* {@link #PRIVILEGE_UPDATED}、负载数据更新事件 {@link #PAYLOAD_UPDATED}
* 、合约脚本更新事件{@link #SCRIPT_UPDATED} 、合约脚本执行事件{@link #SCRIPT_INVOKED} 这4种事件中的一种或者多种事件;<p>
*
* 这种嵌套关系,表现在事件的编码中是子事件码的比特位中包含了上级事件码;
*
* @author huanghaiquan
*
*/
public enum BlockchainEventType {
/**
* 生成新区块;<br>
*
* 事件码:1 (0x01)
*
*/
BLOCK_GENERATED(1),
/**
* 成功提交新交易;<br>
*
* 事件码:3 (0x03)
*/
TRANSACTION_COMMITED(3),
/**
* 账户的版本已更新;<br>
*
* 事件码:259 (0x103)
*/
ACCOUNT_UPDATED(259),
/**
* 账户权限已被更新;<br>
*
* 事件码:65795 (0x10103)
*/
PRIVILEGE_UPDATED(65795),
/**
* 账户负载数据已被更新;<br>
*
* 事件码:131331 (0x20103)
*/
PAYLOAD_UPDATED(131331),
/**
* 合约脚本已被更新;<br>
*
* 事件码:262403 (0x40103)
*/
SCRIPT_UPDATED(262403),
/**
* 合约脚本已被调用;<br>
*
* 事件码:524547 (0x80103)
*/
SCRIPT_INVOKED(524547);
public final int CODE;
private BlockchainEventType(int code) {
this.CODE = code;
}
}
package com.jd.blockchain.ledger;
/**
* 区块链事件类型;<p>
*
* 每一种事件类型都包含一个事件码;<p>
*
* 在一次事件消息中,可以包含多种事件,而且事件之间具有嵌套关系;<br>
*
* 例如:<p>
*
* 一个区块生成事件 {@link #BLOCK_GENERATED} 含了交易提交事件
* {@link #TRANSACTION_COMMITED};<p>
*
* 交易提交事件 {@link #TRANSACTION_COMMITED} 必然包含账户更新事件 {@link #ACCOUNT_UPDATED};<p>
*
* 更进一步,账户更新事件 {@link #ACCOUNT_UPDATED} 也必然包含了权限更新事件
* {@link #PRIVILEGE_UPDATED}、负载数据更新事件 {@link #PAYLOAD_UPDATED}
* 、合约脚本更新事件{@link #SCRIPT_UPDATED} 、合约脚本执行事件{@link #SCRIPT_INVOKED} 这4种事件中的一种或者多种事件;<p>
*
* 这种嵌套关系,表现在事件的编码中是子事件码的比特位中包含了上级事件码;
*
* @author huanghaiquan
*
*/
public enum BlockchainEventType {
/**
* 生成新区块;<br>
*
* 事件码:1 (0x01)
*
*/
BLOCK_GENERATED(1),
/**
* 成功提交新交易;<br>
*
* 事件码:3 (0x03)
*/
TRANSACTION_COMMITED(3),
/**
* 账户的版本已更新;<br>
*
* 事件码:259 (0x103)
*/
ACCOUNT_UPDATED(259),
/**
* 账户权限已被更新;<br>
*
* 事件码:65795 (0x10103)
*/
PRIVILEGE_UPDATED(65795),
/**
* 账户负载数据已被更新;<br>
*
* 事件码:131331 (0x20103)
*/
PAYLOAD_UPDATED(131331),
/**
* 合约脚本已被更新;<br>
*
* 事件码:262403 (0x40103)
*/
SCRIPT_UPDATED(262403),
/**
* 合约脚本已被调用;<br>
*
* 事件码:524547 (0x80103)
*/
SCRIPT_INVOKED(524547);
public final int CODE;
private BlockchainEventType(int code) {
this.CODE = code;
}
}

+ 216
- 216
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainIdentityData.java View File

@@ -1,216 +1,216 @@
package com.jd.blockchain.ledger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.CryptoAlgorithm;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.ByteArray;
import com.jd.blockchain.utils.io.BytesEncoding;
import com.jd.blockchain.utils.io.BytesReader;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.BytesWriter;
import com.jd.blockchain.utils.io.RuntimeIOException;
/**
* 区块链身份;
*
* @author huanghaiquan
*
*/
public class BlockchainIdentityData implements BytesWriter, BytesReader, Externalizable, BlockchainIdentity {
private Bytes address;
private PubKey pubKey;
private BlockchainIdentityData() {
}
public BlockchainIdentityData(PubKey pubKey) {
this.pubKey = pubKey;
this.address = AddressEncoding.generateAddress(pubKey);
}
public BlockchainIdentityData(CryptoAlgorithm algorithm, ByteArray pubKeyBytes) {
this.pubKey = new PubKey(algorithm, pubKeyBytes.bytes());
this.address = AddressEncoding.generateAddress(pubKey);
}
public BlockchainIdentityData(Bytes address, PubKey pubKey) {
if (!verifyAddress(address, pubKey)) {
throw new IllegalArgumentException("Blockchain address is mismatch with the pub-key!");
}
this.address = address;
this.pubKey = pubKey;
}
public static boolean verifyAddress(Bytes address, PubKey pubKey) {
Bytes addr = AddressEncoding.generateAddress(pubKey);
return addr.equals(address);
}
@Override
public void resolvFrom(InputStream in) throws IOException {
Bytes addr = AddressEncoding.readAddress(in);
byte[] value = BytesEncoding.readInShort(in);
PubKey pk = new PubKey(value);
this.address = addr;
this.pubKey = pk;
}
@Override
public void writeTo(OutputStream out) throws IOException {
AddressEncoding.writeAddress(address, out);
BytesEncoding.writeInShort(pubKey.toBytes(), out);
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.BlockchainIdentity#getAddress()
*/
@Override
public Bytes getAddress() {
return address;
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.BlockchainIdentity#getPubKey()
*/
@Override
public PubKey getPubKey() {
return pubKey;
}
public static BlockchainIdentity resolveFrom(ByteArray bytes) {
try {
BlockchainIdentityData id = new BlockchainIdentityData();
id.resolvFrom(bytes.asInputStream());
return id;
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public static ByteArray toBytes(List<BlockchainIdentityData> identities) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BytesUtils.writeInt(identities.size(), out);
for (BlockchainIdentityData identity : identities) {
identity.writeTo(out);
}
return ByteArray.wrap(out.toByteArray());
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public static List<BlockchainIdentityData> resolveIdentitiesFrom(ByteArray bytes) {
try {
InputStream in = bytes.asInputStream();
int identitiesLen = BytesUtils.readInt(in);
List<BlockchainIdentityData> identities = new ArrayList<>();
for (int i = 0; i < identitiesLen; i++) {
BlockchainIdentityData id = new BlockchainIdentityData();
id.resolvFrom(in);
identities.add(id);
}
return identities;
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public ByteArray toBytes() {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeTo(out);
return ByteArray.wrap(out.toByteArray());
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
@Override
public int hashCode() {
return address.hashCode();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof BlockchainIdentityData)) {
return false;
}
BlockchainIdentity identity = (BlockchainIdentity) other;
if (!getAddress().equals(identity.getAddress())) {
return false;
}
return pubKey.equals(identity.getPubKey());
}
/**
* The object implements the writeExternal method to save its contents by
* calling the methods of DataOutput for its primitive values or calling the
* writeObject method of ObjectOutput for objects, strings, and arrays.
*
* @param out
* the stream to write the object to
* @throws IOException
* Includes any I/O exceptions that may occur
* @serialData Overriding methods should use this tag to describe the data
* layout of this Externalizable object. List the sequence of
* element types and, if possible, relate the element to a
* public/protected field and/or method of this Externalizable
* class.
*/
@Override
public void writeExternal(ObjectOutput out) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
writeTo(os);
byte[] bts = os.toByteArray();
out.writeInt(bts.length);
out.write(bts);
}
/**
* The object implements the readExternal method to restore its contents by
* calling the methods of DataInput for primitive types and readObject for
* objects, strings and arrays. The readExternal method must read the values in
* the same sequence and with the same types as were written by writeExternal.
*
* @param in
* the stream to read data from in order to restore the object
* @throws IOException
* if I/O errors occur
* @throws ClassNotFoundException
* If the class for an object being restored cannot be found.
*/
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
int len = in.readInt();
byte[] bts = new byte[len];
in.readFully(bts);
this.resolvFrom(new ByteArrayInputStream(bts));
}
}
package com.jd.blockchain.ledger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.CryptoAlgorithm;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.ByteArray;
import com.jd.blockchain.utils.io.BytesEncoding;
import com.jd.blockchain.utils.io.BytesReader;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.BytesWriter;
import com.jd.blockchain.utils.io.RuntimeIOException;
/**
* 区块链身份;
*
* @author huanghaiquan
*
*/
public class BlockchainIdentityData implements BytesWriter, BytesReader, Externalizable, BlockchainIdentity {
private Bytes address;
private PubKey pubKey;
private BlockchainIdentityData() {
}
public BlockchainIdentityData(PubKey pubKey) {
this.pubKey = pubKey;
this.address = AddressEncoding.generateAddress(pubKey);
}
public BlockchainIdentityData(CryptoAlgorithm algorithm, ByteArray pubKeyBytes) {
this.pubKey = new PubKey(algorithm, pubKeyBytes.bytes());
this.address = AddressEncoding.generateAddress(pubKey);
}
public BlockchainIdentityData(Bytes address, PubKey pubKey) {
if (!verifyAddress(address, pubKey)) {
throw new IllegalArgumentException("Blockchain address is mismatch with the pub-key!");
}
this.address = address;
this.pubKey = pubKey;
}
public static boolean verifyAddress(Bytes address, PubKey pubKey) {
Bytes addr = AddressEncoding.generateAddress(pubKey);
return addr.equals(address);
}
@Override
public void resolvFrom(InputStream in) throws IOException {
Bytes addr = AddressEncoding.readAddress(in);
byte[] value = BytesEncoding.readInShort(in);
PubKey pk = new PubKey(value);
this.address = addr;
this.pubKey = pk;
}
@Override
public void writeTo(OutputStream out) throws IOException {
AddressEncoding.writeAddress(address, out);
BytesEncoding.writeInShort(pubKey.toBytes(), out);
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.BlockchainIdentity#getAddress()
*/
@Override
public Bytes getAddress() {
return address;
}
/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.BlockchainIdentity#getPubKey()
*/
@Override
public PubKey getPubKey() {
return pubKey;
}
public static BlockchainIdentity resolveFrom(ByteArray bytes) {
try {
BlockchainIdentityData id = new BlockchainIdentityData();
id.resolvFrom(bytes.asInputStream());
return id;
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public static ByteArray toBytes(List<BlockchainIdentityData> identities) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BytesUtils.writeInt(identities.size(), out);
for (BlockchainIdentityData identity : identities) {
identity.writeTo(out);
}
return ByteArray.wrap(out.toByteArray());
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public static List<BlockchainIdentityData> resolveIdentitiesFrom(ByteArray bytes) {
try {
InputStream in = bytes.asInputStream();
int identitiesLen = BytesUtils.readInt(in);
List<BlockchainIdentityData> identities = new ArrayList<>();
for (int i = 0; i < identitiesLen; i++) {
BlockchainIdentityData id = new BlockchainIdentityData();
id.resolvFrom(in);
identities.add(id);
}
return identities;
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
public ByteArray toBytes() {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeTo(out);
return ByteArray.wrap(out.toByteArray());
} catch (IOException e) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
@Override
public int hashCode() {
return address.hashCode();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof BlockchainIdentityData)) {
return false;
}
BlockchainIdentity identity = (BlockchainIdentity) other;
if (!getAddress().equals(identity.getAddress())) {
return false;
}
return pubKey.equals(identity.getPubKey());
}
/**
* The object implements the writeExternal method to save its contents by
* calling the methods of DataOutput for its primitive values or calling the
* writeObject method of ObjectOutput for objects, strings, and arrays.
*
* @param out
* the stream to write the object to
* @throws IOException
* Includes any I/O exceptions that may occur
* @serialData Overriding methods should use this tag to describe the data
* layout of this Externalizable object. List the sequence of
* element types and, if possible, relate the element to a
* public/protected field and/or method of this Externalizable
* class.
*/
@Override
public void writeExternal(ObjectOutput out) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
writeTo(os);
byte[] bts = os.toByteArray();
out.writeInt(bts.length);
out.write(bts);
}
/**
* The object implements the readExternal method to restore its contents by
* calling the methods of DataInput for primitive types and readObject for
* objects, strings and arrays. The readExternal method must read the values in
* the same sequence and with the same types as were written by writeExternal.
*
* @param in
* the stream to read data from in order to restore the object
* @throws IOException
* if I/O errors occur
* @throws ClassNotFoundException
* If the class for an object being restored cannot be found.
*/
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
int len = in.readInt();
byte[] bts = new byte[len];
in.readFully(bts);
this.resolvFrom(new ByteArrayInputStream(bts));
}
}

+ 40
- 40
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainKeyGenerator.java View File

@@ -1,40 +1,40 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.CryptoAlgorithm;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.SignatureFunction;
/**
* 区块链密钥生成器;
*
* @author huanghaiquan
*
*/
public class BlockchainKeyGenerator {
public static final String DEFAULT_ALGORITHM = "ED25519";
private BlockchainKeyGenerator() {
}
public static BlockchainKeyGenerator getInstance() {
return new BlockchainKeyGenerator();
}
public BlockchainKeypair generate() {
return generate(DEFAULT_ALGORITHM);
}
public BlockchainKeypair generate(String algorithmName) {
CryptoAlgorithm algorithm = Crypto.getAlgorithm(algorithmName);
return generate(algorithm);
}
public BlockchainKeypair generate(CryptoAlgorithm signatureAlgorithm) {
SignatureFunction signFunc = Crypto.getSignatureFunction(signatureAlgorithm);
AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair();
return new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.CryptoAlgorithm;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.SignatureFunction;
/**
* 区块链密钥生成器;
*
* @author huanghaiquan
*
*/
public class BlockchainKeyGenerator {
public static final String DEFAULT_ALGORITHM = "ED25519";
private BlockchainKeyGenerator() {
}
public static BlockchainKeyGenerator getInstance() {
return new BlockchainKeyGenerator();
}
public BlockchainKeypair generate() {
return generate(DEFAULT_ALGORITHM);
}
public BlockchainKeypair generate(String algorithmName) {
CryptoAlgorithm algorithm = Crypto.getAlgorithm(algorithmName);
return generate(algorithm);
}
public BlockchainKeypair generate(CryptoAlgorithm signatureAlgorithm) {
SignatureFunction signFunc = Crypto.getSignatureFunction(signatureAlgorithm);
AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair();
return new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());
}
}

+ 46
- 46
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BlockchainKeypair.java View File

@@ -1,46 +1,46 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.utils.Bytes;
/**
* 区块链密钥对;
*
* @author huanghaiquan
*
*/
public class BlockchainKeypair extends AsymmetricKeypair {
private BlockchainIdentity id;
// public BlockchainKeyPair(CryptoAlgorithm algorithm, ByteArray pubKeyBytes, ByteArray privKeyBytes) {
// this.id = new BlockchainIdentity(algorithm, pubKeyBytes);
// privKey = new PrivKey(algorithm, privKeyBytes.bytes());
// }
public BlockchainKeypair(String address, PubKey pubKey, PrivKey privKey) {
super(pubKey, privKey);
if (pubKey.getAlgorithm() != privKey.getAlgorithm()) {
throw new IllegalArgumentException("The PublicKey's algorithm is different from the PrivateKey's!");
}
this.id = new BlockchainIdentityData(Bytes.fromBase58(address), pubKey);
}
public BlockchainKeypair(PubKey pubKey, PrivKey privKey) {
super(pubKey, privKey);
if (pubKey.getAlgorithm() != privKey.getAlgorithm()) {
throw new IllegalArgumentException("The PublicKey's algorithm is different from the PrivateKey's!");
}
this.id = new BlockchainIdentityData(pubKey);
}
public Bytes getAddress() {
return id.getAddress();
}
public BlockchainIdentity getIdentity() {
return id;
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.utils.Bytes;
/**
* 区块链密钥对;
*
* @author huanghaiquan
*
*/
public class BlockchainKeypair extends AsymmetricKeypair {
private BlockchainIdentity id;
// public BlockchainKeyPair(CryptoAlgorithm algorithm, ByteArray pubKeyBytes, ByteArray privKeyBytes) {
// this.id = new BlockchainIdentity(algorithm, pubKeyBytes);
// privKey = new PrivKey(algorithm, privKeyBytes.bytes());
// }
public BlockchainKeypair(String address, PubKey pubKey, PrivKey privKey) {
super(pubKey, privKey);
if (pubKey.getAlgorithm() != privKey.getAlgorithm()) {
throw new IllegalArgumentException("The PublicKey's algorithm is different from the PrivateKey's!");
}
this.id = new BlockchainIdentityData(Bytes.fromBase58(address), pubKey);
}
public BlockchainKeypair(PubKey pubKey, PrivKey privKey) {
super(pubKey, privKey);
if (pubKey.getAlgorithm() != privKey.getAlgorithm()) {
throw new IllegalArgumentException("The PublicKey's algorithm is different from the PrivateKey's!");
}
this.id = new BlockchainIdentityData(pubKey);
}
public Bytes getAddress() {
return id.getAddress();
}
public BlockchainIdentity getIdentity() {
return id;
}
}

+ 23
- 23
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/CodeDeployOperation.java View File

@@ -1,23 +1,23 @@
//package com.jd.blockchain.ledger;
//
//import com.jd.blockchain.ledger.data.AccountUpdateOperationBuilder;
//
///**
// * 合约代码部署操作;
// *
// * @author huanghaiquan
// *
// */
//public interface CodeDeployOperation extends AccountUpdateOperationBuilder {
//
// /**
// * 修改脚本;
// *
// * @param code
// * 合约代码;
// * @param codeVersion
// * 预期的当前的代码的版本;如果指定为 -1,则不进行版本检查;
// */
// void set(BlockchainIdentity id, String code, long codeVersion);
//
//}
//package com.jd.blockchain.ledger;
//
//import com.jd.blockchain.ledger.data.AccountUpdateOperationBuilder;
//
///**
// * 合约代码部署操作;
// *
// * @author huanghaiquan
// *
// */
//public interface CodeDeployOperation extends AccountUpdateOperationBuilder {
//
// /**
// * 修改脚本;
// *
// * @param code
// * 合约代码;
// * @param codeVersion
// * 预期的当前的代码的版本;如果指定为 -1,则不进行版本检查;
// */
// void set(BlockchainIdentity id, String code, long codeVersion);
//
//}

+ 31
- 31
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractCodeDeployOperation.java View File

@@ -1,31 +1,31 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_CONTRACT_DEPLOY)
public interface ContractCodeDeployOperation extends Operation {
@DataField(order=2, refContract = true)
BlockchainIdentity getContractID();
@DataField(order=3, primitiveType=PrimitiveType.BYTES)
byte[] getChainCode();
/**
* 地址签名;
*
* <br>
* 这是合约账户身份 ({@link #getContractID()}) 使用对应的私钥对地址做出的签名;
* <br>
* 在注册时将校验此签名与账户地址、公钥是否相匹配,以此保证只有私钥的持有者才能注册相应的合约账户,确保合约账户的唯一性;
*
* @return
*/
@DataField(order=4, refContract = true)
DigitalSignature getAddressSignature();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_CONTRACT_DEPLOY)
public interface ContractCodeDeployOperation extends Operation {
@DataField(order=2, refContract = true)
BlockchainIdentity getContractID();
@DataField(order=3, primitiveType=PrimitiveType.BYTES)
byte[] getChainCode();
/**
* 地址签名;
*
* <br>
* 这是合约账户身份 ({@link #getContractID()}) 使用对应的私钥对地址做出的签名;
* <br>
* 在注册时将校验此签名与账户地址、公钥是否相匹配,以此保证只有私钥的持有者才能注册相应的合约账户,确保合约账户的唯一性;
*
* @return
*/
@DataField(order=4, refContract = true)
DigitalSignature getAddressSignature();
}

+ 32
- 32
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountKVSetOperation.java View File

@@ -1,32 +1,32 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.utils.Bytes;
@DataContract(code= DataCodes.TX_OP_DATA_ACC_SET)
public interface DataAccountKVSetOperation extends Operation {
@DataField(order=2, primitiveType=PrimitiveType.BYTES)
Bytes getAccountAddress();
@DataField(order=3, list=true, refContract=true)
KVWriteEntry[] getWriteSet();
@DataContract(code=DataCodes.TX_OP_DATA_ACC_SET_KV)
public static interface KVWriteEntry{
@DataField(order=1, primitiveType=PrimitiveType.TEXT)
String getKey();
@DataField(order=2, refContract = true)
BytesValue getValue();
@DataField(order=3, primitiveType=PrimitiveType.INT64)
long getExpectedVersion();
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.utils.Bytes;
@DataContract(code= DataCodes.TX_OP_DATA_ACC_SET)
public interface DataAccountKVSetOperation extends Operation {
@DataField(order=2, primitiveType=PrimitiveType.BYTES)
Bytes getAccountAddress();
@DataField(order=3, list=true, refContract=true)
KVWriteEntry[] getWriteSet();
@DataContract(code=DataCodes.TX_OP_DATA_ACC_SET_KV)
public static interface KVWriteEntry{
@DataField(order=1, primitiveType=PrimitiveType.TEXT)
String getKey();
@DataField(order=2, refContract = true)
BytesValue getValue();
@DataField(order=3, primitiveType=PrimitiveType.INT64)
long getExpectedVersion();
}
}

+ 26
- 26
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountRegisterOperation.java View File

@@ -1,26 +1,26 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_DATA_ACC_REG)
public interface DataAccountRegisterOperation extends Operation {
@DataField(order=1, refContract = true)
BlockchainIdentity getAccountID();
/**
* 地址签名;
*
* <br>
* 这是账户身份 ({@link #getAccountID()}) 使用对应的私钥对地址做出的签名;
* <br>
* 在注册时将校验此签名与账户地址、公钥是否相匹配,以此保证只有私钥的持有者才能注册数据账户,确保数据账户的唯一性;
*
* @return
*/
@DataField(order=2, refContract = true)
DigitalSignature getAddressSignature();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_DATA_ACC_REG)
public interface DataAccountRegisterOperation extends Operation {
@DataField(order=1, refContract = true)
BlockchainIdentity getAccountID();
/**
* 地址签名;
*
* <br>
* 这是账户身份 ({@link #getAccountID()}) 使用对应的私钥对地址做出的签名;
* <br>
* 在注册时将校验此签名与账户地址、公钥是否相匹配,以此保证只有私钥的持有者才能注册数据账户,确保数据账户的唯一性;
*
* @return
*/
@DataField(order=2, refContract = true)
DigitalSignature getAddressSignature();
}

+ 185
- 185
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java View File

@@ -1,185 +1,185 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.BaseType;
import com.jd.blockchain.binaryproto.EnumContract;
import com.jd.blockchain.binaryproto.EnumField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
/**
* 键值操作的数据类型;
*
* @author huanghaiquan
*
*/
@EnumContract(code = DataCodes.ENUM_TYPE_BYTES_VALUE_TYPE)
public enum DataType {
/**
* 空;
*/
NIL(PrimitiveType.NIL.CODE),
/**
* 布尔型;
*/
BOOLEAN(PrimitiveType.BOOLEAN.CODE),
/**
* 数值型:
*/
INT8(PrimitiveType.INT8.CODE),
INT16(PrimitiveType.INT16.CODE),
INT32(PrimitiveType.INT32.CODE),
INT64(PrimitiveType.INT64.CODE),
/**
* 文本数据;
*/
TEXT(PrimitiveType.TEXT.CODE),
/**
* 二进制数据;
*/
BYTES(PrimitiveType.BYTES.CODE),
/**
* 时间戳;
*/
TIMESTAMP((byte) (BaseType.INTEGER | 0x08)),
/**
* 文本数据;
*/
JSON((byte) (BaseType.TEXT | 0x01)),
/**
* 文本数据;
*/
XML((byte) (BaseType.TEXT | 0x02)),
/**
* 大整数;
*/
BIG_INT((byte) (BaseType.BYTES | 0x01)),
/**
* 图片;
*/
IMG((byte) (BaseType.BYTES | 0x02)),
/**
* 视频;
*/
VIDEO((byte) (BaseType.BYTES | 0x03)),
/**
* 位置坐标;
*/
LOCATION((byte) (BaseType.BYTES | 0x04)),
/**
* 公钥;
*/
PUB_KEY((byte) (BaseType.BYTES | 0x05)),
/**
* 签名摘要;
*/
SIGNATURE_DIGEST((byte) (BaseType.BYTES | 0x06)),
/**
* 哈希摘要;
*/
HASH_DIGEST((byte) (BaseType.BYTES | 0x07)),
/**
* 加密数据;
*/
ENCRYPTED_DATA((byte) (BaseType.BYTES | 0x08)),
/**
* DataContract 数据;
*/
DATA_CONTRACT((byte) (BaseType.EXT | 0x01));
public static final boolean BOOLEAN_DEFAULT_VALUE = false;
public static final byte INT8_DEFAULT_VALUE = 0;
public static final short INT16_DEFAULT_VALUE = 0;
public static final int INT32_DEFAULT_VALUE = 0;
public static final long INT64_DEFAULT_VALUE = 0;
@EnumField(type = PrimitiveType.INT8)
public final byte CODE;
private DataType(byte code) {
this.CODE = code;
}
/**
* 是否表示“文本类型”或“文本衍生类型”;
*
* @return
*/
public boolean isText() {
return BaseType.TEXT == (BaseType.TEXT & CODE);
}
/**
* 是否表示“字节类型”或“字节衍生类型”;
*
* @return
*/
public boolean isBytes() {
return BaseType.BYTES == (BaseType.BYTES & CODE);
}
/**
* 是否表示“整数类型”或“整数衍生类型”;
*
* @return
*/
public boolean isInteger() {
return BaseType.INTEGER == (BaseType.INTEGER & CODE);
}
/**
* 是否表示“布尔类型”;
*
* @return
*/
public boolean isBoolean() {
return BaseType.BOOLEAN == (BaseType.BOOLEAN & CODE);
}
/**
* 是否表示“扩展类型”;
*
* @return
*/
public boolean isExt() {
return BaseType.EXT == (BaseType.EXT & CODE);
}
public static DataType valueOf(byte code) {
for (DataType dataType : DataType.values()) {
if (dataType.CODE == code) {
return dataType;
}
}
throw new IllegalArgumentException("Code [" + code + "] not supported by BytesValueType enum!");
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.BaseType;
import com.jd.blockchain.binaryproto.EnumContract;
import com.jd.blockchain.binaryproto.EnumField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
/**
* 键值操作的数据类型;
*
* @author huanghaiquan
*
*/
@EnumContract(code = DataCodes.ENUM_TYPE_BYTES_VALUE_TYPE)
public enum DataType {
/**
* 空;
*/
NIL(PrimitiveType.NIL.CODE),
/**
* 布尔型;
*/
BOOLEAN(PrimitiveType.BOOLEAN.CODE),
/**
* 数值型:
*/
INT8(PrimitiveType.INT8.CODE),
INT16(PrimitiveType.INT16.CODE),
INT32(PrimitiveType.INT32.CODE),
INT64(PrimitiveType.INT64.CODE),
/**
* 文本数据;
*/
TEXT(PrimitiveType.TEXT.CODE),
/**
* 二进制数据;
*/
BYTES(PrimitiveType.BYTES.CODE),
/**
* 时间戳;
*/
TIMESTAMP((byte) (BaseType.INTEGER | 0x08)),
/**
* 文本数据;
*/
JSON((byte) (BaseType.TEXT | 0x01)),
/**
* 文本数据;
*/
XML((byte) (BaseType.TEXT | 0x02)),
/**
* 大整数;
*/
BIG_INT((byte) (BaseType.BYTES | 0x01)),
/**
* 图片;
*/
IMG((byte) (BaseType.BYTES | 0x02)),
/**
* 视频;
*/
VIDEO((byte) (BaseType.BYTES | 0x03)),
/**
* 位置坐标;
*/
LOCATION((byte) (BaseType.BYTES | 0x04)),
/**
* 公钥;
*/
PUB_KEY((byte) (BaseType.BYTES | 0x05)),
/**
* 签名摘要;
*/
SIGNATURE_DIGEST((byte) (BaseType.BYTES | 0x06)),
/**
* 哈希摘要;
*/
HASH_DIGEST((byte) (BaseType.BYTES | 0x07)),
/**
* 加密数据;
*/
ENCRYPTED_DATA((byte) (BaseType.BYTES | 0x08)),
/**
* DataContract 数据;
*/
DATA_CONTRACT((byte) (BaseType.EXT | 0x01));
public static final boolean BOOLEAN_DEFAULT_VALUE = false;
public static final byte INT8_DEFAULT_VALUE = 0;
public static final short INT16_DEFAULT_VALUE = 0;
public static final int INT32_DEFAULT_VALUE = 0;
public static final long INT64_DEFAULT_VALUE = 0;
@EnumField(type = PrimitiveType.INT8)
public final byte CODE;
private DataType(byte code) {
this.CODE = code;
}
/**
* 是否表示“文本类型”或“文本衍生类型”;
*
* @return
*/
public boolean isText() {
return BaseType.TEXT == (BaseType.TEXT & CODE);
}
/**
* 是否表示“字节类型”或“字节衍生类型”;
*
* @return
*/
public boolean isBytes() {
return BaseType.BYTES == (BaseType.BYTES & CODE);
}
/**
* 是否表示“整数类型”或“整数衍生类型”;
*
* @return
*/
public boolean isInteger() {
return BaseType.INTEGER == (BaseType.INTEGER & CODE);
}
/**
* 是否表示“布尔类型”;
*
* @return
*/
public boolean isBoolean() {
return BaseType.BOOLEAN == (BaseType.BOOLEAN & CODE);
}
/**
* 是否表示“扩展类型”;
*
* @return
*/
public boolean isExt() {
return BaseType.EXT == (BaseType.EXT & CODE);
}
public static DataType valueOf(byte code) {
for (DataType dataType : DataType.values()) {
if (dataType.CODE == code) {
return dataType;
}
}
throw new IllegalArgumentException("Code [" + code + "] not supported by BytesValueType enum!");
}
}

+ 27
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataVersionConflictException.java View File

@@ -1,27 +1,27 @@
package com.jd.blockchain.ledger;
public class DataVersionConflictException extends LedgerException {
private static final long serialVersionUID = 3583192000738807503L;
private TransactionState state;
public DataVersionConflictException() {
this(TransactionState.DATA_VERSION_CONFLICT, null);
}
public DataVersionConflictException(String message) {
this(TransactionState.DATA_VERSION_CONFLICT, message);
}
private DataVersionConflictException(TransactionState state, String message) {
super(message);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public TransactionState getState() {
return state;
}
}
package com.jd.blockchain.ledger;
public class DataVersionConflictException extends LedgerException {
private static final long serialVersionUID = 3583192000738807503L;
private TransactionState state;
public DataVersionConflictException() {
this(TransactionState.DATA_VERSION_CONFLICT, null);
}
public DataVersionConflictException(String message) {
this(TransactionState.DATA_VERSION_CONFLICT, message);
}
private DataVersionConflictException(TransactionState state, String message) {
super(message);
assert TransactionState.SUCCESS != state;
this.state = state;
}
public TransactionState getState() {
return state;
}
}

+ 15
- 15
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DigitalSignature.java View File

@@ -1,15 +1,15 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
/**
* 数字签名;
*
* @author huanghaiquan
*
*/
@DataContract(code= DataCodes.DIGITALSIGNATURE)
public interface DigitalSignature extends DigitalSignatureBody {
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
/**
* 数字签名;
*
* @author huanghaiquan
*
*/
@DataContract(code= DataCodes.DIGITALSIGNATURE)
public interface DigitalSignature extends DigitalSignatureBody {
}

+ 30
- 30
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/EndpointRequest.java View File

@@ -1,30 +1,30 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
@DataContract(code= DataCodes.REQUEST_ENDPOINT)
public interface EndpointRequest {
@DataField(order=1, primitiveType = PrimitiveType.BYTES)
HashDigest getHash();
/**
* 交易内容;
*
* @return
*/
@DataField(order=2, refContract=true)
TransactionContent getTransactionContent();
/**
* 终端用户的签名列表;
*
* @return
*/
@DataField(order=3, list=true, refContract=true)
DigitalSignature[] getEndpointSignatures();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
@DataContract(code= DataCodes.REQUEST_ENDPOINT)
public interface EndpointRequest {
@DataField(order=1, primitiveType = PrimitiveType.BYTES)
HashDigest getHash();
/**
* 交易内容;
*
* @return
*/
@DataField(order=2, refContract=true)
TransactionContent getTransactionContent();
/**
* 终端用户的签名列表;
*
* @return
*/
@DataField(order=3, list=true, refContract=true)
DigitalSignature[] getEndpointSignatures();
}

+ 46
- 46
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashAlgorithm.java View File

@@ -1,46 +1,46 @@
//package com.jd.blockchain.ledger;
//
///**
// * Hash 算法的代码常量;
// *
// * @author zhaoming9
// *
// */
//public enum HashAlgorithm {
//
// RIPE160((byte) 1),
//
// SHA256((byte) 2),
//
// SM3((byte) 4);
//
// public final byte CODE;
//
// private HashAlgorithm(byte algorithm) {
// CODE = algorithm;
// }
//
// public byte getAlgorithm() {
// return CODE;
// }
//
// public static HashAlgorithm valueOf(byte algorithm) {
// for (HashAlgorithm hashAlgorithm : HashAlgorithm.values()) {
// if (hashAlgorithm.CODE == algorithm) {
// return hashAlgorithm;
// }
// }
// throw new IllegalArgumentException("Unsupported hash algorithm [" + algorithm + "]!");
// }
//
// public static void checkHashAlgorithm(HashAlgorithm algorithm) {
// switch (algorithm) {
// case RIPE160:
// break;
// case SHA256:
// break;
// default:
// throw new IllegalArgumentException("Unsupported hash algorithm [" + algorithm + "]!");
// }
// }
//}
//package com.jd.blockchain.ledger;
//
///**
// * Hash 算法的代码常量;
// *
// * @author zhaoming9
// *
// */
//public enum HashAlgorithm {
//
// RIPE160((byte) 1),
//
// SHA256((byte) 2),
//
// SM3((byte) 4);
//
// public final byte CODE;
//
// private HashAlgorithm(byte algorithm) {
// CODE = algorithm;
// }
//
// public byte getAlgorithm() {
// return CODE;
// }
//
// public static HashAlgorithm valueOf(byte algorithm) {
// for (HashAlgorithm hashAlgorithm : HashAlgorithm.values()) {
// if (hashAlgorithm.CODE == algorithm) {
// return hashAlgorithm;
// }
// }
// throw new IllegalArgumentException("Unsupported hash algorithm [" + algorithm + "]!");
// }
//
// public static void checkHashAlgorithm(HashAlgorithm algorithm) {
// switch (algorithm) {
// case RIPE160:
// break;
// case SHA256:
// break;
// default:
// throw new IllegalArgumentException("Unsupported hash algorithm [" + algorithm + "]!");
// }
// }
//}

+ 37
- 37
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/HashObject.java View File

@@ -1,37 +1,37 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* HashObject 表示以“哈希值”作为唯一标识的对象;
*
* @author huanghaiquan
*
*/
@DataContract(code= DataCodes.HASH_OBJECT)
public interface HashObject {
/**
* 哈希值;
*
* @return
*/
//no need annotation
HashDigest getHash();
// /**
// * 哈希算法;
// *
// * @return
// */
// HashAlgorithm getHashAlgorithm();
// /**
// * 进行哈希运算的数据;
// * @return
// */
// ByteArray getHashData();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* HashObject 表示以“哈希值”作为唯一标识的对象;
*
* @author huanghaiquan
*
*/
@DataContract(code= DataCodes.HASH_OBJECT)
public interface HashObject {
/**
* 哈希值;
*
* @return
*/
//no need annotation
HashDigest getHash();
// /**
// * 哈希算法;
// *
// * @return
// */
// HashAlgorithm getHashAlgorithm();
// /**
// * 进行哈希运算的数据;
// * @return
// */
// ByteArray getHashData();
}

+ 59
- 59
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Ledger.java View File

@@ -1,59 +1,59 @@
//package com.jd.blockchain.ledger;
//
//import my.utils.io.ByteArray;
//
//import java.io.Serializable;
//
///**
// * Ledger 账本;<br>
// *
// * 账本只是一个逻辑上的对象,它是对一条区块的hash链的归纳抽象,而在存储上并没有具体的存在形式,而是具体化为由一个特定的创世区块作为开端的区块 hash
// * 链;<br>
// *
// * 账本的唯一标识也是其创世区块(GenisisBlock)的 hash;<br>
// *
// * @author huanghaiquan
// *
// */
//public interface Ledger extends Serializable {
//
// /**
// * 账本的 hash; <br>
// *
// * 同时也是账本的唯一,等同于其创世区块(GenisisBlock)的 hash {@link GenesisBlock#getBlockHash()};
// *
// * @return
// */
// ByteArray getLedgerHash();
//
// /**
// * 账本结构版本;<br>
// *
// * 等同于 {@link Block#getLedgerVersion()};
// *
// * @return
// */
// long getLedgerVersion();
//
// /**
// * 由随机数构成的该账本的创世序列;
// *
// * @return
// */
// ByteArray getGenesisKey();
//
// /**
// * 当前最新区块的 hash;
// *
// * @return
// */
// ByteArray getBlockHash();
//
// /**
// * 账本的区块高度;
// *
// * @return
// */
// long getBlockHeight();
//
//}
//package com.jd.blockchain.ledger;
//
//import my.utils.io.ByteArray;
//
//import java.io.Serializable;
//
///**
// * Ledger 账本;<br>
// *
// * 账本只是一个逻辑上的对象,它是对一条区块的hash链的归纳抽象,而在存储上并没有具体的存在形式,而是具体化为由一个特定的创世区块作为开端的区块 hash
// * 链;<br>
// *
// * 账本的唯一标识也是其创世区块(GenisisBlock)的 hash;<br>
// *
// * @author huanghaiquan
// *
// */
//public interface Ledger extends Serializable {
//
// /**
// * 账本的 hash; <br>
// *
// * 同时也是账本的唯一,等同于其创世区块(GenisisBlock)的 hash {@link GenesisBlock#getBlockHash()};
// *
// * @return
// */
// ByteArray getLedgerHash();
//
// /**
// * 账本结构版本;<br>
// *
// * 等同于 {@link Block#getLedgerVersion()};
// *
// * @return
// */
// long getLedgerVersion();
//
// /**
// * 由随机数构成的该账本的创世序列;
// *
// * @return
// */
// ByteArray getGenesisKey();
//
// /**
// * 当前最新区块的 hash;
// *
// * @return
// */
// ByteArray getBlockHash();
//
// /**
// * 账本的区块高度;
// *
// * @return
// */
// long getBlockHeight();
//
//}

+ 323
- 323
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerImpl.java View File

@@ -1,323 +1,323 @@
//package com.jd.blockchain.ledger;
//
//import com.jd.blockchain.ledger.data.HashEncoding;
//
//import my.utils.io.ByteArray;
//import my.utils.io.BytesEncoding;
//import my.utils.io.BytesReader;
//import my.utils.io.BytesUtils;
//import my.utils.io.BytesWriter;
//import my.utils.io.NumberMask;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.util.Objects;
//
///**
// * Ledger 实现
// *
// * @author zhaoming9
// */
//public class LedgerImpl implements Ledger, BytesWriter, BytesReader {
//
// private HashAlgorithm ledgerHashAlgorithm = HashAlgorithm.SHA256; // 账本hash算法
// private ByteArray ledgerHash = ByteArray.EMPTY; // 账本hash
//
// private long blockHeight = 0; // 账本当前高度
// private long blockVersion = 0; // 账本当前版本
//
// private HashAlgorithm currentBlockHashAlgorithm = HashAlgorithm.SHA256; // 账本当前区块hash算法
// private ByteArray currentBlockHash = ByteArray.EMPTY; // 账本当前区块hash
//
// private HashAlgorithm previousBlockHashAlgorithm = HashAlgorithm.SHA256; // 账本前一区块hash算法
// private ByteArray previousBlockHash = ByteArray.EMPTY; // 账本前一区块hash
//
// private ByteArray accountRoot = ByteArray.EMPTY; // account mpt root hash
// private long accountCount; // 账户数量
// private long txTotalCount; // 交易数量
//
// private ByteArray genesisKey=ByteArray.EMPTY; // 创世块随机序列
//
// public LedgerImpl() {
// }
//
// /**
// * 初始化一个新的账本;
// * @param genesisKey
// */
// public LedgerImpl(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// /**
// * @param ledgerHashAlgorithm
// * @param ledgerHash
// * @param height
// * @param version
// * @param currentBlockHashAlgorithm
// * @param currentBlockHash
// * @param previousBlockHashAlgorithm
// * @param previousBlockHash
// * @param accountRoot
// * @param accountCount
// * @param txTotalCount
// * @param genesisKey
// */
// private LedgerImpl(HashAlgorithm ledgerHashAlgorithm, ByteArray ledgerHash, long height, long version,
// HashAlgorithm currentBlockHashAlgorithm, ByteArray currentBlockHash,
// HashAlgorithm previousBlockHashAlgorithm, ByteArray previousBlockHash,
// ByteArray accountRoot, long accountCount, long txTotalCount, ByteArray genesisKey) {
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// this.ledgerHash = ledgerHash;
// this.blockHeight = height;
// this.blockVersion = version;
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// this.currentBlockHash = currentBlockHash;
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// this.previousBlockHash = previousBlockHash;
// this.accountRoot = accountRoot;
// this.accountCount = accountCount;
// this.txTotalCount = txTotalCount;
// this.genesisKey = genesisKey;
// }
//
// public LedgerImpl(ByteArray ledgerHash, long blockHeight, long blockVersion, ByteArray currentBlockHash,
// ByteArray previousBlockHash, ByteArray accountRoot, long accountCount, long txTotalCount, ByteArray genesisKey) {
// this(HashAlgorithm.SHA256, ledgerHash, blockHeight, blockVersion, HashAlgorithm.SHA256, currentBlockHash,
// HashAlgorithm.SHA256, previousBlockHash, accountRoot, accountCount, txTotalCount, genesisKey);
// }
//
// public LedgerImpl(LedgerImpl ledger) {
// this(ledger.getLedgerHashAlgorithm(), ledger.getLedgerHash(), ledger.getBlockHeight(), ledger.getBlockVersion(),
// ledger.getCurrentBlockHashAlgorithm(), ledger.getCurrentBlockHash(),
// ledger.getPreviousBlockHashAlgorithm(), ledger.getPreviousBlockHash(),
// ledger.getAccountRoot(), ledger.getAccountCount(), ledger.getTxTotalCount(),ledger.getGenesisKey());
// }
//
// public LedgerImpl nextLedger(ByteArray nextBlockHash, ByteArray accountRoot, long newAccountCnt, long newTxCnt) {
// LedgerImpl nextLedger = new LedgerImpl(this);
// nextLedger.blockHeight+=1;
// nextLedger.previousBlockHash = nextLedger.currentBlockHash;
// nextLedger.currentBlockHash = nextBlockHash;
// nextLedger.accountRoot = accountRoot;
// nextLedger.accountCount += newAccountCnt;
// nextLedger.txTotalCount += newTxCnt;
//
// return nextLedger;
// }
//
// /**
// * 账本的 hash; <br>
// * <p>
// * 同时也是账本的唯一,等同于其创世区块(GenisisBlock)的 hash
// *
// * @return
// */
// @Override
// public ByteArray getLedgerHash() {
// return ledgerHash;
// }
//
// /**
// * 由随机数构成的该账本的创世序列;
// *
// * @return
// */
// @Override
// public ByteArray getGenesisKey() {
// return genesisKey;
// }
//
// /**
// * 当前最新区块的 hash;
// *
// * @return
// */
// @Override
// public ByteArray getBlockHash() {
// return currentBlockHash;
// }
//
// public HashAlgorithm getBlockHashAlgorithm() {
// return currentBlockHashAlgorithm;
// }
//
// /**
// * 账本的区块高度;
// *
// * @return
// */
// @Override
// public long getBlockHeight() {
// return blockHeight;
// }
//
// @Override
// public void resolvFrom(InputStream in) throws IOException {
// HashAlgorithm ledgerHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(ledgerHashAlgorithm);
// ByteArray ledgerHash = HashEncoding.read(in);
//
// long height = BytesUtils.readLong(in);
// long version = BytesUtils.readLong(in);
//
// HashAlgorithm currentBlockHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(currentBlockHashAlgorithm);
// ByteArray currentBlockHash = HashEncoding.read(in);
//
// HashAlgorithm previousBlockHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(previousBlockHashAlgorithm);
// ByteArray previousBlockHash = HashEncoding.read(in);
//
// ByteArray accountHash = HashEncoding.read(in);
// long accountCount = BytesUtils.readLong(in);
// long txTotalCount = BytesUtils.readLong(in);
// ByteArray key = BytesEncoding.readAsByteArray(NumberMask.SHORT, in);
//
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// this.ledgerHash = ledgerHash;
// this.blockHeight = height;
// this.blockVersion = version;
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// this.currentBlockHash = currentBlockHash;
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// this.previousBlockHash = previousBlockHash;
// this.accountRoot = accountHash;
// this.accountCount = accountCount;
// this.txTotalCount = txTotalCount;
// this.genesisKey = key;
// }
//
// @Override
// public void writeTo(OutputStream out) throws IOException {
// BytesUtils.writeByte(ledgerHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(ledgerHash, out);
//
// BytesUtils.writeLong(blockHeight, out);
// BytesUtils.writeLong(blockVersion, out);
//
// BytesUtils.writeByte(currentBlockHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(currentBlockHash, out);
//
// BytesUtils.writeByte(previousBlockHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(previousBlockHash, out);
//
// HashEncoding.write(accountRoot, out);
// BytesUtils.writeLong(accountCount, out);
// BytesUtils.writeLong(txTotalCount, out);
// BytesEncoding.write(genesisKey, NumberMask.SHORT, out);
// }
//
// public HashAlgorithm getLedgerHashAlgorithm() {
// return ledgerHashAlgorithm;
// }
//
// public void setLedgerHashAlgorithm(HashAlgorithm ledgerHashAlgorithm) {
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// }
//
// public void setLedgerHash(ByteArray ledgerHash) {
// this.ledgerHash = ledgerHash;
// }
//
// public void setBlockHeight(long blockHeight) {
// this.blockHeight = blockHeight;
// }
//
// public HashAlgorithm getCurrentBlockHashAlgorithm() {
// return currentBlockHashAlgorithm;
// }
//
// public void setCurrentBlockHashAlgorithm(HashAlgorithm currentBlockHashAlgorithm) {
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// }
//
// public long getBlockVersion() {
// return blockVersion;
// }
//
// public void setBlockVersion(long blockVersion) {
// this.blockVersion = blockVersion;
// }
//
// public void setGenesisKey(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// public ByteArray getCurrentBlockHash() {
// return currentBlockHash;
// }
//
// public void setCurrentBlockHash(ByteArray currentBlockHash) {
// this.currentBlockHash = currentBlockHash;
// }
//
// public HashAlgorithm getPreviousBlockHashAlgorithm() {
// return previousBlockHashAlgorithm;
// }
//
// public void setPreviousBlockHashAlgorithm(HashAlgorithm previousBlockHashAlgorithm) {
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// }
//
// public ByteArray getAccountRoot() {
// return accountRoot;
// }
//
// public void setAccountRoot(ByteArray accountRoot) {
// this.accountRoot = accountRoot;
// }
//
// public long getAccountCount() {
// return accountCount;
// }
//
// public void setAccountCount(long accountCount) {
// this.accountCount = accountCount;
// }
//
// public long getTxTotalCount() {
// return txTotalCount;
// }
//
// public void setTxTotalCount(long txTotalCount) {
// this.txTotalCount = txTotalCount;
// }
//
// public ByteArray getPreviousBlockHash() {
// return previousBlockHash;
// }
//
// public void setPreviousBlockHash(ByteArray previousBlockHash) {
// this.previousBlockHash = previousBlockHash;
// }
//
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof LedgerImpl)) return false;
// LedgerImpl ledger = (LedgerImpl) o;
// return getBlockHeight() == ledger.getBlockHeight() &&
// getBlockVersion() == ledger.getBlockVersion() &&
// getLedgerHashAlgorithm() == ledger.getLedgerHashAlgorithm() &&
// Objects.equals(getLedgerHash(), ledger.getLedgerHash()) &&
// getCurrentBlockHashAlgorithm() == ledger.getCurrentBlockHashAlgorithm() &&
// Objects.equals(getCurrentBlockHash(), ledger.getCurrentBlockHash()) &&
// getPreviousBlockHashAlgorithm() == ledger.getPreviousBlockHashAlgorithm() &&
// Objects.equals(getPreviousBlockHash(), ledger.getPreviousBlockHash()) &&
// Objects.equals(getGenesisKey(), ledger.getGenesisKey());
// }
//
// @Override
// public int hashCode() {
//
// return Objects.hash(getLedgerHashAlgorithm(), getLedgerHash(), getBlockHeight(), getBlockVersion(), getCurrentBlockHashAlgorithm(), getCurrentBlockHash(), getPreviousBlockHashAlgorithm(), getPreviousBlockHash(), getGenesisKey());
// }
//
// @Override
// public long getLedgerVersion() {
// // TODO Auto-generated method stub
// return 0;
// }
//}
//package com.jd.blockchain.ledger;
//
//import com.jd.blockchain.ledger.data.HashEncoding;
//
//import my.utils.io.ByteArray;
//import my.utils.io.BytesEncoding;
//import my.utils.io.BytesReader;
//import my.utils.io.BytesUtils;
//import my.utils.io.BytesWriter;
//import my.utils.io.NumberMask;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.util.Objects;
//
///**
// * Ledger 实现
// *
// * @author zhaoming9
// */
//public class LedgerImpl implements Ledger, BytesWriter, BytesReader {
//
// private HashAlgorithm ledgerHashAlgorithm = HashAlgorithm.SHA256; // 账本hash算法
// private ByteArray ledgerHash = ByteArray.EMPTY; // 账本hash
//
// private long blockHeight = 0; // 账本当前高度
// private long blockVersion = 0; // 账本当前版本
//
// private HashAlgorithm currentBlockHashAlgorithm = HashAlgorithm.SHA256; // 账本当前区块hash算法
// private ByteArray currentBlockHash = ByteArray.EMPTY; // 账本当前区块hash
//
// private HashAlgorithm previousBlockHashAlgorithm = HashAlgorithm.SHA256; // 账本前一区块hash算法
// private ByteArray previousBlockHash = ByteArray.EMPTY; // 账本前一区块hash
//
// private ByteArray accountRoot = ByteArray.EMPTY; // account mpt root hash
// private long accountCount; // 账户数量
// private long txTotalCount; // 交易数量
//
// private ByteArray genesisKey=ByteArray.EMPTY; // 创世块随机序列
//
// public LedgerImpl() {
// }
//
// /**
// * 初始化一个新的账本;
// * @param genesisKey
// */
// public LedgerImpl(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// /**
// * @param ledgerHashAlgorithm
// * @param ledgerHash
// * @param height
// * @param version
// * @param currentBlockHashAlgorithm
// * @param currentBlockHash
// * @param previousBlockHashAlgorithm
// * @param previousBlockHash
// * @param accountRoot
// * @param accountCount
// * @param txTotalCount
// * @param genesisKey
// */
// private LedgerImpl(HashAlgorithm ledgerHashAlgorithm, ByteArray ledgerHash, long height, long version,
// HashAlgorithm currentBlockHashAlgorithm, ByteArray currentBlockHash,
// HashAlgorithm previousBlockHashAlgorithm, ByteArray previousBlockHash,
// ByteArray accountRoot, long accountCount, long txTotalCount, ByteArray genesisKey) {
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// this.ledgerHash = ledgerHash;
// this.blockHeight = height;
// this.blockVersion = version;
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// this.currentBlockHash = currentBlockHash;
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// this.previousBlockHash = previousBlockHash;
// this.accountRoot = accountRoot;
// this.accountCount = accountCount;
// this.txTotalCount = txTotalCount;
// this.genesisKey = genesisKey;
// }
//
// public LedgerImpl(ByteArray ledgerHash, long blockHeight, long blockVersion, ByteArray currentBlockHash,
// ByteArray previousBlockHash, ByteArray accountRoot, long accountCount, long txTotalCount, ByteArray genesisKey) {
// this(HashAlgorithm.SHA256, ledgerHash, blockHeight, blockVersion, HashAlgorithm.SHA256, currentBlockHash,
// HashAlgorithm.SHA256, previousBlockHash, accountRoot, accountCount, txTotalCount, genesisKey);
// }
//
// public LedgerImpl(LedgerImpl ledger) {
// this(ledger.getLedgerHashAlgorithm(), ledger.getLedgerHash(), ledger.getBlockHeight(), ledger.getBlockVersion(),
// ledger.getCurrentBlockHashAlgorithm(), ledger.getCurrentBlockHash(),
// ledger.getPreviousBlockHashAlgorithm(), ledger.getPreviousBlockHash(),
// ledger.getAccountRoot(), ledger.getAccountCount(), ledger.getTxTotalCount(),ledger.getGenesisKey());
// }
//
// public LedgerImpl nextLedger(ByteArray nextBlockHash, ByteArray accountRoot, long newAccountCnt, long newTxCnt) {
// LedgerImpl nextLedger = new LedgerImpl(this);
// nextLedger.blockHeight+=1;
// nextLedger.previousBlockHash = nextLedger.currentBlockHash;
// nextLedger.currentBlockHash = nextBlockHash;
// nextLedger.accountRoot = accountRoot;
// nextLedger.accountCount += newAccountCnt;
// nextLedger.txTotalCount += newTxCnt;
//
// return nextLedger;
// }
//
// /**
// * 账本的 hash; <br>
// * <p>
// * 同时也是账本的唯一,等同于其创世区块(GenisisBlock)的 hash
// *
// * @return
// */
// @Override
// public ByteArray getLedgerHash() {
// return ledgerHash;
// }
//
// /**
// * 由随机数构成的该账本的创世序列;
// *
// * @return
// */
// @Override
// public ByteArray getGenesisKey() {
// return genesisKey;
// }
//
// /**
// * 当前最新区块的 hash;
// *
// * @return
// */
// @Override
// public ByteArray getBlockHash() {
// return currentBlockHash;
// }
//
// public HashAlgorithm getBlockHashAlgorithm() {
// return currentBlockHashAlgorithm;
// }
//
// /**
// * 账本的区块高度;
// *
// * @return
// */
// @Override
// public long getBlockHeight() {
// return blockHeight;
// }
//
// @Override
// public void resolvFrom(InputStream in) throws IOException {
// HashAlgorithm ledgerHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(ledgerHashAlgorithm);
// ByteArray ledgerHash = HashEncoding.read(in);
//
// long height = BytesUtils.readLong(in);
// long version = BytesUtils.readLong(in);
//
// HashAlgorithm currentBlockHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(currentBlockHashAlgorithm);
// ByteArray currentBlockHash = HashEncoding.read(in);
//
// HashAlgorithm previousBlockHashAlgorithm = HashAlgorithm.valueOf(BytesUtils.readByte(in));
// HashAlgorithm.checkHashAlgorithm(previousBlockHashAlgorithm);
// ByteArray previousBlockHash = HashEncoding.read(in);
//
// ByteArray accountHash = HashEncoding.read(in);
// long accountCount = BytesUtils.readLong(in);
// long txTotalCount = BytesUtils.readLong(in);
// ByteArray key = BytesEncoding.readAsByteArray(NumberMask.SHORT, in);
//
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// this.ledgerHash = ledgerHash;
// this.blockHeight = height;
// this.blockVersion = version;
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// this.currentBlockHash = currentBlockHash;
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// this.previousBlockHash = previousBlockHash;
// this.accountRoot = accountHash;
// this.accountCount = accountCount;
// this.txTotalCount = txTotalCount;
// this.genesisKey = key;
// }
//
// @Override
// public void writeTo(OutputStream out) throws IOException {
// BytesUtils.writeByte(ledgerHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(ledgerHash, out);
//
// BytesUtils.writeLong(blockHeight, out);
// BytesUtils.writeLong(blockVersion, out);
//
// BytesUtils.writeByte(currentBlockHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(currentBlockHash, out);
//
// BytesUtils.writeByte(previousBlockHashAlgorithm.getAlgorithm(), out);
// HashEncoding.write(previousBlockHash, out);
//
// HashEncoding.write(accountRoot, out);
// BytesUtils.writeLong(accountCount, out);
// BytesUtils.writeLong(txTotalCount, out);
// BytesEncoding.write(genesisKey, NumberMask.SHORT, out);
// }
//
// public HashAlgorithm getLedgerHashAlgorithm() {
// return ledgerHashAlgorithm;
// }
//
// public void setLedgerHashAlgorithm(HashAlgorithm ledgerHashAlgorithm) {
// this.ledgerHashAlgorithm = ledgerHashAlgorithm;
// }
//
// public void setLedgerHash(ByteArray ledgerHash) {
// this.ledgerHash = ledgerHash;
// }
//
// public void setBlockHeight(long blockHeight) {
// this.blockHeight = blockHeight;
// }
//
// public HashAlgorithm getCurrentBlockHashAlgorithm() {
// return currentBlockHashAlgorithm;
// }
//
// public void setCurrentBlockHashAlgorithm(HashAlgorithm currentBlockHashAlgorithm) {
// this.currentBlockHashAlgorithm = currentBlockHashAlgorithm;
// }
//
// public long getBlockVersion() {
// return blockVersion;
// }
//
// public void setBlockVersion(long blockVersion) {
// this.blockVersion = blockVersion;
// }
//
// public void setGenesisKey(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// public ByteArray getCurrentBlockHash() {
// return currentBlockHash;
// }
//
// public void setCurrentBlockHash(ByteArray currentBlockHash) {
// this.currentBlockHash = currentBlockHash;
// }
//
// public HashAlgorithm getPreviousBlockHashAlgorithm() {
// return previousBlockHashAlgorithm;
// }
//
// public void setPreviousBlockHashAlgorithm(HashAlgorithm previousBlockHashAlgorithm) {
// this.previousBlockHashAlgorithm = previousBlockHashAlgorithm;
// }
//
// public ByteArray getAccountRoot() {
// return accountRoot;
// }
//
// public void setAccountRoot(ByteArray accountRoot) {
// this.accountRoot = accountRoot;
// }
//
// public long getAccountCount() {
// return accountCount;
// }
//
// public void setAccountCount(long accountCount) {
// this.accountCount = accountCount;
// }
//
// public long getTxTotalCount() {
// return txTotalCount;
// }
//
// public void setTxTotalCount(long txTotalCount) {
// this.txTotalCount = txTotalCount;
// }
//
// public ByteArray getPreviousBlockHash() {
// return previousBlockHash;
// }
//
// public void setPreviousBlockHash(ByteArray previousBlockHash) {
// this.previousBlockHash = previousBlockHash;
// }
//
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof LedgerImpl)) return false;
// LedgerImpl ledger = (LedgerImpl) o;
// return getBlockHeight() == ledger.getBlockHeight() &&
// getBlockVersion() == ledger.getBlockVersion() &&
// getLedgerHashAlgorithm() == ledger.getLedgerHashAlgorithm() &&
// Objects.equals(getLedgerHash(), ledger.getLedgerHash()) &&
// getCurrentBlockHashAlgorithm() == ledger.getCurrentBlockHashAlgorithm() &&
// Objects.equals(getCurrentBlockHash(), ledger.getCurrentBlockHash()) &&
// getPreviousBlockHashAlgorithm() == ledger.getPreviousBlockHashAlgorithm() &&
// Objects.equals(getPreviousBlockHash(), ledger.getPreviousBlockHash()) &&
// Objects.equals(getGenesisKey(), ledger.getGenesisKey());
// }
//
// @Override
// public int hashCode() {
//
// return Objects.hash(getLedgerHashAlgorithm(), getLedgerHash(), getBlockHeight(), getBlockVersion(), getCurrentBlockHashAlgorithm(), getCurrentBlockHash(), getPreviousBlockHashAlgorithm(), getPreviousBlockHash(), getGenesisKey());
// }
//
// @Override
// public long getLedgerVersion() {
// // TODO Auto-generated method stub
// return 0;
// }
//}

+ 13
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerInitOperation.java View File

@@ -1,13 +1,13 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_LEDGER_INIT)
public interface LedgerInitOperation extends Operation{
@DataField(order=1, refContract=true)
LedgerInitSetting getInitSetting();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code= DataCodes.TX_OP_LEDGER_INIT)
public interface LedgerInitOperation extends Operation{
@DataField(order=1, refContract=true)
LedgerInitSetting getInitSetting();
}

+ 67
- 67
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/MagicNumber.java View File

@@ -1,67 +1,67 @@
package com.jd.blockchain.ledger;
/**
* 魔数表;
*
* @author huanghaiquan
*
*/
public class MagicNumber {
/**
* JD区块链系统标识的高位,即小写字母 j 的 ASCII;
*
*/
public static final byte JD_HIGH = 0x6A;
/**
* JD区块链系统标识的低位, 即小写字母 d 的 ASCII;
*/
public static final byte JD_LOW = 0x64;
/**
* 创世区块标识;
*/
public static final byte GENESIS_BLOCK = 0x00;
/**
* 子区块标识;
*
* 注:“子区块”是除了“创世区块”之外其它的区块;
*/
public static final byte CHILD_BLOCK = 0x01;
/**
* 交易内容标识;
*/
public static final byte TX_CONTENT = 0x10;
/**
* 交易请求标识;
*/
public static final byte TX_REQUEST = 0x11;
/**
* 交易持久标识;
*/
public static final byte TX_PERSISTENCE = 0x12;
/**
* 数字签名标识;
*/
public static final byte SIGNATURE = 0x20;
// /**
// * 公钥标识;
// */
// public static final byte PUB_KEY = 0x21;
//
// /**
// * 私钥标识;
// */
// public static final byte PRIV_KEY = 0x22;
}
package com.jd.blockchain.ledger;
/**
* 魔数表;
*
* @author huanghaiquan
*
*/
public class MagicNumber {
/**
* JD区块链系统标识的高位,即小写字母 j 的 ASCII;
*
*/
public static final byte JD_HIGH = 0x6A;
/**
* JD区块链系统标识的低位, 即小写字母 d 的 ASCII;
*/
public static final byte JD_LOW = 0x64;
/**
* 创世区块标识;
*/
public static final byte GENESIS_BLOCK = 0x00;
/**
* 子区块标识;
*
* 注:“子区块”是除了“创世区块”之外其它的区块;
*/
public static final byte CHILD_BLOCK = 0x01;
/**
* 交易内容标识;
*/
public static final byte TX_CONTENT = 0x10;
/**
* 交易请求标识;
*/
public static final byte TX_REQUEST = 0x11;
/**
* 交易持久标识;
*/
public static final byte TX_PERSISTENCE = 0x12;
/**
* 数字签名标识;
*/
public static final byte SIGNATURE = 0x20;
// /**
// * 公钥标识;
// */
// public static final byte PUB_KEY = 0x21;
//
// /**
// * 私钥标识;
// */
// public static final byte PRIV_KEY = 0x22;
}

+ 22
- 22
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/NodeRequest.java View File

@@ -1,22 +1,22 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code = DataCodes.REQUEST_NODE)
public interface NodeRequest extends EndpointRequest {
/**
* 接入交易的节点的签名;<br>
*
* 注:能够提交交易的节点可以是共识节点或网关节点;
*
* @return
*/
@DataField(order=1, list=true, refContract=true)
DigitalSignature[] getNodeSignatures();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code = DataCodes.REQUEST_NODE)
public interface NodeRequest extends EndpointRequest {
/**
* 接入交易的节点的签名;<br>
*
* 注:能够提交交易的节点可以是共识节点或网关节点;
*
* @return
*/
@DataField(order=1, list=true, refContract=true)
DigitalSignature[] getNodeSignatures();
}

+ 27
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/OperationArgument.java View File

@@ -1,27 +1,27 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.utils.io.ByteArray;
/**
* 操作参数;
*
* @author huanghaiquan
*
*/
public interface OperationArgument {
/**
* 参数类型; <br>
*
* @return
*/
byte getKey();
/**
* 参数值;
*
* @return
*/
ByteArray getValue();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.utils.io.ByteArray;
/**
* 操作参数;
*
* @author huanghaiquan
*
*/
public interface OperationArgument {
/**
* 参数类型; <br>
*
* @return
*/
byte getKey();
/**
* 参数值;
*
* @return
*/
ByteArray getValue();
}

+ 68
- 68
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/PermissionType.java View File

@@ -1,68 +1,68 @@
package com.jd.blockchain.ledger;
/**
* 权限类型;
*
* @author huanghaiquan
*
*/
public enum PermissionType {
/**
* 账户权限配置;
*/
SET_PRIVILEGE(1),
/**
* 注册参与方;
*/
REG_PARTICIPANT(2),
/**
* 配置账本;包括除了{@link #SET_PRIVILEGE}、 {@link #REG_PARTICIPANT} 之外的其它账本设置,例如:设置密码参数、共识参数等;
*/
CONFIG_LEDGER(4),
/**
* 用户注册;
*/
REG_USER(8),
/**
* 注册数据账户;
*/
REG_DATA_ACCOUNT(16),
/**
* 部署新的合约代码;
*/
DEPLOY_CONTRACT(32),
/**
* 写入用户信息;
*/
SET_USER(1024),
/**
* 写入数据;
*/
SET_DATA(2048),
/**
* 写入数据;
*/
INVOKE_CONTRACT(4096),
/**
* 升级合约代码;
*/
UPDATE_CONTRACT(8192);
public final int CODE;
private PermissionType(int code) {
this.CODE = code;
}
}
package com.jd.blockchain.ledger;
/**
* 权限类型;
*
* @author huanghaiquan
*
*/
public enum PermissionType {
/**
* 账户权限配置;
*/
SET_PRIVILEGE(1),
/**
* 注册参与方;
*/
REG_PARTICIPANT(2),
/**
* 配置账本;包括除了{@link #SET_PRIVILEGE}、 {@link #REG_PARTICIPANT} 之外的其它账本设置,例如:设置密码参数、共识参数等;
*/
CONFIG_LEDGER(4),
/**
* 用户注册;
*/
REG_USER(8),
/**
* 注册数据账户;
*/
REG_DATA_ACCOUNT(16),
/**
* 部署新的合约代码;
*/
DEPLOY_CONTRACT(32),
/**
* 写入用户信息;
*/
SET_USER(1024),
/**
* 写入数据;
*/
SET_DATA(2048),
/**
* 写入数据;
*/
INVOKE_CONTRACT(4096),
/**
* 升级合约代码;
*/
UPDATE_CONTRACT(8192);
public final int CODE;
private PermissionType(int code) {
this.CODE = code;
}
}

+ 39
- 39
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/RolesConfigureOperation.java View File

@@ -1,39 +1,39 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
/**
* 角色配置操作;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_OP_ROLE_CONFIGURE)
public interface RolesConfigureOperation extends Operation {
@DataField(order = 2, refContract = true, list = true)
RolePrivilegeEntry[] getRoles();
@DataContract(code = DataCodes.TX_OP_ROLE_CONFIGURE_ENTRY)
public static interface RolePrivilegeEntry {
@DataField(order = 1, primitiveType = PrimitiveType.TEXT)
String getRoleName();
@DataField(order = 2, refEnum = true, list = true)
LedgerPermission[] getEnableLedgerPermissions();
@DataField(order = 3, refEnum = true, list = true)
LedgerPermission[] getDisableLedgerPermissions();
@DataField(order = 4, refEnum = true, list = true)
TransactionPermission[] getEnableTransactionPermissions();
@DataField(order = 5, refEnum = true, list = true)
TransactionPermission[] getDisableTransactionPermissions();
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
/**
* 角色配置操作;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_OP_ROLE_CONFIGURE)
public interface RolesConfigureOperation extends Operation {
@DataField(order = 2, refContract = true, list = true)
RolePrivilegeEntry[] getRoles();
@DataContract(code = DataCodes.TX_OP_ROLE_CONFIGURE_ENTRY)
public static interface RolePrivilegeEntry {
@DataField(order = 1, primitiveType = PrimitiveType.TEXT)
String getRoleName();
@DataField(order = 2, refEnum = true, list = true)
LedgerPermission[] getEnableLedgerPermissions();
@DataField(order = 3, refEnum = true, list = true)
LedgerPermission[] getDisableLedgerPermissions();
@DataField(order = 4, refEnum = true, list = true)
TransactionPermission[] getEnableTransactionPermissions();
@DataField(order = 5, refEnum = true, list = true)
TransactionPermission[] getDisableTransactionPermissions();
}
}

+ 21
- 21
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/SignatureInfo.java View File

@@ -1,21 +1,21 @@
package com.jd.blockchain.ledger;
public interface SignatureInfo {
/**
* 签署账户的地址;
*
* @return
*/
String getAddress();
/**
* 签名的摘要;
*
* 注:采用Base64编码;
*
* @return
*/
String getDigest();
}
package com.jd.blockchain.ledger;
public interface SignatureInfo {
/**
* 签署账户的地址;
*
* @return
*/
String getAddress();
/**
* 签名的摘要;
*
* 注:采用Base64编码;
*
* @return
*/
String getDigest();
}

+ 37
- 37
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/StateOpType.java View File

@@ -1,37 +1,37 @@
package com.jd.blockchain.ledger;
/**
* 状态操作类型;
*
* @author huanghaiquan
*
*/
public enum StateOpType {
/**
* 设置状态值;
*/
SET((byte) 1),
/**
* 移除状态值;
*/
REMOVE((byte) 0);
public final byte CODE;
private StateOpType(byte code) {
this.CODE = code;
}
public static StateOpType valueOf(byte code) {
for (StateOpType opType : StateOpType.values()) {
if (opType.CODE == code) {
return opType;
}
}
throw new IllegalArgumentException("Unsupported code[" + code + "] of StateOpType!");
}
}
package com.jd.blockchain.ledger;
/**
* 状态操作类型;
*
* @author huanghaiquan
*
*/
public enum StateOpType {
/**
* 设置状态值;
*/
SET((byte) 1),
/**
* 移除状态值;
*/
REMOVE((byte) 0);
public final byte CODE;
private StateOpType(byte code) {
this.CODE = code;
}
public static StateOpType valueOf(byte code) {
for (StateOpType opType : StateOpType.values()) {
if (opType.CODE == code) {
return opType;
}
}
throw new IllegalArgumentException("Unsupported code[" + code + "] of StateOpType!");
}
}

+ 54
- 54
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java View File

@@ -1,54 +1,54 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* Transaction 区块链交易,是被原子执行的操作集合;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX)
public interface Transaction extends NodeRequest, HashObject {
/**
* 交易 Hash;
*
* 这是包含交易内容、签名列表、交易结果的完整性 hash;
*
* @return
*/
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
@Override
HashDigest getHash();
/**
* 交易被包含的区块高度;
*
* @return
*/
@DataField(order = 2, primitiveType = PrimitiveType.INT64)
long getBlockHeight();
/**
* 交易的执行结果;
*
* 值为枚举值 {@link TransactionState#CODE} 之一;
*
* @return
*/
@DataField(order = 3, refEnum = true)
TransactionState getExecutionState();
/**
* 交易的返回结果
*
* @return
*/
@DataField(order=4, list = true, refContract=true)
OperationResult[] getOperationResults();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* Transaction 区块链交易,是被原子执行的操作集合;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX)
public interface Transaction extends NodeRequest, HashObject {
/**
* 交易 Hash;
*
* 这是包含交易内容、签名列表、交易结果的完整性 hash;
*
* @return
*/
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
@Override
HashDigest getHash();
/**
* 交易被包含的区块高度;
*
* @return
*/
@DataField(order = 2, primitiveType = PrimitiveType.INT64)
long getBlockHeight();
/**
* 交易的执行结果;
*
* 值为枚举值 {@link TransactionState#CODE} 之一;
*
* @return
*/
@DataField(order = 3, refEnum = true)
TransactionState getExecutionState();
/**
* 交易的返回结果
*
* @return
*/
@DataField(order=4, list = true, refContract=true)
OperationResult[] getOperationResults();
}

+ 51
- 51
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionBuilder.java View File

@@ -1,51 +1,51 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.transaction.ClientOperator;
import com.jd.blockchain.transaction.LedgerInitOperator;
/**
* 区块链交易模板;
*
* @author huanghaiquan
*
*/
public interface TransactionBuilder extends ClientOperator, LedgerInitOperator {
HashDigest getLedgerHash();
/**
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;<br>
*
* @return
*/
TransactionRequestBuilder prepareRequest();
/**
* 生成交易内容;
*
* @return
*/
TransactionContent prepareContent();
/**
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;
*
* @param time 交易时间戳;
* @return
*/
TransactionRequestBuilder prepareRequest(long time);
/**
* 生成交易内容;
*
* @param time 交易时间戳;
* @return
*/
TransactionContent prepareContent(long time);
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.transaction.ClientOperator;
import com.jd.blockchain.transaction.LedgerInitOperator;
/**
* 区块链交易模板;
*
* @author huanghaiquan
*
*/
public interface TransactionBuilder extends ClientOperator, LedgerInitOperator {
HashDigest getLedgerHash();
/**
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;<br>
*
* @return
*/
TransactionRequestBuilder prepareRequest();
/**
* 生成交易内容;
*
* @return
*/
TransactionContent prepareContent();
/**
* 基于当前的系统时间完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;
*
* @param time 交易时间戳;
* @return
*/
TransactionRequestBuilder prepareRequest(long time);
/**
* 生成交易内容;
*
* @param time 交易时间戳;
* @return
*/
TransactionContent prepareContent(long time);
}

+ 81
- 81
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRequestBuilder.java View File

@@ -1,81 +1,81 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest;
/**
* 已就绪的交易;
*
* @author huanghaiquan
*
*/
public interface TransactionRequestBuilder extends HashObject {
/**
* 交易内容的 Hash;
*
* @return
*/
@Override
HashDigest getHash();
/**
* 交易数据内容; <br>
*
* <br>
* 如果需要对交易进行外部签名,可以将此数据块发送到外部进行签名;
*
* @return
*/
TransactionContent getTransactionContent();
/**
* 对交易进行签名;
*
* @param address
* 签名账户的地址;
* @param privKey
* 签名账户的私钥;
* @return
*/
DigitalSignature signAsEndpoint(AsymmetricKeypair keyPair);
/**
* 对交易进行签名;
*
* @param address
* 签名账户的地址;
* @param privKey
* 签名账户的私钥;
* @return
*/
DigitalSignature signAsNode(AsymmetricKeypair keyPair);
/**
* 加入签名;
*
* @param address
* 签名账户的地址;
* @param digest
* Base64格式的签名摘要;
* @return
*/
void addEndpointSignature(DigitalSignature... signature);
/**
* 加入签名;
*
* @param address
* 签名账户的地址;
* @param digest
* Base64格式的签名摘要;
* @return
*/
void addNodeSignature(DigitalSignature... signatures);
/**
* 生成交易请求;
*
*/
TransactionRequest buildRequest();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest;
/**
* 已就绪的交易;
*
* @author huanghaiquan
*
*/
public interface TransactionRequestBuilder extends HashObject {
/**
* 交易内容的 Hash;
*
* @return
*/
@Override
HashDigest getHash();
/**
* 交易数据内容; <br>
*
* <br>
* 如果需要对交易进行外部签名,可以将此数据块发送到外部进行签名;
*
* @return
*/
TransactionContent getTransactionContent();
/**
* 对交易进行签名;
*
* @param address
* 签名账户的地址;
* @param privKey
* 签名账户的私钥;
* @return
*/
DigitalSignature signAsEndpoint(AsymmetricKeypair keyPair);
/**
* 对交易进行签名;
*
* @param address
* 签名账户的地址;
* @param privKey
* 签名账户的私钥;
* @return
*/
DigitalSignature signAsNode(AsymmetricKeypair keyPair);
/**
* 加入签名;
*
* @param address
* 签名账户的地址;
* @param digest
* Base64格式的签名摘要;
* @return
*/
void addEndpointSignature(DigitalSignature... signature);
/**
* 加入签名;
*
* @param address
* 签名账户的地址;
* @param digest
* Base64格式的签名摘要;
* @return
*/
void addNodeSignature(DigitalSignature... signatures);
/**
* 生成交易请求;
*
*/
TransactionRequest buildRequest();
}

+ 67
- 67
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionResponse.java View File

@@ -1,68 +1,68 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* 交易请求 {@link TransactionRequest} 的回复;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_RESPONSE)
public interface TransactionResponse {
/**
* 交易原始内容的哈希;
*
* @return
*/
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
HashDigest getContentHash();
/**
* 执行状态;
*
* @return
*/
@DataField(order = 2, refEnum = true)
TransactionState getExecutionState();
/**
* 交易被纳入的区块哈希;
*
* @return
*/
@DataField(order = 3, primitiveType = PrimitiveType.BYTES)
HashDigest getBlockHash();
/**
* 交易被纳入的区块高度;
*
* <p>
* 如果未生成区块,则返回 -1;
*
* @return
*/
@DataField(order = 4, primitiveType = PrimitiveType.INT64)
long getBlockHeight();
/**
* 交易是否执行成功
*
* @return
*/
@DataField(order = 5, primitiveType = PrimitiveType.BOOLEAN)
boolean isSuccess();
/**
* 合约返回值
*
* @return
*/
@DataField(order=6, list=true, refContract = true)
OperationResult[] getOperationResults();
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.crypto.HashDigest;
/**
* 交易请求 {@link TransactionRequest} 的回复;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_RESPONSE)
public interface TransactionResponse {
/**
* 交易原始内容的哈希;
*
* @return
*/
@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
HashDigest getContentHash();
/**
* 执行状态;
*
* @return
*/
@DataField(order = 2, refEnum = true)
TransactionState getExecutionState();
/**
* 交易被纳入的区块哈希;
*
* @return
*/
@DataField(order = 3, primitiveType = PrimitiveType.BYTES)
HashDigest getBlockHash();
/**
* 交易被纳入的区块高度;
*
* <p>
* 如果未生成区块,则返回 -1;
*
* @return
*/
@DataField(order = 4, primitiveType = PrimitiveType.INT64)
long getBlockHeight();
/**
* 交易是否执行成功
*
* @return
*/
@DataField(order = 5, primitiveType = PrimitiveType.BOOLEAN)
boolean isSuccess();
/**
* 合约返回值
*
* @return
*/
@DataField(order=6, list=true, refContract = true)
OperationResult[] getOperationResults();
}

+ 16
- 16
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionRollbackException.java View File

@@ -1,16 +1,16 @@
package com.jd.blockchain.ledger;
public class TransactionRollbackException extends RuntimeException {
private static final long serialVersionUID = -1223140447229570029L;
public TransactionRollbackException(String message) {
super(message);
}
public TransactionRollbackException(String message, Throwable cause) {
super(message, cause);
}
}
package com.jd.blockchain.ledger;
public class TransactionRollbackException extends RuntimeException {
private static final long serialVersionUID = -1223140447229570029L;
public TransactionRollbackException(String message) {
super(message);
}
public TransactionRollbackException(String message, Throwable cause) {
super(message, cause);
}
}

+ 27
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionTemplate.java View File

@@ -1,27 +1,27 @@
package com.jd.blockchain.ledger;
import java.io.Closeable;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.transaction.ClientOperator;
/**
* 区块链交易模板;
*
* @author huanghaiquan
*
*/
public interface TransactionTemplate extends ClientOperator, Closeable {
HashDigest getLedgerHash();
/**
* 完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;
*
* @return
*/
PreparedTransaction prepare();
}
package com.jd.blockchain.ledger;
import java.io.Closeable;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.transaction.ClientOperator;
/**
* 区块链交易模板;
*
* @author huanghaiquan
*
*/
public interface TransactionTemplate extends ClientOperator, Closeable {
HashDigest getLedgerHash();
/**
* 完成交易定义,并生成就绪的交易数据; <br>
*
* 注:调用此方法后,不能再向当前对象加入更多的操作;
*
* @return
*/
PreparedTransaction prepare();
}

+ 57
- 57
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserAuthorizeOperation.java View File

@@ -1,57 +1,57 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.utils.Bytes;
/**
* 角色配置操作;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_OP_USER_ROLES_AUTHORIZE)
public interface UserAuthorizeOperation extends Operation {
@DataField(order = 2, refContract = true, list = true)
UserRolesEntry[] getUserRolesAuthorizations();
@DataContract(code = DataCodes.TX_OP_USER_ROLE_AUTHORIZE_ENTRY)
public static interface UserRolesEntry {
/**
* 用户地址;
*
* @return
*/
@DataField(order = 0, primitiveType = PrimitiveType.BYTES, list = true)
Bytes[] getUserAddresses();
/**
* 要更新的多角色权限策略;
*
* @return
*/
@DataField(order = 2, refEnum = true)
RolesPolicy getPolicy();
/**
* 授权的角色清单;
*
* @return
*/
@DataField(order = 3, primitiveType = PrimitiveType.TEXT, list = true)
String[] getAuthorizedRoles();
/**
* 取消授权的角色清单;
*
* @return
*/
@DataField(order = 4, primitiveType = PrimitiveType.TEXT, list = true)
String[] getUnauthorizedRoles();
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.utils.Bytes;
/**
* 角色配置操作;
*
* @author huanghaiquan
*
*/
@DataContract(code = DataCodes.TX_OP_USER_ROLES_AUTHORIZE)
public interface UserAuthorizeOperation extends Operation {
@DataField(order = 2, refContract = true, list = true)
UserRolesEntry[] getUserRolesAuthorizations();
@DataContract(code = DataCodes.TX_OP_USER_ROLE_AUTHORIZE_ENTRY)
public static interface UserRolesEntry {
/**
* 用户地址;
*
* @return
*/
@DataField(order = 0, primitiveType = PrimitiveType.BYTES, list = true)
Bytes[] getUserAddresses();
/**
* 要更新的多角色权限策略;
*
* @return
*/
@DataField(order = 2, refEnum = true)
RolesPolicy getPolicy();
/**
* 授权的角色清单;
*
* @return
*/
@DataField(order = 3, primitiveType = PrimitiveType.TEXT, list = true)
String[] getAuthorizedRoles();
/**
* 取消授权的角色清单;
*
* @return
*/
@DataField(order = 4, primitiveType = PrimitiveType.TEXT, list = true)
String[] getUnauthorizedRoles();
}
}

+ 29
- 29
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserInfoSetOperation.java View File

@@ -1,29 +1,29 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
/**
* @author huanghaiquan
*
*/
@DataContract(code=DataCodes.TX_OP_USER_INFO_SET)
public interface UserInfoSetOperation extends Operation {
String getUserAddress();
KVEntry[] getPropertiesWriteSet();
@DataContract(code=DataCodes.TX_OP_USER_INFO_SET_KV)
public static interface KVEntry{
String getKey();
String getValue();
long getExpectedVersion();
}
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.consts.DataCodes;
/**
* @author huanghaiquan
*
*/
@DataContract(code=DataCodes.TX_OP_USER_INFO_SET)
public interface UserInfoSetOperation extends Operation {
String getUserAddress();
KVEntry[] getPropertiesWriteSet();
@DataContract(code=DataCodes.TX_OP_USER_INFO_SET_KV)
public static interface KVEntry{
String getKey();
String getValue();
long getExpectedVersion();
}
}

+ 13
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/UserRegisterOperation.java View File

@@ -1,13 +1,13 @@
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code = DataCodes.TX_OP_USER_REG)
public interface UserRegisterOperation extends Operation {
@DataField(order = 2, refContract = true)
BlockchainIdentity getUserID();
}
package com.jd.blockchain.ledger;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.consts.DataCodes;
@DataContract(code = DataCodes.TX_OP_USER_REG)
public interface UserRegisterOperation extends Operation {
@DataField(order = 2, refContract = true)
BlockchainIdentity getUserID();
}

+ 26
- 26
source/ledger/ledger-model/src/main/java/com/jd/blockchain/setting/GatewayIncomingSetting.java View File

@@ -1,26 +1,26 @@
package com.jd.blockchain.setting;
/**
* 网关接入设置;
*
* @author huanghaiquan
*
*/
public class GatewayIncomingSetting {
private LedgerIncomingSetting[] ledgers;
/**
* 所有账本的接入设置;
*
* @return
*/
public LedgerIncomingSetting[] getLedgers() {
return ledgers;
}
public void setLedgers(LedgerIncomingSetting[] ledgerSettings) {
this.ledgers = ledgerSettings;
}
}
package com.jd.blockchain.setting;
/**
* 网关接入设置;
*
* @author huanghaiquan
*
*/
public class GatewayIncomingSetting {
private LedgerIncomingSetting[] ledgers;
/**
* 所有账本的接入设置;
*
* @return
*/
public LedgerIncomingSetting[] getLedgers() {
return ledgers;
}
public void setLedgers(LedgerIncomingSetting[] ledgerSettings) {
this.ledgers = ledgerSettings;
}
}

+ 358
- 358
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java View File

@@ -1,358 +1,358 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.utils.Bytes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.net.NetworkAddress;
/**
* @author huanghaiquan
*
*/
public class BlockchainOperationFactory implements ClientOperator, LedgerInitOperator {
private static final SecurityOperationBuilderImpl SECURITY_OP_BUILDER = new SecurityOperationBuilderImpl();
private static final LedgerInitOperationBuilderImpl LEDGER_INIT_OP_BUILDER = new LedgerInitOperationBuilderImpl();
private static final UserRegisterOperationBuilderImpl USER_REG_OP_BUILDER = new UserRegisterOperationBuilderImpl();
private static final DataAccountRegisterOperationBuilderImpl DATA_ACC_REG_OP_BUILDER = new DataAccountRegisterOperationBuilderImpl();
private static final ContractCodeDeployOperationBuilderImpl CONTRACT_CODE_DEPLOY_OP_BUILDER = new ContractCodeDeployOperationBuilderImpl();
// private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl();
private SecurityOperationBuilderFilter securityOpBuilder = new SecurityOperationBuilderFilter();
private static final ParticipantRegisterOperationBuilderImpl PARTICIPANT_REG_OP_BUILDER = new ParticipantRegisterOperationBuilderImpl();
private static final ParticipantStateUpdateOperationBuilderImpl PARTICIPANT_STATE_UPDATE_OP_BUILDER = new ParticipantStateUpdateOperationBuilderImpl();
private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter();
private UserRegisterOperationBuilder userRegOpBuilder = new UserRegisterOperationBuilderFilter();
private DataAccountRegisterOperationBuilder dataAccRegOpBuilder = new DataAccountRegisterOperationBuilderFilter();
private ContractCodeDeployOperationBuilder contractCodeDeployOpBuilder = new ContractCodeDeployOperationBuilderFilter();
private ContractEventSendOperationBuilder contractEventSendOpBuilder = new ContractEventSendOperationBuilderFilter();
private ContractInvocationProxyBuilder contractInvoProxyBuilder = new ContractInvocationProxyBuilder();
private ParticipantRegisterOperationBuilder participantRegOpBuilder = new ParticipantRegisterOperationBuilderFilter();
private ParticipantStateUpdateOperationBuilder participantStateModifyOpBuilder = new ParticipantStateUpdateOperationBuilderFilter();
// TODO: 暂时只支持单线程情形,未考虑多线程;
private List<Operation> operationList = new ArrayList<>();
@Override
public LedgerInitOperationBuilder ledgers() {
return ledgerInitOpBuilder;
}
@Override
public SecurityOperationBuilder security() {
return securityOpBuilder;
}
@Override
public UserRegisterOperationBuilder users() {
return userRegOpBuilder;
}
@Override
public DataAccountRegisterOperationBuilder dataAccounts() {
return dataAccRegOpBuilder;
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) {
return new DataAccountKVSetOperationBuilderFilter(Bytes.fromBase58(accountAddress));
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) {
return new DataAccountKVSetOperationBuilderFilter(accountAddress);
}
@Override
public ContractCodeDeployOperationBuilder contracts() {
return contractCodeDeployOpBuilder;
}
public ContractEventSendOperationBuilder contractEvents() {
return contractEventSendOpBuilder;
}
@Override
public ParticipantRegisterOperationBuilder participants() {return participantRegOpBuilder;}
@Override
public ParticipantStateUpdateOperationBuilder states() {return participantStateModifyOpBuilder;}
@Override
public <T> T contract(String address, Class<T> contractIntf) {
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder);
}
@Override
public <T> T contract(Bytes address, Class<T> contractIntf) {
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder);
}
/**
* 返回已经定义的操作列表;
*
* @return
*/
public Collection<Operation> getOperations() {
return operationList;
}
/**
* 返回与操作列表对应的返回值处理器;
*
* @return
*/
public Collection<OperationResultHandle> getReturnValuetHandlers() {
List<OperationResultHandle> resultHandlers = new ArrayList<OperationResultHandle>();
int index = 0;
for (Operation op : operationList) {
if (op instanceof ContractEventSendOperation) {
// 操作具有返回值,创建对应的结果处理器;
ContractEventSendOpTemplate opTemp = (ContractEventSendOpTemplate) op;
ContractInvocation invocation = opTemp.getInvocation();
OperationResultHandle retnHandler;
if (invocation == null) {
retnHandler = new NullOperationReturnValueHandler(index);
} else {
invocation.setOperationIndex(index);
retnHandler = invocation;
}
resultHandlers.add(retnHandler);
}
index++;
}
return resultHandlers;
}
public void clear() {
operationList.clear();
}
// --------------------------------- 内部类型 -----------------------------------
private class LedgerInitOperationBuilderFilter implements LedgerInitOperationBuilder {
@Override
public LedgerInitOperation create(LedgerInitSetting initSetting) {
LedgerInitOperation op = LEDGER_INIT_OP_BUILDER.create(initSetting);
operationList.add(op);
return op;
}
}
private class UserRegisterOperationBuilderFilter implements UserRegisterOperationBuilder {
@Override
public UserRegisterOperation register(BlockchainIdentity userID) {
UserRegisterOperation op = USER_REG_OP_BUILDER.register(userID);
operationList.add(op);
return op;
}
}
private class SecurityOperationBuilderFilter implements SecurityOperationBuilder {
@Override
public RolesConfigurer roles() {
RolesConfigurer rolesConfigurer = SECURITY_OP_BUILDER.roles();
operationList.add(rolesConfigurer.getOperation());
return rolesConfigurer;
}
@Override
public UserAuthorizer authorziations() {
UserAuthorizer userAuthorizer = SECURITY_OP_BUILDER.authorziations();
operationList.add(userAuthorizer.getOperation());
return userAuthorizer;
}
}
private class DataAccountRegisterOperationBuilderFilter implements DataAccountRegisterOperationBuilder {
@Override
public DataAccountRegisterOperation register(BlockchainIdentity accountID) {
DataAccountRegisterOperation op = DATA_ACC_REG_OP_BUILDER.register(accountID);
operationList.add(op);
return op;
}
}
private class DataAccountKVSetOperationBuilderFilter implements DataAccountKVSetOperationBuilder {
private DataAccountKVSetOperationBuilder innerBuilder;
private DataAccountKVSetOperation op;
public DataAccountKVSetOperationBuilderFilter(Bytes accountAddress) {
innerBuilder = new DataAccountKVSetOperationBuilderImpl(accountAddress);
}
@Override
public DataAccountKVSetOperation getOperation() {
return innerBuilder.getOperation();
}
private void addOperation() {
if (op == null) {
op = innerBuilder.getOperation();
operationList.add(op);
}
}
@Override
public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) {
innerBuilder.setText(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) {
innerBuilder.setInt64(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) {
innerBuilder.setBytes(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) {
innerBuilder.setBytes(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) {
innerBuilder.setImage(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) {
innerBuilder.setJSON(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) {
innerBuilder.setXML(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) {
innerBuilder.setTimestamp(key, value, expVersion);
addOperation();
return this;
}
}
private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder {
@Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode);
operationList.add(op);
return op;
}
}
private class ParticipantRegisterOperationBuilderFilter implements ParticipantRegisterOperationBuilder {
@Override
public ParticipantRegisterOperation register(String participantName, BlockchainIdentity participantIdentity, NetworkAddress networkAddress) {
ParticipantRegisterOperation op = PARTICIPANT_REG_OP_BUILDER.register(participantName, participantIdentity, networkAddress);
operationList.add(op);
return op;
}
}
private class ParticipantStateUpdateOperationBuilderFilter implements ParticipantStateUpdateOperationBuilder {
@Override
public ParticipantStateUpdateOperation update(BlockchainIdentity blockchainIdentity, NetworkAddress networkAddress, ParticipantNodeState participantNodeState) {
ParticipantStateUpdateOperation op = PARTICIPANT_STATE_UPDATE_OP_BUILDER.update(blockchainIdentity, networkAddress, participantNodeState);
operationList.add(op);
return op;
}
}
private class ContractEventSendOperationBuilderFilter implements ContractEventSendOperationBuilder {
@Override
public ContractEventSendOperation send(String address, String event, BytesValueList args) {
return send(Bytes.fromBase58(address), event, args);
}
@Override
public synchronized ContractEventSendOperation send(Bytes address, String event, BytesValueList args) {
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
operationList.add(op);
return op;
}
}
/**
* 不做任何操作的返回值处理器;
*
* @author huanghaiquan
*
*/
private static class NullOperationReturnValueHandler implements OperationResultHandle {
private int operationIndex;
public NullOperationReturnValueHandler(int operationIndex) {
this.operationIndex = operationIndex;
}
@Override
public int getOperationIndex() {
return operationIndex;
}
@Override
public Object complete(BytesValue bytesValue) {
return null;
}
@Override
public void complete(Throwable error) {
}
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.utils.Bytes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.net.NetworkAddress;
/**
* @author huanghaiquan
*
*/
public class BlockchainOperationFactory implements ClientOperator, LedgerInitOperator {
private static final SecurityOperationBuilderImpl SECURITY_OP_BUILDER = new SecurityOperationBuilderImpl();
private static final LedgerInitOperationBuilderImpl LEDGER_INIT_OP_BUILDER = new LedgerInitOperationBuilderImpl();
private static final UserRegisterOperationBuilderImpl USER_REG_OP_BUILDER = new UserRegisterOperationBuilderImpl();
private static final DataAccountRegisterOperationBuilderImpl DATA_ACC_REG_OP_BUILDER = new DataAccountRegisterOperationBuilderImpl();
private static final ContractCodeDeployOperationBuilderImpl CONTRACT_CODE_DEPLOY_OP_BUILDER = new ContractCodeDeployOperationBuilderImpl();
// private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl();
private SecurityOperationBuilderFilter securityOpBuilder = new SecurityOperationBuilderFilter();
private static final ParticipantRegisterOperationBuilderImpl PARTICIPANT_REG_OP_BUILDER = new ParticipantRegisterOperationBuilderImpl();
private static final ParticipantStateUpdateOperationBuilderImpl PARTICIPANT_STATE_UPDATE_OP_BUILDER = new ParticipantStateUpdateOperationBuilderImpl();
private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter();
private UserRegisterOperationBuilder userRegOpBuilder = new UserRegisterOperationBuilderFilter();
private DataAccountRegisterOperationBuilder dataAccRegOpBuilder = new DataAccountRegisterOperationBuilderFilter();
private ContractCodeDeployOperationBuilder contractCodeDeployOpBuilder = new ContractCodeDeployOperationBuilderFilter();
private ContractEventSendOperationBuilder contractEventSendOpBuilder = new ContractEventSendOperationBuilderFilter();
private ContractInvocationProxyBuilder contractInvoProxyBuilder = new ContractInvocationProxyBuilder();
private ParticipantRegisterOperationBuilder participantRegOpBuilder = new ParticipantRegisterOperationBuilderFilter();
private ParticipantStateUpdateOperationBuilder participantStateModifyOpBuilder = new ParticipantStateUpdateOperationBuilderFilter();
// TODO: 暂时只支持单线程情形,未考虑多线程;
private List<Operation> operationList = new ArrayList<>();
@Override
public LedgerInitOperationBuilder ledgers() {
return ledgerInitOpBuilder;
}
@Override
public SecurityOperationBuilder security() {
return securityOpBuilder;
}
@Override
public UserRegisterOperationBuilder users() {
return userRegOpBuilder;
}
@Override
public DataAccountRegisterOperationBuilder dataAccounts() {
return dataAccRegOpBuilder;
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) {
return new DataAccountKVSetOperationBuilderFilter(Bytes.fromBase58(accountAddress));
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) {
return new DataAccountKVSetOperationBuilderFilter(accountAddress);
}
@Override
public ContractCodeDeployOperationBuilder contracts() {
return contractCodeDeployOpBuilder;
}
public ContractEventSendOperationBuilder contractEvents() {
return contractEventSendOpBuilder;
}
@Override
public ParticipantRegisterOperationBuilder participants() {return participantRegOpBuilder;}
@Override
public ParticipantStateUpdateOperationBuilder states() {return participantStateModifyOpBuilder;}
@Override
public <T> T contract(String address, Class<T> contractIntf) {
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder);
}
@Override
public <T> T contract(Bytes address, Class<T> contractIntf) {
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder);
}
/**
* 返回已经定义的操作列表;
*
* @return
*/
public Collection<Operation> getOperations() {
return operationList;
}
/**
* 返回与操作列表对应的返回值处理器;
*
* @return
*/
public Collection<OperationResultHandle> getReturnValuetHandlers() {
List<OperationResultHandle> resultHandlers = new ArrayList<OperationResultHandle>();
int index = 0;
for (Operation op : operationList) {
if (op instanceof ContractEventSendOperation) {
// 操作具有返回值,创建对应的结果处理器;
ContractEventSendOpTemplate opTemp = (ContractEventSendOpTemplate) op;
ContractInvocation invocation = opTemp.getInvocation();
OperationResultHandle retnHandler;
if (invocation == null) {
retnHandler = new NullOperationReturnValueHandler(index);
} else {
invocation.setOperationIndex(index);
retnHandler = invocation;
}
resultHandlers.add(retnHandler);
}
index++;
}
return resultHandlers;
}
public void clear() {
operationList.clear();
}
// --------------------------------- 内部类型 -----------------------------------
private class LedgerInitOperationBuilderFilter implements LedgerInitOperationBuilder {
@Override
public LedgerInitOperation create(LedgerInitSetting initSetting) {
LedgerInitOperation op = LEDGER_INIT_OP_BUILDER.create(initSetting);
operationList.add(op);
return op;
}
}
private class UserRegisterOperationBuilderFilter implements UserRegisterOperationBuilder {
@Override
public UserRegisterOperation register(BlockchainIdentity userID) {
UserRegisterOperation op = USER_REG_OP_BUILDER.register(userID);
operationList.add(op);
return op;
}
}
private class SecurityOperationBuilderFilter implements SecurityOperationBuilder {
@Override
public RolesConfigurer roles() {
RolesConfigurer rolesConfigurer = SECURITY_OP_BUILDER.roles();
operationList.add(rolesConfigurer.getOperation());
return rolesConfigurer;
}
@Override
public UserAuthorizer authorziations() {
UserAuthorizer userAuthorizer = SECURITY_OP_BUILDER.authorziations();
operationList.add(userAuthorizer.getOperation());
return userAuthorizer;
}
}
private class DataAccountRegisterOperationBuilderFilter implements DataAccountRegisterOperationBuilder {
@Override
public DataAccountRegisterOperation register(BlockchainIdentity accountID) {
DataAccountRegisterOperation op = DATA_ACC_REG_OP_BUILDER.register(accountID);
operationList.add(op);
return op;
}
}
private class DataAccountKVSetOperationBuilderFilter implements DataAccountKVSetOperationBuilder {
private DataAccountKVSetOperationBuilder innerBuilder;
private DataAccountKVSetOperation op;
public DataAccountKVSetOperationBuilderFilter(Bytes accountAddress) {
innerBuilder = new DataAccountKVSetOperationBuilderImpl(accountAddress);
}
@Override
public DataAccountKVSetOperation getOperation() {
return innerBuilder.getOperation();
}
private void addOperation() {
if (op == null) {
op = innerBuilder.getOperation();
operationList.add(op);
}
}
@Override
public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) {
innerBuilder.setText(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) {
innerBuilder.setInt64(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) {
innerBuilder.setBytes(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) {
innerBuilder.setBytes(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) {
innerBuilder.setImage(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) {
innerBuilder.setJSON(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) {
innerBuilder.setXML(key, value, expVersion);
addOperation();
return this;
}
@Override
public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) {
innerBuilder.setTimestamp(key, value, expVersion);
addOperation();
return this;
}
}
private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder {
@Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode);
operationList.add(op);
return op;
}
}
private class ParticipantRegisterOperationBuilderFilter implements ParticipantRegisterOperationBuilder {
@Override
public ParticipantRegisterOperation register(String participantName, BlockchainIdentity participantIdentity, NetworkAddress networkAddress) {
ParticipantRegisterOperation op = PARTICIPANT_REG_OP_BUILDER.register(participantName, participantIdentity, networkAddress);
operationList.add(op);
return op;
}
}
private class ParticipantStateUpdateOperationBuilderFilter implements ParticipantStateUpdateOperationBuilder {
@Override
public ParticipantStateUpdateOperation update(BlockchainIdentity blockchainIdentity, NetworkAddress networkAddress, ParticipantNodeState participantNodeState) {
ParticipantStateUpdateOperation op = PARTICIPANT_STATE_UPDATE_OP_BUILDER.update(blockchainIdentity, networkAddress, participantNodeState);
operationList.add(op);
return op;
}
}
private class ContractEventSendOperationBuilderFilter implements ContractEventSendOperationBuilder {
@Override
public ContractEventSendOperation send(String address, String event, BytesValueList args) {
return send(Bytes.fromBase58(address), event, args);
}
@Override
public synchronized ContractEventSendOperation send(Bytes address, String event, BytesValueList args) {
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
operationList.add(op);
return op;
}
}
/**
* 不做任何操作的返回值处理器;
*
* @author huanghaiquan
*
*/
private static class NullOperationReturnValueHandler implements OperationResultHandle {
private int operationIndex;
public NullOperationReturnValueHandler(int operationIndex) {
this.operationIndex = operationIndex;
}
@Override
public int getOperationIndex() {
return operationIndex;
}
@Override
public Object complete(BytesValue bytesValue) {
return null;
}
@Override
public void complete(Throwable error) {
}
}
}

+ 330
- 330
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainQueryService.java View File

@@ -1,330 +1,330 @@
package com.jd.blockchain.transaction;
import org.springframework.cglib.core.Block;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractInfo;
import com.jd.blockchain.ledger.TypedKVEntry;
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.LedgerMetadata;
import com.jd.blockchain.ledger.LedgerTransaction;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.Transaction;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.UserInfo;
/**
* 区块链查询器;
*
* @author huanghaiquan
*
*/
public interface BlockchainQueryService {
/**
* 返回所有的账本的 hash 列表;<br>
*
* 注:账本的 hash 既是该账本的创世区块的 hash;
*
* @return 账本 hash 的集合;
*/
HashDigest[] getLedgerHashs();
/**
* 获取账本信息;
*
* @param ledgerHash
* @return 账本对象;如果不存在,则返回 null;
*/
LedgerInfo getLedger(HashDigest ledgerHash);
/**
* 获取账本信息;
*
* @param ledgerHash
* @return 账本对象;如果不存在,则返回 null;
*/
LedgerAdminInfo getLedgerAdminInfo(HashDigest ledgerHash);
/**
* 返回当前账本的参与者信息列表
*
* @param ledgerHash
* @return
*/
ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash);
/**
* 返回当前账本的元数据
*
* @param ledgerHash
* @return
*/
LedgerMetadata getLedgerMetadata(HashDigest ledgerHash);
/**
* 返回指定账本序号的区块;
*
* @param ledgerHash 账本hash;
* @param height 高度;
* @return
*/
LedgerBlock getBlock(HashDigest ledgerHash, long height);
/**
* 返回指定区块hash的区块;
*
* @param ledgerHash 账本hash;
* @param blockHash 区块hash;
* @return
*/
LedgerBlock getBlock(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回指定高度的区块中记录的交易总数;
*
* @param ledgerHash
* @param height
* @return
*/
long getTransactionCount(HashDigest ledgerHash, long height);
/**
* 返回指定高度的区块中记录的交易总数;
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getTransactionCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的交易总数
*
* @param ledgerHash
* @return
*/
long getTransactionTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度的区块中记录的数据账户总数
*
* @param ledgerHash
* @param height
* @return
*/
long getDataAccountCount(HashDigest ledgerHash, long height);
/**
* 返回指定的区块中记录的数据账户总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getDataAccountCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的数据账户总数
*
* @param ledgerHash
* @return
*/
long getDataAccountTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度区块中的用户总数
*
* @param ledgerHash
* @param height
* @return
*/
long getUserCount(HashDigest ledgerHash, long height);
/**
* 返回指定区块中的用户总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getUserCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的用户总数
*
* @param ledgerHash
* @return
*/
long getUserTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度区块中的合约总数
*
* @param ledgerHash
* @param height
* @return
*/
long getContractCount(HashDigest ledgerHash, long height);
/**
* 返回指定区块中的合约总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getContractCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的合约总数
*
* @param ledgerHash
* @return
*/
long getContractTotalCount(HashDigest ledgerHash);
/**
* 分页返回指定账本序号的区块中的交易列表;
*
* @param ledgerHash 账本hash;
* @param height 账本高度;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 最小为1,最大值受到系统参数的限制;<br>
* 注:通过 {@link #getBlock(String, long)} 方法获得的区块信息中可以得到区块的总交易数
* {@link Block#getTxCount()};
* @return
*/
LedgerTransaction[] getTransactions(HashDigest ledgerHash, long height, int fromIndex, int count);
/**
* 分页返回指定账本序号的区块中的交易列表;
*
* @param ledgerHash 账本hash;
* @param blockHash 账本高度;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 如果参数值为 -1,则返回全部的记录;<br>
* 注:通过 {@link #getBlock(String, String)}
* 方法获得的区块信息中可以得到区块的总交易数 {@link Block#getTxCount()};
* @return
*/
LedgerTransaction[] getTransactions(HashDigest ledgerHash, HashDigest blockHash, int fromIndex, int count);
/**
* 根据交易内容的哈希获取对应的交易记录;
*
* @param ledgerHash 账本hash;
* @param contentHash 交易内容的hash,即交易的 {@link Transaction#getContentHash()} 属性的值;
* @return
*/
LedgerTransaction getTransactionByContentHash(HashDigest ledgerHash, HashDigest contentHash);
/**
* 根据交易内容的哈希获取对应的交易状态;
*
* @param ledgerHash 账本hash;
* @param contentHash 交易内容的hash,即交易的 {@link Transaction#getContentHash()} 属性的值;
* @return
*/
TransactionState getTransactionStateByContentHash(HashDigest ledgerHash, HashDigest contentHash);
/**
* 返回用户信息;
*
* @param ledgerHash
* @param address
* @return
*/
UserInfo getUser(HashDigest ledgerHash, String address);
/**
* 返回数据账户信息;
*
* @param ledgerHash
* @param address
* @return
*/
BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address);
/**
* 返回数据账户中指定的键的最新值; <br>
*
* 返回结果的顺序与指定的键的顺序是一致的;<br>
*
* 如果某个键不存在,则返回版本为 -1 的数据项;
*
* @param ledgerHash
* @param address
* @param keys
* @return
*/
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys);
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO);
/**
* 返回指定数据账户中KV数据的总数; <br>
*
* @param ledgerHash
* @param address
* @return
*/
long getDataEntriesTotalCount(HashDigest ledgerHash, String address);
/**
* 返回数据账户中指定序号的最新值; 返回结果的顺序与指定的序号的顺序是一致的;<br>
*
* @param ledgerHash 账本hash;
* @param address 数据账户地址;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 如果参数值为 -1,则返回全部的记录;<br>
* @return
*/
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count);
/**
* 返回合约账户信息;
*
* @param ledgerHash
* @param address
* @return
*/
ContractInfo getContract(HashDigest ledgerHash, String address);
/**
* get users by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count);
/**
* get data accounts by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count);
/**
* get contract accounts by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count);
}
package com.jd.blockchain.transaction;
import org.springframework.cglib.core.Block;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractInfo;
import com.jd.blockchain.ledger.TypedKVEntry;
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.LedgerMetadata;
import com.jd.blockchain.ledger.LedgerTransaction;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.Transaction;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.UserInfo;
/**
* 区块链查询器;
*
* @author huanghaiquan
*
*/
public interface BlockchainQueryService {
/**
* 返回所有的账本的 hash 列表;<br>
*
* 注:账本的 hash 既是该账本的创世区块的 hash;
*
* @return 账本 hash 的集合;
*/
HashDigest[] getLedgerHashs();
/**
* 获取账本信息;
*
* @param ledgerHash
* @return 账本对象;如果不存在,则返回 null;
*/
LedgerInfo getLedger(HashDigest ledgerHash);
/**
* 获取账本信息;
*
* @param ledgerHash
* @return 账本对象;如果不存在,则返回 null;
*/
LedgerAdminInfo getLedgerAdminInfo(HashDigest ledgerHash);
/**
* 返回当前账本的参与者信息列表
*
* @param ledgerHash
* @return
*/
ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash);
/**
* 返回当前账本的元数据
*
* @param ledgerHash
* @return
*/
LedgerMetadata getLedgerMetadata(HashDigest ledgerHash);
/**
* 返回指定账本序号的区块;
*
* @param ledgerHash 账本hash;
* @param height 高度;
* @return
*/
LedgerBlock getBlock(HashDigest ledgerHash, long height);
/**
* 返回指定区块hash的区块;
*
* @param ledgerHash 账本hash;
* @param blockHash 区块hash;
* @return
*/
LedgerBlock getBlock(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回指定高度的区块中记录的交易总数;
*
* @param ledgerHash
* @param height
* @return
*/
long getTransactionCount(HashDigest ledgerHash, long height);
/**
* 返回指定高度的区块中记录的交易总数;
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getTransactionCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的交易总数
*
* @param ledgerHash
* @return
*/
long getTransactionTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度的区块中记录的数据账户总数
*
* @param ledgerHash
* @param height
* @return
*/
long getDataAccountCount(HashDigest ledgerHash, long height);
/**
* 返回指定的区块中记录的数据账户总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getDataAccountCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的数据账户总数
*
* @param ledgerHash
* @return
*/
long getDataAccountTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度区块中的用户总数
*
* @param ledgerHash
* @param height
* @return
*/
long getUserCount(HashDigest ledgerHash, long height);
/**
* 返回指定区块中的用户总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getUserCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的用户总数
*
* @param ledgerHash
* @return
*/
long getUserTotalCount(HashDigest ledgerHash);
/**
* 返回指定高度区块中的合约总数
*
* @param ledgerHash
* @param height
* @return
*/
long getContractCount(HashDigest ledgerHash, long height);
/**
* 返回指定区块中的合约总数
*
* @param ledgerHash
* @param blockHash
* @return
*/
long getContractCount(HashDigest ledgerHash, HashDigest blockHash);
/**
* 返回当前账本的合约总数
*
* @param ledgerHash
* @return
*/
long getContractTotalCount(HashDigest ledgerHash);
/**
* 分页返回指定账本序号的区块中的交易列表;
*
* @param ledgerHash 账本hash;
* @param height 账本高度;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 最小为1,最大值受到系统参数的限制;<br>
* 注:通过 {@link #getBlock(String, long)} 方法获得的区块信息中可以得到区块的总交易数
* {@link Block#getTxCount()};
* @return
*/
LedgerTransaction[] getTransactions(HashDigest ledgerHash, long height, int fromIndex, int count);
/**
* 分页返回指定账本序号的区块中的交易列表;
*
* @param ledgerHash 账本hash;
* @param blockHash 账本高度;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 如果参数值为 -1,则返回全部的记录;<br>
* 注:通过 {@link #getBlock(String, String)}
* 方法获得的区块信息中可以得到区块的总交易数 {@link Block#getTxCount()};
* @return
*/
LedgerTransaction[] getTransactions(HashDigest ledgerHash, HashDigest blockHash, int fromIndex, int count);
/**
* 根据交易内容的哈希获取对应的交易记录;
*
* @param ledgerHash 账本hash;
* @param contentHash 交易内容的hash,即交易的 {@link Transaction#getContentHash()} 属性的值;
* @return
*/
LedgerTransaction getTransactionByContentHash(HashDigest ledgerHash, HashDigest contentHash);
/**
* 根据交易内容的哈希获取对应的交易状态;
*
* @param ledgerHash 账本hash;
* @param contentHash 交易内容的hash,即交易的 {@link Transaction#getContentHash()} 属性的值;
* @return
*/
TransactionState getTransactionStateByContentHash(HashDigest ledgerHash, HashDigest contentHash);
/**
* 返回用户信息;
*
* @param ledgerHash
* @param address
* @return
*/
UserInfo getUser(HashDigest ledgerHash, String address);
/**
* 返回数据账户信息;
*
* @param ledgerHash
* @param address
* @return
*/
BlockchainIdentity getDataAccount(HashDigest ledgerHash, String address);
/**
* 返回数据账户中指定的键的最新值; <br>
*
* 返回结果的顺序与指定的键的顺序是一致的;<br>
*
* 如果某个键不存在,则返回版本为 -1 的数据项;
*
* @param ledgerHash
* @param address
* @param keys
* @return
*/
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys);
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO);
/**
* 返回指定数据账户中KV数据的总数; <br>
*
* @param ledgerHash
* @param address
* @return
*/
long getDataEntriesTotalCount(HashDigest ledgerHash, String address);
/**
* 返回数据账户中指定序号的最新值; 返回结果的顺序与指定的序号的顺序是一致的;<br>
*
* @param ledgerHash 账本hash;
* @param address 数据账户地址;
* @param fromIndex 开始的记录数;
* @param count 本次返回的记录数;<br>
* 如果参数值为 -1,则返回全部的记录;<br>
* @return
*/
TypedKVEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count);
/**
* 返回合约账户信息;
*
* @param ledgerHash
* @param address
* @return
*/
ContractInfo getContract(HashDigest ledgerHash, String address);
/**
* get users by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getUsers(HashDigest ledgerHash, int fromIndex, int count);
/**
* get data accounts by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getDataAccounts(HashDigest ledgerHash, int fromIndex, int count);
/**
* get contract accounts by ledgerHash and its range;
*
* @param ledgerHash
* @param fromIndex
* @param count
* @return
*/
BlockchainIdentity[] getContractAccounts(HashDigest ledgerHash, int fromIndex, int count);
}

+ 41
- 41
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOpTemplate.java View File

@@ -1,41 +1,41 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.DigitalSignature;
public class ContractCodeDeployOpTemplate implements ContractCodeDeployOperation {
static {
DataContractRegistry.register(ContractCodeDeployOperation.class);
}
private BlockchainIdentity contractID;
private byte[] chainCode;
public ContractCodeDeployOpTemplate() {
}
public ContractCodeDeployOpTemplate(BlockchainIdentity contractID, byte[] chainCode) {
this.contractID = contractID;
this.chainCode = chainCode;
}
@Override
public BlockchainIdentity getContractID() {
return contractID;
}
@Override
public byte[] getChainCode() {
return chainCode;
}
@Override
public DigitalSignature getAddressSignature() {
// TODO Auto-generated method stub
return null;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.DigitalSignature;
public class ContractCodeDeployOpTemplate implements ContractCodeDeployOperation {
static {
DataContractRegistry.register(ContractCodeDeployOperation.class);
}
private BlockchainIdentity contractID;
private byte[] chainCode;
public ContractCodeDeployOpTemplate() {
}
public ContractCodeDeployOpTemplate(BlockchainIdentity contractID, byte[] chainCode) {
this.contractID = contractID;
this.chainCode = chainCode;
}
@Override
public BlockchainIdentity getContractID() {
return contractID;
}
@Override
public byte[] getChainCode() {
return chainCode;
}
@Override
public DigitalSignature getAddressSignature() {
// TODO Auto-generated method stub
return null;
}
}

+ 19
- 19
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOperationBuilder.java View File

@@ -1,19 +1,19 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
public interface ContractCodeDeployOperationBuilder {
/**
* 部署合约;
*
* @param id
* 区块链身份;
* @param chainCode
* 合约应用的字节代码;
* @return
*/
ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
public interface ContractCodeDeployOperationBuilder {
/**
* 部署合约;
*
* @param id
* 区块链身份;
* @param chainCode
* 合约应用的字节代码;
* @return
*/
ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode);
}

+ 14
- 14
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractCodeDeployOperationBuilderImpl.java View File

@@ -1,14 +1,14 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
public class ContractCodeDeployOperationBuilderImpl implements ContractCodeDeployOperationBuilder{
@Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
ContractCodeDeployOpTemplate op = new ContractCodeDeployOpTemplate(id, chainCode);
return op;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
public class ContractCodeDeployOperationBuilderImpl implements ContractCodeDeployOperationBuilder{
@Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
ContractCodeDeployOpTemplate op = new ContractCodeDeployOpTemplate(id, chainCode);
return op;
}
}

+ 24
- 24
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilder.java View File

@@ -1,24 +1,24 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.utils.Bytes;
public interface ContractEventSendOperationBuilder {
/**
* @param address 合约地址;
* @param event 事件名;
* @param args 事件参数;
* @return
*/
ContractEventSendOperation send(String address, String event, BytesValueList args);
/**
* @param address 合约地址;
* @param event 事件名;
* @param args 事件参数;
* @return
*/
ContractEventSendOperation send(Bytes address, String event, BytesValueList args);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.utils.Bytes;
public interface ContractEventSendOperationBuilder {
/**
* @param address 合约地址;
* @param event 事件名;
* @param args 事件参数;
* @return
*/
ContractEventSendOperation send(String address, String event, BytesValueList args);
/**
* @param address 合约地址;
* @param event 事件名;
* @param args 事件参数;
* @return
*/
ContractEventSendOperation send(Bytes address, String event, BytesValueList args);
}

+ 21
- 21
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java View File

@@ -1,21 +1,21 @@
//package com.jd.blockchain.transaction;
//
//import com.jd.blockchain.ledger.ContractEventSendOperation;
//import com.jd.blockchain.utils.Bytes;
//
//@Deprecated
//class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder {
//
// @Override
// public ContractEventSendOperation send(String address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args);
// return op;
// }
//
// @Override
// public ContractEventSendOperation send(Bytes address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
// return op;
// }
//
//}
//package com.jd.blockchain.transaction;
//
//import com.jd.blockchain.ledger.ContractEventSendOperation;
//import com.jd.blockchain.utils.Bytes;
//
//@Deprecated
//class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder {
//
// @Override
// public ContractEventSendOperation send(String address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args);
// return op;
// }
//
// @Override
// public ContractEventSendOperation send(Bytes address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
// return op;
// }
//
//}

+ 44
- 44
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java View File

@@ -1,44 +1,44 @@
package com.jd.blockchain.transaction;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jd.blockchain.contract.ContractType;
import com.jd.blockchain.utils.Bytes;
/**
* 合约调用代理的构建器;
*
* @author huanghaiquan
*
*/
public class ContractInvocationProxyBuilder {
private Map<Class<?>, ContractType> contractTypes = new ConcurrentHashMap<>();
public <T> T create(String address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) {
return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder);
}
@SuppressWarnings("unchecked")
public <T> T create(Bytes address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) {
ContractType contractType = resolveContractType(contractIntf);
ContractInvocationHandler proxyHandler = new ContractInvocationHandler(address, contractType, contractEventBuilder);
T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { contractIntf }, proxyHandler);
return proxy;
}
private ContractType resolveContractType(Class<?> contractIntf) {
ContractType contractType = contractTypes.get(contractIntf);
if (contractType != null) {
return contractType;
}
ContractType ct = ContractType.resolve(contractIntf);
contractTypes.put(contractIntf, ct);
return ct;
}
}
package com.jd.blockchain.transaction;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jd.blockchain.contract.ContractType;
import com.jd.blockchain.utils.Bytes;
/**
* 合约调用代理的构建器;
*
* @author huanghaiquan
*
*/
public class ContractInvocationProxyBuilder {
private Map<Class<?>, ContractType> contractTypes = new ConcurrentHashMap<>();
public <T> T create(String address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) {
return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder);
}
@SuppressWarnings("unchecked")
public <T> T create(Bytes address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) {
ContractType contractType = resolveContractType(contractIntf);
ContractInvocationHandler proxyHandler = new ContractInvocationHandler(address, contractType, contractEventBuilder);
T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { contractIntf }, proxyHandler);
return proxy;
}
private ContractType resolveContractType(Class<?> contractIntf) {
ContractType contractType = contractTypes.get(contractIntf);
if (contractType != null) {
return contractType;
}
ContractType ct = ContractType.resolve(contractIntf);
contractTypes.put(contractIntf, ct);
return ct;
}
}

+ 65
- 65
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOpTemplate.java View File

@@ -1,65 +1,65 @@
package com.jd.blockchain.transaction;
import java.util.LinkedHashMap;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation {
static {
DataContractRegistry.register(DataAccountKVSetOperation.class);
}
private Bytes accountAddress;
private Map<String, KVWriteEntry> kvset = new LinkedHashMap<>();
public DataAccountKVSetOpTemplate() {
}
public DataAccountKVSetOpTemplate(Bytes accountAddress) {
this.accountAddress = accountAddress;
}
public DataAccountKVSetOpTemplate(Bytes accountAddress, Map<String, KVWriteEntry> kvset) {
this.accountAddress = accountAddress;
this.kvset = kvset;
}
@Override
public Bytes getAccountAddress() {
return accountAddress;
}
@Override
public KVWriteEntry[] getWriteSet() {
return kvset.values().toArray(new KVWriteEntry[kvset.size()]);
}
public void setWriteSet(Object[] kvEntries) {
for (Object object : kvEntries) {
KVWriteEntry kvEntry = (KVWriteEntry) object;
set(kvEntry.getKey(), kvEntry.getValue(), kvEntry.getExpectedVersion());
}
return;
}
public void set(String key, BytesValue value, long expVersion) {
if (kvset.containsKey(key)) {
throw new IllegalArgumentException("Cann't set the same key repeatedly!");
}
KVData kvdata = new KVData(key, value, expVersion);
kvset.put(key, kvdata);
}
public void set(KVData kvData) {
if (kvset.containsKey(kvData.getKey())) {
throw new IllegalArgumentException("Cann't set the same key repeatedly!");
}
kvset.put(kvData.getKey(), kvData);
}
}
package com.jd.blockchain.transaction;
import java.util.LinkedHashMap;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation {
static {
DataContractRegistry.register(DataAccountKVSetOperation.class);
}
private Bytes accountAddress;
private Map<String, KVWriteEntry> kvset = new LinkedHashMap<>();
public DataAccountKVSetOpTemplate() {
}
public DataAccountKVSetOpTemplate(Bytes accountAddress) {
this.accountAddress = accountAddress;
}
public DataAccountKVSetOpTemplate(Bytes accountAddress, Map<String, KVWriteEntry> kvset) {
this.accountAddress = accountAddress;
this.kvset = kvset;
}
@Override
public Bytes getAccountAddress() {
return accountAddress;
}
@Override
public KVWriteEntry[] getWriteSet() {
return kvset.values().toArray(new KVWriteEntry[kvset.size()]);
}
public void setWriteSet(Object[] kvEntries) {
for (Object object : kvEntries) {
KVWriteEntry kvEntry = (KVWriteEntry) object;
set(kvEntry.getKey(), kvEntry.getValue(), kvEntry.getExpectedVersion());
}
return;
}
public void set(String key, BytesValue value, long expVersion) {
if (kvset.containsKey(key)) {
throw new IllegalArgumentException("Cann't set the same key repeatedly!");
}
KVData kvdata = new KVData(key, value, expVersion);
kvset.put(key, kvdata);
}
public void set(KVData kvData) {
if (kvset.containsKey(kvData.getKey())) {
throw new IllegalArgumentException("Cann't set the same key repeatedly!");
}
kvset.put(kvData.getKey(), kvData);
}
}

+ 151
- 151
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilder.java View File

@@ -1,151 +1,151 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
/**
* @author huanghaiquan
*
*/
public interface DataAccountKVSetOperationBuilder {
/**
* 数据账户的KV写入操作;
*
* @return
*/
DataAccountKVSetOperation getOperation();
// /**
// * 写入字节数组;
// *
// * @param key
// * 键;
// * @param value
// * 值;byte[]格式
// * @param expVersion
// * 预期的当前版本;如果版本不匹配,则写入失败;
// * @return
// */
// @Deprecated
// DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion);
/**
* 写入字节数组;
*
* @param key
* 键;
* @param value
* 值;byte[]格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion);
/**
* 写入字节数组;
*
* @param key
* 键;
* @param value
* 值;Bytes格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion);
/**
* 写入键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion);
// /**
// * 写入文本键值;
// *
// * @param key
// * 键;
// * @param value
// * 值;String格式
// * @param expVersion
// * 预期的当前版本;如果版本不匹配,则写入失败;
// * @return
// */
// @Deprecated
// DataAccountKVSetOperationBuilder set(String key, String value, long expVersion);
/**
* 写入文本键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion);
/**
* 写入JSON键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion);
/**
* 写入XML键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion);
/**
* 写入64位整数;
*
* @param key
* 键;
* @param value
* 值;long格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion);
/**
* 写入时间戳;
*
* @param key
* 键;
* @param value
* 值;long格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
/**
* @author huanghaiquan
*
*/
public interface DataAccountKVSetOperationBuilder {
/**
* 数据账户的KV写入操作;
*
* @return
*/
DataAccountKVSetOperation getOperation();
// /**
// * 写入字节数组;
// *
// * @param key
// * 键;
// * @param value
// * 值;byte[]格式
// * @param expVersion
// * 预期的当前版本;如果版本不匹配,则写入失败;
// * @return
// */
// @Deprecated
// DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion);
/**
* 写入字节数组;
*
* @param key
* 键;
* @param value
* 值;byte[]格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion);
/**
* 写入字节数组;
*
* @param key
* 键;
* @param value
* 值;Bytes格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion);
/**
* 写入键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion);
// /**
// * 写入文本键值;
// *
// * @param key
// * 键;
// * @param value
// * 值;String格式
// * @param expVersion
// * 预期的当前版本;如果版本不匹配,则写入失败;
// * @return
// */
// @Deprecated
// DataAccountKVSetOperationBuilder set(String key, String value, long expVersion);
/**
* 写入文本键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion);
/**
* 写入JSON键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion);
/**
* 写入XML键值;
*
* @param key
* 键;
* @param value
* 值;String格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion);
/**
* 写入64位整数;
*
* @param key
* 键;
* @param value
* 值;long格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion);
/**
* 写入时间戳;
*
* @param key
* 键;
* @param value
* 值;long格式
* @param expVersion
* 预期的当前版本;如果版本不匹配,则写入失败;
* @return
*/
DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion);
}

+ 88
- 88
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java View File

@@ -1,88 +1,88 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOperationBuilder {
private DataAccountKVSetOpTemplate operation;
public DataAccountKVSetOperationBuilderImpl(Bytes accountAddress) {
operation = new DataAccountKVSetOpTemplate(accountAddress);
}
@Override
public DataAccountKVSetOperation getOperation() {
return operation;
}
// @Deprecated
// @Override
// public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) {
// return setBytes(key, value, expVersion);
// }
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) {
BytesValue bytesValue = TypedValue.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) {
BytesValue bytesValue = TypedValue.fromImage(value);
operation.set(key, bytesValue, expVersion);
return this;
}
// @Override
// public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) {
// return setText(key, value, expVersion);
// }
@Override
public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromText(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) {
BytesValue bytesValue = TypedValue.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) {
BytesValue bytesValue = TypedValue.fromInt64(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromJSON(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromXML(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) {
BytesValue bytesValue = TypedValue.fromTimestamp(value);
operation.set(key, bytesValue, expVersion);
return this;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.TypedValue;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOperationBuilder {
private DataAccountKVSetOpTemplate operation;
public DataAccountKVSetOperationBuilderImpl(Bytes accountAddress) {
operation = new DataAccountKVSetOpTemplate(accountAddress);
}
@Override
public DataAccountKVSetOperation getOperation() {
return operation;
}
// @Deprecated
// @Override
// public DataAccountKVSetOperationBuilder set(String key, byte[] value, long expVersion) {
// return setBytes(key, value, expVersion);
// }
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) {
BytesValue bytesValue = TypedValue.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) {
BytesValue bytesValue = TypedValue.fromImage(value);
operation.set(key, bytesValue, expVersion);
return this;
}
// @Override
// public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) {
// return setText(key, value, expVersion);
// }
@Override
public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromText(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) {
BytesValue bytesValue = TypedValue.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) {
BytesValue bytesValue = TypedValue.fromInt64(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromJSON(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) {
BytesValue bytesValue = TypedValue.fromXML(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) {
BytesValue bytesValue = TypedValue.fromTimestamp(value);
operation.set(key, bytesValue, expVersion);
return this;
}
}

+ 34
- 34
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOpTemplate.java View File

@@ -1,34 +1,34 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
import com.jd.blockchain.ledger.DigitalSignature;
public class DataAccountRegisterOpTemplate implements DataAccountRegisterOperation {
static {
DataContractRegistry.register(DataAccountKVSetOperation.class);
}
private BlockchainIdentity accountID;
public DataAccountRegisterOpTemplate() {
}
public DataAccountRegisterOpTemplate(BlockchainIdentity accountID) {
this.accountID = accountID;
}
@Override
public BlockchainIdentity getAccountID() {
return accountID;
}
@Override
public DigitalSignature getAddressSignature() {
// TODO Auto-generated method stub
return null;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
import com.jd.blockchain.ledger.DigitalSignature;
public class DataAccountRegisterOpTemplate implements DataAccountRegisterOperation {
static {
DataContractRegistry.register(DataAccountKVSetOperation.class);
}
private BlockchainIdentity accountID;
public DataAccountRegisterOpTemplate() {
}
public DataAccountRegisterOpTemplate(BlockchainIdentity accountID) {
this.accountID = accountID;
}
@Override
public BlockchainIdentity getAccountID() {
return accountID;
}
@Override
public DigitalSignature getAddressSignature() {
// TODO Auto-generated method stub
return null;
}
}

+ 14
- 14
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOperationBuilder.java View File

@@ -1,14 +1,14 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
public interface DataAccountRegisterOperationBuilder {
/**
* @param id
* @return
*/
DataAccountRegisterOperation register(BlockchainIdentity id);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
public interface DataAccountRegisterOperationBuilder {
/**
* @param id
* @return
*/
DataAccountRegisterOperation register(BlockchainIdentity id);
}

+ 15
- 15
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountRegisterOperationBuilderImpl.java View File

@@ -1,15 +1,15 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
public class DataAccountRegisterOperationBuilderImpl implements DataAccountRegisterOperationBuilder{
@Override
public DataAccountRegisterOperation register(BlockchainIdentity userID) {
return new DataAccountRegisterOpTemplate(userID);
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
public class DataAccountRegisterOperationBuilderImpl implements DataAccountRegisterOperationBuilder{
@Override
public DataAccountRegisterOperation register(BlockchainIdentity userID) {
return new DataAccountRegisterOpTemplate(userID);
}
}

+ 116
- 116
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DigitalSignatureBlob.java View File

@@ -1,116 +1,116 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.crypto.SignatureDigest;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MagicNumber;
/**
* 数字签名的字节块;
*
* <pre>
* 字节位如下:
* [第1字节]:标识数据类型为数字签名的魔数常量 ({@link MagicNumber#SIGNATURE});
*
* [第2字节] - [第N字节]: 公钥;
* 注:公钥的值是包含了公钥算法标识和公钥内容的字节码编码;
*
* [第N+1字节] - 结束: 摘要;
*
* </pre>
*
* @author huanghaiquan
*
*/
public class DigitalSignatureBlob implements DigitalSignature {
private PubKey pubKey;
private SignatureDigest digest;
@Override
public PubKey getPubKey() {
return pubKey;
}
@Override
public SignatureDigest getDigest() {
return digest;
}
public DigitalSignatureBlob() {
}
public DigitalSignatureBlob(PubKey pubKey, SignatureDigest digest) {
this.pubKey = pubKey;
this.digest = digest;
}
// @Override
// public void resolvFrom(InputStream in) {
// try {
// byte[] buff = new byte[1];
// int len = in.read(buff);
// if (len < 1) {
// throw new IllegalArgumentException("No enough bytes was read for the magic number [SIGNATURE]!");
// }
// if (buff[0] != MagicNumber.SIGNATURE) {
// throw new IllegalArgumentException("Magic number [SIGNATURE] dismatch!");
// }
// PubKey pk = CryptoKeyEncoding.readPubKey(in);
// ByteArray dg = BytesEncoding.readAsByteArray(NumberMask.SHORT, in);
// this.pubKey = pk;
// this.digest = dg;
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public void writeTo(OutputStream out) {
// try {
// out.write(MagicNumber.SIGNATURE);
// CryptoKeyEncoding.writeKey(pubKey, out);
// BytesEncoding.write(digest, NumberMask.SHORT, out);
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof DigitalSignatureBlob)) return false;
// DigitalSignatureBlob that = (DigitalSignatureBlob) o;
// return Objects.equals(getPubKey(), that.getPubKey()) &&
// Objects.equals(getDigest(), that.getDigest());
// }
//
// public byte[] toBytes() {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// writeTo(out);
// return out.toByteArray();
// }
//
// @Override
// public String toString() {
// return toBytes().toString();
// }
//
// @Override
// public void writeExternal(ObjectOutput out) throws IOException {
// byte[] bts = toBytes();
// out.writeInt(bts.length);
// out.write(bts, 0, bts.length);
// }
//
// @Override
// public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// int size = in.readInt();
// byte[] bs = new byte[size];
// in.readFully(bs, 0, size);
// resolvFrom(new ByteArrayInputStream(bs));
// }
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.crypto.SignatureDigest;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MagicNumber;
/**
* 数字签名的字节块;
*
* <pre>
* 字节位如下:
* [第1字节]:标识数据类型为数字签名的魔数常量 ({@link MagicNumber#SIGNATURE});
*
* [第2字节] - [第N字节]: 公钥;
* 注:公钥的值是包含了公钥算法标识和公钥内容的字节码编码;
*
* [第N+1字节] - 结束: 摘要;
*
* </pre>
*
* @author huanghaiquan
*
*/
public class DigitalSignatureBlob implements DigitalSignature {
private PubKey pubKey;
private SignatureDigest digest;
@Override
public PubKey getPubKey() {
return pubKey;
}
@Override
public SignatureDigest getDigest() {
return digest;
}
public DigitalSignatureBlob() {
}
public DigitalSignatureBlob(PubKey pubKey, SignatureDigest digest) {
this.pubKey = pubKey;
this.digest = digest;
}
// @Override
// public void resolvFrom(InputStream in) {
// try {
// byte[] buff = new byte[1];
// int len = in.read(buff);
// if (len < 1) {
// throw new IllegalArgumentException("No enough bytes was read for the magic number [SIGNATURE]!");
// }
// if (buff[0] != MagicNumber.SIGNATURE) {
// throw new IllegalArgumentException("Magic number [SIGNATURE] dismatch!");
// }
// PubKey pk = CryptoKeyEncoding.readPubKey(in);
// ByteArray dg = BytesEncoding.readAsByteArray(NumberMask.SHORT, in);
// this.pubKey = pk;
// this.digest = dg;
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public void writeTo(OutputStream out) {
// try {
// out.write(MagicNumber.SIGNATURE);
// CryptoKeyEncoding.writeKey(pubKey, out);
// BytesEncoding.write(digest, NumberMask.SHORT, out);
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof DigitalSignatureBlob)) return false;
// DigitalSignatureBlob that = (DigitalSignatureBlob) o;
// return Objects.equals(getPubKey(), that.getPubKey()) &&
// Objects.equals(getDigest(), that.getDigest());
// }
//
// public byte[] toBytes() {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// writeTo(out);
// return out.toByteArray();
// }
//
// @Override
// public String toString() {
// return toBytes().toString();
// }
//
// @Override
// public void writeExternal(ObjectOutput out) throws IOException {
// byte[] bts = toBytes();
// out.writeInt(bts.length);
// out.write(bts, 0, bts.length);
// }
//
// @Override
// public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// int size = in.readInt();
// byte[] bs = new byte[size];
// in.readFully(bs, 0, size);
// resolvFrom(new ByteArrayInputStream(bs));
// }
}

+ 26
- 26
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOpTemplate.java View File

@@ -1,26 +1,26 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public class LedgerInitOpTemplate implements LedgerInitOperation {
static {
DataContractRegistry.register(LedgerInitOperation.class);
}
private LedgerInitSetting initSetting;
public LedgerInitOpTemplate() {
}
public LedgerInitOpTemplate(LedgerInitSetting initSetting) {
this.initSetting = initSetting;
}
@Override
public LedgerInitSetting getInitSetting() {
return initSetting;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public class LedgerInitOpTemplate implements LedgerInitOperation {
static {
DataContractRegistry.register(LedgerInitOperation.class);
}
private LedgerInitSetting initSetting;
public LedgerInitOpTemplate() {
}
public LedgerInitOpTemplate(LedgerInitSetting initSetting) {
this.initSetting = initSetting;
}
@Override
public LedgerInitSetting getInitSetting() {
return initSetting;
}
}

+ 17
- 17
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOperationBuilder.java View File

@@ -1,17 +1,17 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public interface LedgerInitOperationBuilder {
/**
* 注册;
*
* @param initSetting
* 账本初始化配置;
* @return LedgerInitOperation
*/
LedgerInitOperation create(LedgerInitSetting initSetting);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public interface LedgerInitOperationBuilder {
/**
* 注册;
*
* @param initSetting
* 账本初始化配置;
* @return LedgerInitOperation
*/
LedgerInitOperation create(LedgerInitSetting initSetting);
}

+ 13
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LedgerInitOperationBuilderImpl.java View File

@@ -1,13 +1,13 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public class LedgerInitOperationBuilderImpl implements LedgerInitOperationBuilder {
@Override
public LedgerInitOperation create(LedgerInitSetting initSetting) {
return new LedgerInitOpTemplate(initSetting);
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.LedgerInitSetting;
public class LedgerInitOperationBuilderImpl implements LedgerInitOperationBuilder {
@Override
public LedgerInitOperation create(LedgerInitSetting initSetting) {
return new LedgerInitOpTemplate(initSetting);
}
}

+ 38
- 38
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/NewLedgerOpBlob.java View File

@@ -1,38 +1,38 @@
package com.jd.blockchain.transaction;
//package com.jd.blockchain.ledger.data;
//
//import com.jd.blockchain.ledger.OperationType;
//import my.utils.io.ByteArray;
//
//public class NewLedgerOpBlob {
//
// private ByteArray genesisKey;
//
// public NewLedgerOpBlob() {
// }
//
// public NewLedgerOpBlob(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// public void resolvFrom(OpBlob opBlob) {
//// if (OperationType.NEW_LEDGER.CODE != opBlob.getCode()) {
//// throw new IllegalArgumentException(
//// "Could not resolve operation info due to NEW_LEDGER operation code mismatch!");
//// }
////
//// genesisKey = opBlob.getArg(0);
// }
//
// public OpBlob toBlob() {
// // 写入操作码;
// OpBlob opBlob = new OpBlob();
// opBlob.setOperation(OperationType.NEW_LEDGER.CODE, genesisKey);
//
// return opBlob;
// }
//
// public ByteArray getGenesisKey() {
// return genesisKey;
// }
//}
package com.jd.blockchain.transaction;
//package com.jd.blockchain.ledger.data;
//
//import com.jd.blockchain.ledger.OperationType;
//import my.utils.io.ByteArray;
//
//public class NewLedgerOpBlob {
//
// private ByteArray genesisKey;
//
// public NewLedgerOpBlob() {
// }
//
// public NewLedgerOpBlob(ByteArray genesisKey) {
// this.genesisKey = genesisKey;
// }
//
// public void resolvFrom(OpBlob opBlob) {
//// if (OperationType.NEW_LEDGER.CODE != opBlob.getCode()) {
//// throw new IllegalArgumentException(
//// "Could not resolve operation info due to NEW_LEDGER operation code mismatch!");
//// }
////
//// genesisKey = opBlob.getArg(0);
// }
//
// public OpBlob toBlob() {
// // 写入操作码;
// OpBlob opBlob = new OpBlob();
// opBlob.setOperation(OperationType.NEW_LEDGER.CODE, genesisKey);
//
// return opBlob;
// }
//
// public ByteArray getGenesisKey() {
// return genesisKey;
// }
//}

+ 25
- 25
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PrivilegeSettingOperationBuilder.java View File

@@ -1,25 +1,25 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.PermissionType;
/**
* 账户权限设置操作;
*
* <br>
*
* 注:默认情况下,在账户被注册时,账户自身会包含在权限设置表中,具有全部的权限; <br>
*
* 但这不是必须的,使用者可以根据业务需要,去掉账户自身的权限,并将权限赋予其它的账户,以此实现将区块链账户分别用于表示“角色”和“数据”这两种目的;
*
* @author huanghaiquan
*
*/
public interface PrivilegeSettingOperationBuilder {
PrivilegeSettingOperationBuilder setThreshhold(PermissionType privilege, long threshhold);
PrivilegeSettingOperationBuilder enable(PermissionType privilege, String address, int weight);
PrivilegeSettingOperationBuilder disable(PermissionType privilege, String address);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.PermissionType;
/**
* 账户权限设置操作;
*
* <br>
*
* 注:默认情况下,在账户被注册时,账户自身会包含在权限设置表中,具有全部的权限; <br>
*
* 但这不是必须的,使用者可以根据业务需要,去掉账户自身的权限,并将权限赋予其它的账户,以此实现将区块链账户分别用于表示“角色”和“数据”这两种目的;
*
* @author huanghaiquan
*
*/
public interface PrivilegeSettingOperationBuilder {
PrivilegeSettingOperationBuilder setThreshhold(PermissionType privilege, long threshhold);
PrivilegeSettingOperationBuilder enable(PermissionType privilege, String address, int weight);
PrivilegeSettingOperationBuilder disable(PermissionType privilege, String address);
}

+ 30
- 30
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PubKeyData.java View File

@@ -1,30 +1,30 @@
package com.jd.blockchain.transaction;
//package com.jd.blockchain.ledger.data;
//
//import com.jd.blockchain.ledger.KeyType;
//import com.jd.blockchain.ledger.PubKey;
//
//import my.utils.io.ByteArray;
//
//public class PubKeyData implements PubKey{
//
// private KeyType type;
//
// private ByteArray value;
//
// public PubKeyData(KeyType type, ByteArray value) {
// this.type = type;
// this.value = value;
// }
//
// @Override
// public KeyType getType() {
// return type;
// }
//
// @Override
// public ByteArray getValue() {
// return value;
// }
//
//}
package com.jd.blockchain.transaction;
//package com.jd.blockchain.ledger.data;
//
//import com.jd.blockchain.ledger.KeyType;
//import com.jd.blockchain.ledger.PubKey;
//
//import my.utils.io.ByteArray;
//
//public class PubKeyData implements PubKey{
//
// private KeyType type;
//
// private ByteArray value;
//
// public PubKeyData(KeyType type, ByteArray value) {
// this.type = type;
// this.value = value;
// }
//
// @Override
// public KeyType getType() {
// return type;
// }
//
// @Override
// public ByteArray getValue() {
// return value;
// }
//
//}

+ 139
- 139
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/RolesConfigureOpTemplate.java View File

@@ -1,139 +1,139 @@
package com.jd.blockchain.transaction;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.RolesConfigureOperation;
import com.jd.blockchain.ledger.SecurityUtils;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.utils.ArrayUtils;
public class RolesConfigureOpTemplate implements RolesConfigurer, RolesConfigureOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
DataContractRegistry.register(RolesConfigureOperation.class);
DataContractRegistry.register(RolePrivilegeEntry.class);
}
private Map<String, RolePrivilegeConfig> rolesMap = Collections
.synchronizedMap(new LinkedHashMap<String, RolePrivilegeConfig>());
public RolesConfigureOpTemplate() {
}
boolean isEmpty() {
return rolesMap.isEmpty();
}
@Override
public RolePrivilegeEntry[] getRoles() {
return rolesMap.values().toArray(new RolePrivilegeEntry[rolesMap.size()]);
}
@Override
public RolesConfigureOperation getOperation() {
return this;
}
@Override
public RolePrivilegeConfigurer configure(String roleName) {
roleName = SecurityUtils.formatRoleName(roleName);
RolePrivilegeConfig roleConfig = rolesMap.get(roleName);
if (roleConfig == null) {
roleConfig = new RolePrivilegeConfig(roleName);
rolesMap.put(roleName, roleConfig);
}
return roleConfig;
}
private class RolePrivilegeConfig implements RolePrivilegeConfigurer, RolePrivilegeEntry {
private String roleName;
private Set<LedgerPermission> enableLedgerPermissions = new LinkedHashSet<LedgerPermission>();
private Set<LedgerPermission> disableLedgerPermissions = new LinkedHashSet<LedgerPermission>();
private Set<TransactionPermission> enableTxPermissions = new LinkedHashSet<TransactionPermission>();
private Set<TransactionPermission> disableTxPermissions = new LinkedHashSet<TransactionPermission>();
private RolePrivilegeConfig(String roleName) {
this.roleName = roleName;
}
@Override
public String getRoleName() {
return roleName;
}
@Override
public LedgerPermission[] getEnableLedgerPermissions() {
return ArrayUtils.toArray(enableLedgerPermissions, LedgerPermission.class);
}
@Override
public LedgerPermission[] getDisableLedgerPermissions() {
return ArrayUtils.toArray(disableLedgerPermissions, LedgerPermission.class);
}
@Override
public TransactionPermission[] getEnableTransactionPermissions() {
return ArrayUtils.toArray(enableTxPermissions, TransactionPermission.class);
}
@Override
public TransactionPermission[] getDisableTransactionPermissions() {
return ArrayUtils.toArray(disableTxPermissions, TransactionPermission.class);
}
@Override
public RolePrivilegeConfigurer enable(LedgerPermission... permissions) {
List<LedgerPermission> permissionList = ArrayUtils.asList(permissions);
enableLedgerPermissions.addAll(permissionList);
disableLedgerPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer disable(LedgerPermission... permissions) {
List<LedgerPermission> permissionList = ArrayUtils.asList(permissions);
disableLedgerPermissions.addAll(permissionList);
enableLedgerPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer enable(TransactionPermission... permissions) {
List<TransactionPermission> permissionList = ArrayUtils.asList(permissions);
enableTxPermissions.addAll(permissionList);
disableTxPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer disable(TransactionPermission... permissions) {
List<TransactionPermission> permissionList = ArrayUtils.asList(permissions);
disableTxPermissions.addAll(permissionList);
enableTxPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer configure(String roleName) {
return RolesConfigureOpTemplate.this.configure(roleName);
}
}
}
package com.jd.blockchain.transaction;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.RolesConfigureOperation;
import com.jd.blockchain.ledger.SecurityUtils;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.utils.ArrayUtils;
public class RolesConfigureOpTemplate implements RolesConfigurer, RolesConfigureOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
DataContractRegistry.register(RolesConfigureOperation.class);
DataContractRegistry.register(RolePrivilegeEntry.class);
}
private Map<String, RolePrivilegeConfig> rolesMap = Collections
.synchronizedMap(new LinkedHashMap<String, RolePrivilegeConfig>());
public RolesConfigureOpTemplate() {
}
boolean isEmpty() {
return rolesMap.isEmpty();
}
@Override
public RolePrivilegeEntry[] getRoles() {
return rolesMap.values().toArray(new RolePrivilegeEntry[rolesMap.size()]);
}
@Override
public RolesConfigureOperation getOperation() {
return this;
}
@Override
public RolePrivilegeConfigurer configure(String roleName) {
roleName = SecurityUtils.formatRoleName(roleName);
RolePrivilegeConfig roleConfig = rolesMap.get(roleName);
if (roleConfig == null) {
roleConfig = new RolePrivilegeConfig(roleName);
rolesMap.put(roleName, roleConfig);
}
return roleConfig;
}
private class RolePrivilegeConfig implements RolePrivilegeConfigurer, RolePrivilegeEntry {
private String roleName;
private Set<LedgerPermission> enableLedgerPermissions = new LinkedHashSet<LedgerPermission>();
private Set<LedgerPermission> disableLedgerPermissions = new LinkedHashSet<LedgerPermission>();
private Set<TransactionPermission> enableTxPermissions = new LinkedHashSet<TransactionPermission>();
private Set<TransactionPermission> disableTxPermissions = new LinkedHashSet<TransactionPermission>();
private RolePrivilegeConfig(String roleName) {
this.roleName = roleName;
}
@Override
public String getRoleName() {
return roleName;
}
@Override
public LedgerPermission[] getEnableLedgerPermissions() {
return ArrayUtils.toArray(enableLedgerPermissions, LedgerPermission.class);
}
@Override
public LedgerPermission[] getDisableLedgerPermissions() {
return ArrayUtils.toArray(disableLedgerPermissions, LedgerPermission.class);
}
@Override
public TransactionPermission[] getEnableTransactionPermissions() {
return ArrayUtils.toArray(enableTxPermissions, TransactionPermission.class);
}
@Override
public TransactionPermission[] getDisableTransactionPermissions() {
return ArrayUtils.toArray(disableTxPermissions, TransactionPermission.class);
}
@Override
public RolePrivilegeConfigurer enable(LedgerPermission... permissions) {
List<LedgerPermission> permissionList = ArrayUtils.asList(permissions);
enableLedgerPermissions.addAll(permissionList);
disableLedgerPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer disable(LedgerPermission... permissions) {
List<LedgerPermission> permissionList = ArrayUtils.asList(permissions);
disableLedgerPermissions.addAll(permissionList);
enableLedgerPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer enable(TransactionPermission... permissions) {
List<TransactionPermission> permissionList = ArrayUtils.asList(permissions);
enableTxPermissions.addAll(permissionList);
disableTxPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer disable(TransactionPermission... permissions) {
List<TransactionPermission> permissionList = ArrayUtils.asList(permissions);
disableTxPermissions.addAll(permissionList);
enableTxPermissions.removeAll(permissionList);
return this;
}
@Override
public RolePrivilegeConfigurer configure(String roleName) {
return RolesConfigureOpTemplate.this.configure(roleName);
}
}
}

+ 19
- 19
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/SecurityOperationBuilder.java View File

@@ -1,19 +1,19 @@
package com.jd.blockchain.transaction;
public interface SecurityOperationBuilder {
/**
* 配置角色;
*
* @return
*/
RolesConfigurer roles();
/**
* 授权用户;
*
* @return
*/
UserAuthorizer authorziations();
}
package com.jd.blockchain.transaction;
public interface SecurityOperationBuilder {
/**
* 配置角色;
*
* @return
*/
RolesConfigurer roles();
/**
* 授权用户;
*
* @return
*/
UserAuthorizer authorziations();
}

+ 27
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/SignatureEncoding.java View File

@@ -1,27 +1,27 @@
package com.jd.blockchain.transaction;
import org.springframework.util.Base64Utils;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.ledger.DigitalSignature;
public class SignatureEncoding {
public static byte[] encode(DigitalSignature signature) {
return BinaryProtocol.encode(signature, DigitalSignature.class);
}
public static DigitalSignature decode(byte[] bytesSignature) {
return BinaryProtocol.decode(bytesSignature);
}
public static DigitalSignature decodeFromBase64(String base64Signature) {
byte[] bytesSignature = Base64Utils.decodeFromUrlSafeString(base64Signature);
return decode(bytesSignature);
}
public static String encodeToBase64(DigitalSignature signature) {
byte[] bytesSignature = encode(signature);
return Base64Utils.encodeToUrlSafeString(bytesSignature);
}
}
package com.jd.blockchain.transaction;
import org.springframework.util.Base64Utils;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.ledger.DigitalSignature;
public class SignatureEncoding {
public static byte[] encode(DigitalSignature signature) {
return BinaryProtocol.encode(signature, DigitalSignature.class);
}
public static DigitalSignature decode(byte[] bytesSignature) {
return BinaryProtocol.decode(bytesSignature);
}
public static DigitalSignature decodeFromBase64(String base64Signature) {
byte[] bytesSignature = Base64Utils.decodeFromUrlSafeString(base64Signature);
return decode(bytesSignature);
}
public static String encodeToBase64(DigitalSignature signature) {
byte[] bytesSignature = encode(signature);
return Base64Utils.encodeToUrlSafeString(bytesSignature);
}
}

+ 10
- 10
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TransactionService.java View File

@@ -1,10 +1,10 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionResponse;
public interface TransactionService {
TransactionResponse process(TransactionRequest txRequest);
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionResponse;
public interface TransactionService {
TransactionResponse process(TransactionRequest txRequest);
}

+ 106
- 106
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java View File

@@ -1,106 +1,106 @@
package com.jd.blockchain.transaction;
import java.util.ArrayList;
import java.util.List;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.NodeRequest;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
public class TxRequestBuilder implements TransactionRequestBuilder {
private static final String DEFAULT_HASH_ALGORITHM = "SHA256";
private TransactionContent txContent;
private List<DigitalSignature> endpointSignatures = new ArrayList<>();
private List<DigitalSignature> nodeSignatures = new ArrayList<>();
public TxRequestBuilder(TransactionContent txContent) {
this.txContent = txContent;
}
@Override
public HashDigest getHash() {
return txContent.getHash();
}
@Override
public TransactionContent getTransactionContent() {
return txContent;
}
@Override
public DigitalSignature signAsEndpoint(AsymmetricKeypair keyPair) {
DigitalSignature signature = SignatureUtils.sign(txContent, keyPair);
addEndpointSignature(signature);
return signature;
}
@Override
public DigitalSignature signAsNode(AsymmetricKeypair keyPair) {
DigitalSignature signature = SignatureUtils.sign(txContent, keyPair);
addNodeSignature(signature);
return signature;
}
@Override
public void addNodeSignature(DigitalSignature... signatures) {
if (signatures != null) {
for (DigitalSignature s : signatures) {
nodeSignatures.add(s);
}
}
}
@Override
public void addEndpointSignature(DigitalSignature... signatures) {
if (signatures != null) {
for (DigitalSignature s : signatures) {
endpointSignatures.add(s);
}
}
}
// public static DigitalSignature sign(TransactionContent txContent, AsymmetricKeypair keyPair) {
// SignatureDigest signatureDigest = sign(txContent, keyPair.getPrivKey());
// DigitalSignature signature = new DigitalSignatureBlob(keyPair.getPubKey(), signatureDigest);
// return signature;
// }
//
// public static SignatureDigest sign(TransactionContent txContent, PrivKey privKey) {
// return Crypto.getSignatureFunction(privKey.getAlgorithm()).sign(privKey, txContent.getHash().toBytes());
// }
// public static boolean verifySignature(TransactionContent txContent, SignatureDigest signDigest, PubKey pubKey) {
// if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) {
// return false;
// }
// return verifyHashSignature(txContent.getHash(), signDigest, pubKey);
// }
//
// public static boolean verifyHashSignature(HashDigest hash, SignatureDigest signDigest, PubKey pubKey) {
// return Crypto.getSignatureFunction(pubKey.getAlgorithm()).verify(signDigest, pubKey, hash.toBytes());
// }
@Override
public TransactionRequest buildRequest() {
TxRequestMessage txMessage = new TxRequestMessage(txContent);
txMessage.addEndpointSignatures(endpointSignatures);
txMessage.addNodeSignatures(nodeSignatures);
byte[] reqBytes = BinaryProtocol.encode(txMessage, NodeRequest.class);
HashDigest reqHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(reqBytes);
txMessage.setHash(reqHash);
return txMessage;
}
}
package com.jd.blockchain.transaction;
import java.util.ArrayList;
import java.util.List;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.NodeRequest;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
public class TxRequestBuilder implements TransactionRequestBuilder {
private static final String DEFAULT_HASH_ALGORITHM = "SHA256";
private TransactionContent txContent;
private List<DigitalSignature> endpointSignatures = new ArrayList<>();
private List<DigitalSignature> nodeSignatures = new ArrayList<>();
public TxRequestBuilder(TransactionContent txContent) {
this.txContent = txContent;
}
@Override
public HashDigest getHash() {
return txContent.getHash();
}
@Override
public TransactionContent getTransactionContent() {
return txContent;
}
@Override
public DigitalSignature signAsEndpoint(AsymmetricKeypair keyPair) {
DigitalSignature signature = SignatureUtils.sign(txContent, keyPair);
addEndpointSignature(signature);
return signature;
}
@Override
public DigitalSignature signAsNode(AsymmetricKeypair keyPair) {
DigitalSignature signature = SignatureUtils.sign(txContent, keyPair);
addNodeSignature(signature);
return signature;
}
@Override
public void addNodeSignature(DigitalSignature... signatures) {
if (signatures != null) {
for (DigitalSignature s : signatures) {
nodeSignatures.add(s);
}
}
}
@Override
public void addEndpointSignature(DigitalSignature... signatures) {
if (signatures != null) {
for (DigitalSignature s : signatures) {
endpointSignatures.add(s);
}
}
}
// public static DigitalSignature sign(TransactionContent txContent, AsymmetricKeypair keyPair) {
// SignatureDigest signatureDigest = sign(txContent, keyPair.getPrivKey());
// DigitalSignature signature = new DigitalSignatureBlob(keyPair.getPubKey(), signatureDigest);
// return signature;
// }
//
// public static SignatureDigest sign(TransactionContent txContent, PrivKey privKey) {
// return Crypto.getSignatureFunction(privKey.getAlgorithm()).sign(privKey, txContent.getHash().toBytes());
// }
// public static boolean verifySignature(TransactionContent txContent, SignatureDigest signDigest, PubKey pubKey) {
// if (!TxBuilder.verifyTxContentHash(txContent, txContent.getHash())) {
// return false;
// }
// return verifyHashSignature(txContent.getHash(), signDigest, pubKey);
// }
//
// public static boolean verifyHashSignature(HashDigest hash, SignatureDigest signDigest, PubKey pubKey) {
// return Crypto.getSignatureFunction(pubKey.getAlgorithm()).verify(signDigest, pubKey, hash.toBytes());
// }
@Override
public TransactionRequest buildRequest() {
TxRequestMessage txMessage = new TxRequestMessage(txContent);
txMessage.addEndpointSignatures(endpointSignatures);
txMessage.addNodeSignatures(nodeSignatures);
byte[] reqBytes = BinaryProtocol.encode(txMessage, NodeRequest.class);
HashDigest reqHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(reqBytes);
txMessage.setHash(reqHash);
return txMessage;
}
}

+ 385
- 385
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestMessage.java View File

@@ -1,385 +1,385 @@
package com.jd.blockchain.transaction;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MagicNumber;
import com.jd.blockchain.ledger.NodeRequest;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.utils.Bytes;
/**
* TxRequestMessage 交易消息;
* <p>
*
* TxRequestMessage 表示参与者提交的交易请求,由3部分组成:交易内容、参与者签名、网关节点签名;<br>
*
* <pre>
* 字节位如下:
* [第1字节]:标识数据类型为交易请求的魔数常量 ({@link MagicNumber#TX_REQUEST});
*
* [第2字节] - [第N字节]: 交易内容;
*
* [第N+1字节]: 交易参与者数量(有效值范围 0 - 255);
* 注:在单个交易中,参与者的数量总是有限的,对于那些需要更多参与者且数量不确定的场景,可以通过合约来实现把参与者分为多次 TX 提交,最终组合完成一次完整的业务进程;
* [第N+2字节] - [第X字节]: 参与者的签名列表;
*
* [第X+1字节]:对交易请求的哈希算法的代码;
* [第X+2字节] - [第Y字节]:对交易请求的哈希值;针对交易请求中此段之前的全部内容进行哈希计算,包括:交易请求魔数、交易内容、签名者列表、哈希算法代码;
*
* [第Y+1字节] - 结束: 网关节点针对交易请求的签名;
* </pre>
*
* @author huanghaiquan
*
*/
public class TxRequestMessage implements TransactionRequest {// , Externalizable {
/**
* 交易参与者的个数的最大值;
*/
public static final int MAX_TX_PARTICIPANT_COUNT = 0xFF;
private HashDigest hash;
private TransactionContent transactionContent;
private Map<Bytes, DigitalSignature> endpointSignatureMap = new LinkedHashMap<>();
private Map<Bytes, DigitalSignature> nodeSignatureMap = new LinkedHashMap<>();
// private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA_256;
// public TxRequestMessage() {
// }
static {
DataContractRegistry.register(NodeRequest.class);
}
public TxRequestMessage(TransactionContent txContent) {
// if (!(txContent instanceof BytesWriter)) {
// throw new IllegalArgumentException("The tx content must be instance of
// BytesWriter!");
// }
this.transactionContent = txContent;
}
public TxRequestMessage(TransactionRequest txRequest) {
this.transactionContent = txRequest.getTransactionContent();
setHash(txRequest.getHash());
setEndpointSignatures(txRequest.getEndpointSignatures());
setNodeSignatures(txRequest.getNodeSignatures());
}
@Override
public TransactionContent getTransactionContent() {
return this.transactionContent;
}
@Override
public DigitalSignature[] getEndpointSignatures() {
return endpointSignatureMap.values().toArray(new DigitalSignature[endpointSignatureMap.size()]);
}
@Override
public DigitalSignature[] getNodeSignatures() {
return nodeSignatureMap.values().toArray(new DigitalSignature[nodeSignatureMap.size()]);
}
public void setEndpointSignatures(Object[] endpointSignatures) {
if (endpointSignatures != null) {
for (Object object : endpointSignatures) {
DigitalSignature endpointSignature = (DigitalSignature) object;
addEndpointSignatures(endpointSignature);
}
}
return;
}
public void setNodeSignatures(Object[] nodeSignatures) {
if (nodeSignatures != null) {
for (Object object : nodeSignatures) {
DigitalSignature nodeSignature = (DigitalSignature) object;
addNodeSignatures(nodeSignature);
}
}
return;
}
private void doAddEndpointSignature(DigitalSignature signature) {
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
if (endpointSignatureMap.containsKey(address)) {
throw new IllegalArgumentException(
String.format("Participant signature of Address[%s] already exist!", address));
}
endpointSignatureMap.put(address, signature);
}
/**
* 从参与者签名列表中检查是否包含指定的参与者;
*
* @param userBid
* 参与者的身份;
* @return
*/
public boolean containsEndpointSignature(BlockchainIdentity userBid) {
return endpointSignatureMap.containsKey(userBid.getAddress());
}
public boolean containsEndpointSignature(Bytes userAddress) {
return endpointSignatureMap.containsKey(userAddress);
}
public void addEndpointSignatures(DigitalSignature... signature) {
for (DigitalSignature sign : signature) {
doAddEndpointSignature(sign);
}
}
public void addEndpointSignatures(List<DigitalSignature> signature) {
for (DigitalSignature sign : signature) {
doAddEndpointSignature(sign);
}
}
/**
* 从节点签名列表中检查是否包含指定的节点;
*
* @param nodeBid
* 节点的身份;
* @return
*/
public boolean containsNodeSignature(BlockchainIdentity nodeBid) {
return nodeSignatureMap.containsKey(nodeBid.getAddress());
}
public boolean containsNodeSignature(Bytes nodeAddress) {
return nodeSignatureMap.containsKey(nodeAddress);
}
private void doAddNodeSignatures(DigitalSignature signature) {
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
if (nodeSignatureMap.containsKey(address)) {
throw new IllegalArgumentException(String.format("Node signature of Address[%s] already exist!", address));
}
nodeSignatureMap.put(address, signature);
}
public void addNodeSignatures(DigitalSignature... signature) {
for (DigitalSignature sign : signature) {
doAddNodeSignatures(sign);
}
}
public void addNodeSignatures(List<DigitalSignature> signature) {
for (DigitalSignature sign : signature) {
doAddNodeSignatures(sign);
}
}
@Override
public HashDigest getHash() {
return hash;
}
public void setHash(HashDigest hash) {
this.hash = hash;
}
// public HashDigest updateHash() {
// return computeHash(this.defaultHashAlgorithm);
// }
// public HashDigest updateHash(CryptoAlgorithm hashAlgorithm) {
// return computeHash(hashAlgorithm);
// }
//
// private HashDigest computeHash(CryptoAlgorithm hashAlgorithm) {
// byte[] reqBody = getRequestBody();
// this.hash = CryptoUtils.hash(hashAlgorithm).hash(reqBody);
// return this.hash;
// }
// @Override
// public void resolvFrom(InputStream in) throws IOException {
// // 解析校验交易请求魔数;
// byte[] buff = new byte[1];
// int len = in.read(buff, 0, 1);
// if (len < 1) {
// throw new IllegalArgumentException("No bytes was read for the magic number
// [TX_REQUEST]!");
// }
// if (MagicNumber.TX_REQUEST != buff[0]) {
// throw new IllegalArgumentException("Magic number [TX_REQUEST] dismatch!");
// }
//
// // 解析交易内容;
// TxContentBlob txContentBlob = new TxContentBlob();
// txContentBlob.resolvFrom(in);
//
// // 解析参与者签名列表;
// int participantCount = NumberMask.TINY.resolveMaskedNumber(in);
// List<DigitalSignature> partiSignList = new ArrayList<>();
// for (int i = 0; i < participantCount; i++) {
// DigitalSignatureBlob signature = new DigitalSignatureBlob();
// signature.resolvFrom(in);
//
// partiSignList.add(signature);
// }
//
// // 解析节点签名列表;
// int nodeCount = NumberMask.TINY.resolveMaskedNumber(in);
// List<DigitalSignature> nodeSignList = new ArrayList<>();
// for (int i = 0; i < nodeCount; i++) {
// DigitalSignatureBlob nodeSign = new DigitalSignatureBlob();
// nodeSign.resolvFrom(in);
// nodeSignList.add(nodeSign);
// }
//
// // 解析哈希算法标识符;
// HashAlgorithm hashAlgorithm = HashAlgorithm.valueOf((byte) in.read());
//
// // 解析原始的哈希;
// ByteArray hash = HashEncoding.read(in);
//
// this.txContent = txContentBlob;
// addParticipantSignatures(partiSignList);
// addNodeSignatures(nodeSignList);
// this.hash = hash;
//
// // 校验原始哈希;
// byte[] bodyBytes = getRequestBody();
// ByteArray rHash = HashEncoding.computeHash(bodyBytes, hashAlgorithm);
// if (!rHash.equals(hash)) {
// throw new IllegalArgumentException("The hash is not match with request
// content!");
// }
// }
//
// /**
// * 输出交易请求消息;
// *
// * 注:此方法不会自动重新计算hash;如果消息的内容发生改变后,需要调用主动调用 {@link #updateHash()} 方法重新计算 hash;
// */
// @Override
// public void writeTo(OutputStream out) throws IOException {
// if (this.hash == null) {
// updateHash();
// }
//
// buildRequestBody(out);
//
// // 写入 hash 值;
// HashEncoding.write(hash, out);
// }
// /**
// * 生成请求体,包括:交易请求魔数、交易内容、参与者签名者列表、哈希算法代号;
// *
// * @param out
// * @throws IOException
// */
// private void buildRequestBody(OutputStream out) throws IOException {
//
// buildParticipantRequest(out);
//
// // 写入节点签名列表;
// NumberMask.TINY.writeMask(nodeSignatureMap.size(), out);
// for (DigitalSignature nodeSignatureBlob : nodeSignatureMap.values()) {
// nodeSignatureBlob.writeTo(out);
// }
//
// // 写入 hash 算法代号;
// out.write(hashAlgorithm.getAlgorithm());
// }
// /**
// * 生成参与者的请求数据;
// *
// * <br>
// * 参与者的请求数据仅包含“交易请求模数({@link MagicNumber#TX_REQUEST })”
// * “交易内容({@link #getTransactionContent()})”
// * 和“参与者签名列表({@link #getParticipantSignatures()})”三项属性;
// *
// * @param out
// */
// public void buildParticipantRequest(OutputStream out) {
// try {
// // 写入魔数;
// out.write(MagicNumber.TX_REQUEST);
//
// // 写入交易内容;
// txContent.writeTo(out);
//
// // 写入 1 个字节的参与者签名数量;
// if (participantSignatureMap.size() > MAX_TX_PARTICIPANT_COUNT) {
// throw new IllegalArgumentException("The number of participant signatures is
// out of the max count["
// + MAX_TX_PARTICIPANT_COUNT + "]!");
// }
//
// NumberMask.TINY.writeMask(participantSignatureMap.size(), out);
// // 写入参与者签名列表;
// for (DigitalSignature digitalSignatureBlob :
// participantSignatureMap.values()) {
// digitalSignatureBlob.writeTo(out);
// }
//
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public void writeExternal(ObjectOutput out) throws IOException {
// ByteArrayOutputStream os = new ByteArrayOutputStream();
// writeTo(os);
// byte[] bts = os.toByteArray();
// out.writeInt(bts.length);
// out.write(bts);
// }
//
// @Override
// public void readExternal(ObjectInput in) throws IOException,
// ClassNotFoundException {
// int len = in.readInt();
// byte[] bts = new byte[len];
// in.readFully(bts);
// this.resolvFrom(new ByteArrayInputStream(bts));
// }
// @Override
// public byte[] toBytes() {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// try {
// writeTo(out);
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// return out.toByteArray();
// }
// @Override
// public ByteArray getHashData() {
// return ByteArray.wrap(getRequestBody());
// }
// private byte[] getRequestBody() {
// try {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// buildRequestBody(out);
//
// return out.toByteArray();
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
}
package com.jd.blockchain.transaction;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.DigitalSignature;
import com.jd.blockchain.ledger.MagicNumber;
import com.jd.blockchain.ledger.NodeRequest;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.utils.Bytes;
/**
* TxRequestMessage 交易消息;
* <p>
*
* TxRequestMessage 表示参与者提交的交易请求,由3部分组成:交易内容、参与者签名、网关节点签名;<br>
*
* <pre>
* 字节位如下:
* [第1字节]:标识数据类型为交易请求的魔数常量 ({@link MagicNumber#TX_REQUEST});
*
* [第2字节] - [第N字节]: 交易内容;
*
* [第N+1字节]: 交易参与者数量(有效值范围 0 - 255);
* 注:在单个交易中,参与者的数量总是有限的,对于那些需要更多参与者且数量不确定的场景,可以通过合约来实现把参与者分为多次 TX 提交,最终组合完成一次完整的业务进程;
* [第N+2字节] - [第X字节]: 参与者的签名列表;
*
* [第X+1字节]:对交易请求的哈希算法的代码;
* [第X+2字节] - [第Y字节]:对交易请求的哈希值;针对交易请求中此段之前的全部内容进行哈希计算,包括:交易请求魔数、交易内容、签名者列表、哈希算法代码;
*
* [第Y+1字节] - 结束: 网关节点针对交易请求的签名;
* </pre>
*
* @author huanghaiquan
*
*/
public class TxRequestMessage implements TransactionRequest {// , Externalizable {
/**
* 交易参与者的个数的最大值;
*/
public static final int MAX_TX_PARTICIPANT_COUNT = 0xFF;
private HashDigest hash;
private TransactionContent transactionContent;
private Map<Bytes, DigitalSignature> endpointSignatureMap = new LinkedHashMap<>();
private Map<Bytes, DigitalSignature> nodeSignatureMap = new LinkedHashMap<>();
// private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA_256;
// public TxRequestMessage() {
// }
static {
DataContractRegistry.register(NodeRequest.class);
}
public TxRequestMessage(TransactionContent txContent) {
// if (!(txContent instanceof BytesWriter)) {
// throw new IllegalArgumentException("The tx content must be instance of
// BytesWriter!");
// }
this.transactionContent = txContent;
}
public TxRequestMessage(TransactionRequest txRequest) {
this.transactionContent = txRequest.getTransactionContent();
setHash(txRequest.getHash());
setEndpointSignatures(txRequest.getEndpointSignatures());
setNodeSignatures(txRequest.getNodeSignatures());
}
@Override
public TransactionContent getTransactionContent() {
return this.transactionContent;
}
@Override
public DigitalSignature[] getEndpointSignatures() {
return endpointSignatureMap.values().toArray(new DigitalSignature[endpointSignatureMap.size()]);
}
@Override
public DigitalSignature[] getNodeSignatures() {
return nodeSignatureMap.values().toArray(new DigitalSignature[nodeSignatureMap.size()]);
}
public void setEndpointSignatures(Object[] endpointSignatures) {
if (endpointSignatures != null) {
for (Object object : endpointSignatures) {
DigitalSignature endpointSignature = (DigitalSignature) object;
addEndpointSignatures(endpointSignature);
}
}
return;
}
public void setNodeSignatures(Object[] nodeSignatures) {
if (nodeSignatures != null) {
for (Object object : nodeSignatures) {
DigitalSignature nodeSignature = (DigitalSignature) object;
addNodeSignatures(nodeSignature);
}
}
return;
}
private void doAddEndpointSignature(DigitalSignature signature) {
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
if (endpointSignatureMap.containsKey(address)) {
throw new IllegalArgumentException(
String.format("Participant signature of Address[%s] already exist!", address));
}
endpointSignatureMap.put(address, signature);
}
/**
* 从参与者签名列表中检查是否包含指定的参与者;
*
* @param userBid
* 参与者的身份;
* @return
*/
public boolean containsEndpointSignature(BlockchainIdentity userBid) {
return endpointSignatureMap.containsKey(userBid.getAddress());
}
public boolean containsEndpointSignature(Bytes userAddress) {
return endpointSignatureMap.containsKey(userAddress);
}
public void addEndpointSignatures(DigitalSignature... signature) {
for (DigitalSignature sign : signature) {
doAddEndpointSignature(sign);
}
}
public void addEndpointSignatures(List<DigitalSignature> signature) {
for (DigitalSignature sign : signature) {
doAddEndpointSignature(sign);
}
}
/**
* 从节点签名列表中检查是否包含指定的节点;
*
* @param nodeBid
* 节点的身份;
* @return
*/
public boolean containsNodeSignature(BlockchainIdentity nodeBid) {
return nodeSignatureMap.containsKey(nodeBid.getAddress());
}
public boolean containsNodeSignature(Bytes nodeAddress) {
return nodeSignatureMap.containsKey(nodeAddress);
}
private void doAddNodeSignatures(DigitalSignature signature) {
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
if (nodeSignatureMap.containsKey(address)) {
throw new IllegalArgumentException(String.format("Node signature of Address[%s] already exist!", address));
}
nodeSignatureMap.put(address, signature);
}
public void addNodeSignatures(DigitalSignature... signature) {
for (DigitalSignature sign : signature) {
doAddNodeSignatures(sign);
}
}
public void addNodeSignatures(List<DigitalSignature> signature) {
for (DigitalSignature sign : signature) {
doAddNodeSignatures(sign);
}
}
@Override
public HashDigest getHash() {
return hash;
}
public void setHash(HashDigest hash) {
this.hash = hash;
}
// public HashDigest updateHash() {
// return computeHash(this.defaultHashAlgorithm);
// }
// public HashDigest updateHash(CryptoAlgorithm hashAlgorithm) {
// return computeHash(hashAlgorithm);
// }
//
// private HashDigest computeHash(CryptoAlgorithm hashAlgorithm) {
// byte[] reqBody = getRequestBody();
// this.hash = CryptoUtils.hash(hashAlgorithm).hash(reqBody);
// return this.hash;
// }
// @Override
// public void resolvFrom(InputStream in) throws IOException {
// // 解析校验交易请求魔数;
// byte[] buff = new byte[1];
// int len = in.read(buff, 0, 1);
// if (len < 1) {
// throw new IllegalArgumentException("No bytes was read for the magic number
// [TX_REQUEST]!");
// }
// if (MagicNumber.TX_REQUEST != buff[0]) {
// throw new IllegalArgumentException("Magic number [TX_REQUEST] dismatch!");
// }
//
// // 解析交易内容;
// TxContentBlob txContentBlob = new TxContentBlob();
// txContentBlob.resolvFrom(in);
//
// // 解析参与者签名列表;
// int participantCount = NumberMask.TINY.resolveMaskedNumber(in);
// List<DigitalSignature> partiSignList = new ArrayList<>();
// for (int i = 0; i < participantCount; i++) {
// DigitalSignatureBlob signature = new DigitalSignatureBlob();
// signature.resolvFrom(in);
//
// partiSignList.add(signature);
// }
//
// // 解析节点签名列表;
// int nodeCount = NumberMask.TINY.resolveMaskedNumber(in);
// List<DigitalSignature> nodeSignList = new ArrayList<>();
// for (int i = 0; i < nodeCount; i++) {
// DigitalSignatureBlob nodeSign = new DigitalSignatureBlob();
// nodeSign.resolvFrom(in);
// nodeSignList.add(nodeSign);
// }
//
// // 解析哈希算法标识符;
// HashAlgorithm hashAlgorithm = HashAlgorithm.valueOf((byte) in.read());
//
// // 解析原始的哈希;
// ByteArray hash = HashEncoding.read(in);
//
// this.txContent = txContentBlob;
// addParticipantSignatures(partiSignList);
// addNodeSignatures(nodeSignList);
// this.hash = hash;
//
// // 校验原始哈希;
// byte[] bodyBytes = getRequestBody();
// ByteArray rHash = HashEncoding.computeHash(bodyBytes, hashAlgorithm);
// if (!rHash.equals(hash)) {
// throw new IllegalArgumentException("The hash is not match with request
// content!");
// }
// }
//
// /**
// * 输出交易请求消息;
// *
// * 注:此方法不会自动重新计算hash;如果消息的内容发生改变后,需要调用主动调用 {@link #updateHash()} 方法重新计算 hash;
// */
// @Override
// public void writeTo(OutputStream out) throws IOException {
// if (this.hash == null) {
// updateHash();
// }
//
// buildRequestBody(out);
//
// // 写入 hash 值;
// HashEncoding.write(hash, out);
// }
// /**
// * 生成请求体,包括:交易请求魔数、交易内容、参与者签名者列表、哈希算法代号;
// *
// * @param out
// * @throws IOException
// */
// private void buildRequestBody(OutputStream out) throws IOException {
//
// buildParticipantRequest(out);
//
// // 写入节点签名列表;
// NumberMask.TINY.writeMask(nodeSignatureMap.size(), out);
// for (DigitalSignature nodeSignatureBlob : nodeSignatureMap.values()) {
// nodeSignatureBlob.writeTo(out);
// }
//
// // 写入 hash 算法代号;
// out.write(hashAlgorithm.getAlgorithm());
// }
// /**
// * 生成参与者的请求数据;
// *
// * <br>
// * 参与者的请求数据仅包含“交易请求模数({@link MagicNumber#TX_REQUEST })”
// * “交易内容({@link #getTransactionContent()})”
// * 和“参与者签名列表({@link #getParticipantSignatures()})”三项属性;
// *
// * @param out
// */
// public void buildParticipantRequest(OutputStream out) {
// try {
// // 写入魔数;
// out.write(MagicNumber.TX_REQUEST);
//
// // 写入交易内容;
// txContent.writeTo(out);
//
// // 写入 1 个字节的参与者签名数量;
// if (participantSignatureMap.size() > MAX_TX_PARTICIPANT_COUNT) {
// throw new IllegalArgumentException("The number of participant signatures is
// out of the max count["
// + MAX_TX_PARTICIPANT_COUNT + "]!");
// }
//
// NumberMask.TINY.writeMask(participantSignatureMap.size(), out);
// // 写入参与者签名列表;
// for (DigitalSignature digitalSignatureBlob :
// participantSignatureMap.values()) {
// digitalSignatureBlob.writeTo(out);
// }
//
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
//
// @Override
// public void writeExternal(ObjectOutput out) throws IOException {
// ByteArrayOutputStream os = new ByteArrayOutputStream();
// writeTo(os);
// byte[] bts = os.toByteArray();
// out.writeInt(bts.length);
// out.write(bts);
// }
//
// @Override
// public void readExternal(ObjectInput in) throws IOException,
// ClassNotFoundException {
// int len = in.readInt();
// byte[] bts = new byte[len];
// in.readFully(bts);
// this.resolvFrom(new ByteArrayInputStream(bts));
// }
// @Override
// public byte[] toBytes() {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// try {
// writeTo(out);
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// return out.toByteArray();
// }
// @Override
// public ByteArray getHashData() {
// return ByteArray.wrap(getRequestBody());
// }
// private byte[] getRequestBody() {
// try {
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// buildRequestBody(out);
//
// return out.toByteArray();
// } catch (IOException e) {
// throw new RuntimeIOException(e.getMessage(), e);
// }
// }
}

+ 86
- 86
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java View File

@@ -1,86 +1,86 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.OperationResult;
import com.jd.blockchain.ledger.TransactionResponse;
/**
* @author huanghaiquan
*
*/
public class TxResponseMessage implements TransactionResponse {
private HashDigest contentHash;
private HashDigest blockHash;
private long blockHeight;
private TransactionState executionState;
private OperationResult[] operationResults;
public TxResponseMessage() {
}
// 重新包装operationResults
public TxResponseMessage(TransactionResponse transactionResponse, OperationResult[] operationResults) {
this.contentHash = transactionResponse.getContentHash();
this.blockHash = transactionResponse.getBlockHash();
this.blockHeight = transactionResponse.getBlockHeight();
this.executionState = transactionResponse.getExecutionState();
this.operationResults = operationResults;
}
public TxResponseMessage(HashDigest contentHash) {
this.contentHash = contentHash;
}
@Override
public HashDigest getContentHash() {
return contentHash;
}
@Override
public TransactionState getExecutionState() {
return executionState;
}
public void setExecutionState(TransactionState executionState) {
this.executionState = executionState;
}
@Override
public HashDigest getBlockHash() {
return blockHash;
}
public void setBlockHash(HashDigest blockHash) {
this.blockHash = blockHash;
}
@Override
public long getBlockHeight() {
return blockHeight;
}
public void setBlockHeight(long blockHeight) {
this.blockHeight = blockHeight;
}
public void setOperationResults(OperationResult[] operationResults) {
this.operationResults = operationResults;
}
@Override
public boolean isSuccess() {
return blockHash != null & executionState == TransactionState.SUCCESS;
}
@Override
public OperationResult[] getOperationResults() {
return operationResults;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.OperationResult;
import com.jd.blockchain.ledger.TransactionResponse;
/**
* @author huanghaiquan
*
*/
public class TxResponseMessage implements TransactionResponse {
private HashDigest contentHash;
private HashDigest blockHash;
private long blockHeight;
private TransactionState executionState;
private OperationResult[] operationResults;
public TxResponseMessage() {
}
// 重新包装operationResults
public TxResponseMessage(TransactionResponse transactionResponse, OperationResult[] operationResults) {
this.contentHash = transactionResponse.getContentHash();
this.blockHash = transactionResponse.getBlockHash();
this.blockHeight = transactionResponse.getBlockHeight();
this.executionState = transactionResponse.getExecutionState();
this.operationResults = operationResults;
}
public TxResponseMessage(HashDigest contentHash) {
this.contentHash = contentHash;
}
@Override
public HashDigest getContentHash() {
return contentHash;
}
@Override
public TransactionState getExecutionState() {
return executionState;
}
public void setExecutionState(TransactionState executionState) {
this.executionState = executionState;
}
@Override
public HashDigest getBlockHash() {
return blockHash;
}
public void setBlockHash(HashDigest blockHash) {
this.blockHash = blockHash;
}
@Override
public long getBlockHeight() {
return blockHeight;
}
public void setBlockHeight(long blockHeight) {
this.blockHeight = blockHeight;
}
public void setOperationResults(OperationResult[] operationResults) {
this.operationResults = operationResults;
}
@Override
public boolean isSuccess() {
return blockHash != null & executionState == TransactionState.SUCCESS;
}
@Override
public OperationResult[] getOperationResults() {
return operationResults;
}
}

+ 111
- 111
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java View File

@@ -1,111 +1,111 @@
package com.jd.blockchain.transaction;
import java.io.IOException;
import java.util.Collection;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.utils.Bytes;
public class TxTemplate implements TransactionTemplate {
private TxBuilder txBuilder;
private TransactionService txService;
private TxStateManager stateManager;
public TxTemplate(HashDigest ledgerHash, TransactionService txService) {
this.stateManager = new TxStateManager();
this.txBuilder = new TxBuilder(ledgerHash);
this.txService = txService;
}
@Override
public HashDigest getLedgerHash() {
return txBuilder.getLedgerHash();
}
@Override
public PreparedTransaction prepare() {
stateManager.prepare();
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
return new PreparedTx(stateManager, txReqBuilder, txService, txBuilder.getReturnValuehandlers());
}
@Override
public SecurityOperationBuilder security() {
stateManager.operate();
return txBuilder.security();
}
@Override
public UserRegisterOperationBuilder users() {
stateManager.operate();
return txBuilder.users();
}
@Override
public DataAccountRegisterOperationBuilder dataAccounts() {
stateManager.operate();
return txBuilder.dataAccounts();
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) {
stateManager.operate();
return txBuilder.dataAccount(accountAddress);
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) {
stateManager.operate();
return txBuilder.dataAccount(accountAddress);
}
@Override
public ContractCodeDeployOperationBuilder contracts() {
stateManager.operate();
return txBuilder.contracts();
}
@Override
public ParticipantRegisterOperationBuilder participants() {
stateManager.operate();
return txBuilder.participants();
}
@Override
public ParticipantStateUpdateOperationBuilder states() {
stateManager.operate();
return txBuilder.states();
}
@Override
public <T> T contract(Bytes address, Class<T> contractIntf) {
stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
@Override
public <T> T contract(String address, Class<T> contractIntf) {
stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
@Override
public void close() throws IOException {
if (!stateManager.close()) {
Collection<OperationResultHandle> handlers = txBuilder.getReturnValuehandlers();
if (handlers.size() > 0) {
TransactionCancelledExeption error = new TransactionCancelledExeption(
"Transaction template has been cancelled!");
for (OperationResultHandle handle : handlers) {
handle.complete(error);
}
}
}
}
}
package com.jd.blockchain.transaction;
import java.io.IOException;
import java.util.Collection;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.utils.Bytes;
public class TxTemplate implements TransactionTemplate {
private TxBuilder txBuilder;
private TransactionService txService;
private TxStateManager stateManager;
public TxTemplate(HashDigest ledgerHash, TransactionService txService) {
this.stateManager = new TxStateManager();
this.txBuilder = new TxBuilder(ledgerHash);
this.txService = txService;
}
@Override
public HashDigest getLedgerHash() {
return txBuilder.getLedgerHash();
}
@Override
public PreparedTransaction prepare() {
stateManager.prepare();
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
return new PreparedTx(stateManager, txReqBuilder, txService, txBuilder.getReturnValuehandlers());
}
@Override
public SecurityOperationBuilder security() {
stateManager.operate();
return txBuilder.security();
}
@Override
public UserRegisterOperationBuilder users() {
stateManager.operate();
return txBuilder.users();
}
@Override
public DataAccountRegisterOperationBuilder dataAccounts() {
stateManager.operate();
return txBuilder.dataAccounts();
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) {
stateManager.operate();
return txBuilder.dataAccount(accountAddress);
}
@Override
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) {
stateManager.operate();
return txBuilder.dataAccount(accountAddress);
}
@Override
public ContractCodeDeployOperationBuilder contracts() {
stateManager.operate();
return txBuilder.contracts();
}
@Override
public ParticipantRegisterOperationBuilder participants() {
stateManager.operate();
return txBuilder.participants();
}
@Override
public ParticipantStateUpdateOperationBuilder states() {
stateManager.operate();
return txBuilder.states();
}
@Override
public <T> T contract(Bytes address, Class<T> contractIntf) {
stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
@Override
public <T> T contract(String address, Class<T> contractIntf) {
stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
@Override
public void close() throws IOException {
if (!stateManager.close()) {
Collection<OperationResultHandle> handlers = txBuilder.getReturnValuehandlers();
if (handlers.size() > 0) {
TransactionCancelledExeption error = new TransactionCancelledExeption(
"Transaction template has been cancelled!");
for (OperationResultHandle handle : handlers) {
handle.complete(error);
}
}
}
}
}

+ 130
- 130
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserAuthorizeOpTemplate.java View File

@@ -1,130 +1,130 @@
package com.jd.blockchain.transaction;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.RolesPolicy;
import com.jd.blockchain.ledger.SecurityUtils;
import com.jd.blockchain.ledger.UserAuthorizeOperation;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.utils.ArrayUtils;
import com.jd.blockchain.utils.Bytes;
public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
DataContractRegistry.register(UserAuthorizeOperation.class);
DataContractRegistry.register(UserRolesEntry.class);
}
private Set<AuthorizationDataEntry> userAuthMap = Collections
.synchronizedSet(new LinkedHashSet<AuthorizationDataEntry>());
public UserAuthorizeOpTemplate() {
}
public UserAuthorizeOpTemplate(BlockchainIdentity userID) {
}
@Override
public AuthorizationDataEntry[] getUserRolesAuthorizations() {
return ArrayUtils.toArray(userAuthMap, AuthorizationDataEntry.class);
}
@Override
public UserAuthorizeOperation getOperation() {
return this;
}
@Override
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
AuthorizationDataEntry userRolesAuth = new AuthorizationDataEntry(userAddresses);
userAuthMap.add(userRolesAuth);
return userRolesAuth;
}
@Override
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
Bytes[] addresses = Arrays.stream(userIds).map(p -> p.getAddress()).toArray(Bytes[]::new);
return forUser(addresses);
}
private class AuthorizationDataEntry implements UserRolesAuthorizer, UserRolesEntry {
private Bytes[] userAddress;
private RolesPolicy policy = RolesPolicy.UNION;
private Set<String> authRoles = new LinkedHashSet<String>();
private Set<String> unauthRoles = new LinkedHashSet<String>();
private AuthorizationDataEntry(Bytes[] userAddress) {
this.userAddress = userAddress;
}
@Override
public Bytes[] getUserAddresses() {
return userAddress;
}
@Override
public RolesPolicy getPolicy() {
return policy;
}
@Override
public String[] getAuthorizedRoles() {
return ArrayUtils.toArray(authRoles, String.class);
}
@Override
public String[] getUnauthorizedRoles() {
return ArrayUtils.toArray(unauthRoles, String.class);
}
@Override
public UserRolesAuthorizer setPolicy(RolesPolicy policy) {
this.policy = policy;
return this;
}
@Override
public UserRolesAuthorizer authorize(String... roles) {
String roleName;
for (String r : roles) {
roleName = SecurityUtils.formatRoleName(r);
authRoles.add(roleName);
unauthRoles.remove(roleName);
}
return this;
}
@Override
public UserRolesAuthorizer unauthorize(String... roles) {
String roleName;
for (String r : roles) {
roleName = SecurityUtils.formatRoleName(r);
unauthRoles.add(roleName);
authRoles.remove(roleName);
}
return this;
}
@Override
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
return UserAuthorizeOpTemplate.this.forUser(userIds);
}
@Override
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
return UserAuthorizeOpTemplate.this.forUser(userAddresses);
}
}
}
package com.jd.blockchain.transaction;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.RolesPolicy;
import com.jd.blockchain.ledger.SecurityUtils;
import com.jd.blockchain.ledger.UserAuthorizeOperation;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.utils.ArrayUtils;
import com.jd.blockchain.utils.Bytes;
public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
DataContractRegistry.register(UserAuthorizeOperation.class);
DataContractRegistry.register(UserRolesEntry.class);
}
private Set<AuthorizationDataEntry> userAuthMap = Collections
.synchronizedSet(new LinkedHashSet<AuthorizationDataEntry>());
public UserAuthorizeOpTemplate() {
}
public UserAuthorizeOpTemplate(BlockchainIdentity userID) {
}
@Override
public AuthorizationDataEntry[] getUserRolesAuthorizations() {
return ArrayUtils.toArray(userAuthMap, AuthorizationDataEntry.class);
}
@Override
public UserAuthorizeOperation getOperation() {
return this;
}
@Override
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
AuthorizationDataEntry userRolesAuth = new AuthorizationDataEntry(userAddresses);
userAuthMap.add(userRolesAuth);
return userRolesAuth;
}
@Override
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
Bytes[] addresses = Arrays.stream(userIds).map(p -> p.getAddress()).toArray(Bytes[]::new);
return forUser(addresses);
}
private class AuthorizationDataEntry implements UserRolesAuthorizer, UserRolesEntry {
private Bytes[] userAddress;
private RolesPolicy policy = RolesPolicy.UNION;
private Set<String> authRoles = new LinkedHashSet<String>();
private Set<String> unauthRoles = new LinkedHashSet<String>();
private AuthorizationDataEntry(Bytes[] userAddress) {
this.userAddress = userAddress;
}
@Override
public Bytes[] getUserAddresses() {
return userAddress;
}
@Override
public RolesPolicy getPolicy() {
return policy;
}
@Override
public String[] getAuthorizedRoles() {
return ArrayUtils.toArray(authRoles, String.class);
}
@Override
public String[] getUnauthorizedRoles() {
return ArrayUtils.toArray(unauthRoles, String.class);
}
@Override
public UserRolesAuthorizer setPolicy(RolesPolicy policy) {
this.policy = policy;
return this;
}
@Override
public UserRolesAuthorizer authorize(String... roles) {
String roleName;
for (String r : roles) {
roleName = SecurityUtils.formatRoleName(r);
authRoles.add(roleName);
unauthRoles.remove(roleName);
}
return this;
}
@Override
public UserRolesAuthorizer unauthorize(String... roles) {
String roleName;
for (String r : roles) {
roleName = SecurityUtils.formatRoleName(r);
unauthRoles.add(roleName);
authRoles.remove(roleName);
}
return this;
}
@Override
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) {
return UserAuthorizeOpTemplate.this.forUser(userIds);
}
@Override
public UserRolesAuthorizer forUser(Bytes... userAddresses) {
return UserAuthorizeOpTemplate.this.forUser(userAddresses);
}
}
}

+ 27
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/UserRegisterOpTemplate.java View File

@@ -1,27 +1,27 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.UserRegisterOperation;
public class UserRegisterOpTemplate implements UserRegisterOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
}
private BlockchainIdentity userID;
public UserRegisterOpTemplate() {
}
public UserRegisterOpTemplate(BlockchainIdentity userID) {
this.userID = userID;
}
@Override
public BlockchainIdentity getUserID() {
return userID;
}
}
package com.jd.blockchain.transaction;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.UserRegisterOperation;
public class UserRegisterOpTemplate implements UserRegisterOperation {
static {
DataContractRegistry.register(UserRegisterOperation.class);
}
private BlockchainIdentity userID;
public UserRegisterOpTemplate() {
}
public UserRegisterOpTemplate(BlockchainIdentity userID) {
this.userID = userID;
}
@Override
public BlockchainIdentity getUserID() {
return userID;
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save