Browse Source

Fix getDataEntry results error!

tags/1.0.0
shaozhuguang 6 years ago
parent
commit
532fec678b
20 changed files with 1129 additions and 47 deletions
  1. +2
    -2
      source/contract/contract-samples/pom.xml
  2. +17
    -0
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContract.java
  3. +109
    -0
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java
  4. +1
    -1
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataAccountKVSetOperation.java
  5. +0
    -3
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/DataType.java
  6. +8
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataVO.java
  7. +7
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVInfoVO.java
  8. +33
    -1
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java
  9. +17
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java
  10. +104
    -28
      source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java
  11. +7
    -3
      source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java
  12. +385
    -0
      source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientResolveUtil.java
  13. +5
    -0
      source/sdk/sdk-samples/pom.xml
  14. +38
    -0
      source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Constant.java
  15. +51
    -0
      source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Base_Demo.java
  16. +164
    -0
      source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java
  17. BIN
      source/sdk/sdk-samples/src/main/resources/transfer.jar
  18. +171
    -0
      source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDKDemo_Contract_Test.java
  19. BIN
      source/sdk/sdk-samples/src/test/resources/transfer.jar
  20. +10
    -9
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java

+ 2
- 2
source/contract/contract-samples/pom.xml View File

@@ -34,11 +34,11 @@
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>contract</finalName>
<finalName>transfer</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.jd.blockchain.contract.ReadContractImpl</mainClass>
<mainClass>com.jd.blockchain.contract.TransferContractImpl</mainClass>
</manifest>
</archive>
<descriptorRefs>


+ 17
- 0
source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContract.java View File

@@ -0,0 +1,17 @@
package com.jd.blockchain.contract;

@Contract
public interface TransferContract {

@ContractEvent(name = "create")
String create(String address, String account, long money);

@ContractEvent(name = "transfer")
String transfer(String address, String from, String to, long money);

@ContractEvent(name = "read")
long read(String address, String account);

@ContractEvent(name = "readAll")
String readAll(String address, String account);
}

+ 109
- 0
source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/TransferContractImpl.java View File

@@ -0,0 +1,109 @@
package com.jd.blockchain.contract;

import com.alibaba.fastjson.JSON;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.KVDataEntry;
import com.jd.blockchain.ledger.KVDataVO;
import com.jd.blockchain.ledger.KVInfoVO;

public class TransferContractImpl implements EventProcessingAwire, TransferContract {

private ContractEventContext eventContext;

private HashDigest ledgerHash;

@Override
public String create(String address, String account, long money) {
KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account);
// 肯定有返回值,但若不存在则返回version=-1
if (kvDataEntries != null && kvDataEntries.length > 0) {
long currVersion = kvDataEntries[0].getVersion();
if (currVersion > -1) {
throw new IllegalStateException(String.format("%s -> %s already have created !!!", address, account));
}
eventContext.getLedger().dataAccount(address).setInt64(account, money, -1L);
} else {
throw new IllegalStateException(String.format("Ledger[%s] inner Error !!!", ledgerHash.toBase58()));
}
return String.format("DataAccountAddress[%s] -> Create(By Contract Operation) Account = %s and Money = %s Success!!! \r\n",
address, account, money);
}

@Override
public String transfer(String address, String from, String to, long money) {
// 首先查询余额
KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, from, to);
if (kvDataEntries == null || kvDataEntries.length != 2) {
throw new IllegalStateException(String.format("%s -> %s - %s may be not created !!!", address, from, to));
} else {
// 判断from账号中钱数量是否足够
long fromMoney = 0L, toMoney = 0L, fromVersion = 0L, toVersion = 0L;
for (KVDataEntry kvDataEntry : kvDataEntries) {
if (kvDataEntry.getKey().equals(from)) {
fromMoney = (long) kvDataEntry.getValue();
fromVersion = kvDataEntry.getVersion();
} else {
toMoney = (long) kvDataEntry.getValue();
toVersion = kvDataEntry.getVersion();
}
}
if (fromMoney < money) {
throw new IllegalStateException(String.format("%s -> %s not have enough money !!!", address, from));
}
long fromNewMoney = fromMoney - money;
long toNewMoney = toMoney + money;
// 重新设置
eventContext.getLedger().dataAccount(address).setInt64(from, fromNewMoney, fromVersion);
eventContext.getLedger().dataAccount(address).setInt64(to, toNewMoney, toVersion);
}

return String.format("DataAccountAddress[%s] transfer from [%s] to [%s] and [money = %s] Success !!!", address, from, to, money);
}

@Override
public long read(String address, String account) {
KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account);
if (kvDataEntries == null || kvDataEntries.length == 0) {
return -1;
}
return (long)kvDataEntries[0].getValue();
}

@Override
public String readAll(String address, String account) {
KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, account);
// 获取最新的版本号
if (kvDataEntries == null || kvDataEntries.length == 0) {
return "";
}
long newestVersion = kvDataEntries[0].getVersion();
if (newestVersion == -1) {
return "";
}
KVDataVO[] kvDataVOS = new KVDataVO[1];
long[] versions = new long[(int)newestVersion + 1];
for (int i = 0; i < versions.length; i++) {
versions[i] = i;
}
KVDataVO kvDataVO = new KVDataVO(account, versions);

kvDataVOS[0] = kvDataVO;

KVInfoVO kvInfoVO = new KVInfoVO(kvDataVOS);

KVDataEntry[] allEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, kvInfoVO);

return JSON.toJSONString(allEntries);
}

@Override
public void beforeEvent(ContractEventContext eventContext) {
this.eventContext = eventContext;
this.ledgerHash = eventContext.getCurrentLedgerHash();
}

@Override
public void postEvent(ContractEventContext eventContext, Exception error) {

}
}

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

@@ -7,7 +7,7 @@ import com.jd.blockchain.consts.DataCodes;
import com.jd.blockchain.utils.Bytes;
@DataContract(code= DataCodes.TX_OP_DATA_ACC_SET)
public interface DataAccountKVSetOperation extends Operation{
public interface DataAccountKVSetOperation extends Operation {
@DataField(order=2, primitiveType=PrimitiveType.BYTES)
Bytes getAccountAddress();


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

@@ -106,9 +106,6 @@ public enum DataType {
ENCRYPTED_DATA((byte) (BaseType.BYTES | 0x08));
@EnumField(type = PrimitiveType.INT8)
public final byte CODE;


+ 8
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVDataVO.java View File

@@ -8,6 +8,14 @@ public class KVDataVO {
private String key;
private long[] version;

public KVDataVO() {
}

public KVDataVO(String key, long[] version) {
this.key = key;
this.version = version;
}

public String getKey() {
return key;
}


+ 7
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/KVInfoVO.java View File

@@ -8,6 +8,13 @@ package com.jd.blockchain.ledger;
public class KVInfoVO {
private KVDataVO[] data;

public KVInfoVO() {
}

public KVInfoVO(KVDataVO[] data) {
this.data = data;
}

public KVDataVO[] getData() {
return data;
}


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

@@ -61,7 +61,7 @@ public class ContractInvocationProxy implements InvocationHandler {
((ContractEventSendOpTemplate) sendOperation).setEventAndArgs(event, argBytes);
}
// 代理操作,返回值类型无法创建
return null;
return returnResult(method.getReturnType());
}

private byte[] serializeArgs(Object[] args) {
@@ -74,4 +74,36 @@ public class ContractInvocationProxy implements InvocationHandler {
}
return -1;
}

private Object returnResult(Class<?> clazz) {
if (clazz.equals(Void.TYPE)) {
return null;
}

if (!clazz.isPrimitive()) {
// 非基本类型
return null;
} else {
// 基本类型需要处理返回值,目前采用枚举遍历方式
// 八种基本类型:int, double, float, long, short, boolean, byte, char, void
if (clazz.equals(int.class)) {
return 0;
} else if (clazz.equals(double.class)) {
return 0.0D;
} else if (clazz.equals(float.class)) {
return 0F;
} else if (clazz.equals(long.class)) {
return 0L;
} else if (clazz.equals(short.class)) {
return (short)0;
} else if (clazz.equals(boolean.class)) {
return Boolean.FALSE;
} else if (clazz.equals(byte.class)) {
return (byte)0;
} else if (clazz.equals(char.class)) {
return (char)0;
}
return null;
}
}
}

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

@@ -60,6 +60,23 @@ public class ContractType {

public static ContractType resolve(Class<?> contractIntf) {

// 如果是Class则首先获取其接口
if (!contractIntf.isInterface()) {
Class<?> realIntf = null;
Class<?>[] interfaces = contractIntf.getInterfaces();
for (Class<?> intf: interfaces) {
if (intf.isAnnotationPresent(Contract.class)) {
realIntf = intf;
break;
}
}
if (realIntf == null) {
throw new IllegalDataException(String.format(
"%s is not a Contract Type, because there is not @Contract !", contractIntf.getName()));
}
contractIntf = realIntf;
}

// 接口上必须有注解
if (!contractIntf.isAnnotationPresent(Contract.class)) {
throw new IllegalDataException("It is not a Contract Type, because there is not @Contract !");


source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientOperationUtil.java → source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/converters/ClientResolveUtil.java View File

@@ -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.DataType;
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) {

@@ -297,4 +312,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;
}
}
}

+ 7
- 3
source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/BlockchainServiceProxy.java View File

@@ -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


+ 385
- 0
source/sdk/sdk-client/src/main/java/com/jd/blockchain/sdk/client/ClientResolveUtil.java View File

@@ -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 <writeSetObj.size(); i++) {
// JSONObject currWriteSetObj = writeSetObj.getJSONObject(i);
// long expectedVersion = currWriteSetObj.getLong("expectedVersion");
// JSONObject valueObj = currWriteSetObj.getJSONObject("value");
// String typeStr = valueObj.getString("type");
// String realValBase58 = valueObj.getString("value");
// String key = currWriteSetObj.getString("key");
// DataType dataType = DataType.valueOf(typeStr);
// BytesValue bytesValue =BytesValueEntry.fromType(dataType, Base58Utils.decode(realValBase58));
// KVData kvData = new KVData(key, bytesValue, expectedVersion);
// kvOperation.set(kvData);
// }
//
// return kvOperation;
// }
//
// public static LedgerInitOperation convertLedgerInitOperation(JSONObject jsonObject) {
// JSONObject legerInitObj = jsonObject.getJSONObject("initSetting");
// LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData();
// String ledgerSeedStr = legerInitObj.getString("ledgerSeed");
//
// // 种子需要做Base64转换
// ledgerInitSettingData.setLedgerSeed(Base64.decodeBase64(BytesUtils.toBytes(ledgerSeedStr)));
//
// String consensusProvider = legerInitObj.getString("consensusProvider");
//
// ledgerInitSettingData.setConsensusProvider(consensusProvider);
//
// JSONObject cryptoSettingObj = legerInitObj.getJSONObject("cryptoSetting");
// boolean autoVerifyHash = cryptoSettingObj.getBoolean("autoVerifyHash");
// short hashAlgorithm = cryptoSettingObj.getShort("hashAlgorithm");
//
// CryptoConfig cryptoConfig = new CryptoConfig();
//
// cryptoConfig.setAutoVerifyHash(autoVerifyHash);
//
// cryptoConfig.setHashAlgorithm(hashAlgorithm);
//
// ledgerInitSettingData.setCryptoSetting(cryptoConfig);
//
//
// JSONObject consensusSettingsObj = legerInitObj.getJSONObject("consensusSettings");
// Bytes consensusSettings = Bytes.fromBase58(consensusSettingsObj.getString("value"));
//
// ledgerInitSettingData.setConsensusSettings(consensusSettings);
//
// JSONArray consensusParticipantsArray = legerInitObj.getJSONArray("consensusParticipants");
//
// if (!consensusParticipantsArray.isEmpty()) {
// ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipantsArray.size()];
// for (int i = 0; i < consensusParticipantsArray.size(); i++) {
// JSONObject currConsensusParticipant = consensusParticipantsArray.getJSONObject(i);
// String addressBase58 = currConsensusParticipant.getString("address");
// String name = currConsensusParticipant.getString("name");
// int id = currConsensusParticipant.getInteger("id");
// JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey");
// String pubKeyBase58 = pubKeyObj.getString("value");
// // 生成ParticipantNode对象
// ParticipantCertData participantCertData = new ParticipantCertData(id, addressBase58, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()));
// participantNodes[i] = participantCertData;
// }
// ledgerInitSettingData.setConsensusParticipants(participantNodes);
// }
//
// return new LedgerInitOpTemplate(ledgerInitSettingData);
// }
//
// public static UserRegisterOperation convertUserRegisterOperation(JSONObject jsonObject) {
// JSONObject user = jsonObject.getJSONObject("userID");
// return new UserRegisterOpTemplate(blockchainIdentity(user));
// }
//
// public static ContractCodeDeployOperation convertContractCodeDeployOperation(JSONObject jsonObject) {
// JSONObject contract = jsonObject.getJSONObject("contractID");
// BlockchainIdentityData blockchainIdentity = blockchainIdentity(contract);
//
// String chainCodeStr = jsonObject.getString("chainCode");
// ContractCodeDeployOpTemplate contractCodeDeployOpTemplate = new ContractCodeDeployOpTemplate(blockchainIdentity, BytesUtils.toBytes(chainCodeStr));
// return contractCodeDeployOpTemplate;
// }
//
// public static ContractEventSendOperation convertContractEventSendOperation(JSONObject jsonObject) {
// JSONObject contractAddressObj = jsonObject.getJSONObject("contractAddress");
// String contractAddress = contractAddressObj.getString("value");
// String argsStr = jsonObject.getString("args");
// String event = jsonObject.getString("event");
// return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event, BytesUtils.toBytes(argsStr));
// }
//
// private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) {
// JSONObject addressObj = jsonObject.getJSONObject("address");
// // base58值
// String addressBase58 = addressObj.getString("value");
// Bytes address = Bytes.fromBase58(addressBase58);
//
// JSONObject pubKeyObj = jsonObject.getJSONObject("pubKey");
// // base58值
// String pubKeyBase58 = pubKeyObj.getString("value");
// PubKey pubKey = new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes());
//
// // 生成对应的对象
// return new BlockchainIdentityData(address, pubKey);
// }
//
// public static class CryptoConfig implements CryptoSetting {
//
// private short hashAlgorithm;
//
// private boolean autoVerifyHash;
//
// @Override
// public CryptoProvider[] getSupportedProviders() {
// return new CryptoProvider[0];
// }
//
// @Override
// public short getHashAlgorithm() {
// return hashAlgorithm;
// }
//
// @Override
// public boolean getAutoVerifyHash() {
// return autoVerifyHash;
// }
//
// public void setHashAlgorithm(short hashAlgorithm) {
// this.hashAlgorithm = hashAlgorithm;
// }
//
// public void setAutoVerifyHash(boolean autoVerifyHash) {
// this.autoVerifyHash = autoVerifyHash;
// }
// }
//
// public static class ParticipantCertData implements ParticipantNode{
// private int id;
// private String address;
// private String name;
// private PubKey pubKey;
//
// public ParticipantCertData() {
// }
//
// public ParticipantCertData(ParticipantNode participantNode) {
// this.address = participantNode.getAddress();
// this.name = participantNode.getName();
// this.pubKey = participantNode.getPubKey();
// }
//
// public ParticipantCertData(int id, String address, String name, PubKey pubKey) {
// this.id = id;
// this.address = address;
// this.name = name;
// this.pubKey = pubKey;
// }
//
// @Override
// public String getAddress() {
// return address;
// }
//
// @Override
// public String getName() {
// return name;
// }
//
// @Override
// public PubKey getPubKey() {
// return pubKey;
// }
//
// public int getId() {
// return id;
// }
//
// public void setId(int id) {
// this.id = id;
// }
// }
//
// public static class KvData implements KVDataEntry {
//
// private String key;
//
// private long version;
//
// private DataType dataType;
//
// private Object value;
//
// public KvData() {
// }
//
// public KvData(String key, long version, DataType dataType) {
// this(key, version, dataType, null);
// }
//
// public KvData(String key, long version, DataType dataType, Object value) {
// this.key = key;
// this.version = version;
// this.dataType = dataType;
// this.value = value;
// }
//
// public void setKey(String key) {
// this.key = key;
// }
//
// public void setVersion(long version) {
// this.version = version;
// }
//
// public void setDataType(DataType dataType) {
// this.dataType = dataType;
// }
//
// public void setValue(Object value) {
// this.value = value;
// }
//
// @Override
// public String getKey() {
// return key;
// }
//
// @Override
// public long getVersion() {
// return version;
// }
//
// @Override
// public DataType getType() {
// return dataType;
// }
//
// @Override
// public Object getValue() {
// return value;
// }
// }
//}

+ 5
- 0
source/sdk/sdk-samples/pom.xml View File

@@ -25,6 +25,11 @@
<artifactId>tools-initializer</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>contract-samples</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>


+ 38
- 0
source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDKDemo_Constant.java View File

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

+ 51
- 0
source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Base_Demo.java View File

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

+ 164
- 0
source/sdk/sdk-samples/src/main/java/com/jd/blockchain/sdk/samples/SDK_Contract_Demo.java View File

@@ -0,0 +1,164 @@
package com.jd.blockchain.sdk.samples;

import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.contract.TransferContract;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.transaction.ContractEventExecutor;
import com.jd.blockchain.utils.Bytes;

import static com.jd.blockchain.sdk.samples.SDKDemo_Constant.readChainCodes;

public class SDK_Contract_Demo extends SDK_Base_Demo {

public static void main(String[] args) {
SDK_Contract_Demo demo = new SDK_Contract_Demo();
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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.readAll(address, account);
return transferContract;
});
commit(txTpl);
return eventResult.get();
}

private long readByContract(String address, String account, Bytes contractAddress) {
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
// 使用合约创建
TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
EventResult<Long> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.read(address, account);
return transferContract;
});
commit(txTpl);
return eventResult.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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.transfer(address, from, to, money);
return transferContract;
});
commit(txTpl);
return eventResult.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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.create(address, account, money);
return transferContract;
});
commit(txTpl);
return eventResult.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);
}
}
}

BIN
source/sdk/sdk-samples/src/main/resources/transfer.jar View File


+ 171
- 0
source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDKDemo_Contract_Test.java View File

@@ -0,0 +1,171 @@
package test.com.jd.blockchain.sdk.test;

import com.jd.blockchain.contract.EventResult;
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.*;
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.ContractEventExecutor;
import com.jd.blockchain.utils.Bytes;
import org.junit.Before;
import org.junit.Test;

import static com.jd.blockchain.sdk.samples.SDKDemo_Constant.readChainCodes;

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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.readAll(address, account);
return transferContract;
});
commit(txTpl);
return eventResult.get();
}

private long read(String address, String account, Bytes contractAddress) {
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash);
// 使用合约创建
TransferContract transferContract = txTpl.contract(contractAddress, TransferContract.class);
EventResult<Long> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.read(address, account);
return transferContract;
});
commit(txTpl);
return eventResult.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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.transfer(address, from, to, money);
return transferContract;
});
commit(txTpl);
return eventResult.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);
EventResult<String> eventResult = txTpl.result((ContractEventExecutor<TransferContract>) () -> {
transferContract.create(address, account, money);
return transferContract;
});
commit(txTpl);
return eventResult.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();
}
}

BIN
source/sdk/sdk-samples/src/test/resources/transfer.jar View File


+ 10
- 9
source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java View File

@@ -24,6 +24,7 @@ import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.contract.ReadContract;
import com.jd.blockchain.ledger.*;
@@ -556,9 +557,13 @@ public class IntegrationBase {
// 再提交一个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).setText(key2, value2, -1);
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);

@@ -578,10 +583,7 @@ public class IntegrationBase {

ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);

EventResult<String> read2 = txContract.result((ContractEventExecutor<ReadContract>) () -> {
readContract2.read(newDataAccount.getAddress().toBase58(), key2);
return readContract2;
});
readContract2.read(newDataAccount.getAddress().toBase58(), key2);

ReadContract readContract3 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);

@@ -601,14 +603,13 @@ public class IntegrationBase {

// 通过EventResult获取结果
System.out.printf("readContract1.result = %s \r\n", read1.get());
System.out.printf("readContract2.result = %s \r\n", read2.get());
System.out.printf("readContract3.result = %s \r\n", read3.get());


// 打印结果
// for (OperationResult or : operationResults) {
// System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), or.getResult());
// }
for (OperationResult or : operationResults) {
System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), ContractSerializeUtils.resolve(or.getResult()));
}
//
// // 验证结果
// assertNotNull(contractReturn);


Loading…
Cancel
Save