diff --git a/hiero-enterprise-base/src/main/java/org/hiero/base/SmartContractClient.java b/hiero-enterprise-base/src/main/java/org/hiero/base/SmartContractClient.java index 40393868..01b22566 100644 --- a/hiero-enterprise-base/src/main/java/org/hiero/base/SmartContractClient.java +++ b/hiero-enterprise-base/src/main/java/org/hiero/base/SmartContractClient.java @@ -1,7 +1,12 @@ package org.hiero.base; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.DEFAULT_GAS; +import static org.hiero.base.protocol.data.ContractCreateRequest.DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE; +import static org.hiero.base.protocol.data.TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE; + import com.hedera.hashgraph.sdk.ContractId; import com.hedera.hashgraph.sdk.FileId; +import com.hedera.hashgraph.sdk.Hbar; import java.nio.file.Path; import java.util.Objects; import org.hiero.base.data.ContractCallResult; @@ -16,7 +21,6 @@ * 'operator account'. */ public interface SmartContractClient { - /** * Create a new smart contract based on the file the given file ID. The file must contain the * bytecode for the contract. @@ -30,8 +34,12 @@ public interface SmartContractClient { default ContractId createContract( @NonNull String fileId, @Nullable ContractParam... constructorParams) throws HieroException { - Objects.requireNonNull(fileId, "fileId"); - return createContract(FileId.fromString(fileId), constructorParams); + Objects.requireNonNull(fileId, "fileId must not be null"); + return createContract( + FileId.fromString(fileId), + DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, + DEFAULT_GAS, + constructorParams); } /** @@ -43,9 +51,13 @@ default ContractId createContract( * @return the ID of the new contract * @throws HieroException if the contract could not be created */ - @NonNull ContractId createContract( + default @NonNull ContractId createContract( @NonNull FileId fileId, @Nullable ContractParam... constructorParams) - throws HieroException; + throws HieroException { + Objects.requireNonNull(fileId, "fileId must not be null"); + return createContract( + fileId, DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, DEFAULT_GAS, constructorParams); + } /** * Create a new smart contract with the given contents. The contents must be the bytecode for the @@ -56,9 +68,13 @@ default ContractId createContract( * @return the ID of the new contract * @throws HieroException if the contract could not be created */ - @NonNull ContractId createContract( + default @NonNull ContractId createContract( @NonNull byte[] contents, @Nullable ContractParam... constructorParams) - throws HieroException; + throws HieroException { + Objects.requireNonNull(contents, "contents must not be null"); + return createContract( + contents, DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, DEFAULT_GAS, constructorParams); + } /** * Create a new smart contract based on a file. The contents of the file must be the bytecode for @@ -69,8 +85,89 @@ default ContractId createContract( * @return the ID of the new contract * @throws HieroException if the contract could not be created */ - @NonNull ContractId createContract( + default @NonNull ContractId createContract( @NonNull Path pathToBin, @Nullable ContractParam... constructorParams) + throws HieroException { + Objects.requireNonNull(pathToBin, "pathToBin must not be null"); + return createContract( + pathToBin, DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, DEFAULT_GAS, constructorParams); + } + + /** + * Create a new smart contract based on the file the given file ID, using a custom max transaction + * fee and gas. The file must contain the bytecode for the contract. + * + * @param fileId the ID of the file containing the contract bytecode + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param constructorParams the parameters to pass to the contract constructor + * @return the ID of the new contract + * @throws HieroException if the contract could not be created + */ + default @NonNull ContractId createContract( + @NonNull String fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) + throws HieroException { + Objects.requireNonNull(fileId, "fileId must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + + return createContract(FileId.fromString(fileId), maxTransactionFee, gas, constructorParams); + } + + /** + * Create a new smart contract based on the file with the given file ID, using a custom max + * transaction fee and gas. The file must contain the bytecode for the contract. + * + * @param fileId the ID of the file containing the contract bytecode + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param constructorParams the parameters to pass to the contract constructor + * @return the ID of the new contract + * @throws HieroException if the contract could not be created + */ + @NonNull ContractId createContract( + @NonNull FileId fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) + throws HieroException; + + /** + * Create a new smart contract with the given contents, using a custom maximum transaction fee and + * gas. The contents must be the bytecode for the contract. + * + * @param contents the contents of the contract + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param constructorParams the parameters to pass to the contract constructor + * @return the ID of the new contract + * @throws HieroException if the contract could not be created + */ + @NonNull ContractId createContract( + @NonNull byte[] contents, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) + throws HieroException; + + /** + * Create a new smart contract based on a local file, using a custom maximum transaction fee and + * gas. The contents of the file must be the bytecode for the contract. + * + * @param pathToBin the path to the file containing the contract bytecode + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param constructorParams the parameters to pass to the contract constructor + * @return the ID of the new contract + * @throws HieroException if the contract could not be created + */ + @NonNull ContractId createContract( + @NonNull Path pathToBin, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) throws HieroException; /** @@ -88,8 +185,15 @@ default ContractCallResult callContractFunction( @NonNull String functionName, @Nullable ContractParam... params) throws HieroException { - Objects.requireNonNull(contractId, "contractId"); - return callContractFunction(ContractId.fromString(contractId), functionName, params); + Objects.requireNonNull(contractId, "contractId must not be null"); + Objects.requireNonNull(functionName, "functionName must not be null"); + + return callContractFunction( + ContractId.fromString(contractId), + functionName, + DEFAULT_MAX_TRANSACTION_FEE, + DEFAULT_GAS, + params); } /** @@ -101,9 +205,61 @@ default ContractCallResult callContractFunction( * @return the result of the function call * @throws HieroException if the function could not be called */ + default @NonNull ContractCallResult callContractFunction( + @NonNull ContractId contractId, + @NonNull String functionName, + @Nullable ContractParam... params) + throws HieroException { + Objects.requireNonNull(contractId, "contractId must not be null"); + Objects.requireNonNull(functionName, "functionName must not be null"); + + return callContractFunction( + contractId, functionName, DEFAULT_MAX_TRANSACTION_FEE, DEFAULT_GAS, params); + } + + /** + * Call a function on a smart contract with custom max transaction fee and gas. + * + * @param contractId the ID of the contract + * @param functionName the name of the function to call + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param params the parameters to pass to the function + * @return the result of the function call + * @throws HieroException if the function could not be called + */ + @NonNull + default ContractCallResult callContractFunction( + @NonNull String contractId, + @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... params) + throws HieroException { + Objects.requireNonNull(contractId, "contractId must not be null"); + Objects.requireNonNull(functionName, "functionName must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + + return callContractFunction( + ContractId.fromString(contractId), functionName, maxTransactionFee, gas, params); + } + + /** + * Call a function on a smart contract with custom max transaction fee and gas. + * + * @param contractId the ID of the contract + * @param functionName the name of the function to call + * @param maxTransactionFee the custom max transaction fee in Hbar + * @param gas the custom max gas that can be spent + * @param params the parameters to pass to the function + * @return the result of the function call + * @throws HieroException if the function could not be called + */ @NonNull ContractCallResult callContractFunction( @NonNull ContractId contractId, @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, @Nullable ContractParam... params) throws HieroException; } diff --git a/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/ProtocolLayerClientImpl.java b/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/ProtocolLayerClientImpl.java index d9a77f6e..24574040 100644 --- a/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/ProtocolLayerClientImpl.java +++ b/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/ProtocolLayerClientImpl.java @@ -120,6 +120,7 @@ public class ProtocolLayerClientImpl implements ProtocolLayerClient { private static final Logger log = LoggerFactory.getLogger(ProtocolLayerClientImpl.class); public static final int DEFAULT_GAS = 5_000_000; + public static final int MAX_GAS_LIMIT = 15_000_000; private final List listeners; @@ -282,7 +283,7 @@ public ContractCreateResult executeContractCreateTransaction( .setMaxTransactionFee(request.maxTransactionFee()) .setTransactionValidDuration(request.transactionValidDuration()) .setBytecodeFileId(request.fileId()) - .setGas(DEFAULT_GAS) + .setGas(request.gas()) .setConstructorParameters(constructorParams); final TransactionReceipt receipt = executeTransactionAndWaitOnReceipt(transaction, TransactionType.CONTRACT_CREATE); @@ -321,7 +322,7 @@ public ContractCallResult executeContractCallTransaction( .setTransactionValidDuration(request.transactionValidDuration()) .setContractId(request.contractId()) .setFunction(request.functionName(), functionParams) - .setGas(DEFAULT_GAS); + .setGas(request.gas()); final TransactionRecord record = executeTransactionAndWaitOnRecord(transaction, TransactionType.CONTRACT_CALL); return new ContractCallResult( diff --git a/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/SmartContractClientImpl.java b/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/SmartContractClientImpl.java index b1d3abb5..e1e5a809 100644 --- a/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/SmartContractClientImpl.java +++ b/hiero-enterprise-base/src/main/java/org/hiero/base/implementation/SmartContractClientImpl.java @@ -1,8 +1,11 @@ package org.hiero.base.implementation; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.MAX_GAS_LIMIT; + import com.hedera.hashgraph.sdk.ContractFunctionResult; import com.hedera.hashgraph.sdk.ContractId; import com.hedera.hashgraph.sdk.FileId; +import com.hedera.hashgraph.sdk.Hbar; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -39,14 +42,27 @@ public SmartContractClientImpl( @NonNull @Override public ContractId createContract( - @NonNull final FileId fileId, @Nullable final ContractParam... constructorParams) + @NonNull final FileId fileId, + @NonNull final Hbar maxTransactionFee, + final int gas, + @Nullable final ContractParam... constructorParams) throws HieroException { + Objects.requireNonNull(fileId, "fileId must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + + if (gas < 0 || gas > MAX_GAS_LIMIT) { + throw new IllegalArgumentException( + "gas must be between 0 and " + MAX_GAS_LIMIT + " inclusive"); + } + try { final ContractCreateRequest request; if (constructorParams == null) { - request = ContractCreateRequest.of(fileId); + request = ContractCreateRequest.of(fileId, maxTransactionFee, gas); } else { - request = ContractCreateRequest.of(fileId, Arrays.asList(constructorParams)); + request = + ContractCreateRequest.of( + fileId, maxTransactionFee, gas, Arrays.asList(constructorParams)); } final ContractCreateResult result = protocolLayerClient.executeContractCreateTransaction(request); @@ -59,11 +75,17 @@ public ContractId createContract( @NonNull @Override public ContractId createContract( - @NonNull final byte[] contents, @Nullable final ContractParam... constructorParams) + @NonNull final byte[] contents, + @NonNull final Hbar maxTransactionFee, + final int gas, + @Nullable final ContractParam... constructorParams) throws HieroException { + Objects.requireNonNull(contents, "contents must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + try { final FileId fileId = fileClient.createFile(contents); - final ContractId contract = createContract(fileId, constructorParams); + final ContractId contract = createContract(fileId, maxTransactionFee, gas, constructorParams); fileClient.deleteFile(fileId); return contract; } catch (Exception e) { @@ -74,11 +96,17 @@ public ContractId createContract( @NonNull @Override public ContractId createContract( - @NonNull final Path pathToBin, @Nullable final ContractParam... constructorParams) + @NonNull final Path pathToBin, + @NonNull final Hbar maxTransactionFee, + final int gas, + @Nullable final ContractParam... constructorParams) throws HieroException { + Objects.requireNonNull(pathToBin, "pathToBin must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + try { final byte[] bytes = Files.readAllBytes(pathToBin); - return createContract(bytes, constructorParams); + return createContract(bytes, maxTransactionFee, gas, constructorParams); } catch (Exception e) { throw new HieroException("Failed to create contract from path " + pathToBin, e); } @@ -89,10 +117,23 @@ public ContractId createContract( public ContractCallResult callContractFunction( @NonNull final ContractId contractId, @NonNull final String functionName, + @NonNull final Hbar maxTransactionFee, + final int gas, @Nullable ContractParam... params) throws HieroException { + + Objects.requireNonNull(contractId, "contractId must not be null"); + Objects.requireNonNull(functionName, "functionName must not be null"); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + + if (gas < 0 || gas > MAX_GAS_LIMIT) { + throw new IllegalArgumentException( + "gas must be between 0 and " + MAX_GAS_LIMIT + " inclusive"); + } + try { - final ContractCallRequest request = ContractCallRequest.of(contractId, functionName, params); + final ContractCallRequest request = + ContractCallRequest.of(contractId, functionName, maxTransactionFee, gas, params); final ContractFunctionResult result = protocolLayerClient.executeContractCallTransaction(request).contractFunctionResult(); return new ContractCallResultImpl(result); diff --git a/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCallRequest.java b/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCallRequest.java index c98e3ce9..20864bd3 100644 --- a/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCallRequest.java +++ b/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCallRequest.java @@ -1,5 +1,7 @@ package org.hiero.base.protocol.data; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.MAX_GAS_LIMIT; + import com.hedera.hashgraph.sdk.ContractId; import com.hedera.hashgraph.sdk.Hbar; import java.time.Duration; @@ -14,6 +16,7 @@ public record ContractCallRequest( @NonNull Duration transactionValidDuration, @NonNull ContractId contractId, @NonNull String functionName, + int gas, @NonNull List> functionParams) implements TransactionRequest { @@ -23,6 +26,7 @@ public record ContractCallRequest( Objects.requireNonNull(contractId, "contractId is required"); Objects.requireNonNull(functionName, "functionName is required"); Objects.requireNonNull(functionParams, "functionParams is required"); + if (maxTransactionFee.toTinybars() < 0) { throw new IllegalArgumentException("maxTransactionFee must be non-negative"); } @@ -32,26 +36,36 @@ public record ContractCallRequest( if (functionName.isBlank() || functionName.contains(" ")) { throw new IllegalArgumentException("functionName must not be blank or contain spaces"); } + + if (gas < 0 || gas > MAX_GAS_LIMIT) { + throw new IllegalArgumentException( + "gas must be between 0 and " + MAX_GAS_LIMIT + " inclusive"); + } } @NonNull public static ContractCallRequest of( @NonNull String contractId, @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, @Nullable ContractParam... functionParams) { Objects.requireNonNull(contractId, "contractId must not be null"); - return of(ContractId.fromString(contractId), functionName, functionParams); + return of( + ContractId.fromString(contractId), functionName, maxTransactionFee, gas, functionParams); } @NonNull public static ContractCallRequest of( @NonNull ContractId contractId, @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, @Nullable ContractParam... functionParams) { if (functionParams == null) { - return of(contractId, functionName, List.of()); + return of(contractId, functionName, maxTransactionFee, gas, List.of()); } else { - return of(contractId, functionName, List.of(functionParams)); + return of(contractId, functionName, maxTransactionFee, gas, List.of(functionParams)); } } @@ -59,21 +73,27 @@ public static ContractCallRequest of( public static ContractCallRequest of( @NonNull String contractId, @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, @NonNull List> functionParams) { Objects.requireNonNull(contractId, "contractId must not be null"); - return of(ContractId.fromString(contractId), functionName, functionParams); + return of( + ContractId.fromString(contractId), functionName, maxTransactionFee, gas, functionParams); } @NonNull public static ContractCallRequest of( @NonNull ContractId contractId, @NonNull String functionName, + @NonNull Hbar maxTransactionFee, + int gas, @NonNull List> functionParams) { return new ContractCallRequest( - DEFAULT_MAX_TRANSACTION_FEE, + maxTransactionFee, DEFAULT_TRANSACTION_VALID_DURATION, contractId, functionName, + gas, List.copyOf(functionParams)); } } diff --git a/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCreateRequest.java b/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCreateRequest.java index 1d726311..023799c3 100644 --- a/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCreateRequest.java +++ b/hiero-enterprise-base/src/main/java/org/hiero/base/protocol/data/ContractCreateRequest.java @@ -1,5 +1,7 @@ package org.hiero.base.protocol.data; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.MAX_GAS_LIMIT; + import com.hedera.hashgraph.sdk.FileId; import com.hedera.hashgraph.sdk.Hbar; import java.time.Duration; @@ -13,53 +15,76 @@ public record ContractCreateRequest( @NonNull Hbar maxTransactionFee, @NonNull Duration transactionValidDuration, @NonNull FileId fileId, + int gas, @NonNull List> constructorParams) implements TransactionRequest { + public static final Hbar DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE = Hbar.from(16); + public ContractCreateRequest { Objects.requireNonNull(maxTransactionFee, "maxTransactionFee is required"); Objects.requireNonNull(transactionValidDuration, "transactionValidDuration is required"); Objects.requireNonNull(fileId, "fileId is required"); Objects.requireNonNull(constructorParams, "constructorParams is required"); + if (maxTransactionFee.toTinybars() < 0) { throw new IllegalArgumentException("maxTransactionFee must be non-negative"); } if (transactionValidDuration.isNegative() || transactionValidDuration.isZero()) { throw new IllegalArgumentException("transactionValidDuration must be positive"); } + if (gas < 0 || gas > MAX_GAS_LIMIT) { + throw new IllegalArgumentException( + "gas must be between 0 and " + MAX_GAS_LIMIT + " inclusive"); + } } @NonNull public static ContractCreateRequest of( - @NonNull String fileId, @Nullable ContractParam... constructorParams) { + @NonNull String fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) { Objects.requireNonNull(fileId, "fileId must not be null"); - return of(FileId.fromString(fileId), constructorParams); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + return of(FileId.fromString(fileId), maxTransactionFee, gas, constructorParams); } @NonNull public static ContractCreateRequest of( - @NonNull FileId fileId, @Nullable ContractParam... constructorParams) { + @NonNull FileId fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @Nullable ContractParam... constructorParams) { if (constructorParams == null) { - return of(fileId, List.of()); + return of(fileId, maxTransactionFee, gas, List.of()); } else { - return of(fileId, List.of(constructorParams)); + return of(fileId, maxTransactionFee, gas, List.of(constructorParams)); } } @NonNull public static ContractCreateRequest of( - @NonNull String fileId, @NonNull List> constructorParams) { + @NonNull String fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @NonNull List> constructorParams) { Objects.requireNonNull(fileId, "fileId must not be null"); - return of(FileId.fromString(fileId), constructorParams); + Objects.requireNonNull(maxTransactionFee, "maxTransactionFee must not be null"); + return of(FileId.fromString(fileId), maxTransactionFee, gas, constructorParams); } @NonNull public static ContractCreateRequest of( - @NonNull FileId fileId, @NonNull List> constructorParams) { + @NonNull FileId fileId, + @NonNull Hbar maxTransactionFee, + int gas, + @NonNull List> constructorParams) { return new ContractCreateRequest( - DEFAULT_MAX_TRANSACTION_FEE, + maxTransactionFee, DEFAULT_TRANSACTION_VALID_DURATION, fileId, + gas, List.copyOf(constructorParams)); } } diff --git a/hiero-enterprise-base/src/test/java/org/hiero/base/test/ProtocolLayerDataCreationTests.java b/hiero-enterprise-base/src/test/java/org/hiero/base/test/ProtocolLayerDataCreationTests.java index 3d2b6d05..2a15d5be 100644 --- a/hiero-enterprise-base/src/test/java/org/hiero/base/test/ProtocolLayerDataCreationTests.java +++ b/hiero-enterprise-base/src/test/java/org/hiero/base/test/ProtocolLayerDataCreationTests.java @@ -1,5 +1,7 @@ package org.hiero.base.test; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.MAX_GAS_LIMIT; + import com.hedera.hashgraph.sdk.AccountId; import com.hedera.hashgraph.sdk.ContractFunctionResult; import com.hedera.hashgraph.sdk.ContractId; @@ -453,19 +455,30 @@ void testContractCallRequestCreation() { final String contractIdString = "0.0.12345"; final ContractId contractId = ContractId.fromString(contractIdString); final String functionName = "functionName"; + final int gas = 1_000_000; final ContractParam contractParam = ContractParam.int32(1); final List> constructorParams = List.of(contractParam); - Assertions.assertDoesNotThrow(() -> ContractCallRequest.of(contractIdString, functionName)); Assertions.assertDoesNotThrow( - () -> ContractCallRequest.of(contractIdString, functionName, contractParam)); + () -> ContractCallRequest.of(contractIdString, functionName, maxTransactionFee, gas)); + Assertions.assertDoesNotThrow( + () -> + ContractCallRequest.of( + contractIdString, functionName, maxTransactionFee, gas, contractParam)); + Assertions.assertDoesNotThrow( + () -> + ContractCallRequest.of( + contractIdString, functionName, maxTransactionFee, gas, constructorParams)); Assertions.assertDoesNotThrow( - () -> ContractCallRequest.of(contractIdString, functionName, constructorParams)); - Assertions.assertDoesNotThrow(() -> ContractCallRequest.of(contractId, functionName)); + () -> ContractCallRequest.of(contractId, functionName, maxTransactionFee, gas)); Assertions.assertDoesNotThrow( - () -> ContractCallRequest.of(contractId, functionName, contractParam)); + () -> + ContractCallRequest.of( + contractId, functionName, maxTransactionFee, gas, contractParam)); Assertions.assertDoesNotThrow( - () -> ContractCallRequest.of(contractId, functionName, constructorParams)); + () -> + ContractCallRequest.of( + contractId, functionName, maxTransactionFee, gas, constructorParams)); Assertions.assertDoesNotThrow( () -> new ContractCallRequest( @@ -473,39 +486,67 @@ void testContractCallRequestCreation() { transactionValidDuration, contractId, functionName, + gas, constructorParams)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCallRequest.of((String) null, functionName)); + NullPointerException.class, + () -> ContractCallRequest.of((String) null, functionName, maxTransactionFee, gas)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCallRequest.of(contractIdString, null)); + NullPointerException.class, + () -> ContractCallRequest.of(contractIdString, null, maxTransactionFee, gas)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCallRequest.of(contractIdString, functionName, (ContractParam) null)); + () -> ContractCallRequest.of(contractIdString, functionName, null, gas)); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> ContractCallRequest.of(contractIdString, functionName, maxTransactionFee, -1)); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> + ContractCallRequest.of( + contractIdString, functionName, maxTransactionFee, MAX_GAS_LIMIT + 1)); + Assertions.assertThrows( NullPointerException.class, () -> - ContractCallRequest.of(contractIdString, functionName, (List>) null)); + ContractCallRequest.of( + contractIdString, functionName, maxTransactionFee, gas, (ContractParam) null)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCallRequest.of((ContractId) null, functionName)); + NullPointerException.class, + () -> + ContractCallRequest.of( + contractIdString, + functionName, + maxTransactionFee, + gas, + (List>) null)); + Assertions.assertThrows( + NullPointerException.class, + () -> ContractCallRequest.of((ContractId) null, functionName, maxTransactionFee, gas)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCallRequest.of(contractId, null)); + NullPointerException.class, + () -> ContractCallRequest.of(contractId, null, maxTransactionFee, gas)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCallRequest.of(contractId, functionName, (ContractParam) null)); + () -> + ContractCallRequest.of( + contractId, functionName, maxTransactionFee, gas, (ContractParam) null)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCallRequest.of(contractId, functionName, (List>) null)); + () -> + ContractCallRequest.of( + contractId, functionName, maxTransactionFee, gas, (List>) null)); Assertions.assertThrows( NullPointerException.class, () -> new ContractCallRequest( - null, transactionValidDuration, contractId, functionName, constructorParams)); + null, transactionValidDuration, contractId, functionName, gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, () -> new ContractCallRequest( - maxTransactionFee, null, contractId, functionName, constructorParams)); + maxTransactionFee, null, contractId, functionName, gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, () -> @@ -514,17 +555,23 @@ void testContractCallRequestCreation() { transactionValidDuration, null, functionName, + gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, () -> new ContractCallRequest( - maxTransactionFee, transactionValidDuration, contractId, null, constructorParams)); + maxTransactionFee, + transactionValidDuration, + contractId, + null, + gas, + constructorParams)); Assertions.assertThrows( NullPointerException.class, () -> new ContractCallRequest( - maxTransactionFee, transactionValidDuration, contractId, functionName, null)); + maxTransactionFee, transactionValidDuration, contractId, functionName, gas, null)); Assertions.assertThrows( IllegalArgumentException.class, () -> @@ -533,12 +580,18 @@ void testContractCallRequestCreation() { transactionValidDuration, contractId, functionName, + gas, constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> new ContractCallRequest( - maxTransactionFee, Duration.ZERO, contractId, functionName, constructorParams)); + maxTransactionFee, + Duration.ZERO, + contractId, + functionName, + gas, + constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> @@ -547,17 +600,28 @@ void testContractCallRequestCreation() { Duration.ofSeconds(-1), contractId, functionName, + gas, constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> new ContractCallRequest( - maxTransactionFee, transactionValidDuration, contractId, "", constructorParams)); + maxTransactionFee, + transactionValidDuration, + contractId, + "", + gas, + constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> new ContractCallRequest( - maxTransactionFee, transactionValidDuration, contractId, " ", constructorParams)); + maxTransactionFee, + transactionValidDuration, + contractId, + " ", + gas, + constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> @@ -566,6 +630,7 @@ void testContractCallRequestCreation() { transactionValidDuration, contractId, " blankPrefix", + gas, constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, @@ -575,6 +640,7 @@ void testContractCallRequestCreation() { transactionValidDuration, contractId, "blankSuffix ", + gas, constructorParams)); } @@ -677,75 +743,101 @@ void testContractCreateRequestCreation() { final Hbar maxTransactionFee = Hbar.fromTinybars(1000); final Duration transactionValidDuration = Duration.ofSeconds(10); final String fileIdString = "0.0.12345"; + final int gas = 1_000_000; final FileId fileId = FileId.fromString(fileIdString); final ContractParam contractParam = ContractParam.int32(1); final List> constructorParams = List.of(contractParam); // then - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileIdString)); - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileIdString, contractParam)); - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileIdString, constructorParams)); - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileId)); - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileId, contractParam)); - Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileId, constructorParams)); + Assertions.assertDoesNotThrow( + () -> ContractCreateRequest.of(fileIdString, maxTransactionFee, gas)); + Assertions.assertDoesNotThrow( + () -> ContractCreateRequest.of(fileIdString, maxTransactionFee, gas, contractParam)); + Assertions.assertDoesNotThrow( + () -> ContractCreateRequest.of(fileIdString, maxTransactionFee, gas, constructorParams)); + Assertions.assertDoesNotThrow(() -> ContractCreateRequest.of(fileId, maxTransactionFee, gas)); + Assertions.assertDoesNotThrow( + () -> ContractCreateRequest.of(fileId, maxTransactionFee, gas, contractParam)); + Assertions.assertDoesNotThrow( + () -> ContractCreateRequest.of(fileId, maxTransactionFee, gas, constructorParams)); Assertions.assertDoesNotThrow( () -> new ContractCreateRequest( - maxTransactionFee, transactionValidDuration, fileId, constructorParams)); + maxTransactionFee, transactionValidDuration, fileId, gas, constructorParams)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCreateRequest.of((String) null)); + NullPointerException.class, + () -> ContractCreateRequest.of((String) null, maxTransactionFee, gas)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCreateRequest.of((String) null, contractParam)); + NullPointerException.class, () -> ContractCreateRequest.of(fileId, null, gas)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of((String) null, constructorParams)); + () -> ContractCreateRequest.of((String) null, maxTransactionFee, gas, contractParam)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of(fileIdString, (ContractParam) null)); + () -> ContractCreateRequest.of((String) null, maxTransactionFee, gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of(fileIdString, (List>) null)); + () -> ContractCreateRequest.of(fileIdString, null, gas, constructorParams)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCreateRequest.of((FileId) null)); + NullPointerException.class, + () -> + ContractCreateRequest.of( + fileIdString, maxTransactionFee, gas, (ContractParam) null)); Assertions.assertThrows( - NullPointerException.class, () -> ContractCreateRequest.of((FileId) null, contractParam)); + NullPointerException.class, + () -> + ContractCreateRequest.of( + fileIdString, maxTransactionFee, gas, (List>) null)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of((FileId) null, constructorParams)); + () -> ContractCreateRequest.of((FileId) null, maxTransactionFee, gas)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of(fileId, (ContractParam) null)); + () -> ContractCreateRequest.of((FileId) null, maxTransactionFee, gas, contractParam)); Assertions.assertThrows( NullPointerException.class, - () -> ContractCreateRequest.of(fileId, (List>) null)); + () -> ContractCreateRequest.of((FileId) null, maxTransactionFee, gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, - () -> new ContractCreateRequest(null, transactionValidDuration, fileId, constructorParams)); + () -> ContractCreateRequest.of(fileId, maxTransactionFee, gas, (ContractParam) null)); Assertions.assertThrows( NullPointerException.class, - () -> new ContractCreateRequest(maxTransactionFee, null, fileId, constructorParams)); + () -> + ContractCreateRequest.of( + fileId, maxTransactionFee, gas, (List>) null)); Assertions.assertThrows( NullPointerException.class, () -> new ContractCreateRequest( - maxTransactionFee, transactionValidDuration, null, constructorParams)); + null, transactionValidDuration, fileId, gas, constructorParams)); Assertions.assertThrows( NullPointerException.class, - () -> new ContractCreateRequest(maxTransactionFee, transactionValidDuration, fileId, null)); + () -> new ContractCreateRequest(maxTransactionFee, null, fileId, gas, constructorParams)); + Assertions.assertThrows( + NullPointerException.class, + () -> + new ContractCreateRequest( + maxTransactionFee, transactionValidDuration, null, gas, constructorParams)); + Assertions.assertThrows( + NullPointerException.class, + () -> + new ContractCreateRequest( + maxTransactionFee, transactionValidDuration, fileId, gas, null)); Assertions.assertThrows( IllegalArgumentException.class, () -> new ContractCreateRequest( - Hbar.from(-100), transactionValidDuration, fileId, constructorParams)); + Hbar.from(-100), transactionValidDuration, fileId, gas, constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> - new ContractCreateRequest(maxTransactionFee, Duration.ZERO, fileId, constructorParams)); + new ContractCreateRequest( + maxTransactionFee, Duration.ZERO, fileId, gas, constructorParams)); Assertions.assertThrows( IllegalArgumentException.class, () -> new ContractCreateRequest( - maxTransactionFee, Duration.ofSeconds(-1), fileId, constructorParams)); + maxTransactionFee, Duration.ofSeconds(-1), fileId, gas, constructorParams)); } @Test diff --git a/hiero-enterprise-base/src/test/java/org/hiero/base/test/SmartContractClientImplTest.java b/hiero-enterprise-base/src/test/java/org/hiero/base/test/SmartContractClientImplTest.java new file mode 100644 index 00000000..78441e61 --- /dev/null +++ b/hiero-enterprise-base/src/test/java/org/hiero/base/test/SmartContractClientImplTest.java @@ -0,0 +1,587 @@ +package org.hiero.base.test; + +import static org.hiero.base.implementation.ProtocolLayerClientImpl.DEFAULT_GAS; +import static org.hiero.base.implementation.ProtocolLayerClientImpl.MAX_GAS_LIMIT; +import static org.hiero.base.protocol.data.ContractCreateRequest.DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE; +import static org.hiero.base.protocol.data.TransactionRequest.DEFAULT_MAX_TRANSACTION_FEE; +import static org.hiero.base.protocol.data.TransactionRequest.DEFAULT_TRANSACTION_VALID_DURATION; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.hedera.hashgraph.sdk.ContractFunctionResult; +import com.hedera.hashgraph.sdk.ContractId; +import com.hedera.hashgraph.sdk.FileId; +import com.hedera.hashgraph.sdk.Hbar; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.hiero.base.FileClient; +import org.hiero.base.HieroException; +import org.hiero.base.data.ContractParam; +import org.hiero.base.implementation.SmartContractClientImpl; +import org.hiero.base.protocol.ProtocolLayerClient; +import org.hiero.base.protocol.data.ContractCallRequest; +import org.hiero.base.protocol.data.ContractCallResult; +import org.hiero.base.protocol.data.ContractCreateRequest; +import org.hiero.base.protocol.data.ContractCreateResult; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.ArgumentCaptor; + +public class SmartContractClientImplTest { + private ProtocolLayerClient mockProtocolLayerClient; + private FileClient mockFileClient; + + private final ArgumentCaptor contractCreateRequestCaptor = + ArgumentCaptor.forClass(ContractCreateRequest.class); + private final ArgumentCaptor contractCallRequestCaptor = + ArgumentCaptor.forClass(ContractCallRequest.class); + + private SmartContractClientImpl smartContractClient; + + @TempDir private Path tempDir; + + @BeforeEach + public void setUp() { + mockProtocolLayerClient = mock(ProtocolLayerClient.class); + mockFileClient = mock(FileClient.class); + smartContractClient = new SmartContractClientImpl(mockProtocolLayerClient, mockFileClient); + } + + @Test + public void shouldCreateContractWithFileId() throws HieroException { + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final FileId fileId = FileId.fromString("0.0.101"); + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = smartContractClient.createContract(fileId); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(fileId, request.fileId()); + Assertions.assertTrue(request.constructorParams().isEmpty()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void sgouldCreateContractWithFileIdAndConstructorParameters() throws HieroException { + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final FileId fileId = FileId.fromString("0.0.101"); + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = smartContractClient.createContract(fileId, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(fileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void shouldCreateContractWithFileIdUsesCustomMaxFeeAndGasConfig() throws HieroException { + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final FileId fileId = FileId.fromString("0.0.101"); + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + final Hbar maxTransactionFee = Hbar.from(20); + final int gas = 1_000_000; + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = + smartContractClient.createContract(fileId, maxTransactionFee, gas, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(fileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(maxTransactionFee, request.maxTransactionFee()); + Assertions.assertEquals(gas, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithContents() throws HieroException { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = smartContractClient.createContract(contents); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertTrue(request.constructorParams().isEmpty()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithContentsAndConstructorParameters() throws HieroException { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = smartContractClient.createContract(contents, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithContentsWithCustomMaxFeeAndGas() throws HieroException { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + final Hbar maxTransactionFee = Hbar.from(20); + final int gas = 1_000_000; + + // then + when(mockResponse.contractId()).thenReturn(mockContractId); + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + + final ContractId contractId = + smartContractClient.createContract(contents, maxTransactionFee, gas, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(maxTransactionFee, request.maxTransactionFee()); + Assertions.assertEquals(gas, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithPath() throws Exception { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + final Path path = tempDir.resolve("contract.bin"); + Files.write(path, contents); + + // then + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + when(mockResponse.contractId()).thenReturn(mockContractId); + + final ContractId contractId = smartContractClient.createContract(path); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertTrue(request.constructorParams().isEmpty()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithPathAndConstructorParameters() throws Exception { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + final Path path = tempDir.resolve("contract.bin"); + Files.write(path, contents); + + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + + // then + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + when(mockResponse.contractId()).thenReturn(mockContractId); + + final ContractId contractId = smartContractClient.createContract(path, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(DEFAULT_CONTRACT_CREATE_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + public void createContractWithPathWithCustomMaxFeeAndGas() throws Exception { + final FileId mockFileId = FileId.fromString("0.0.101"); + final ContractId mockContractId = ContractId.fromString("0.0.1"); + final ContractCreateResult mockResponse = mock(ContractCreateResult.class); + + // given + final byte[] contents = "6080604052348015600e575f80fd5b506157d".getBytes(); + final Path path = tempDir.resolve("contract.bin"); + Files.write(path, contents); + + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + final Hbar maxTransactionFee = Hbar.from(20); + final int gas = 1_000_000; + + // then + when(mockFileClient.createFile(contents)).thenReturn(mockFileId); + when(mockProtocolLayerClient.executeContractCreateTransaction(any(ContractCreateRequest.class))) + .thenReturn(mockResponse); + when(mockResponse.contractId()).thenReturn(mockContractId); + + final ContractId contractId = + smartContractClient.createContract(path, maxTransactionFee, gas, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCreateTransaction(contractCreateRequestCaptor.capture()); + verify(mockResponse, times(1)).contractId(); + verify(mockFileClient, times(1)).createFile(contents); + verify(mockFileClient, times(1)).deleteFile(mockFileId); + + Assertions.assertEquals(mockContractId, contractId); + + final ContractCreateRequest request = contractCreateRequestCaptor.getValue(); + Assertions.assertEquals(mockFileId, request.fileId()); + Assertions.assertEquals(2, request.constructorParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.constructorParams()); + Assertions.assertEquals(maxTransactionFee, request.maxTransactionFee()); + Assertions.assertEquals(gas, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + void shouldThrowNullPointerExceptionForNullArgumentsOnCreateContract() { + Assertions.assertThrows( + NullPointerException.class, () -> smartContractClient.createContract((FileId) null)); + Assertions.assertThrows( + NullPointerException.class, () -> smartContractClient.createContract((byte[]) null)); + Assertions.assertThrows( + NullPointerException.class, () -> smartContractClient.createContract((Path) null)); + + // maxTransactionFee + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.createContract(FileId.fromString("0.0.100"), null, 1)); + Assertions.assertThrows( + NullPointerException.class, + () -> + smartContractClient.createContract( + "6080604052348015600e575f80fd5b506157d".getBytes(), null, 1)); + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.createContract(tempDir.resolve("contract.bin"), null, 1)); + } + + @Test + void shouldThrowExceptionIfGasIsLessThanZeroOnCreateContract() { + final FileId fileId = FileId.fromString("0.0.101"); + final Hbar maxTransactionFee = Hbar.from(10); + + Assertions.assertThrows( + IllegalArgumentException.class, + () -> smartContractClient.createContract(fileId, maxTransactionFee, -1)); + } + + @Test + void shouldThrowExceptionIfGasGreaterThanMaxGasLimitOnCreateContract() { + final FileId fileId = FileId.fromString("0.0.101"); + final Hbar maxTransactionFee = Hbar.from(10); + final int gas = MAX_GAS_LIMIT + 1; + + Assertions.assertThrows( + IllegalArgumentException.class, + () -> smartContractClient.createContract(fileId, maxTransactionFee, gas)); + } + + @Test + void shouldCallContractFunction() throws Exception { + final ContractFunctionResult mockCallResult = mock(ContractFunctionResult.class); + final ContractCallResult response = mock(ContractCallResult.class); + + // given + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething()"; + + // then + when(mockProtocolLayerClient.executeContractCallTransaction(any(ContractCallRequest.class))) + .thenReturn(response); + when(response.contractFunctionResult()).thenReturn(mockCallResult); + + final org.hiero.base.data.ContractCallResult result = + smartContractClient.callContractFunction(contractId, functionName); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCallTransaction(contractCallRequestCaptor.capture()); + verify(response, times(1)).contractFunctionResult(); + + Assertions.assertNotNull(result); + + final ContractCallRequest request = contractCallRequestCaptor.getValue(); + Assertions.assertEquals(contractId, request.contractId()); + Assertions.assertEquals(functionName, request.functionName()); + Assertions.assertTrue(request.functionParams().isEmpty()); + Assertions.assertEquals(DEFAULT_MAX_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + void shouldCallContractFunctionWithParams() throws Exception { + final ContractFunctionResult mockCallResult = mock(ContractFunctionResult.class); + final ContractCallResult response = mock(ContractCallResult.class); + + // given + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething()"; + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + + // then + when(mockProtocolLayerClient.executeContractCallTransaction(any(ContractCallRequest.class))) + .thenReturn(response); + when(response.contractFunctionResult()).thenReturn(mockCallResult); + + final org.hiero.base.data.ContractCallResult result = + smartContractClient.callContractFunction(contractId, functionName, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCallTransaction(contractCallRequestCaptor.capture()); + verify(response, times(1)).contractFunctionResult(); + + Assertions.assertNotNull(result); + + final ContractCallRequest request = contractCallRequestCaptor.getValue(); + Assertions.assertEquals(contractId, request.contractId()); + Assertions.assertEquals(functionName, request.functionName()); + Assertions.assertEquals(2, request.functionParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.functionParams()); + Assertions.assertEquals(DEFAULT_MAX_TRANSACTION_FEE, request.maxTransactionFee()); + Assertions.assertEquals(DEFAULT_GAS, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + void shouldCallContractFunctionUsingCustomMaxFeeAndGas() throws Exception { + final ContractFunctionResult mockCallResult = mock(ContractFunctionResult.class); + final ContractCallResult response = mock(ContractCallResult.class); + + // given + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething()"; + final ContractParam param1 = ContractParam.string("Hello"); + final ContractParam param2 = ContractParam.int32(10); + final Hbar maxTransactionFee = Hbar.from(20); + final int gas = 1_000_000; + + // then + when(mockProtocolLayerClient.executeContractCallTransaction(any(ContractCallRequest.class))) + .thenReturn(response); + when(response.contractFunctionResult()).thenReturn(mockCallResult); + + final org.hiero.base.data.ContractCallResult result = + smartContractClient.callContractFunction( + contractId, functionName, maxTransactionFee, gas, param1, param2); + + // verify + verify(mockProtocolLayerClient, times(1)) + .executeContractCallTransaction(contractCallRequestCaptor.capture()); + verify(response, times(1)).contractFunctionResult(); + + Assertions.assertNotNull(result); + + final ContractCallRequest request = contractCallRequestCaptor.getValue(); + Assertions.assertEquals(contractId, request.contractId()); + Assertions.assertEquals(functionName, request.functionName()); + Assertions.assertEquals(2, request.functionParams().size()); + Assertions.assertEquals(List.of(param1, param2), request.functionParams()); + Assertions.assertEquals(maxTransactionFee, request.maxTransactionFee()); + Assertions.assertEquals(gas, request.gas()); + Assertions.assertEquals(DEFAULT_TRANSACTION_VALID_DURATION, request.transactionValidDuration()); + } + + @Test + void shouldThrowNullPointerExceptionForNullArgumentsOnFunctionCall() { + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething"; + + // contractId + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.callContractFunction((ContractId) null, functionName)); + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.callContractFunction((String) null, functionName)); + + // functionName + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.callContractFunction(contractId, null)); + + // maxTransactionFee + Assertions.assertThrows( + NullPointerException.class, + () -> smartContractClient.callContractFunction(contractId, functionName, null, 1)); + } + + @Test + void shouldThrowExceptionIfGasIsLessThanZeroOnFunctionCall() { + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething"; + final Hbar maxTransactionFee = Hbar.from(10); + + Assertions.assertThrows( + IllegalArgumentException.class, + () -> + smartContractClient.callContractFunction( + contractId, functionName, maxTransactionFee, -1)); + } + + @Test + void shouldThrowExceptionIfGasGreaterThanMaxGasLimitOnFunctionCall() { + final ContractId contractId = ContractId.fromString("0.0.101"); + final String functionName = "doSomething"; + final Hbar maxTransactionFee = Hbar.from(10); + final int gas = MAX_GAS_LIMIT + 1; + + Assertions.assertThrows( + IllegalArgumentException.class, + () -> + smartContractClient.callContractFunction( + contractId, functionName, maxTransactionFee, gas)); + } +} diff --git a/hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/SmartContractClientTest.java b/hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/SmartContractClientTest.java new file mode 100644 index 00000000..9fd422fd --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/SmartContractClientTest.java @@ -0,0 +1,248 @@ +package org.hiero.microprofile.test; + +import static org.hiero.base.data.ContractParam.int256; +import static org.hiero.base.data.ContractParam.string; + +import com.hedera.hashgraph.sdk.ContractId; +import com.hedera.hashgraph.sdk.FileId; +import io.helidon.microprofile.tests.junit5.AddBean; +import io.helidon.microprofile.tests.junit5.Configuration; +import io.helidon.microprofile.tests.junit5.HelidonTest; +import jakarta.inject.Inject; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; +import org.hiero.base.FileClient; +import org.hiero.base.HieroException; +import org.hiero.base.SmartContractClient; +import org.hiero.base.data.ContractCallResult; +import org.hiero.microprofile.ClientProvider; +import org.hiero.test.HieroTestUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +@HelidonTest +@AddBean(ClientProvider.class) +@Configuration(useExisting = true) +public class SmartContractClientTest { + @BeforeAll + static void setup() { + final Config build = + ConfigProviderResolver.instance().getBuilder().withSources(new TestConfigSource()).build(); + ConfigProviderResolver.instance() + .registerConfig(build, Thread.currentThread().getContextClassLoader()); + } + + @Inject private HieroTestUtils hieroTestUtils; + + @Inject private SmartContractClient smartContractClient; + @Inject private FileClient fileClient; + + @Test + void testContractCreateByFileId() throws Exception { + // given + final Path path = + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); + final String content = Files.readString(path, StandardCharsets.UTF_8); + final byte[] bytes = content.getBytes(StandardCharsets.UTF_8); + final FileId fileId = fileClient.createFile(bytes); + + // when + final ContractId contract = smartContractClient.createContract(fileId); + + // then + Assertions.assertNotNull(contract); + } + + @Test + void testContractCreateByBytes() throws Exception { + // given + final Path path = + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); + final String content = Files.readString(path, StandardCharsets.UTF_8); + final byte[] bytes = content.getBytes(StandardCharsets.UTF_8); + + // when + final ContractId contract = smartContractClient.createContract(bytes); + + // then + Assertions.assertNotNull(contract); + } + + @Test + void testContractCreateSimple() throws Exception { + // given + final Path path = + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); + + // when + final ContractId contract = smartContractClient.createContract(path); + + // then + Assertions.assertNotNull(contract); + } + + @Test + void testContractCreateSimpleWithLargeContract() throws Exception { + // given + final Path path = + Path.of(SmartContractClientTest.class.getResource("/large_contract.bin").getPath()); + + // when + final ContractId contract = smartContractClient.createContract(path); + + // then + Assertions.assertNotNull(contract); + } + + @Test + void testContractCreateSimpleInvalidContent() throws Exception { + // given + final byte[] content = "invalid".getBytes(StandardCharsets.UTF_8); + + // then + Assertions.assertThrows( + HieroException.class, () -> smartContractClient.createContract(content)); + } + + @Test + void testContractWithConstructorParam() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/string_param_constructor_contract.bin") + .getPath()); + + // when + final ContractId contract = smartContractClient.createContract(path, string("Hello")); + + // then + Assertions.assertNotNull(contract); + } + + @Test + void testCallFunction() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + + // when + final ContractCallResult result = smartContractClient.callContractFunction(contract, "get"); + + // then + Assertions.assertNotNull(result); + } + + @Test + void testCallInvalidFunction() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + + // when + Assertions.assertThrows( + HieroException.class, () -> smartContractClient.callContractFunction(contract, "invalid")); + } + + @Test + void testCallFunctionWithParam() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + + // when + final ContractCallResult result = + smartContractClient.callContractFunction(contract, "set", int256(123)); + + // then + Assertions.assertNotNull(result); + } + + @Test + void testCallFunctionWithInvalidParam() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + + // then + Assertions.assertThrows( + HieroException.class, + () -> smartContractClient.callContractFunction(contract, "get", int256(123))); + } + + @Test + void testCallFunctionWithResult() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + smartContractClient.callContractFunction(contract, "set", int256(123)); + + // when + final ContractCallResult result = smartContractClient.callContractFunction(contract, "get"); + + // then + Assertions.assertNotNull(result); + Assertions.assertEquals(BigInteger.valueOf(123), result.getInt256(0)); + } + + @Test + void testCallFunctionWithWrongResult() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + smartContractClient.callContractFunction(contract, "set", int256(123)); + + // when + final ContractCallResult result = smartContractClient.callContractFunction(contract, "get"); + + // then + Assertions.assertThrows(IllegalArgumentException.class, () -> result.getString(0)); + } + + @Test + void testCallFunctionWithWrongResultCount() throws Exception { + // given + final Path path = + Path.of( + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); + final ContractId contract = smartContractClient.createContract(path); + smartContractClient.callContractFunction(contract, "set", int256(123)); + + // when + final ContractCallResult result = smartContractClient.callContractFunction(contract, "get"); + + // then + Assertions.assertThrows(IllegalArgumentException.class, () -> result.getString(1)); + } +} diff --git a/hiero-enterprise-microprofile/src/test/resources/datatypes.bin b/hiero-enterprise-microprofile/src/test/resources/datatypes.bin new file mode 100644 index 00000000..c54e5272 --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/resources/datatypes.bin @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b506157d78061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061057f575f3560e01c80636db5e946116102e3578063b0c902a31161018b578063e0261689116100f2578063ef1bc6a2116100ab578063f6d05e0911610085578063f6d05e0914611753578063f8c9378014611783578063ff11840f146117b3578063ffc0095f146117e35761057f565b8063ef1bc6a2146116c3578063f56d0a83146116f3578063f5e2e5ca146117235761057f565b8063e0261689146115a3578063e123b039146115d3578063e24602d214611603578063e331e19514611633578063e749812d14611663578063e8522bca146116935761057f565b8063cfbd13b411610144578063cfbd13b414611483578063d195dc37146114b3578063d6550de9146114e3578063d9e09a8614611513578063dec2aee114611543578063df32fa9e146115735761057f565b8063b0c902a314611363578063b9d618bf14611393578063c7b40bdc146113c3578063c7b98a56146113f3578063ca8e1fba14611423578063cc95080a146114535761057f565b806395bf6fa21161024a578063a2b6e31b11610203578063a9868e3c116101dd578063a9868e3c146112a3578063abd7affb146112d3578063ac9ec39514611303578063ad961b0f146113335761057f565b8063a2b6e31b14611213578063a454b07b14611243578063a5c6e016146112735761057f565b806395bf6fa2146110f3578063969be2071461112357806397733394146111535780639d266e2c146111835780639fe1355f146111b3578063a1dcf352146111e35761057f565b80637db1b9141161029c5780637db1b91414610fd3578063820f51dc1461100357806387f4daa91461103357806388c3504a146110635780638916a15f1461109357806390f6ce51146110c35761057f565b80636db5e94614610eb35780636f4c5d8514610ee3578063720e9a2e14610f135780637240588714610f4357806376ba9c6b14610f73578063778027de14610fa35761057f565b806336eb598c116104465780635318189c116103ad57806360c540a01161036657806364d82b0a1161034057806364d82b0a14610df357806365c3693014610e23578063663e71c914610e535780636871bd5e14610e835761057f565b806360c540a014610d6357806361b54e3414610d935780636489463114610dc35761057f565b80635318189c14610c43578063541bbf1c14610c7357806357d1cc7814610ca35780635a3ef87514610cd35780635b85f6d414610d035780635bf41ead14610d335761057f565b80633ee1ae90116103ff5780633ee1ae9014610b2357806346283ce214610b535780634beae35714610b835780634eb3846414610bb35780634fcc943114610be357806352824d5714610c135761057f565b806336eb598c14610a03578063376fd58c14610a33578063388c507614610a63578063389faf7614610a935780633a15376614610ac35780633b24478914610af35761057f565b806322b779af116104ea5780633241c47a116104a35780633241c47a146108e357806333a99cea146109135780633416fd531461094357806334d4a46a1461097357806334dacfcf146109a357806335249943146109d35761057f565b806322b779af146107c35780632349ed8f146107f357806327d4557e1461082357806328f1ad31146108535780632a6fc7ae14610883578063315eea98146108b35761057f565b806316c79a091161053c57806316c79a09146106a357806317403132146106d3578063189a6bb2146107035780631cf7fa18146107335780631e661499146107635780631ec79e5c146107935761057f565b80630999a256146105835780630ab5f092146105b35780630b56b6c3146105e35780630ddcfe8e146106135780630ff8440c146106435780631170a90c14610673575b5f80fd5b61059d60048036038101906105989190611be1565b611813565b6040516105aa9190611c1b565b60405180910390f35b6105cd60048036038101906105c89190611c89565b61181c565b6040516105da9190611cc3565b60405180910390f35b6105fd60048036038101906105f89190611d12565b611825565b60405161060a9190611d4c565b60405180910390f35b61062d60048036038101906106289190611dbf565b61182e565b60405161063a9190611df9565b60405180910390f35b61065d60048036038101906106589190611e48565b611837565b60405161066a9190611e82565b60405180910390f35b61068d60048036038101906106889190611ef0565b611840565b60405161069a9190611f2a565b60405180910390f35b6106bd60048036038101906106b89190611f79565b611849565b6040516106ca9190611fb3565b60405180910390f35b6106ed60048036038101906106e89190612002565b611852565b6040516106fa919061203c565b60405180910390f35b61071d6004803603810190610718919061208b565b61185b565b60405161072a91906120c5565b60405180910390f35b61074d60048036038101906107489190612133565b611864565b60405161075a919061216d565b60405180910390f35b61077d600480360381019061077891906121bc565b61186d565b60405161078a91906121f6565b60405180910390f35b6107ad60048036038101906107a89190612245565b611876565b6040516107ba919061227f565b60405180910390f35b6107dd60048036038101906107d891906122d6565b61187f565b6040516107ea9190612310565b60405180910390f35b61080d6004803603810190610808919061237e565b611888565b60405161081a91906123b8565b60405180910390f35b61083d60048036038101906108389190612426565b611891565b60405161084a9190612460565b60405180910390f35b61086d600480360381019061086891906124af565b61189a565b60405161087a91906124e9565b60405180910390f35b61089d60048036038101906108989190612537565b6118a3565b6040516108aa9190612571565b60405180910390f35b6108cd60048036038101906108c891906125df565b6118ac565b6040516108da9190612619565b60405180910390f35b6108fd60048036038101906108f89190612687565b6118b5565b60405161090a91906126c1565b60405180910390f35b61092d6004803603810190610928919061271a565b6118be565b60405161093a9190612754565b60405180910390f35b61095d600480360381019061095891906127c2565b6118c7565b60405161096a91906127fc565b60405180910390f35b61098d6004803603810190610988919061284a565b6118d0565b60405161099a9190612884565b60405180910390f35b6109bd60048036038101906109b891906128f2565b6118d9565b6040516109ca919061292c565b60405180910390f35b6109ed60048036038101906109e8919061297b565b6118e2565b6040516109fa91906129b5565b60405180910390f35b610a1d6004803603810190610a189190612a15565b6118eb565b604051610a2a9190612a4f565b60405180910390f35b610a4d6004803603810190610a489190612abd565b6118f4565b604051610a5a9190612af7565b60405180910390f35b610a7d6004803603810190610a789190612b65565b6118fd565b604051610a8a9190612b9f565b60405180910390f35b610aad6004803603810190610aa89190612c0d565b611906565b604051610aba9190612c47565b60405180910390f35b610add6004803603810190610ad89190612c96565b61190f565b604051610aea9190612cd0565b60405180910390f35b610b0d6004803603810190610b089190612d1c565b611918565b604051610b1a9190612d56565b60405180910390f35b610b3d6004803603810190610b389190612dc4565b611921565b604051610b4a9190612dfe565b60405180910390f35b610b6d6004803603810190610b689190612e4d565b61192a565b604051610b7a9190612e87565b60405180910390f35b610b9d6004803603810190610b989190612eef565b611933565b604051610baa9190612f29565b60405180910390f35b610bcd6004803603810190610bc89190612f75565b61193c565b604051610bda9190612faf565b60405180910390f35b610bfd6004803603810190610bf89190613015565b611945565b604051610c0a919061304f565b60405180910390f35b610c2d6004803603810190610c28919061309e565b61194e565b604051610c3a91906130d8565b60405180910390f35b610c5d6004803603810190610c589190613146565b611957565b604051610c6a9190613180565b60405180910390f35b610c8d6004803603810190610c8891906131cf565b611960565b604051610c9a9190613209565b60405180910390f35b610cbd6004803603810190610cb89190613277565b611969565b604051610cca91906132b1565b60405180910390f35b610ced6004803603810190610ce8919061331c565b611972565b604051610cfa9190613356565b60405180910390f35b610d1d6004803603810190610d1891906133a9565b61197b565b604051610d2a91906133e3565b60405180910390f35b610d4d6004803603810190610d48919061342f565b611984565b604051610d5a9190613469565b60405180910390f35b610d7d6004803603810190610d7891906134b8565b61198d565b604051610d8a91906134f2565b60405180910390f35b610dad6004803603810190610da89190613560565b611996565b604051610dba919061359a565b60405180910390f35b610ddd6004803603810190610dd891906135fe565b61199f565b604051610dea9190613638565b60405180910390f35b610e0d6004803603810190610e0891906136a6565b6119a8565b604051610e1a91906136e0565b60405180910390f35b610e3d6004803603810190610e389190613743565b6119b1565b604051610e4a919061377d565b60405180910390f35b610e6d6004803603810190610e6891906137eb565b6119ba565b604051610e7a9190613825565b60405180910390f35b610e9d6004803603810190610e989190613874565b6119c3565b604051610eaa91906138ae565b60405180910390f35b610ecd6004803603810190610ec891906138fd565b6119cc565b604051610eda9190613937565b60405180910390f35b610efd6004803603810190610ef891906139a5565b6119d5565b604051610f0a91906139df565b60405180910390f35b610f2d6004803603810190610f289190613a2e565b6119de565b604051610f3a9190613a68565b60405180910390f35b610f5d6004803603810190610f589190613acd565b6119e7565b604051610f6a9190613b07565b60405180910390f35b610f8d6004803603810190610f889190613b75565b6119f0565b604051610f9a9190613baf565b60405180910390f35b610fbd6004803603810190610fb89190613c1d565b6119f9565b604051610fca9190613c57565b60405180910390f35b610fed6004803603810190610fe89190613ca6565b611a02565b604051610ffa9190613ce0565b60405180910390f35b61101d60048036038101906110189190613d34565b611a0b565b60405161102a9190613d6e565b60405180910390f35b61104d60048036038101906110489190613dbd565b611a14565b60405161105a9190613df7565b60405180910390f35b61107d60048036038101906110789190613e65565b611a1d565b60405161108a9190613e9f565b60405180910390f35b6110ad60048036038101906110a89190613f0d565b611a26565b6040516110ba9190613f47565b60405180910390f35b6110dd60048036038101906110d89190613fa2565b611a2f565b6040516110ea9190613fdc565b60405180910390f35b61110d6004803603810190611108919061402b565b611a38565b60405161111a9190614065565b60405180910390f35b61113d600480360381019061113891906140c4565b611a41565b60405161114a91906140fe565b60405180910390f35b61116d6004803603810190611168919061416c565b611a4a565b60405161117a91906141a6565b60405180910390f35b61119d600480360381019061119891906141f5565b611a53565b6040516111aa919061422f565b60405180910390f35b6111cd60048036038101906111c8919061427e565b611a5c565b6040516111da91906142b8565b60405180910390f35b6111fd60048036038101906111f89190614307565b611a65565b60405161120a9190614341565b60405180910390f35b61122d60048036038101906112289190614396565b611a6e565b60405161123a91906143d0565b60405180910390f35b61125d60048036038101906112589190614525565b611a77565b60405161126a91906145cc565b60405180910390f35b61128d6004803603810190611288919061462f565b611a81565b60405161129a9190614669565b60405180910390f35b6112bd60048036038101906112b891906146ba565b611a8a565b6040516112ca91906146f4565b60405180910390f35b6112ed60048036038101906112e8919061475b565b611a93565b6040516112fa9190614795565b60405180910390f35b61131d60048036038101906113189190614803565b611a9c565b60405161132a919061483d565b60405180910390f35b61134d600480360381019061134891906148a9565b611aa5565b60405161135a91906148e3565b60405180910390f35b61137d60048036038101906113789190614932565b611aae565b60405161138a919061496c565b60405180910390f35b6113ad60048036038101906113a891906149bb565b611ab7565b6040516113ba91906149f5565b60405180910390f35b6113dd60048036038101906113d89190614a4d565b611ac0565b6040516113ea9190614a87565b60405180910390f35b61140d60048036038101906114089190614aca565b611ac9565b60405161141a9190614b04565b60405180910390f35b61143d60048036038101906114389190614b72565b611ad2565b60405161144a9190614bac565b60405180910390f35b61146d60048036038101906114689190614bfb565b611adb565b60405161147a9190614c35565b60405180910390f35b61149d60048036038101906114989190614c84565b611ae4565b6040516114aa9190614cbe565b60405180910390f35b6114cd60048036038101906114c89190614d2b565b611aed565b6040516114da9190614d65565b60405180910390f35b6114fd60048036038101906114f89190614dbb565b611af6565b60405161150a9190614df5565b60405180910390f35b61152d60048036038101906115289190614e47565b611aff565b60405161153a9190614e81565b60405180910390f35b61155d60048036038101906115589190614ed0565b611b08565b60405161156a9190614f0a565b60405180910390f35b61158d60048036038101906115889190614f78565b611b11565b60405161159a9190614fb2565b60405180910390f35b6115bd60048036038101906115b8919061501b565b611b1a565b6040516115ca9190615055565b60405180910390f35b6115ed60048036038101906115e891906150b2565b611b23565b6040516115fa91906150ec565b60405180910390f35b61161d6004803603810190611618919061513c565b611b2c565b60405161162a9190615176565b60405180910390f35b61164d600480360381019061164891906151e4565b611b35565b60405161165a919061521e565b60405180910390f35b61167d6004803603810190611678919061528c565b611b3e565b60405161168a91906152c6565b60405180910390f35b6116ad60048036038101906116a89190615334565b611b47565b6040516116ba919061536e565b60405180910390f35b6116dd60048036038101906116d891906153bd565b611b50565b6040516116ea91906153f7565b60405180910390f35b61170d60048036038101906117089190615455565b611b59565b60405161171a919061548f565b60405180910390f35b61173d600480360381019061173891906154de565b611b62565b60405161174a9190615518565b60405180910390f35b61176d60048036038101906117689190615579565b611b6b565b60405161177a91906155b3565b60405180910390f35b61179d60048036038101906117989190615621565b611b74565b6040516117aa919061565b565b60405180910390f35b6117cd60048036038101906117c891906156c5565b611b7d565b6040516117da91906156ff565b60405180910390f35b6117fd60048036038101906117f8919061574e565b611b86565b60405161180a9190615788565b60405180910390f35b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b6060819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f819050919050565b5f604051905090565b5f80fd5b5f80fd5b5f6bffffffffffffffffffffffff82169050919050565b611bc081611ba0565b8114611bca575f80fd5b50565b5f81359050611bdb81611bb7565b92915050565b5f60208284031215611bf657611bf5611b98565b5b5f611c0384828501611bcd565b91505092915050565b611c1581611ba0565b82525050565b5f602082019050611c2e5f830184611c0c565b92915050565b5f7fffffff000000000000000000000000000000000000000000000000000000000082169050919050565b611c6881611c34565b8114611c72575f80fd5b50565b5f81359050611c8381611c5f565b92915050565b5f60208284031215611c9e57611c9d611b98565b5b5f611cab84828501611c75565b91505092915050565b611cbd81611c34565b82525050565b5f602082019050611cd65f830184611cb4565b92915050565b5f8160020b9050919050565b611cf181611cdc565b8114611cfb575f80fd5b50565b5f81359050611d0c81611ce8565b92915050565b5f60208284031215611d2757611d26611b98565b5b5f611d3484828501611cfe565b91505092915050565b611d4681611cdc565b82525050565b5f602082019050611d5f5f830184611d3d565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611d8e82611d65565b9050919050565b611d9e81611d84565b8114611da8575f80fd5b50565b5f81359050611db981611d95565b92915050565b5f60208284031215611dd457611dd3611b98565b5b5f611de184828501611dab565b91505092915050565b611df381611d84565b82525050565b5f602082019050611e0c5f830184611dea565b92915050565b5f81600f0b9050919050565b611e2781611e12565b8114611e31575f80fd5b50565b5f81359050611e4281611e1e565b92915050565b5f60208284031215611e5d57611e5c611b98565b5b5f611e6a84828501611e34565b91505092915050565b611e7c81611e12565b82525050565b5f602082019050611e955f830184611e73565b92915050565b5f7fffffffffffffffffffffffffffffffffffff000000000000000000000000000082169050919050565b611ecf81611e9b565b8114611ed9575f80fd5b50565b5f81359050611eea81611ec6565b92915050565b5f60208284031215611f0557611f04611b98565b5b5f611f1284828501611edc565b91505092915050565b611f2481611e9b565b82525050565b5f602082019050611f3d5f830184611f1b565b92915050565b5f8160040b9050919050565b611f5881611f43565b8114611f62575f80fd5b50565b5f81359050611f7381611f4f565b92915050565b5f60208284031215611f8e57611f8d611b98565b5b5f611f9b84828501611f65565b91505092915050565b611fad81611f43565b82525050565b5f602082019050611fc65f830184611fa4565b92915050565b5f81601c0b9050919050565b611fe181611fcc565b8114611feb575f80fd5b50565b5f81359050611ffc81611fd8565b92915050565b5f6020828403121561201757612016611b98565b5b5f61202484828501611fee565b91505092915050565b61203681611fcc565b82525050565b5f60208201905061204f5f83018461202d565b92915050565b5f81600c0b9050919050565b61206a81612055565b8114612074575f80fd5b50565b5f8135905061208581612061565b92915050565b5f602082840312156120a05761209f611b98565b5b5f6120ad84828501612077565b91505092915050565b6120bf81612055565b82525050565b5f6020820190506120d85f8301846120b6565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b612112816120de565b811461211c575f80fd5b50565b5f8135905061212d81612109565b92915050565b5f6020828403121561214857612147611b98565b5b5f6121558482850161211f565b91505092915050565b612167816120de565b82525050565b5f6020820190506121805f83018461215e565b92915050565b5f8160010b9050919050565b61219b81612186565b81146121a5575f80fd5b50565b5f813590506121b681612192565b92915050565b5f602082840312156121d1576121d0611b98565b5b5f6121de848285016121a8565b91505092915050565b6121f081612186565b82525050565b5f6020820190506122095f8301846121e7565b92915050565b5f8160070b9050919050565b6122248161220f565b811461222e575f80fd5b50565b5f8135905061223f8161221b565b92915050565b5f6020828403121561225a57612259611b98565b5b5f61226784828501612231565b91505092915050565b6122798161220f565b82525050565b5f6020820190506122925f830184612270565b92915050565b5f68ffffffffffffffffff82169050919050565b6122b581612298565b81146122bf575f80fd5b50565b5f813590506122d0816122ac565b92915050565b5f602082840312156122eb576122ea611b98565b5b5f6122f8848285016122c2565b91505092915050565b61230a81612298565b82525050565b5f6020820190506123235f830184612301565b92915050565b5f7fffff00000000000000000000000000000000000000000000000000000000000082169050919050565b61235d81612329565b8114612367575f80fd5b50565b5f8135905061237881612354565b92915050565b5f6020828403121561239357612392611b98565b5b5f6123a08482850161236a565b91505092915050565b6123b281612329565b82525050565b5f6020820190506123cb5f8301846123a9565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612405816123d1565b811461240f575f80fd5b50565b5f81359050612420816123fc565b92915050565b5f6020828403121561243b5761243a611b98565b5b5f61244884828501612412565b91505092915050565b61245a816123d1565b82525050565b5f6020820190506124735f830184612451565b92915050565b5f8160060b9050919050565b61248e81612479565b8114612498575f80fd5b50565b5f813590506124a981612485565b92915050565b5f602082840312156124c4576124c3611b98565b5b5f6124d18482850161249b565b91505092915050565b6124e381612479565b82525050565b5f6020820190506124fc5f8301846124da565b92915050565b5f815f0b9050919050565b61251681612502565b8114612520575f80fd5b50565b5f813590506125318161250d565b92915050565b5f6020828403121561254c5761254b611b98565b5b5f61255984828501612523565b91505092915050565b61256b81612502565b82525050565b5f6020820190506125845f830184612562565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000082169050919050565b6125be8161258a565b81146125c8575f80fd5b50565b5f813590506125d9816125b5565b92915050565b5f602082840312156125f4576125f3611b98565b5b5f612601848285016125cb565b91505092915050565b6126138161258a565b82525050565b5f60208201905061262c5f83018461260a565b92915050565b5f7fffffffffffffffffffffff00000000000000000000000000000000000000000082169050919050565b61266681612632565b8114612670575f80fd5b50565b5f813590506126818161265d565b92915050565b5f6020828403121561269c5761269b611b98565b5b5f6126a984828501612673565b91505092915050565b6126bb81612632565b82525050565b5f6020820190506126d45f8301846126b2565b92915050565b5f6affffffffffffffffffffff82169050919050565b6126f9816126da565b8114612703575f80fd5b50565b5f81359050612714816126f0565b92915050565b5f6020828403121561272f5761272e611b98565b5b5f61273c84828501612706565b91505092915050565b61274e816126da565b82525050565b5f6020820190506127675f830184612745565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffff000000000000000000000082169050919050565b6127a18161276d565b81146127ab575f80fd5b50565b5f813590506127bc81612798565b92915050565b5f602082840312156127d7576127d6611b98565b5b5f6127e4848285016127ae565b91505092915050565b6127f68161276d565b82525050565b5f60208201905061280f5f8301846127ed565b92915050565b5f8115159050919050565b61282981612815565b8114612833575f80fd5b50565b5f8135905061284481612820565b92915050565b5f6020828403121561285f5761285e611b98565b5b5f61286c84828501612836565b91505092915050565b61287e81612815565b82525050565b5f6020820190506128975f830184612875565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000082169050919050565b6128d18161289d565b81146128db575f80fd5b50565b5f813590506128ec816128c8565b92915050565b5f6020828403121561290757612906611b98565b5b5f612914848285016128de565b91505092915050565b6129268161289d565b82525050565b5f60208201905061293f5f83018461291d565b92915050565b5f81600d0b9050919050565b61295a81612945565b8114612964575f80fd5b50565b5f8135905061297581612951565b92915050565b5f602082840312156129905761298f611b98565b5b5f61299d84828501612967565b91505092915050565b6129af81612945565b82525050565b5f6020820190506129c85f8301846129a6565b92915050565b5f71ffffffffffffffffffffffffffffffffffff82169050919050565b6129f4816129ce565b81146129fe575f80fd5b50565b5f81359050612a0f816129eb565b92915050565b5f60208284031215612a2a57612a29611b98565b5b5f612a3784828501612a01565b91505092915050565b612a49816129ce565b82525050565b5f602082019050612a625f830184612a40565b92915050565b5f7fffffffffffffffffffffffffff0000000000000000000000000000000000000082169050919050565b612a9c81612a68565b8114612aa6575f80fd5b50565b5f81359050612ab781612a93565b92915050565b5f60208284031215612ad257612ad1611b98565b5b5f612adf84828501612aa9565b91505092915050565b612af181612a68565b82525050565b5f602082019050612b0a5f830184612ae8565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000082169050919050565b612b4481612b10565b8114612b4e575f80fd5b50565b5f81359050612b5f81612b3b565b92915050565b5f60208284031215612b7a57612b79611b98565b5b5f612b8784828501612b51565b91505092915050565b612b9981612b10565b82525050565b5f602082019050612bb25f830184612b90565b92915050565b5f7fffffffffffffffffffffffffffffffff0000000000000000000000000000000082169050919050565b612bec81612bb8565b8114612bf6575f80fd5b50565b5f81359050612c0781612be3565b92915050565b5f60208284031215612c2257612c21611b98565b5b5f612c2f84828501612bf9565b91505092915050565b612c4181612bb8565b82525050565b5f602082019050612c5a5f830184612c38565b92915050565b5f8160100b9050919050565b612c7581612c60565b8114612c7f575f80fd5b50565b5f81359050612c9081612c6c565b92915050565b5f60208284031215612cab57612caa611b98565b5b5f612cb884828501612c82565b91505092915050565b612cca81612c60565b82525050565b5f602082019050612ce35f830184612cc1565b92915050565b5f819050919050565b612cfb81612ce9565b8114612d05575f80fd5b50565b5f81359050612d1681612cf2565b92915050565b5f60208284031215612d3157612d30611b98565b5b5f612d3e84828501612d08565b91505092915050565b612d5081612ce9565b82525050565b5f602082019050612d695f830184612d47565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082169050919050565b612da381612d6f565b8114612dad575f80fd5b50565b5f81359050612dbe81612d9a565b92915050565b5f60208284031215612dd957612dd8611b98565b5b5f612de684828501612db0565b91505092915050565b612df881612d6f565b82525050565b5f602082019050612e115f830184612def565b92915050565b5f8160090b9050919050565b612e2c81612e17565b8114612e36575f80fd5b50565b5f81359050612e4781612e23565b92915050565b5f60208284031215612e6257612e61611b98565b5b5f612e6f84828501612e39565b91505092915050565b612e8181612e17565b82525050565b5f602082019050612e9a5f830184612e78565b92915050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b612ece81612ea0565b8114612ed8575f80fd5b50565b5f81359050612ee981612ec5565b92915050565b5f60208284031215612f0457612f03611b98565b5b5f612f1184828501612edb565b91505092915050565b612f2381612ea0565b82525050565b5f602082019050612f3c5f830184612f1a565b92915050565b5f819050919050565b612f5481612f42565b8114612f5e575f80fd5b50565b5f81359050612f6f81612f4b565b92915050565b5f60208284031215612f8a57612f89611b98565b5b5f612f9784828501612f61565b91505092915050565b612fa981612f42565b82525050565b5f602082019050612fc25f830184612fa0565b92915050565b5f77ffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b612ff481612fc8565b8114612ffe575f80fd5b50565b5f8135905061300f81612feb565b92915050565b5f6020828403121561302a57613029611b98565b5b5f61303784828501613001565b91505092915050565b61304981612fc8565b82525050565b5f6020820190506130625f830184613040565b92915050565b5f81601d0b9050919050565b61307d81613068565b8114613087575f80fd5b50565b5f8135905061309881613074565b92915050565b5f602082840312156130b3576130b2611b98565b5b5f6130c08482850161308a565b91505092915050565b6130d281613068565b82525050565b5f6020820190506130eb5f8301846130c9565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082169050919050565b613125816130f1565b811461312f575f80fd5b50565b5f813590506131408161311c565b92915050565b5f6020828403121561315b5761315a611b98565b5b5f61316884828501613132565b91505092915050565b61317a816130f1565b82525050565b5f6020820190506131935f830184613171565b92915050565b5f8160160b9050919050565b6131ae81613199565b81146131b8575f80fd5b50565b5f813590506131c9816131a5565b92915050565b5f602082840312156131e4576131e3611b98565b5b5f6131f1848285016131bb565b91505092915050565b61320381613199565b82525050565b5f60208201905061321c5f8301846131fa565b92915050565b5f7fffffffffff00000000000000000000000000000000000000000000000000000082169050919050565b61325681613222565b8114613260575f80fd5b50565b5f813590506132718161324d565b92915050565b5f6020828403121561328c5761328b611b98565b5b5f61329984828501613263565b91505092915050565b6132ab81613222565b82525050565b5f6020820190506132c45f8301846132a2565b92915050565b5f7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6132fb816132ca565b8114613305575f80fd5b50565b5f81359050613316816132f2565b92915050565b5f6020828403121561333157613330611b98565b5b5f61333e84828501613308565b91505092915050565b613350816132ca565b82525050565b5f6020820190506133695f830184613347565b92915050565b5f64ffffffffff82169050919050565b6133888161336f565b8114613392575f80fd5b50565b5f813590506133a38161337f565b92915050565b5f602082840312156133be576133bd611b98565b5b5f6133cb84828501613395565b91505092915050565b6133dd8161336f565b82525050565b5f6020820190506133f65f8301846133d4565b92915050565b5f819050919050565b61340e816133fc565b8114613418575f80fd5b50565b5f8135905061342981613405565b92915050565b5f6020828403121561344457613443611b98565b5b5f6134518482850161341b565b91505092915050565b613463816133fc565b82525050565b5f60208201905061347c5f83018461345a565b92915050565b5f8160190b9050919050565b61349781613482565b81146134a1575f80fd5b50565b5f813590506134b28161348e565b92915050565b5f602082840312156134cd576134cc611b98565b5b5f6134da848285016134a4565b91505092915050565b6134ec81613482565b82525050565b5f6020820190506135055f8301846134e3565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000082169050919050565b61353f8161350b565b8114613549575f80fd5b50565b5f8135905061355a81613536565b92915050565b5f6020828403121561357557613574611b98565b5b5f6135828482850161354c565b91505092915050565b6135948161350b565b82525050565b5f6020820190506135ad5f83018461358b565b92915050565b5f75ffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6135dd816135b3565b81146135e7575f80fd5b50565b5f813590506135f8816135d4565b92915050565b5f6020828403121561361357613612611b98565b5b5f613620848285016135ea565b91505092915050565b613632816135b3565b82525050565b5f60208201905061364b5f830184613629565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000082169050919050565b61368581613651565b811461368f575f80fd5b50565b5f813590506136a08161367c565b92915050565b5f602082840312156136bb576136ba611b98565b5b5f6136c884828501613692565b91505092915050565b6136da81613651565b82525050565b5f6020820190506136f35f8301846136d1565b92915050565b5f74ffffffffffffffffffffffffffffffffffffffffff82169050919050565b613722816136f9565b811461372c575f80fd5b50565b5f8135905061373d81613719565b92915050565b5f6020828403121561375857613757611b98565b5b5f6137658482850161372f565b91505092915050565b613777816136f9565b82525050565b5f6020820190506137905f83018461376e565b92915050565b5f7fffffffffffffffffffffffffffffffffff00000000000000000000000000000082169050919050565b6137ca81613796565b81146137d4575f80fd5b50565b5f813590506137e5816137c1565b92915050565b5f60208284031215613800576137ff611b98565b5b5f61380d848285016137d7565b91505092915050565b61381f81613796565b82525050565b5f6020820190506138385f830184613816565b92915050565b5f8160080b9050919050565b6138538161383e565b811461385d575f80fd5b50565b5f8135905061386e8161384a565b92915050565b5f6020828403121561388957613888611b98565b5b5f61389684828501613860565b91505092915050565b6138a88161383e565b82525050565b5f6020820190506138c15f83018461389f565b92915050565b5f8160050b9050919050565b6138dc816138c7565b81146138e6575f80fd5b50565b5f813590506138f7816138d3565b92915050565b5f6020828403121561391257613911611b98565b5b5f61391f848285016138e9565b91505092915050565b613931816138c7565b82525050565b5f60208201905061394a5f830184613928565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082169050919050565b61398481613950565b811461398e575f80fd5b50565b5f8135905061399f8161397b565b92915050565b5f602082840312156139ba576139b9611b98565b5b5f6139c784828501613991565b91505092915050565b6139d981613950565b82525050565b5f6020820190506139f25f8301846139d0565b92915050565b5f8160030b9050919050565b613a0d816139f8565b8114613a17575f80fd5b50565b5f81359050613a2881613a04565b92915050565b5f60208284031215613a4357613a42611b98565b5b5f613a5084828501613a1a565b91505092915050565b613a62816139f8565b82525050565b5f602082019050613a7b5f830184613a59565b92915050565b5f76ffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b613aac81613a81565b8114613ab6575f80fd5b50565b5f81359050613ac781613aa3565b92915050565b5f60208284031215613ae257613ae1611b98565b5b5f613aef84828501613ab9565b91505092915050565b613b0181613a81565b82525050565b5f602082019050613b1a5f830184613af8565b92915050565b5f7fffffffffffffffffffffffff000000000000000000000000000000000000000082169050919050565b613b5481613b20565b8114613b5e575f80fd5b50565b5f81359050613b6f81613b4b565b92915050565b5f60208284031215613b8a57613b89611b98565b5b5f613b9784828501613b61565b91505092915050565b613ba981613b20565b82525050565b5f602082019050613bc25f830184613ba0565b92915050565b5f7fffffffffffffffffffff0000000000000000000000000000000000000000000082169050919050565b613bfc81613bc8565b8114613c06575f80fd5b50565b5f81359050613c1781613bf3565b92915050565b5f60208284031215613c3257613c31611b98565b5b5f613c3f84828501613c09565b91505092915050565b613c5181613bc8565b82525050565b5f602082019050613c6a5f830184613c48565b92915050565b5f8160150b9050919050565b613c8581613c70565b8114613c8f575f80fd5b50565b5f81359050613ca081613c7c565b92915050565b5f60208284031215613cbb57613cba611b98565b5b5f613cc884828501613c92565b91505092915050565b613cda81613c70565b82525050565b5f602082019050613cf35f830184613cd1565b92915050565b5f65ffffffffffff82169050919050565b613d1381613cf9565b8114613d1d575f80fd5b50565b5f81359050613d2e81613d0a565b92915050565b5f60208284031215613d4957613d48611b98565b5b5f613d5684828501613d20565b91505092915050565b613d6881613cf9565b82525050565b5f602082019050613d815f830184613d5f565b92915050565b5f8160120b9050919050565b613d9c81613d87565b8114613da6575f80fd5b50565b5f81359050613db781613d93565b92915050565b5f60208284031215613dd257613dd1611b98565b5b5f613ddf84828501613da9565b91505092915050565b613df181613d87565b82525050565b5f602082019050613e0a5f830184613de8565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000082169050919050565b613e4481613e10565b8114613e4e575f80fd5b50565b5f81359050613e5f81613e3b565b92915050565b5f60208284031215613e7a57613e79611b98565b5b5f613e8784828501613e51565b91505092915050565b613e9981613e10565b82525050565b5f602082019050613eb25f830184613e90565b92915050565b5f7fffffffffffffffff00000000000000000000000000000000000000000000000082169050919050565b613eec81613eb8565b8114613ef6575f80fd5b50565b5f81359050613f0781613ee3565b92915050565b5f60208284031215613f2257613f21611b98565b5b5f613f2f84828501613ef9565b91505092915050565b613f4181613eb8565b82525050565b5f602082019050613f5a5f830184613f38565b92915050565b5f6cffffffffffffffffffffffffff82169050919050565b613f8181613f60565b8114613f8b575f80fd5b50565b5f81359050613f9c81613f78565b92915050565b5f60208284031215613fb757613fb6611b98565b5b5f613fc484828501613f8e565b91505092915050565b613fd681613f60565b82525050565b5f602082019050613fef5f830184613fcd565b92915050565b5f8160180b9050919050565b61400a81613ff5565b8114614014575f80fd5b50565b5f8135905061402581614001565b92915050565b5f602082840312156140405761403f611b98565b5b5f61404d84828501614017565b91505092915050565b61405f81613ff5565b82525050565b5f6020820190506140785f830184614056565b92915050565b5f70ffffffffffffffffffffffffffffffffff82169050919050565b6140a38161407e565b81146140ad575f80fd5b50565b5f813590506140be8161409a565b92915050565b5f602082840312156140d9576140d8611b98565b5b5f6140e6848285016140b0565b91505092915050565b6140f88161407e565b82525050565b5f6020820190506141115f8301846140ef565b92915050565b5f7fffffffffffffffffff000000000000000000000000000000000000000000000082169050919050565b61414b81614117565b8114614155575f80fd5b50565b5f8135905061416681614142565b92915050565b5f6020828403121561418157614180611b98565b5b5f61418e84828501614158565b91505092915050565b6141a081614117565b82525050565b5f6020820190506141b95f830184614197565b92915050565b5f8160130b9050919050565b6141d4816141bf565b81146141de575f80fd5b50565b5f813590506141ef816141cb565b92915050565b5f6020828403121561420a57614209611b98565b5b5f614217848285016141e1565b91505092915050565b614229816141bf565b82525050565b5f6020820190506142425f830184614220565b92915050565b5f81601b0b9050919050565b61425d81614248565b8114614267575f80fd5b50565b5f8135905061427881614254565b92915050565b5f6020828403121561429357614292611b98565b5b5f6142a08482850161426a565b91505092915050565b6142b281614248565b82525050565b5f6020820190506142cb5f8301846142a9565b92915050565b5f81601a0b9050919050565b6142e6816142d1565b81146142f0575f80fd5b50565b5f81359050614301816142dd565b92915050565b5f6020828403121561431c5761431b611b98565b5b5f614329848285016142f3565b91505092915050565b61433b816142d1565b82525050565b5f6020820190506143545f830184614332565b92915050565b5f66ffffffffffffff82169050919050565b6143758161435a565b811461437f575f80fd5b50565b5f813590506143908161436c565b92915050565b5f602082840312156143ab576143aa611b98565b5b5f6143b884828501614382565b91505092915050565b6143ca8161435a565b82525050565b5f6020820190506143e35f8301846143c1565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614437826143f1565b810181811067ffffffffffffffff8211171561445657614455614401565b5b80604052505050565b5f614468611b8f565b9050614474828261442e565b919050565b5f67ffffffffffffffff82111561449357614492614401565b5b61449c826143f1565b9050602081019050919050565b828183375f83830152505050565b5f6144c96144c484614479565b61445f565b9050828152602081018484840111156144e5576144e46143ed565b5b6144f08482856144a9565b509392505050565b5f82601f83011261450c5761450b6143e9565b5b813561451c8482602086016144b7565b91505092915050565b5f6020828403121561453a57614539611b98565b5b5f82013567ffffffffffffffff81111561455757614556611b9c565b5b614563848285016144f8565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61459e8261456c565b6145a88185614576565b93506145b8818560208601614586565b6145c1816143f1565b840191505092915050565b5f6020820190508181035f8301526145e48184614594565b905092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b61460e816145ec565b8114614618575f80fd5b50565b5f8135905061462981614605565b92915050565b5f6020828403121561464457614643611b98565b5b5f6146518482850161461b565b91505092915050565b614663816145ec565b82525050565b5f60208201905061467c5f83018461465a565b92915050565b5f62ffffff82169050919050565b61469981614682565b81146146a3575f80fd5b50565b5f813590506146b481614690565b92915050565b5f602082840312156146cf576146ce611b98565b5b5f6146dc848285016146a6565b91505092915050565b6146ee81614682565b82525050565b5f6020820190506147075f8301846146e5565b92915050565b5f78ffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b61473a8161470d565b8114614744575f80fd5b50565b5f8135905061475581614731565b92915050565b5f602082840312156147705761476f611b98565b5b5f61477d84828501614747565b91505092915050565b61478f8161470d565b82525050565b5f6020820190506147a85f830184614786565b92915050565b5f7fffffffffffffffffffffffffffff00000000000000000000000000000000000082169050919050565b6147e2816147ae565b81146147ec575f80fd5b50565b5f813590506147fd816147d9565b92915050565b5f6020828403121561481857614817611b98565b5b5f614825848285016147ef565b91505092915050565b614837816147ae565b82525050565b5f6020820190506148505f83018461482e565b92915050565b5f7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b61488881614856565b8114614892575f80fd5b50565b5f813590506148a38161487f565b92915050565b5f602082840312156148be576148bd611b98565b5b5f6148cb84828501614895565b91505092915050565b6148dd81614856565b82525050565b5f6020820190506148f65f8301846148d4565b92915050565b5f8160110b9050919050565b614911816148fc565b811461491b575f80fd5b50565b5f8135905061492c81614908565b92915050565b5f6020828403121561494757614946611b98565b5b5f6149548482850161491e565b91505092915050565b614966816148fc565b82525050565b5f60208201905061497f5f83018461495d565b92915050565b5f81601e0b9050919050565b61499a81614985565b81146149a4575f80fd5b50565b5f813590506149b581614991565b92915050565b5f602082840312156149d0576149cf611b98565b5b5f6149dd848285016149a7565b91505092915050565b6149ef81614985565b82525050565b5f602082019050614a085f8301846149e6565b92915050565b5f69ffffffffffffffffffff82169050919050565b614a2c81614a0e565b8114614a36575f80fd5b50565b5f81359050614a4781614a23565b92915050565b5f60208284031215614a6257614a61611b98565b5b5f614a6f84828501614a39565b91505092915050565b614a8181614a0e565b82525050565b5f602082019050614a9a5f830184614a78565b92915050565b614aa981611d65565b8114614ab3575f80fd5b50565b5f81359050614ac481614aa0565b92915050565b5f60208284031215614adf57614ade611b98565b5b5f614aec84828501614ab6565b91505092915050565b614afe81611d65565b82525050565b5f602082019050614b175f830184614af5565b92915050565b5f7fffffffffffffffffffffffffffffff000000000000000000000000000000000082169050919050565b614b5181614b1d565b8114614b5b575f80fd5b50565b5f81359050614b6c81614b48565b92915050565b5f60208284031215614b8757614b86611b98565b5b5f614b9484828501614b5e565b91505092915050565b614ba681614b1d565b82525050565b5f602082019050614bbf5f830184614b9d565b92915050565b5f81600b0b9050919050565b614bda81614bc5565b8114614be4575f80fd5b50565b5f81359050614bf581614bd1565b92915050565b5f60208284031215614c1057614c0f611b98565b5b5f614c1d84828501614be7565b91505092915050565b614c2f81614bc5565b82525050565b5f602082019050614c485f830184614c26565b92915050565b5f8160140b9050919050565b614c6381614c4e565b8114614c6d575f80fd5b50565b5f81359050614c7e81614c5a565b92915050565b5f60208284031215614c9957614c98611b98565b5b5f614ca684828501614c70565b91505092915050565b614cb881614c4e565b82525050565b5f602082019050614cd15f830184614caf565b92915050565b5f7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b614d0a81614cd7565b8114614d14575f80fd5b50565b5f81359050614d2581614d01565b92915050565b5f60208284031215614d4057614d3f611b98565b5b5f614d4d84828501614d17565b91505092915050565b614d5f81614cd7565b82525050565b5f602082019050614d785f830184614d56565b92915050565b5f67ffffffffffffffff82169050919050565b614d9a81614d7e565b8114614da4575f80fd5b50565b5f81359050614db581614d91565b92915050565b5f60208284031215614dd057614dcf611b98565b5b5f614ddd84828501614da7565b91505092915050565b614def81614d7e565b82525050565b5f602082019050614e085f830184614de6565b92915050565b5f63ffffffff82169050919050565b614e2681614e0e565b8114614e30575f80fd5b50565b5f81359050614e4181614e1d565b92915050565b5f60208284031215614e5c57614e5b611b98565b5b5f614e6984828501614e33565b91505092915050565b614e7b81614e0e565b82525050565b5f602082019050614e945f830184614e72565b92915050565b5f81600e0b9050919050565b614eaf81614e9a565b8114614eb9575f80fd5b50565b5f81359050614eca81614ea6565b92915050565b5f60208284031215614ee557614ee4611b98565b5b5f614ef284828501614ebc565b91505092915050565b614f0481614e9a565b82525050565b5f602082019050614f1d5f830184614efb565b92915050565b5f7fffffffffffffffffffffffffffffffffffffff0000000000000000000000000082169050919050565b614f5781614f23565b8114614f61575f80fd5b50565b5f81359050614f7281614f4e565b92915050565b5f60208284031215614f8d57614f8c611b98565b5b5f614f9a84828501614f64565b91505092915050565b614fac81614f23565b82525050565b5f602082019050614fc55f830184614fa3565b92915050565b5f7affffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b614ffa81614fcb565b8114615004575f80fd5b50565b5f8135905061501581614ff1565b92915050565b5f602082840312156150305761502f611b98565b5b5f61503d84828501615007565b91505092915050565b61504f81614fcb565b82525050565b5f6020820190506150685f830184615046565b92915050565b5f6effffffffffffffffffffffffffffff82169050919050565b6150918161506e565b811461509b575f80fd5b50565b5f813590506150ac81615088565b92915050565b5f602082840312156150c7576150c6611b98565b5b5f6150d48482850161509e565b91505092915050565b6150e68161506e565b82525050565b5f6020820190506150ff5f8301846150dd565b92915050565b5f61ffff82169050919050565b61511b81615105565b8114615125575f80fd5b50565b5f8135905061513681615112565b92915050565b5f6020828403121561515157615150611b98565b5b5f61515e84828501615128565b91505092915050565b61517081615105565b82525050565b5f6020820190506151895f830184615167565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000082169050919050565b6151c38161518f565b81146151cd575f80fd5b50565b5f813590506151de816151ba565b92915050565b5f602082840312156151f9576151f8611b98565b5b5f615206848285016151d0565b91505092915050565b6152188161518f565b82525050565b5f6020820190506152315f83018461520f565b92915050565b5f7fffffffffffffff0000000000000000000000000000000000000000000000000082169050919050565b61526b81615237565b8114615275575f80fd5b50565b5f8135905061528681615262565b92915050565b5f602082840312156152a1576152a0611b98565b5b5f6152ae84828501615278565b91505092915050565b6152c081615237565b82525050565b5f6020820190506152d95f8301846152b7565b92915050565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b615313816152df565b811461531d575f80fd5b50565b5f8135905061532e8161530a565b92915050565b5f6020828403121561534957615348611b98565b5b5f61535684828501615320565b91505092915050565b615368816152df565b82525050565b5f6020820190506153815f83018461535f565b92915050565b5f81600a0b9050919050565b61539c81615387565b81146153a6575f80fd5b50565b5f813590506153b781615393565b92915050565b5f602082840312156153d2576153d1611b98565b5b5f6153df848285016153a9565b91505092915050565b6153f181615387565b82525050565b5f60208201905061540a5f8301846153e8565b92915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b61543481615410565b811461543e575f80fd5b50565b5f8135905061544f8161542b565b92915050565b5f6020828403121561546a57615469611b98565b5b5f61547784828501615441565b91505092915050565b61548981615410565b82525050565b5f6020820190506154a25f830184615480565b92915050565b5f60ff82169050919050565b6154bd816154a8565b81146154c7575f80fd5b50565b5f813590506154d8816154b4565b92915050565b5f602082840312156154f3576154f2611b98565b5b5f615500848285016154ca565b91505092915050565b615512816154a8565b82525050565b5f60208201905061552b5f830184615509565b92915050565b5f72ffffffffffffffffffffffffffffffffffffff82169050919050565b61555881615531565b8114615562575f80fd5b50565b5f813590506155738161554f565b92915050565b5f6020828403121561558e5761558d611b98565b5b5f61559b84828501615565565b91505092915050565b6155ad81615531565b82525050565b5f6020820190506155c65f8301846155a4565b92915050565b5f7fffffffffffff000000000000000000000000000000000000000000000000000082169050919050565b615600816155cc565b811461560a575f80fd5b50565b5f8135905061561b816155f7565b92915050565b5f6020828403121561563657615635611b98565b5b5f6156438482850161560d565b91505092915050565b615655816155cc565b82525050565b5f60208201905061566e5f83018461564c565b92915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6156a481615674565b81146156ae575f80fd5b50565b5f813590506156bf8161569b565b92915050565b5f602082840312156156da576156d9611b98565b5b5f6156e7848285016156b1565b91505092915050565b6156f981615674565b82525050565b5f6020820190506157125f8301846156f0565b92915050565b5f8160170b9050919050565b61572d81615718565b8114615737575f80fd5b50565b5f8135905061574881615724565b92915050565b5f6020828403121561576357615762611b98565b5b5f6157708482850161573a565b91505092915050565b61578281615718565b82525050565b5f60208201905061579b5f830184615779565b9291505056fea26469706673582212201ebd2d9245c78f49212fb4320e0d905e34d705bd83b3a3bc23383c8acba3c58464736f6c634300081a0033 \ No newline at end of file diff --git a/hiero-enterprise-microprofile/src/test/resources/large_contract.bin b/hiero-enterprise-microprofile/src/test/resources/large_contract.bin new file mode 100644 index 00000000..7ce1fcf6 --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/resources/large_contract.bin @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001805f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0181905550610f19806100bf5f395ff3fe608060405234801561000f575f80fd5b5060043610610086575f3560e01c8063609ff1bd11610059578063609ff1bd146101115780639e7b8d611461012f578063a3ec138d1461014b578063e2ba53f01461017e57610086565b80630121b93f1461008a578063013cf08b146100a65780632e4176cf146100d75780635c19a95c146100f5575b5f80fd5b6100a4600480360381019061009f9190610993565b61019c565b005b6100c060048036038101906100bb9190610993565b6102d7565b6040516100ce9291906109e5565b60405180910390f35b6100df610306565b6040516100ec9190610a4b565b60405180910390f35b61010f600480360381019061010a9190610a8e565b610329565b005b6101196106ae565b6040516101269190610ab9565b60405180910390f35b61014960048036038101906101449190610a8e565b610729565b005b61016560048036038101906101609190610a8e565b6108d4565b6040516101759493929190610aec565b60405180910390f35b61018661092c565b6040516101939190610b2f565b60405180910390f35b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f815f015403610221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021890610ba2565b60405180910390fd5b806001015f9054906101000a900460ff1615610272576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161026990610c0a565b60405180910390fd5b6001816001015f6101000a81548160ff021916908315150217905550818160020181905550805f0154600283815481106102af576102ae610c28565b5b905f5260205f2090600202016001015f8282546102cc9190610c82565b925050819055505050565b600281815481106102e6575f80fd5b905f5260205f2090600202015f91509050805f0154908060010154905082565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050806001015f9054906101000a900460ff16156103ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b190610cff565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610428576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041f90610d67565b60405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146105925760015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361058d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058490610dcf565b60405180910390fd5b610429565b6001816001015f6101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050806001015f9054906101000a900460ff161561068c57815f0154600282600201548154811061066357610662610c28565b5b905f5260205f2090600202016001015f8282546106809190610c82565b925050819055506106a9565b815f0154815f015f8282546106a19190610c82565b925050819055505b505050565b5f805f90505f5b6002805490508110156107245781600282815481106106d7576106d6610c28565b5b905f5260205f209060020201600101541115610717576002818154811061070157610700610c28565b5b905f5260205f2090600202016001015491508092505b80806001019150506106b5565b505090565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90610e5d565b60405180910390fd5b60015f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff1615610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a90610ec5565b60405180910390fd5b5f60015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01541461088d575f80fd5b6001805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f018190555050565b6001602052805f5260405f205f91509050805f015490806001015f9054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b5f60026109376106ae565b8154811061094857610947610c28565b5b905f5260205f2090600202015f0154905090565b5f80fd5b5f819050919050565b61097281610960565b811461097c575f80fd5b50565b5f8135905061098d81610969565b92915050565b5f602082840312156109a8576109a761095c565b5b5f6109b58482850161097f565b91505092915050565b5f819050919050565b6109d0816109be565b82525050565b6109df81610960565b82525050565b5f6040820190506109f85f8301856109c7565b610a0560208301846109d6565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a3582610a0c565b9050919050565b610a4581610a2b565b82525050565b5f602082019050610a5e5f830184610a3c565b92915050565b610a6d81610a2b565b8114610a77575f80fd5b50565b5f81359050610a8881610a64565b92915050565b5f60208284031215610aa357610aa261095c565b5b5f610ab084828501610a7a565b91505092915050565b5f602082019050610acc5f8301846109d6565b92915050565b5f8115159050919050565b610ae681610ad2565b82525050565b5f608082019050610aff5f8301876109d6565b610b0c6020830186610add565b610b196040830185610a3c565b610b2660608301846109d6565b95945050505050565b5f602082019050610b425f8301846109c7565b92915050565b5f82825260208201905092915050565b7f486173206e6f20726967687420746f20766f74650000000000000000000000005f82015250565b5f610b8c601483610b48565b9150610b9782610b58565b602082019050919050565b5f6020820190508181035f830152610bb981610b80565b9050919050565b7f416c726561647920766f7465642e0000000000000000000000000000000000005f82015250565b5f610bf4600e83610b48565b9150610bff82610bc0565b602082019050919050565b5f6020820190508181035f830152610c2181610be8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610c8c82610960565b9150610c9783610960565b9250828201905080821115610caf57610cae610c55565b5b92915050565b7f596f7520616c726561647920766f7465642e00000000000000000000000000005f82015250565b5f610ce9601283610b48565b9150610cf482610cb5565b602082019050919050565b5f6020820190508181035f830152610d1681610cdd565b9050919050565b7f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e00005f82015250565b5f610d51601e83610b48565b9150610d5c82610d1d565b602082019050919050565b5f6020820190508181035f830152610d7e81610d45565b9050919050565b7f466f756e64206c6f6f7020696e2064656c65676174696f6e2e000000000000005f82015250565b5f610db9601983610b48565b9150610dc482610d85565b602082019050919050565b5f6020820190508181035f830152610de681610dad565b9050919050565b7f4f6e6c79206368616972706572736f6e2063616e2067697665207269676874205f8201527f746f20766f74652e000000000000000000000000000000000000000000000000602082015250565b5f610e47602883610b48565b9150610e5282610ded565b604082019050919050565b5f6020820190508181035f830152610e7481610e3b565b9050919050565b7f54686520766f74657220616c726561647920766f7465642e00000000000000005f82015250565b5f610eaf601883610b48565b9150610eba82610e7b565b602082019050919050565b5f6020820190508181035f830152610edc81610ea3565b905091905056fea26469706673582212204229541172c4be6600c0fc79405b6363d8bb043e68e407a4c2ce40895458370e64736f6c634300081a0033 \ No newline at end of file diff --git a/hiero-enterprise-microprofile/src/test/resources/small_contract.bin b/hiero-enterprise-microprofile/src/test/resources/small_contract.bin new file mode 100644 index 00000000..dded8ea8 --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/resources/small_contract.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610118806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063b4598503146037578063fe17e8b7146070575b600080fd5b60408051808201909152600d81526c48656c6c6f2c20576f726c642160981b60208201525b604051606791906096565b60405180910390f35b60408051808201909152600b81526a48656c6c6f2c204f48472160a81b6020820152605c565b600060208083528351808285015260005b8181101560c15785810183015185820160400152820160a7565b506000604082860101526040601f19601f830116850101925050509291505056fea264697066735822122092e0b690eaa3de2581f4b757d0675c3bebfaba72b6d17ddb72855d915865693864736f6c63430008110033 \ No newline at end of file diff --git a/hiero-enterprise-microprofile/src/test/resources/string_param_constructor_contract.bin b/hiero-enterprise-microprofile/src/test/resources/string_param_constructor_contract.bin new file mode 100644 index 00000000..45c7543a --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/resources/string_param_constructor_contract.bin @@ -0,0 +1 @@ +608060405234801561000f575f80fd5b506040516106bc3803806106bc83398181016040528101906100319190610193565b805f908161003f91906103e7565b50506104b6565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6100a58261005f565b810181811067ffffffffffffffff821117156100c4576100c361006f565b5b80604052505050565b5f6100d6610046565b90506100e2828261009c565b919050565b5f67ffffffffffffffff8211156101015761010061006f565b5b61010a8261005f565b9050602081019050919050565b8281835e5f83830152505050565b5f610137610132846100e7565b6100cd565b9050828152602081018484840111156101535761015261005b565b5b61015e848285610117565b509392505050565b5f82601f83011261017a57610179610057565b5b815161018a848260208601610125565b91505092915050565b5f602082840312156101a8576101a761004f565b5b5f82015167ffffffffffffffff8111156101c5576101c4610053565b5b6101d184828501610166565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061022857607f821691505b60208210810361023b5761023a6101e4565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261029d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610262565b6102a78683610262565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6102eb6102e66102e1846102bf565b6102c8565b6102bf565b9050919050565b5f819050919050565b610304836102d1565b610318610310826102f2565b84845461026e565b825550505050565b5f90565b61032c610320565b6103378184846102fb565b505050565b5b8181101561035a5761034f5f82610324565b60018101905061033d565b5050565b601f82111561039f5761037081610241565b61037984610253565b81016020851015610388578190505b61039c61039485610253565b83018261033c565b50505b505050565b5f82821c905092915050565b5f6103bf5f19846008026103a4565b1980831691505092915050565b5f6103d783836103b0565b9150826002028217905092915050565b6103f0826101da565b67ffffffffffffffff8111156104095761040861006f565b5b6104138254610211565b61041e82828561035e565b5f60209050601f83116001811461044f575f841561043d578287015190505b61044785826103cc565b8655506104ae565b601f19841661045d86610241565b5f5b828110156104845784890151825560018201915060208501945060208101905061045f565b868310156104a1578489015161049d601f8916826103b0565b8355505b6001600288020188555050505b505050505050565b6101f9806104c35f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c806306fdde031461002d575b5f80fd5b61003561004b565b6040516100429190610146565b60405180910390f35b5f805461005790610193565b80601f016020809104026020016040519081016040528092919081815260200182805461008390610193565b80156100ce5780601f106100a5576101008083540402835291602001916100ce565b820191905f5260205f20905b8154815290600101906020018083116100b157829003601f168201915b505050505081565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610118826100d6565b61012281856100e0565b93506101328185602086016100f0565b61013b816100fe565b840191505092915050565b5f6020820190508181035f83015261015e818461010e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806101aa57607f821691505b6020821081036101bd576101bc610166565b5b5091905056fea26469706673582212201412e6d4699d83d6755c548fe6aa49800c508cda4c6d277c14bb8f74bfc4674c64736f6c634300081a0033 \ No newline at end of file diff --git a/hiero-enterprise-microprofile/src/test/resources/uint_getter_setter_contract.bin b/hiero-enterprise-microprofile/src/test/resources/uint_getter_setter_contract.bin new file mode 100644 index 00000000..900d5b1a --- /dev/null +++ b/hiero-enterprise-microprofile/src/test/resources/uint_getter_setter_contract.bin @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b506101438061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c80636d4ce63c14610038578063e5c19b2d14610056575b5f80fd5b610040610072565b60405161004d919061009b565b60405180910390f35b610070600480360381019061006b91906100e2565b61007a565b005b5f8054905090565b805f8190555050565b5f819050919050565b61009581610083565b82525050565b5f6020820190506100ae5f83018461008c565b92915050565b5f80fd5b6100c181610083565b81146100cb575f80fd5b50565b5f813590506100dc816100b8565b92915050565b5f602082840312156100f7576100f66100b4565b5b5f610104848285016100ce565b9150509291505056fea2646970667358221220f28c19862a0c2c63bf120b0d3cd8f0a7749aea3ed3a89688130ec688064597a364736f6c634300081a0033 \ No newline at end of file diff --git a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ProtocolLayerClientTests.java b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ProtocolLayerClientTests.java index 5e106357..fa067cef 100644 --- a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ProtocolLayerClientTests.java +++ b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ProtocolLayerClientTests.java @@ -134,14 +134,16 @@ void testFileDelete() throws Exception { void testContractCreate() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/small_contract.bin").getPath()); + Path.of(ProtocolLayerClientTests.class.getResource("/small_contract.bin").getPath()); final String content = Files.readString(path, StandardCharsets.UTF_8); final byte[] bytes = content.getBytes(StandardCharsets.UTF_8); final FileCreateRequest fileCreateRequest = FileCreateRequest.of(bytes); final FileCreateResult result = protocolLayerClient.executeFileCreateTransaction(fileCreateRequest); final FileId fileId = result.fileId(); - final ContractCreateRequest request = ContractCreateRequest.of(fileId); + final Hbar maxTransactionFee = Hbar.from(16); + final int gas = 5_000_000; + final ContractCreateRequest request = ContractCreateRequest.of(fileId, maxTransactionFee, gas); // when final ContractCreateResult contractCreateResult = diff --git a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ContractServiceTest.java b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractClientTest.java similarity index 80% rename from hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ContractServiceTest.java rename to hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractClientTest.java index 8344bfff..6b944cc7 100644 --- a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/ContractServiceTest.java +++ b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractClientTest.java @@ -20,7 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(classes = HieroTestConfig.class) -public class ContractServiceTest { +public class SmartContractClientTest { @Autowired private FileClient fileClient; @@ -30,7 +30,7 @@ public class ContractServiceTest { void testContractCreateByFileId() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/small_contract.bin").getPath()); + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); final String content = Files.readString(path, StandardCharsets.UTF_8); final byte[] bytes = content.getBytes(StandardCharsets.UTF_8); final FileId fileId = fileClient.createFile(bytes); @@ -46,7 +46,7 @@ void testContractCreateByFileId() throws Exception { void testContractCreateByBytes() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/small_contract.bin").getPath()); + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); final String content = Files.readString(path, StandardCharsets.UTF_8); final byte[] bytes = content.getBytes(StandardCharsets.UTF_8); @@ -61,7 +61,7 @@ void testContractCreateByBytes() throws Exception { void testContractCreateSimple() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/small_contract.bin").getPath()); + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); // when final ContractId contract = smartContractClient.createContract(path); @@ -74,7 +74,7 @@ void testContractCreateSimple() throws Exception { void testContractCreateSimpleWithLargeContract() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/large_contract.bin").getPath()); + Path.of(SmartContractClientTest.class.getResource("/large_contract.bin").getPath()); // when final ContractId contract = smartContractClient.createContract(path); @@ -98,7 +98,7 @@ void testContractWithConstructorParam() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class + SmartContractClientTest.class .getResource("/string_param_constructor_contract.bin") .getPath()); @@ -114,7 +114,7 @@ void testContractWithConstructorParam() throws Exception { void testContractWithInvalidConstructorParam() throws Exception { // given final Path path = - Path.of(ContractServiceTest.class.getResource("/small_contract.bin").getPath()); + Path.of(SmartContractClientTest.class.getResource("/small_contract.bin").getPath()); // when Assertions.assertThrows( @@ -126,7 +126,9 @@ void testCallFunction() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); // when @@ -141,7 +143,9 @@ void testCallInvalidFunction() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); // when @@ -154,7 +158,9 @@ void testCallFunctionWithParam() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); // when @@ -170,7 +176,9 @@ void testCallFunctionWithInvalidParam() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); // then @@ -184,7 +192,9 @@ void testCallFunctionWithResult() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); smartContractClient.callContractFunction(contract, "set", int256(123)); @@ -201,7 +211,9 @@ void testCallFunctionWithWrongResult() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); smartContractClient.callContractFunction(contract, "set", int256(123)); @@ -217,7 +229,9 @@ void testCallFunctionWithWrongResultCount() throws Exception { // given final Path path = Path.of( - ContractServiceTest.class.getResource("/uint_getter_setter_contract.bin").getPath()); + SmartContractClientTest.class + .getResource("/uint_getter_setter_contract.bin") + .getPath()); final ContractId contract = smartContractClient.createContract(path); smartContractClient.callContractFunction(contract, "set", int256(123)); diff --git a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractDatatypesTests.java b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractDatatypesTests.java index cfb6e093..5e56b84c 100644 --- a/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractDatatypesTests.java +++ b/hiero-enterprise-spring/src/test/java/org/hiero/spring/test/SmartContractDatatypesTests.java @@ -31,7 +31,7 @@ private synchronized ContractId getOrCreateContractId() { if (contractId == null) { try { final Path path = - Path.of(ContractServiceTest.class.getResource("/datatypes.bin").getPath()); + Path.of(SmartContractDatatypesTests.class.getResource("/datatypes.bin").getPath()); contractId = smartContractClient.createContract(path); } catch (Exception e) { throw new RuntimeException("Can not create contract", e);