@@ -42,7 +42,7 @@ public class ContractEventSendOperationHandle implements OperationHandle { | |||||
contract.getAddress().toBase58(),contract.getChaincodeVersion(),contract.getChainCode()). | contract.getAddress().toBase58(),contract.getChaincodeVersion(),contract.getChainCode()). | ||||
processEvent(localContractEventContext); | processEvent(localContractEventContext); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
e.printStackTrace(); | |||||
throw new LedgerException("contract processEvent exception. detail:"+e.getMessage()); | |||||
} | } | ||||
} | } | ||||
@@ -1,21 +1,25 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.base.data.TypeCodes; | |||||
import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.utils.ValueType; | |||||
/** | |||||
* 交易内容; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
@DataContract(code= TypeCodes.TX_CONTENT) | |||||
public interface TransactionContent extends TransactionContentBody, HashObject { | |||||
@Override | |||||
@DataField(order=1, primitiveType = ValueType.BYTES) | |||||
HashDigest getHash(); | |||||
} | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.base.data.TypeCodes; | |||||
import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.utils.ValueType; | |||||
/** | |||||
* 交易内容; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
@DataContract(code= TypeCodes.TX_CONTENT) | |||||
public interface TransactionContent extends TransactionContentBody, HashObject { | |||||
@Override | |||||
@DataField(order=1, primitiveType = ValueType.BYTES) | |||||
HashDigest getHash(); | |||||
//获得交易操作时间; | |||||
@DataField(order=2, primitiveType = ValueType.INT64) | |||||
Long getTxOpTime(); | |||||
} |
@@ -1,36 +1,44 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.base.data.TypeCodes; | |||||
import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.utils.ValueType; | |||||
/** | |||||
* 交易内容; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
@DataContract(code = TypeCodes.TX_CONTENT_BODY) | |||||
public interface TransactionContentBody { | |||||
/** | |||||
* 执行交易的账本地址; | |||||
* | |||||
* 注:除了账本的创世交易之外,任何交易的账本地址都不允许为 null; | |||||
* | |||||
* @return | |||||
*/ | |||||
@DataField(order = 1, primitiveType = ValueType.BYTES) | |||||
HashDigest getLedgerHash(); | |||||
/** | |||||
* 操作列表; | |||||
* | |||||
* @return | |||||
*/ | |||||
@DataField(order = 2, list = true, refContract = true, genericContract = true) | |||||
Operation[] getOperations(); | |||||
} | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.base.data.TypeCodes; | |||||
import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.utils.ValueType; | |||||
/** | |||||
* 交易内容; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
@DataContract(code = TypeCodes.TX_CONTENT_BODY) | |||||
public interface TransactionContentBody { | |||||
/** | |||||
* 执行交易的账本地址; | |||||
* | |||||
* 注:除了账本的创世交易之外,任何交易的账本地址都不允许为 null; | |||||
* | |||||
* @return | |||||
*/ | |||||
@DataField(order = 1, primitiveType = ValueType.BYTES) | |||||
HashDigest getLedgerHash(); | |||||
/** | |||||
* 操作列表; | |||||
* | |||||
* @return | |||||
*/ | |||||
@DataField(order = 2, list = true, refContract = true, genericContract = true) | |||||
Operation[] getOperations(); | |||||
/** | |||||
* 交易操作时间 | |||||
* | |||||
* @return | |||||
*/ | |||||
@DataField(order = 3, primitiveType = ValueType.INT64) | |||||
Long getTxOpTime(); | |||||
} |
@@ -1,88 +1,89 @@ | |||||
package com.jd.blockchain.ledger.data; | |||||
import com.jd.blockchain.binaryproto.BinaryEncodingUtils; | |||||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||||
import com.jd.blockchain.crypto.CryptoUtils; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.ledger.TransactionBuilder; | |||||
import com.jd.blockchain.ledger.TransactionContent; | |||||
import com.jd.blockchain.ledger.TransactionContentBody; | |||||
import com.jd.blockchain.ledger.TransactionRequestBuilder; | |||||
import com.jd.blockchain.utils.Bytes; | |||||
public class TxBuilder implements TransactionBuilder { | |||||
static { | |||||
DataContractRegistry.register(TransactionContentBody.class); | |||||
} | |||||
private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | |||||
private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA256; | |||||
private HashDigest ledgerHash; | |||||
public TxBuilder(HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
@Override | |||||
public HashDigest getLedgerHash() { | |||||
return ledgerHash; | |||||
} | |||||
@Override | |||||
public TransactionRequestBuilder prepareRequest() { | |||||
TransactionContent txContent = prepareContent(); | |||||
return new TxRequestBuilder(txContent); | |||||
} | |||||
@Override | |||||
public TransactionContent prepareContent() { | |||||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | |||||
txContent.addOperations(opFactory.getOperations()); | |||||
byte[] contentBodyBytes = BinaryEncodingUtils.encode(txContent, TransactionContentBody.class); | |||||
HashDigest contentHash = CryptoUtils.hash(defaultHashAlgorithm).hash(contentBodyBytes); | |||||
txContent.setHash(contentHash); | |||||
return txContent; | |||||
} | |||||
@Override | |||||
public LedgerInitOperationBuilder ledgers() { | |||||
return opFactory.ledgers(); | |||||
} | |||||
@Override | |||||
public UserRegisterOperationBuilder users() { | |||||
return opFactory.users(); | |||||
} | |||||
@Override | |||||
public DataAccountRegisterOperationBuilder dataAccounts() { | |||||
return opFactory.dataAccounts(); | |||||
} | |||||
@Override | |||||
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | |||||
return opFactory.dataAccount(accountAddress); | |||||
} | |||||
@Override | |||||
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { | |||||
return opFactory.dataAccount(accountAddress); | |||||
} | |||||
@Override | |||||
public ContractCodeDeployOperationBuilder contracts() { | |||||
return opFactory.contracts(); | |||||
} | |||||
@Override | |||||
public ContractEventSendOperationBuilder contractEvents() { | |||||
return opFactory.contractEvents(); | |||||
} | |||||
} | |||||
package com.jd.blockchain.ledger.data; | |||||
import com.jd.blockchain.binaryproto.BinaryEncodingUtils; | |||||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||||
import com.jd.blockchain.crypto.CryptoUtils; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.ledger.TransactionBuilder; | |||||
import com.jd.blockchain.ledger.TransactionContent; | |||||
import com.jd.blockchain.ledger.TransactionContentBody; | |||||
import com.jd.blockchain.ledger.TransactionRequestBuilder; | |||||
import com.jd.blockchain.utils.Bytes; | |||||
public class TxBuilder implements TransactionBuilder { | |||||
static { | |||||
DataContractRegistry.register(TransactionContentBody.class); | |||||
} | |||||
private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | |||||
private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA256; | |||||
private HashDigest ledgerHash; | |||||
public TxBuilder(HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
@Override | |||||
public HashDigest getLedgerHash() { | |||||
return ledgerHash; | |||||
} | |||||
@Override | |||||
public TransactionRequestBuilder prepareRequest() { | |||||
TransactionContent txContent = prepareContent(); | |||||
return new TxRequestBuilder(txContent); | |||||
} | |||||
@Override | |||||
public TransactionContent prepareContent() { | |||||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | |||||
txContent.addOperations(opFactory.getOperations()); | |||||
txContent.setTxOpTime(System.currentTimeMillis()); | |||||
byte[] contentBodyBytes = BinaryEncodingUtils.encode(txContent, TransactionContentBody.class); | |||||
HashDigest contentHash = CryptoUtils.hash(defaultHashAlgorithm).hash(contentBodyBytes); | |||||
txContent.setHash(contentHash); | |||||
return txContent; | |||||
} | |||||
@Override | |||||
public LedgerInitOperationBuilder ledgers() { | |||||
return opFactory.ledgers(); | |||||
} | |||||
@Override | |||||
public UserRegisterOperationBuilder users() { | |||||
return opFactory.users(); | |||||
} | |||||
@Override | |||||
public DataAccountRegisterOperationBuilder dataAccounts() { | |||||
return opFactory.dataAccounts(); | |||||
} | |||||
@Override | |||||
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | |||||
return opFactory.dataAccount(accountAddress); | |||||
} | |||||
@Override | |||||
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { | |||||
return opFactory.dataAccount(accountAddress); | |||||
} | |||||
@Override | |||||
public ContractCodeDeployOperationBuilder contracts() { | |||||
return opFactory.contracts(); | |||||
} | |||||
@Override | |||||
public ContractEventSendOperationBuilder contractEvents() { | |||||
return opFactory.contractEvents(); | |||||
} | |||||
} |
@@ -1,92 +1,104 @@ | |||||
package com.jd.blockchain.ledger.data; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
import com.jd.blockchain.binaryproto.DConstructor; | |||||
import com.jd.blockchain.binaryproto.FieldSetter; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.ledger.Operation; | |||||
import com.jd.blockchain.ledger.TransactionContent; | |||||
import com.jd.blockchain.utils.io.NumberMask; | |||||
/** | |||||
* 交易内容的数据块; | |||||
* <p> | |||||
* | |||||
* 包含原始交易请求的数据块; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
public class TxContentBlob implements TransactionContent { | |||||
/** | |||||
* 操作数量的最大值; | |||||
*/ | |||||
public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; | |||||
private List<Operation> operationList = new ArrayList<Operation>(); | |||||
private HashDigest hash; | |||||
private HashDigest ledgerHash; | |||||
@DConstructor(name ="TxContentBlob") | |||||
public TxContentBlob(@FieldSetter(name="getLedgerHash", type="HashDigest") HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
/** | |||||
* 交易内容的哈希值; | |||||
*/ | |||||
@Override | |||||
public HashDigest getHash() { | |||||
return this.hash; | |||||
} | |||||
/** | |||||
* 更新交易内容的哈希值; | |||||
* <p> | |||||
* 注:当前对象只充当值对象,不校验指定哈希值的完整性,调用者应该在外部实施完整性校验; | |||||
* @param hash | |||||
*/ | |||||
public void setHash(HashDigest hash) { | |||||
this.hash = hash; | |||||
} | |||||
/** | |||||
* 交易请求链的hash | |||||
* | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public HashDigest getLedgerHash() { | |||||
return ledgerHash; | |||||
} | |||||
public void setLedgerHash(HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
@Override | |||||
public Operation[] getOperations() { | |||||
return operationList.toArray(new Operation[operationList.size()]); | |||||
} | |||||
public void setOperations(Object[] operations) { | |||||
//in array's case ,cast will failed! | |||||
for (Object operation : operations) { | |||||
Operation op = (Operation)operation; | |||||
addOperation(op); | |||||
} | |||||
} | |||||
public void addOperation(Operation operation) { | |||||
operationList.add(operation); | |||||
} | |||||
public void addOperations(Collection<Operation> operations) { | |||||
operationList.addAll(operations); | |||||
} | |||||
} | |||||
package com.jd.blockchain.ledger.data; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
import com.jd.blockchain.binaryproto.DConstructor; | |||||
import com.jd.blockchain.binaryproto.FieldSetter; | |||||
import com.jd.blockchain.crypto.hash.HashDigest; | |||||
import com.jd.blockchain.ledger.Operation; | |||||
import com.jd.blockchain.ledger.TransactionContent; | |||||
import com.jd.blockchain.utils.io.NumberMask; | |||||
/** | |||||
* 交易内容的数据块; | |||||
* <p> | |||||
* | |||||
* 包含原始交易请求的数据块; | |||||
* | |||||
* @author huanghaiquan | |||||
* | |||||
*/ | |||||
public class TxContentBlob implements TransactionContent { | |||||
/** | |||||
* 操作数量的最大值; | |||||
*/ | |||||
public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; | |||||
private List<Operation> operationList = new ArrayList<Operation>(); | |||||
private HashDigest hash; | |||||
private HashDigest ledgerHash; | |||||
//交易操作时间; | |||||
private Long txOpTime; | |||||
@DConstructor(name ="TxContentBlob") | |||||
public TxContentBlob(@FieldSetter(name="getLedgerHash", type="HashDigest") HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
/** | |||||
* 交易内容的哈希值; | |||||
*/ | |||||
@Override | |||||
public HashDigest getHash() { | |||||
return this.hash; | |||||
} | |||||
/** | |||||
* 更新交易内容的哈希值; | |||||
* <p> | |||||
* 注:当前对象只充当值对象,不校验指定哈希值的完整性,调用者应该在外部实施完整性校验; | |||||
* @param hash | |||||
*/ | |||||
public void setHash(HashDigest hash) { | |||||
this.hash = hash; | |||||
} | |||||
/** | |||||
* 交易请求链的hash | |||||
* | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public HashDigest getLedgerHash() { | |||||
return ledgerHash; | |||||
} | |||||
public void setLedgerHash(HashDigest ledgerHash) { | |||||
this.ledgerHash = ledgerHash; | |||||
} | |||||
@Override | |||||
public Operation[] getOperations() { | |||||
return operationList.toArray(new Operation[operationList.size()]); | |||||
} | |||||
public void setOperations(Object[] operations) { | |||||
//in array's case ,cast will failed! | |||||
for (Object operation : operations) { | |||||
Operation op = (Operation)operation; | |||||
addOperation(op); | |||||
} | |||||
} | |||||
public void addOperation(Operation operation) { | |||||
operationList.add(operation); | |||||
} | |||||
public void addOperations(Collection<Operation> operations) { | |||||
operationList.addAll(operations); | |||||
} | |||||
@Override | |||||
public Long getTxOpTime() { | |||||
return txOpTime; | |||||
} | |||||
public void setTxOpTime(Long txOpTime) { | |||||
this.txOpTime = txOpTime; | |||||
} | |||||
} |
@@ -139,7 +139,7 @@ public class IntegrationTest4Bftsmart { | |||||
} | } | ||||
try { | try { | ||||
Thread.sleep(60000); | |||||
Thread.sleep(60000000); | |||||
} catch (InterruptedException e) { | } catch (InterruptedException e) { | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
} | } | ||||