@@ -31,7 +31,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl(); | private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl(); | ||||
private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter(); | private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter(); | ||||
private UserRegisterOperationBuilder userRegOpBuilder = new UserRegisterOperationBuilderFilter(); | private UserRegisterOperationBuilder userRegOpBuilder = new UserRegisterOperationBuilderFilter(); | ||||
@@ -42,6 +41,8 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
private ContractEventSendOperationBuilder contractEventSendOpBuilder = new ContractEventSendOperationBuilderFilter(); | private ContractEventSendOperationBuilder contractEventSendOpBuilder = new ContractEventSendOperationBuilderFilter(); | ||||
private ContractInvocationProxyBuilder contractInvoProxyBuilder = new ContractInvocationProxyBuilder(); | |||||
private List<Operation> operationList = new ArrayList<>(); | private List<Operation> operationList = new ArrayList<>(); | ||||
@Override | @Override | ||||
@@ -77,11 +78,15 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
public ContractEventSendOperationBuilder contractEvents() { | public ContractEventSendOperationBuilder contractEvents() { | ||||
return contractEventSendOpBuilder; | return contractEventSendOpBuilder; | ||||
} | } | ||||
@Override | @Override | ||||
public <T> T contract(String address, Class<T> contractIntf) { | public <T> T contract(String address, Class<T> contractIntf) { | ||||
// TODO Auto-generated method stub | |||||
return null; | |||||
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder); | |||||
} | |||||
@Override | |||||
public <T> T contract(Bytes address, Class<T> contractIntf) { | |||||
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder); | |||||
} | } | ||||
public Collection<Operation> getOperations() { | public Collection<Operation> getOperations() { | ||||
@@ -152,6 +157,7 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
@Override | @Override | ||||
public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { | public DataAccountKVSetOperationBuilder set(String key, String value, long expVersion) { | ||||
innerBuilder.set(key, value, expVersion); | innerBuilder.set(key, value, expVersion); | ||||
@@ -161,6 +167,7 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
@Override | @Override | ||||
public DataAccountKVSetOperationBuilder set(String key, long value, long expVersion) { | public DataAccountKVSetOperationBuilder set(String key, long value, long expVersion) { | ||||
innerBuilder.set(key, value, expVersion); | innerBuilder.set(key, value, expVersion); | ||||
@@ -170,6 +177,7 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
@Override | @Override | ||||
public DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion) { | public DataAccountKVSetOperationBuilder set(String key, Bytes value, long expVersion) { | ||||
innerBuilder.set(key, value, expVersion); | innerBuilder.set(key, value, expVersion); | ||||
@@ -9,16 +9,16 @@ public class ContractInvocationProxyBuilder { | |||||
private Map<Class<?>, ContractType> contractTypes; | private Map<Class<?>, ContractType> contractTypes; | ||||
public <T> T create(String address, Class<T> contractIntf, BlockchainOperationFactory opFactory) { | |||||
return create(Bytes.fromBase58(address), contractIntf, opFactory); | |||||
public <T> T create(String address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) { | |||||
return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder); | |||||
} | } | ||||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
public <T> T create(Bytes address, Class<T> contractIntf, BlockchainOperationFactory opFactory) { | |||||
public <T> T create(Bytes address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) { | |||||
ContractType contractType = resolveContractType(contractIntf); | ContractType contractType = resolveContractType(contractIntf); | ||||
ContractInvocationProxy proxyHandler = new ContractInvocationProxy(address, contractType, | ContractInvocationProxy proxyHandler = new ContractInvocationProxy(address, contractType, | ||||
opFactory.contractEvents()); | |||||
contractEventBuilder); | |||||
T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), | T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), | ||||
new Class<?>[] { contractIntf }, proxyHandler); | new Class<?>[] { contractIntf }, proxyHandler); | ||||
@@ -19,10 +19,8 @@ public class TxBuilder implements TransactionBuilder { | |||||
private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | ||||
private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; | private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; | ||||
private HashDigest ledgerHash; | private HashDigest ledgerHash; | ||||
private ContractInvocationProxyBuilder contractInvoProxyBuilder; | |||||
public TxBuilder(HashDigest ledgerHash) { | public TxBuilder(HashDigest ledgerHash) { | ||||
this.ledgerHash = ledgerHash; | this.ledgerHash = ledgerHash; | ||||
@@ -38,16 +36,16 @@ public class TxBuilder implements TransactionBuilder { | |||||
TransactionContent txContent = prepareContent(); | TransactionContent txContent = prepareContent(); | ||||
return new TxRequestBuilder(txContent); | return new TxRequestBuilder(txContent); | ||||
} | } | ||||
@Override | @Override | ||||
public TransactionContent prepareContent() { | public TransactionContent prepareContent() { | ||||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | TxContentBlob txContent = new TxContentBlob(ledgerHash); | ||||
txContent.addOperations(opFactory.getOperations()); | txContent.addOperations(opFactory.getOperations()); | ||||
byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); | byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); | ||||
HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); | HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); | ||||
txContent.setHash(contentHash); | txContent.setHash(contentHash); | ||||
return txContent; | return txContent; | ||||
} | } | ||||
@@ -55,7 +53,7 @@ public class TxBuilder implements TransactionBuilder { | |||||
public LedgerInitOperationBuilder ledgers() { | public LedgerInitOperationBuilder ledgers() { | ||||
return opFactory.ledgers(); | return opFactory.ledgers(); | ||||
} | } | ||||
@Override | @Override | ||||
public UserRegisterOperationBuilder users() { | public UserRegisterOperationBuilder users() { | ||||
return opFactory.users(); | return opFactory.users(); | ||||
@@ -65,7 +63,7 @@ public class TxBuilder implements TransactionBuilder { | |||||
public DataAccountRegisterOperationBuilder dataAccounts() { | public DataAccountRegisterOperationBuilder dataAccounts() { | ||||
return opFactory.dataAccounts(); | return opFactory.dataAccounts(); | ||||
} | } | ||||
@Override | @Override | ||||
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | ||||
return opFactory.dataAccount(accountAddress); | return opFactory.dataAccount(accountAddress); | ||||
@@ -84,15 +82,15 @@ public class TxBuilder implements TransactionBuilder { | |||||
public ContractEventSendOperationBuilder contractEvents() { | public ContractEventSendOperationBuilder contractEvents() { | ||||
return opFactory.contractEvents(); | return opFactory.contractEvents(); | ||||
} | } | ||||
@Override | @Override | ||||
public <T> T contract(Bytes address, Class<T> contractIntf) { | public <T> T contract(Bytes address, Class<T> contractIntf) { | ||||
return contractInvoProxyBuilder.create(address, contractIntf, opFactory); | |||||
return opFactory.contract(address, contractIntf); | |||||
} | } | ||||
@Override | @Override | ||||
public <T> T contract(String address, Class<T> contractIntf) { | public <T> T contract(String address, Class<T> contractIntf) { | ||||
return contractInvoProxyBuilder.create(address, contractIntf, opFactory); | |||||
return opFactory.contract(address, contractIntf); | |||||
} | } | ||||
} | } |
@@ -58,6 +58,11 @@ public class TxTemplate implements TransactionTemplate { | |||||
// return txBuilder.contractEvents(); | // return txBuilder.contractEvents(); | ||||
// } | // } | ||||
@Override | |||||
public <T> T contract(Bytes address, Class<T> contractIntf) { | |||||
return txBuilder.contract(address, contractIntf); | |||||
} | |||||
@Override | @Override | ||||
public <T> T contract(String address, Class<T> contractIntf) { | public <T> T contract(String address, Class<T> contractIntf) { | ||||
return txBuilder.contract(address, contractIntf); | return txBuilder.contract(address, contractIntf); | ||||
@@ -547,87 +547,87 @@ public class IntegrationTest { | |||||
} | } | ||||
} | } | ||||
private LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||||
BlockchainService blockchainService, IntegratedContext context) { | |||||
// valid the basic data in contract; | |||||
prepareContractData(adminKey, ledgerHash, blockchainService, context); | |||||
BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||||
// 定义交易; | |||||
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||||
byte[] contractCode = getChainCodeBytes(); | |||||
txTpl.users().register(userKey.getIdentity()); | |||||
txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||||
// 签名; | |||||
PreparedTransaction ptx = txTpl.prepare(); | |||||
ptx.sign(adminKey); | |||||
// 提交并等待共识返回; | |||||
TransactionResponse txResp = ptx.commit(); | |||||
// 验证结果; | |||||
txResp.getContentHash(); | |||||
Node node0 = context.getNode(0); | |||||
LedgerRepository ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||||
LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); | |||||
byte[] contractCodeInDb = ledgerOfNode0.getContractAccountSet(block).getContract(contractDeployKey.getAddress()) | |||||
.getChainCode(); | |||||
txContentHash = ptx.getHash(); | |||||
// execute the contract; | |||||
testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||||
return block; | |||||
} | |||||
private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||||
BlockchainService blockchainService, IntegratedContext context) { | |||||
LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||||
LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||||
// 定义交易; | |||||
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||||
txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, | |||||
("888##abc##" + contractDataKey.getAddress() + "##" + previousBlock.getHash().toBase58() + "##" | |||||
+ userKey.getAddress() + "##" + contractDeployKey.getAddress() + "##" + txContentHash.toBase58() | |||||
+ "##SOME-VALUE").getBytes()); | |||||
// 签名; | |||||
PreparedTransaction ptx = txTpl.prepare(); | |||||
ptx.sign(adminKey); | |||||
// 提交并等待共识返回; | |||||
TransactionResponse txResp = ptx.commit(); | |||||
// 验证结果; | |||||
txResp.getContentHash(); | |||||
LedgerInfo latestLedgerInfo = blockchainService.getLedger(ledgerHash); | |||||
Node node0 = context.getNode(0); | |||||
LedgerRepository ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||||
LedgerBlock backgroundLedgerBlock = ledgerOfNode0.retrieveLatestBlock(); | |||||
// 验证合约中的赋值,外部可以获得; | |||||
DataAccountSet dataAccountSet = ledgerOfNode0.getDataAccountSet(backgroundLedgerBlock); | |||||
AsymmetricKeypair key = Crypto.getSignatureFunction("ED25519").generateKeypair(); | |||||
PubKey pubKey = key.getPubKey(); | |||||
Bytes dataAddress = AddressEncoding.generateAddress(pubKey); | |||||
// 验证userAccount,从合约内部赋值,然后外部验证;由于目前不允许输入重复的key,所以在内部合约中构建的key,不便于在外展示,屏蔽之; | |||||
// UserAccountSet userAccountSet = | |||||
// ledgerOfNode0.getUserAccountSet(backgroundLedgerBlock); | |||||
// PubKey userPubKey = new PubKey(CryptoAlgorithm.ED25519, | |||||
// userPubKeyVal.getBytes()); | |||||
// String userAddress = AddressEncoding.generateAddress(userPubKey); | |||||
// assertEquals(userAddress, userAccountSet.getUser(userAddress).getAddress()); | |||||
} | |||||
// private LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||||
// BlockchainService blockchainService, IntegratedContext context) { | |||||
// // valid the basic data in contract; | |||||
// prepareContractData(adminKey, ledgerHash, blockchainService, context); | |||||
// | |||||
// BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||||
// | |||||
// // 定义交易; | |||||
// TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||||
// byte[] contractCode = getChainCodeBytes(); | |||||
// | |||||
// txTpl.users().register(userKey.getIdentity()); | |||||
// | |||||
// txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||||
// | |||||
// // 签名; | |||||
// PreparedTransaction ptx = txTpl.prepare(); | |||||
// ptx.sign(adminKey); | |||||
// | |||||
// // 提交并等待共识返回; | |||||
// TransactionResponse txResp = ptx.commit(); | |||||
// | |||||
// // 验证结果; | |||||
// txResp.getContentHash(); | |||||
// | |||||
// Node node0 = context.getNode(0); | |||||
// LedgerRepository ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||||
// LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); | |||||
// byte[] contractCodeInDb = ledgerOfNode0.getContractAccountSet(block).getContract(contractDeployKey.getAddress()) | |||||
// .getChainCode(); | |||||
// txContentHash = ptx.getHash(); | |||||
// | |||||
// // execute the contract; | |||||
// testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||||
// | |||||
// return block; | |||||
// } | |||||
// private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||||
// BlockchainService blockchainService, IntegratedContext context) { | |||||
// LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||||
// LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||||
// | |||||
// // 定义交易; | |||||
// TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||||
// | |||||
// txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, | |||||
// ("888##abc##" + contractDataKey.getAddress() + "##" + previousBlock.getHash().toBase58() + "##" | |||||
// + userKey.getAddress() + "##" + contractDeployKey.getAddress() + "##" + txContentHash.toBase58() | |||||
// + "##SOME-VALUE").getBytes()); | |||||
// | |||||
// // 签名; | |||||
// PreparedTransaction ptx = txTpl.prepare(); | |||||
// ptx.sign(adminKey); | |||||
// | |||||
// // 提交并等待共识返回; | |||||
// TransactionResponse txResp = ptx.commit(); | |||||
// | |||||
// // 验证结果; | |||||
// txResp.getContentHash(); | |||||
// | |||||
// LedgerInfo latestLedgerInfo = blockchainService.getLedger(ledgerHash); | |||||
// | |||||
// Node node0 = context.getNode(0); | |||||
// LedgerRepository ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||||
// LedgerBlock backgroundLedgerBlock = ledgerOfNode0.retrieveLatestBlock(); | |||||
// | |||||
// // 验证合约中的赋值,外部可以获得; | |||||
// DataAccountSet dataAccountSet = ledgerOfNode0.getDataAccountSet(backgroundLedgerBlock); | |||||
// AsymmetricKeypair key = Crypto.getSignatureFunction("ED25519").generateKeypair(); | |||||
// PubKey pubKey = key.getPubKey(); | |||||
// Bytes dataAddress = AddressEncoding.generateAddress(pubKey); | |||||
// | |||||
// // 验证userAccount,从合约内部赋值,然后外部验证;由于目前不允许输入重复的key,所以在内部合约中构建的key,不便于在外展示,屏蔽之; | |||||
// // UserAccountSet userAccountSet = | |||||
// // ledgerOfNode0.getUserAccountSet(backgroundLedgerBlock); | |||||
// // PubKey userPubKey = new PubKey(CryptoAlgorithm.ED25519, | |||||
// // userPubKeyVal.getBytes()); | |||||
// // String userAddress = AddressEncoding.generateAddress(userPubKey); | |||||
// // assertEquals(userAddress, userAccountSet.getUser(userAddress).getAddress()); | |||||
// } | |||||
private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, | private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, | ||||
IntegratedContext context) { | IntegratedContext context) { | ||||