diff --git a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java
index e8ebb6a3..dd6276ba 100644
--- a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java
+++ b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java
@@ -96,7 +96,7 @@ public abstract class AbstractContractCode implements ContractCode {
eventContext.getEvent(), address.toString(), error.getMessage()), error);
}
- BytesValue retnBytes = BytesValueEncoding.encode(retn, handleMethod.getReturnType());
+ BytesValue retnBytes = BytesValueEncoding.encodeSingle(retn, handleMethod.getReturnType());
return retnBytes;
}
diff --git a/source/ledger/ledger-model/pom.xml b/source/ledger/ledger-model/pom.xml
index d9df06a7..f15cafbe 100644
--- a/source/ledger/ledger-model/pom.xml
+++ b/source/ledger/ledger-model/pom.xml
@@ -39,7 +39,6 @@
${project.version}
test
-
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java
index f21918fb..c7e4738d 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java
@@ -1,24 +1,131 @@
package com.jd.blockchain.ledger;
+import com.jd.blockchain.binaryproto.BinaryProtocol;
+import com.jd.blockchain.binaryproto.DataContract;
+import com.jd.blockchain.ledger.resolver.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
public class BytesValueEncoding {
-
-
-
-
- public static BytesValue encode(Object value, Class> type) {
- throw new IllegalStateException("Not implemented!");
+
+ private static final Map, BytesValueResolver> CLASS_RESOLVER_MAP = new ConcurrentHashMap<>();
+
+ private static final Map DATA_TYPE_RESOLVER_MAP = new ConcurrentHashMap<>();
+
+ static {
+ init();
}
-
- public static BytesValueList encode(Object[] values, Class>[] types) {
- throw new IllegalStateException("Not implemented!");
+
+ private static void init() {
+ BytesValueResolver[] resolvers = new BytesValueResolver[]{
+ new BytesToBytesValueResolver(),
+ new IntegerToBytesValueResolver(),
+ new LongToBytesValueResolver(),
+ new ShortToBytesValueResolver(),
+ new StringToBytesValueResolver()
+ };
+
+ for (BytesValueResolver currResolver : resolvers) {
+ // 填充classMAP
+ Class>[] supportClasses = currResolver.supportClasses();
+ if (supportClasses != null && supportClasses.length > 0) {
+ for (Class> clazz : supportClasses) {
+ CLASS_RESOLVER_MAP.put(clazz, currResolver);
+ }
+ }
+
+ // 填充dataTypeMap
+ DataType[] supportDataTypes = currResolver.supportDataTypes();
+ if (supportDataTypes != null && supportDataTypes.length > 0) {
+ for (DataType dataType : supportDataTypes) {
+ DATA_TYPE_RESOLVER_MAP.put(dataType, currResolver);
+ }
+ }
+ }
+ }
+
+
+ public static BytesValue encodeSingle(Object value, Class> type) {
+ if (type == null) {
+ type = value.getClass();
+ }
+ if (type.isInterface()) {
+ // 判断是否含有DataContract注解
+ if (!type.isAnnotationPresent(DataContract.class)) {
+ throw new IllegalStateException(String.format("Interface[%s] can not be serialize !!!", type.getName()));
+ }
+ // 将对象序列化
+ byte[] serialBytes = BinaryProtocol.encode(value, type);
+ return BytesData.fromType(DataType.DATA_CONTRACT, serialBytes);
+ }
+ BytesValueResolver bytesValueResolver = CLASS_RESOLVER_MAP.get(type);
+ if (bytesValueResolver == null) {
+ throw new IllegalStateException(String.format("Class[%s] can not find encoder !!!", type.getName()));
+ }
+ return bytesValueResolver.encode(value, type);
}
+ public static BytesValueList encodeArray(Object[] values, Class>[] types) {
+ if (values == null || values.length == 0) {
+ return null;
+ }
+ if (types != null && types.length != values.length) {
+ throw new IllegalStateException("Types can be null, or types's length must be equal BytesValue[]'s !!!");
+ }
+
+ BytesValueListData bytesValueListData = new BytesValueListData();
+ for (int i = 0; i < values.length; i++) {
+ BytesValue bytesValue = encodeSingle(values[i], types == null ? null : types[i]);
+ bytesValueListData.add(bytesValue);
+ }
+ return bytesValueListData;
+ }
+
+ public static Object decode(BytesValue value) {
+ return decode(value, null);
+ }
+
public static Object decode(BytesValue value, Class> type) {
- throw new IllegalStateException("Not implemented!");
+ DataType dataType = value.getType();
+ BytesValueResolver valueResolver = DATA_TYPE_RESOLVER_MAP.get(dataType);
+ if (valueResolver == null) {
+ throw new IllegalStateException(String.format("DataType[%s] can not find encoder !!!", dataType.name()));
+ }
+ return type == null ? valueResolver.decode(value) : valueResolver.decode(value, type);
}
public static Object[] decode(BytesValueList values, Class>[] types) {
- throw new IllegalStateException("Not implemented!");
+ BytesValue[] bytesValues = values.getValues();
+ if (bytesValues == null || bytesValues.length == 0) {
+ return null;
+ }
+ // 允许types为null,此时每个BytesValue按照当前的对象来处理
+ // 若types不为null,则types's长度必须和bytesValues一致
+ if (types != null && types.length != bytesValues.length) {
+ throw new IllegalStateException("Types can be null, or types's length must be equal BytesValue[]'s !!!");
+ }
+ Object[] resolveObjs = new Object[bytesValues.length];
+ if (types == null) {
+ // 按照默认方式解析
+ for (int i = 0; i < bytesValues.length; i++) {
+ BytesValue bytesValue = bytesValues[i];
+ DataType dataType = bytesValue.getType();
+ BytesValueResolver valueResolver = DATA_TYPE_RESOLVER_MAP.get(dataType);
+ if (valueResolver == null) {
+ throw new IllegalStateException(String.format("DataType[%s] can not find encoder !!!", dataType.name()));
+ }
+ resolveObjs[i] = valueResolver.decode(bytesValue);
+ }
+ return resolveObjs;
+ }
+ // 按照输入的Class进行解析
+ for (int i = 0; i < bytesValues.length; i++) {
+ resolveObjs[i] = decode(bytesValues[i], types[i]);
+ }
+ return resolveObjs;
}
public static Object getDefaultValue(Class> type) {
@@ -54,7 +161,29 @@ public class BytesValueEncoding {
}
public static boolean supportType(Class> currParamType) {
- // TODO Auto-generated method stub
- return false;
+ if (currParamType.isInterface()) {
+ // 接口序列化必须实现DataContract注解
+ if (!currParamType.isAnnotationPresent(DataContract.class)) {
+ throw new IllegalStateException(String.format("Interface[%s] can not be serialize !!!", currParamType.getName()));
+ }
+ return true;
+ }
+ return CLASS_RESOLVER_MAP.containsKey(currParamType);
+ }
+
+
+ public static class BytesValueListData implements BytesValueList {
+
+ private List bytesValues = new ArrayList<>();
+
+ public void add(BytesValue bytesValue) {
+ bytesValues.add(bytesValue);
+ }
+
+ @Override
+ public BytesValue[] getValues() {
+ BytesValue[] bytesValueArray = new BytesValue[bytesValues.size()];
+ return bytesValues.toArray(bytesValueArray);
+ }
}
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java
new file mode 100644
index 00000000..995d5522
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/AbstractBytesValueResolver.java
@@ -0,0 +1,54 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+
+public abstract class AbstractBytesValueResolver implements BytesValueResolver {
+
+ protected boolean isSupport(Class> type) {
+ if (type == null) {
+ return false;
+ }
+ Class>[] supports = supportClasses();
+ if (supports != null && supports.length > 0) {
+ for (Class> clazz : supports) {
+ if (type.equals(clazz)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected boolean isSupport(DataType dataType) {
+ if (dataType == null) {
+ return false;
+ }
+ DataType[] supports = supportDataTypes();
+ if (supports != null && supports.length > 0) {
+ for (DataType dt : supports) {
+ if (dataType.equals(dt)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public BytesValue encode(Object value) {
+ return encode(value, value.getClass());
+ }
+
+ @Override
+ public Object decode(BytesValue value) {
+ DataType dataType = value.getType();
+ if (!isSupport(dataType)) {
+ throw new IllegalStateException(String.format("Un-support encode DataType[%s] Object !!!", dataType.name()));
+ }
+ return decode(value.getValue());
+ }
+
+ protected abstract Object decode(Bytes value);
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java
new file mode 100644
index 00000000..f4871515
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesToBytesValueResolver.java
@@ -0,0 +1,58 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+
+import java.util.Set;
+
+public class BytesToBytesValueResolver extends AbstractBytesValueResolver {
+
+ private final Class>[] supportClasses = {Bytes.class, byte[].class};
+
+ private final DataType[] supportDataTypes = {DataType.BYTES};
+
+ private final Set> convertClasses = initByteConvertSet();
+
+ @Override
+ public BytesValue encode(Object value, Class> type) {
+ if (!isSupport(type)) {
+ throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName()));
+ }
+ if (type.equals(byte[].class)) {
+ return BytesData.fromBytes((byte[]) value);
+ }
+ return BytesData.fromBytes((Bytes) value);
+ }
+
+ @Override
+ public Class>[] supportClasses() {
+ return supportClasses;
+ }
+
+ @Override
+ public DataType[] supportDataTypes() {
+ return supportDataTypes;
+ }
+
+ @Override
+ protected Object decode(Bytes value) {
+ return value;
+ }
+
+ @Override
+ public Object decode(BytesValue value, Class> clazz) {
+ Bytes bytesVal = (Bytes) decode(value);
+ if (!convertClasses.contains(clazz)) {
+ throw new IllegalStateException(String.format("Un-Support decode value to class[%s] !!!", clazz.getName()));
+ }
+
+ if (clazz.equals(String.class)) {
+ return bytesVal.toUTF8String();
+ } else if (clazz.equals(byte[].class)) {
+ return bytesVal.toBytes();
+ }
+ return bytesVal;
+ }
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesValueResolver.java
new file mode 100644
index 00000000..08e48658
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/BytesValueResolver.java
@@ -0,0 +1,80 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public interface BytesValueResolver {
+
+ /**
+ * Int相关的可转换Class集合
+ */
+ Class>[] supportIntConvertClasses = {
+ short.class, Short.class, int.class, Integer.class, long.class, Long.class};
+
+ /**
+ * 字节数组(字符串)相关可转换的Class集合
+ */
+ Class>[] supportByteConvertClasses = {
+ String.class, Bytes.class, byte[].class};
+
+ default Set> initIntConvertSet() {
+ return new HashSet<>(Arrays.asList(supportIntConvertClasses));
+ }
+
+ default Set> initByteConvertSet() {
+ return new HashSet<>(Arrays.asList(supportByteConvertClasses));
+ }
+
+ /**
+ * 将对象转换为BytesValue
+ *
+ * @param value
+ * @return
+ */
+ BytesValue encode(Object value);
+
+ /**
+ * 将对象转换为BytesValue
+ *
+ * @param value
+ * @param type
+ * @return
+ */
+ BytesValue encode(Object value, Class> type);
+
+ /**
+ * 当前解析器支持的Class列表
+ *
+ * @return
+ */
+ Class>[] supportClasses();
+
+ /**
+ * 当前解析器支持的DataType列表
+ *
+ * @return
+ */
+ DataType[] supportDataTypes();
+
+ /**
+ * 将BytesValue解析为对应的Object
+ *
+ * @param value
+ * @return
+ */
+ Object decode(BytesValue value);
+
+ /**
+ * 将BytesValue转换为指定Class的Object
+ *
+ * @param value
+ * @param clazz
+ * @return
+ */
+ Object decode(BytesValue value, Class> clazz);
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java
new file mode 100644
index 00000000..a8400f02
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/IntegerToBytesValueResolver.java
@@ -0,0 +1,58 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+
+import java.util.Set;
+
+public class IntegerToBytesValueResolver extends AbstractBytesValueResolver {
+
+ private final Class>[] supportClasses = {Integer.class, int.class};
+
+ private final DataType[] supportDataTypes = {DataType.INT32};
+
+ private final Set> convertClasses = initIntConvertSet();
+
+ @Override
+ public BytesValue encode(Object value, Class> type) {
+ if (!isSupport(type)) {
+ throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName()));
+ }
+ return BytesData.fromInt32((int) value);
+ }
+
+ @Override
+ public Class>[] supportClasses() {
+ return supportClasses;
+ }
+
+ @Override
+ public DataType[] supportDataTypes() {
+ return supportDataTypes;
+ }
+
+ @Override
+ protected Object decode(Bytes value) {
+ return BytesUtils.toInt(value.toBytes());
+ }
+
+ @Override
+ public Object decode(BytesValue value, Class> clazz) {
+ // 支持转换为short、int、long
+ int intVal = (int)decode(value);
+ if (convertClasses.contains(clazz)) {
+ // 对于short和Short需要强制类型转换
+ if (clazz.equals(short.class) || clazz.equals(Short.class)) {
+ return (short) intVal;
+ } else if (clazz.equals(long.class) || clazz.equals(Long.class)) {
+ return (long) intVal;
+ }
+ return intVal;
+ } else {
+ throw new IllegalStateException(String.format("Un-Support decode value to class[%s] !!!", clazz.getName()));
+ }
+ }
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java
new file mode 100644
index 00000000..fa11bcf4
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/LongToBytesValueResolver.java
@@ -0,0 +1,58 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+
+import java.util.Set;
+
+public class LongToBytesValueResolver extends AbstractBytesValueResolver {
+
+ private final Class>[] supportClasses = {Long.class, long.class};
+
+ private final DataType[] supportDataTypes = {DataType.INT64};
+
+ private final Set> convertClasses = initIntConvertSet();
+
+ @Override
+ public BytesValue encode(Object value, Class> type) {
+ if (!isSupport(type)) {
+ throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName()));
+ }
+ return BytesData.fromInt64((long)value);
+ }
+
+ @Override
+ public Class>[] supportClasses() {
+ return supportClasses;
+ }
+
+ @Override
+ public DataType[] supportDataTypes() {
+ return supportDataTypes;
+ }
+
+ @Override
+ protected Object decode(Bytes value) {
+ return BytesUtils.toLong(value.toBytes());
+ }
+
+ @Override
+ public Object decode(BytesValue value, Class> clazz) {
+ // 支持转换为short、int、long
+ long longVal = (long)decode(value);
+ if (convertClasses.contains(clazz)) {
+ // 对于short和Short需要强制类型转换
+ if (clazz.equals(short.class) || clazz.equals(Short.class)) {
+ return (short) longVal;
+ } else if (clazz.equals(int.class) || clazz.equals(Integer.class)) {
+ return (int) longVal;
+ }
+ return longVal;
+ } else {
+ throw new IllegalStateException(String.format("Un-Support decode value to class[%s] !!!", clazz.getName()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java
new file mode 100644
index 00000000..b8eea38c
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/ShortToBytesValueResolver.java
@@ -0,0 +1,57 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+
+import java.util.Set;
+
+public class ShortToBytesValueResolver extends AbstractBytesValueResolver {
+
+ private final Class>[] supportClasses = {Short.class, short.class};
+
+ private final DataType[] supportDataTypes = {DataType.INT16};
+
+ private final Set> convertClasses = initIntConvertSet();
+
+ @Override
+ public BytesValue encode(Object value, Class> type) {
+ if (!isSupport(type)) {
+ throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName()));
+ }
+ return BytesData.fromInt16((short)value);
+ }
+
+ @Override
+ public Class>[] supportClasses() {
+ return supportClasses;
+ }
+
+ @Override
+ public DataType[] supportDataTypes() {
+ return supportDataTypes;
+ }
+
+ @Override
+ protected Object decode(Bytes value) {
+ return BytesUtils.toShort(value.toBytes());
+ }
+
+ @Override
+ public Object decode(BytesValue value, Class> clazz) {
+ // 支持转换为short、int、long,由short转int、long无需转换
+ short shortVal = (short)decode(value);
+ if (convertClasses.contains(clazz)) {
+ if (clazz.equals(int.class) || clazz.equals(Integer.class)) {
+ return (int) shortVal;
+ } else if (clazz.equals(long.class) || clazz.equals(Long.class)) {
+ return (long) shortVal;
+ }
+ return shortVal;
+ } else {
+ throw new IllegalStateException(String.format("Un-Support decode value to class[%s] !!!", clazz.getName()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java
new file mode 100644
index 00000000..dca8e5d1
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/resolver/StringToBytesValueResolver.java
@@ -0,0 +1,66 @@
+package com.jd.blockchain.ledger.resolver;
+
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+import com.jd.blockchain.utils.serialize.json.JSONSerializeUtils;
+
+import java.util.Set;
+
+
+public class StringToBytesValueResolver extends AbstractBytesValueResolver {
+
+ private final Class>[] supportClasses = {String.class};
+
+ private final DataType[] supportDataTypes = {DataType.TEXT, DataType.XML, DataType.JSON};
+
+ private final Set> convertClasses = initByteConvertSet();
+
+ @Override
+ public BytesValue encode(Object value, Class> type) {
+ if (!isSupport(type)) {
+ throw new IllegalStateException(String.format("Un-support encode Class[%s] Object !!!", type.getName()));
+ }
+ // 类型判断
+ String valString = (String)value;
+ if (JSONSerializeUtils.isJSON(valString)) {
+ return BytesData.fromJSON(valString);
+ }
+ // 暂不处理XML格式
+ return BytesData.fromText(valString);
+ }
+
+ @Override
+ public Class>[] supportClasses() {
+ return supportClasses;
+ }
+
+ @Override
+ public DataType[] supportDataTypes() {
+ return supportDataTypes;
+ }
+
+ @Override
+ protected Object decode(Bytes value) {
+ return BytesUtils.toString(value.toBytes());
+ }
+
+ @Override
+ public Object decode(BytesValue value, Class> clazz) {
+ // 支持三种类型对象返回,String.class,byte[].class,Bytes.class
+ String textValue = (String)decode(value);
+
+ if (!convertClasses.contains(clazz)) {
+ throw new IllegalStateException(String.format("Un-Support decode value to class[%s] !!!", clazz.getName()));
+ }
+
+ if (clazz.equals(byte[].class)) {
+ return BytesUtils.toBytes(textValue);
+ } else if (clazz.equals(Bytes.class)) {
+ return Bytes.fromString(textValue);
+ }
+ return textValue;
+ }
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java
index 744eab47..8b48d509 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java
@@ -53,7 +53,7 @@ public class ContractInvocationHandler implements InvocationHandler {
}
// 序列化调用参数;
Class>[] argTypes = method.getParameterTypes();
- BytesValueList argBytes = BytesValueEncoding.encode(args, argTypes);
+ BytesValueList argBytes = BytesValueEncoding.encodeArray(args, argTypes);
// 定义合约调用操作;
ContractEventSendOpTemplate opTemplate = (ContractEventSendOpTemplate) sendOpBuilder.send(contractAddress,
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesToBytesValueResolverTest.java
new file mode 100644
index 00000000..fb470200
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesToBytesValueResolverTest.java
@@ -0,0 +1,43 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.ledger.resolver.BytesToBytesValueResolver;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class BytesToBytesValueResolverTest {
+
+ private BytesToBytesValueResolver resolver = new BytesToBytesValueResolver();
+
+ @Test
+ public void test() {
+ String text = "www.jd.com";
+
+ byte[] bytes = BytesUtils.toBytes(text);
+
+ Bytes bytesObj = Bytes.fromString(text);
+
+ BytesValue bytesValue = resolver.encode(bytes);
+
+ assertNotNull(bytesValue);
+
+ assertEquals(bytesValue.getType(), DataType.BYTES);
+
+ assertEquals(bytesObj, bytesValue.getValue());
+
+ Bytes resolveBytesObj = (Bytes)resolver.decode(bytesValue);
+
+ assertEquals(bytesObj, resolveBytesObj);
+
+ byte[] resolveBytes = (byte[])resolver.decode(bytesValue, byte[].class);
+
+ assertArrayEquals(bytes, resolveBytes);
+
+ String resolveText = (String)resolver.decode(bytesValue, String.class);
+
+ assertEquals(text, resolveText);
+ }
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesValueEncodingTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesValueEncodingTest.java
new file mode 100644
index 00000000..d6bde510
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesValueEncodingTest.java
@@ -0,0 +1,24 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.BytesValueEncoding;
+import com.jd.blockchain.utils.Bytes;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class BytesValueEncodingTest {
+ @Test
+ public void testSupport() {
+ assertTrue(BytesValueEncoding.supportType(byte[].class));
+ assertTrue(BytesValueEncoding.supportType(int.class));
+ assertTrue(BytesValueEncoding.supportType(Integer.class));
+ assertTrue(BytesValueEncoding.supportType(short.class));
+ assertTrue(BytesValueEncoding.supportType(Short.class));
+ assertTrue(BytesValueEncoding.supportType(long.class));
+ assertTrue(BytesValueEncoding.supportType(Long.class));
+ assertTrue(BytesValueEncoding.supportType(String.class));
+ assertTrue(BytesValueEncoding.supportType(Bytes.class));
+
+
+
+ }
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/IntegerToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/IntegerToBytesValueResolverTest.java
new file mode 100644
index 00000000..4b65ae16
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/IntegerToBytesValueResolverTest.java
@@ -0,0 +1,51 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.ledger.resolver.IntegerToBytesValueResolver;
+import static org.junit.Assert.*;
+
+import com.jd.blockchain.utils.Bytes;
+import org.junit.Test;
+
+public class IntegerToBytesValueResolverTest {
+
+ private IntegerToBytesValueResolver resolver = new IntegerToBytesValueResolver();
+
+ @Test
+ public void test() {
+ int intVal = 1024;
+
+ BytesValue intBytesValue = resolver.encode(intVal);
+
+ BytesValue intBytesValue1 = resolver.encode(intVal, int.class);
+
+ BytesValue intBytesValue2 = resolver.encode(intVal, Integer.class);
+
+ assertEquals(intBytesValue.getValue(), intBytesValue1.getValue());
+
+ assertEquals(intBytesValue.getValue(), intBytesValue2.getValue());
+
+ Bytes intBytes = Bytes.fromInt(intVal);
+
+ assertEquals(intBytes, intBytesValue.getValue());
+
+ assertEquals(intBytesValue.getType(), DataType.INT32);
+
+ int resolveInt = (int)resolver.decode(intBytesValue);
+
+ assertEquals(intVal, resolveInt);
+
+ short resolveShort = (short) resolver.decode(intBytesValue, short.class);
+ assertEquals(resolveShort, 1024);
+ Short resolveShortObj = (Short) resolver.decode(intBytesValue, Short.class);
+ assertEquals((short)resolveShortObj, resolveShort);
+
+ long resolveLong = (long) resolver.decode(intBytesValue, long.class);
+ assertEquals(resolveLong, 1024L);
+
+ Long resolveLongObj = (Long) resolver.decode(intBytesValue, Long.class);
+ assertEquals(resolveLong, (long) resolveLongObj);
+
+ }
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/LongToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/LongToBytesValueResolverTest.java
new file mode 100644
index 00000000..19cbdcbd
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/LongToBytesValueResolverTest.java
@@ -0,0 +1,52 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.ledger.resolver.IntegerToBytesValueResolver;
+import com.jd.blockchain.ledger.resolver.LongToBytesValueResolver;
+import com.jd.blockchain.utils.Bytes;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class LongToBytesValueResolverTest {
+
+ private LongToBytesValueResolver resolver = new LongToBytesValueResolver();
+
+ @Test
+ public void test() {
+ long longVal = 65536L;
+
+ BytesValue longBytesValue = resolver.encode(longVal);
+
+ BytesValue longBytesValue1 = resolver.encode(longVal, long.class);
+
+ BytesValue longBytesValue2 = resolver.encode(longVal, Long.class);
+
+ assertEquals(longBytesValue.getValue(), longBytesValue1.getValue());
+
+ assertEquals(longBytesValue.getValue(), longBytesValue2.getValue());
+
+ Bytes longBytes = Bytes.fromLong(longVal);
+
+ assertEquals(longBytes, longBytesValue.getValue());
+
+ assertEquals(longBytesValue.getType(), DataType.INT64);
+
+ long resolveLong = (long)resolver.decode(longBytesValue);
+
+ assertEquals(longVal, resolveLong);
+
+ short resolveShort = (short) resolver.decode(longBytesValue, short.class);
+ assertEquals(resolveShort, (short)65536);
+
+ Short resolveShortObj = (Short) resolver.decode(longBytesValue, Short.class);
+ assertEquals((short)resolveShortObj, resolveShort);
+
+ int resolveInt = (int) resolver.decode(longBytesValue, int.class);
+ assertEquals(resolveInt, 65536);
+
+ Integer resolveIntObj = (Integer) resolver.decode(longBytesValue, Integer.class);
+ assertEquals(resolveInt, (int) resolveIntObj);
+ }
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ShortToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ShortToBytesValueResolverTest.java
new file mode 100644
index 00000000..6c4ef0c8
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ShortToBytesValueResolverTest.java
@@ -0,0 +1,43 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.ledger.resolver.ShortToBytesValueResolver;
+import com.jd.blockchain.utils.Bytes;
+import com.jd.blockchain.utils.io.BytesUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ShortToBytesValueResolverTest {
+
+ private ShortToBytesValueResolver resolver = new ShortToBytesValueResolver();
+
+ @Test
+ public void test() {
+ short shortVal = 64;
+
+ BytesValue shortBytesValue = resolver.encode(shortVal);
+
+ Bytes shortBytes = new Bytes(BytesUtils.toBytes(shortVal));
+
+ assertEquals(shortBytes, shortBytesValue.getValue());
+
+ assertEquals(shortBytesValue.getType(), DataType.INT16);
+
+ short resolveShort = (short)resolver.decode(shortBytesValue);
+
+ assertEquals(shortVal, resolveShort);
+
+ int resolveInt = (int) resolver.decode(shortBytesValue, int.class);
+ assertEquals(resolveInt, 64);
+ Integer resolveIntObj = (Integer) resolver.decode(shortBytesValue, Integer.class);
+ assertEquals((int)resolveIntObj, resolveShort);
+
+ long resolveLong = (long) resolver.decode(shortBytesValue, long.class);
+ assertEquals(resolveLong, 64L);
+
+ Long resolveLongObj = (Long) resolver.decode(shortBytesValue, Long.class);
+ assertEquals(resolveLong, (long) resolveLongObj);
+ }
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/StringToBytesValueResolverTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/StringToBytesValueResolverTest.java
new file mode 100644
index 00000000..6538e88e
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/StringToBytesValueResolverTest.java
@@ -0,0 +1,79 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.ledger.DataType;
+import com.jd.blockchain.ledger.resolver.StringToBytesValueResolver;
+import com.jd.blockchain.utils.Bytes;
+import static org.junit.Assert.*;
+
+import com.jd.blockchain.utils.io.BytesUtils;
+import org.junit.Test;
+
+public class StringToBytesValueResolverTest {
+
+ private StringToBytesValueResolver resolver = new StringToBytesValueResolver();
+
+ @Test
+ public void testText() {
+ String textVal = "JDChain";
+
+ BytesValue textBytesValue = resolver.encode(textVal);
+
+ assertEquals(Bytes.fromString(textVal), textBytesValue.getValue());
+
+ assertEquals(textBytesValue.getType(), DataType.TEXT);
+
+ String resolveText = (String)resolver.decode(textBytesValue);
+
+ assertEquals(resolveText, textVal);
+
+ byte[] resolveBytes = (byte[]) resolver.decode(textBytesValue, byte[].class);
+
+ assertArrayEquals(resolveBytes, BytesUtils.toBytes(textVal));
+
+ Bytes resolveBytesObj = (Bytes) resolver.decode(textBytesValue, Bytes.class);
+
+ assertEquals(resolveBytesObj, Bytes.fromString(textVal));
+
+ }
+
+ @Test
+ public void testJson() {
+ Person person = new Person("zhangsan", 80);
+ String personJson = JSON.toJSONString(person);
+ BytesValue textBytesValue = resolver.encode(personJson);
+ assertEquals(Bytes.fromString(personJson), textBytesValue.getValue());
+ assertEquals(textBytesValue.getType(), DataType.JSON);
+ }
+
+ public static class Person {
+ private String name;
+
+ private int age;
+
+ public Person() {
+ }
+
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+}
diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
index 5419a531..f0f904ad 100644
--- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
+++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
@@ -31,348 +31,347 @@ import java.lang.reflect.Field;
public class ClientResolveUtil {
- public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) {
- if (kvDataEntries == null || kvDataEntries.length == 0) {
- return kvDataEntries;
- }
- KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length];
- // kvDataEntries是代理对象,需要处理
- for (int i = 0; i < kvDataEntries.length; i++) {
- KVDataEntry kvDataEntry = kvDataEntries[i];
- String key = kvDataEntry.getKey();
- long version = kvDataEntry.getVersion();
- DataType dataType = kvDataEntry.getType();
- KvData innerKvData = new KvData(key, version, dataType);
- Object valueObj = kvDataEntry.getValue();
- switch (dataType) {
- case NIL:
- break;
- case BYTES:
- case TEXT:
- case JSON:
- innerKvData.setValue(valueObj.toString());
- break;
- case INT32:
- innerKvData.setValue(Integer.parseInt(valueObj.toString()));
- break;
- case INT64:
- innerKvData.setValue(Long.parseLong(valueObj.toString()));
- break;
- default:
- throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!");
- }
- resolveKvDataEntries[i] = innerKvData;
- }
- return resolveKvDataEntries;
- }
-
- public static Operation read(Operation operation) {
-
- try {
- // Class
- Class> clazz = operation.getClass();
- Field field = clazz.getSuperclass().getDeclaredField("h");
- field.setAccessible(true);
- Object object = field.get(operation);
- if (object instanceof JSONObject) {
- JSONObject jsonObject = (JSONObject) object;
- if (jsonObject.containsKey("accountID")) {
- return convertDataAccountRegisterOperation(jsonObject);
- } else if (jsonObject.containsKey("userID")) {
- return convertUserRegisterOperation(jsonObject);
- } else if (jsonObject.containsKey("contractID")) {
- return convertContractCodeDeployOperation(jsonObject);
- } else if (jsonObject.containsKey("writeSet")) {
- return convertDataAccountKVSetOperation(jsonObject);
- } else if (jsonObject.containsKey("initSetting")) {
- return convertLedgerInitOperation(jsonObject);
- } else if (jsonObject.containsKey("contractAddress")) {
- return convertContractEventSendOperation(jsonObject);
- }
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return null;
- }
-
- public static Object readValueByBytesValue(BytesValue bytesValue) {
- DataType dataType = bytesValue.getType();
- Bytes saveVal = bytesValue.getValue();
- Object showVal;
- switch (dataType) {
- case BYTES:
- // return hex
- showVal = HexUtils.encode(saveVal.toBytes());
- break;
- case TEXT:
- case JSON:
- showVal = saveVal.toUTF8String();
- break;
- case INT64:
- showVal = BytesUtils.toLong(saveVal.toBytes());
- break;
- default:
- showVal = HexUtils.encode(saveVal.toBytes());
- break;
- }
- return showVal;
- }
-
- public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) {
- JSONObject account = jsonObject.getJSONObject("accountID");
- return new DataAccountRegisterOpTemplate(blockchainIdentity(account));
- }
-
- public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) {
- // 写入集合处理
- JSONArray writeSetObj = jsonObject.getJSONArray("writeSet");
- JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress");
- String addressBase58 = accountAddrObj.getString("value");
- Bytes address = Bytes.fromBase58(addressBase58);
-
- DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address);
- for (int i = 0; i < writeSetObj.size(); i++) {
- JSONObject currWriteSetObj = writeSetObj.getJSONObject(i);
- long expectedVersion = currWriteSetObj.getLong("expectedVersion");
- JSONObject valueObj = currWriteSetObj.getJSONObject("value");
- String typeStr = valueObj.getString("type");
- String realValBase58 = valueObj.getString("value");
- String key = currWriteSetObj.getString("key");
- DataType dataType = DataType.valueOf(typeStr);
- BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58));
- KVData kvData = new KVData(key, bytesValue, expectedVersion);
- kvOperation.set(kvData);
- }
-
- return kvOperation;
- }
-
- public static LedgerInitOperation convertLedgerInitOperation(JSONObject jsonObject) {
- JSONObject legerInitObj = jsonObject.getJSONObject("initSetting");
- LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData();
- String ledgerSeedStr = legerInitObj.getString("ledgerSeed");
-
- // 种子需要做Base64转换
- ledgerInitSettingData.setLedgerSeed(Base64.decodeBase64(BytesUtils.toBytes(ledgerSeedStr)));
-
- String consensusProvider = legerInitObj.getString("consensusProvider");
-
- ledgerInitSettingData.setConsensusProvider(consensusProvider);
-
- JSONObject cryptoSettingObj = legerInitObj.getJSONObject("cryptoSetting");
- boolean autoVerifyHash = cryptoSettingObj.getBoolean("autoVerifyHash");
- short hashAlgorithm = cryptoSettingObj.getShort("hashAlgorithm");
-
- CryptoConfig cryptoConfig = new CryptoConfig();
-
- cryptoConfig.setAutoVerifyHash(autoVerifyHash);
-
- cryptoConfig.setHashAlgorithm(hashAlgorithm);
-
- ledgerInitSettingData.setCryptoSetting(cryptoConfig);
-
- JSONObject consensusSettingsObj = legerInitObj.getJSONObject("consensusSettings");
- Bytes consensusSettings = Bytes.fromBase58(consensusSettingsObj.getString("value"));
-
- ledgerInitSettingData.setConsensusSettings(consensusSettings);
-
- JSONArray consensusParticipantsArray = legerInitObj.getJSONArray("consensusParticipants");
-
- if (!consensusParticipantsArray.isEmpty()) {
- ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipantsArray.size()];
- for (int i = 0; i < consensusParticipantsArray.size(); i++) {
- JSONObject currConsensusParticipant = consensusParticipantsArray.getJSONObject(i);
- String addressBase58 = currConsensusParticipant.getString("address");
- String name = currConsensusParticipant.getString("name");
- int id = currConsensusParticipant.getInteger("id");
- JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey");
- String pubKeyBase58 = pubKeyObj.getString("value");
- // 生成ParticipantNode对象
- ParticipantCertData participantCertData = new ParticipantCertData(id, addressBase58, name,
- new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()));
- participantNodes[i] = participantCertData;
- }
- ledgerInitSettingData.setConsensusParticipants(participantNodes);
- }
-
- return new LedgerInitOpTemplate(ledgerInitSettingData);
- }
-
- public static UserRegisterOperation convertUserRegisterOperation(JSONObject jsonObject) {
- JSONObject user = jsonObject.getJSONObject("userID");
- return new UserRegisterOpTemplate(blockchainIdentity(user));
- }
-
- public static ContractCodeDeployOperation convertContractCodeDeployOperation(JSONObject jsonObject) {
- JSONObject contract = jsonObject.getJSONObject("contractID");
- BlockchainIdentityData blockchainIdentity = blockchainIdentity(contract);
-
- String chainCodeStr = jsonObject.getString("chainCode");
- ContractCodeDeployOpTemplate contractCodeDeployOpTemplate = new ContractCodeDeployOpTemplate(blockchainIdentity,
- BytesUtils.toBytes(chainCodeStr));
- return contractCodeDeployOpTemplate;
- }
-
- public static ContractEventSendOperation convertContractEventSendOperation(JSONObject jsonObject) {
- JSONObject contractAddressObj = jsonObject.getJSONObject("contractAddress");
- String contractAddress = contractAddressObj.getString("value");
- String argsStr = jsonObject.getString("args");
- String event = jsonObject.getString("event");
- return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event,
- BytesDataList.singleText(argsStr));
- }
-
- private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) {
- JSONObject addressObj = jsonObject.getJSONObject("address");
- // base58值
- String addressBase58 = addressObj.getString("value");
- Bytes address = Bytes.fromBase58(addressBase58);
-
- JSONObject pubKeyObj = jsonObject.getJSONObject("pubKey");
- // base58值
- String pubKeyBase58 = pubKeyObj.getString("value");
- PubKey pubKey = new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes());
-
- // 生成对应的对象
- return new BlockchainIdentityData(address, pubKey);
- }
-
- public static class CryptoConfig implements CryptoSetting {
-
- private short hashAlgorithm;
-
- private boolean autoVerifyHash;
-
- @Override
- public CryptoProvider[] getSupportedProviders() {
- return new CryptoProvider[0];
- }
-
- @Override
- public short getHashAlgorithm() {
- return hashAlgorithm;
- }
-
- @Override
- public boolean getAutoVerifyHash() {
- return autoVerifyHash;
- }
-
- public void setHashAlgorithm(short hashAlgorithm) {
- this.hashAlgorithm = hashAlgorithm;
- }
-
- public void setAutoVerifyHash(boolean autoVerifyHash) {
- this.autoVerifyHash = autoVerifyHash;
- }
- }
-
- public static class ParticipantCertData implements ParticipantNode {
- private int id;
- private String address;
- private String name;
- private PubKey pubKey;
-
- public ParticipantCertData() {
- }
-
- public ParticipantCertData(ParticipantNode participantNode) {
- this.address = participantNode.getAddress();
- this.name = participantNode.getName();
- this.pubKey = participantNode.getPubKey();
- }
-
- public ParticipantCertData(int id, String address, String name, PubKey pubKey) {
- this.id = id;
- this.address = address;
- this.name = name;
- this.pubKey = pubKey;
- }
-
- @Override
- public String getAddress() {
- return address;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public PubKey getPubKey() {
- return pubKey;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
- }
-
- public static class KvData implements KVDataEntry {
-
- private String key;
-
- private long version;
-
- private DataType dataType;
-
- private Object value;
-
- public KvData() {
- }
-
- public KvData(String key, long version, DataType dataType) {
- this(key, version, dataType, null);
- }
-
- public KvData(String key, long version, DataType dataType, Object value) {
- this.key = key;
- this.version = version;
- this.dataType = dataType;
- this.value = value;
- }
-
- public void setKey(String key) {
- this.key = key;
- }
-
- public void setVersion(long version) {
- this.version = version;
- }
-
- public void setDataType(DataType dataType) {
- this.dataType = dataType;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
- @Override
- public String getKey() {
- return key;
- }
-
- @Override
- public long getVersion() {
- return version;
- }
-
- @Override
- public DataType getType() {
- return dataType;
- }
-
- @Override
- public Object getValue() {
- return value;
- }
- }
+ public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) {
+ if (kvDataEntries == null || kvDataEntries.length == 0) {
+ return kvDataEntries;
+ }
+ KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length];
+ // kvDataEntries是代理对象,需要处理
+ for (int i = 0; i < kvDataEntries.length; i++) {
+ KVDataEntry kvDataEntry = kvDataEntries[i];
+ String key = kvDataEntry.getKey();
+ long version = kvDataEntry.getVersion();
+ DataType dataType = kvDataEntry.getType();
+ KvData innerKvData = new KvData(key, version, dataType);
+ Object valueObj = kvDataEntry.getValue();
+ switch (dataType) {
+ case NIL:
+ break;
+ case BYTES:
+ case TEXT:
+ case JSON:
+ innerKvData.setValue(valueObj.toString());
+ break;
+ case INT32:
+ innerKvData.setValue(Integer.parseInt(valueObj.toString()));
+ break;
+ case INT64:
+ innerKvData.setValue(Long.parseLong(valueObj.toString()));
+ break;
+ default:
+ throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!");
+ }
+ resolveKvDataEntries[i] = innerKvData;
+ }
+ return resolveKvDataEntries;
+ }
+
+ public static Operation read(Operation operation) {
+
+ try {
+ // Class
+ Class> clazz = operation.getClass();
+ Field field = clazz.getSuperclass().getDeclaredField("h");
+ field.setAccessible(true);
+ Object object = field.get(operation);
+ if (object instanceof JSONObject) {
+ JSONObject jsonObject = (JSONObject) object;
+ if (jsonObject.containsKey("accountID")) {
+ return convertDataAccountRegisterOperation(jsonObject);
+ } else if (jsonObject.containsKey("userID")) {
+ return convertUserRegisterOperation(jsonObject);
+ } else if (jsonObject.containsKey("contractID")) {
+ return convertContractCodeDeployOperation(jsonObject);
+ } else if (jsonObject.containsKey("writeSet")) {
+ return convertDataAccountKVSetOperation(jsonObject);
+ } else if (jsonObject.containsKey("initSetting")) {
+ return convertLedgerInitOperation(jsonObject);
+ } else if (jsonObject.containsKey("contractAddress")) {
+ return convertContractEventSendOperation(jsonObject);
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return null;
+ }
+
+ public static Object readValueByBytesValue(BytesValue bytesValue) {
+ DataType dataType = bytesValue.getType();
+ Bytes saveVal = bytesValue.getValue();
+ Object showVal;
+ switch (dataType) {
+ case BYTES:
+ // return hex
+ showVal = HexUtils.encode(saveVal.toBytes());
+ break;
+ case TEXT:
+ case JSON:
+ showVal = saveVal.toUTF8String();
+ break;
+ case INT64:
+ showVal = BytesUtils.toLong(saveVal.toBytes());
+ break;
+ default:
+ showVal = HexUtils.encode(saveVal.toBytes());
+ break;
+ }
+ return showVal;
+ }
+
+ public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) {
+ JSONObject account = jsonObject.getJSONObject("accountID");
+ return new DataAccountRegisterOpTemplate(blockchainIdentity(account));
+ }
+
+ public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) {
+ // 写入集合处理
+ JSONArray writeSetObj = jsonObject.getJSONArray("writeSet");
+ JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress");
+ String addressBase58 = accountAddrObj.getString("value");
+ Bytes address = Bytes.fromBase58(addressBase58);
+
+ DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address);
+ for (int i = 0; i implements InvocationHandler {
OperationResult opResult = operationResults[0];
// 处理返回值
- return BytesValueEncoding.encode(opResult.getResult(), method.getReturnType());
+ return BytesValueEncoding.encodeSingle(opResult.getResult(), method.getReturnType());
}
private boolean isExecuteContractMethod(Method method) {
diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java
index 255ebd2a..93520e0e 100644
--- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java
+++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/BytesUtils.java
@@ -6,6 +6,7 @@ import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
import com.jd.blockchain.utils.IllegalDataException;
@@ -370,6 +371,10 @@ public class BytesUtils {
return value;
}
+ public static short toShort(byte[] bytes) {
+ return toShort(bytes, 0);
+ }
+
public static char toChar(byte[] bytes, int offset) {
char value = 0;
value = (char) ((value | (bytes[offset] & 0xFF)) << 8);