Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/main/java/cn/hyperchain/sdk/service/ContractService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ public interface ContractService {
Request<TxHashResponse> invoke(Transaction transaction, int... nodeIds);

Request<ReceiptResponse> getReceipt(String txHash, int... nodeIds);

Request<TxHashResponse> maintain(Transaction transaction, int... nodeIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,27 @@ public Request<ReceiptResponse> getReceipt(String txHash, int... nodeIds) {

receiptResponsePollingRequest.addParams(txHash);
receiptResponsePollingRequest.setJsonrpc(jsonrpc);
receiptResponsePollingRequest.setJsonrpc(namespace);
receiptResponsePollingRequest.setNamespace(namespace);

return receiptResponsePollingRequest;
}

@Override
public Request<TxHashResponse> maintain(Transaction transaction, int... nodeIds) {
ContractRequest<TxHashResponse> txHashResponseContractRequest = new ContractRequest<TxHashResponse>(CONTRACT_PREFIX + "maintainContract", providerManager, TxHashResponse.class, transaction, nodeIds);

Map<String, Object> params = commonParamMap(transaction);
params.put("to", transaction.getTo());
params.put("opcode", transaction.getOpCode());

txHashResponseContractRequest.addParams(params);
txHashResponseContractRequest.setJsonrpc(jsonrpc);
txHashResponseContractRequest.setNamespace(namespace);
txHashResponseContractRequest.setContractService(this);

return txHashResponseContractRequest;
}

private Map<String, Object> commonParamMap(Transaction transaction) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("from", transaction.getFrom());
Expand Down
80 changes: 66 additions & 14 deletions src/main/java/cn/hyperchain/sdk/transaction/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import java.util.Date;

public class Transaction {
private Transaction() {}
private Transaction() {
}

private static final Logger logger = Logger.getLogger(Transaction.class);

Expand All @@ -34,6 +35,7 @@ public static class Builder {

/**
* create transfer or generate transaction.
*
* @param from account address
*/
public Builder(String from) {
Expand All @@ -44,7 +46,8 @@ public Builder(String from) {

/**
* create a transform transaction from account A to account B.
* @param to origin account
*
* @param to origin account
* @param value goal account
* @return {@link Builder}
*/
Expand All @@ -56,6 +59,7 @@ public Builder transfer(String to, long value) {

/**
* make transaction status is simulate.
*
* @return {@link Builder}
*/
public Builder simulate() {
Expand All @@ -65,6 +69,7 @@ public Builder simulate() {

/**
* add transaction extra info.
*
* @param extra extra data
* @return {@link Builder}
*/
Expand All @@ -73,8 +78,46 @@ public Builder extra(String extra) {
return this;
}

/**
* upgrade contract.
*
* @param contractAddress contract address in chain
* @param payload payload of the new contract
* @return {@link Builder}
*/
public Builder upgrade(String contractAddress, String payload) {
transaction.setPayload(payload);
transaction.setTo(contractAddress);
transaction.setOpCode(1);
return this;
}

/**
* freeze contract.
*
* @param contractAddress contract address in chain
* @return {@link Builder}
*/
public Builder freeze(String contractAddress) {
transaction.setOpCode(2);
transaction.setTo(contractAddress);
return this;
}

/**
* unfreeze contract.
* @param contractAddress contract address in chain
* @return {@link Builder}
*/
public Builder unfreeze(String contractAddress) {
transaction.setTo(contractAddress);
transaction.setOpCode(3);
return this;
}

/**
* build transaction instance.
*
* @return {@link Transaction}
*/
public Transaction build() {
Expand All @@ -93,6 +136,7 @@ public HVMBuilder(String from) {

/**
* create deployment transaction for {@link VMType} HVM.
*
* @param fis FileInputStream for the given jar file
* @return {@link Builder}
*/
Expand All @@ -105,8 +149,9 @@ public Builder deploy(InputStream fis) {

/**
* create invoking transaction for {@link VMType} HVM.
*
* @param contractAddress contract address in chain
* @param baseInvoke an instance of {@link BaseInvoke}
* @param baseInvoke an instance of {@link BaseInvoke}
* @return {@link Builder}
*/
public Builder invoke(String contractAddress, BaseInvoke baseInvoke) {
Expand All @@ -115,6 +160,8 @@ public Builder invoke(String contractAddress, BaseInvoke baseInvoke) {
super.transaction.setPayload(payload);
return this;
}


}

public static class EVMBuilder extends Builder {
Expand All @@ -125,6 +172,7 @@ public EVMBuilder(String from) {

/**
* deploy Solidity contract bin.
*
* @param bin contract bin
* @return {@link Builder}
*/
Expand All @@ -136,8 +184,9 @@ public Builder deploy(String bin) {

/**
* deploy Solidity contract bin with params.
* @param bin contract bin
* @param abi contract abi
*
* @param bin contract bin
* @param abi contract abi
* @param params deploy contract params
* @return {@link Builder}
*/
Expand All @@ -150,9 +199,10 @@ public Builder deploy(String bin, Abi abi, Object... params) {

/**
* invoke Solidity contract whit specific method and params.
*
* @param methodName method name
* @param abi contract abi
* @param params invoke params
* @param abi contract abi
* @param params invoke params
* @return {@link Builder}
*/
public Builder invoke(String contractAddress, String methodName, Abi abi, Object... params) {
Expand All @@ -161,18 +211,20 @@ public Builder invoke(String contractAddress, String methodName, Abi abi, Object
super.transaction.setPayload(payload);
return this;
}


}

private void setNeedHashString() {
String value = Utils.isBlank(this.payload) ? String.valueOf(this.value) : this.payload;
this.needHashString = "from=" + chPrefix(this.from.toLowerCase())
+ "&to=" + chPrefix(this.to.toLowerCase())
+ "&value=" + chPrefix(value).toLowerCase()
+ "&timestamp=0x" + Long.toHexString(this.timestamp)
+ "&nonce=0x" + Long.toHexString(this.nonce)
+ "&opcode=" + this.opCode
+ "&extra=" + this.extra
+ "&vmtype=" + this.vmType.getType();
+ "&to=" + chPrefix(this.to.toLowerCase())
+ "&value=" + chPrefix(value).toLowerCase()
+ "&timestamp=0x" + Long.toHexString(this.timestamp)
+ "&nonce=0x" + Long.toHexString(this.nonce)
+ "&opcode=" + this.opCode
+ "&extra=" + this.extra
+ "&vmtype=" + this.vmType.getType();
}

public void sign(Account account) {
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/cn/hyperchain/sdk/EVMTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void testEVM() throws Exception {
String bin = FileUtil.readFile(inputStream1);
String abiStr = FileUtil.readFile(inputStream2);
Abi abi = Abi.fromJson(abiStr);

Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).deploy(bin, abi, "contract01").build();
transaction.sign(account);
ReceiptResponse receiptResponse = contractService.deploy(transaction).send().polling();
Expand All @@ -68,5 +69,27 @@ public void testEVM() throws Exception {
System.out.println(o.getClass());
System.out.println(new String((byte[]) o));
}

System.out.println("*********************************************************************");
// maintain contract test

// test freeze
Transaction transaction2 = new Transaction.EVMBuilder(account.getAddress()).upgrade(contractAddress, bin).build();
transaction2.sign(account);
ReceiptResponse receiptResponse2 = contractService.maintain(transaction2).send().polling();
System.out.println(receiptResponse2.getRet());

// test thaw
Transaction transaction3 = new Transaction.EVMBuilder(account.getAddress()).freeze(contractAddress).build();
transaction3.sign(account);
ReceiptResponse receiptResponse3 = contractService.maintain(transaction3).send().polling();
System.out.println(receiptResponse3.getRet());

// test upgrade
Transaction transaction4 = new Transaction.EVMBuilder(account.getAddress()).unfreeze(contractAddress).build();
transaction4.sign(account);
ReceiptResponse receiptResponse4 = contractService.maintain(transaction4).send().polling();
System.out.println(receiptResponse4.getRet());

}
}
28 changes: 25 additions & 3 deletions src/test/java/cn/hyperchain/sdk/HVMTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import cn.hyperchain.sdk.hvm.StudentInvoke;
import cn.hyperchain.sdk.provider.DefaultHttpProvider;
import cn.hyperchain.sdk.provider.ProviderManager;
import cn.hyperchain.sdk.request.Request;
import cn.hyperchain.sdk.response.ReceiptResponse;
import cn.hyperchain.sdk.response.TxHashResponse;
import cn.hyperchain.sdk.service.AccountService;
import cn.hyperchain.sdk.service.ContractService;
import cn.hyperchain.sdk.service.ServiceManager;
Expand Down Expand Up @@ -38,6 +40,7 @@ public void testHVM() throws RequestException, IOException {
AccountService accountService = ServiceManager.getAccountService(providerManager);
// 3. build transaction
Account account = accountService.genAccount(Algo.SMRAW);
Account backup = account;
InputStream payload = FileUtil.readFileAsStream("hvm-jar/hvmbasic-1.0.0-student.jar");
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).deploy(payload).build();
transaction.sign(accountService.fromAccountJson(account.toJson()));
Expand All @@ -46,19 +49,38 @@ public void testHVM() throws RequestException, IOException {
// 4. get request
ReceiptResponse receiptResponse = contractService.deploy(transaction).send().polling();
// 5. polling && get result && decode result
System.out.println("合约地址: " + receiptResponse.getContractAddress());
String contractAddress = receiptResponse.getContractAddress();
System.out.println("合约地址: " + contractAddress);
System.out.println("部署返回(未解码): " + receiptResponse.getRet());
System.out.println("部署返回(解码):" + Decoder.decodeHVM(receiptResponse.getRet(), String.class));
// 6. invoke
account = accountService.genAccount(Algo.ECRAW);
Transaction transaction1 = new Transaction.HVMBuilder(account.getAddress()).invoke(receiptResponse.getContractAddress(), new StudentInvoke()).build();
Transaction transaction1 = new Transaction.HVMBuilder(account.getAddress()).invoke(contractAddress, new StudentInvoke()).build();
transaction1.sign(accountService.fromAccountJson(account.toJson()));
Assert.assertTrue(account.verify(transaction1.getNeedHashString().getBytes(), ByteUtil.fromHex(transaction1.getSignature())));
Assert.assertTrue(SignerUtil.verifySign(transaction1.getNeedHashString(), transaction1.getSignature(), account.getPublicKey()));
// 7. request
ReceiptResponse receiptResponse1 = contractService.invoke(transaction1).send().polling();
TxHashResponse txHashResponse = contractService.invoke(transaction1).send();
ReceiptResponse receiptResponse1 = txHashResponse.polling();
// 8. get result & decode result
System.out.println("调用返回(未解码): " + receiptResponse1.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse1.getRet(), String.class));

Transaction transaction2 = new Transaction.HVMBuilder(backup.getAddress()).freeze(contractAddress).build();
transaction2.sign(backup);
Assert.assertTrue(backup.verify(transaction2.getNeedHashString().getBytes(), ByteUtil.fromHex(transaction2.getSignature())));
Assert.assertTrue(SignerUtil.verifySign(transaction2.getNeedHashString(), transaction2.getSignature(), backup.getPublicKey()));
TxHashResponse response = contractService.maintain(transaction2).send();
ReceiptResponse receiptResponse2 = response.polling();
System.out.println("调用返回(未解码): " + receiptResponse2.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse2.getRet(), String.class));

Transaction transaction3 = new Transaction.HVMBuilder(backup.getAddress()).unfreeze(contractAddress).build();
transaction3.sign(backup);
Assert.assertTrue(backup.verify(transaction2.getNeedHashString().getBytes(), ByteUtil.fromHex(transaction2.getSignature())));
Assert.assertTrue(SignerUtil.verifySign(transaction2.getNeedHashString(), transaction2.getSignature(), backup.getPublicKey()));
ReceiptResponse receiptResponse3 = contractService.maintain(transaction3).send().polling();
System.out.println("调用返回(未解码): " + receiptResponse3.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse3.getRet(), String.class));
}
}