(invocation);
+ }
+
+ /**
+ * 解析合约方法调用的返回值;
+ *
+ * 用法示例:
+ *
+ * import static com.jd.blockchain.transaction.ContractReturnValue.*;
+ *
+ *
+ * LongValueHolder retnHolder = decode(contract.issue(assetKey, amount));
+ *
+ * PreparedTransaction prepTx = tx.prepare();
+ * prepTx.sign(userKey);
+ * prepTx.commit()
+ *
+ * long retnValue = retnHolder.get(); //这是同步方法,会阻塞当前线程等待交易提交后返回结果;
+ *
+ *
+ * @param call
+ * @return
+ */
+ public static LongValueHolder decode(long call) {
+ ContractInvocation invocation = ContractInvocationStub.take();
+ return new LongValueHolder(invocation);
+ }
+
+ /**
+ * 解析合约方法调用的返回值;
+ *
+ * 用法示例:
+ *
+ * import static com.jd.blockchain.transaction.ContractReturnValue.*;
+ *
+ *
+ * IntValueHolder retnHolder = decode(contract.issue(assetKey, amount));
+ *
+ * PreparedTransaction prepTx = tx.prepare();
+ * prepTx.sign(userKey);
+ * prepTx.commit()
+ *
+ * int retnValue = retnHolder.get(); //这是同步方法,会阻塞当前线程等待交易提交后返回结果;
+ *
+ *
+ * @param call
+ * @return
+ */
+ public static IntValueHolder decode(int call) {
+ ContractInvocation invocation = ContractInvocationStub.take();
+ return new IntValueHolder(invocation);
+ }
+
+ /**
+ * 解析合约方法调用的返回值;
+ *
+ * 用法示例:
+ *
+ * import static com.jd.blockchain.transaction.ContractReturnValue.*;
+ *
+ *
+ * ShortValueHolder retnHolder = decode(contract.issue(assetKey, amount));
+ *
+ * PreparedTransaction prepTx = tx.prepare();
+ * prepTx.sign(userKey);
+ * prepTx.commit()
+ *
+ * short retnValue = retnHolder.get(); //这是同步方法,会阻塞当前线程等待交易提交后返回结果;
+ *
+ *
+ * @param call
+ * @return
+ */
+ public static ShortValueHolder decode(short call) {
+ ContractInvocation invocation = ContractInvocationStub.take();
+ return new ShortValueHolder(invocation);
+ }
+
+ /**
+ * 解析合约方法调用的返回值;
+ *
+ * 用法示例:
+ *
+ * import static com.jd.blockchain.transaction.ContractReturnValue.*;
+ *
+ *
+ * ByteValueHolder retnHolder = decode(contract.issue(assetKey, amount));
+ *
+ * PreparedTransaction prepTx = tx.prepare();
+ * prepTx.sign(userKey);
+ * prepTx.commit()
+ *
+ * byte retnValue = retnHolder.get(); //这是同步方法,会阻塞当前线程等待交易提交后返回结果;
+ *
+ *
+ * @param call
+ * @return
+ */
+ public static ByteValueHolder decode(byte call) {
+ ContractInvocation invocation = ContractInvocationStub.take();
+ return new ByteValueHolder(invocation);
+ }
+
+ /**
+ * 解析合约方法调用的返回值;
+ *
+ * 用法示例:
+ *
+ * import static com.jd.blockchain.transaction.ContractReturnValue.*;
+ *
+ *
+ * BooleanValueHolder retnHolder = decode(contract.issue(assetKey, amount));
+ *
+ * PreparedTransaction prepTx = tx.prepare();
+ * prepTx.sign(userKey);
+ * prepTx.commit()
+ *
+ * boolean retnValue = retnHolder.get(); //这是同步方法,会阻塞当前线程等待交易提交后返回结果;
+ *
+ *
+ * @param call
+ * @return
+ */
+ public static BooleanValueHolder decode(boolean call) {
+ ContractInvocation invocation = ContractInvocationStub.take();
+ return new BooleanValueHolder(invocation);
+ }
+
+
+ //----------------------- 内部类型 -----------------------
+
+
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java
deleted file mode 100644
index 8110fc33..00000000
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.jd.blockchain.transaction;
-
-import com.jd.blockchain.binaryproto.DataContract;
-import com.jd.blockchain.contract.Contract;
-import com.jd.blockchain.contract.ContractEvent;
-import com.jd.blockchain.contract.ContractException;
-import com.jd.blockchain.contract.ContractSerializeUtils;
-import com.jd.blockchain.utils.IllegalDataException;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.*;
-
-public class ContractType {
-
- private String name;
- private Map events = new HashMap<>();
- private Map handleMethods = new HashMap<>();
- private Map> dataContractMap = new HashMap<>();
-
- /**
- * 返回声明的所有事件;
- *
- * @return
- */
- public Set getEvents() {
- return events.keySet();
- }
-
- public Map> getDataContractMap() {
- return dataContractMap;
- }
-
- /**
- * 返回指定方法声明的事件;
- *
- * 如果不存在,则返回 null;
- *
- * @param method
- * @return
- */
- public String getEvent(Method method) {
- return handleMethods.get(method);
- }
-
- /**
- * 返回事件的处理方法;
- *
- * 如果不存在,则返回 null;
- *
- * @param event
- * @return
- */
- public Method getHandleMethod(String event) {
- return events.get(event);
- }
-
- private ContractType() {
- }
-
- public static ContractType resolve(Class> contractIntf){
- ContractType contractType = new ContractType();
-
- Annotation annotation = contractIntf.getDeclaredAnnotation(Contract.class);
-
- //contains: @Contract?
- boolean isContractType = annotation != null ? true : false;
- if(!isContractType){
- throw new IllegalDataException("is not Contract Type, becaust there is not @Contract.");
- }
-
- //contractIntf contains @Contract and @ContractEvent;
- Method[] classMethods = contractIntf.getDeclaredMethods();
- for (Method method : classMethods) {
- // if current method contains @ContractEvent,then put it in this map;
- ContractEvent contractEvent = method.getAnnotation(ContractEvent.class);
- if (contractEvent != null) {
- String eventName_ = contractEvent.name();
- //if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO!
- if(contractType.events.containsKey(eventName_)){
- throw new ContractException("there is repeat definition of contractEvent to @ContractEvent.");
- }
- //check param's type is fit for need.
- Class>[] paramTypes = method.getParameterTypes();
- List dataContractList = new ArrayList();
- for(Class> curParamType : paramTypes){
- DataContract dataContract = ContractSerializeUtils.parseDataContract(curParamType);
- dataContractList.add(dataContract);
- }
- if(dataContractList.size()>0){
- contractType.dataContractMap.put(method,dataContractList);
- }
-
- contractType.events.put(eventName_, method);
- contractType.handleMethods.put(method,eventName_);
- }
- }
- return contractType;
- }
-
- @Override
- public String toString() {
- return "ContractType{" +
- "name='" + name + '\'' +
- ", events=" + events +
- ", handleMethods=" + handleMethods +
- '}';
- }
-}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java
index d8125022..b2ccef13 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/DataAccountKVSetOperationBuilderImpl.java
@@ -1,7 +1,7 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.BytesValue;
-import com.jd.blockchain.ledger.BytesValueEntry;
+import com.jd.blockchain.ledger.BytesData;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.utils.Bytes;
@@ -26,14 +26,14 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, byte[] value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromBytes(value);
+ BytesValue bytesValue = BytesData.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setImage(String key, byte[] value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromImage(value);
+ BytesValue bytesValue = BytesData.fromImage(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@@ -45,42 +45,42 @@ public class DataAccountKVSetOperationBuilderImpl implements DataAccountKVSetOpe
@Override
public DataAccountKVSetOperationBuilder setText(String key, String value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromText(value);
+ BytesValue bytesValue = BytesData.fromText(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setBytes(String key, Bytes value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromBytes(value);
+ BytesValue bytesValue = BytesData.fromBytes(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setInt64(String key, long value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromInt64(value);
+ BytesValue bytesValue = BytesData.fromInt64(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setJSON(String key, String value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromJSON(value);
+ BytesValue bytesValue = BytesData.fromJSON(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setXML(String key, String value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromXML(value);
+ BytesValue bytesValue = BytesData.fromXML(value);
operation.set(key, bytesValue, expVersion);
return this;
}
@Override
public DataAccountKVSetOperationBuilder setTimestamp(String key, long value, long expVersion) {
- BytesValue bytesValue = BytesValueEntry.fromTimestamp(value);
+ BytesValue bytesValue = BytesData.fromTimestamp(value);
operation.set(key, bytesValue, expVersion);
return this;
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java
index fd001fb6..8540a470 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java
@@ -4,14 +4,6 @@ import com.jd.blockchain.utils.Bytes;
public interface EventOperator {
- // /**
- // * 合约事件;
- // *
- // * @return
- // */
- // @Deprecated
- // ContractEventSendOperationBuilder contractEvents();
-
/**
* 创建调用合约的代理实例;
*
@@ -30,4 +22,11 @@ public interface EventOperator {
*/
T contract(Bytes address, Class contractIntf);
+// /**
+// * 执行合约异步等待应答结果
+// *
+// * @param execute
+// * @return
+// */
+// EventResult result(ContractEventExecutor execute);
}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/GenericValueHolder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/GenericValueHolder.java
new file mode 100644
index 00000000..1832f315
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/GenericValueHolder.java
@@ -0,0 +1,23 @@
+package com.jd.blockchain.transaction;
+
+public class GenericValueHolder extends ValueHolderWrapper {
+
+ GenericValueHolder(OperationResultHolder resultHolder) {
+ super(resultHolder);
+ }
+
+ /**
+ * 获取值;
+ *
+ * 此方法不堵塞,调用立即返回;
+ *
+ * 如果未完成时( {@link #isCompleted()} 为 false ),总是返回 null;
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public T get() {
+ return (T) super.getValue();
+ }
+
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/IntValueHolder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/IntValueHolder.java
new file mode 100644
index 00000000..5e490ca3
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/IntValueHolder.java
@@ -0,0 +1,22 @@
+package com.jd.blockchain.transaction;
+
+public class IntValueHolder extends ValueHolderWrapper {
+
+ IntValueHolder(OperationResultHolder resultHolder) {
+ super(resultHolder);
+ }
+
+ /**
+ * 获取值;
+ *
+ * 此方法不堵塞,调用立即返回;
+ *
+ * 如果未完成时( {@link #isCompleted()} 为 false ),总是返回 0;
+ *
+ * @return
+ */
+ public int get() {
+ return super.isCompleted() ? (int) super.getValue() : 0;
+ }
+
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LongValueHolder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LongValueHolder.java
new file mode 100644
index 00000000..e5409f29
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/LongValueHolder.java
@@ -0,0 +1,22 @@
+package com.jd.blockchain.transaction;
+
+public class LongValueHolder extends ValueHolderWrapper {
+
+ LongValueHolder(OperationResultHolder resultHolder) {
+ super(resultHolder);
+ }
+
+ /**
+ * 获取值;
+ *
+ * 此方法不堵塞,调用立即返回;
+ *
+ * 如果未完成时( {@link #isCompleted()} 为 false ),总是返回 0;
+ *
+ * @return
+ */
+ public long get() {
+ return super.isCompleted() ? (long) super.getValue() : 0;
+ }
+
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedContext.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedContext.java
new file mode 100644
index 00000000..1197f95b
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedContext.java
@@ -0,0 +1,24 @@
+package com.jd.blockchain.transaction;
+
+import com.jd.blockchain.ledger.BytesValue;
+
+public class OperationCompletedContext {
+
+ private int operationIndex;
+
+ private BytesValue returnBytesValue;
+
+ public OperationCompletedContext(int operationIndex, BytesValue returnBytesValue) {
+ this.operationIndex = operationIndex;
+ this.returnBytesValue = returnBytesValue;
+ }
+
+ public int getOperationIndex() {
+ return operationIndex;
+ }
+
+ public BytesValue getReturnBytesValue() {
+ return returnBytesValue;
+ }
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedListener.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedListener.java
new file mode 100644
index 00000000..c11f27dd
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationCompletedListener.java
@@ -0,0 +1,20 @@
+package com.jd.blockchain.transaction;
+
+/**
+ * 操作完成监听器;
+ *
+ * @author huanghaiquan
+ *
+ */
+public interface OperationCompletedListener {
+
+ /**
+ * 当操作完成时发生;
+ *
+ * @param retnValue 返回值;
+ * @param error 异常;如果值为非空,则表示由异常导致结束;
+ * @param context 上下文对象;
+ */
+ void onCompleted(Object retnValue, Throwable error, OperationCompletedContext context);
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHandle.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHandle.java
new file mode 100644
index 00000000..12bc7b33
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHandle.java
@@ -0,0 +1,35 @@
+package com.jd.blockchain.transaction;
+
+import com.jd.blockchain.ledger.BytesValue;
+
+/**
+ * 操作返回值处理器;
+ *
+ * @author huanghaiquan
+ *
+ */
+interface OperationResultHandle {
+
+ /**
+ * 操作的索引位置;
+ *
+ * @return
+ */
+ int getOperationIndex();
+
+ /**
+ * 正常地完成;
+ *
+ * @param returnBytesValue
+ * @return
+ */
+ Object complete(BytesValue returnBytesValue);
+
+ /**
+ * 以异常方式完成;
+ *
+ * @param error
+ */
+ void complete(Throwable error);
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHolder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHolder.java
new file mode 100644
index 00000000..2f8ec8e6
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/OperationResultHolder.java
@@ -0,0 +1,82 @@
+package com.jd.blockchain.transaction;
+
+import com.jd.blockchain.ledger.BytesValue;
+import com.jd.blockchain.utils.event.EventMulticaster;
+
+abstract class OperationResultHolder implements OperationResultHandle {
+
+ private Object value;
+
+ private Throwable error;
+
+ private volatile boolean completed;
+
+ private EventMulticaster listenerMulticaster =
+ new EventMulticaster<>(OperationCompletedListener.class);
+
+ /**
+ * 导致结束的错误;
+ *
+ * @return
+ */
+ public Throwable getError() {
+ return error;
+ }
+
+ /**
+ * 是否已经处理完成;
+ *
+ * @return
+ */
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ /**
+ * 获取操作的返回值;
+ * 在操作未完成之前,总是返回 null;
+ * 可以通过 {@link #isCompleted()} 方法判断操作是否已经完成;
+ * 可以通过 {@link #addCompletedListener(OperationCompletedListener)}
+ * 方法添加监听器来监听操作完成的事件;
+ *
+ * @return
+ */
+ public Object getResult() {
+ return value;
+ }
+
+ /**
+ * 添加操作完成监听器;
+ *
+ * @param listener
+ */
+ public void addCompletedListener(OperationCompletedListener listener) {
+ listenerMulticaster.addListener(listener);
+ }
+
+ protected abstract Object decodeResult(BytesValue bytesValue);
+
+ @Override
+ public Object complete(BytesValue bytesValue) {
+ if (this.completed) {
+ throw new IllegalStateException(
+ "Contract invocation has been completed, and is not allowed to be completed again!");
+ }
+ this.completed = true;
+ this.value = decodeResult(bytesValue);
+ OperationCompletedContext context = new OperationCompletedContext(getOperationIndex(), null);
+ listenerMulticaster.getBroadcaster().onCompleted(value, null, context);
+ return null;
+ }
+
+ @Override
+ public void complete(Throwable error) {
+ if (completed) {
+ return;
+ }
+ this.completed = true;
+ this.error = error;
+ OperationCompletedContext context = new OperationCompletedContext(getOperationIndex(), null);
+ listenerMulticaster.getBroadcaster().onCompleted(null, error, context);
+ }
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java
index 2b0422c0..b2d0f107 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java
@@ -1,5 +1,12 @@
package com.jd.blockchain.transaction;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.springframework.cglib.proxy.UndeclaredThrowableException;
+
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
@@ -8,6 +15,7 @@ import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.crypto.SignatureDigest;
import com.jd.blockchain.crypto.SignatureFunction;
import com.jd.blockchain.ledger.DigitalSignature;
+import com.jd.blockchain.ledger.OperationResult;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionRequest;
@@ -20,9 +28,32 @@ public class PreparedTx implements PreparedTransaction {
private TransactionService txProcessor;
- public PreparedTx(TransactionRequestBuilder txReqBuilder, TransactionService txProcessor) {
+ private OperationResultHandle[] opReturnValueHandlers;
+
+ private TxStateManager stateManager;
+
+ /**
+ * 创建一个“就绪交易”对象;
+ *
+ * @param txReqBuilder 交易请求构建器;
+ * @param txProcessor 交易处理服务;
+ * @param opReturnValueHandlerList 操作返回值处理器列表;
+ */
+ public PreparedTx(TxStateManager stateManager, TransactionRequestBuilder txReqBuilder,
+ TransactionService txProcessor, Collection opReturnValueHandlerList) {
+ this.stateManager = stateManager;
this.txReqBuilder = txReqBuilder;
this.txProcessor = txProcessor;
+
+ this.opReturnValueHandlers = opReturnValueHandlerList
+ .toArray(new OperationResultHandle[opReturnValueHandlerList.size()]);
+ // 按照操作索引升序排列;
+ Arrays.sort(opReturnValueHandlers, new Comparator() {
+ @Override
+ public int compare(OperationResultHandle o1, OperationResultHandle o2) {
+ return o1.getOperationIndex() - o2.getOperationIndex();
+ }
+ });
}
@Override
@@ -53,9 +84,60 @@ public class PreparedTx implements PreparedTransaction {
@Override
public TransactionResponse commit() {
- TransactionRequest txReq = txReqBuilder.buildRequest();
- // 发起交易请求;
- TransactionResponse txResponse = txProcessor.process(txReq);
+ stateManager.commit();
+ TransactionResponse txResponse = null;
+ try {
+ TransactionRequest txReq = txReqBuilder.buildRequest();
+ // 发起交易请求;
+ txResponse = txProcessor.process(txReq);
+
+ stateManager.complete();
+
+ } catch (Exception ex) {
+ stateManager.close();
+ handleError(ex);
+ throw new UndeclaredThrowableException(ex);
+ }
+
+ if (txResponse != null) {
+ handleResults(txResponse);
+ }
+
return txResponse;
}
+
+ @Override
+ public void close() throws IOException {
+ if (!stateManager.close()) {
+ TransactionCancelledExeption error = new TransactionCancelledExeption(
+ "Prepared transaction has been cancelled!");
+ handleError(error);
+ }
+ }
+
+ private void handleError(Throwable error) {
+ for (OperationResultHandle handle : opReturnValueHandlers) {
+ handle.complete(error);
+ }
+ }
+
+ private void handleResults(TransactionResponse txResponse) {
+ // 解析返回值;正常的情况下,返回结果列表与结果处理器列表中元素对应的操作索引是一致的;
+ OperationResult[] opResults = txResponse.getOperationResults();
+ if (opResults != null && opResults.length > 0) {
+ if (opResults.length != opReturnValueHandlers.length) {
+ throw new IllegalStateException(String.format(
+ "The operation result list of tx doesn't match it's return value handler list! --[TX.Content.Hash=%s][NumOfResults=%s][NumOfHandlers=%s]",
+ txResponse.getContentHash(), opResults.length, opReturnValueHandlers.length));
+ }
+ for (int i = 0; i < opResults.length; i++) {
+ if (opResults[i].getIndex() != opReturnValueHandlers[i].getOperationIndex()) {
+ throw new IllegalStateException(
+ "The operation indexes of the items in the result list and in the handler list don't match!");
+ }
+ opReturnValueHandlers[i].complete(opResults[i].getResult());
+ }
+ }
+ }
+
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ShortValueHolder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ShortValueHolder.java
new file mode 100644
index 00000000..f9867d65
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ShortValueHolder.java
@@ -0,0 +1,22 @@
+package com.jd.blockchain.transaction;
+
+public class ShortValueHolder extends ValueHolderWrapper {
+
+ ShortValueHolder(OperationResultHolder resultHolder) {
+ super(resultHolder);
+ }
+
+ /**
+ * 获取值;
+ *
+ * 此方法不堵塞,调用立即返回;
+ *
+ * 如果未完成时( {@link #isCompleted()} 为 false ),总是返回 0;
+ *
+ * @return
+ */
+ public short get() {
+ return super.isCompleted() ? (short) super.getValue() : 0;
+ }
+
+}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TransactionCancelledExeption.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TransactionCancelledExeption.java
new file mode 100644
index 00000000..69e37b24
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TransactionCancelledExeption.java
@@ -0,0 +1,15 @@
+package com.jd.blockchain.transaction;
+
+public class TransactionCancelledExeption extends RuntimeException {
+
+ private static final long serialVersionUID = -2577951411093171806L;
+
+ public TransactionCancelledExeption(String message) {
+ super(message);
+ }
+
+ public TransactionCancelledExeption(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java
index 12fe552f..cb32c1bd 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java
@@ -1,5 +1,7 @@
package com.jd.blockchain.transaction;
+import java.util.Collection;
+
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.Crypto;
@@ -49,6 +51,10 @@ public class TxBuilder implements TransactionBuilder {
return txContent;
}
+ public Collection getReturnValuehandlers() {
+ return opFactory.getReturnValuetHandlers();
+ }
+
@Override
public LedgerInitOperationBuilder ledgers() {
return opFactory.ledgers();
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java
index 5265b4be..7d6701a5 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxRequestBuilder.java
@@ -71,8 +71,7 @@ public class TxRequestBuilder implements TransactionRequestBuilder {
}
public static SignatureDigest sign(TransactionContent txContent, PrivKey privKey) {
- return Crypto.getSignatureFunction(privKey.getAlgorithm()).sign(privKey,
- txContent.getHash().toBytes());
+ return Crypto.getSignatureFunction(privKey.getAlgorithm()).sign(privKey, txContent.getHash().toBytes());
}
public static boolean verifySignature(TransactionContent txContent, SignatureDigest signDigest, PubKey pubKey) {
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java
index 5d143898..57107ff3 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxResponseMessage.java
@@ -2,6 +2,7 @@ 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;
/**
@@ -18,10 +19,19 @@ public class TxResponseMessage implements TransactionResponse {
private TransactionState executionState;
- private String[] contractReturn;
+ 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;
@@ -59,8 +69,8 @@ public class TxResponseMessage implements TransactionResponse {
this.blockHeight = blockHeight;
}
- public void setContractReturn(String[] contractReturn) {
- this.contractReturn = contractReturn;
+ public void setOperationResults(OperationResult[] operationResults) {
+ this.operationResults = operationResults;
}
@Override
@@ -69,8 +79,8 @@ public class TxResponseMessage implements TransactionResponse {
}
@Override
- public String[] getContractReturn() {
- return contractReturn;
+ public OperationResult[] getOperationResults() {
+ return operationResults;
}
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxStateManager.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxStateManager.java
new file mode 100644
index 00000000..db799f1d
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxStateManager.java
@@ -0,0 +1,76 @@
+package com.jd.blockchain.transaction;
+
+class TxStateManager {
+
+ private State state = State.OPERABLE;
+
+ public void operate() {
+ if (state != State.OPERABLE) {
+ throw new IllegalStateException(String.format("Cannot define operations in %s state!", state));
+ }
+ }
+
+ public void prepare() {
+ if (state != State.OPERABLE) {
+ throw new IllegalStateException(
+ String.format("Cannot switch to %s state in %s state!", State.PREPARED, state));
+ }
+ state = State.PREPARED;
+ }
+
+ public void commit() {
+ if (state != State.PREPARED) {
+ throw new IllegalStateException(
+ String.format("Cannot switch to %s state in %s state!", State.COMMITTED, state));
+ }
+ state = State.COMMITTED;
+ }
+
+ public void complete() {
+ if (state != State.COMMITTED) {
+ throw new IllegalStateException(String.format("Cannot complete normally in %s state!", state));
+ }
+ state = State.CLOSED;
+ }
+
+ /**
+ * 关闭交易;
+ *
+ * @param error
+ * @return 此次操作前是否已经处于关闭状态;
+ * 如果返回 true ,则表示之前已经处于关闭状态,此次操作将被忽略;
+ * 如果返回 fasle,则表示之前处于非关闭状态,此次操作将切换为关闭状态;
+ */
+ public boolean close() {
+ if (state == State.CLOSED) {
+ return true;
+ }
+ state = State.CLOSED;
+ return false;
+ }
+
+ private static enum State {
+
+ /**
+ * 可操作;
+ */
+ OPERABLE,
+
+ /**
+ * 就绪;
+ */
+ PREPARED,
+
+ /**
+ * 已提交;
+ */
+ COMMITTED,
+
+ /**
+ * 已关闭;
+ */
+ CLOSED
+
+ }
+
+}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java
index 984ecf07..9777d238 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java
@@ -1,5 +1,8 @@
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;
@@ -12,7 +15,10 @@ public class TxTemplate implements TransactionTemplate {
private TransactionService txService;
+ private TxStateManager stateManager;
+
public TxTemplate(HashDigest ledgerHash, TransactionService txService) {
+ this.stateManager = new TxStateManager();
this.txBuilder = new TxBuilder(ledgerHash);
this.txService = txService;
}
@@ -24,48 +30,63 @@ public class TxTemplate implements TransactionTemplate {
@Override
public PreparedTransaction prepare() {
+ stateManager.prepare();
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
- return new PreparedTx(txReqBuilder, txService);
+ return new PreparedTx(stateManager, txReqBuilder, txService, txBuilder.getReturnValuehandlers());
}
@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 ContractEventSendOperationBuilder contractEvents() {
-// return txBuilder.contractEvents();
-// }
-
@Override
public T contract(Bytes address, Class contractIntf) {
+ stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
-
+
@Override
public T contract(String address, Class contractIntf) {
+ stateManager.operate();
return txBuilder.contract(address, contractIntf);
}
+ @Override
+ public void close() throws IOException {
+ if (!stateManager.close()) {
+ Collection handlers = txBuilder.getReturnValuehandlers();
+ if (handlers.size() > 0) {
+ TransactionCancelledExeption error = new TransactionCancelledExeption("Transaction template has been cancelled!");
+ for (OperationResultHandle handle : handlers) {
+ handle.complete(error);
+ }
+ }
+ }
+ }
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ValueHolderWrapper.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ValueHolderWrapper.java
new file mode 100644
index 00000000..42c4f86b
--- /dev/null
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ValueHolderWrapper.java
@@ -0,0 +1,34 @@
+package com.jd.blockchain.transaction;
+
+class ValueHolderWrapper {
+ private OperationResultHolder valueHolder;
+
+ protected ValueHolderWrapper(OperationResultHolder valueHolder) {
+ this.valueHolder = valueHolder;
+ }
+
+ public boolean isCompleted() {
+ return valueHolder.isCompleted();
+ }
+
+ public Throwable getError() {
+ return valueHolder.getError();
+ }
+
+ /**
+ * 获取值;
+ *
+ * 此方法不堵塞,调用立即返回;
+ *
+ * 如果未完成时( {@link #isCompleted()} 为 false ),总是返回 null;
+ *
+ * @return
+ */
+ protected Object getValue() {
+ return valueHolder.getResult();
+ }
+
+ public void addCompletedListener(OperationCompletedListener listener) {
+ valueHolder.addCompletedListener(listener);
+ }
+}
\ No newline at end of file
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..73d51d7b
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/BytesValueEncodingTest.java
@@ -0,0 +1,69 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.ledger.*;
+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));
+ assertTrue(BytesValueEncoding.supportType(Operation.class));
+ assertFalse(BytesValueEncoding.supportType(byte.class));
+ }
+
+ @Test
+ public void testSingle() {
+ long longVal = 1024L;
+ BytesValue longBytesVal1 = BytesValueEncoding.encodeSingle(longVal, null);
+ BytesValue longBytesVal2 = BytesValueEncoding.encodeSingle(longVal, long.class);
+ BytesValue longBytesVal3 = BytesValueEncoding.encodeSingle(longVal, Long.class);
+
+ assertEquals(longBytesVal1.getValue(), longBytesVal2.getValue());
+ assertEquals(longBytesVal1.getType(), longBytesVal2.getType());
+ assertEquals(longBytesVal2.getValue(), longBytesVal3.getValue());
+ assertEquals(longBytesVal2.getType(), longBytesVal3.getType());
+
+ long resolveLongVal1 = (long)BytesValueEncoding.decode(longBytesVal1);
+ long resolveLongVal2 = (long)BytesValueEncoding.decode(longBytesVal2);
+ long resolveLongVal3 = (long)BytesValueEncoding.decode(longBytesVal3);
+
+ assertEquals(resolveLongVal1, 1024L);
+ assertEquals(resolveLongVal2, 1024L);
+ assertEquals(resolveLongVal3, 1024L);
+ }
+
+ @Test
+ public void testArray() {
+ Object[] values = new Object[]{1024L, "zhangsan", "lisi".getBytes(), 16};
+ Class>[] classes = new Class[]{long.class, String.class, byte[].class, int.class};
+
+ BytesValueList bytesValueList = BytesValueEncoding.encodeArray(values, null);
+ BytesValueList bytesValueList1 = BytesValueEncoding.encodeArray(values, classes);
+
+ assertEquals(bytesValueList1.getValues().length, values.length);
+
+
+ BytesValue[] bytesValues = bytesValueList.getValues();
+ assertEquals(bytesValues.length, values.length);
+
+ assertEquals(DataType.INT64, bytesValues[0].getType());
+ assertEquals(DataType.TEXT, bytesValues[1].getType());
+ assertEquals(DataType.BYTES, bytesValues[2].getType());
+ assertEquals(DataType.INT32, bytesValues[3].getType());
+
+ Object[] resolveObjs = BytesValueEncoding.decode(bytesValueList, classes);
+
+ assertArrayEquals(resolveObjs, values);
+ }
+
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractEventSendOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractEventSendOpTemplateTest.java
index fb197953..bdfaaa80 100644
--- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractEventSendOpTemplateTest.java
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractEventSendOpTemplateTest.java
@@ -8,21 +8,22 @@
*/
package test.com.jd.blockchain.ledger.data;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
+import com.jd.blockchain.ledger.BytesData;
+import com.jd.blockchain.ledger.BytesDataList;
+import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.ledger.ContractEventSendOperation;
-import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.transaction.ContractEventSendOpTemplate;
-import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
import com.jd.blockchain.utils.Bytes;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
/**
*
* @author shaozhuguang
@@ -32,34 +33,37 @@ import static org.junit.Assert.assertEquals;
public class ContractEventSendOpTemplateTest {
- private ContractEventSendOpTemplate data;
+ private ContractEventSendOpTemplate data;
- @Before
- public void initContractEventSendOpTemplate() {
- DataContractRegistry.register(ContractEventSendOperation.class);
- DataContractRegistry.register(Operation.class);
- String contractAddress = "zhangsan-address", event = "zhangsan-event";
- byte[] args = "zhangsan-args".getBytes();
- data = new ContractEventSendOpTemplate(Bytes.fromString(contractAddress), event, args);
- }
+ @Before
+ public void initContractEventSendOpTemplate() {
+ DataContractRegistry.register(BytesValueList.class);
+ DataContractRegistry.register(ContractEventSendOperation.class);
+ DataContractRegistry.register(Operation.class);
+ String contractAddress = "zhangsan-address", event = "zhangsan-event";
+ BytesValueList args = new BytesDataList(BytesData.fromText("zhangsan-args"));
+ data = new ContractEventSendOpTemplate(Bytes.fromString(contractAddress), event, args);
+ }
- @Test
- public void testSerialize_ContractEventSendOperation() throws Exception {
- byte[] serialBytes = BinaryProtocol.encode(data, ContractEventSendOperation.class);
- ContractEventSendOperation resolvedData = BinaryProtocol.decode(serialBytes);
- System.out.println("------Assert start ------");
- assertEquals(resolvedData.getContractAddress(), data.getContractAddress());
- assertEquals(resolvedData.getEvent(), data.getEvent());
- assertArrayEquals(resolvedData.getArgs(), data.getArgs());
- System.out.println("------Assert OK ------");
- }
+ @Test
+ public void testSerialize_ContractEventSendOperation() throws Exception {
+ byte[] serialBytes = BinaryProtocol.encode(data, ContractEventSendOperation.class);
+ ContractEventSendOperation resolvedData = BinaryProtocol.decode(serialBytes);
+ System.out.println("------Assert start ------");
+ assertEquals(resolvedData.getContractAddress(), data.getContractAddress());
+ assertEquals(resolvedData.getEvent(), data.getEvent());
+ byte[] expectedBytes = BinaryProtocol.encode(resolvedData.getArgs(), BytesValueList.class);
+ byte[] actualBytes = BinaryProtocol.encode(data.getArgs(), BytesValueList.class);
+ assertArrayEquals(expectedBytes, actualBytes);
+ System.out.println("------Assert OK ------");
+ }
- @Test
- public void testSerialize_Operation() throws Exception {
- byte[] serialBytes = BinaryProtocol.encode(data, Operation.class);
- Operation resolvedData = BinaryProtocol.decode(serialBytes);
- System.out.println("------Assert start ------");
- System.out.println(resolvedData);
- System.out.println("------Assert OK ------");
- }
+ @Test
+ public void testSerialize_Operation() throws Exception {
+ byte[] serialBytes = BinaryProtocol.encode(data, Operation.class);
+ Operation resolvedData = BinaryProtocol.decode(serialBytes);
+ System.out.println("------Assert start ------");
+ System.out.println(resolvedData);
+ System.out.println("------Assert OK ------");
+ }
}
\ No newline at end of file
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractTypeTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractTypeTest.java
new file mode 100644
index 00000000..beceb39c
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractTypeTest.java
@@ -0,0 +1,68 @@
+package test.com.jd.blockchain.ledger.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.jd.blockchain.contract.ContractException;
+import com.jd.blockchain.contract.ContractType;
+
+public class ContractTypeTest {
+
+ /**
+ * 正常测试;
+ * @throws SecurityException
+ * @throws NoSuchMethodException
+ */
+ @Test
+ public void normalTest() throws NoSuchMethodException, SecurityException {
+ ContractType contractType = ContractType.resolve(NormalContract.class);
+
+ assertEquals("NORMAL-CONTRACT", contractType.getName());
+
+ Set events = contractType.getEvents();
+ assertEquals(5, events.size());
+ assertTrue(events.contains("issue"));
+ assertTrue(events.contains("get_amount"));
+ assertTrue(events.contains("get_balance"));
+ assertTrue(events.contains("assign"));
+ assertTrue(events.contains("transfer"));
+
+ Method issueMethod = contractType.getHandleMethod("issue");
+ assertNotNull(issueMethod);
+ Method getAmountMethod = contractType.getHandleMethod("get_amount");
+ assertNotNull(getAmountMethod);
+ Method getBalanceMethod = contractType.getHandleMethod("get_balance");
+ assertNotNull(getBalanceMethod);
+ Method assignMethod = contractType.getHandleMethod("assign");
+ assertNotNull(assignMethod);
+ Method transferMethod = contractType.getHandleMethod("transfer");
+ assertNotNull(transferMethod);
+
+ assertEquals("issue", contractType.getEvent(issueMethod));
+ assertEquals("get_amount", contractType.getEvent(getAmountMethod));
+ assertEquals("get_balance", contractType.getEvent(getBalanceMethod));
+ assertEquals("assign", contractType.getEvent(assignMethod));
+ assertEquals("transfer", contractType.getEvent(transferMethod));
+
+ Method toStringMethod = NormalContractImpl.class.getMethod("toString");
+ assertNull(contractType.getEvent(toStringMethod));
+ assertNull(contractType.getHandleMethod("NotExist"));
+
+ //解析非合约声明接口类型时,应该正常,只需要实现接口(该接口定义了具体的合约类型)即可
+ ContractException ex = null;
+ try {
+ ContractType.resolve(NormalContractImpl.class);
+ } catch (ContractException e) {
+ ex = e;
+ }
+ assertNull(ex);
+ }
+
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java
index 005af7c6..a87919b4 100644
--- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/DataAccountKVSetOpTemplateTest.java
@@ -16,7 +16,7 @@ import org.junit.Test;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
-import com.jd.blockchain.ledger.BytesValueEntry;
+import com.jd.blockchain.ledger.BytesData;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
@@ -29,7 +29,6 @@ import com.jd.blockchain.utils.Bytes;
* @create 2018/8/30
* @since 1.0.0
*/
-//todo 尚未测试通过,等张爽处理完再测试
public class DataAccountKVSetOpTemplateTest {
private DataAccountKVSetOpTemplate data;
@@ -42,11 +41,11 @@ public class DataAccountKVSetOpTemplateTest {
String accountAddress = "zhangsandhakhdkah";
data = new DataAccountKVSetOpTemplate(Bytes.fromString(accountAddress));
KVData kvData1 =
- new KVData("test1", BytesValueEntry.fromText("zhangsan"), 9999L);
+ new KVData("test1", BytesData.fromText("zhangsan"), 9999L);
KVData kvData2 =
- new KVData("test2", BytesValueEntry.fromText("lisi"), 9990L);
+ new KVData("test2", BytesData.fromText("lisi"), 9990L);
KVData kvData3 =
- new KVData("test3", BytesValueEntry.fromText("wangwu"), 1990L);
+ new KVData("test3", BytesData.fromText("wangwu"), 1990L);
data.set(kvData1);
data.set(kvData2);
data.set(kvData3);
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/KVDataTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java
index 39824505..229c308d 100644
--- a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/KVDataTest.java
@@ -16,7 +16,7 @@ import org.junit.Test;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
-import com.jd.blockchain.ledger.BytesValueEntry;
+import com.jd.blockchain.ledger.BytesData;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
import com.jd.blockchain.transaction.KVData;
@@ -38,7 +38,7 @@ public class KVDataTest {
byte[] value = "test-value".getBytes();
long expectedVersion = 9999L;
- kvData = new KVData(key, BytesValueEntry.fromBytes(value), expectedVersion);
+ kvData = new KVData(key, BytesData.fromBytes(value), expectedVersion);
}
@Test
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/NormalContract.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/NormalContract.java
new file mode 100644
index 00000000..87dcd127
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/NormalContract.java
@@ -0,0 +1,58 @@
+package test.com.jd.blockchain.ledger.data;
+
+import com.jd.blockchain.contract.Contract;
+import com.jd.blockchain.contract.ContractEvent;
+
+@Contract(name="NORMAL-CONTRACT")
+public interface NormalContract {
+
+ /**
+ * 发行资产;
+ *
+ * @param asset 资产代码;
+ * @param amount 本次发行的资产数量;
+ * @return 资产总量;
+ */
+ @ContractEvent(name="issue")
+ long issue(String asset, long amount);
+
+ /**
+ * 获取资产总量;
+ *
+ * @param asset
+ * @return
+ */
+ @ContractEvent(name="get_amount")
+ long getAmount(String asset);
+
+ /**
+ * 获取资产余额;
+ *
+ * @param address
+ * @param asset
+ * @return
+ */
+ @ContractEvent(name="get_balance")
+ long getBalance(String address, String asset);
+
+ /**
+ * 向账户分配资产;
+ *
+ * @param address
+ * @param asset
+ * @param amount
+ */
+ @ContractEvent(name="assign")
+ void assign(String address, String asset, int amount);
+
+ /**
+ * 转移资产;
+ *
+ * @param fromAddress
+ * @param toAddress
+ * @param asset
+ * @param amount
+ */
+ @ContractEvent(name="transfer")
+ void transfer(String fromAddress, String toAddress, String asset, long amount);
+}
diff --git a/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/NormalContractImpl.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/NormalContractImpl.java
new file mode 100644
index 00000000..ad71598d
--- /dev/null
+++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/NormalContractImpl.java
@@ -0,0 +1,35 @@
+package test.com.jd.blockchain.ledger.data;
+
+public class NormalContractImpl implements NormalContract{
+
+ @Override
+ public long issue(String asset, long amount) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public long getAmount(String asset) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public long getBalance(String address, String asset) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void assign(String address, String asset, int amount) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void transfer(String fromAddress, String toAddress, String asset, long amount) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
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/ledger/ledger-rpc/src/main/java/com/jd/blockchain/web/serializes/ByteArrayObjectJsonSerializer.java b/source/ledger/ledger-rpc/src/main/java/com/jd/blockchain/web/serializes/ByteArrayObjectJsonSerializer.java
index 896e1f4a..e4a82b13 100644
--- a/source/ledger/ledger-rpc/src/main/java/com/jd/blockchain/web/serializes/ByteArrayObjectJsonSerializer.java
+++ b/source/ledger/ledger-rpc/src/main/java/com/jd/blockchain/web/serializes/ByteArrayObjectJsonSerializer.java
@@ -2,7 +2,7 @@ package com.jd.blockchain.web.serializes;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.jd.blockchain.binaryproto.DataType;
+import com.jd.blockchain.binaryproto.BaseType;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.crypto.SignatureDigest;
@@ -92,20 +92,20 @@ public class ByteArrayObjectJsonSerializer implements ObjectSerializer {
public static class BytesValueJson {
- public BytesValueJson(DataType type, Object value) {
+ public BytesValueJson(BaseType type, Object value) {
this.type = type;
this.value = value;
}
- DataType type;
+ BaseType type;
Object value;
- public DataType getType() {
+ public BaseType getType() {
return type;
}
- public void setType(DataType type) {
+ public void setType(BaseType type) {
this.type = type;
}
diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java
index ae62e2d6..d207d725 100644
--- a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java
+++ b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java
@@ -2,6 +2,7 @@ package com.jd.blockchain.peer.consensus;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.ledger.LedgerBlock;
+import com.jd.blockchain.ledger.OperationResult;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionState;
@@ -309,8 +310,8 @@ public class ConsensusMessageDispatcher implements MessageHandle {
}
@Override
- public String[] getContractReturn() {
- return txResp.getContractReturn();
+ public OperationResult[] getOperationResults() {
+ return txResp.getOperationResults();
}
}
diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java b/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java
index 01c2ef61..53f5b36e 100644
--- a/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java
+++ b/source/peer/src/main/java/com/jd/blockchain/peer/web/LedgerQueryController.java
@@ -3,6 +3,7 @@ package com.jd.blockchain.peer.web;
import java.util.ArrayList;
import java.util.List;
+import com.jd.blockchain.ledger.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@@ -13,19 +14,6 @@ import org.springframework.web.bind.annotation.RestController;
import com.jd.blockchain.contract.ContractException;
import com.jd.blockchain.crypto.HashDigest;
-import com.jd.blockchain.ledger.AccountHeader;
-import com.jd.blockchain.ledger.BytesValue;
-import com.jd.blockchain.ledger.KVDataEntry;
-import com.jd.blockchain.ledger.KVDataObject;
-import com.jd.blockchain.ledger.KVDataVO;
-import com.jd.blockchain.ledger.KVInfoVO;
-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.TransactionState;
-import com.jd.blockchain.ledger.UserInfo;
import com.jd.blockchain.ledger.core.ContractAccountSet;
import com.jd.blockchain.ledger.core.DataAccount;
import com.jd.blockchain.ledger.core.DataAccountSet;
@@ -454,8 +442,8 @@ public class LedgerQueryController implements BlockchainQueryService {
@RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts/address/{address}")
@Override
- public AccountHeader getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash,
- @PathVariable(name = "address") String address) {
+ public ContractInfo getContract(@PathVariable(name = "ledgerHash") HashDigest ledgerHash,
+ @PathVariable(name = "address") String address) {
LedgerRepository ledger = ledgerService.getLedger(ledgerHash);
LedgerBlock block = ledger.getLatestBlock();
ContractAccountSet contractAccountSet = ledger.getContractAccountSet(block);
diff --git a/source/pom.xml b/source/pom.xml
index f8c9dfce..11ba5866 100644
--- a/source/pom.xml
+++ b/source/pom.xml
@@ -41,7 +41,7 @@
0.8.1-SNAPSHOT
0.0.8.RELEASE
- 0.6.6.RELEASE
+ 0.7.0.RELEASE
@@ -49,7 +49,7 @@
1.2.2
1.8.8
-
+ 0.5.35
1.0.18
1.2.2
1.2.4
@@ -112,8 +112,8 @@
com.jd.blockchain
- browser
- ${browser.version}
+ explorer
+ ${explorer.version}
@@ -147,6 +147,27 @@
${disruptor.version}
+
+ org.bitbucket.mstrobel
+ procyon-core
+ ${procyon.version}
+
+
+ org.bitbucket.mstrobel
+ procyon-expressions
+ ${procyon.version}
+
+
+ org.bitbucket.mstrobel
+ procyon-reflection
+ ${procyon.version}
+
+
+ org.bitbucket.mstrobel
+ procyon-compilertools
+ ${procyon.version}
+
+
com.alibaba
fastjson
diff --git a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java
index e2c064cd..885d9aac 100644
--- a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java
+++ b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java
@@ -10,7 +10,7 @@ public interface Module {
String getName();
Class> loadClass(String className);
-
+
InputStream loadResourceAsStream(String name);
String getMainClass();
diff --git a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/RuntimeContext.java b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/RuntimeContext.java
index c161371e..569a95a5 100644
--- a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/RuntimeContext.java
+++ b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/RuntimeContext.java
@@ -131,17 +131,17 @@ public abstract class RuntimeContext {
private ClassLoader moduleClassLoader;
- private String MainClass;
+ private String mainClass;
public DefaultModule(String name, ClassLoader cl, String mainClass) {
this.name = name;
this.moduleClassLoader = cl;
- this.MainClass = mainClass;
+ this.mainClass = mainClass;
}
@Override
public String getMainClass() {
- return MainClass;
+ return mainClass;
}
diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/ContractSettings.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/ContractSettings.java
new file mode 100644
index 00000000..4a004b2b
--- /dev/null
+++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/ContractSettings.java
@@ -0,0 +1,64 @@
+package com.jd.blockchain.sdk;
+
+import com.jd.blockchain.crypto.HashDigest;
+import com.jd.blockchain.crypto.PubKey;
+import com.jd.blockchain.utils.Bytes;
+
+public class ContractSettings {
+
+ private Bytes address;
+
+ private PubKey pubKey;
+
+ private HashDigest rootHash;
+
+ private String chainCode;
+
+ public ContractSettings() {
+ }
+
+ public ContractSettings(Bytes address, PubKey pubKey, HashDigest rootHash) {
+ this.address = address;
+ this.pubKey = pubKey;
+ this.rootHash = rootHash;
+ }
+
+ public ContractSettings(Bytes address, PubKey pubKey, HashDigest rootHash, String chainCode) {
+ this.address = address;
+ this.pubKey = pubKey;
+ this.rootHash = rootHash;
+ this.chainCode = chainCode;
+ }
+
+ public Bytes getAddress() {
+ return address;
+ }
+
+ public void setAddress(Bytes address) {
+ this.address = address;
+ }
+
+ public PubKey getPubKey() {
+ return pubKey;
+ }
+
+ public void setPubKey(PubKey pubKey) {
+ this.pubKey = pubKey;
+ }
+
+ public HashDigest getRootHash() {
+ return rootHash;
+ }
+
+ public void setRootHash(HashDigest rootHash) {
+ this.rootHash = rootHash;
+ }
+
+ public String getChainCode() {
+ return chainCode;
+ }
+
+ public void setChainCode(String chainCode) {
+ this.chainCode = chainCode;
+ }
+}
diff --git a/source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientOperationUtil.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
similarity index 75%
rename from source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientOperationUtil.java
rename to source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
index f3f23779..f0f904ad 100644
--- a/source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientOperationUtil.java
+++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
@@ -1,46 +1,26 @@
/**
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved
- * FileName: com.jd.blockchain.sdk.client.ClientOperationUtil
+ * FileName: com.jd.blockchain.sdk.client.ClientResolveUtil
* Author: shaozhuguang
* Department: Y事业部
* Date: 2019/3/27 下午4:12
* Description:
*/
-package com.jd.blockchain.sdk.client;
-
-import java.lang.reflect.Field;
-
-import org.apache.commons.codec.binary.Base64;
+package com.jd.blockchain.sdk.converters;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jd.blockchain.crypto.CryptoProvider;
import com.jd.blockchain.crypto.PubKey;
-import com.jd.blockchain.ledger.BlockchainIdentityData;
-import com.jd.blockchain.ledger.BytesValue;
-import com.jd.blockchain.ledger.BytesValueEntry;
-import com.jd.blockchain.ledger.BytesValueType;
-import com.jd.blockchain.ledger.ContractCodeDeployOperation;
-import com.jd.blockchain.ledger.ContractEventSendOperation;
-import com.jd.blockchain.ledger.CryptoSetting;
-import com.jd.blockchain.ledger.DataAccountKVSetOperation;
-import com.jd.blockchain.ledger.DataAccountRegisterOperation;
-import com.jd.blockchain.ledger.LedgerInitOperation;
-import com.jd.blockchain.ledger.Operation;
-import com.jd.blockchain.ledger.ParticipantNode;
-import com.jd.blockchain.ledger.UserRegisterOperation;
-import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate;
-import com.jd.blockchain.transaction.ContractEventSendOpTemplate;
-import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
-import com.jd.blockchain.transaction.DataAccountRegisterOpTemplate;
-import com.jd.blockchain.transaction.KVData;
-import com.jd.blockchain.transaction.LedgerInitOpTemplate;
-import com.jd.blockchain.transaction.LedgerInitSettingData;
-import com.jd.blockchain.transaction.UserRegisterOpTemplate;
+import com.jd.blockchain.ledger.*;
+import com.jd.blockchain.transaction.*;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.codec.Base58Utils;
import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.io.BytesUtils;
+import org.apache.commons.codec.binary.Base64;
+
+import java.lang.reflect.Field;
/**
*
@@ -49,7 +29,42 @@ import com.jd.blockchain.utils.io.BytesUtils;
* @since 1.0.0
*/
-public class ClientOperationUtil {
+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) {
@@ -83,7 +98,7 @@ public class ClientOperationUtil {
}
public static Object readValueByBytesValue(BytesValue bytesValue) {
- BytesValueType dataType = bytesValue.getType();
+ DataType dataType = bytesValue.getType();
Bytes saveVal = bytesValue.getValue();
Object showVal;
switch (dataType) {
@@ -125,8 +140,8 @@ public class ClientOperationUtil {
String typeStr = valueObj.getString("type");
String realValBase58 = valueObj.getString("value");
String key = currWriteSetObj.getString("key");
- BytesValueType dataType = BytesValueType.valueOf(typeStr);
- BytesValue bytesValue =BytesValueEntry.fromType(dataType, Base58Utils.decode(realValBase58));
+ DataType dataType = DataType.valueOf(typeStr);
+ BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58));
KVData kvData = new KVData(key, bytesValue, expectedVersion);
kvOperation.set(kvData);
}
@@ -204,7 +219,8 @@ public class ClientOperationUtil {
String contractAddress = contractAddressObj.getString("value");
String argsStr = jsonObject.getString("args");
String event = jsonObject.getString("event");
- return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event, BytesUtils.toBytes(argsStr));
+ return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event,
+ BytesValueEncoding.encodeArray(new Object[]{argsStr}, null));
}
private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) {
@@ -297,4 +313,65 @@ public class ClientOperationUtil {
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;
+ }
+ }
}
\ No newline at end of file
diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java
index e18f1df7..c850b57a 100644
--- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java
+++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java
@@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.*;
import com.jd.blockchain.sdk.BlockchainEventHandle;
import com.jd.blockchain.sdk.BlockchainEventListener;
import com.jd.blockchain.sdk.BlockchainService;
+import com.jd.blockchain.sdk.converters.ClientResolveUtil;
import com.jd.blockchain.transaction.BlockchainQueryService;
import com.jd.blockchain.transaction.TransactionService;
import com.jd.blockchain.transaction.TxTemplate;
@@ -144,17 +145,20 @@ public abstract class BlockchainServiceProxy implements BlockchainService {
@Override
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys) {
- return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys);
+ KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys);
+ return ClientResolveUtil.read(kvDataEntries);
}
@Override
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) {
- return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO);
+ KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO);
+ return ClientResolveUtil.read(kvDataEntries);
}
@Override
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) {
- return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count);
+ KVDataEntry[] kvDataEntries = getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count);
+ return ClientResolveUtil.read(kvDataEntries);
}
@Override
@@ -163,7 +167,7 @@ public abstract class BlockchainServiceProxy implements BlockchainService {
}
@Override
- public AccountHeader getContract(HashDigest ledgerHash, String address) {
+ public ContractInfo getContract(HashDigest ledgerHash, String address) {
return getQueryService(ledgerHash).getContract(ledgerHash, address);
}
diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java
index bd063a5d..838ad829 100644
--- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java
+++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java
@@ -544,7 +544,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService
*/
@HttpAction(method=HttpMethod.GET, path="ledgers/{ledgerHash}/contracts/address/{address}")
@Override
- AccountHeader getContract(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash,
+ ContractInfo getContract(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash,
@PathParam(name="address") String address);
diff --git a/source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientResolveUtil.java b/source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientResolveUtil.java
new file mode 100644
index 00000000..72cd4cb8
--- /dev/null
+++ b/source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientResolveUtil.java
@@ -0,0 +1,385 @@
+///**
+// * Copyright: Copyright 2016-2020 JD.COM All Right Reserved
+// * FileName: com.jd.blockchain.sdk.client.ClientResolveUtil
+// * Author: shaozhuguang
+// * Department: Y事业部
+// * Date: 2019/3/27 下午4:12
+// * Description:
+// */
+//package com.jd.blockchain.sdk.client;
+//
+//import java.lang.reflect.Field;
+//
+//import com.jd.blockchain.ledger.*;
+//import com.jd.blockchain.utils.io.ByteArray;
+//import org.apache.commons.codec.binary.Base64;
+//
+//import com.alibaba.fastjson.JSONArray;
+//import com.alibaba.fastjson.JSONObject;
+//import com.jd.blockchain.crypto.CryptoProvider;
+//import com.jd.blockchain.crypto.PubKey;
+//import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate;
+//import com.jd.blockchain.transaction.ContractEventSendOpTemplate;
+//import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate;
+//import com.jd.blockchain.transaction.DataAccountRegisterOpTemplate;
+//import com.jd.blockchain.transaction.KVData;
+//import com.jd.blockchain.transaction.LedgerInitOpTemplate;
+//import com.jd.blockchain.transaction.LedgerInitSettingData;
+//import com.jd.blockchain.transaction.UserRegisterOpTemplate;
+//import com.jd.blockchain.utils.Bytes;
+//import com.jd.blockchain.utils.codec.Base58Utils;
+//import com.jd.blockchain.utils.codec.HexUtils;
+//import com.jd.blockchain.utils.io.BytesUtils;
+//
+///**
+// *
+// * @author shaozhuguang
+// * @create 2019/3/27
+// * @since 1.0.0
+// */
+//
+//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 tools-initializer
${project.version}
+
+ com.jd.blockchain
+ contract-samples
+ ${project.version}
+
diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContract2.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContract2.java
index 03e6e720..8af3a729 100644
--- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContract2.java
+++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContract2.java
@@ -1,53 +1,53 @@
-package com.jd.blockchain.contract.samples;
-
-import com.jd.blockchain.binaryproto.DataContract;
-import com.jd.blockchain.consts.DataCodes;
-import com.jd.blockchain.contract.Contract;
-import com.jd.blockchain.contract.ContractEvent;
-import com.jd.blockchain.ledger.ContractBizContent;
-import com.jd.blockchain.ledger.TransactionContentBody;
-import com.jd.blockchain.utils.Bytes;
-
-import java.math.BigDecimal;
-
-/**
- * 示例:一个“资产管理”智能合约;
- *
- * @author zhaogw
- */
-@Contract
-public interface AssetContract2 {
-
- /**
- * 发行资产;
- * 新发行的资产数量;
- * @param assetHolderAddress
- * 新发行的资产的持有账户;
- */
- @ContractEvent(name = "issue-asset-0")
- void issue(ContractBizContent contractBizContent, String assetHolderAddress);
-
- /**
- * issue asset;
- * @param contractBizContent
- * @param assetHolderAddress
- * @param cashNumber
- */
- @ContractEvent(name = "issue-asset")
- public void issue(ContractBizContent contractBizContent, String assetHolderAddress, long cashNumber);
-
- /**
- * Bytes can bring the byte[];
- * @param bytes
- * @param assetHolderAddress
- * @param cashNumber
- */
- @ContractEvent(name = "issue-asset-2")
- void issue(Bytes bytes,String assetHolderAddress, long cashNumber);
-
- @ContractEvent(name = "issue-asset-3")
- void issue(Byte bytes, String assetHolderAddress, long cashNumber);
-
- @ContractEvent(name = "issue-asset-4")
- void issue(Byte byteObj, String assetHolderAddress, Bytes cashNumber);
-}
\ No newline at end of file
+//package com.jd.blockchain.contract.samples;
+//
+//import com.jd.blockchain.binaryproto.DataContract;
+//import com.jd.blockchain.consts.DataCodes;
+//import com.jd.blockchain.contract.Contract;
+//import com.jd.blockchain.contract.ContractEvent;
+//import com.jd.blockchain.ledger.ContractBizContent;
+//import com.jd.blockchain.ledger.TransactionContentBody;
+//import com.jd.blockchain.utils.Bytes;
+//
+//import java.math.BigDecimal;
+//
+///**
+// * 示例:一个“资产管理”智能合约;
+// *
+// * @author zhaogw
+// */
+//@Contract
+//public interface AssetContract2 {
+//
+// /**
+// * 发行资产;
+// * 新发行的资产数量;
+// * @param assetHolderAddress
+// * 新发行的资产的持有账户;
+// */
+// @ContractEvent(name = "issue-asset-0")
+// void issue(ContractBizContent contractBizContent, String assetHolderAddress);
+//
+// /**
+// * issue asset;
+// * @param contractBizContent
+// * @param assetHolderAddress
+// * @param cashNumber
+// */
+// @ContractEvent(name = "issue-asset")
+// public void issue(ContractBizContent contractBizContent, String assetHolderAddress, long cashNumber);
+//
+// /**
+// * Bytes can bring the byte[];
+// * @param bytes
+// * @param assetHolderAddress
+// * @param cashNumber
+// */
+// @ContractEvent(name = "issue-asset-2")
+// void issue(Bytes bytes,String assetHolderAddress, long cashNumber);
+//
+// @ContractEvent(name = "issue-asset-3")
+// void issue(Byte bytes, String assetHolderAddress, long cashNumber);
+//
+// @ContractEvent(name = "issue-asset-4")
+// void issue(Byte byteObj, String assetHolderAddress, Bytes cashNumber);
+//}
\ No newline at end of file
diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java
index 770f78c4..02258ed2 100644
--- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java
+++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java
@@ -6,7 +6,7 @@ import java.util.Set;
import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.ContractException;
-import com.jd.blockchain.contract.EventProcessingAwire;
+import com.jd.blockchain.contract.EventProcessingAware;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.KVDataEntry;
@@ -21,7 +21,7 @@ import com.jd.blockchain.ledger.KVDataObject;
* @author huanghaiquan
*
*/
-public class AssetContractImpl implements EventProcessingAwire, AssetContract {
+public class AssetContractImpl implements EventProcessingAware, AssetContract {
// 资产管理账户的地址;
private static final String ASSET_ADDRESS = "2njZBNbFQcmKd385DxVejwSjy4driRzf9Pk";
// 保存资产总数的键;
@@ -171,17 +171,7 @@ public class AssetContractImpl implements EventProcessingAwire, AssetContract {
* com.jd.blockchain.contract.model.ContractError)
*/
@Override
- public void postEvent(ContractEventContext eventContext, ContractException error) {
+ public void postEvent(ContractEventContext eventContext, Exception error) {
this.eventContext = null;
}
-
- @Override
- public void postEvent(ContractException error) {
-
- }
-
- @Override
- public void postEvent() {
-
- }
}
diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Constant.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Constant.java
new file mode 100644
index 00000000..aa5ac2f7
--- /dev/null
+++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Constant.java
@@ -0,0 +1,38 @@
+package com.jd.blockchain.sdk.samples;
+
+import org.apache.commons.io.FileUtils;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.File;
+
+public class SDKDemo_Constant {
+
+ public static final String GW_IPADDR = "127.0.0.1";
+
+ public static final int GW_PORT = 11000;
+
+ public static final String[] PUB_KEYS = {
+ "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9",
+ "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX",
+ "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x",
+ "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk"};
+
+ public static final String[] PRIV_KEYS = {
+ "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x",
+ "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT",
+ "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF",
+ "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns"};
+
+ public static final String PASSWORD = "abc";
+
+ public static final byte[] readChainCodes(String contractZip) {
+ // 构建合约的字节数组;
+ try {
+ ClassPathResource contractPath = new ClassPathResource(contractZip);
+ File contractFile = new File(contractPath.getURI());
+ return FileUtils.readFileToByteArray(contractFile);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Base_Demo.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Base_Demo.java
new file mode 100644
index 00000000..bbd4ed71
--- /dev/null
+++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Base_Demo.java
@@ -0,0 +1,51 @@
+package com.jd.blockchain.sdk.samples;
+
+import com.jd.blockchain.crypto.HashDigest;
+import com.jd.blockchain.crypto.PrivKey;
+import com.jd.blockchain.crypto.PubKey;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionTemplate;
+import com.jd.blockchain.sdk.BlockchainService;
+import com.jd.blockchain.sdk.client.GatewayServiceFactory;
+import com.jd.blockchain.tools.keygen.KeyGenCommand;
+
+public abstract class SDK_Base_Demo {
+
+ protected BlockchainKeypair adminKey;
+
+ protected HashDigest ledgerHash;
+
+ protected BlockchainService blockchainService;
+
+ public SDK_Base_Demo() {
+ init();
+ }
+
+ public void init() {
+ // 生成连接网关的账号
+ PrivKey privKey = KeyGenCommand.decodePrivKeyWithRawPassword(SDKDemo_Constant.PRIV_KEYS[0], SDKDemo_Constant.PASSWORD);
+
+ PubKey pubKey = KeyGenCommand.decodePubKey(SDKDemo_Constant.PUB_KEYS[0]);
+
+ adminKey = new BlockchainKeypair(pubKey, privKey);
+
+ // 连接网关
+ GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(SDKDemo_Constant.GW_IPADDR,
+ SDKDemo_Constant.GW_PORT, false, adminKey);
+
+ // 获取网关对应的Service处理类
+ blockchainService = serviceFactory.getBlockchainService();
+
+ HashDigest[] ledgerHashs = blockchainService.getLedgerHashs();
+ // 获取当前账本Hash
+ ledgerHash = ledgerHashs[0];
+ }
+
+ public TransactionResponse commit(TransactionTemplate txTpl) {
+ PreparedTransaction ptx = txTpl.prepare();
+ ptx.sign(adminKey);
+ return ptx.commit();
+ }
+}
diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java
new file mode 100644
index 00000000..9d43b199
--- /dev/null
+++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java
@@ -0,0 +1,156 @@
+package com.jd.blockchain.sdk.samples;
+
+import static com.jd.blockchain.sdk.samples.SDKDemo_Constant.readChainCodes;
+import static com.jd.blockchain.transaction.ContractReturnValue.decode;
+
+import com.jd.blockchain.contract.TransferContract;
+import com.jd.blockchain.ledger.BlockchainKeyGenerator;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.KVDataEntry;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionTemplate;
+import com.jd.blockchain.transaction.LongValueHolder;
+import com.jd.blockchain.transaction.GenericValueHolder;
+import com.jd.blockchain.utils.Bytes;
+
+public class SDK_Contract_Demo extends SDK_Base_Demo {
+
+ public static void main(String[] args) {
+ new SDK_Contract_Demo().executeContract();
+ }
+
+ public void executeContract() {
+
+ // 发布jar包
+ // 定义交易模板
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+
+ // 将jar包转换为二进制数据
+ byte[] contractCode = readChainCodes("transfer.jar");
+
+ // 生成一个合约账号
+ BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate();
+
+ // 生成发布合约操作
+ txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode);
+
+ // 生成预发布交易;
+ PreparedTransaction ptx = txTpl.prepare();
+
+ // 对交易进行签名
+ ptx.sign(adminKey);
+
+ // 提交并等待共识返回;
+ TransactionResponse txResp = ptx.commit();
+
+ // 获取合约地址
+ Bytes contractAddress = contractDeployKey.getAddress();
+
+ // 打印交易返回信息
+ System.out.printf("Tx[%s] -> BlockHeight = %s, BlockHash = %s, isSuccess = %s, ExecutionState = %s \r\n",
+ txResp.getContentHash().toBase58(), txResp.getBlockHeight(), txResp.getBlockHash().toBase58(),
+ txResp.isSuccess(), txResp.getExecutionState());
+
+ // 打印合约地址
+ System.out.printf("ContractAddress = %s \r\n", contractAddress.toBase58());
+
+ // 注册一个数据账户
+ BlockchainKeypair dataAccount = createDataAccount();
+ // 获取数据账户地址
+ String dataAddress = dataAccount.getAddress().toBase58();
+ // 打印数据账户地址
+ System.out.printf("DataAccountAddress = %s \r\n", dataAddress);
+
+ // 创建两个账号:
+ String account0 = "jd_zhangsan", account1 = "jd_lisi";
+ long account0Money = 3000L, account1Money = 2000L;
+ // 创建两个账户
+ // 使用KV操作创建一个账户
+ System.out.println(create(dataAddress, account0, account0Money, false, null));
+ // 使用合约创建一个账户
+ System.out.println(create(dataAddress, account1, account1Money, true, contractAddress));
+
+ // 转账,使得双方钱达到一致
+ System.out.println(transfer(dataAddress, account0, account1, 500L, contractAddress));
+
+ // 通过合约读取account0的当前信息
+ System.out.printf("Read DataAccountAddress[%s] Account = %s 's money = %s (By Contract)\r\n", dataAddress,
+ account0, readByContract(dataAddress, account0, contractAddress));
+ // 通过KV读取account1的当前信息
+ System.out.printf("Read DataAccountAddress[%s] Account = %s 's money = %s (By KV Operation)\r\n", dataAddress,
+ account1, readByKvOperation(dataAddress, account1));
+
+ // 通过合约读取account0的历史信息
+ System.out.println(readAll(dataAddress, account0, contractAddress));
+ // 通过合约读取account1的历史信息
+ System.out.println(readAll(dataAddress, account1, contractAddress));
+ }
+
+ private String readAll(String address, String account, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.readAll(address, account));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private long readByContract(String address, String account, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ LongValueHolder result = decode(transferContract.read(address, account));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private long readByKvOperation(String address, String account) {
+ KVDataEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, address, account);
+ if (kvDataEntries == null || kvDataEntries.length == 0) {
+ throw new IllegalStateException(String.format("Ledger %s Service inner Error !!!", ledgerHash.toBase58()));
+ }
+ KVDataEntry kvDataEntry = kvDataEntries[0];
+ if (kvDataEntry.getVersion() == -1) {
+ return 0L;
+ }
+ return (long) (kvDataEntry.getValue());
+ }
+
+ private String transfer(String address, String from, String to, long money, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.transfer(address, from, to, money));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private BlockchainKeypair createDataAccount() {
+ // 首先注册一个数据账户
+ BlockchainKeypair newDataAccount = BlockchainKeyGenerator.getInstance().generate();
+
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ txTpl.dataAccounts().register(newDataAccount.getIdentity());
+ commit(txTpl);
+ return newDataAccount;
+ }
+
+ private String create(String address, String account, long money, boolean useContract, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ if (useContract) {
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.create(address, account, money));
+ commit(txTpl);
+ return result.get();
+ } else {
+ // 通过KV创建
+ txTpl.dataAccount(address).setInt64(account, money, -1);
+ TransactionResponse txResp = commit(txTpl);
+ return String.format(
+ "DataAccountAddress[%s] -> Create(By KV Operation) Account = %s and Money = %s Success!!! \r\n",
+ address, account, money);
+ }
+ }
+}
diff --git a/source/sdk/sdk-samples/src/main/resources/transfer.jar b/source/sdk/sdk-samples/src/main/resources/transfer.jar
new file mode 100644
index 00000000..a161392e
Binary files /dev/null and b/source/sdk/sdk-samples/src/main/resources/transfer.jar differ
diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDKDemo_Contract_Test_.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDKDemo_Contract_Test_.java
new file mode 100644
index 00000000..2f7755da
--- /dev/null
+++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDKDemo_Contract_Test_.java
@@ -0,0 +1,165 @@
+package test.com.jd.blockchain.sdk.test;
+
+import static com.jd.blockchain.sdk.samples.SDKDemo_Constant.readChainCodes;
+import static com.jd.blockchain.transaction.ContractReturnValue.decode;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jd.blockchain.contract.TransferContract;
+import com.jd.blockchain.crypto.HashDigest;
+import com.jd.blockchain.crypto.PrivKey;
+import com.jd.blockchain.crypto.PubKey;
+import com.jd.blockchain.ledger.BlockchainKeyGenerator;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionTemplate;
+import com.jd.blockchain.sdk.BlockchainService;
+import com.jd.blockchain.sdk.client.GatewayServiceFactory;
+import com.jd.blockchain.sdk.samples.SDKDemo_Constant;
+import com.jd.blockchain.tools.keygen.KeyGenCommand;
+import com.jd.blockchain.transaction.LongValueHolder;
+import com.jd.blockchain.transaction.GenericValueHolder;
+import com.jd.blockchain.utils.Bytes;
+
+public class SDKDemo_Contract_Test_ {
+
+ private BlockchainKeypair adminKey;
+
+ private HashDigest ledgerHash;
+
+ private BlockchainService blockchainService;
+
+ @Before
+ public void init() {
+ // 生成连接网关的账号
+ PrivKey privKey = KeyGenCommand.decodePrivKeyWithRawPassword(SDKDemo_Constant.PRIV_KEYS[0],
+ SDKDemo_Constant.PASSWORD);
+
+ PubKey pubKey = KeyGenCommand.decodePubKey(SDKDemo_Constant.PUB_KEYS[0]);
+
+ adminKey = new BlockchainKeypair(pubKey, privKey);
+
+ // 连接网关
+ GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(SDKDemo_Constant.GW_IPADDR,
+ SDKDemo_Constant.GW_PORT, false, adminKey);
+
+ blockchainService = serviceFactory.getBlockchainService();
+
+ HashDigest[] ledgerHashs = blockchainService.getLedgerHashs();
+
+ ledgerHash = ledgerHashs[0];
+ }
+
+ @Test
+ public void testContract() {
+
+ // 发布jar包
+ // 定义交易;
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+
+ byte[] contractCode = readChainCodes("transfer.jar");
+
+ // 生成一个合约账号
+ BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate();
+
+ txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode);
+
+ // 签名;
+ PreparedTransaction ptx = txTpl.prepare();
+
+ ptx.sign(adminKey);
+
+ // 提交并等待共识返回;
+ TransactionResponse txResp = ptx.commit();
+
+ System.out.println(txResp.isSuccess());
+
+ // 首先注册一个数据账户
+ BlockchainKeypair dataAccount = createDataAccount();
+
+ String dataAddress = dataAccount.getAddress().toBase58();
+
+ Bytes contractAddress = contractDeployKey.getAddress();
+
+ // 创建两个账号:
+ String account0 = "jd_zhangsan", account1 = "jd_lisi";
+ long account0Money = 3000L, account1Money = 2000L;
+ // 创建两个账户
+ // 使用KV创建一个账户
+ System.out.println(create(dataAddress, account0, account0Money, false, null));
+ // 使用合约创建一个账户
+ System.out.println(create(dataAddress, account1, account1Money, true, contractAddress));
+
+ // 转账,使得双方钱达到一致
+ System.out.println(transfer(dataAddress, account0, account1, 500L, contractAddress));
+
+ // 读取当前结果
+ System.out.println(read(dataAddress, account0, contractAddress));
+ System.out.println(read(dataAddress, account1, contractAddress));
+
+ // 读取账号历史信息
+ System.out.println(readAll(dataAddress, account0, contractAddress));
+ System.out.println(readAll(dataAddress, account1, contractAddress));
+ }
+
+ private String readAll(String address, String account, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.readAll(address, account));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private long read(String address, String account, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ LongValueHolder result = decode(transferContract.read(address, account));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private String transfer(String address, String from, String to, long money, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.transfer(address, from, to, money));
+ commit(txTpl);
+ return result.get();
+ }
+
+ private BlockchainKeypair createDataAccount() {
+ // 首先注册一个数据账户
+ BlockchainKeypair newDataAccount = BlockchainKeyGenerator.getInstance().generate();
+
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ txTpl.dataAccounts().register(newDataAccount.getIdentity());
+ commit(txTpl);
+ return newDataAccount;
+ }
+
+ private String create(String address, String account, long money, boolean useContract, Bytes contractAddress) {
+ TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ if (useContract) {
+ // 使用合约创建
+ TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
+ GenericValueHolder result = decode(transferContract.create(address, account, money));
+ commit(txTpl);
+ return result.get();
+ } else {
+ // 通过KV创建
+ txTpl.dataAccount(address).setInt64(account, money, -1);
+ TransactionResponse txResp = commit(txTpl);
+ return account + money;
+ }
+ }
+
+ private TransactionResponse commit(TransactionTemplate txTpl) {
+ PreparedTransaction ptx = txTpl.prepare();
+ ptx.sign(adminKey);
+ return ptx.commit();
+ }
+}
diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java
index 608c3788..244d8071 100644
--- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java
+++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java
@@ -1,10 +1,29 @@
package test.com.jd.blockchain.sdk.test;
-import com.jd.blockchain.binaryproto.BinaryProtocol;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+
import com.jd.blockchain.contract.samples.AssetContract;
-import com.jd.blockchain.contract.samples.AssetContract2;
-import com.jd.blockchain.crypto.*;
-import com.jd.blockchain.ledger.*;
+import com.jd.blockchain.crypto.AsymmetricKeypair;
+import com.jd.blockchain.crypto.Crypto;
+import com.jd.blockchain.crypto.HashDigest;
+import com.jd.blockchain.crypto.PrivKey;
+import com.jd.blockchain.crypto.PubKey;
+import com.jd.blockchain.crypto.SignatureFunction;
+import com.jd.blockchain.ledger.BlockchainIdentity;
+import com.jd.blockchain.ledger.BlockchainKeyGenerator;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.client.GatewayServiceFactory;
import com.jd.blockchain.sdk.samples.SDKDemo_Contract;
@@ -13,19 +32,6 @@ import com.jd.blockchain.utils.codec.Base58Utils;
import com.jd.blockchain.utils.io.ByteArray;
import com.jd.blockchain.utils.net.NetworkAddress;
import com.jd.blockchain.utils.serialize.json.JSONSerializeUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.util.ReflectionUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.reflect.Method;
-
-import static org.junit.Assert.*;
/**
* 演示合约执行的过程;
@@ -62,63 +68,63 @@ public class SDK_Contract_Test {
bcsrv = serviceFactory.getBlockchainService();
}
- /**
- * 演示合约执行的过程;
- */
-// @Test
- public void demoContract1() {
- String dataAddress = registerData4Contract();
- // 发起交易;
- TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash);
- String contractAddress = "LdeNg8JHFCKABJt6AaRNVCZPgY4ofGPd8MgcR";
- AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class);
-// assetContract.issue(transactionContentBody,contractAddress);
-// assetContract.issue(transactionContentBody,contractAddress,888888);
-// assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777);
-// assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777);
- Byte byteObj = Byte.parseByte("127");
- assetContract.issue(byteObj,dataAddress,321123);
-// assetContract.issue(contractBizContent,dataAddress);
- assetContract.issue(Byte.parseByte("126"),dataAddress,Bytes.fromString("100.234"));
-
- // TX 准备就绪;
- PreparedTransaction prepTx = txTemp.prepare();
- prepTx.sign(signKeyPair);
- // 提交交易;
- TransactionResponse transactionResponse = prepTx.commit();
-
- //check;
- KVDataEntry[] dataEntries = bcsrv.getDataEntries(ledgerHash,dataAddress,"total");
- assertEquals("100",dataEntries[0].getValue().toString());
- }
-
- /**
- * 演示合约执行的过程;
- */
-// @Test
- public void demoContract2() throws IOException {
- String contractAddress = deploy();
- String dataAddress = registerData4Contract();
- System.out.println("dataAddress="+dataAddress);
- // 发起交易;
- TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash);
-
- AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class);
- ContractBizContent contractBizContent = () -> new String[]{"param1","param2"};
- assetContract.issue(contractBizContent,dataAddress,123456);
-
- // TX 准备就绪;
- PreparedTransaction prepTx = txTemp.prepare();
- prepTx.sign(signKeyPair);
- // 提交交易;
- TransactionResponse transactionResponse = prepTx.commit();
-
- //check;
- assertTrue(transactionResponse.isSuccess());
- KVDataEntry[] dataEntries = bcsrv.getDataEntries(ledgerHash,dataAddress,contractBizContent.getAttrs()[0],contractBizContent.getAttrs()[1]);
- assertEquals("value1",dataEntries[0].getValue().toString());
- assertEquals(888,dataEntries[1].getValue());
- }
+// /**
+// * 演示合约执行的过程;
+// */
+//// @Test
+// public void demoContract1() {
+// String dataAddress = registerData4Contract();
+// // 发起交易;
+// TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash);
+// String contractAddress = "LdeNg8JHFCKABJt6AaRNVCZPgY4ofGPd8MgcR";
+// AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class);
+//// assetContract.issue(transactionContentBody,contractAddress);
+//// assetContract.issue(transactionContentBody,contractAddress,888888);
+//// assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777);
+//// assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777);
+// Byte byteObj = Byte.parseByte("127");
+// assetContract.issue(byteObj,dataAddress,321123);
+//// assetContract.issue(contractBizContent,dataAddress);
+// assetContract.issue(Byte.parseByte("126"),dataAddress,Bytes.fromString("100.234"));
+//
+// // TX 准备就绪;
+// PreparedTransaction prepTx = txTemp.prepare();
+// prepTx.sign(signKeyPair);
+// // 提交交易;
+// TransactionResponse transactionResponse = prepTx.commit();
+//
+// //check;
+// KVDataEntry[] dataEntries = bcsrv.getDataEntries(ledgerHash,dataAddress,"total");
+// assertEquals("100",dataEntries[0].getValue().toString());
+// }
+
+// /**
+// * 演示合约执行的过程;
+// */
+//// @Test
+// public void demoContract2() throws IOException {
+// String contractAddress = deploy();
+// String dataAddress = registerData4Contract();
+// System.out.println("dataAddress="+dataAddress);
+// // 发起交易;
+// TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash);
+//
+// AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class);
+// ContractBizContent contractBizContent = () -> new String[]{"param1","param2"};
+// assetContract.issue(contractBizContent,dataAddress,123456);
+//
+// // TX 准备就绪;
+// PreparedTransaction prepTx = txTemp.prepare();
+// prepTx.sign(signKeyPair);
+// // 提交交易;
+// TransactionResponse transactionResponse = prepTx.commit();
+//
+// //check;
+// assertTrue(transactionResponse.isSuccess());
+// KVDataEntry[] dataEntries = bcsrv.getDataEntries(ledgerHash,dataAddress,contractBizContent.getAttrs()[0],contractBizContent.getAttrs()[1]);
+// assertEquals("value1",dataEntries[0].getValue().toString());
+// assertEquals(888,dataEntries[1].getValue());
+// }
// @Test
public void registerData(){
@@ -346,31 +352,31 @@ public class SDK_Contract_Test {
}
- @Test
- public void testStringArr(){
- ContractBizContent contractBizContent = () -> new String[]{"1","2","you are welcome!"};
- byte[] bizBytes = BinaryProtocol.encode(contractBizContent,ContractBizContent.class);
- ContractBizContent actualObj = BinaryProtocol.decodeAs(bizBytes,ContractBizContent.class);
- assertArrayEquals(contractBizContent.getAttrs(),actualObj.getAttrs());
- }
-
- @Test
- public void testContractArgs(){
- ContractBizContent contractBizContent = () -> new String[]{"param1"};
- Method method = ReflectionUtils.findMethod(AssetContract2.class,"issue",ContractBizContent.class,String.class);
- ContractArgs contractArgs = new ContractArgs() {
- @Override
- public Method getMethod() {
- return method;
- }
-
- @Override
- public Object[] getArgs() {
- return new Object[]{contractBizContent,"hello"};
- }
- };
-
- //add the annotation;
+// @Test
+// public void testStringArr(){
+// ContractBizContent contractBizContent = () -> new String[]{"1","2","you are welcome!"};
+// byte[] bizBytes = BinaryProtocol.encode(contractBizContent,ContractBizContent.class);
+// ContractBizContent actualObj = BinaryProtocol.decodeAs(bizBytes,ContractBizContent.class);
+// assertArrayEquals(contractBizContent.getAttrs(),actualObj.getAttrs());
+// }
- }
+// @Test
+// public void testContractArgs(){
+// ContractBizContent contractBizContent = () -> new String[]{"param1"};
+// Method method = ReflectionUtils.findMethod(AssetContract2.class,"issue",ContractBizContent.class,String.class);
+// ContractArgs contractArgs = new ContractArgs() {
+// @Override
+// public Method getMethod() {
+// return method;
+// }
+//
+// @Override
+// public Object[] getArgs() {
+// return new Object[]{contractBizContent,"hello"};
+// }
+// };
+//
+// //add the annotation;
+//
+// }
}
diff --git a/source/sdk/sdk-samples/src/test/resources/transfer.jar b/source/sdk/sdk-samples/src/test/resources/transfer.jar
new file mode 100644
index 00000000..a161392e
Binary files /dev/null and b/source/sdk/sdk-samples/src/test/resources/transfer.jar differ
diff --git a/source/storage/storage-composite/src/main/java/com/jd/blockchain/storage/service/impl/composite/CompositeConnectionFactory.java b/source/storage/storage-composite/src/main/java/com/jd/blockchain/storage/service/impl/composite/CompositeConnectionFactory.java
index 96a5d6b8..ed1633c6 100644
--- a/source/storage/storage-composite/src/main/java/com/jd/blockchain/storage/service/impl/composite/CompositeConnectionFactory.java
+++ b/source/storage/storage-composite/src/main/java/com/jd/blockchain/storage/service/impl/composite/CompositeConnectionFactory.java
@@ -42,7 +42,7 @@ public class CompositeConnectionFactory implements DbConnectionFactory {
connectionFactoryMap.put(dbPrefix, dbConnectionFactory);
}
} catch (Exception e) {
- LOGGER.error("class:{%s} init error {%s}", clazz.getName(), e.getMessage());
+ LOGGER.error("class:{} init error {}", clazz.getName(), e.getMessage());
}
}
}
diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java
index 1e318f97..25a40ad0 100644
--- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java
+++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/LedgerPerformanceTest.java
@@ -10,20 +10,18 @@ import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.DoubleStream;
+import com.jd.blockchain.crypto.*;
+import com.jd.blockchain.ledger.core.CryptoConfig;
import org.springframework.core.io.ClassPathResource;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusProviders;
import com.jd.blockchain.consensus.ConsensusSettings;
-import com.jd.blockchain.crypto.AsymmetricKeypair;
-import com.jd.blockchain.crypto.Crypto;
-import com.jd.blockchain.crypto.CryptoAlgorithm;
-import com.jd.blockchain.crypto.HashDigest;
-import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.BytesDataList;
import com.jd.blockchain.ledger.DataAccountKVSetOperation;
import com.jd.blockchain.ledger.DataAccountRegisterOperation;
import com.jd.blockchain.ledger.LedgerBlock;
@@ -143,8 +141,9 @@ public class LedgerPerformanceTest {
batchCount = Integer.parseInt(args[1]);
}
}
- if (contract){
- testContract(ledgerHash, testNode.getPartiKey(), ledgerManager, opHandler, batchSize, batchCount, silent);
+ if (contract) {
+ testContract(ledgerHash, testNode.getPartiKey(), ledgerManager, opHandler, batchSize, batchCount,
+ silent);
}
if (usertest) {
@@ -177,8 +176,9 @@ public class LedgerPerformanceTest {
* @param batchCount
* @param silent
*/
- private static void testUserRegistering(HashDigest ledgerHash, AsymmetricKeypair adminKey, LedgerManager ledgerManager,
- DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, boolean silent) {
+ private static void testUserRegistering(HashDigest ledgerHash, AsymmetricKeypair adminKey,
+ LedgerManager ledgerManager, DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount,
+ boolean silent) {
LedgerRepository ledger = ledgerManager.getLedger(ledgerHash);
ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [注册用户] =================");
@@ -273,7 +273,7 @@ public class LedgerPerformanceTest {
* @param silent
*/
private static void testContract(HashDigest ledgerHash, AsymmetricKeypair adminKey, LedgerManager ledgerManager,
- DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, boolean silent) {
+ DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, boolean silent) {
LedgerRepository ledger = ledgerManager.getLedger(ledgerHash);
ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [执行合约] =================");
@@ -285,8 +285,8 @@ public class LedgerPerformanceTest {
// 准备请求
int totalCount = batchSize * batchCount;
- List contractTxList = prepareContractRequests(ledgerHash,
- adminKey, totalCount, false, txProc);
+ List contractTxList = prepareContractRequests(ledgerHash, adminKey, totalCount, false,
+ txProc);
Prompter consolePrompter = new PresetAnswerPrompter("N");
@@ -303,6 +303,7 @@ public class LedgerPerformanceTest {
}
}
+
private static void execPerformanceTest(int batchCount, int batchSize, List txList,
LedgerRepository ledger, LedgerManager ledgerManager, DefaultOperationHandleRegisteration opHandler,
boolean statistic) {
@@ -407,8 +408,7 @@ public class LedgerPerformanceTest {
// BlockchainKeyPair dataAccountKey =
// BlockchainKeyGenerator.getInstance().generate();
BlockchainIdentity targetAccount = dataAccounts[count % dataAccounts.length];
- txbuilder.dataAccount(targetAccount.getAddress()).setText("key-" + startTs + "-" + i,
- "value-" + i, -1L);
+ txbuilder.dataAccount(targetAccount.getAddress()).setText("key-" + startTs + "-" + i, "value-" + i, -1L);
TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest();
reqBuilder.signAsEndpoint(adminKey);
txList.add(reqBuilder.buildRequest());
@@ -426,8 +426,9 @@ public class LedgerPerformanceTest {
public static ConsensusProvider getConsensusProvider(String provider) {
return ConsensusProviders.getProvider(provider);
}
- public static List prepareContractRequests(HashDigest ledgerHash,
- AsymmetricKeypair adminKey, int count, boolean statistic, TransactionBatchProcessor txProc) {
+
+ public static List prepareContractRequests(HashDigest ledgerHash, AsymmetricKeypair adminKey,
+ int count, boolean statistic, TransactionBatchProcessor txProc) {
// deploy contract
byte[] chainCode;
@@ -436,7 +437,7 @@ public class LedgerPerformanceTest {
InputStream input = LedgerPerformanceTest.class.getClassLoader().getResourceAsStream("example1.jar");
chainCode = new byte[input.available()];
input.read(chainCode);
- }catch (IOException e){
+ } catch (IOException e) {
e.printStackTrace();
return null;
}
@@ -457,10 +458,10 @@ public class LedgerPerformanceTest {
System.out.println(resp.isSuccess());
TransactionBatchResultHandle handle = txProc.prepare();
handle.commit();
- try{
+ try {
Thread.sleep(1000);
- } catch (Exception e){
+ } catch (Exception e) {
e.printStackTrace();
}
@@ -468,8 +469,9 @@ public class LedgerPerformanceTest {
List txList = new ArrayList<>();
for (int i = 0; i < count; i++) {
txbuilder = new TxBuilder(ledgerHash);
- String args = dataIdentity.getAddress().toString() + "##"+Integer.toString(i)+ "##"+Integer.toString(i);
- txbuilder.contractEvents().send(contractIdentity.getAddress(), "hello", args.getBytes());
+ String args = dataIdentity.getAddress().toString() + "##" + Integer.toString(i) + "##"
+ + Integer.toString(i);
+ txbuilder.contractEvents().send(contractIdentity.getAddress(), "print", BytesDataList.singleText("hello"));
// txbuilder.contractEvents().send(contractIdentity.getAddress(), "print", args.getBytes());
reqBuilder = txbuilder.prepareRequest();
reqBuilder.signAsEndpoint(adminKey);
@@ -485,7 +487,8 @@ public class LedgerPerformanceTest {
return txList;
}
- public static NodeContext[] initLedgers(boolean optimized, CryptoAlgorithm hashAlg, DBType dbType, String provider, String config) {
+ public static NodeContext[] initLedgers(boolean optimized, CryptoAlgorithm hashAlg, DBType dbType, String provider,
+ String config) {
Map serviceRegisterMap = new ConcurrentHashMap<>();
Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter();
diff --git a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java
index 33d494a3..b5bcd809 100644
--- a/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java
+++ b/source/test/test-integration/src/main/java/test/com/jd/blockchain/intgr/perf/Utils.java
@@ -6,16 +6,13 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
+import com.jd.blockchain.crypto.*;
+import com.jd.blockchain.crypto.service.classic.ClassicCryptoService;
+import com.jd.blockchain.crypto.service.sm.SMCryptoService;
import org.springframework.core.io.ClassPathResource;
import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusSettings;
-import com.jd.blockchain.crypto.CryptoAlgorithm;
-import com.jd.blockchain.crypto.AsymmetricKeypair;
-import com.jd.blockchain.crypto.Crypto;
-import com.jd.blockchain.crypto.HashDigest;
-import com.jd.blockchain.crypto.PrivKey;
-import com.jd.blockchain.crypto.SignatureDigest;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.ledger.core.CryptoConfig;
import com.jd.blockchain.ledger.core.LedgerInitDecision;
@@ -39,16 +36,20 @@ public class Utils {
public static final String PASSWORD = "abc";
- public static final String[] PUB_KEYS = { "3snPdw7i7PapsDoW185c3kfK6p8s6SwiJAdEUzgnfeuUox12nxgzXu",
- "3snPdw7i7Ph1SYLQt9uqVEqiuvNXjxCdGvEdN6otJsg5rbr7Aze7kf",
- "3snPdw7i7PezptA6dNBkotPjmKEbTkY8fmusLBnfj8Cf7eFwhWDwKr",
- "3snPdw7i7PerZYfRzEB61SAN9tFK4yHm9wUSRtkLSSGXHkQRbB5PkS" };
+ public static final String[] PUB_KEYS = {
+ "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9",
+ "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX",
+ "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x",
+ "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" };
public static final String[] PRIV_KEYS = {
- "177gjyoEUhdD1NkQSxBVvfSyovMd1ha5H46zsb9kyErLNBuQkLRAf2ea6CNjStjCFJQN8S1",
- "177gjsa6KcyxUpx7T3tvCVMuqHvvguiQFRLmDY9jaMcH6L9R4k7XgANLfY3paC5XaXeASej",
- "177gju7AgXp371qqprjEN3Lg4Hc4EWHnDH9eWgTttEUoN8PuNpQTbS253uTxdKn5w1zZXUp",
- "177gjtddYr7CtN6iN6KRgu1kKzFn6quQsx3DQLnUD1xgj5E2QhUTMDnpZKzSKbB7kt35gzj" };
+ "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x",
+ "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT",
+ "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF",
+ "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" };
+
+ private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(),
+ SMCryptoService.class.getName() };
private Map serviceRegisterMap = new ConcurrentHashMap<>();
@@ -131,7 +132,14 @@ public class Utils {
public AsyncCallback startInit(int currentId, PrivKey privKey, LedgerInitProperties setting,
ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig,
Prompter prompter, boolean autoVerifyHash, CryptoAlgorithm hashAlg) {
+
+ CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
+ for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
+ supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
+ }
CryptoConfig cryptoSetting = new CryptoConfig();
+ cryptoSetting.setSupportedProviders(supportedProviders);
+ cryptoSetting.setSupportedProviders(supportedProviders);
cryptoSetting.setAutoVerifyHash(autoVerifyHash);
cryptoSetting.setHashAlgorithm(hashAlg);
diff --git a/source/test/test-integration/src/main/resources/ledger_init_test_web2.init b/source/test/test-integration/src/main/resources/ledger_init_test_web2.init
index 888d5e61..5d64bdb6 100644
--- a/source/test/test-integration/src/main/resources/ledger_init_test_web2.init
+++ b/source/test/test-integration/src/main/resources/ledger_init_test_web2.init
@@ -4,6 +4,17 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途;
#ledger.name=
+#共识服务提供者;必须;
+consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider
+
+#共识服务的参数配置;必须;
+consensus.conf=classpath:bftsmart.config
+
+#密码服务提供者列表,以英文逗点“,”分隔;必须;
+crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \
+com.jd.blockchain.crypto.service.sm.SMCryptoService
+
+
#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置;
cons_parti.count=4
@@ -12,7 +23,7 @@ cons_parti.0.name=jd.com
#第0个参与方的公钥文件路径;
cons_parti.0.pubkey-path=keys/jd-com.pub
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
-cons_parti.0.pubkey=3snPdw7i7PapsDoW185c3kfK6p8s6SwiJAdEUzgnfeuUox12nxgzXu
+cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9
#第0个参与方的账本初始服务的主机;
cons_parti.0.initializer.host=127.0.0.1
#第0个参与方的账本初始服务的端口;
@@ -25,7 +36,7 @@ cons_parti.1.name=at.com
#第1个参与方的公钥文件路径;
cons_parti.1.pubkey-path=keys/at-com.pub
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
-cons_parti.1.pubkey=3snPdw7i7Ph1SYLQt9uqVEqiuvNXjxCdGvEdN6otJsg5rbr7Aze7kf
+cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX
#第1个参与方的账本初始服务的主机;
cons_parti.1.initializer.host=127.0.0.1
#第1个参与方的账本初始服务的端口;
@@ -38,7 +49,7 @@ cons_parti.2.name=bt.com
#第2个参与方的公钥文件路径;
cons_parti.2.pubkey-path=keys/bt-com.pub
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
-cons_parti.2.pubkey=3snPdw7i7PezptA6dNBkotPjmKEbTkY8fmusLBnfj8Cf7eFwhWDwKr
+cons_parti.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x
#第2个参与方的账本初始服务的主机;
cons_parti.2.initializer.host=127.0.0.1
#第2个参与方的账本初始服务的端口;
@@ -51,7 +62,7 @@ cons_parti.3.name=xt.com
#第3个参与方的公钥文件路径;
cons_parti.3.pubkey-path=keys/xt-com.pub
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
-cons_parti.3.pubkey=3snPdw7i7PerZYfRzEB61SAN9tFK4yHm9wUSRtkLSSGXHkQRbB5PkS
+cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk
#第3个参与方的账本初始服务的主机;
cons_parti.3.initializer.host=127.0.0.1
#第3个参与方的账本初始服务的端口;
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
index 81a04e7e..455940dd 100644
--- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
@@ -8,44 +8,53 @@
*/
package test.com.jd.blockchain.intgr;
+import static com.jd.blockchain.transaction.ContractReturnValue.decode;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.commons.io.FileUtils;
+import org.springframework.core.io.ClassPathResource;
+
import com.jd.blockchain.binaryproto.DataContractRegistry;
+import com.jd.blockchain.contract.ReadContract;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest;
-import com.jd.blockchain.ledger.*;
-import com.jd.blockchain.ledger.core.LedgerManage;
+import com.jd.blockchain.ledger.BlockchainKeyGenerator;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.KVDataEntry;
+import com.jd.blockchain.ledger.LedgerBlock;
+import com.jd.blockchain.ledger.LedgerInitOperation;
+import com.jd.blockchain.ledger.OperationResult;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionState;
+import com.jd.blockchain.ledger.TransactionTemplate;
+import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.ledger.core.LedgerRepository;
import com.jd.blockchain.ledger.core.impl.LedgerManager;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.storage.service.DbConnection;
import com.jd.blockchain.storage.service.DbConnectionFactory;
import com.jd.blockchain.tools.initializer.LedgerBindingConfig;
+import com.jd.blockchain.transaction.GenericValueHolder;
import com.jd.blockchain.utils.Bytes;
-import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.concurrent.ThreadInvoker;
import com.jd.blockchain.utils.net.NetworkAddress;
-import org.apache.commons.io.FileUtils;
-import org.junit.Assert;
-import org.springframework.core.io.ClassPathResource;
-import test.com.jd.blockchain.intgr.contract.AssetContract;
-import test.com.jd.blockchain.intgr.contract.AssetContract2;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicLong;
-
-import static org.junit.Assert.*;
-
/**
*
* @author shaozhuguang
@@ -63,7 +72,8 @@ public class IntegrationBase {
public static final String PASSWORD = "abc";
- public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9",
+ public static final String[] PUB_KEYS = {
+ "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9",
"3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX",
"3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x",
"3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" };
@@ -441,9 +451,9 @@ public class IntegrationBase {
// 合约测试使用的初始化数据;
static BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate();
static BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate();
- // 保存资产总数的键;
- // 第二个参数;
- private static String contractZipName = "contract.jar";
+ // 保存资产总数的键;
+ // 第二个参数;
+ private static String contractZipName = "contract-read.jar";
static HashDigest txContentHash;
public static LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash,
@@ -477,67 +487,146 @@ public class IntegrationBase {
assertArrayEquals(contractCode, contractCodeInDb);
// execute the contract;
- testContractExe(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository);
- testContractExe1(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository);
-
+// testContractExe(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository);
+// testContractExe1(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository);
+ testExeReadContract(adminKey, ledgerHash, blockchainService);
return block;
}
- private static void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey,
- BlockchainService blockchainService, LedgerRepository ledgerRepository) {
- LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash);
- LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1);
+// private static void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey,
+// BlockchainService blockchainService, LedgerRepository ledgerRepository) {
+// LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash);
+// LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1);
+//
+// // 定义交易;
+// TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+//
+// Byte byteObj = Byte.parseByte("123");
+//// txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj,
+//// contractDeployKey.getAddress().toBase58(),321123);
+// txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj,
+// dataKey.getAddress().toBase58(),Bytes.fromString("123321"));
+//
+// // 签名;
+// PreparedTransaction ptx = txTpl.prepare();
+// ptx.sign(adminKey);
+//
+// // 提交并等待共识返回;
+// TransactionResponse txResp = ptx.commit();
+//
+// // 验证结果;
+// Assert.assertTrue(txResp.isSuccess());
+// assertEquals(ptx.getHash(),txResp.getContentHash());
+// LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight());
+// KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(0,1);
+// assertEquals("100",kvDataEntries[0].getValue().toString());
+// }
+
+// private static void testContractExe1(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey,
+// BlockchainService blockchainService,LedgerRepository ledgerRepository) {
+// LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash);
+// LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1);
+//
+// // 定义交易;
+// TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+//
+// AssetContract2 assetContract = txTpl.contract(contractDeployKey.getAddress(), AssetContract2.class);
+// ContractBizContent contractBizContent = () -> new String[]{"param1","param2"};
+// assetContract.issue(contractBizContent,dataKey.getAddress().toBase58(),123456);
+//
+// // 签名;
+// PreparedTransaction ptx = txTpl.prepare();
+// ptx.sign(adminKey);
+//
+// // 提交并等待共识返回;
+// TransactionResponse txResp = ptx.commit();
+//
+// // 验证结果;
+// Assert.assertTrue(txResp.isSuccess());
+// assertEquals(ptx.getHash(),txResp.getContentHash());
+// LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight());
+// KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(1,2);
+// assertEquals("value1",kvDataEntries[0].getValue().toString());
+// assertEquals(888L,kvDataEntries[1].getValue());
+// }
+
+ private static void testExeReadContract(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) {
+
+ // 首先注册一个数据账户
+ BlockchainKeypair newDataAccount = BlockchainKeyGenerator.getInstance().generate();
- // 定义交易;
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ txTpl.dataAccounts().register(newDataAccount.getIdentity());
- Byte byteObj = Byte.parseByte("123");
-// txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj,
-// contractDeployKey.getAddress().toBase58(),321123);
- txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj,
- dataKey.getAddress().toBase58(),Bytes.fromString("123321"));
-
- // 签名;
PreparedTransaction ptx = txTpl.prepare();
ptx.sign(adminKey);
// 提交并等待共识返回;
- TransactionResponse txResp = ptx.commit();
+ ptx.commit();
- // 验证结果;
- Assert.assertTrue(txResp.isSuccess());
- assertEquals(ptx.getHash(),txResp.getContentHash());
- LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight());
- KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(0,1);
- assertEquals("100",kvDataEntries[0].getValue().toString());
- }
+ // 再提交一个KV写入
+ String key1 = "JingDong", value1 = "www.jd.com";
+ String key2 = "JD", value2 = "JingDong";
+ String key3 = "Test", value3 = "OK";
+
+ TransactionTemplate txKv = blockchainService.newTransaction(ledgerHash);
+ txKv.dataAccount(newDataAccount.getAddress())
+ .setText(key1, value1, -1)
+ .setBytes(key2, Bytes.fromString(value2), -1)
+ .setBytes(key3, Bytes.fromString(value3).toBytes(), -1);
+ PreparedTransaction kvPtx = txKv.prepare();
+ kvPtx.sign(adminKey);
- private static void testContractExe1(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey,
- BlockchainService blockchainService,LedgerRepository ledgerRepository) {
- LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash);
- LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1);
+ // 提交并等待共识返回;
+ kvPtx.commit();
- // 定义交易;
- TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
+ // 下面才是执行Read交易
+ // 定义交易;
+ TransactionTemplate txContract = blockchainService.newTransaction(ledgerHash);
- AssetContract2 assetContract = txTpl.contract(contractDeployKey.getAddress(), AssetContract2.class);
- ContractBizContent contractBizContent = () -> new String[]{"param1","param2"};
- assetContract.issue(contractBizContent,dataKey.getAddress().toBase58(),123456);
+ ReadContract readContract1 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
- // 签名;
- PreparedTransaction ptx = txTpl.prepare();
- ptx.sign(adminKey);
+ GenericValueHolder result1 = decode(readContract1.read(newDataAccount.getAddress().toBase58(), key1));
- // 提交并等待共识返回;
- TransactionResponse txResp = ptx.commit();
+ ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
- // 验证结果;
- Assert.assertTrue(txResp.isSuccess());
- assertEquals(ptx.getHash(),txResp.getContentHash());
- LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight());
- KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(1,2);
- assertEquals("value1",kvDataEntries[0].getValue().toString());
- assertEquals(888L,kvDataEntries[1].getValue());
+ readContract2.read(newDataAccount.getAddress().toBase58(), key2);
+
+ ReadContract readContract3 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
+
+ GenericValueHolder result3 = decode(readContract3.readVersion(newDataAccount.getAddress().toBase58(), key2));
+
+ // 签名;
+ PreparedTransaction contractPtx = txContract.prepare();
+ contractPtx.sign(adminKey);
+
+ // 提交并等待共识返回;
+ TransactionResponse readTxResp = contractPtx.commit();
+
+ OperationResult[] operationResults = readTxResp.getOperationResults();
+
+ // 通过EventResult获取结果
+ System.out.printf("readContract1.result = %s \r\n", result1.get());
+ System.out.printf("readContract3.result = %s \r\n", result3.get());
+
+
+// // 打印结果
+// for (OperationResult or : operationResults) {
+// System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), ContractSerializeUtils.resolve(or.getResult()));
+// }
+//
+// // 验证结果
+// assertNotNull(contractReturn);
+// assertEquals(contractReturn.length, 3);
+//
+// String returnVal1 = contractReturn[0];
+// assertEquals(value1, returnVal1);
+//
+// String returnVal2 = contractReturn[1];
+// assertEquals(value2, returnVal2);
+//
+// String returnVal3 = contractReturn[2];
+// assertEquals("0", returnVal3);
}
/**
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java
index 1da5341b..f1f5288c 100644
--- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java
@@ -1,12 +1,32 @@
package test.com.jd.blockchain.intgr;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+
import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusSettings;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig;
-import com.jd.blockchain.ledger.*;
+import com.jd.blockchain.ledger.BlockchainKeyGenerator;
+import com.jd.blockchain.ledger.BlockchainKeypair;
+import com.jd.blockchain.ledger.LedgerBlock;
+import com.jd.blockchain.ledger.LedgerInfo;
+import com.jd.blockchain.ledger.PreparedTransaction;
+import com.jd.blockchain.ledger.TransactionResponse;
+import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.ledger.core.LedgerRepository;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.client.GatewayServiceFactory;
@@ -17,22 +37,12 @@ import com.jd.blockchain.tools.initializer.Prompter;
import com.jd.blockchain.tools.keygen.KeyGenCommand;
import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback;
import com.jd.blockchain.utils.net.NetworkAddress;
-import org.junit.Test;
-import org.springframework.core.io.ClassPathResource;
+
import test.com.jd.blockchain.intgr.IntegratedContext.Node;
import test.com.jd.blockchain.intgr.contract.AssetContract;
import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest;
import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-
-import static org.junit.Assert.*;
-
/**
* 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块;
*/
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/capability/LedgerPerfCapabilityTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/capability/LedgerPerfCapabilityTest.java
index 6c6e4642..6e23c83f 100644
--- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/capability/LedgerPerfCapabilityTest.java
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/capability/LedgerPerfCapabilityTest.java
@@ -38,22 +38,22 @@ public class LedgerPerfCapabilityTest {
@Test
public void testKvStorage4Memory() {
- LedgerPerformanceTest.test(new String[]{SILENT, CONSENSUS});
+ LedgerPerformanceTest.test(new String[]{SILENT});
}
@Test
public void testUserRegister4Memory() {
- LedgerPerformanceTest.test(new String[]{USERTEST, SILENT, CONSENSUS});
+ LedgerPerformanceTest.test(new String[]{USERTEST, SILENT});
}
@Test
public void testKvStorage4Rocksdb() {
- LedgerPerformanceTest.test(new String[]{ROCKSDB, SILENT, CONSENSUS});
+ LedgerPerformanceTest.test(new String[]{ROCKSDB, SILENT});
}
@Test
public void testUserRegister4Rocksdb() {
- LedgerPerformanceTest.test(new String[]{USERTEST, ROCKSDB, SILENT, CONSENSUS});
+ LedgerPerformanceTest.test(new String[]{USERTEST, ROCKSDB, SILENT});
}
public void testUserRegister4Redis() {
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContract2.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContract2.java
deleted file mode 100644
index a70142fb..00000000
--- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContract2.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package test.com.jd.blockchain.intgr.contract;
-
-import com.jd.blockchain.contract.Contract;
-import com.jd.blockchain.contract.ContractEvent;
-import com.jd.blockchain.ledger.ContractBizContent;
-import com.jd.blockchain.utils.Bytes;
-
-import java.math.BigDecimal;
-
-/**
- * 示例:一个“资产管理”智能合约;
- *
- * @author zhaogw
- */
-@Contract
-public interface AssetContract2 {
-
- /**
- * 发行资产;
- * 新发行的资产数量;
- * @param assetHolderAddress
- * 新发行的资产的持有账户;
- */
- @ContractEvent(name = "issue-asset-0")
- void issue(ContractBizContent contractBizContent, String assetHolderAddress);
-
- /**
- * 发行资产;
- * 新发行的资产数量;
- * @param assetHolderAddress
- * 新发行的资产的持有账户;
- */
- @ContractEvent(name = "issue-asset")
- void issue(ContractBizContent contractBizContent, String assetHolderAddress, long cashNumber);
-
- @ContractEvent(name = "issue-asset-2")
- void issue(Bytes bytes, String assetHolderAddress, long cashNumber);
-
- @ContractEvent(name = "issue-asset-3")
- void issue(Byte byteObj, String assetHolderAddress, long cashNumber);
-
- @ContractEvent(name = "issue-asset-4")
- void issue(Byte byteObj, String assetHolderAddress, Bytes cashNumber);
-}
\ No newline at end of file
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContractImpl.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContractImpl.java
new file mode 100644
index 00000000..9c1ec6e1
--- /dev/null
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/AssetContractImpl.java
@@ -0,0 +1,5 @@
+package test.com.jd.blockchain.intgr.contract;
+
+public class AssetContractImpl {
+
+}
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/ContractInvocationTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/ContractInvocationTest.java
new file mode 100644
index 00000000..46698426
--- /dev/null
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/contract/ContractInvocationTest.java
@@ -0,0 +1,14 @@
+package test.com.jd.blockchain.intgr.contract;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class ContractInvocationTest {
+
+ @Test
+ public void test() {
+
+ }
+
+}
diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java
index a97a26c4..77bdef66 100644
--- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java
+++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/ledger/LedgerBlockGeneratingTest.java
@@ -58,8 +58,6 @@ public class LedgerBlockGeneratingTest {
DefaultOperationHandleRegisteration opHandler = new DefaultOperationHandleRegisteration();
- System.gc();
-
test(ledgerHash, node.getPartiKey(), ledgerManager, opHandler, 1000, 5);
}
diff --git a/source/test/test-integration/src/test/resources/contract-read.jar b/source/test/test-integration/src/test/resources/contract-read.jar
index 38f81951..ddf9c668 100644
Binary files a/source/test/test-integration/src/test/resources/contract-read.jar and b/source/test/test-integration/src/test/resources/contract-read.jar differ
diff --git a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java
index 4c9af288..ecf5f640 100644
--- a/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java
+++ b/source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java
@@ -425,7 +425,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI
userRegOP.getUserID().getPubKey());
}
- txCtx.commit(TransactionState.SUCCESS);
+ txCtx.commit(TransactionState.SUCCESS, null);
return ledgerEditor.prepare();
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerLedgerInitializer.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerLedgerInitializer.java
index b03d88af..570ccfc4 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerLedgerInitializer.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerLedgerInitializer.java
@@ -293,7 +293,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon
userRegOP.getUserID().getPubKey());
}
- txCtx.commit(TransactionState.SUCCESS);
+ txCtx.commit(TransactionState.SUCCESS, null);
return ledgerEditor.prepare();
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerNodeContext.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerNodeContext.java
index 1d7f91ec..8e32d3df 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerNodeContext.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerNodeContext.java
@@ -19,32 +19,7 @@ import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm;
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService;
import com.jd.blockchain.crypto.service.sm.SMCryptoService;
-import com.jd.blockchain.ledger.AccountHeader;
-import com.jd.blockchain.ledger.BlockchainIdentity;
-import com.jd.blockchain.ledger.BlockchainKeyGenerator;
-import com.jd.blockchain.ledger.BlockchainKeypair;
-import com.jd.blockchain.ledger.ContractCodeDeployOperation;
-import com.jd.blockchain.ledger.ContractEventSendOperation;
-import com.jd.blockchain.ledger.DataAccountKVSetOperation;
-import com.jd.blockchain.ledger.DataAccountRegisterOperation;
-import com.jd.blockchain.ledger.EndpointRequest;
-import com.jd.blockchain.ledger.KVDataEntry;
-import com.jd.blockchain.ledger.KVInfoVO;
-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.NodeRequest;
-import com.jd.blockchain.ledger.Operation;
-import com.jd.blockchain.ledger.ParticipantNode;
-import com.jd.blockchain.ledger.TransactionContent;
-import com.jd.blockchain.ledger.TransactionContentBody;
-import com.jd.blockchain.ledger.TransactionRequest;
-import com.jd.blockchain.ledger.TransactionRequestBuilder;
-import com.jd.blockchain.ledger.TransactionResponse;
-import com.jd.blockchain.ledger.TransactionState;
-import com.jd.blockchain.ledger.UserInfo;
-import com.jd.blockchain.ledger.UserRegisterOperation;
+import com.jd.blockchain.ledger.*;
import com.jd.blockchain.ledger.core.CryptoConfig;
import com.jd.blockchain.ledger.core.LedgerDataSet;
import com.jd.blockchain.ledger.core.LedgerEditor;
@@ -398,7 +373,7 @@ public class MockerNodeContext implements BlockchainQueryService {
}
@Override
- public AccountHeader getContract(HashDigest ledgerHash, String address) {
+ public ContractInfo getContract(HashDigest ledgerHash, String address) {
return queryService.getContract(ledgerHash, address);
}
@@ -427,15 +402,16 @@ public class MockerNodeContext implements BlockchainQueryService {
return reqBuilder.buildRequest();
}
- public void txProcess(TransactionRequest txRequest) {
+ public OperationResult[] txProcess(TransactionRequest txRequest) {
LedgerEditor newEditor = ledgerRepository.createNextBlock();
LedgerBlock latestBlock = ledgerRepository.getLatestBlock();
LedgerDataSet previousDataSet = ledgerRepository.getDataSet(latestBlock);
TransactionBatchProcessor txProc = new TransactionBatchProcessor(newEditor, previousDataSet, opHandler,
ledgerManager);
- txProc.schedule(txRequest);
+ TransactionResponse txResp = txProc.schedule(txRequest);
TransactionBatchResultHandle handle = txProc.prepare();
handle.commit();
+ return txResp.getOperationResults();
}
private LedgerRepository registerLedger(HashDigest ledgerHash, DBConnectionConfig dbConnConf) {
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java
index 5813849b..e414e2df 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java
@@ -2,11 +2,11 @@ package com.jd.blockchain.mocker.contracts;
import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.ContractException;
-import com.jd.blockchain.contract.EventProcessingAwire;
+import com.jd.blockchain.contract.EventProcessingAware;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.KVDataEntry;
-public class AccountContractImpl implements EventProcessingAwire, AccountContract {
+public class AccountContractImpl implements EventProcessingAware, AccountContract {
private ContractEventContext eventContext;
@@ -65,17 +65,8 @@ public class AccountContractImpl implements EventProcessingAwire, AccountContrac
}
@Override
- public void postEvent(ContractEventContext eventContext, ContractException error) {
+ public void postEvent(ContractEventContext eventContext, Exception error) {
}
- @Override
- public void postEvent(ContractException error) {
-
- }
-
- @Override
- public void postEvent() {
-
- }
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContract.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContract.java
index 2dbd8ae5..9662dd68 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContract.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContract.java
@@ -10,5 +10,5 @@ public interface WriteContract {
void print(String name);
@ContractEvent(name = "writeKv")
- void writeKv(String address, String key, String value);
+ String writeKv(String address, String key, String value);
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java
index 48874420..83f5521d 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java
@@ -2,9 +2,9 @@ package com.jd.blockchain.mocker.contracts;
import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.ContractException;
-import com.jd.blockchain.contract.EventProcessingAwire;
+import com.jd.blockchain.contract.EventProcessingAware;
-public class WriteContractImpl implements EventProcessingAwire, WriteContract {
+public class WriteContractImpl implements EventProcessingAware, WriteContract {
private ContractEventContext eventContext;
@@ -15,8 +15,9 @@ public class WriteContractImpl implements EventProcessingAwire, WriteContract {
}
@Override
- public void writeKv(String address, String key, String value) {
+ public String writeKv(String address, String key, String value) {
eventContext.getLedger().dataAccount(address).setText(key, value, -1);
+ return String.format("address = %s, key = %s, value = %s, version = %s", address, key, value, 0);
}
@Override
@@ -25,17 +26,8 @@ public class WriteContractImpl implements EventProcessingAwire, WriteContract {
}
@Override
- public void postEvent(ContractEventContext eventContext, ContractException error) {
+ public void postEvent(ContractEventContext eventContext, Exception error) {
System.out.println("----- postEvent1 -----");
}
- @Override
- public void postEvent(ContractException error) {
- System.out.println("----- postEvent2 -----");
- }
-
- @Override
- public void postEvent() {
- System.out.println("----- postEvent3 -----");
- }
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java
index 53bc9417..cb26ac92 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java
@@ -1,26 +1,25 @@
package com.jd.blockchain.mocker.handler;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.ContractException;
-import com.jd.blockchain.contract.EventProcessingAwire;
+import com.jd.blockchain.contract.EventProcessingAware;
import com.jd.blockchain.contract.LedgerContext;
import com.jd.blockchain.crypto.HashDigest;
-import com.jd.blockchain.ledger.BlockchainIdentity;
-import com.jd.blockchain.ledger.ContractEventSendOperation;
-import com.jd.blockchain.ledger.Operation;
-import com.jd.blockchain.ledger.TransactionRequest;
-import com.jd.blockchain.ledger.core.*;
+import com.jd.blockchain.ledger.*;
+import com.jd.blockchain.ledger.core.LedgerDataSet;
+import com.jd.blockchain.ledger.core.LedgerService;
+import com.jd.blockchain.ledger.core.OperationHandle;
+import com.jd.blockchain.ledger.core.TransactionRequestContext;
import com.jd.blockchain.ledger.core.impl.LedgerManager;
import com.jd.blockchain.ledger.core.impl.LedgerQueryService;
import com.jd.blockchain.ledger.core.impl.OperationHandleContext;
import com.jd.blockchain.ledger.core.impl.handles.ContractLedgerContext;
import com.jd.blockchain.mocker.proxy.ExecutorProxy;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-
public class MockerContractExeHandle implements OperationHandle {
private Map executorProxyMap = new ConcurrentHashMap<>();
@@ -30,7 +29,7 @@ public class MockerContractExeHandle implements OperationHandle {
private HashDigest ledgerHash;
@Override
- public void process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
+ public BytesValue process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) {
ContractEventSendOperation contractOP = (ContractEventSendOperation) op;
@@ -38,28 +37,39 @@ public class MockerContractExeHandle implements OperationHandle {
ExecutorProxy executorProxy = executorProxyMap.get(txHash);
+ Object result = null;
if (executorProxy != null) {
LedgerQueryService queryService = new LedgerQueryService(ledgerManager);
ContractLedgerContext ledgerContext = new ContractLedgerContext(queryService, opHandleContext);
- MockerContractEventContext contractEventContext = new MockerContractEventContext(
- ledgerHash, contractOP.getEvent(), requestContext.getRequest(), ledgerContext);
+ MockerContractEventContext contractEventContext = new MockerContractEventContext(ledgerHash,
+ contractOP.getEvent(), requestContext.getRequest(), ledgerContext);
- EventProcessingAwire eventProcessingAwire = (EventProcessingAwire) executorProxy.getInstance();
- try {
- //
- // Before处理过程
- eventProcessingAwire.beforeEvent(contractEventContext);
- executorProxy.invoke();
+ Object instance = executorProxy.getInstance();
+ EventProcessingAware awire = null;
- // After处理过程
- eventProcessingAwire.postEvent();
+ if (instance instanceof EventProcessingAware) {
+ awire = (EventProcessingAware) instance;
+ awire.beforeEvent(contractEventContext);
+ }
+
+ try {
+ result = executorProxy.invoke();
+ if (awire != null) {
+ // After处理过程
+ awire.postEvent(contractEventContext, null);
+ }
} catch (Exception e) {
- eventProcessingAwire.postEvent(new ContractException(e.getMessage()));
+ if (awire != null) {
+ awire.postEvent(contractEventContext, new ContractException(e.getMessage()));
+ }
} finally {
removeExecutorProxy(txHash);
}
}
+
+ // No return value;
+ return BytesValueEncoding.encodeSingle(result, null);
}
@Override
@@ -90,8 +100,8 @@ public class MockerContractExeHandle implements OperationHandle {
private LedgerContext ledgerContext;
- public MockerContractEventContext(HashDigest ledgeHash, String event,
- TransactionRequest transactionRequest, LedgerContext ledgerContext) {
+ public MockerContractEventContext(HashDigest ledgeHash, String event, TransactionRequest transactionRequest,
+ LedgerContext ledgerContext) {
this.ledgeHash = ledgeHash;
this.event = event;
this.transactionRequest = transactionRequest;
@@ -119,7 +129,7 @@ public class MockerContractExeHandle implements OperationHandle {
}
@Override
- public byte[] getArgs() {
+ public BytesValueList getArgs() {
return null;
}
diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java
index 69fc305c..b2e23766 100644
--- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java
+++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java
@@ -1,80 +1,88 @@
package com.jd.blockchain.mocker.proxy;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
import com.jd.blockchain.contract.Contract;
import com.jd.blockchain.contract.ContractEvent;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
+import com.jd.blockchain.ledger.BytesValueEncoding;
+import com.jd.blockchain.ledger.OperationResult;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.mocker.MockerNodeContext;
import com.jd.blockchain.mocker.handler.MockerContractExeHandle;
import com.jd.blockchain.transaction.TxBuilder;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
public class ContractProxy implements InvocationHandler {
- private BlockchainIdentity identity;
+ private BlockchainIdentity identity;
+
+ private MockerNodeContext mockerNodeContext;
- private MockerNodeContext mockerNodeContext;
+ private T instance;
- private T instance;
+ private MockerContractExeHandle operationHandle;
- private MockerContractExeHandle operationHandle;
+ public ContractProxy(BlockchainIdentity identity, MockerNodeContext mockerNodeContext, T instance,
+ MockerContractExeHandle operationHandle) {
+ this.identity = identity;
+ this.mockerNodeContext = mockerNodeContext;
+ this.instance = instance;
+ this.operationHandle = operationHandle;
+ }
- public ContractProxy(BlockchainIdentity identity, MockerNodeContext mockerNodeContext,
- T instance, MockerContractExeHandle operationHandle) {
- this.identity = identity;
- this.mockerNodeContext = mockerNodeContext;
- this.instance = instance;
- this.operationHandle = operationHandle;
- }
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // 实际执行时,首先判断执行的是否是添加注解的方法
+ if (!isExecuteContractMethod(method)) {
+ return method.invoke(instance, args);
+ }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- // 实际执行时,首先判断执行的是否是添加注解的方法
- if (!isExecuteContractMethod(method)) {
- return method.invoke(instance, args);
- }
+ // 首先发送一次执行的请求
+ TxBuilder txBuilder = mockerNodeContext.txBuilder();
- // 首先发送一次执行的请求
- TxBuilder txBuilder = mockerNodeContext.txBuilder();
+ Class> contractInft = null;
- Class> contractInft = null;
+ Class>[] instanceInfts = instance.getClass().getInterfaces();
- Class>[] instanceInfts = instance.getClass().getInterfaces();
+ for (Class> instanceInft : instanceInfts) {
+ if (instanceInft.isAnnotationPresent(Contract.class)) {
+ contractInft = instanceInft;
+ break;
+ }
+ }
- for (Class> instanceInft : instanceInfts) {
- if (instanceInft.isAnnotationPresent(Contract.class)) {
- contractInft = instanceInft;
- break;
- }
- }
+ if (contractInft == null) {
+ throw new IllegalStateException(
+ "This object does not implement the interface for the @Contract annotation !!!");
+ }
- if (contractInft == null) {
- throw new IllegalStateException("This object does not implement the interface for the @Contract annotation !!!");
- }
+ // 生成代理类
+ Object proxyInstance = txBuilder.contract(identity.getAddress().toBase58(), contractInft);
+ // 代理方式执行一次
+ method.invoke(proxyInstance, args);
- // 生成代理类
- Object proxyInstance = txBuilder.contract(identity.getAddress().toBase58(), contractInft);
- // 代理方式执行一次
- method.invoke(proxyInstance, args);
+ TransactionRequest txRequest = mockerNodeContext.txRequest(txBuilder);
- TransactionRequest txRequest = mockerNodeContext.txRequest(txBuilder);
+ // 放入到Map中
+ HashDigest txHash = txRequest.getTransactionContent().getHash();
+ operationHandle.registerExecutorProxy(txHash, new ExecutorProxy(instance, method, args));
- // 放入到Map中
- HashDigest txHash = txRequest.getTransactionContent().getHash();
- operationHandle.registerExecutorProxy(txHash, new ExecutorProxy(instance, method, args));
+ // 提交该请求至整个区块链系统
+ OperationResult[] operationResults = mockerNodeContext.txProcess(txRequest);
+ if (operationResults == null || operationResults.length == 0) {
+ return null;
+ }
+ OperationResult opResult = operationResults[0];
- // 提交该请求至整个区块链系统
- mockerNodeContext.txProcess(txRequest);
- // 不处理返回值
- return null;
- }
+ // 处理返回值
+ return BytesValueEncoding.decode(opResult.getResult(), method.getReturnType());
+ }
- private boolean isExecuteContractMethod(Method method) {
- Annotation annotation = method.getAnnotation(ContractEvent.class);
- return annotation != null;
- }
+ private boolean isExecuteContractMethod(Method method) {
+ Annotation annotation = method.getAnnotation(ContractEvent.class);
+ return annotation != null;
+ }
}
diff --git a/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/AccountMockerTest.java b/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/AccountMockerTest.java
index d52a3732..5058ebdc 100644
--- a/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/AccountMockerTest.java
+++ b/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/AccountMockerTest.java
@@ -39,7 +39,7 @@ public class AccountMockerTest {
accountContract.create(address, accountTo, 1000L);
- accountContract.print(address, accountFrom, accountTo);
+// accountContract.print(address, accountFrom, accountTo);
// 开始转账
accountContract.transfer(address, accountFrom, accountTo, 500);
diff --git a/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/SampleTest.java b/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/SampleTest.java
index c388ef99..19cd34df 100644
--- a/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/SampleTest.java
+++ b/source/tools/tools-mocker/src/test/java/test/com/jd/blockchain/contract/SampleTest.java
@@ -33,7 +33,9 @@ public class SampleTest {
writeContract = mockerNodeContext.deployContract(writeContract);
- writeContract.writeKv(dataAccountAddress, key, value);
+ String result = writeContract.writeKv(dataAccountAddress, key, value);
+
+ System.out.println(result);
// 查询结果
KVDataEntry[] dataEntries = mockerNodeContext.getDataEntries(ledgerHash, dataAccountAddress, key);
diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/event/DefaultExceptionHandle.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/event/DefaultExceptionHandle.java
index 998e619c..5ff08720 100644
--- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/event/DefaultExceptionHandle.java
+++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/event/DefaultExceptionHandle.java
@@ -5,8 +5,6 @@ import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.jd.blockchain.utils.console.CommandConsole;
-
public class DefaultExceptionHandle implements ExceptionHandle {
@Override
@@ -21,9 +19,8 @@ public class DefaultExceptionHandle implements ExceptionHandle implements Disposable {
}
public EventMulticaster(Class listenerClass, Logger errorLogger) {
- this(listenerClass, new ExceptionLoggingHandle(errorLogger));
+ this(listenerClass, new RethrowExceptionHandler(errorLogger));
}
@SuppressWarnings("unchecked")
public EventMulticaster(Class listenerClass, ExceptionHandle exHandle) {
+ if (!listenerClass.isInterface()) {
+ throw new IllegalArgumentException("The specified class of listener does not represent an interface!");
+ }
// 初始化错误处理器;
- this.exHandle = exHandle == null ? new DefaultExceptionHandle() : exHandle;
+ this.exHandle = exHandle == null
+ ? new RethrowExceptionHandler(LoggerFactory.getLogger(EventMulticaster.class))
+ : exHandle;
// 解析出不支持的方法;
Method[] methods = ReflectionUtils.getAllDeclaredMethods(listenerClass);
- List supMths = new LinkedList();
+ List supMths = new ArrayList();
for (Method method : methods) {
if (method.getDeclaringClass() == Object.class) {
// 不支持 Object 方法;
@@ -86,14 +92,14 @@ public class EventMulticaster implements Disposable {
throw new UnsupportedOperationException("Unsupported method for event multicasting!");
}
}
-
- protected void doNotify(List listeners, Method method, Object[] args){
+
+ protected void doNotify(List listeners, Method method, Object[] args) {
for (TListener listener : listeners) {
doNotifySingle(listener, method, args);
}
}
-
- protected void doNotifySingle(TListener listener, Method method, Object[] args){
+
+ protected void doNotifySingle(TListener listener, Method method, Object[] args) {
try {
ReflectionUtils.invokeMethod(method, listener, args);
} catch (Exception e) {
@@ -104,12 +110,12 @@ public class EventMulticaster implements Disposable {
public void addListener(TListener listener) {
listeners.add(listener);
}
-
+
public void removeListener(TListener listener) {
listeners.remove(listener);
}
- public TListener broadcast() {
+ public TListener getBroadcaster() {
return listenerProxy;
}
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);
diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java
index 77cfca01..0d4d86e1 100644
--- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java
+++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/io/FileUtils.java
@@ -442,37 +442,44 @@ public class FileUtils {
}
public static void deleteFile(File file) {
- deleteFile(file, false);
+ deletePath(file, false);
}
public static void deleteFile(String dir, boolean silent) {
File directory = new File(dir);
- deleteFile(directory, silent);
+ deletePath(directory, silent);
}
/**
- * 删除文件;
+ * 删除文件;
*
- * @param file
- * @param silent 是否静默删除;如果为 true ,则吞噬删除过程中的异常,意味着方法即便正常返回时也有可能删除不完全;
+ * @param path 如果指定的路径是单个文件,则删除该文件;如果指定路径是目录,则删除该目录及其下的全部文件;
+ * @param silent 是否静默删除;如果为 true ,则吞噬删除过程中的异常, 意味着方法即便正常返回时也有可能删除不完全;
+ * @return 如果删除成功,则返回 true; 否则返回 false,或者抛出 {@link RuntimeIOException};
*/
- public static void deleteFile(File file, boolean silent) {
- if (file.isFile()) {
+ public static boolean deletePath(File path, boolean silent) {
+ if (path.isFile()) {
try {
- file.delete();
- return;
+ path.delete();
+ return true;
} catch (Exception e) {
if (!silent) {
throw new RuntimeIOException(e.getMessage(), e);
}
}
+
+ return false;
}
- File[] files = file.listFiles();
+
+ // delete dir;
+ File[] files = path.listFiles();
if (files == null) {
- return;
+ return false;
}
+
for (File f : files) {
- deleteFile(f, silent);
+ deletePath(f, silent);
}
+ return path.delete();
}
}