From 330112e737ba17d950c8edfe2adbdbc96fbacaf0 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 9 Aug 2023 16:32:19 +0200 Subject: [PATCH 01/53] Working (early) implementation of serializing receive parameters. Custom serialization of AbstractAddress. Refactoring of Errors returned from JNI rust layer. Refactoring of BakerKeys- ConfigureBakerKeys- TransferToPublicJni- Result to remove Optional fields. --- concordium-base | 2 +- .../sdk/crypto/CryptoJniNative.java | 12 ++ .../crypto/bakertransactions/BakerKeys.java | 6 +- .../bakertransactions/BakerKeysResult.java | 21 +- .../bakertransactions/ConfigureBakerKeys.java | 6 +- .../ConfigureBakerKeysJniInput.java | 28 ++- .../ConfigureBakerKeysResult.java | 21 +- .../EncryptedAmountTransferJniResult.java | 21 +- .../EncryptedTransfers.java | 11 +- .../TransferToPublicJniResult.java | 23 ++- .../sdk/exceptions/CryptoJniException.java | 29 ++- .../concordium/sdk/exceptions/JNIError.java | 23 +++ .../sdk/exceptions/JNIErrorType.java | 19 ++ .../sdk/transactions/Parameter.java | 11 +- .../concordium/sdk/transactions/Schema.java | 34 ++++ .../sdk/transactions/SchemaParameter.java | 92 +++++++++ .../sdk/transactions/SchemaVersion.java | 20 ++ .../SerializeParameterResult.java | 35 ++++ .../transactions/UpdateContractPayload.java | 7 + .../concordium/sdk/types/AbstractAddress.java | 29 +++ .../transactions/TransferToPublicTest.java | 2 +- crypto-jni/Cargo.lock | 128 +----------- crypto-jni/Cargo.toml | 1 + crypto-jni/src/lib.rs | 192 ++++++++++++++++-- 24 files changed, 562 insertions(+), 211 deletions(-) create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java diff --git a/concordium-base b/concordium-base index 4e980f763..7c94c5960 160000 --- a/concordium-base +++ b/concordium-base @@ -1 +1 @@ -Subproject commit 4e980f763b0014129529224fd22ed3d34e6304bd +Subproject commit 7c94c596000ad3353cb860bf68460891703f8ccf diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 8c21d210c..057482eb5 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -71,4 +71,16 @@ public class CryptoJniNative { */ public static native String generateConfigureBakerKeysPayload(String input); + /** + * Serializes a json representation of a parameter using a schema of the module. + * @param parameterJson json representation of the parameter. + * @param contractName name of the contract. + * @param methodName name of the method. + * @param schemaBytes schema of the contract. + * @param schemaVersion version of the schema. + * @param verboseErrors whether errors are in verbose format or not. + * @return JSON representing (SerializedParam, ResultCode, ErrorMessage) + */ + public static native String serializeParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); + } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java index d6d5c6d85..928bbf177 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java @@ -1,7 +1,6 @@ package com.concordium.sdk.crypto.bakertransactions; import com.concordium.sdk.crypto.CryptoJniNative; -import com.concordium.sdk.crypto.CryptoJniResultCode; import com.concordium.sdk.crypto.NativeResolver; import com.concordium.sdk.exceptions.CryptoJniException; import com.concordium.sdk.serializing.JsonMapper; @@ -27,11 +26,10 @@ public static BakerKeysJniOutput createBakerKeys() { } if (!result.isok()) { throw CryptoJniException.from( - result.getErr().orElse(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + result.getErr()); } - return result.getOk().orElseThrow( - () -> CryptoJniException.from(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + return result.getOk(); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java index 4b84848db..29b16a886 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java @@ -1,12 +1,12 @@ package com.concordium.sdk.crypto.bakertransactions; -import com.concordium.sdk.crypto.CryptoJniResultCode; +import com.concordium.sdk.exceptions.JNIError; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.ToString; -import java.util.Optional; +import java.util.Objects; /** * Class that holds the result of generating baker keys payload @@ -18,21 +18,26 @@ public class BakerKeysResult { * An optional `BakerKeysJniOutput` object, containing the output of the generate baker keys function. */ @JsonProperty("Ok") - private final Optional ok; + private final BakerKeysJniOutput ok; /** * An optional `CryptoJniResultCode` object, containing an error code if the generate baker keys function failed. */ @JsonProperty("Err") - private final Optional err; + private final JNIError err; + + private boolean isSuccess; @JsonCreator BakerKeysResult( @JsonProperty("Ok") BakerKeysJniOutput ok, - @JsonProperty("Err") CryptoJniResultCode err + @JsonProperty("Err") JNIError err ) { - this.ok = Optional.ofNullable(ok); - this.err = Optional.ofNullable(err); + this.ok = ok; + this.err = err; + if (Objects.isNull(err)) { + isSuccess = true; + } } /** @@ -41,6 +46,6 @@ public class BakerKeysResult { * @return a boolean indicating whether the `ok` field is present. */ public boolean isok() { - return ok.isPresent(); + return this.isSuccess; } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java index e22a9fc89..3900af5d5 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java @@ -1,7 +1,6 @@ package com.concordium.sdk.crypto.bakertransactions; import com.concordium.sdk.crypto.CryptoJniNative; -import com.concordium.sdk.crypto.CryptoJniResultCode; import com.concordium.sdk.crypto.NativeResolver; import com.concordium.sdk.exceptions.CryptoJniException; import com.concordium.sdk.serializing.JsonMapper; @@ -29,12 +28,11 @@ public static ConfigureBakerKeysJniOutput generateConfigureBakerKeysPayload(Conf if (!result.isok()) { throw CryptoJniException.from( - result.getErr().orElse(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + result.getErr()); } // return the ok field of the result object - return result.getOk().orElseThrow( - () -> CryptoJniException.from(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + return result.getOk(); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java index 73473457e..d79753703 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java @@ -1,6 +1,7 @@ package com.concordium.sdk.crypto.bakertransactions; import com.concordium.sdk.types.AccountAddress; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.Builder; import lombok.Data; @@ -8,14 +9,37 @@ * Configure the account as a baker. Only valid for protocol version 4 and up. */ @Data -@Builder public class ConfigureBakerKeysJniInput { + /** * The address of the account that will be configured as a baker */ - private final AccountAddress sender; + private final ConfigureBakerAccountAddress sender; + /** * The baker keys that will be configured for the account */ private final BakerKeysJniOutput keys; + + @Builder + public ConfigureBakerKeysJniInput(AccountAddress sender, BakerKeysJniOutput keys) { + this.sender = new ConfigureBakerAccountAddress(sender); + this.keys = keys; + } + + /** + * Document why I am here... + */ + private static class ConfigureBakerAccountAddress { + private final AccountAddress address; + + private ConfigureBakerAccountAddress(AccountAddress address) { + this.address = address; + } + + @JsonValue + String getAddress () { + return this.address.encoded(); + } + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java index 67060f6f8..2fee33ca6 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java @@ -1,12 +1,12 @@ package com.concordium.sdk.crypto.bakertransactions; -import com.concordium.sdk.crypto.CryptoJniResultCode; +import com.concordium.sdk.exceptions.JNIError; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.ToString; -import java.util.Optional; +import java.util.Objects; @Data @ToString(doNotUseGetters = true) @@ -15,21 +15,26 @@ public class ConfigureBakerKeysResult { * An optional `ConfigureBakerKeysJniOutput` object, containing the output of the configure baker keys function. */ @JsonProperty("Ok") - private final Optional ok; + private final ConfigureBakerKeysJniOutput ok; /** * An optional `CryptoJniResultCode` object, containing an error code if the configure baker keys function failed. */ @JsonProperty("Err") - private final Optional err; + private final JNIError err; + + private boolean isSuccess; @JsonCreator ConfigureBakerKeysResult( @JsonProperty("Ok") ConfigureBakerKeysJniOutput ok, - @JsonProperty("Err") CryptoJniResultCode err + @JsonProperty("Err") JNIError err ) { - this.ok = Optional.ofNullable(ok); - this.err = Optional.ofNullable(err); + this.ok = ok; + this.err = err; + if (Objects.isNull(err)) { + isSuccess = true; + } } /** @@ -38,6 +43,6 @@ public class ConfigureBakerKeysResult { * @return a boolean indicating whether the `ok` field is present. */ public boolean isok() { - return ok.isPresent(); + return isSuccess; } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java index 951e0bd4b..24f13f41c 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java @@ -1,30 +1,35 @@ package com.concordium.sdk.crypto.encryptedtransfers; -import com.concordium.sdk.crypto.CryptoJniResultCode; +import com.concordium.sdk.exceptions.JNIError; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; -import java.util.Optional; +import java.util.Objects; @Data public class EncryptedAmountTransferJniResult { @JsonProperty("Ok") - private final Optional ok; + private final EncryptedAmountTransferJniOutput ok; @JsonProperty("Err") - private final Optional err; + private final JNIError err; + + private boolean isSuccess; @JsonCreator EncryptedAmountTransferJniResult( @JsonProperty("Ok") EncryptedAmountTransferJniOutput ok, - @JsonProperty("Err") CryptoJniResultCode err + @JsonProperty("Err") JNIError err ) { - this.ok = Optional.ofNullable(ok); - this.err = Optional.ofNullable(err); + this.ok = ok; + this.err = err; + if (Objects.isNull(err)) { + isSuccess = true; + } } public boolean isok() { - return ok.isPresent(); + return isSuccess; } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java index a5d06eb77..bae767e73 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java @@ -1,7 +1,6 @@ package com.concordium.sdk.crypto.encryptedtransfers; import com.concordium.sdk.crypto.CryptoJniNative; -import com.concordium.sdk.crypto.CryptoJniResultCode; import com.concordium.sdk.crypto.NativeResolver; import com.concordium.sdk.crypto.elgamal.ElgamalPublicKey; import com.concordium.sdk.crypto.elgamal.ElgamalSecretKey; @@ -55,11 +54,10 @@ static TransferToPublicJniOutput createSecToPubTransferPayload(TransferToPublicJ if (!result.isok()) { throw CryptoJniException.from( - result.getErr().orElse(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + result.getErr()); } - return result.getOk().orElseThrow( - () -> CryptoJniException.from(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + return result.getOk(); } @@ -91,11 +89,10 @@ static EncryptedAmountTransferJniOutput createEncryptedTransferPayload(Encrypted if (!result.isok()) { throw CryptoJniException.from( - result.getErr().orElse(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + result.getErr()); } - return result.getOk().orElseThrow( - () -> CryptoJniException.from(CryptoJniResultCode.ERROR_UNKNOWN_RESULT_CODE)); + return result.getOk(); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java index a69de941d..64ecc8036 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java @@ -1,11 +1,11 @@ package com.concordium.sdk.crypto.encryptedtransfers; -import com.concordium.sdk.crypto.CryptoJniResultCode; +import com.concordium.sdk.exceptions.JNIError; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; -import java.util.Optional; +import java.util.Objects; @Data public class TransferToPublicJniResult { @@ -13,21 +13,26 @@ public class TransferToPublicJniResult { * An optional `TransferToPublicJniOutput` object, containing the output of the encrypted transfer function. */ @JsonProperty("Ok") - private final Optional ok; + private final TransferToPublicJniOutput ok; /** * An optional `CryptoJniResultCode` object, containing an error code if the encrypted transfer function failed. */ - @JsonProperty("Err") - private final Optional err; + @JsonProperty("Err") //CryptoJniResultCode + private final JNIError err; + + private boolean isSuccess; @JsonCreator TransferToPublicJniResult( @JsonProperty("Ok") TransferToPublicJniOutput ok, - @JsonProperty("Err") CryptoJniResultCode err + @JsonProperty("Err") JNIError err ) { - this.ok = Optional.ofNullable(ok); - this.err = Optional.ofNullable(err); + this.ok = ok; + this.err = err; + if (Objects.isNull(err)) { + isSuccess = true; + } } /** @@ -36,6 +41,6 @@ public class TransferToPublicJniResult { * @return a boolean indicating whether the `ok` field is present. */ public boolean isok() { - return ok.isPresent(); + return this.isSuccess; } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java index ee23e8d56..d4bd7fb84 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java @@ -1,6 +1,5 @@ package com.concordium.sdk.exceptions; -import com.concordium.sdk.crypto.CryptoJniResultCode; import lombok.Getter; /** @@ -12,25 +11,23 @@ public final class CryptoJniException extends RuntimeException { * The result code of the failed cryptographic operation. */ @Getter - private final CryptoJniResultCode code; + private final JNIErrorType errorType; + @Getter + private final String errorMessage; - /** - * Creates a new `CryptoJniException` object with the given result code. - * - * @param code the result code of the failed cryptographic operation. - */ - private CryptoJniException(CryptoJniResultCode code) { - super(code.getErrorMessage()); - this.code = code; + + CryptoJniException(JNIError error) { + super(error.getErrorType() + ": " + error.getErrorMessage()); + this.errorType = error.getErrorType(); + this.errorMessage = error.getErrorMessage(); } /** - * Creates a new `CryptoJniException` object from the given result code. - * - * @param code the result code of the failed cryptographic operation. - * @return a new `CryptoJniException` object. + * Create a new CryptoJniException from the {@link JNIError}. + * @param error {@link JNIError} returned from the rust layer. + * @return {@link CryptoJniException} matching the {@link JNIError}. */ - public static CryptoJniException from(CryptoJniResultCode code) { - return new CryptoJniException(code); + public static CryptoJniException from(JNIError error) { + return new CryptoJniException(error); } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java new file mode 100644 index 000000000..bc2d07575 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java @@ -0,0 +1,23 @@ +package com.concordium.sdk.exceptions; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.ToString; + + +@Getter +@ToString +public class JNIError { + + private final String errorMessage; + private final JNIErrorType errorType; + + @JsonCreator + public JNIError( + @JsonProperty("errorType") JNIErrorType type, + @JsonProperty("errorMessage") String errorMessage) { + this.errorMessage = errorMessage; + this.errorType = type; + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java new file mode 100644 index 000000000..f8dc0337d --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java @@ -0,0 +1,19 @@ +package com.concordium.sdk.exceptions; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents the different types of possible errors when performing operations using the JNI. + */ +public enum JNIErrorType { + @JsonProperty("ParameterSerializationError") + PARAMETER_SERIALIZATION_ERROR, + @JsonProperty("Utf8DecodeError") + UTF8_DECODE_ERROR, + @JsonProperty("JsonDeserializationError") + JSON_DESERIALIZATION_ERROR , + @JsonProperty("NativeConversionError") + NATIVE_CONVERSION_ERROR, + @JsonProperty("PayloadCreationError") + PAYLOAD_CREATION_ERROR +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 0b66f09de..2841dfa2c 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -2,6 +2,7 @@ import com.concordium.sdk.types.UInt16; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Getter; import lombok.ToString; import lombok.val; @@ -11,7 +12,7 @@ /** * The parameters are used for updating the smart contract instance. - * i.e. calling a recieve function exposed in the smart contract with the parameters. + * i.e. calling a "receive" function exposed in the smart contract with the parameters. * Buffer of the parameters message. * In the current supported protocols the size is limited to be 1kb. */ @@ -19,11 +20,13 @@ @Getter @ToString public final class Parameter { + public static final int MAX_SIZE = 1024; public static final Parameter EMPTY = Parameter.from(new byte[0]); private final byte[] bytes; @JsonCreator Parameter(byte[] bytes) { + // TODO enforce 1kb max this.bytes = bytes; } @@ -44,4 +47,10 @@ public byte[] getBytes() { buffer.put(paramBuffer); return buffer.array(); } + + public static Parameter from(SchemaParameter param) throws JsonProcessingException { + + //return from(param.toBytes()); + return null; + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java new file mode 100644 index 000000000..bccf06982 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java @@ -0,0 +1,34 @@ +package com.concordium.sdk.transactions; + +import lombok.Getter; + +import java.io.*; + +/** + * TODO comment + */ +@Getter +public class Schema { + + private final byte[] schemaBytes; + + private final SchemaVersion version; + + Schema(byte[] schemaBytes, SchemaVersion version) { + this.schemaBytes = schemaBytes; + this.version = version; + } + + public static Schema from(byte[] schemaBytes, SchemaVersion version) { + return new Schema(schemaBytes, version); + } + + public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.UNKNOWN);} + + public static Schema from(InputStream stream) { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); + return null; + } + + +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java new file mode 100644 index 000000000..8864006de --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -0,0 +1,92 @@ +package com.concordium.sdk.transactions; + +import com.concordium.sdk.crypto.CryptoJniNative; +import com.concordium.sdk.crypto.NativeResolver; +import com.concordium.sdk.exceptions.CryptoJniException; +import com.concordium.sdk.serializing.JsonMapper; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.val; +import org.apache.commons.codec.DecoderException; + +/** + * TODO comment. + */ +@Getter +public abstract class SchemaParameter { + + static { + NativeResolver.loadLib(); + } + + /** + * Schema of the module. TODO better comment + */ + @JsonIgnore + private final Schema schema; + @JsonIgnore + private final ReceiveName receiveName; + @JsonIgnore + private boolean initialized; // @JsonIgnore does not work for name: 'isInitialized' + @JsonIgnore + private String serializedParameter; + + protected SchemaParameter(Schema schema, ReceiveName receiveName) { + this.schema = schema; + this.receiveName = receiveName; + this.initialized = false; + this.serializedParameter = ""; + } + + /** + * TODO comment + * @throws IllegalArgumentException + * @throws + * + * + * // + */ + public void initialize() { + initialize(false); + } + + /** + * TODO comment + * @param verboseErrors + */ + @SneakyThrows + public void initialize(boolean verboseErrors) { + String json = JsonMapper.INSTANCE.writeValueAsString(this); + System.out.println(json); + String method = receiveName.getMethod(); + String contractName = receiveName.getContractName(); + byte[] schemaBytes = schema.getSchemaBytes(); + SchemaVersion version = schema.getVersion(); + SerializeParameterResult result = null; + try { + val jsonStr = CryptoJniNative.serializeParameter(json, contractName, method, schemaBytes, version.getVersion(), verboseErrors); + result = JsonMapper.INSTANCE.readValue(jsonStr, SerializeParameterResult.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + System.out.println(result); + if (!result.isSuccess()) { + throw CryptoJniException.from( + result.getErr() + ); + } + this.initialized = true; + serializedParameter = result.getSerializedParameter(); + } + + /** + * TODO comment + * @return + */ + public String toBytes() throws JsonProcessingException, DecoderException { + if (!initialized) {throw new IllegalStateException("Must initialize parameter before passing to method");} + return serializedParameter; + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java new file mode 100644 index 000000000..f44532486 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java @@ -0,0 +1,20 @@ +package com.concordium.sdk.transactions; + +import lombok.Getter; + +/** + * TODO comment. Where are the versions coming from (link?) + */ +@Getter +public enum SchemaVersion { + V0(0), + V1(1), + V2(2), + V3(3), + UNKNOWN(-1); + + private final int version; + SchemaVersion(int version) { + this.version = version; + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java new file mode 100644 index 000000000..e12427c45 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java @@ -0,0 +1,35 @@ +package com.concordium.sdk.transactions; + +import com.concordium.sdk.exceptions.JNIError; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.ToString; + +import java.util.Objects; + +@Data +@ToString(doNotUseGetters = true) +public class SerializeParameterResult { + + @JsonProperty("Ok") + private final String serializedParameter; + + @JsonProperty("Err") + private final JNIError err; + + private boolean isSuccess; + + @JsonCreator + SerializeParameterResult( + @JsonProperty("Ok") String ok, + @JsonProperty("Err") JNIError err + ) { + this.serializedParameter = ok; + this.err = err; + if (Objects.isNull(err)) { + isSuccess = true; + } + } + +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index 7de3f80a9..0f57a8f6c 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -60,6 +60,13 @@ public static UpdateContractPayload from(final long amount, Parameter.from(parameter)); } + + + public static UpdateContractPayload from(@NonNull final ContractAddress contractAddress, + SchemaParameter parameter) { + return null; + } + public static UpdateContractPayload from(@NonNull final CCDAmount amount, @NonNull final ContractAddress contractAddress, @NonNull final ReceiveName receiveName, diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java index 194ac4fa4..485a305ed 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java @@ -2,10 +2,15 @@ import com.concordium.grpc.v2.Address; import com.concordium.sdk.transactions.AccountType; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.val; +import java.io.IOException; import java.util.Map; /** @@ -13,6 +18,7 @@ * Implementations are either Account - or Contract addresses. */ @EqualsAndHashCode +@JsonSerialize (using = AbstractAddress.AbstractAddressJsonSerializer.class) public abstract class AbstractAddress { @Getter @@ -59,4 +65,27 @@ public String toString() { return this.type.toString(); } + public static class AbstractAddressJsonSerializer extends JsonSerializer { + @Override + public void serialize(AbstractAddress address, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + switch (address.getType()){ + case ADDRESS_ACCOUNT: + AccountAddress accountAddress = (AccountAddress) address; + + jsonGenerator.writeStartObject(); + + jsonGenerator.writeFieldName("Account"); + + jsonGenerator.writeStartArray(); + jsonGenerator.writeString(accountAddress.encoded()); + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndObject(); + + case ADDRESS_CONTRACT: + break; + } + } + } + } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/transactions/TransferToPublicTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/transactions/TransferToPublicTest.java index f04953afe..294039b33 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/transactions/TransferToPublicTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/transactions/TransferToPublicTest.java @@ -645,7 +645,7 @@ public void shouldThrowCreateExceptionWhenInvalidCryptographicParams() { .signer(TransactionTestHelper.getValidSigner()) .build(); } catch (CryptoJniException ex) { - Assert.assertNotNull(ex.getCode().getErrorMessage()); + Assert.assertNotNull(ex.getErrorMessage()); continue; } diff --git a/crypto-jni/Cargo.lock b/crypto-jni/Cargo.lock index 1a3889d8a..54d2f8517 100644 --- a/crypto-jni/Cargo.lock +++ b/crypto-jni/Cargo.lock @@ -46,12 +46,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "base64" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - [[package]] name = "block-buffer" version = "0.9.0" @@ -192,7 +186,7 @@ dependencies = [ "js-sys", "num-traits", "serde", - "time 0.1.45", + "time", "wasm-bindgen", "winapi", ] @@ -221,7 +215,6 @@ dependencies = [ name = "concordium-contracts-common" version = "7.0.0" dependencies = [ - "base64", "bs58", "chrono", "concordium-contracts-common-derive", @@ -243,7 +236,7 @@ version = "3.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 1.0.107", ] [[package]] @@ -277,7 +270,6 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "serde_with", "sha2 0.10.6", "sha3", "subtle", @@ -291,7 +283,7 @@ version = "1.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 1.0.107", ] [[package]] @@ -376,6 +368,7 @@ dependencies = [ "concordium_base", "curve25519-dalek", "ed25519-dalek", + "hex", "jni", "rand 0.7.3", "serde", @@ -439,41 +432,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.27", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.27", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -666,23 +624,6 @@ dependencies = [ "cxx-build", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1204,34 +1145,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap", - "serde", - "serde_json", - "serde_with_macros", - "time 0.3.23", -] - -[[package]] -name = "serde_with_macros" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.27", -] - [[package]] name = "sha2" version = "0.9.9" @@ -1272,12 +1185,6 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" version = "2.4.1" @@ -1358,33 +1265,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "time" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" -dependencies = [ - "time-core", -] - [[package]] name = "toml" version = "0.5.11" diff --git a/crypto-jni/Cargo.toml b/crypto-jni/Cargo.toml index 5402f65cb..00205854c 100644 --- a/crypto-jni/Cargo.toml +++ b/crypto-jni/Cargo.toml @@ -14,6 +14,7 @@ anyhow = "1.0" serde = "1.0" serde_json = "1.0" concordium_base = { path = "../concordium-base/rust-src/concordium_base" } +hex = "0.4" [lib] crate_type = ["cdylib"] diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index d51974eb0..c6a92deff 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -1,6 +1,6 @@ pub use concordium_base::common::types::{AccountAddress, ACCOUNT_ADDRESS_SIZE}; use concordium_base::common::Serialize; -use concordium_base::contracts_common::Amount; +use concordium_base::contracts_common::{Amount, schema::VersionedModuleSchema}; use concordium_base::encrypted_transfers; use concordium_base::encrypted_transfers::types::{ AggregatedDecryptedAmount, EncryptedAmount, EncryptedAmountTransferData, @@ -16,12 +16,13 @@ use concordium_base::transactions::{ use concordium_base::{base, common::*}; use core::slice; use ed25519_dalek::*; -use jni::sys::jstring; +use jni::sys::{jstring, jboolean, JNI_FALSE}; use rand::thread_rng; use serde_json::{from_str, to_string}; use std::convert::{From, TryFrom}; use std::i8; use std::str::Utf8Error; +use hex; use jni::{ objects::{JClass, JString}, @@ -29,6 +30,8 @@ use jni::{ JNIEnv, }; +use anyhow::{anyhow, Result}; + const SUCCESS: i32 = 0; const NATIVE_CONVERSION_ERROR: i32 = 1; const MALFORMED_SECRET_KEY: i32 = 2; @@ -179,28 +182,83 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generatePu #[derive(SerdeSerialize, SerdeDeserialize)] enum CryptoJniResult { Ok(T), - Err(jint), + Err(JNIError), +} + +#[derive(SerdeSerialize, SerdeDeserialize)] +#[allow(non_snake_case)] +enum JNIErrorType { + ParameterSerializationError, + Utf8DecodeError, + JsonDeserializationError, + NativeConversionError, + PayloadCreationError, +} + + +#[derive(SerdeSerialize, SerdeDeserialize)] +#[allow(non_snake_case)] +struct JNIError { + errorType: JNIErrorType, + errorMessage: String, + } impl From for CryptoJniResult { - fn from(_: serde_json::Error) -> Self { - CryptoJniResult::Err(1) + fn from(e: serde_json::Error) -> Self { + let error = JNIError { + errorType: JNIErrorType::JsonDeserializationError, + errorMessage: e.to_string(), + }; + CryptoJniResult::Err(error) } } impl From for CryptoJniResult { - fn from(_: Utf8Error) -> Self { - CryptoJniResult::Err(2) + fn from(e: Utf8Error) -> Self { + let error = JNIError { + errorType: JNIErrorType::Utf8DecodeError, + errorMessage: e.to_string(), + }; + CryptoJniResult::Err(error) } } impl From for CryptoJniResult { - fn from(_: jni::errors::Error) -> Self { - CryptoJniResult::Err(3) + fn from(e: jni::errors::Error) -> Self { + let error = JNIError { + errorType: JNIErrorType::NativeConversionError, + errorMessage: e.to_string(), + }; + CryptoJniResult::Err(error) + } +} + +/** + * Creates errors from strings. + * Used when payload creation fails as no error to be passed on is generated. + */ +impl From<&str> for CryptoJniResult { + fn from(e: &str) -> Self { + let error = JNIError { + errorType: JNIErrorType::PayloadCreationError, + errorMessage: e.to_string(), + }; + CryptoJniResult::Err(error) + } +} + +impl From for CryptoJniResult { + fn from(e: anyhow::Error) -> Self { + let error = JNIError { + errorType: JNIErrorType::ParameterSerializationError, + errorMessage: e.to_string(), + }; + CryptoJniResult::Err(error) } } -const PAYLOAD_CREATION_ERROR: i32 = 5; +const PAYLOAD_CREATION_ERROR: &str = "Could not create payload"; impl CryptoJniResult { fn to_jstring(&self, env: &JNIEnv) -> jstring { @@ -239,7 +297,7 @@ struct JniInput { } type EncryptedTranfersInput = JniInput; -type Result = CryptoJniResult>; +type EncryptedTransferResult = CryptoJniResult>; #[no_mangle] #[allow(non_snake_case)] @@ -255,11 +313,11 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT Ok(java_str) => match java_str.to_str() { Ok(rust_str) => match from_str(rust_str) { Ok(input) => input, - Err(err) => return Result::from(err).to_jstring(&env), + Err(err) => return EncryptedTransferResult::from(err).to_jstring(&env), }, - Err(err) => return Result::from(err).to_jstring(&env), + Err(err) => return EncryptedTransferResult::from(err).to_jstring(&env), }, - Err(err) => return Result::from(err).to_jstring(&env), + Err(err) => return EncryptedTransferResult::from(err).to_jstring(&env), }; let decrypted_amount = match decrypt_encrypted_amount( @@ -267,7 +325,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT input.sender_secret_key.clone(), ) { CryptoJniResult::Ok(amount) => amount, - CryptoJniResult::Err(err) => return Result::Err(err).to_jstring(&env), + CryptoJniResult::Err(err) => return EncryptedTransferResult::Err(err).to_jstring(&env) }; let input_amount: AggregatedDecryptedAmount = AggregatedDecryptedAmount { @@ -290,7 +348,8 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT match payload { Some(payload) => CryptoJniResult::Ok(payload).to_jstring(&env), - None => Result::Err(PAYLOAD_CREATION_ERROR).to_jstring(&env), + None => + return EncryptedTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env) } } @@ -334,7 +393,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateEn input.sender_secret_key.clone(), ) { CryptoJniResult::Ok(amount) => amount, - CryptoJniResult::Err(err) => return Result::Err(err).to_jstring(&env), + CryptoJniResult::Err(err) => return EncryptedAmountTransferResult::Err(err).to_jstring(&env), }; let input_amount: AggregatedDecryptedAmount = AggregatedDecryptedAmount { @@ -358,7 +417,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateEn match payload { Some(payload) => CryptoJniResult::Ok(payload).to_jstring(&env), - None => EncryptedAmountTransferResult::Err(PAYLOAD_CREATION_ERROR).to_jstring(&env), + None => return EncryptedAmountTransferResult::Err(JNIError { errorType: JNIErrorType::JsonDeserializationError, errorMessage: ":C".to_string() }, ).to_jstring(&env) //EncryptedAmountTransferResult::Err(JNIError::PayloadCreationError(PAYLOAD_CREATION_ERROR.to_string())).to_jstring(&env), } } @@ -408,3 +467,100 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateCo return CryptoJniResult::Ok(payload).to_jstring(&env); } + +type SerializeParamResult = CryptoJniResult; + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeParameter( + env: JNIEnv, + _: JClass, + parameter: JString, + contractName: JString, + methodName: JString, + schemaBytes: jbyteArray, + schemaVersion: jint, + verboseErrors: jboolean, +) -> jstring { + + let schema = match env.convert_byte_array(schemaBytes) { + Ok(x) => x, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + + let parameter: String = match env.get_string(parameter) { + Ok(java_str) => match java_str.to_str() { + Ok(rust_str) => String::from(rust_str), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + let contractName: String = match env.get_string(contractName) { + Ok(java_str) => match java_str.to_str() { + Ok(rust_str) => String::from(rust_str), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + let methodName: String = match env.get_string(methodName) { + Ok(java_str) => match java_str.to_str() { + Ok(rust_str) => String::from(rust_str), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + let version: Option = match schemaVersion { + 0 => Some(0), + 1 => Some(1), + 2 => Some(2), + 3 => Some(3), + _ => None, + }; + + let verboseErrors = verboseErrors != JNI_FALSE; + + let serializedParameter = serialize_receive_contract_parameters_aux( + ¶meter, + &contractName, + &methodName, + &schema, + &version, + verboseErrors + ); + + + let result = match serializedParameter { + Ok(serializedParameter) => hex::encode(serializedParameter), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + + }; + + return SerializeParamResult::Ok(result).to_jstring(&env); + + +} + + +#[allow(non_snake_case)] +pub fn serialize_receive_contract_parameters_aux( + parameter: &str, + contractName: &str, + methodName: &str, + schemaBytes: &Vec, + schemaVersion: &Option, + verboseErrors: bool, +) -> Result> { + + let module_schema = VersionedModuleSchema::new(schemaBytes, schemaVersion)?; + let parameter_type = module_schema.get_receive_param_schema(contractName, methodName)?; + let value: serde_json::Value = from_str(parameter)?; + + let res = parameter_type + .serial_value(&value) + .map_err(|e| anyhow!("{}", e.display(verboseErrors))); + return Ok(res?); +} From c308d2097a478a852dfd03b1875d3b7d89da0cab Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 9 Aug 2023 17:38:19 +0200 Subject: [PATCH 02/53] early implementation of instantiating UpdateContractPayload and InvokeInstanceRequest with SchemaReceiveParameter --- .../smartcontracts/InvokeInstanceRequest.java | 69 +++++++++++++++++-- .../sdk/transactions/Parameter.java | 7 +- ...meter.java => SchemaReceiveParameter.java} | 36 +++++----- .../transactions/UpdateContractPayload.java | 18 ++++- 4 files changed, 100 insertions(+), 30 deletions(-) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{SchemaParameter.java => SchemaReceiveParameter.java} (59%) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 021874c12..92e5b7592 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -1,15 +1,10 @@ package com.concordium.sdk.requests.smartcontracts; import com.concordium.sdk.requests.BlockQuery; -import com.concordium.sdk.transactions.CCDAmount; -import com.concordium.sdk.transactions.Parameter; -import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.*; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.ContractAddress; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; +import lombok.*; import java.util.Objects; @@ -62,6 +57,66 @@ public class InvokeInstanceRequest { */ private Energy energy; + public static InvokeInstanceRequest from(BlockQuery blockHash, + AbstractAddress invoker, + ContractAddress instance, + CCDAmount amount, + ReceiveName entrypoint, + Parameter parameter, + Energy energy) { + return InvokeInstanceRequest.builder() + .blockHash(blockHash) + .invoker(invoker) + .instance(instance) + .amount(amount) + .entrypoint(entrypoint) + .parameter(parameter) + .energy(energy).build(); + } + public static InvokeInstanceRequest from(BlockQuery blockHash, + ContractAddress instance, + CCDAmount amount, + ReceiveName entrypoint, + Parameter parameter, + Energy energy) { + return InvokeInstanceRequest.builder() + .blockHash(blockHash) + .instance(instance) + .amount(amount) + .entrypoint(entrypoint) + .parameter(parameter) + .energy(energy).build(); + } + + public static InvokeInstanceRequest from(BlockQuery blockHash, + AbstractAddress invoker, + ContractAddress instance, + CCDAmount amount, + SchemaReceiveParameter schemaReceiveParameter, + Energy energy) { + return InvokeInstanceRequest.builder() + .blockHash(blockHash) + .invoker(invoker) + .instance(instance) + .amount(amount) + .entrypoint(schemaReceiveParameter.getReceiveName()) + .parameter(Parameter.from(schemaReceiveParameter)) + .energy(energy).build(); + } + + public static InvokeInstanceRequest from(BlockQuery blockHash, + ContractAddress instance, + CCDAmount amount, + SchemaReceiveParameter schemaReceiveParameter, + Energy energy) { + return InvokeInstanceRequest.builder() + .blockHash(blockHash) + .instance(instance) + .amount(amount) + .entrypoint(schemaReceiveParameter.getReceiveName()) + .parameter(Parameter.from(schemaReceiveParameter)) + .energy(energy).build(); + } public boolean hasInvoker() { return !Objects.isNull(this.invoker); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 2841dfa2c..6c6972154 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.ToString; import lombok.val; +import org.apache.commons.codec.DecoderException; import java.nio.ByteBuffer; @@ -48,9 +49,7 @@ public byte[] getBytes() { return buffer.array(); } - public static Parameter from(SchemaParameter param) throws JsonProcessingException { - - //return from(param.toBytes()); - return null; + public static Parameter from(SchemaReceiveParameter param) { + return from(param.toBytes()); } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java similarity index 59% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java index 8864006de..19d9bb579 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java @@ -6,17 +6,20 @@ import com.concordium.sdk.serializing.JsonMapper; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.AccessLevel; import lombok.Getter; import lombok.SneakyThrows; import lombok.val; import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; /** * TODO comment. */ @Getter -public abstract class SchemaParameter { +public abstract class SchemaReceiveParameter { + //static block to load native library static { NativeResolver.loadLib(); } @@ -31,9 +34,11 @@ public abstract class SchemaParameter { @JsonIgnore private boolean initialized; // @JsonIgnore does not work for name: 'isInitialized' @JsonIgnore + @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? + // Should this be stored as a String or just converted to a byte[] at once? private String serializedParameter; - protected SchemaParameter(Schema schema, ReceiveName receiveName) { + protected SchemaReceiveParameter(Schema schema, ReceiveName receiveName) { this.schema = schema; this.receiveName = receiveName; this.initialized = false; @@ -56,37 +61,34 @@ public void initialize() { * TODO comment * @param verboseErrors */ - @SneakyThrows + public void initialize(boolean verboseErrors) { - String json = JsonMapper.INSTANCE.writeValueAsString(this); - System.out.println(json); - String method = receiveName.getMethod(); + String methodName = receiveName.getMethod(); String contractName = receiveName.getContractName(); byte[] schemaBytes = schema.getSchemaBytes(); - SchemaVersion version = schema.getVersion(); - SerializeParameterResult result = null; + SchemaVersion schemaVersion = schema.getVersion(); + SerializeParameterResult result = null; // The other classes using the jni initializes the result as null. Why ? try { - val jsonStr = CryptoJniNative.serializeParameter(json, contractName, method, schemaBytes, version.getVersion(), verboseErrors); - result = JsonMapper.INSTANCE.readValue(jsonStr, SerializeParameterResult.class); + String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); + val resultJson = CryptoJniNative.serializeParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } - System.out.println(result); if (!result.isSuccess()) { - throw CryptoJniException.from( - result.getErr() - ); + throw CryptoJniException.from(result.getErr()); } - this.initialized = true; serializedParameter = result.getSerializedParameter(); + this.initialized = true; } /** * TODO comment * @return */ - public String toBytes() throws JsonProcessingException, DecoderException { + @SneakyThrows // Is this okay? The hex should always be valid? maybe? + public byte[] toBytes() { if (!initialized) {throw new IllegalStateException("Must initialize parameter before passing to method");} - return serializedParameter; + return Hex.decodeHex(serializedParameter); } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index 0f57a8f6c..fb85f02d3 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -63,8 +63,22 @@ public static UpdateContractPayload from(final long amount, public static UpdateContractPayload from(@NonNull final ContractAddress contractAddress, - SchemaParameter parameter) { - return null; + SchemaReceiveParameter schemaReceiveParameter) { + return new UpdateContractPayload( + CCDAmount.fromMicro(0), + contractAddress, + schemaReceiveParameter.getReceiveName(), + Parameter.from(schemaReceiveParameter)); + } + + public static UpdateContractPayload from(CCDAmount amount, + @NonNull final ContractAddress contractAddress, + SchemaReceiveParameter schemaReceiveParameter) { + return new UpdateContractPayload( + amount, + contractAddress, + schemaReceiveParameter.getReceiveName(), + Parameter.from(schemaReceiveParameter)); } public static UpdateContractPayload from(@NonNull final CCDAmount amount, From 097fb726240f1b7faeae231c7f25e0aeadc6fac7 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 9 Aug 2023 18:03:26 +0200 Subject: [PATCH 03/53] Defined SchemaInitParameter class and function serializeInitParameter in CryptoJniNative and lib.rs --- .../sdk/crypto/CryptoJniNative.java | 17 +++- .../sdk/transactions/SchemaInitParameter.java | 89 +++++++++++++++++++ .../transactions/SchemaReceiveParameter.java | 3 +- crypto-jni/src/lib.rs | 2 +- 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 057482eb5..1df829c40 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -1,5 +1,7 @@ package com.concordium.sdk.crypto; +import com.concordium.sdk.transactions.SerializeParameterResult; + public class CryptoJniNative { /** @@ -79,8 +81,19 @@ public class CryptoJniNative { * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. * @param verboseErrors whether errors are in verbose format or not. - * @return JSON representing (SerializedParam, ResultCode, ErrorMessage) + * @return JSON representing {@link SerializeParameterResult} + */ + public static native String serializeReceiveParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); + + /** + * Serializes a json representation of a parameter using a schema of the module. + * @param parameterJson json representation of the parameter. + * @param contractName name of the contract. + * @param schemaBytes schema of the contract. + * @param schemaVersion version of the schema. + * @param verboseErrors whether errors are in verbose format or not. + * @return JSON representing {@link SerializeParameterResult} */ - public static native String serializeParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); + public static native String serializeInitParameter(String parameterJson, String contractName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java new file mode 100644 index 000000000..bce31f7c6 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java @@ -0,0 +1,89 @@ +package com.concordium.sdk.transactions; + +import com.concordium.sdk.crypto.CryptoJniNative; +import com.concordium.sdk.crypto.NativeResolver; +import com.concordium.sdk.exceptions.CryptoJniException; +import com.concordium.sdk.serializing.JsonMapper; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.val; +import org.apache.commons.codec.binary.Hex; + +@Getter +public abstract class SchemaInitParameter { + + //static block to load native library + static { + NativeResolver.loadLib(); + } + + /** + * Schema of the module. TODO better comment + */ + @JsonIgnore + private final Schema schema; + @JsonIgnore + private final InitName initName; + @JsonIgnore + private boolean initialized; // @JsonIgnore does not work for name: 'isInitialized' + @JsonIgnore + @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? + // Should this be stored as a String or just converted to a byte[] at once? + private String serializedParameter; + + protected SchemaInitParameter(Schema schema, InitName initName) { + this.schema = schema; + this.initName = initName; + this.initialized = false; + this.serializedParameter = ""; + } + + /** + * TODO comment + * @throws IllegalArgumentException + * @throws + * + * + * // + */ + public void initialize() { + initialize(false); + } + + /** + * TODO comment + * @param verboseErrors + */ + + public void initialize(boolean verboseErrors) { + String contractName = initName.getName(); + byte[] schemaBytes = schema.getSchemaBytes(); + SchemaVersion schemaVersion = schema.getVersion(); + SerializeParameterResult result = null; // The other classes using the jni initializes the result as null. Why ? + try { + String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); + val resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + if (!result.isSuccess()) { + throw CryptoJniException.from(result.getErr()); + } + serializedParameter = result.getSerializedParameter(); + this.initialized = true; + } + + /** + * TODO comment + * @return + */ + @SneakyThrows // Is this okay? The hex should always be valid? maybe? + public byte[] toBytes() { + if (!initialized) {throw new IllegalStateException("Must initialize parameter before passing to method");} + return Hex.decodeHex(serializedParameter); + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java index 19d9bb579..9581ae0be 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java @@ -10,7 +10,6 @@ import lombok.Getter; import lombok.SneakyThrows; import lombok.val; -import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; /** @@ -70,7 +69,7 @@ public void initialize(boolean verboseErrors) { SerializeParameterResult result = null; // The other classes using the jni initializes the result as null. Why ? try { String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - val resultJson = CryptoJniNative.serializeParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + val resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index c6a92deff..a0219f4c5 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -472,7 +472,7 @@ type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] -pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeParameter( +pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeReceiveParameter( env: JNIEnv, _: JClass, parameter: JString, From 5f6b0c737d73223b573cc9c8b64285f5d6f0586a Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Thu, 10 Aug 2023 12:37:33 +0200 Subject: [PATCH 04/53] Implemented functionality for SchemaInitParameter in lib.rs. Added option to construct Schema from an InputStream --- .../sdk/transactions/InitContractPayload.java | 4 + .../sdk/transactions/Parameter.java | 9 +- .../concordium/sdk/transactions/Schema.java | 24 ++++- crypto-jni/src/lib.rs | 89 ++++++++++++++++++- 4 files changed, 121 insertions(+), 5 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index 59cbc3580..9933a8093 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -70,6 +70,10 @@ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, In return new InitContractPayload(amount, moduleRef, initName, parameter); } + public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaInitParameter schemaInitParameter) { + return new InitContractPayload(amount, moduleRef, schemaInitParameter.getInitName(), Parameter.from(schemaInitParameter)); + } + /** * @return buffer bytes of InitContractPayload */ diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 6c6972154..c347e0c41 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -27,7 +27,6 @@ public final class Parameter { @JsonCreator Parameter(byte[] bytes) { - // TODO enforce 1kb max this.bytes = bytes; } @@ -35,6 +34,7 @@ public final class Parameter { * This function takes a byte array and returns a Parameter object. */ public static Parameter from(byte[] parameter) { + if (parameter.length > MAX_SIZE) {throw new IllegalArgumentException("Parameter must not exceed " + MAX_SIZE + " bytes, argument size was: " + parameter.length);} return new Parameter(parameter); } @@ -49,6 +49,13 @@ public byte[] getBytes() { return buffer.array(); } + /** + * TODO comment this and below + * @param param + * @return + */ + public static Parameter from(SchemaInitParameter param) {return from(param.toBytes());} + public static Parameter from(SchemaReceiveParameter param) { return from(param.toBytes()); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java index bccf06982..79a3686b1 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java @@ -25,9 +25,27 @@ public static Schema from(byte[] schemaBytes, SchemaVersion version) { public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.UNKNOWN);} - public static Schema from(InputStream stream) { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); - return null; + /** + * TODO comment + * taken from https://www.baeldung.com/convert-input-stream-to-array-of-bytes + * @param is + * @param version + * @return + * @throws IOException + */ + public static Schema from(InputStream is, SchemaVersion version) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + int nRead; + byte[] data = new byte[4]; + + while ((nRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + buffer.flush(); + byte[] targetArray = buffer.toByteArray(); + return from(targetArray, version); } diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index a0219f4c5..7bffec5e4 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -417,7 +417,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateEn match payload { Some(payload) => CryptoJniResult::Ok(payload).to_jstring(&env), - None => return EncryptedAmountTransferResult::Err(JNIError { errorType: JNIErrorType::JsonDeserializationError, errorMessage: ":C".to_string() }, ).to_jstring(&env) //EncryptedAmountTransferResult::Err(JNIError::PayloadCreationError(PAYLOAD_CREATION_ERROR.to_string())).to_jstring(&env), + None => return EncryptedAmountTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env) } } @@ -564,3 +564,90 @@ pub fn serialize_receive_contract_parameters_aux( .map_err(|e| anyhow!("{}", e.display(verboseErrors))); return Ok(res?); } + +//// Init param +/// + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeInitParameter( + env: JNIEnv, + _: JClass, + parameter: JString, + contractName: JString, + schemaBytes: jbyteArray, + schemaVersion: jint, + verboseErrors: jboolean, +) -> jstring { + + let schema = match env.convert_byte_array(schemaBytes) { + Ok(x) => x, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + + let parameter: String = match env.get_string(parameter) { + Ok(java_str) => match java_str.to_str() { + Ok(rust_str) => String::from(rust_str), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + let contractName: String = match env.get_string(contractName) { + Ok(java_str) => match java_str.to_str() { + Ok(rust_str) => String::from(rust_str), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }, + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + }; + + let version: Option = match schemaVersion { + 0 => Some(0), + 1 => Some(1), + 2 => Some(2), + 3 => Some(3), + _ => None, + }; + + let verboseErrors = verboseErrors != JNI_FALSE; + + let serializedParameter = serialize_receive_init_parameters_aux( + ¶meter, + &contractName, + &schema, + &version, + verboseErrors + ); + + + let result = match serializedParameter { + Ok(serializedParameter) => hex::encode(serializedParameter), + Err(err) => return SerializeParamResult::from(err).to_jstring(&env), + + }; + + return SerializeParamResult::Ok(result).to_jstring(&env); + + +} + + +#[allow(non_snake_case)] +pub fn serialize_receive_init_parameters_aux( + parameter: &str, + contractName: &str, + schemaBytes: &Vec, + schemaVersion: &Option, + verboseErrors: bool, +) -> Result> { + + let module_schema = VersionedModuleSchema::new(schemaBytes, schemaVersion)?; + let parameter_type = module_schema.get_init_param_schema(contractName)?; + let value: serde_json::Value = from_str(parameter)?; + + let res = parameter_type + .serial_value(&value) + .map_err(|e| anyhow!("{}", e.display(verboseErrors))); + return Ok(res?); +} \ No newline at end of file From 5cc9ff010ad47c1f1c6a9afba2c53a15903a308a Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Thu, 10 Aug 2023 12:38:00 +0200 Subject: [PATCH 05/53] Implemented functionality for SchemaInitParameter in lib.rs. Added option to construct Schema from an InputStream --- .../main/java/com/concordium/sdk/transactions/Parameter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index c347e0c41..30a5ecf70 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -2,11 +2,9 @@ import com.concordium.sdk.types.UInt16; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Getter; import lombok.ToString; import lombok.val; -import org.apache.commons.codec.DecoderException; import java.nio.ByteBuffer; From a0c503fb63ee492e7b8829780b048da9e7cb2503 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 16 Aug 2023 16:02:21 +0200 Subject: [PATCH 06/53] Refactoring SchemaInitParameter and SchemaReceiveParameter into one class (SchemaParameter). Comments. --- .../sdk/crypto/CryptoJniNative.java | 4 +- .../concordium/sdk/exceptions/JNIError.java | 3 + .../smartcontracts/InvokeInstanceRequest.java | 69 ++++++-- .../sdk/transactions/InitContractPayload.java | 11 +- .../sdk/transactions/Parameter.java | 12 +- .../sdk/transactions/ParameterType.java | 9 + .../concordium/sdk/transactions/Schema.java | 49 +++--- .../sdk/transactions/SchemaInitParameter.java | 89 ---------- .../sdk/transactions/SchemaParameter.java | 161 ++++++++++++++++++ .../transactions/SchemaReceiveParameter.java | 93 ---------- .../SerializeParameterResult.java | 3 + .../transactions/UpdateContractPayload.java | 44 +++-- crypto-jni/src/lib.rs | 24 ++- 13 files changed, 314 insertions(+), 257 deletions(-) create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java delete mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java delete mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 1df829c40..16f41aa16 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -74,7 +74,7 @@ public class CryptoJniNative { public static native String generateConfigureBakerKeysPayload(String input); /** - * Serializes a json representation of a parameter using a schema of the module. + * Serializes json representation of a parameter for a receive function using a schema of the module. * @param parameterJson json representation of the parameter. * @param contractName name of the contract. * @param methodName name of the method. @@ -86,7 +86,7 @@ public class CryptoJniNative { public static native String serializeReceiveParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); /** - * Serializes a json representation of a parameter using a schema of the module. + * Serializes json representation of a parameter for an init function using a schema of the module. * @param parameterJson json representation of the parameter. * @param contractName name of the contract. * @param schemaBytes schema of the contract. diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java index bc2d07575..3c992d3c4 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java @@ -6,6 +6,9 @@ import lombok.ToString; +/** + * TODO comment. + */ @Getter @ToString public class JNIError { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 92e5b7592..594dd8b46 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -57,6 +57,19 @@ public class InvokeInstanceRequest { */ private Energy energy; + /** + * Creates a {@link InvokeInstanceRequest} from the given parameters. + * + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param invoker Invoker of the contract, must exist in the blockstate. + * If this is not supplied then the contract will be invoked by an account with address 0, + * no credentials and sufficient amount of CCD to cover the transfer amount. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. + * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. + * @param parameter The parameter bytes to include in the invocation of the entrypoint. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + */ public static InvokeInstanceRequest from(BlockQuery blockHash, AbstractAddress invoker, ContractAddress instance, @@ -73,6 +86,17 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, .parameter(parameter) .energy(energy).build(); } + /** + * Creates a {@link InvokeInstanceRequest} from the given parameters. + * The contract will be invoked by an account with address 0, no credentials and sufficient CCD to cover the transfer amount. + * + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. + * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. + * @param parameter The parameter bytes to include in the invocation of the entrypoint. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, CCDAmount amount, @@ -88,34 +112,45 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, .energy(energy).build(); } + /** + * Creates a {@link InvokeInstanceRequest} from the given parameters. + * + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param invoker Invoker of the contract, must exist in the blockstate. + * If this is not supplied then the contract will be invoked by an account with address 0, + * no credentials and sufficient amount of CCD to cover the transfer amount. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + */ public static InvokeInstanceRequest from(BlockQuery blockHash, AbstractAddress invoker, ContractAddress instance, CCDAmount amount, - SchemaReceiveParameter schemaReceiveParameter, + SchemaParameter schemaParameter, Energy energy) { - return InvokeInstanceRequest.builder() - .blockHash(blockHash) - .invoker(invoker) - .instance(instance) - .amount(amount) - .entrypoint(schemaReceiveParameter.getReceiveName()) - .parameter(Parameter.from(schemaReceiveParameter)) - .energy(energy).build(); + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + return from(blockHash, invoker, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } + /** + * Creates a {@link InvokeInstanceRequest} from the given parameters. + * The contract will be invoked by an account with address 0, no credentials and sufficient CCD to cover the transfer amount. + * + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, CCDAmount amount, - SchemaReceiveParameter schemaReceiveParameter, + SchemaParameter schemaParameter, Energy energy) { - return InvokeInstanceRequest.builder() - .blockHash(blockHash) - .instance(instance) - .amount(amount) - .entrypoint(schemaReceiveParameter.getReceiveName()) - .parameter(Parameter.from(schemaReceiveParameter)) - .energy(energy).build(); + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + return from(blockHash, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } public boolean hasInvoker() { return !Objects.isNull(this.invoker); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index 9933a8093..ef63815f9 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -70,8 +70,15 @@ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, In return new InitContractPayload(amount, moduleRef, initName, parameter); } - public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaInitParameter schemaInitParameter) { - return new InitContractPayload(amount, moduleRef, schemaInitParameter.getInitName(), Parameter.from(schemaInitParameter)); + /** + * Create a new instance of {@link InitContractPayload} from the given parameters. + * @param amount CCD amount to deposit. + * @param moduleRef HAsh of the smart contract module reference. + * @param schemaParameter {@link SchemaParameter} message to invoke the initialization method with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + */ + public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaParameter schemaParameter) { + if (! (schemaParameter.getType() == ParameterType.INIT)) {throw new IllegalArgumentException("SchemaParameter must be initialized with an InitName");} + return new InitContractPayload(amount, moduleRef, schemaParameter.getInitName(), Parameter.from(schemaParameter)); } /** diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 30a5ecf70..a13a9cc6f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -48,13 +48,9 @@ public byte[] getBytes() { } /** - * TODO comment this and below - * @param param - * @return + * Constructs a {@link Parameter} from the provided {@link SchemaParameter}. + * @param param {@link SchemaParameter} to convert. + * @return converted {@link Parameter}. */ - public static Parameter from(SchemaInitParameter param) {return from(param.toBytes());} - - public static Parameter from(SchemaReceiveParameter param) { - return from(param.toBytes()); - } + public static Parameter from(SchemaParameter param) {return from(param.toBytes());} } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java new file mode 100644 index 000000000..65d861314 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java @@ -0,0 +1,9 @@ +package com.concordium.sdk.transactions; + +/** + * TODO comment + */ +public enum ParameterType { + INIT, + RECEIVE +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java index 79a3686b1..128ea5daa 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java @@ -2,51 +2,46 @@ import lombok.Getter; -import java.io.*; - /** - * TODO comment + * The schema for a smart contract. Used when creating {@link SchemaParameter}. */ @Getter public class Schema { + /** + * The bytes of the schema. + */ private final byte[] schemaBytes; + /** + * The version of the schema. + */ private final SchemaVersion version; + /** + * Creates a {@link Schema} from the provided bytes and {@link SchemaVersion}. + * @param schemaBytes the bytes of the schema. + * @param version the version of the schema. + */ Schema(byte[] schemaBytes, SchemaVersion version) { this.schemaBytes = schemaBytes; this.version = version; } + /** + * Creates a {@link Schema} from the provided bytes and {@link SchemaVersion}. + * @param schemaBytes the bytes of the schema. + * @param version the version of the schema. + * @return {@link Schema} containing the provided bytes. + */ public static Schema from(byte[] schemaBytes, SchemaVersion version) { return new Schema(schemaBytes, version); } - public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.UNKNOWN);} - /** - * TODO comment - * taken from https://www.baeldung.com/convert-input-stream-to-array-of-bytes - * @param is - * @param version - * @return - * @throws IOException + * Creates a schema from the provided bytes. + * @param schemaBytes the bytes of the schema. + * @return {@link Schema} containing the provided bytes. */ - public static Schema from(InputStream is, SchemaVersion version) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - int nRead; - byte[] data = new byte[4]; - - while ((nRead = is.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); - } - - buffer.flush(); - byte[] targetArray = buffer.toByteArray(); - return from(targetArray, version); - } - - + public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.UNKNOWN);} } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java deleted file mode 100644 index bce31f7c6..000000000 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaInitParameter.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.concordium.sdk.transactions; - -import com.concordium.sdk.crypto.CryptoJniNative; -import com.concordium.sdk.crypto.NativeResolver; -import com.concordium.sdk.exceptions.CryptoJniException; -import com.concordium.sdk.serializing.JsonMapper; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.SneakyThrows; -import lombok.val; -import org.apache.commons.codec.binary.Hex; - -@Getter -public abstract class SchemaInitParameter { - - //static block to load native library - static { - NativeResolver.loadLib(); - } - - /** - * Schema of the module. TODO better comment - */ - @JsonIgnore - private final Schema schema; - @JsonIgnore - private final InitName initName; - @JsonIgnore - private boolean initialized; // @JsonIgnore does not work for name: 'isInitialized' - @JsonIgnore - @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? - // Should this be stored as a String or just converted to a byte[] at once? - private String serializedParameter; - - protected SchemaInitParameter(Schema schema, InitName initName) { - this.schema = schema; - this.initName = initName; - this.initialized = false; - this.serializedParameter = ""; - } - - /** - * TODO comment - * @throws IllegalArgumentException - * @throws - * - * - * // - */ - public void initialize() { - initialize(false); - } - - /** - * TODO comment - * @param verboseErrors - */ - - public void initialize(boolean verboseErrors) { - String contractName = initName.getName(); - byte[] schemaBytes = schema.getSchemaBytes(); - SchemaVersion schemaVersion = schema.getVersion(); - SerializeParameterResult result = null; // The other classes using the jni initializes the result as null. Why ? - try { - String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - val resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); - result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - if (!result.isSuccess()) { - throw CryptoJniException.from(result.getErr()); - } - serializedParameter = result.getSerializedParameter(); - this.initialized = true; - } - - /** - * TODO comment - * @return - */ - @SneakyThrows // Is this okay? The hex should always be valid? maybe? - public byte[] toBytes() { - if (!initialized) {throw new IllegalStateException("Must initialize parameter before passing to method");} - return Hex.decodeHex(serializedParameter); - } -} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java new file mode 100644 index 000000000..6c7201f2b --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -0,0 +1,161 @@ +package com.concordium.sdk.transactions; + +import com.concordium.sdk.crypto.CryptoJniNative; +import com.concordium.sdk.crypto.NativeResolver; +import com.concordium.sdk.exceptions.CryptoJniException; +import com.concordium.sdk.exceptions.JNIError; +import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; +import com.concordium.sdk.serializing.JsonMapper; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.SneakyThrows; +import org.apache.commons.codec.binary.Hex; + +/** + * Wrapper for parameters serializable via a {@link Schema} to be used with smart contracts. + * Must be initialized by calling {@link SchemaParameter#initialize()} before usage. + * Implementing subclasses must be JSON serializable in accordance with the provided smart contract schema. + * If default serialization does not work, a custom serializer should be implemented and used with annotation @JsonSerialize (using = .class). + * See TODO link example. for example. + */ +@Getter +public abstract class SchemaParameter { + + //static block to load native library + static { + NativeResolver.loadLib(); + } + + /** + * {@link Schema} of the module. + */ + @JsonIgnore + private final Schema schema; + /** + * {@link InitName} containing the name of the contract to be initialized with the parameter. + * Populated iff type is {@link ParameterType#INIT} + */ + @JsonIgnore + private final InitName initName; + /** + * {@link ReceiveName} containing the name of the contract and method to be updated/invoked with the parameter. + * Populated iff type is {@link ParameterType#RECEIVE}. + */ + @JsonIgnore + private final ReceiveName receiveName; + /** + * Whether the parameter has been initialized. Parameter should always be initialized with {@link SchemaParameter#initialize()} before being used to create initialize/update/invoke requests. + */ + @JsonIgnore + private boolean initialized; + /** + * Type of the parameter. + * {@link ParameterType#INIT} to be used with {@link InitContractPayload}. + * {@link ParameterType#RECEIVE} to be used with {@link UpdateContractPayload} and {@link InvokeInstanceRequest}. + */ + @JsonIgnore + private final ParameterType type; + /** + * The serialized parameter, is a hex encoded byte array. Only populated after {@link SchemaParameter#initialize()} has been called. + */ + @JsonIgnore + @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? + // Should this be stored as a String or just converted to a byte[] at once? + private String serializedParameter; + + /** + * Creates a {@link SchemaParameter} of type {@link ParameterType#INIT} for use with {@link InitContractPayload}. + * Parameter must be initialized with {@link SchemaParameter#initialize()} before use. + * @param schema {@link Schema} of the module. + * @param initName The name of the contract to be initialized with the parameter. + */ + protected SchemaParameter(Schema schema, InitName initName) { + this.schema = schema; + this.receiveName = null; + this.initName = initName; + this.type = ParameterType.INIT; + this.initialized = false; + this.serializedParameter = ""; + } + + /** + * Creates a {@link SchemaParameter} of type {@link ParameterType#RECEIVE} for use with {@link UpdateContractPayload} and {@link InvokeInstanceRequest}. + * Parameter must be initialized with {@link SchemaParameter#initialize()} before use. + * @param schema {@link Schema} of the module. + * @param receiveName {@link ReceiveName} containing the name of the contract and method to be updated/invoked with the parameter. + */ + protected SchemaParameter(Schema schema, ReceiveName receiveName) { + this.schema = schema; + this.receiveName = receiveName; + this.initName = null; + this.type = ParameterType.RECEIVE; + this.initialized = false; + this.serializedParameter = ""; + } + + + /** + * Initializes the parameter by ensuring serialization is performed correctly. This is required before parameter is used. + * Use {@link SchemaParameter#initialize(boolean)} with parameter 'true' for more descriptive errors. + * @throws CryptoJniException if the serialization could not be performed. + */ + public void initialize() { + initialize(false); + } + + /** + * Initializes the parameter by ensuring serialization is performed correctly. This is required before parameter is used. + * @param verboseErrors whether to return errors in a verbose format or not. Defaults to false if omitted. + * @throws CryptoJniException if the serialization could not be performed. + */ + public void initialize(boolean verboseErrors) { + byte[] schemaBytes = schema.getSchemaBytes(); + SchemaVersion schemaVersion = schema.getVersion(); + SerializeParameterResult result = getSerializeParameterResult(verboseErrors, schemaBytes, schemaVersion); + if (!result.isSuccess()) { + throw CryptoJniException.from(result.getErr()); + } + serializedParameter = result.getSerializedParameter(); + this.initialized = true; + } + + /** + * Helper method for {@link SchemaParameter#initialize()}. Performs the JNI call and parses result to {@link SerializeParameterResult}. + * @param verboseErrors whether to return verbose errors. + * @param schemaBytes byte[] containing the schema. + * @param schemaVersion version of the schema. + * @return {@link SerializeParameterResult} containing the serialized parameter if successful or a {@link JNIError} if not. + */ + private SerializeParameterResult getSerializeParameterResult(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion) { + SerializeParameterResult result; + try { + String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); + String resultJson; + if (this.type == ParameterType.INIT) { + String contractName = initName.getName(); + resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + } else { + String contractName = receiveName.getContractName(); + String methodName = receiveName.getMethod(); + resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + } + result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + return result; + } + + /** + * Converts the serialized parameter to a byte[]. Should only be called after parameter is initialized with {@link SchemaParameter#initialize()}. + * @throws IllegalStateException if parameter is not initialized. + * @return byte[] containing the serialized parameter. + */ + @SneakyThrows // Is this okay? The hex should always be valid? maybe? + public byte[] toBytes() { + if (!initialized) {throw new IllegalStateException("Must initialize parameter before use");} + return Hex.decodeHex(serializedParameter); + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java deleted file mode 100644 index 9581ae0be..000000000 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaReceiveParameter.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.concordium.sdk.transactions; - -import com.concordium.sdk.crypto.CryptoJniNative; -import com.concordium.sdk.crypto.NativeResolver; -import com.concordium.sdk.exceptions.CryptoJniException; -import com.concordium.sdk.serializing.JsonMapper; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.SneakyThrows; -import lombok.val; -import org.apache.commons.codec.binary.Hex; - -/** - * TODO comment. - */ -@Getter -public abstract class SchemaReceiveParameter { - - //static block to load native library - static { - NativeResolver.loadLib(); - } - - /** - * Schema of the module. TODO better comment - */ - @JsonIgnore - private final Schema schema; - @JsonIgnore - private final ReceiveName receiveName; - @JsonIgnore - private boolean initialized; // @JsonIgnore does not work for name: 'isInitialized' - @JsonIgnore - @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? - // Should this be stored as a String or just converted to a byte[] at once? - private String serializedParameter; - - protected SchemaReceiveParameter(Schema schema, ReceiveName receiveName) { - this.schema = schema; - this.receiveName = receiveName; - this.initialized = false; - this.serializedParameter = ""; - } - - /** - * TODO comment - * @throws IllegalArgumentException - * @throws - * - * - * // - */ - public void initialize() { - initialize(false); - } - - /** - * TODO comment - * @param verboseErrors - */ - - public void initialize(boolean verboseErrors) { - String methodName = receiveName.getMethod(); - String contractName = receiveName.getContractName(); - byte[] schemaBytes = schema.getSchemaBytes(); - SchemaVersion schemaVersion = schema.getVersion(); - SerializeParameterResult result = null; // The other classes using the jni initializes the result as null. Why ? - try { - String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - val resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); - result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - if (!result.isSuccess()) { - throw CryptoJniException.from(result.getErr()); - } - serializedParameter = result.getSerializedParameter(); - this.initialized = true; - } - - /** - * TODO comment - * @return - */ - @SneakyThrows // Is this okay? The hex should always be valid? maybe? - public byte[] toBytes() { - if (!initialized) {throw new IllegalStateException("Must initialize parameter before passing to method");} - return Hex.decodeHex(serializedParameter); - } -} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java index e12427c45..828869ad4 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java @@ -8,6 +8,9 @@ import java.util.Objects; +/** + * TODO comment + */ @Data @ToString(doNotUseGetters = true) public class SerializeParameterResult { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index fb85f02d3..4e49bfed5 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -40,7 +40,7 @@ private UpdateContractPayload(@NonNull final CCDAmount amount, } /** - * > This function creates a payload for updating a contract + * Creates a {@link UpdateContractPayload} with amount = 0 from the given parameters. * * @param amount The amount of CCD to be sent to the contract. * @param contractAddress Address of the contract instance to invoke. @@ -61,26 +61,44 @@ public static UpdateContractPayload from(final long amount, } - + /** + * Creates a {@link UpdateContractPayload} with amount = 0 from the given parameters. + * + * @param contractAddress Address of the contract instance to invoke. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + */ public static UpdateContractPayload from(@NonNull final ContractAddress contractAddress, - SchemaReceiveParameter schemaReceiveParameter) { - return new UpdateContractPayload( - CCDAmount.fromMicro(0), + SchemaParameter schemaParameter) { + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + return from(CCDAmount.fromMicro(0), contractAddress, - schemaReceiveParameter.getReceiveName(), - Parameter.from(schemaReceiveParameter)); + schemaParameter.getReceiveName(), + Parameter.from(schemaParameter)); } + /** + * Creates a {@link UpdateContractPayload} from the given parameters. + * + * @param amount The amount of CCD to be sent to the contract. + * @param contractAddress Address of the contract instance to invoke. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + */ public static UpdateContractPayload from(CCDAmount amount, @NonNull final ContractAddress contractAddress, - SchemaReceiveParameter schemaReceiveParameter) { - return new UpdateContractPayload( - amount, - contractAddress, - schemaReceiveParameter.getReceiveName(), - Parameter.from(schemaReceiveParameter)); + SchemaParameter schemaParameter) { + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + return from(amount, contractAddress, schemaParameter.getReceiveName(), Parameter.from(schemaParameter)); } + /** + * Creates a {@link UpdateContractPayload} with amount = 0 from the given parameters. + * + * @param amount The amount of CCD to be sent to the contract. + * @param contractAddress Address of the contract instance to invoke. + * @param receiveName The {@link ReceiveName} of the smart contract instance to invoke. + * @param param The parameter of the contract method. + * @return A new UpdateContractPayload object. + */ public static UpdateContractPayload from(@NonNull final CCDAmount amount, @NonNull final ContractAddress contractAddress, @NonNull final ReceiveName receiveName, diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 7bffec5e4..4094fa563 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -472,6 +472,10 @@ type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] +/** + * The JNI wrapper for serializing receive parameters. + * Constructs a SerializeParamResult containg the hex encoded serialized parameter. + */ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeReceiveParameter( env: JNIEnv, _: JClass, @@ -546,6 +550,10 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeR #[allow(non_snake_case)] +/** + * Helper method for serialize_receive_parameters. + * Performs the actual serialization. + */ pub fn serialize_receive_contract_parameters_aux( parameter: &str, contractName: &str, @@ -565,9 +573,10 @@ pub fn serialize_receive_contract_parameters_aux( return Ok(res?); } -//// Init param -/// - +/** + * The JNI wrapper for serializing init parameters. + * Constructs a SerializeParamResult containg the hex encoded serialized parameter. + */ #[no_mangle] #[allow(non_snake_case)] pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeInitParameter( @@ -612,7 +621,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI let verboseErrors = verboseErrors != JNI_FALSE; - let serializedParameter = serialize_receive_init_parameters_aux( + let serializedParameter = serialize_init_parameters_aux( ¶meter, &contractName, &schema, @@ -632,9 +641,12 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI } - +/** + * Helper method for serialize_init_parameters. + * Performs the actual serialization. + */ #[allow(non_snake_case)] -pub fn serialize_receive_init_parameters_aux( +pub fn serialize_init_parameters_aux( parameter: &str, contractName: &str, schemaBytes: &Vec, From 1e25499a5b5cdf03da12a5ab63fa90249668d9d6 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 16 Aug 2023 17:09:29 +0200 Subject: [PATCH 07/53] Remaining comments --- .../sdk/crypto/CryptoJniNative.java | 4 +-- .../sdk/crypto/CryptoJniResultCode.java | 27 ------------------- .../crypto/bakertransactions/BakerKeys.java | 2 +- .../bakertransactions/BakerKeysResult.java | 17 +++++------- .../bakertransactions/ConfigureBakerKeys.java | 2 +- .../ConfigureBakerKeysJniInput.java | 2 +- .../ConfigureBakerKeysResult.java | 17 +++++------- .../EncryptedAmountTransferJniResult.java | 14 +++++++--- .../EncryptedTransfers.java | 4 +-- .../TransferToPublicJniResult.java | 17 +++++------- .../sdk/exceptions/CryptoJniException.java | 9 ++++--- .../concordium/sdk/exceptions/JNIError.java | 2 +- .../sdk/transactions/Parameter.java | 1 + .../sdk/transactions/ParameterType.java | 10 ++++++- .../sdk/transactions/SchemaParameter.java | 13 +++++---- .../SerializeParameterResult.java | 13 ++++++++- 16 files changed, 76 insertions(+), 78 deletions(-) delete mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniResultCode.java diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 16f41aa16..efd21a464 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -80,7 +80,7 @@ public class CryptoJniNative { * @param methodName name of the method. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. - * @param verboseErrors whether errors are in verbose format or not. + * @param verboseErrors whether errors are returned in verbose format or not. * @return JSON representing {@link SerializeParameterResult} */ public static native String serializeReceiveParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); @@ -91,7 +91,7 @@ public class CryptoJniNative { * @param contractName name of the contract. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. - * @param verboseErrors whether errors are in verbose format or not. + * @param verboseErrors whether errors are returned in verbose format or not. * @return JSON representing {@link SerializeParameterResult} */ public static native String serializeInitParameter(String parameterJson, String contractName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniResultCode.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniResultCode.java deleted file mode 100644 index 82cf0d8a6..000000000 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniResultCode.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.concordium.sdk.crypto; - -import lombok.Getter; - -public enum CryptoJniResultCode { - SUCCESS(0), - JSON_DESERIALIZATION_ERROR(1, "Json Deserialization error."), - UTF8_ERROR(2, "Incorrect Input String."), - NATIVE_CONVERSION_ERROR(3, "Native Conversion Error."), - AMOUNT_DECRYPTION_ERROR(4, "Input Encrypted Amount could not be Decrypted."), - PAYLOAD_CREATION_ERROR(5, "JNI Output Payload could not be created"), - ERROR_UNKNOWN_RESULT_CODE(6, "Unknown EncryptedTransfersResultCode"); - - private final int code; - @Getter - private final String errorMessage; - - CryptoJniResultCode(int code) { - this.code = code; - this.errorMessage = ""; - } - - CryptoJniResultCode(int code, String err) { - this.code = code; - this.errorMessage = err; - } -} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java index 928bbf177..1ff411321 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java @@ -24,7 +24,7 @@ public static BakerKeysJniOutput createBakerKeys() { } catch (JsonProcessingException e) { throw new RuntimeException(e); } - if (!result.isok()) { + if (!result.isSuccess()) { throw CryptoJniException.from( result.getErr()); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java index 29b16a886..5d40c0ef7 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java @@ -15,17 +15,22 @@ @ToString(doNotUseGetters = true) public class BakerKeysResult { /** - * An optional `BakerKeysJniOutput` object, containing the output of the generate baker keys function. + * A {@link BakerKeysJniOutput} object, containing the output of the generate baker keys function if it succeeded. + * Populated iff {@link BakerKeysResult#isSuccess} is true. */ @JsonProperty("Ok") private final BakerKeysJniOutput ok; /** - * An optional `CryptoJniResultCode` object, containing an error code if the generate baker keys function failed. + * A {@link JNIError} object, containing an error message if the generate baker keys function failed. + * Populated iff {@link BakerKeysResult#isSuccess} is false. */ @JsonProperty("Err") private final JNIError err; + /** + * Whether the function succeeded or not. + */ private boolean isSuccess; @JsonCreator @@ -40,12 +45,4 @@ public class BakerKeysResult { } } - /** - * Returns a boolean indicating whether the `ok` field is present (i.e. whether the baker key was successfully generated). - * - * @return a boolean indicating whether the `ok` field is present. - */ - public boolean isok() { - return this.isSuccess; - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java index 3900af5d5..d11774532 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeys.java @@ -26,7 +26,7 @@ public static ConfigureBakerKeysJniOutput generateConfigureBakerKeysPayload(Conf throw new RuntimeException(e); } - if (!result.isok()) { + if (!result.isSuccess()) { throw CryptoJniException.from( result.getErr()); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java index d79753703..77cc04edb 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java @@ -28,7 +28,7 @@ public ConfigureBakerKeysJniInput(AccountAddress sender, BakerKeysJniOutput keys } /** - * Document why I am here... + * Wrapper for {@link AccountAddress} to ensure correct serialization. */ private static class ConfigureBakerAccountAddress { private final AccountAddress address; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java index 2fee33ca6..033180be2 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysResult.java @@ -12,17 +12,22 @@ @ToString(doNotUseGetters = true) public class ConfigureBakerKeysResult { /** - * An optional `ConfigureBakerKeysJniOutput` object, containing the output of the configure baker keys function. + * A {@link ConfigureBakerKeysResult} object, containing the output of the configure baker keys function if it succeeded. + * Populated iff {@link ConfigureBakerKeysResult#isSuccess} is true. */ @JsonProperty("Ok") private final ConfigureBakerKeysJniOutput ok; /** - * An optional `CryptoJniResultCode` object, containing an error code if the configure baker keys function failed. + * A {@link JNIError} object, containing an error message if the configure baker keys function failed. + * Populated iff {@link ConfigureBakerKeysResult#isSuccess} is false. */ @JsonProperty("Err") private final JNIError err; + /** + * Whether the function succeeded or not. + */ private boolean isSuccess; @JsonCreator @@ -37,12 +42,4 @@ public class ConfigureBakerKeysResult { } } - /** - * Returns a boolean indicating whether the `ok` field is present (i.e. whether the configure baker keys payload was successfully generated). - * - * @return a boolean indicating whether the `ok` field is present. - */ - public boolean isok() { - return isSuccess; - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java index 24f13f41c..4a8f177c8 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedAmountTransferJniResult.java @@ -9,12 +9,23 @@ @Data public class EncryptedAmountTransferJniResult { + /** + * A {@link EncryptedAmountTransferJniResult} object, containing the output of the transfer encrypted amount function if it succeeded. + * Populated iff {@link EncryptedAmountTransferJniResult#isSuccess} is true. + */ @JsonProperty("Ok") private final EncryptedAmountTransferJniOutput ok; + /** + * A {@link JNIError} object, containing an error message if the transfer encrypted amount function failed. + * Populated iff {@link EncryptedAmountTransferJniResult#isSuccess} is false. + */ @JsonProperty("Err") private final JNIError err; + /** + * Whether the function succeeded or not. + */ private boolean isSuccess; @JsonCreator @@ -29,7 +40,4 @@ public class EncryptedAmountTransferJniResult { } } - public boolean isok() { - return isSuccess; - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java index bae767e73..3ea710145 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/EncryptedTransfers.java @@ -52,7 +52,7 @@ static TransferToPublicJniOutput createSecToPubTransferPayload(TransferToPublicJ throw new RuntimeException(e); } - if (!result.isok()) { + if (!result.isSuccess()) { throw CryptoJniException.from( result.getErr()); } @@ -87,7 +87,7 @@ static EncryptedAmountTransferJniOutput createEncryptedTransferPayload(Encrypted throw new RuntimeException(e); } - if (!result.isok()) { + if (!result.isSuccess()) { throw CryptoJniException.from( result.getErr()); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java index 64ecc8036..da65753ee 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/encryptedtransfers/TransferToPublicJniResult.java @@ -10,17 +10,22 @@ @Data public class TransferToPublicJniResult { /** - * An optional `TransferToPublicJniOutput` object, containing the output of the encrypted transfer function. + * A {@link TransferToPublicJniOutput} object, containing the output of the transfer to public function if it succeeded. + * Populated iff {@link TransferToPublicJniResult#isSuccess} is true. */ @JsonProperty("Ok") private final TransferToPublicJniOutput ok; /** - * An optional `CryptoJniResultCode` object, containing an error code if the encrypted transfer function failed. + * A {@link JNIError} object, containing an error message if the generate baker keys function failed. + * Populated iff {@link TransferToPublicJniResult#isSuccess} is false. */ @JsonProperty("Err") //CryptoJniResultCode private final JNIError err; + /** + * Whether the function succeeded or not. + */ private boolean isSuccess; @JsonCreator @@ -35,12 +40,4 @@ public class TransferToPublicJniResult { } } - /** - * Returns a boolean indicating whether the `ok` field is present (i.e. whether the encrypted transfer was successful). - * - * @return a boolean indicating whether the `ok` field is present. - */ - public boolean isok() { - return this.isSuccess; - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java index d4bd7fb84..755bbf578 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java @@ -3,15 +3,18 @@ import lombok.Getter; /** - * Represents an exception that is thrown when a cryptographic operation performed using the JNI (Java Native Interface) - * fails. It has a field, `code`, that contains the result code of the failed operation. + * Represents an exception that is thrown when an operation performed using the JNI (Java Native Interface) + * fails. */ public final class CryptoJniException extends RuntimeException { /** - * The result code of the failed cryptographic operation. + * The type of the failed operation. */ @Getter private final JNIErrorType errorType; + /** + * The error message returned from the JNI. + */ @Getter private final String errorMessage; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java index 3c992d3c4..d2a52381b 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java @@ -7,7 +7,7 @@ /** - * TODO comment. + * Represents error values returned from the JNI. Used to instantiate {@link CryptoJniException}. */ @Getter @ToString diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index a13a9cc6f..3996a48ec 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -49,6 +49,7 @@ public byte[] getBytes() { /** * Constructs a {@link Parameter} from the provided {@link SchemaParameter}. + * Provided {@link SchemaParameter} must be initialized using {@link SchemaParameter#initialize()} beforehand. * @param param {@link SchemaParameter} to convert. * @return converted {@link Parameter}. */ diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java index 65d861314..8e847f9f1 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java @@ -1,9 +1,17 @@ package com.concordium.sdk.transactions; +import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; + /** - * TODO comment + * The possible variants of {@link SchemaParameter}. */ public enum ParameterType { + /** + * The parameter is to be used with {@link InitContractPayload}. + */ INIT, + /** + * The parameter is to be used with {@link UpdateContractPayload} or {@link InvokeInstanceRequest}. + */ RECEIVE } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java index 6c7201f2b..af01aac7c 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -14,11 +14,14 @@ import org.apache.commons.codec.binary.Hex; /** - * Wrapper for parameters serializable via a {@link Schema} to be used with smart contracts. - * Must be initialized by calling {@link SchemaParameter#initialize()} before usage. - * Implementing subclasses must be JSON serializable in accordance with the provided smart contract schema. - * If default serialization does not work, a custom serializer should be implemented and used with annotation @JsonSerialize (using = .class). + * Represents smart contract parameters serializable via a {@link Schema}. + *

+ * Classes representing smart contract parameters should extend this and ensure they are JSON serializable in accordance with the provided smart contract schema. + * If default serialization does not work, a custom serializer should be implemented and used with annotation '@JsonSerialize(using = MyCustomSerializer.class)'. + *

* See TODO link example. for example. + *

+ * Must be initialized by calling {@link SchemaParameter#initialize()} before usage. */ @Getter public abstract class SchemaParameter { @@ -153,7 +156,7 @@ private SerializeParameterResult getSerializeParameterResult(boolean verboseErro * @throws IllegalStateException if parameter is not initialized. * @return byte[] containing the serialized parameter. */ - @SneakyThrows // Is this okay? The hex should always be valid? maybe? + @SneakyThrows public byte[] toBytes() { if (!initialized) {throw new IllegalStateException("Must initialize parameter before use");} return Hex.decodeHex(serializedParameter); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java index 828869ad4..608ad484b 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java @@ -9,18 +9,29 @@ import java.util.Objects; /** - * TODO comment + * Class that holds the result of serializing a parameter using the JNI. */ @Data @ToString(doNotUseGetters = true) public class SerializeParameterResult { + /** + * The serialized parameter as hex encoded bytes if the serialize parameter function succeeded. + * Populated iff {@link SerializeParameterResult#isSuccess} is true. + */ @JsonProperty("Ok") private final String serializedParameter; + /** + * A {@link JNIError} object, containing an error message if the serialize parameter function failed. + * Populated iff {@link SerializeParameterResult#isSuccess} is false. + */ @JsonProperty("Err") private final JNIError err; + /** + * Whether the function succeeded or not. + */ private boolean isSuccess; @JsonCreator From fc29d0552e0351f9681524bb57f4006c6c45409a Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Thu, 17 Aug 2023 13:38:23 +0200 Subject: [PATCH 08/53] Finalized serialization of AbstractAddress. --- .../sdk/transactions/Parameter.java | 4 +- .../sdk/transactions/SchemaParameter.java | 82 +++++++++++-------- .../concordium/sdk/types/AbstractAddress.java | 12 +++ 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 3996a48ec..a527f253e 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -13,13 +13,13 @@ * The parameters are used for updating the smart contract instance. * i.e. calling a "receive" function exposed in the smart contract with the parameters. * Buffer of the parameters message. - * In the current supported protocols the size is limited to be 1kb. + * In the current supported protocols the size is limited to be 64kb. */ @Getter @ToString public final class Parameter { - public static final int MAX_SIZE = 1024; + public static final int MAX_SIZE = 65535; public static final Parameter EMPTY = Parameter.from(new byte[0]); private final byte[] bytes; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java index af01aac7c..605881411 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -7,7 +7,6 @@ import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; import com.concordium.sdk.serializing.JsonMapper; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.core.JsonProcessingException; import lombok.AccessLevel; import lombok.Getter; import lombok.SneakyThrows; @@ -19,7 +18,7 @@ * Classes representing smart contract parameters should extend this and ensure they are JSON serializable in accordance with the provided smart contract schema. * If default serialization does not work, a custom serializer should be implemented and used with annotation '@JsonSerialize(using = MyCustomSerializer.class)'. *

- * See TODO link example. for example. + * See {@link com.concordium.sdk.types.AbstractAddress} for example. *

* Must be initialized by calling {@link SchemaParameter#initialize()} before usage. */ @@ -64,14 +63,14 @@ public abstract class SchemaParameter { * The serialized parameter, is a hex encoded byte array. Only populated after {@link SchemaParameter#initialize()} has been called. */ @JsonIgnore - @Getter(AccessLevel.NONE) // Does this need to be available? getBytes() should always be used for this as it checks for initialization? - // Should this be stored as a String or just converted to a byte[] at once? - private String serializedParameter; + @Getter(AccessLevel.NONE) + private byte[] serializedParameter; /** * Creates a {@link SchemaParameter} of type {@link ParameterType#INIT} for use with {@link InitContractPayload}. * Parameter must be initialized with {@link SchemaParameter#initialize()} before use. - * @param schema {@link Schema} of the module. + * + * @param schema {@link Schema} of the module. * @param initName The name of the contract to be initialized with the parameter. */ protected SchemaParameter(Schema schema, InitName initName) { @@ -80,13 +79,13 @@ protected SchemaParameter(Schema schema, InitName initName) { this.initName = initName; this.type = ParameterType.INIT; this.initialized = false; - this.serializedParameter = ""; } /** * Creates a {@link SchemaParameter} of type {@link ParameterType#RECEIVE} for use with {@link UpdateContractPayload} and {@link InvokeInstanceRequest}. * Parameter must be initialized with {@link SchemaParameter#initialize()} before use. - * @param schema {@link Schema} of the module. + * + * @param schema {@link Schema} of the module. * @param receiveName {@link ReceiveName} containing the name of the contract and method to be updated/invoked with the parameter. */ protected SchemaParameter(Schema schema, ReceiveName receiveName) { @@ -95,13 +94,13 @@ protected SchemaParameter(Schema schema, ReceiveName receiveName) { this.initName = null; this.type = ParameterType.RECEIVE; this.initialized = false; - this.serializedParameter = ""; } /** - * Initializes the parameter by ensuring serialization is performed correctly. This is required before parameter is used. + * Initializes the parameter by ensuring serialization is performed correctly. This is required before the parameter is used. * Use {@link SchemaParameter#initialize(boolean)} with parameter 'true' for more descriptive errors. + * * @throws CryptoJniException if the serialization could not be performed. */ public void initialize() { @@ -109,10 +108,12 @@ public void initialize() { } /** - * Initializes the parameter by ensuring serialization is performed correctly. This is required before parameter is used. + * Initializes the parameter by ensuring serialization is performed correctly. This is required before the parameter is used. + * * @param verboseErrors whether to return errors in a verbose format or not. Defaults to false if omitted. * @throws CryptoJniException if the serialization could not be performed. */ + @SneakyThrows(org.apache.commons.codec.DecoderException.class) public void initialize(boolean verboseErrors) { byte[] schemaBytes = schema.getSchemaBytes(); SchemaVersion schemaVersion = schema.getVersion(); @@ -120,45 +121,60 @@ public void initialize(boolean verboseErrors) { if (!result.isSuccess()) { throw CryptoJniException.from(result.getErr()); } - serializedParameter = result.getSerializedParameter(); + serializedParameter = Hex.decodeHex(result.getSerializedParameter()); this.initialized = true; } /** - * Helper method for {@link SchemaParameter#initialize()}. Performs the JNI call and parses result to {@link SerializeParameterResult}. + * Helper method for {@link SchemaParameter#initialize()}. Json serializes the parameter, performs the JNI call and deserializes the resulting json to {@link SerializeParameterResult}. + * * @param verboseErrors whether to return verbose errors. - * @param schemaBytes byte[] containing the schema. + * @param schemaBytes byte[] containing the schema. * @param schemaVersion version of the schema. * @return {@link SerializeParameterResult} containing the serialized parameter if successful or a {@link JNIError} if not. */ + @SneakyThrows private SerializeParameterResult getSerializeParameterResult(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion) { SerializeParameterResult result; - try { - String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - String resultJson; - if (this.type == ParameterType.INIT) { - String contractName = initName.getName(); - resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); - } else { - String contractName = receiveName.getContractName(); - String methodName = receiveName.getMethod(); - resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); - } - result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); + String resultJson; + resultJson = serializeUsingJNI(verboseErrors, schemaBytes, schemaVersion, parameterJson); + result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); return result; } + /** + * Helper method performing the correct JNI call according to the present {@link ParameterType}. + * + * @param verboseErrors whether to return verbose errors. + * @param schemaBytes byte[] containing the schema. + * @param schemaVersion version of the schema. + * @param parameterJson the parameter serialized as json. + * @return json representing a {@link SerializeParameterResult}. + */ + private String serializeUsingJNI(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion, String parameterJson) { + String resultJson; + if (this.type == ParameterType.INIT) { + String contractName = initName.getName(); + resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + } else { + String contractName = receiveName.getContractName(); + String methodName = receiveName.getMethod(); + resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + } + return resultJson; + } + /** * Converts the serialized parameter to a byte[]. Should only be called after parameter is initialized with {@link SchemaParameter#initialize()}. - * @throws IllegalStateException if parameter is not initialized. + * * @return byte[] containing the serialized parameter. + * @throws IllegalStateException if parameter is not initialized. */ - @SneakyThrows public byte[] toBytes() { - if (!initialized) {throw new IllegalStateException("Must initialize parameter before use");} - return Hex.decodeHex(serializedParameter); + if (!initialized) { + throw new IllegalStateException("Must initialize parameter before use"); + } + return serializedParameter; } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java index 485a305ed..76e4bb30e 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java @@ -81,8 +81,20 @@ public void serialize(AbstractAddress address, JsonGenerator jsonGenerator, Seri jsonGenerator.writeEndArray(); jsonGenerator.writeEndObject(); + break; case ADDRESS_CONTRACT: + ContractAddress contractAddress = (ContractAddress) address; + + jsonGenerator.writeStartObject(); + jsonGenerator.writeFieldName("Contract"); + jsonGenerator.writeStartArray(); + jsonGenerator.writeStartObject(); + jsonGenerator.writeNumberField("index", contractAddress.getIndex()); + jsonGenerator.writeNumberField("subindex", contractAddress.getSubIndex()); + jsonGenerator.writeEndObject(); + jsonGenerator.writeEndArray(); + jsonGenerator.writeEndObject(); break; } } From 9b58d899e6b0b974c9b156922de38c5d13bb970e Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Thu, 17 Aug 2023 16:31:22 +0200 Subject: [PATCH 09/53] Tests and start of examples --- .../smartcontracts/cis2nft/MintParams.java | 25 ++++ .../sdk/transactions/SchemaParameter.java | 15 ++- .../sdk/smartcontract/IncorrectParams.java | 18 +++ .../sdk/smartcontract/MintParams.java | 28 +++++ .../smartcontract/SerializeParameterTest.java | 107 ++++++++++++++++++ .../sdk/smartcontract/cis2-nft.schema.bin | Bin 0 -> 2975 bytes 6 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java new file mode 100644 index 000000000..4c5e33f32 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java @@ -0,0 +1,25 @@ +package com.concordium.sdk.examples.smartcontracts.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import lombok.Getter; + +import java.util.List; + +/** + * Represents the parameter 'MintParams' in the cis2-nft example + */ +@Getter +public class MintParams extends SchemaParameter { + private final AbstractAddress owner; + + private final List tokens; + + public MintParams(Schema schema, ReceiveName receiveName, AbstractAddress owner, List tokens) { + super(schema, receiveName); + this.owner = owner; + this.tokens = tokens; + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java index 605881411..b0507615d 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -15,12 +15,19 @@ /** * Represents smart contract parameters serializable via a {@link Schema}. *

- * Classes representing smart contract parameters should extend this and ensure they are JSON serializable in accordance with the provided smart contract schema. + * Classes representing smart contract parameters should extend this and ensure they are JSON serializable in accordance with the provided smart contract schema.

+ * Fields in the extending class, that should be serialized, must be visible to the serializer. + * Visible fields are:

+ *

    + *
  • Fields with 'getter' methods (either user-created or by @Getter annotation).
  • + *
  • All fields in a class annotated with '@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)'. Fields can be excluded from this with the '@JsonIgnore' annotation.
  • + *
  • Fields annotated with '@JsonProperty'. These have both getter and setter methods generated.
  • + *
  • Public fields
  • + *
* If default serialization does not work, a custom serializer should be implemented and used with annotation '@JsonSerialize(using = MyCustomSerializer.class)'. + * See {@link com.concordium.sdk.types.AbstractAddress} for an example of a custom serializer. *

- * See {@link com.concordium.sdk.types.AbstractAddress} for example. - *

- * Must be initialized by calling {@link SchemaParameter#initialize()} before usage. + * Parameter must be initialized by calling {@link SchemaParameter#initialize()} before usage. */ @Getter public abstract class SchemaParameter { diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java new file mode 100644 index 000000000..b991d4cce --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java @@ -0,0 +1,18 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import lombok.Getter; + +@Getter +public class IncorrectParams extends SchemaParameter { + + private final int value; + + protected IncorrectParams(Schema schema, ReceiveName receiveName) { + super(schema, receiveName); + value = 123; + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java new file mode 100644 index 000000000..b3ca68015 --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java @@ -0,0 +1,28 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; + +import java.util.List; + +/** + * Represents the parameter 'MintParams' in the cis2-nft example + * Used for testing serialization of {@link com.concordium.sdk.types.AbstractAddress} + */ +@Getter +public class MintParams extends SchemaParameter { + + private final AbstractAddress owner; + private final List tokens; + + public MintParams(Schema schema, ReceiveName receiveName, AbstractAddress owner, List tokens) { + super(schema, receiveName); + this.owner = owner; + this.tokens = tokens; + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java new file mode 100644 index 000000000..b2aa290a0 --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java @@ -0,0 +1,107 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.exceptions.CryptoJniException; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import lombok.SneakyThrows; +import lombok.val; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +/** + * This test ensures correct serialization of {@link com.concordium.sdk.transactions.SchemaParameter}.

+ * Specifically custom serialization of {@link com.concordium.sdk.types.AbstractAddress} is tested.

+ * Uses {@link MintParams} to model 'MintParams' in the cis2-nft example + */ +public class SerializeParameterTest { + + /** + * Schema for a cis2-nft contract + */ + private static final Schema SCHEMA; + /** + * entrypoint for method taking {@link MintParams} as parameter. + */ + private static final ReceiveName RECEIVE_NAME = ReceiveName.from("cis2_nft", "mint"); + private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); + private static final List TOKENS = new ArrayList<>(); + /** + * Incorrectly formatted tokens. + */ + private static final List INCORRECT_TOKENS = new ArrayList<>(); + + /** + * Populate TOKENS and initialize SCHEMA + */ + static { + TOKENS.add("21"); + TOKENS.add("22"); + TOKENS.add("23"); + INCORRECT_TOKENS.add("2"); + INCORRECT_TOKENS.add("321"); + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @SneakyThrows + @Test + public void shouldSerializeWithAccountAddress() { + val mintParamsWithAccountAddress = new MintParams(SCHEMA, RECEIVE_NAME, ACCOUNT_ADDRESS, TOKENS); + try { + mintParamsWithAccountAddress.initialize(); + } catch (Exception e) { + fail(); + } + } + + @SneakyThrows + @Test + public void shouldSerializeWithContractAddress() { + val mintParamsWithContractAddress = new MintParams(SCHEMA, RECEIVE_NAME, CONTRACT_ADDRESS, TOKENS); + try { + mintParamsWithContractAddress.initialize(); + } catch (Exception ex) { + fail(); + } + } + + @SneakyThrows + @Test + public void shouldThrowExcpetionOnInvalidParameter() { + IncorrectParams incorrectParamsClass = new IncorrectParams(SCHEMA, RECEIVE_NAME); + MintParams mintParamsWrongTokens = new MintParams(SCHEMA, RECEIVE_NAME, ACCOUNT_ADDRESS, INCORRECT_TOKENS); + int failed = 0; + try { + incorrectParamsClass.initialize(); + } catch (CryptoJniException ex) { + assertNotNull(ex.getErrorType()); + assertNotNull(ex.getErrorMessage()); + failed++; + } + try { + mintParamsWrongTokens.initialize(); + } catch (CryptoJniException ex) { + assertNotNull(ex.getErrorType()); + assertNotNull(ex.getErrorMessage()); + failed++; + } + // Makes sure an exception is thrown in both cases; + assertEquals(failed, 2); + } + + +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8eb4f344c08d906a8d4505ef4d9559c4f42dd2 GIT binary patch literal 2975 zcmdT`U2oGc6m`5ZK2}&J*1n(uFZ==i!8UDDCAuNjJy#}nXhdvRw$m~GIv?d8CzXnX zMp|hPd2kfpYhB-aa_+fVt@aYe*b`b=;or|p9@tabV0{*)Fqyi__tWH<@#a{tUzM2^ za>O2!MM&wC_XBvbKglv%nUEmp0ivE+6P(CuOFvCsy(8nGM~@e@#%3wXLQWBLEcsD1 z`6|zgtWYLgR7QHd{>h1li{rL!RmO=;1TT)XnhpUD|!g+Igm% zk#PjhAF)yQ%72D>7s`oX-3A@DhG8ehB%Nc+A;INU80$r;G||{P-w+3FQph0#rHc)B z%KM$G65Z{q#lpJaNg;+TO$K{pgLGWl>)I3haQzNX^L~04TQ_ChtNS@s5qo)}f{-Ez zDt<)8*U|t4Dpw8@NXA_Fd6WojF0D~fNUp6`vHI6<$=u2BPLghXu3QggLk2*G2uhp` zkUOC<2%_Ah`rKLFRxQyb!L~S!gZ&z6e26sRokJ5-uv$>|>Z%dgh$$)qinS|3f$b-y z?NV`&>_kcq)YrP)0xk^Y?)4kkvn Date: Thu, 17 Aug 2023 17:24:23 +0200 Subject: [PATCH 10/53] Tests and start of examples --- .../cis2nft/SetImplementorsParams.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java new file mode 100644 index 000000000..8fdd8274e --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java @@ -0,0 +1,25 @@ +package com.concordium.sdk.examples.smartcontracts.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.ContractAddress; +import lombok.Getter; + +import java.util.List; + +/** + * TODO + */ +@Getter +public class SetImplementorsParams extends SchemaParameter { + + private final String id; + private final List implementors; + + public SetImplementorsParams(Schema schema, ReceiveName receiveName, String id, List implementors) { + super(schema, receiveName); + this.id = id; + this.implementors = implementors; + } +} From 3936bf4ec7eccc81b5cd8a87eef44a49ada1c3df Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 6 Sep 2023 11:45:33 +0200 Subject: [PATCH 11/53] Fixed bug serializing ContractAddress and AccountAddress --- .../ConfigureBakerKeysJniInput.java | 21 ++-------------- .../sdk/transactions/SchemaParameter.java | 5 ++-- .../concordium/sdk/types/AbstractAddress.java | 11 ++++++-- .../concordium/sdk/types/AccountAddress.java | 15 +++++++++++ .../concordium/sdk/types/ContractAddress.java | 25 ++++++++++++++++--- .../sdk/smartcontract/MintParams.java | 4 +-- .../smartcontract/SerializeParameterTest.java | 3 +-- 7 files changed, 54 insertions(+), 30 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java index 77cc04edb..003128a3f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java @@ -1,7 +1,6 @@ package com.concordium.sdk.crypto.bakertransactions; import com.concordium.sdk.types.AccountAddress; -import com.fasterxml.jackson.annotation.JsonValue; import lombok.Builder; import lombok.Data; @@ -14,7 +13,7 @@ public class ConfigureBakerKeysJniInput { /** * The address of the account that will be configured as a baker */ - private final ConfigureBakerAccountAddress sender; + private final AccountAddress sender; /** * The baker keys that will be configured for the account @@ -23,23 +22,7 @@ public class ConfigureBakerKeysJniInput { @Builder public ConfigureBakerKeysJniInput(AccountAddress sender, BakerKeysJniOutput keys) { - this.sender = new ConfigureBakerAccountAddress(sender); + this.sender = sender; this.keys = keys; } - - /** - * Wrapper for {@link AccountAddress} to ensure correct serialization. - */ - private static class ConfigureBakerAccountAddress { - private final AccountAddress address; - - private ConfigureBakerAccountAddress(AccountAddress address) { - this.address = address; - } - - @JsonValue - String getAddress () { - return this.address.encoded(); - } - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java index b0507615d..b0c8924e1 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -6,6 +6,7 @@ import com.concordium.sdk.exceptions.JNIError; import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; import com.concordium.sdk.serializing.JsonMapper; +import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AccessLevel; import lombok.Getter; @@ -15,7 +16,7 @@ /** * Represents smart contract parameters serializable via a {@link Schema}. *

- * Classes representing smart contract parameters should extend this and ensure they are JSON serializable in accordance with the provided smart contract schema.

+ * Classes representing smart contract parameters should extend this, and ensure that they are JSON serializable in accordance with the provided smart contract schema.

* Fields in the extending class, that should be serialized, must be visible to the serializer. * Visible fields are:

*

    @@ -25,7 +26,7 @@ *
  • Public fields
  • *
* If default serialization does not work, a custom serializer should be implemented and used with annotation '@JsonSerialize(using = MyCustomSerializer.class)'. - * See {@link com.concordium.sdk.types.AbstractAddress} for an example of a custom serializer. + * See {@link AbstractAddress} for an example of a custom serializer. *

* Parameter must be initialized by calling {@link SchemaParameter#initialize()} before usage. */ diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java index 76e4bb30e..9b75eb6ab 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java @@ -2,10 +2,10 @@ import com.concordium.grpc.v2.Address; import com.concordium.sdk.transactions.AccountType; +import com.concordium.sdk.transactions.SchemaParameter; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.val; @@ -16,9 +16,12 @@ /** * An abstract Address. * Implementations are either Account - or Contract addresses. + *

+ * If used as parameter for a smart contract, the field containing the Abstract Address must be annotated:

+ * '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)'

+ * to ensure proper serialization. */ @EqualsAndHashCode -@JsonSerialize (using = AbstractAddress.AbstractAddressJsonSerializer.class) public abstract class AbstractAddress { @Getter @@ -65,6 +68,10 @@ public String toString() { return this.type.toString(); } + /** + * Implements custom serialization for {@link AbstractAddress}. Should be used when creating {@link SchemaParameter} containing {@link AbstractAddress}.

+ * To use, annotate field containing {@link AbstractAddress} with

'@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + */ public static class AbstractAddressJsonSerializer extends JsonSerializer { @Override public void serialize(AbstractAddress address, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AccountAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AccountAddress.java index b7ad8cdf4..59134f238 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AccountAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AccountAddress.java @@ -7,20 +7,27 @@ import com.concordium.sdk.transactions.CredentialRegistrationId; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.collect.ImmutableList; import concordium.ConcordiumP2PRpc; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.val; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; import java.util.Optional; + @EqualsAndHashCode(callSuper = true) +@JsonSerialize(using = AccountAddress.AccountAddressSerializer.class) public final class AccountAddress extends AbstractAddress { public static final int BYTES = 32; private final static int VERSION = 1; @@ -142,4 +149,12 @@ public static Optional> toList(ConcordiumP2PRpc.Js public String toString() { return encoded(); } + + public static class AccountAddressSerializer extends JsonSerializer { + @Override + public void serialize(AccountAddress accountAddress, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + + jsonGenerator.writeString(accountAddress.toString()); + } + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/ContractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/ContractAddress.java index 3f8a9a99e..c41e4448b 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/ContractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/ContractAddress.java @@ -4,11 +4,16 @@ import com.concordium.sdk.transactions.AccountType; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.collect.ImmutableList; import concordium.ConcordiumP2PRpc; import lombok.*; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Objects; import java.util.Optional; @@ -16,14 +21,15 @@ @Getter @ToString @EqualsAndHashCode(callSuper = true) +@JsonSerialize(using = ContractAddress.ContractAddressSerializer.class) public final class ContractAddress extends AbstractAddress { - @JsonProperty("subindex") - private final long subIndex; - @JsonProperty("index") private final long index; + @JsonProperty("subindex") + private final long subIndex; + @JsonCreator @Builder public ContractAddress(@JsonProperty("subindex") long subIndex, @@ -72,4 +78,17 @@ public byte[] getBytes() { buffer.putLong(this.getSubIndex()); return buffer.array(); } + + static class ContractAddressSerializer extends JsonSerializer { + @Override + public void serialize(ContractAddress o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + + jsonGenerator.writeStartObject(); + + jsonGenerator.writeNumberField("index", o.getIndex()); + jsonGenerator.writeNumberField("subindex", o.getSubIndex()); + + jsonGenerator.writeEndObject(); + } + } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java index b3ca68015..725453822 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java @@ -4,8 +4,7 @@ import com.concordium.sdk.transactions.Schema; import com.concordium.sdk.transactions.SchemaParameter; import com.concordium.sdk.types.AbstractAddress; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import java.util.List; @@ -17,6 +16,7 @@ @Getter public class MintParams extends SchemaParameter { + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private final AbstractAddress owner; private final List tokens; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java index b2aa290a0..14d6c0950 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java @@ -7,7 +7,6 @@ import com.concordium.sdk.types.ContractAddress; import lombok.SneakyThrows; import lombok.val; -import org.junit.Assert; import org.junit.Test; import java.io.IOException; @@ -81,7 +80,7 @@ public void shouldSerializeWithContractAddress() { @SneakyThrows @Test - public void shouldThrowExcpetionOnInvalidParameter() { + public void shouldThrowExceptionOnInvalidParameter() { IncorrectParams incorrectParamsClass = new IncorrectParams(SCHEMA, RECEIVE_NAME); MintParams mintParamsWrongTokens = new MintParams(SCHEMA, RECEIVE_NAME, ACCOUNT_ADDRESS, INCORRECT_TOKENS); int failed = 0; From 37db10622dbc027a2f6b254a974b13a24f95b080 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 13 Sep 2023 16:52:17 +0200 Subject: [PATCH 12/53] Added unit tests for serializaton of AbstractAddress, AccountAddress and ContractAddress --- .../smartcontracts/cis2nft/MintParams.java | 25 ------- .../cis2nft/SetImplementorsParams.java | 25 ------- .../sdk/transactions/SchemaParameter.java | 2 + .../concordium/sdk/types/AbstractAddress.java | 27 ++------ .../smartcontract/AbstractAddressTest.java | 65 ++++++++++++++++++ .../sdk/smartcontract/AccountAddressTest.java | 51 ++++++++++++++ .../smartcontract/ContractAddressTest.java | 56 +++++++++++++++ .../smartcontract/schema-unit-test.schema.bin | Bin 0 -> 380 bytes 8 files changed, 181 insertions(+), 70 deletions(-) delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java deleted file mode 100644 index 4c5e33f32..000000000 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/MintParams.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.concordium.sdk.examples.smartcontracts.cis2nft; - -import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; -import com.concordium.sdk.types.AbstractAddress; -import lombok.Getter; - -import java.util.List; - -/** - * Represents the parameter 'MintParams' in the cis2-nft example - */ -@Getter -public class MintParams extends SchemaParameter { - private final AbstractAddress owner; - - private final List tokens; - - public MintParams(Schema schema, ReceiveName receiveName, AbstractAddress owner, List tokens) { - super(schema, receiveName); - this.owner = owner; - this.tokens = tokens; - } -} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java deleted file mode 100644 index 8fdd8274e..000000000 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/smartcontracts/cis2nft/SetImplementorsParams.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.concordium.sdk.examples.smartcontracts.cis2nft; - -import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; -import com.concordium.sdk.types.ContractAddress; -import lombok.Getter; - -import java.util.List; - -/** - * TODO - */ -@Getter -public class SetImplementorsParams extends SchemaParameter { - - private final String id; - private final List implementors; - - public SetImplementorsParams(Schema schema, ReceiveName receiveName, String id, List implementors) { - super(schema, receiveName); - this.id = id; - this.implementors = implementors; - } -} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java index b0c8924e1..0e43ed88c 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java @@ -29,6 +29,8 @@ * See {@link AbstractAddress} for an example of a custom serializer. *

* Parameter must be initialized by calling {@link SchemaParameter#initialize()} before usage. + *

+ * For functions not expecting parameters use {@link Parameter#EMPTY} instead. */ @Getter public abstract class SchemaParameter { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java index 9b75eb6ab..f982168b0 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java @@ -75,35 +75,22 @@ public String toString() { public static class AbstractAddressJsonSerializer extends JsonSerializer { @Override public void serialize(AbstractAddress address, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); switch (address.getType()){ case ADDRESS_ACCOUNT: - AccountAddress accountAddress = (AccountAddress) address; - - jsonGenerator.writeStartObject(); - jsonGenerator.writeFieldName("Account"); - - jsonGenerator.writeStartArray(); - jsonGenerator.writeString(accountAddress.encoded()); - jsonGenerator.writeEndArray(); - - jsonGenerator.writeEndObject(); break; case ADDRESS_CONTRACT: - ContractAddress contractAddress = (ContractAddress) address; - - jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("Contract"); - jsonGenerator.writeStartArray(); - jsonGenerator.writeStartObject(); - jsonGenerator.writeNumberField("index", contractAddress.getIndex()); - jsonGenerator.writeNumberField("subindex", contractAddress.getSubIndex()); - jsonGenerator.writeEndObject(); - jsonGenerator.writeEndArray(); - jsonGenerator.writeEndObject(); break; } + jsonGenerator.writeStartArray(); + + jsonGenerator.writeObject(address); + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndObject(); } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java new file mode 100644 index 000000000..441bec688 --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java @@ -0,0 +1,65 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.fail; + +public class AbstractAddressTest { + static Schema SCHEMA; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void shouldSerializeWithAccountAddress() { + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); + AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + AbstractAddressTest.AbstractAddressContainer abstractAddressContainer = new AbstractAddressTest.AbstractAddressContainer(SCHEMA, receiveName, address); + try { + abstractAddressContainer.initialize(); + } catch (Exception e) { + fail(); + } + } + + @Test + public void shouldSerializeWithContractAddress() { + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); + ContractAddress address = ContractAddress.from(1, 0); + AbstractAddressTest.AbstractAddressContainer abstractAddressContainer = new AbstractAddressTest.AbstractAddressContainer(SCHEMA, receiveName, address); + try { + abstractAddressContainer.initialize(); + } catch (Exception e) { + fail(); + } + } + + @Getter + private static class AbstractAddressContainer extends SchemaParameter { + + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress address; + + public AbstractAddressContainer(Schema schema, ReceiveName receiveName, AbstractAddress address) { + super(schema, receiveName); + this.address = address; + } + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java new file mode 100644 index 000000000..9f43f919f --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java @@ -0,0 +1,51 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.AccountAddress; +import lombok.Getter; +import lombok.SneakyThrows; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.fail; + +public class AccountAddressTest { + static Schema SCHEMA; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @SneakyThrows + @Test + public void shouldSerialize() { + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test","account_address_test" ); + AccountAddress address =AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + AccountAddressTest.AccountAddressContainer accountAddressContainer = new AccountAddressTest.AccountAddressContainer(SCHEMA, receiveName, address); + try { + accountAddressContainer.initialize(); + } + catch (Exception e) { + fail(); + } + } + + @Getter + private static class AccountAddressContainer extends SchemaParameter { + + private AccountAddress address; + + public AccountAddressContainer(Schema schema, ReceiveName receiveName, AccountAddress address) { + super(schema, receiveName); + this.address = address; + } + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java new file mode 100644 index 000000000..a0060c40c --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java @@ -0,0 +1,56 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.types.ContractAddress; +import lombok.Getter; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.fail; + +/** + * Ensures correct serialization of {@link ContractAddress}. + */ +public class ContractAddressTest { + + static Schema SCHEMA; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test + public void shouldSerialize() { + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test","contract_address_test" ); + ContractAddress contractAddress = ContractAddress.from(1, 0); + ContractAddressContainer contractAddressContainer = new ContractAddressContainer(SCHEMA, receiveName, contractAddress); + try { + contractAddressContainer.initialize(); + } + catch (Exception e) { + fail(); + } + } + + /** + * Parameter containing only a ContractAddress. Is to ensure proper serialization of ContractAddress. + */ + @Getter + public static class ContractAddressContainer extends SchemaParameter { + + private final ContractAddress address; + + public ContractAddressContainer(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { + super(schema, receiveName); + this.address = contractAddress; + } + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin new file mode 100644 index 0000000000000000000000000000000000000000..cfe7de4eab93aef253af754d15d4dc82ace6217f GIT binary patch literal 380 zcma)1!3x4K3~gscWgfSKpCjVktEUpXfK|3a($&wOX}9|pNZ`E}Uh<}CrjoxtH$bRzp I(>ayYAE^ji&j0`b literal 0 HcmV?d00001 From 4bf974d11e38cf7a5020df04b07b2fe49aa0ba60 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 15 Sep 2023 13:21:50 +0200 Subject: [PATCH 13/53] UInt8 wrapper and tests. --- .../java/com/concordium/sdk/types/UInt8.java | 53 +++++ .../smartcontract/AbstractAddressTest.java | 15 +- .../sdk/smartcontract/AccountAddressTest.java | 21 +- .../smartcontract/ContractAddressTest.java | 14 +- .../com/concordium/sdk/smartcontract/lib.rs | 199 ++++++++++++++++++ ...t-test.schema.bin => unit-test.schema.bin} | Bin .../com/concordium/sdk/types/UInt8Test.java | 48 +++++ 7 files changed, 328 insertions(+), 22 deletions(-) create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs rename concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/{schema-unit-test.schema.bin => unit-test.schema.bin} (100%) create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java new file mode 100644 index 000000000..6f68c7a2c --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -0,0 +1,53 @@ +package com.concordium.sdk.types; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.val; + +import java.nio.ByteBuffer; + +@EqualsAndHashCode +@Getter +public class UInt8 { + + public static final int BYTES = Byte.BYTES; + final int value; + + private UInt8(int value) { + this.value = value; + } + + public byte[] getBytes() { + val bytes = new byte[1]; + bytes[0] = (byte) (value & 0xff); + return bytes; + } + + public static UInt8 from(String value) { + return UInt8.from(Integer.parseUnsignedInt(value)); + } + + public static UInt8 from(int value) { + if (value < 0) { + throw new NumberFormatException("Value of UInt8 cannot be negative"); + } + if (value > 255) { + throw new NumberFormatException("Value of UInt8 cannot exceed 2^8"); + } + return new UInt8(value); + } + + public static UInt8 from(byte[] valueBytes) { + val buffer = ByteBuffer.allocate(Byte.BYTES); + buffer.put(valueBytes); + return new UInt8(buffer.get(0) & 0xff); + } + + public static UInt8 fromBytes(ByteBuffer source) { + byte[] valueBytes = new byte[1]; + source.get(valueBytes); + return UInt8.from(valueBytes); + } + + public String toString() {return String.valueOf(value);} +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java index 441bec688..3b8d25189 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java @@ -16,12 +16,15 @@ import static org.junit.Assert.fail; +/** + * Ensures correct serialization of {@link AbstractAddress} when annotated correctly. + */ public class AbstractAddressTest { static Schema SCHEMA; static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } @@ -31,7 +34,7 @@ public class AbstractAddressTest { public void shouldSerializeWithAccountAddress() { ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - AbstractAddressTest.AbstractAddressContainer abstractAddressContainer = new AbstractAddressTest.AbstractAddressContainer(SCHEMA, receiveName, address); + AbstractAddressParameter abstractAddressContainer = new AbstractAddressParameter(SCHEMA, receiveName, address); try { abstractAddressContainer.initialize(); } catch (Exception e) { @@ -43,7 +46,7 @@ public void shouldSerializeWithAccountAddress() { public void shouldSerializeWithContractAddress() { ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); ContractAddress address = ContractAddress.from(1, 0); - AbstractAddressTest.AbstractAddressContainer abstractAddressContainer = new AbstractAddressTest.AbstractAddressContainer(SCHEMA, receiveName, address); + AbstractAddressParameter abstractAddressContainer = new AbstractAddressParameter(SCHEMA, receiveName, address); try { abstractAddressContainer.initialize(); } catch (Exception e) { @@ -52,12 +55,12 @@ public void shouldSerializeWithContractAddress() { } @Getter - private static class AbstractAddressContainer extends SchemaParameter { + private static class AbstractAddressParameter extends SchemaParameter { @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) - private AbstractAddress address; + private final AbstractAddress address; - public AbstractAddressContainer(Schema schema, ReceiveName receiveName, AbstractAddress address) { + public AbstractAddressParameter(Schema schema, ReceiveName receiveName, AbstractAddress address) { super(schema, receiveName); this.address = address; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java index 9f43f919f..c2b1c2861 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java @@ -14,36 +14,39 @@ import static org.junit.Assert.fail; +/** + * Ensures correct serialization of {@link AccountAddress}. + */ public class AccountAddressTest { static Schema SCHEMA; static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } } + @SneakyThrows @Test public void shouldSerialize() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test","account_address_test" ); - AccountAddress address =AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - AccountAddressTest.AccountAddressContainer accountAddressContainer = new AccountAddressTest.AccountAddressContainer(SCHEMA, receiveName, address); + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "account_address_test"); + AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + AccountAddressParameter accountAddressContainer = new AccountAddressParameter(SCHEMA, receiveName, address); try { accountAddressContainer.initialize(); - } - catch (Exception e) { + } catch (Exception e) { fail(); } } @Getter - private static class AccountAddressContainer extends SchemaParameter { + private static class AccountAddressParameter extends SchemaParameter { - private AccountAddress address; + private final AccountAddress address; - public AccountAddressContainer(Schema schema, ReceiveName receiveName, AccountAddress address) { + public AccountAddressParameter(Schema schema, ReceiveName receiveName, AccountAddress address) { super(schema, receiveName); this.address = address; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java index a0060c40c..744bdf025 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java @@ -22,20 +22,20 @@ public class ContractAddressTest { static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } } + @Test public void shouldSerialize() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test","contract_address_test" ); + ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "contract_address_test"); ContractAddress contractAddress = ContractAddress.from(1, 0); - ContractAddressContainer contractAddressContainer = new ContractAddressContainer(SCHEMA, receiveName, contractAddress); + ContractAddressParameter contractAddressContainer = new ContractAddressParameter(SCHEMA, receiveName, contractAddress); try { contractAddressContainer.initialize(); - } - catch (Exception e) { + } catch (Exception e) { fail(); } } @@ -44,11 +44,11 @@ public void shouldSerialize() { * Parameter containing only a ContractAddress. Is to ensure proper serialization of ContractAddress. */ @Getter - public static class ContractAddressContainer extends SchemaParameter { + public static class ContractAddressParameter extends SchemaParameter { private final ContractAddress address; - public ContractAddressContainer(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { + public ContractAddressParameter(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { super(schema, receiveName); this.address = contractAddress; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs new file mode 100644 index 000000000..ed674941e --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs @@ -0,0 +1,199 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +//! # A Concordium V1 smart contract +use concordium_std::*; +use core::fmt::Debug; + +/// Your smart contract state. +#[derive(Serialize, SchemaType)] +pub struct State { + // Your state +} + +/// Your smart contract errors. +#[derive(Debug, PartialEq, Eq, Reject, Serial, SchemaType)] +enum Error { + /// Failed parsing the parameter. + #[from(ParseError)] + ParseParams, + /// Your error + YourError, +} + +/// Init function that creates a new smart contract. +#[init(contract = "java_sdk_schema_unit_test")] +fn init( + _ctx: &impl HasInitContext, + _state_builder: &mut StateBuilder, +) -> InitResult { + // Your code + + Ok(State {}) +} + +#[derive(Serialize, SchemaType)] +struct AbstractAddressContainer { + /// The amount of tokens to unwrap. + address: Address, +} + +#[derive(Serialize, SchemaType)] +struct AccountAddressContainer { + /// The amount of tokens to unwrap. + address: AccountAddress, +} + +#[derive(Serialize, SchemaType)] +struct ContractAddressContainer { + /// The amount of tokens to unwrap. + address: ContractAddress, +} + +/// Takes Address as parameter for ensuring correct serialization of Address +#[receive( + contract = "java_sdk_schema_unit_test", + name = "abstract_address_test", + parameter = "AbstractAddressContainer", + error = "Error", + mutable +)] +fn abstract_address_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} + +/// Takes a ContractAddress as parameter for ensuring correct serialization of ContractAddress +#[receive( + contract = "java_sdk_schema_unit_test", + name = "contract_address_test", + parameter = "ContractAddressContainer", + error = "Error", + mutable +)] +fn contract_address_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} + +/// Takes an AccountAddress as parameter for ensuring correct serialization of AccountAddress +#[receive( + contract = "java_sdk_schema_unit_test", + name = "account_address_test", + parameter = "AccountAddressContainer", + error = "Error", + mutable +)] +fn account_address_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} + +/// Receive function. The input parameter is the boolean variable `throw_error`. +/// If `throw_error == true`, the receive function will throw a custom error. +/// If `throw_error == false`, the receive function executes successfully. +#[receive( + contract = "java_sdk_schema_unit_test", + name = "receive", + parameter = "bool", + error = "Error", + mutable +)] +fn receive( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + // Your code + + let throw_error = ctx.parameter_cursor().get()?; // Returns Error::ParseError on failure + if throw_error { + Err(Error::YourError) + } else { + Ok(()) + } +} + +/// View function that returns the content of the state. +#[receive(contract = "java_sdk_schema_unit_test", name = "view", return_value = "State")] +fn view<'b, S: HasStateApi>( + _ctx: &impl HasReceiveContext, + host: &'b impl HasHost, +) -> ReceiveResult<&'b State> { + Ok(host.state()) +} + +#[concordium_cfg_test] +mod tests { + use super::*; + use test_infrastructure::*; + + type ContractResult = Result; + + #[concordium_test] + /// Test that initializing the contract succeeds with some state. + fn test_init() { + let ctx = TestInitContext::empty(); + + let mut state_builder = TestStateBuilder::new(); + + let state_result = init(&ctx, &mut state_builder); + state_result.expect_report("Contract initialization results in error"); + } + + #[concordium_test] + /// Test that invoking the `receive` endpoint with the `false` parameter + /// succeeds in updating the contract. + fn test_throw_no_error() { + let ctx = TestInitContext::empty(); + + let mut state_builder = TestStateBuilder::new(); + + // Initializing state + let initial_state = init(&ctx, &mut state_builder).expect("Initialization should pass"); + + let mut ctx = TestReceiveContext::empty(); + + let throw_error = false; + let parameter_bytes = to_bytes(&throw_error); + ctx.set_parameter(¶meter_bytes); + + let mut host = TestHost::new(initial_state, state_builder); + + // Call the contract function. + let result: ContractResult<()> = receive(&ctx, &mut host); + + // Check the result. + claim!(result.is_ok(), "Results in rejection"); + } + + #[concordium_test] + /// Test that invoking the `receive` endpoint with the `true` parameter + /// results in the `YourError` being thrown. + fn test_throw_error() { + let ctx = TestInitContext::empty(); + + let mut state_builder = TestStateBuilder::new(); + + // Initializing state + let initial_state = init(&ctx, &mut state_builder).expect("Initialization should pass"); + + let mut ctx = TestReceiveContext::empty(); + + let throw_error = true; + let parameter_bytes = to_bytes(&throw_error); + ctx.set_parameter(¶meter_bytes); + + let mut host = TestHost::new(initial_state, state_builder); + + // Call the contract function. + let error: ContractResult<()> = receive(&ctx, &mut host); + + // Check the result. + claim_eq!(error, Err(Error::YourError), "Function should throw an error."); + } +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin similarity index 100% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/schema-unit-test.schema.bin rename to concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java b/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java new file mode 100644 index 000000000..e40dc6ff0 --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java @@ -0,0 +1,48 @@ +package com.concordium.sdk.types; + +import lombok.val; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class UInt8Test { + + @Test + public void testCreation() { + checkNegativeNumber(); + UInt8.from("255"); //(2^8)-1 + checkTooLargeNumber(); + } + + + private void checkNegativeNumber() { + try { + UInt8.from(-13); + fail("Should not be able to create negative UInt8"); + } catch (RuntimeException e) { + if (!e.getMessage().equals("Value of UInt8 cannot be negative")) { + fail("Unexpected error when creating negative UInt8 " + e.getMessage()); + } + } + } + + private void checkTooLargeNumber() { + try { + UInt8.from("256"); //(2^8) + fail("This should exceed the range."); + } catch (NumberFormatException e) { + if (!e.getMessage().equals("Value of UInt8 cannot exceed 2^8")) { + fail("Unexpected error when creating too big UInt8: " + e.getMessage()); + } + } + } + + @Test + public void testSerializeDeserialize() { + val expected = UInt8.from("250"); + val bytes = expected.getBytes(); + val deserialized = UInt8.from(bytes); + assertEquals(expected, deserialized); + assertNotEquals(expected, UInt8.from("42")); + } +} From 44a42b9306686ce1ba76e4ce005d6e8d0af36b4a Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 15 Sep 2023 15:10:50 +0200 Subject: [PATCH 14/53] Added wrappers and unit tests for AbstractAddress, AccountAddress and ContractAddress for passing directly as parameters. Moved smart contract related stuff to transactions.smartcontracts. Moved test resources. --- .../sdk/crypto/CryptoJniNative.java | 2 +- .../smartcontracts/InvokeInstanceRequest.java | 2 + .../sdk/transactions/InitContractPayload.java | 2 + .../sdk/transactions/Parameter.java | 1 + .../transactions/UpdateContractPayload.java | 2 + .../{ => smartcontracts}/ParameterType.java | 4 +- .../{ => smartcontracts}/Schema.java | 2 +- .../{ => smartcontracts}/SchemaParameter.java | 3 +- .../{ => smartcontracts}/SchemaVersion.java | 2 +- .../SerializeParameterResult.java | 2 +- .../parameters/AccountAddressParam.java | 40 +++++++++++ .../parameters/AddressParam.java | 55 ++++++++++++++++ .../parameters/ContractAddressParam.java | 41 ++++++++++++ .../smartcontracts/parameters/ListParam.java | 43 ++++++++++++ .../concordium/sdk/types/AbstractAddress.java | 2 +- .../java/com/concordium/sdk/types/UInt8.java | 17 +---- .../sdk/ClientV2ImportWalletTest.java | 4 +- .../smartcontract/AbstractAddressTest.java | 55 ++++++++++++---- .../sdk/smartcontract/AccountAddressTest.java | 38 ++++++++--- .../smartcontract/ContractAddressTest.java | 37 ++++++++--- .../sdk/smartcontract/IncorrectParams.java | 5 +- .../sdk/smartcontract/ListParamTest.java | 9 +++ .../sdk/smartcontract/MintParams.java | 4 +- .../smartcontract/SerializeParameterTest.java | 7 +- .../sdk/smartcontract/unit-test.schema.bin | Bin 380 -> 0 bytes .../com/concordium/sdk/types/UInt8Test.java | 8 ++- .../smartcontractschema}/cis2-nft.schema.bin | Bin .../smartcontractschema}/lib.rs | 62 ++++++++++++------ .../smartcontractschema/unit-test.schema.bin | Bin 0 -> 586 bytes .../walletexports/browserWallet.json | 0 .../walletexports/genesisWallet.json | 0 31 files changed, 366 insertions(+), 83 deletions(-) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{ => smartcontracts}/ParameterType.java (68%) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{ => smartcontracts}/Schema.java (95%) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{ => smartcontracts}/SchemaParameter.java (98%) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{ => smartcontracts}/SchemaVersion.java (84%) rename concordium-sdk/src/main/java/com/concordium/sdk/transactions/{ => smartcontracts}/SerializeParameterResult.java (95%) create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java create mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java create mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java delete mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin rename concordium-sdk/src/test/{java/com/concordium/sdk/smartcontract => testresources/smartcontractschema}/cis2-nft.schema.bin (100%) rename concordium-sdk/src/test/{java/com/concordium/sdk/smartcontract => testresources/smartcontractschema}/lib.rs (78%) create mode 100644 concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin rename concordium-sdk/src/test/{java/com/concordium/sdk => testresources}/walletexports/browserWallet.json (100%) rename concordium-sdk/src/test/{java/com/concordium/sdk => testresources}/walletexports/genesisWallet.json (100%) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index efd21a464..71b721658 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -1,6 +1,6 @@ package com.concordium.sdk.crypto; -import com.concordium.sdk.transactions.SerializeParameterResult; +import com.concordium.sdk.transactions.smartcontracts.SerializeParameterResult; public class CryptoJniNative { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 594dd8b46..3f8b34b48 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -2,6 +2,8 @@ import com.concordium.sdk.requests.BlockQuery; import com.concordium.sdk.transactions.*; +import com.concordium.sdk.transactions.smartcontracts.ParameterType; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.ContractAddress; import lombok.*; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index ef63815f9..aaa68ab27 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -1,6 +1,8 @@ package com.concordium.sdk.transactions; import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.transactions.smartcontracts.ParameterType; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index a527f253e..2337c5639 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -1,5 +1,6 @@ package com.concordium.sdk.transactions; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.UInt16; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.Getter; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index 4e49bfed5..3673a0629 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -1,5 +1,7 @@ package com.concordium.sdk.transactions; +import com.concordium.sdk.transactions.smartcontracts.ParameterType; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.ContractAddress; import lombok.*; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java similarity index 68% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java index 8e847f9f1..73c750127 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/ParameterType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java @@ -1,6 +1,8 @@ -package com.concordium.sdk.transactions; +package com.concordium.sdk.transactions.smartcontracts; import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; +import com.concordium.sdk.transactions.InitContractPayload; +import com.concordium.sdk.transactions.UpdateContractPayload; /** * The possible variants of {@link SchemaParameter}. diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java similarity index 95% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java index 128ea5daa..40ac0db0e 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Schema.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.transactions; +package com.concordium.sdk.transactions.smartcontracts; import lombok.Getter; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java similarity index 98% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java index 0e43ed88c..eaf5bf8d9 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.transactions; +package com.concordium.sdk.transactions.smartcontracts; import com.concordium.sdk.crypto.CryptoJniNative; import com.concordium.sdk.crypto.NativeResolver; @@ -6,6 +6,7 @@ import com.concordium.sdk.exceptions.JNIError; import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; import com.concordium.sdk.serializing.JsonMapper; +import com.concordium.sdk.transactions.*; import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AccessLevel; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java similarity index 84% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java index f44532486..a808b1980 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SchemaVersion.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.transactions; +package com.concordium.sdk.transactions.smartcontracts; import lombok.Getter; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java similarity index 95% rename from concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java rename to concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java index 608ad484b..f7c5c6063 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.transactions; +package com.concordium.sdk.transactions.smartcontracts; import com.concordium.sdk.exceptions.JNIError; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java new file mode 100644 index 000000000..ed6595e6f --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java @@ -0,0 +1,40 @@ +package com.concordium.sdk.transactions.smartcontracts.parameters; + +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AccountAddress; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +/** + * Wrapper class allowing {@link AccountAddress} to be passed directly as a smart contract parameter. + */ +@Getter +@JsonSerialize(using = AccountAddressParam.AccountAddressParamSerializer.class) +public class AccountAddressParam extends SchemaParameter { + private final AccountAddress accountAddress; + + public AccountAddressParam(Schema schema, InitName initName, AccountAddress accountAddress) { + super(schema, initName); + this.accountAddress = accountAddress; + } + + public AccountAddressParam(Schema schema, ReceiveName receiveName, AccountAddress accountAddress) { + super(schema, receiveName); + this.accountAddress = accountAddress; + } + + public static class AccountAddressParamSerializer extends JsonSerializer { + @Override + public void serialize(AccountAddressParam accountAddressParam, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + jsonGenerator.writeObject(accountAddressParam.getAccountAddress()); + } + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java new file mode 100644 index 000000000..0d54c32ae --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java @@ -0,0 +1,55 @@ +package com.concordium.sdk.transactions.smartcontracts.parameters; + +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +/** + * Wrapper class allowing {@link AbstractAddress} to be passed directly as a smart contract parameter. + */ +@JsonSerialize(using = AddressParam.AddressParamSerializer.class) +@Getter +public class AddressParam extends SchemaParameter { + + private final AbstractAddress address; + + public AddressParam(Schema schema, InitName initName, AbstractAddress address) { + super(schema, initName); + this.address = address; + } + + public AddressParam(Schema schema, ReceiveName receiveName, AbstractAddress address) { + super(schema, receiveName); + this.address = address; + } + + + public static class AddressParamSerializer extends JsonSerializer { + @Override + public void serialize(AddressParam addressParam, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + switch (addressParam.getAddress().getType()) { + case ADDRESS_ACCOUNT: + jsonGenerator.writeFieldName("Account"); + + break; + case ADDRESS_CONTRACT: + jsonGenerator.writeFieldName("Contract"); + break; + } + jsonGenerator.writeStartArray(); + jsonGenerator.writeObject(addressParam.getAddress()); + jsonGenerator.writeEndArray(); + jsonGenerator.writeEndObject(); + } + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java new file mode 100644 index 000000000..06e56614f --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java @@ -0,0 +1,41 @@ +package com.concordium.sdk.transactions.smartcontracts.parameters; + +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.ContractAddress; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +/** + * Wrapper class allowing {@link ContractAddress} to be passed directly as a smart contract parameter. + */ +@Getter +@JsonSerialize(using = ContractAddressParam.ContractAddressParamSerializer.class) +public class ContractAddressParam extends SchemaParameter { + + private final ContractAddress contractAddress; + + public ContractAddressParam(Schema schema, InitName initName, ContractAddress contractAddress) { + super(schema, initName); + this.contractAddress = contractAddress; + } + + public ContractAddressParam(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { + super(schema, receiveName); + this.contractAddress = contractAddress; + } + + public static class ContractAddressParamSerializer extends JsonSerializer { + @Override + public void serialize(ContractAddressParam contractAddressParam, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + jsonGenerator.writeObject(contractAddressParam.getContractAddress()); + } + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java new file mode 100644 index 000000000..9726ec2c4 --- /dev/null +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -0,0 +1,43 @@ +package com.concordium.sdk.transactions.smartcontracts.parameters; + +import com.concordium.sdk.serializing.JsonMapper; +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; +import java.util.List; + +/** + * Wrapper for passing lists as smart contract parameters. + * Contents of the list must be serializable according to the provided {@link Schema}. + */ +@Getter +@JsonSerialize(using = ListParam.ListParamSerializer.class) +public class ListParam extends SchemaParameter { + + private final List list; + + public ListParam(Schema schema, InitName initName, List list) { + super(schema, initName); + this.list = list; + } + + public ListParam(Schema schema, ReceiveName receiveName, List list) { + super(schema, receiveName); + this.list = list; + } + + public static class ListParamSerializer extends JsonSerializer { + @Override + public void serialize(ListParam listParam, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + jsonGenerator.writeRaw(JsonMapper.INSTANCE.writeValueAsString(listParam.getList())); + } + } +} diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java index f982168b0..7df7ea898 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/AbstractAddress.java @@ -2,7 +2,7 @@ import com.concordium.grpc.v2.Address; import com.concordium.sdk.transactions.AccountType; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java index 6f68c7a2c..168cc6d51 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -4,14 +4,11 @@ import lombok.Getter; import lombok.val; -import java.nio.ByteBuffer; - @EqualsAndHashCode @Getter public class UInt8 { - public static final int BYTES = Byte.BYTES; - final int value; + private final int value; private UInt8(int value) { this.value = value; @@ -37,16 +34,8 @@ public static UInt8 from(int value) { return new UInt8(value); } - public static UInt8 from(byte[] valueBytes) { - val buffer = ByteBuffer.allocate(Byte.BYTES); - buffer.put(valueBytes); - return new UInt8(buffer.get(0) & 0xff); - } - - public static UInt8 fromBytes(ByteBuffer source) { - byte[] valueBytes = new byte[1]; - source.get(valueBytes); - return UInt8.from(valueBytes); + public static UInt8 from(byte b) { + return new UInt8(b & 0xff); } public String toString() {return String.valueOf(value);} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/ClientV2ImportWalletTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/ClientV2ImportWalletTest.java index fb7063c03..75ea70a70 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/ClientV2ImportWalletTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/ClientV2ImportWalletTest.java @@ -29,11 +29,11 @@ public class ClientV2ImportWalletTest { @Test public void importBrowserWallet() throws IOException { - assertEquals(EXPECTED_BROWSER_TRANSACTION_SIGNER, TransactionSigner.from(new File("./src/test/java/com/concordium/sdk/walletexports/browserWallet.json"))); + assertEquals(EXPECTED_BROWSER_TRANSACTION_SIGNER, TransactionSigner.from(new File("./src/test/testresources/walletexports/browserWallet.json"))); } @Test public void importGenesisWallet() throws IOException { - assertEquals(EXPECTED_GENESIS_TRANSACTION_SIGNER, TransactionSigner.from(new File("./src/test/java/com/concordium/sdk/walletexports/genesisWallet.json"))); + assertEquals(EXPECTED_GENESIS_TRANSACTION_SIGNER, TransactionSigner.from(new File("./src/test/testresources/walletexports/genesisWallet.json"))); } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java index 3b8d25189..1b75c7fd6 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java @@ -1,8 +1,9 @@ package com.concordium.sdk.smartcontract; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.parameters.AddressParam; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; @@ -18,23 +19,26 @@ /** * Ensures correct serialization of {@link AbstractAddress} when annotated correctly. + * First 2 tests ensures correct serialization of parameters containing {@link AbstractAddress}. + * Last 2 tests ensures correct serialization when {@link AbstractAddress} is passed directly as a parameter using the wrapper {@link AddressParam}. */ public class AbstractAddressTest { static Schema SCHEMA; + static String CONTRACT_NAME = "java_sdk_schema_unit_test"; static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/testresources/smartcontractschema/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } } @Test - public void shouldSerializeWithAccountAddress() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); + public void shouldSerializeContainerWithAccountAddress() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "abstract_address_container_test"); AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - AbstractAddressParameter abstractAddressContainer = new AbstractAddressParameter(SCHEMA, receiveName, address); + AbstractAddressContainer abstractAddressContainer = new AbstractAddressContainer(SCHEMA, receiveName, address); try { abstractAddressContainer.initialize(); } catch (Exception e) { @@ -43,10 +47,10 @@ public void shouldSerializeWithAccountAddress() { } @Test - public void shouldSerializeWithContractAddress() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "abstract_address_test"); + public void shouldSerializeContainerWithContractAddress() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "abstract_address_container_test"); ContractAddress address = ContractAddress.from(1, 0); - AbstractAddressParameter abstractAddressContainer = new AbstractAddressParameter(SCHEMA, receiveName, address); + AbstractAddressContainer abstractAddressContainer = new AbstractAddressContainer(SCHEMA, receiveName, address); try { abstractAddressContainer.initialize(); } catch (Exception e) { @@ -54,13 +58,42 @@ public void shouldSerializeWithContractAddress() { } } + + + @Test + public void shouldSerializeWithAccountAddress() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "abstract_address_test"); + AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + AddressParam addressParam = new AddressParam(SCHEMA, receiveName, address); + try { + addressParam.initialize(); + } catch (Exception e) { + fail(); + } + } + + @Test + public void shouldSerializeWithContractAddress() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "abstract_address_test"); + ContractAddress address = ContractAddress.from(1, 0); + AddressParam addressParam = new AddressParam(SCHEMA, receiveName, address); + try { + addressParam.initialize(); + } catch (Exception e) { + fail(); + } + } + + /** + * Parameter containing only a {@link AbstractAddress}. + */ @Getter - private static class AbstractAddressParameter extends SchemaParameter { + private static class AbstractAddressContainer extends SchemaParameter { @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private final AbstractAddress address; - public AbstractAddressParameter(Schema schema, ReceiveName receiveName, AbstractAddress address) { + public AbstractAddressContainer(Schema schema, ReceiveName receiveName, AbstractAddress address) { super(schema, receiveName); this.address = address; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java index c2b1c2861..a8eda28fd 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java @@ -1,11 +1,11 @@ package com.concordium.sdk.smartcontract; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.parameters.AccountAddressParam; import com.concordium.sdk.types.AccountAddress; import lombok.Getter; -import lombok.SneakyThrows; import org.junit.Test; import java.io.IOException; @@ -16,24 +16,27 @@ /** * Ensures correct serialization of {@link AccountAddress}. + * First test ensures correct serialization of parameters containing {@link AccountAddress}. + * Last tests ensures correct serialization when {@link AccountAddress} is passed directly as a parameter using the wrapper {@link AccountAddressParam}. */ public class AccountAddressTest { static Schema SCHEMA; + static String CONTRACT_NAME = "java_sdk_schema_unit_test"; + static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/testresources/smartcontractschema/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } } - @SneakyThrows @Test - public void shouldSerialize() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "account_address_test"); + public void shouldSerializeContainer() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "account_address_container_test"); AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - AccountAddressParameter accountAddressContainer = new AccountAddressParameter(SCHEMA, receiveName, address); + AccountAddressContainer accountAddressContainer = new AccountAddressContainer(SCHEMA, receiveName, address); try { accountAddressContainer.initialize(); } catch (Exception e) { @@ -41,12 +44,27 @@ public void shouldSerialize() { } } + @Test + public void shouldSerialize() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "account_address_test"); + AccountAddress address = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + AccountAddressParam accountAddressParam = new AccountAddressParam(SCHEMA, receiveName, address); + try { + accountAddressParam.initialize(); + } catch (Exception e) { + fail(); + } + } + + /** + * Parameter containing only a {@link AccountAddress}. + */ @Getter - private static class AccountAddressParameter extends SchemaParameter { + private static class AccountAddressContainer extends SchemaParameter { private final AccountAddress address; - public AccountAddressParameter(Schema schema, ReceiveName receiveName, AccountAddress address) { + public AccountAddressContainer(Schema schema, ReceiveName receiveName, AccountAddress address) { super(schema, receiveName); this.address = address; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java index 744bdf025..405508e8f 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java @@ -1,8 +1,10 @@ package com.concordium.sdk.smartcontract; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.parameters.ContractAddressParam; +import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; import lombok.Getter; import org.junit.Test; @@ -15,24 +17,28 @@ /** * Ensures correct serialization of {@link ContractAddress}. + * First test ensures correct serialization of parameters containing {@link AccountAddress}. + * Last tests ensures correct serialization when {@link ContractAddress} is passed directly as a parameter using the wrapper {@link ContractAddressParam}. */ public class ContractAddressTest { static Schema SCHEMA; + static String CONTRACT_NAME = "java_sdk_schema_unit_test"; + static { try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/testresources/smartcontractschema/unit-test.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } } @Test - public void shouldSerialize() { - ReceiveName receiveName = ReceiveName.from("java_sdk_schema_unit_test", "contract_address_test"); + public void shouldSerializeContainer() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "contract_address_container_test"); ContractAddress contractAddress = ContractAddress.from(1, 0); - ContractAddressParameter contractAddressContainer = new ContractAddressParameter(SCHEMA, receiveName, contractAddress); + ContractAddressContainer contractAddressContainer = new ContractAddressContainer(SCHEMA, receiveName, contractAddress); try { contractAddressContainer.initialize(); } catch (Exception e) { @@ -40,15 +46,28 @@ public void shouldSerialize() { } } + @Test + public void shouldSerialize() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "contract_address_test"); + ContractAddress contractAddress = ContractAddress.from(1, 0); + ContractAddressParam contractAddressParam = new ContractAddressParam(SCHEMA, receiveName, contractAddress); + try { + contractAddressParam.initialize(); + } catch (Exception e) { + fail(); + } + } + + /** - * Parameter containing only a ContractAddress. Is to ensure proper serialization of ContractAddress. + * Parameter containing only a {@link ContractAddress}. */ @Getter - public static class ContractAddressParameter extends SchemaParameter { + public static class ContractAddressContainer extends SchemaParameter { private final ContractAddress address; - public ContractAddressParameter(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { + public ContractAddressContainer(Schema schema, ReceiveName receiveName, ContractAddress contractAddress) { super(schema, receiveName); this.address = contractAddress; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java index b991d4cce..9c3dc2041 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java @@ -1,9 +1,8 @@ package com.concordium.sdk.smartcontract; -import com.concordium.sdk.transactions.InitName; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import lombok.Getter; @Getter diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java new file mode 100644 index 000000000..7be4246f0 --- /dev/null +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java @@ -0,0 +1,9 @@ +package com.concordium.sdk.smartcontract; + +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +/** + * Ensures correct serialization of {@link ListParam} + */ +public class ListParamTest { +} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java index 725453822..e633bee49 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/MintParams.java @@ -1,8 +1,8 @@ package com.concordium.sdk.smartcontract; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; -import com.concordium.sdk.transactions.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java index 14d6c0950..faa569126 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java @@ -2,7 +2,8 @@ import com.concordium.sdk.exceptions.CryptoJniException; import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.Schema; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; import lombok.SneakyThrows; @@ -18,7 +19,7 @@ import static org.junit.Assert.*; /** - * This test ensures correct serialization of {@link com.concordium.sdk.transactions.SchemaParameter}.

+ * This test ensures correct serialization of {@link SchemaParameter}.

* Specifically custom serialization of {@link com.concordium.sdk.types.AbstractAddress} is tested.

* Uses {@link MintParams} to model 'MintParams' in the cis2-nft example */ @@ -50,7 +51,7 @@ public class SerializeParameterTest { INCORRECT_TOKENS.add("2"); INCORRECT_TOKENS.add("321"); try { - SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin"))); + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/testresources/smartcontractschema/cis2-nft.schema.bin"))); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/unit-test.schema.bin deleted file mode 100644 index cfe7de4eab93aef253af754d15d4dc82ace6217f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcma)1!3x4K3~gscWgfSKpCjVktEUpXfK|3a($&wOX}9|pNZ`E}Uh<}CrjoxtH$bRzp I(>ayYAE^ji&j0`b diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java b/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java index e40dc6ff0..ba20c5c72 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java @@ -41,8 +41,14 @@ private void checkTooLargeNumber() { public void testSerializeDeserialize() { val expected = UInt8.from("250"); val bytes = expected.getBytes(); - val deserialized = UInt8.from(bytes); + val deserialized = UInt8.from(bytes[0]); assertEquals(expected, deserialized); assertNotEquals(expected, UInt8.from("42")); } + + @Test + public void testFromSignedByte() { + UInt8 from = UInt8.from((byte)-32); + assertEquals(UInt8.from(224), from); + } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin b/concordium-sdk/src/test/testresources/smartcontractschema/cis2-nft.schema.bin similarity index 100% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/cis2-nft.schema.bin rename to concordium-sdk/src/test/testresources/smartcontractschema/cis2-nft.schema.bin diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs similarity index 78% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs rename to concordium-sdk/src/test/testresources/smartcontractschema/lib.rs index ed674941e..db1279a15 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/lib.rs +++ b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs @@ -49,14 +49,29 @@ struct ContractAddressContainer { address: ContractAddress, } -/// Takes Address as parameter for ensuring correct serialization of Address +/// Takes AddressContainer as parameter for ensuring correct serialization of Address #[receive( contract = "java_sdk_schema_unit_test", - name = "abstract_address_test", + name = "abstract_address_container_test", parameter = "AbstractAddressContainer", error = "Error", mutable )] +fn abstract_address_container_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} + +/// Takes Address as parameter for ensuring correct serialization of Address when passed directly +#[receive( + contract = "java_sdk_schema_unit_test", + name = "abstract_address_test", + parameter = "Address", + error = "Error", + mutable +)] fn abstract_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, @@ -64,14 +79,28 @@ fn abstract_address_test( Ok(()) } -/// Takes a ContractAddress as parameter for ensuring correct serialization of ContractAddress +/// Takes a ContractAddressContainer as parameter for ensuring correct serialization of ContractAddress #[receive( contract = "java_sdk_schema_unit_test", - name = "contract_address_test", + name = "contract_address_container_test", parameter = "ContractAddressContainer", error = "Error", mutable )] +fn contract_address_container_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} +/// Takes Address as parameter for ensuring correct serialization of Address when passed directly +#[receive( + contract = "java_sdk_schema_unit_test", + name = "contract_address_test", + parameter = "ContractAddress", + error = "Error", + mutable +)] fn contract_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, @@ -79,43 +108,34 @@ fn contract_address_test( Ok(()) } -/// Takes an AccountAddress as parameter for ensuring correct serialization of AccountAddress +/// Takes an AccountAddressContainer as parameter for ensuring correct serialization of AccountAddress #[receive( contract = "java_sdk_schema_unit_test", - name = "account_address_test", + name = "account_address_container_test", parameter = "AccountAddressContainer", error = "Error", mutable )] -fn account_address_test( +fn account_address_container_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, ) -> Result<(), Error> { Ok(()) } -/// Receive function. The input parameter is the boolean variable `throw_error`. -/// If `throw_error == true`, the receive function will throw a custom error. -/// If `throw_error == false`, the receive function executes successfully. +/// Takes Address as parameter for ensuring correct serialization of Address when passed directly #[receive( contract = "java_sdk_schema_unit_test", - name = "receive", - parameter = "bool", + name = "account_address_test", + parameter = "AccountAddress", error = "Error", mutable )] -fn receive( +fn account_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, ) -> Result<(), Error> { - // Your code - - let throw_error = ctx.parameter_cursor().get()?; // Returns Error::ParseError on failure - if throw_error { - Err(Error::YourError) - } else { - Ok(()) - } + Ok(()) } /// View function that returns the content of the state. diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin b/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin new file mode 100644 index 0000000000000000000000000000000000000000..26ca42a32f27091c922039372ee083f0c600dbda GIT binary patch literal 586 zcmb_Y!3x4K4DIGXWgfSK7yXtY-o1J%u`4)bEhOFi{F&6<=AnXx6q3BWyu4{zWlE_% z#{)*t)IK$tyX`>_t_wO?3Tn;WBM00lAef+`ZP5~G<6VHxS&X=%Qo<$Z8BphQ-WcNt z7c%LW8~#o_DO9nti@1`@7eKQ7K~MRX^Q#~5jOa11Ia}-(b;Tc-9AwEyYVwU`g81qS gZ`7VLEY6G3KRKUj>4G@QN|`QL*4WusCdcu60~hU Date: Fri, 15 Sep 2023 17:50:42 +0200 Subject: [PATCH 15/53] Added tests for ListParam --- .../smartcontracts/parameters/ListParam.java | 4 +- .../java/com/concordium/sdk/types/UInt8.java | 15 +++++++ .../sdk/smartcontract/ListParamTest.java | 40 +++++++++++++++++- .../smartcontract/SerializeParameterTest.java | 1 - .../testresources/smartcontractschema/lib.rs | 23 ++++++++++ .../smartcontractschema/unit-test.schema.bin | Bin 586 -> 644 bytes 6 files changed, 79 insertions(+), 4 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java index 9726ec2c4..4594c452a 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -15,8 +15,8 @@ import java.util.List; /** - * Wrapper for passing lists as smart contract parameters. - * Contents of the list must be serializable according to the provided {@link Schema}. + * Wrapper for passing lists as smart contract parameters.

+ * Contents of the list must be serializable according to the provided {@link Schema}.

*/ @Getter @JsonSerialize(using = ListParam.ListParamSerializer.class) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java index 168cc6d51..6ca5a4807 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -1,11 +1,18 @@ package com.concordium.sdk.types; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.val; +import java.io.IOException; + @EqualsAndHashCode @Getter +@JsonSerialize(using = UInt8.UInt8Serializer.class) public class UInt8 { private final int value; @@ -38,5 +45,13 @@ public static UInt8 from(byte b) { return new UInt8(b & 0xff); } + @Override public String toString() {return String.valueOf(value);} + + public static class UInt8Serializer extends JsonSerializer { + @Override + public void serialize(UInt8 uInt8, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + jsonGenerator.writeNumber(uInt8.getValue()); + } + } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java index 7be4246f0..1822d2ff3 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java @@ -1,9 +1,47 @@ package com.concordium.sdk.smartcontract; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; +import com.concordium.sdk.types.ContractAddress; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.fail; /** - * Ensures correct serialization of {@link ListParam} + * Ensures correct serialization of {@link ListParam}. */ public class ListParamTest { + + static Schema SCHEMA; + static String CONTRACT_NAME = "java_sdk_schema_unit_test"; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get("./src/test/testresources/smartcontractschema/unit-test.schema.bin"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void shouldSerialize() { + ReceiveName receiveName = ReceiveName.from(CONTRACT_NAME, "list_param_test"); + List list = new ArrayList<>(); + list.add(ContractAddress.from(1, 0)); + list.add(ContractAddress.from(2, 0)); + SchemaParameter parameter = new ListParam(SCHEMA, receiveName, list); + try { + parameter.initialize(true); + } catch (Exception e) { + fail(); + } + } } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java index faa569126..df2b05fae 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeParameterTest.java @@ -20,7 +20,6 @@ /** * This test ensures correct serialization of {@link SchemaParameter}.

- * Specifically custom serialization of {@link com.concordium.sdk.types.AbstractAddress} is tested.

* Uses {@link MintParams} to model 'MintParams' in the cis2-nft example */ public class SerializeParameterTest { diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs index db1279a15..57a9dfb57 100644 --- a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs +++ b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs @@ -31,6 +31,14 @@ fn init( Ok(State {}) } +// +#[derive(Serialize, SchemaType)] +#[concordium(transparent)] +struct ListParam ( + Vec +); + + #[derive(Serialize, SchemaType)] struct AbstractAddressContainer { /// The amount of tokens to unwrap. @@ -49,6 +57,21 @@ struct ContractAddressContainer { address: ContractAddress, } +/// Takes ListParam as parameter for ensuring correct serialization of ListParam +#[receive( + contract = "java_sdk_schema_unit_test", + name = "list_param_test", + parameter = "ListParam", + error = "Error", + mutable +)] +fn list_param_test( + ctx: &impl HasReceiveContext, + _host: &mut impl HasHost, +) -> Result<(), Error> { + Ok(()) +} + /// Takes AddressContainer as parameter for ensuring correct serialization of Address #[receive( contract = "java_sdk_schema_unit_test", diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin b/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin index 26ca42a32f27091c922039372ee083f0c600dbda..c3ffaf3bd5085d5ecf188cc82aa52c751a4af2fb 100644 GIT binary patch delta 44 zcmX@b(!x4Hm62nknh29PKLZ0pPG)gQd_iJSVs3m%YH Date: Wed, 20 Sep 2023 11:16:08 +0200 Subject: [PATCH 16/53] renaming --- .../transactions/smartcontracts/parameters/ListParam.java | 6 +++--- ...ctAddressTest.java => SerializeAbstractAddressTest.java} | 2 +- ...untAddressTest.java => SerializeAccountAddressTest.java} | 2 +- ...ctAddressTest.java => SerializeContractAddressTest.java} | 2 +- .../{ListParamTest.java => SerializeListParamTest.java} | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/{AbstractAddressTest.java => SerializeAbstractAddressTest.java} (98%) rename concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/{AccountAddressTest.java => SerializeAccountAddressTest.java} (98%) rename concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/{ContractAddressTest.java => SerializeContractAddressTest.java} (98%) rename concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/{ListParamTest.java => SerializeListParamTest.java} (97%) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java index 4594c452a..aea3d9865 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -22,14 +22,14 @@ @JsonSerialize(using = ListParam.ListParamSerializer.class) public class ListParam extends SchemaParameter { - private final List list; + private final List list; - public ListParam(Schema schema, InitName initName, List list) { + public ListParam(Schema schema, InitName initName, List list) { super(schema, initName); this.list = list; } - public ListParam(Schema schema, ReceiveName receiveName, List list) { + public ListParam(Schema schema, ReceiveName receiveName, List list) { super(schema, receiveName); this.list = list; } diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAbstractAddressTest.java similarity index 98% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java rename to concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAbstractAddressTest.java index 1b75c7fd6..4ac43ddd4 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AbstractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAbstractAddressTest.java @@ -22,7 +22,7 @@ * First 2 tests ensures correct serialization of parameters containing {@link AbstractAddress}. * Last 2 tests ensures correct serialization when {@link AbstractAddress} is passed directly as a parameter using the wrapper {@link AddressParam}. */ -public class AbstractAddressTest { +public class SerializeAbstractAddressTest { static Schema SCHEMA; static String CONTRACT_NAME = "java_sdk_schema_unit_test"; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAccountAddressTest.java similarity index 98% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java rename to concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAccountAddressTest.java index a8eda28fd..745909cc2 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/AccountAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeAccountAddressTest.java @@ -19,7 +19,7 @@ * First test ensures correct serialization of parameters containing {@link AccountAddress}. * Last tests ensures correct serialization when {@link AccountAddress} is passed directly as a parameter using the wrapper {@link AccountAddressParam}. */ -public class AccountAddressTest { +public class SerializeAccountAddressTest { static Schema SCHEMA; static String CONTRACT_NAME = "java_sdk_schema_unit_test"; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeContractAddressTest.java similarity index 98% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java rename to concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeContractAddressTest.java index 405508e8f..79300937e 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ContractAddressTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeContractAddressTest.java @@ -20,7 +20,7 @@ * First test ensures correct serialization of parameters containing {@link AccountAddress}. * Last tests ensures correct serialization when {@link ContractAddress} is passed directly as a parameter using the wrapper {@link ContractAddressParam}. */ -public class ContractAddressTest { +public class SerializeContractAddressTest { static Schema SCHEMA; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java similarity index 97% rename from concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java rename to concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java index 1822d2ff3..8e657f055 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/ListParamTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java @@ -18,7 +18,7 @@ /** * Ensures correct serialization of {@link ListParam}. */ -public class ListParamTest { +public class SerializeListParamTest { static Schema SCHEMA; static String CONTRACT_NAME = "java_sdk_schema_unit_test"; From 7ae2329de1d7229522d7027efc91c15a5d4a7381 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 20 Sep 2023 13:41:37 +0200 Subject: [PATCH 17/53] ListParam made abstract --- .../smartcontracts/parameters/ListParam.java | 2 +- .../sdk/smartcontract/SerializeListParamTest.java | 8 +++++++- crypto-jni/Cargo.lock | 14 +++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java index aea3d9865..71a40987e 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -20,7 +20,7 @@ */ @Getter @JsonSerialize(using = ListParam.ListParamSerializer.class) -public class ListParam extends SchemaParameter { +public abstract class ListParam extends SchemaParameter { private final List list; diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java index 8e657f055..de9807450 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/SerializeListParamTest.java @@ -37,11 +37,17 @@ public void shouldSerialize() { List list = new ArrayList<>(); list.add(ContractAddress.from(1, 0)); list.add(ContractAddress.from(2, 0)); - SchemaParameter parameter = new ListParam(SCHEMA, receiveName, list); + SchemaParameter parameter = new ContractListParam(SCHEMA, receiveName, list); try { parameter.initialize(true); } catch (Exception e) { fail(); } } + + private static class ContractListParam extends ListParam { + public ContractListParam(Schema schema, ReceiveName receiveName, List list) { + super(schema, receiveName, list); + } + } } diff --git a/crypto-jni/Cargo.lock b/crypto-jni/Cargo.lock index 54d2f8517..79920497c 100644 --- a/crypto-jni/Cargo.lock +++ b/crypto-jni/Cargo.lock @@ -1116,22 +1116,22 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.175" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.175" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.32", ] [[package]] @@ -1204,9 +1204,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.27" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", From b20e27140ef803961586dbc5b84fd4055f8c3348 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 20 Sep 2023 14:18:29 +0200 Subject: [PATCH 18/53] Skeleton for example. All parameters (except a few wrappers needed for wrapCCD) implemented and initializes correctly --- .../cis2nft/BalanceOfQuery.java | 16 +++ .../cis2nft/Cis2NftExample.java | 121 ++++++++++++++++++ .../contractexample/cis2nft/MintParams.java | 34 +++++ .../cis2nft/NftBalanceOfQuery.java | 13 ++ .../cis2nft/NftMetaDataQuery.java | 16 +++ .../contractexample/cis2nft/NftTransfer.java | 16 +++ .../cis2nft/OperatorOfQuery.java | 16 +++ .../contractexample/cis2nft/Receiver.java | 68 ++++++++++ .../cis2nft/SetImplementorsParams.java | 33 +++++ .../contractexample/cis2nft/TokenAmount.java | 7 + .../cis2nft/TokenAmountU8.java | 33 +++++ .../contractexample/cis2nft/TokenId.java | 7 + .../contractexample/cis2nft/TokenIdU32.java | 34 +++++ .../contractexample/cis2nft/Transfer.java | 24 ++++ .../cis2nft/UpdateOperator.java | 47 +++++++ .../cis2nft/cis2-nft.schema.bin | Bin 0 -> 2975 bytes .../contractexample/wccd/AddressParam.java | 46 +++++++ .../wccd/SetMetadataUrlParams.java | 57 +++++++++ .../contractexample/wccd/SetPausedParams.java | 16 +++ .../contractexample/wccd/UnwrapParams.java | 33 +++++ .../contractexample/wccd/UpgradeParams.java | 48 +++++++ .../contractexample/wccd/WCCDExample.java | 102 +++++++++++++++ .../contractexample/wccd/WrapParams.java | 24 ++++ .../contractexample/wccd/cis2-wccd.schema.bin | Bin 0 -> 6262 bytes 24 files changed, 811 insertions(+) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/AddressParam.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java new file mode 100644 index 000000000..b1ece595c --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class BalanceOfQuery { + @JsonProperty("token_id") + private T tokenId; + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress address; +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java new file mode 100644 index 000000000..c2ba07524 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java @@ -0,0 +1,121 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; +import com.concordium.sdk.types.*; +import lombok.SneakyThrows; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class Cis2NftExample { + + @SneakyThrows + public static void main(String[] args) { + AccountAddress accountAddress = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + ContractAddress contractAddress1 = ContractAddress.from(1, 0); + ContractAddress contractAddress2 = ContractAddress.from(2, 0); + Schema cis2nftSchema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + String cis2nftContractName = "cis2_nft"; + + // Initialize MintParams + + ReceiveName mintParamsReceiveName = ReceiveName.from(cis2nftContractName, "mint"); + List tokens = new ArrayList<>(); + tokens.add(TokenIdU32.from(12)); + tokens.add(TokenIdU32.from(22)); + tokens.add(TokenIdU32.from(2132)); + SchemaParameter mintParameter = new MintParams(cis2nftSchema, mintParamsReceiveName, accountAddress, tokens); + mintParameter.initialize(true); + + + // Initialize TransferParameter + ReceiveName nftTransferReceiveName = ReceiveName.from(cis2nftContractName, "transfer"); + TokenIdU32 tokenId = TokenIdU32.from(12); + TokenAmountU8 amount = TokenAmountU8.from(1); + AbstractAddress from = contractAddress1; + Receiver to = new Receiver(contractAddress2, "mint"); + List data = new ArrayList<>(); + data.add(UInt8.from(123)); + data.add(UInt8.from(23)); + NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); + List transfers = new ArrayList<>(); + transfers.add(transfer); + SchemaParameter transferParameter = new ListParam(cis2nftSchema, nftTransferReceiveName, transfers); + transferParameter.initialize(true); + + + // Initialize UpdateOperatorParams + + ReceiveName updateOperatorReceiveName = ReceiveName.from(cis2nftContractName, "updateOperator"); + UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, accountAddress); + UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, contractAddress1); + List updateOperatorList = new ArrayList<>(); + updateOperatorList.add(update1); + updateOperatorList.add(update2); + SchemaParameter updateOperatorsParams = new ListParam(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); + updateOperatorsParams.initialize(true); + + + // Initialize OperatorOfQueryParams + + ReceiveName operatorOfReceiveName = ReceiveName.from(cis2nftContractName, "operatorOf"); + OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(accountAddress, contractAddress1); + OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(contractAddress1, contractAddress2); + List operatorOfQueries = new ArrayList<>(); + operatorOfQueries.add(operatorOfQuery1); + operatorOfQueries.add(operatorOfQuery2); + SchemaParameter operatorOfQueryParams = new ListParam(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); + operatorOfQueryParams.initialize(true); + + + // Initialize ContractBalanceOfQueryParams + + ReceiveName balanceOfReceiveName = ReceiveName.from(cis2nftContractName, "balanceOf"); + NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), accountAddress); + NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), contractAddress1); + List balanceOfQueries = new ArrayList<>(); + balanceOfQueries.add(balanceOfQuery1); + balanceOfQueries.add(balanceOfQuery2); + SchemaParameter contractBalanceOfQueryParams = new ListParam(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); + contractBalanceOfQueryParams.initialize(true); + + // Initialize ContractTokenMetadataQueryParams + + ReceiveName tokenMetadataReceiveName = ReceiveName.from(cis2nftContractName, "tokenMetadata"); + TokenIdU32 token1 = TokenIdU32.from(21); + TokenIdU32 token2 = TokenIdU32.from(22); + List tokensForMetadataQuery = new ArrayList<>(); + tokensForMetadataQuery.add(token1); + tokensForMetadataQuery.add(token2); + SchemaParameter nftMetaDataQuery = new NftMetaDataQuery(cis2nftSchema, tokenMetadataReceiveName, tokensForMetadataQuery); + nftMetaDataQuery.initialize(true); + + // Initialize SupportsQueryParams + + ReceiveName supportsReceiveName = ReceiveName.from(cis2nftContractName, "supports"); + String standardIdentifier1 = "identifier1"; + String standardIdentifier2 = "identifier2"; + List identifiers = new ArrayList<>(); + identifiers.add(standardIdentifier1); + identifiers.add(standardIdentifier2); + SchemaParameter supportsQueryParams = new ListParam(cis2nftSchema, supportsReceiveName, identifiers); + supportsQueryParams.initialize(true); + + // Initialize SetImplementorsParams + + ReceiveName setImplementorsReceiveName = ReceiveName.from(cis2nftContractName, "setImplementors"); + List implementors = new ArrayList<>(); + String identifier = "IdentifierID"; + implementors.add(contractAddress1); + implementors.add(contractAddress2); + SchemaParameter setImplementorsParams = new SetImplementorsParams(cis2nftSchema, setImplementorsReceiveName, identifier, implementors); + setImplementorsParams.initialize(); + + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java new file mode 100644 index 000000000..b6792c1cb --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java @@ -0,0 +1,34 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.util.List; + +/** + * Represents the parameter 'MintParams' in the cis2-nft example + * Used with contract function 'mint' which mints a number of tokens to a given {@link AbstractAddress}. + */ +@Getter +public class MintParams extends SchemaParameter { + + /** + * Owner of the newly minted tokens. + */ + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private final AbstractAddress owner; + /** + * A collection of tokens to mint. + */ + private final List tokens; + + public MintParams(Schema schema, ReceiveName receiveName, AbstractAddress owner, List tokens) { + super(schema, receiveName); + this.owner = owner; + this.tokens = tokens; + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java new file mode 100644 index 000000000..981db4feb --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; + +/** + * Wrapper class for {@link BalanceOfQuery} enforcing the correct Token id for cis2-nft contract. + */ +public class NftBalanceOfQuery extends BalanceOfQuery { + + public NftBalanceOfQuery(TokenIdU32 tokenId, AbstractAddress address) { + super(tokenId, address); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java new file mode 100644 index 000000000..f2c442b17 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +/** + * Wrapper class for {@link ListParam} enforcing the correct Token id for cis2-nft contract. + */ +public class NftMetaDataQuery extends ListParam { + public NftMetaDataQuery(Schema cis2nftSchema, ReceiveName tokenMetadataReceiveName, List tokensForMetadataQuery) { + super(cis2nftSchema, tokenMetadataReceiveName, tokensForMetadataQuery); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java new file mode 100644 index 000000000..2f974dc40 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.UInt8; + +import java.util.List; + +/** + * Wrapper class for {@link Transfer} enforcing the correct Token amount/id for cis2-nft contract. + */ +public class NftTransfer extends Transfer { + + public NftTransfer(TokenIdU32 tokenId, TokenAmountU8 amount, AbstractAddress from, Receiver to, List data) { + super(tokenId, amount, from, to, data); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java new file mode 100644 index 000000000..41503c908 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class OperatorOfQuery { + + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress owner; + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress address; +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java new file mode 100644 index 000000000..332be94e1 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java @@ -0,0 +1,68 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.AccountType; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +@JsonSerialize(using = Receiver.ReceiverSerializer.class) +@Getter +public class Receiver { + + private final AccountType type; + private AccountAddress accountAddress; + private ContractAddress contractAddress; + private String ownedEntrypointName; + + public Receiver(AccountAddress accountAddress) { + this.type = AccountType.ADDRESS_ACCOUNT; + this.accountAddress = accountAddress; + } + + public Receiver(ContractAddress contractAddress, String ownedEntrypointName) { + this.type = AccountType.ADDRESS_CONTRACT; + this.contractAddress = contractAddress; + this.ownedEntrypointName = ownedEntrypointName; + } + + public static class ReceiverSerializer extends JsonSerializer { + @Override + public void serialize(Receiver receiver, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + switch (receiver.getType()) { + case ADDRESS_ACCOUNT: + jsonGenerator.writeStartObject(); + + jsonGenerator.writeFieldName("Account"); + + jsonGenerator.writeStartArray(); + + jsonGenerator.writeObject(receiver.getAccountAddress()); + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndObject(); + break; + case ADDRESS_CONTRACT: + jsonGenerator.writeStartObject(); + + jsonGenerator.writeFieldName("Contract"); + + jsonGenerator.writeStartArray(); + + jsonGenerator.writeObject(receiver.getContractAddress()); + jsonGenerator.writeString(receiver.getOwnedEntrypointName()); + + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndObject(); + + break; + } + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java new file mode 100644 index 000000000..0886f9842 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java @@ -0,0 +1,33 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.ContractAddress; +import lombok.Getter; + +import java.util.List; + +/** + * Represents the parameter 'SetImplementorsParams' in the cis2-nft example + * Used with contract function 'setImplementors' + * Takes a standard identifier and list of contract addresses providing implementations of this standard. + */ +@Getter +public class SetImplementorsParams extends SchemaParameter { + + /** + * The identifier for the standard + */ + private final String id; + /** + * The addresses of the implementors of the standard. + */ + private final List implementors; + + public SetImplementorsParams(Schema schema, ReceiveName receiveName, String id, List implementors) { + super(schema, receiveName); + this.id = id; + this.implementors = implementors; + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java new file mode 100644 index 000000000..377322ba2 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java @@ -0,0 +1,7 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +/** + * Tagging interface for identifying token amounts + */ +public interface TokenAmount { +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java new file mode 100644 index 000000000..958eb5989 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java @@ -0,0 +1,33 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.UInt8; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +@Getter +@JsonSerialize(using = TokenAmountU8.TokenAmountU8Serializer.class) +public class TokenAmountU8 implements TokenAmount { + + private final UInt8 amount; + + private TokenAmountU8(UInt8 amount) { + this.amount = amount; + } + + public static TokenAmountU8 from(int value) { + return new TokenAmountU8(UInt8.from(value)); + } + + public static class TokenAmountU8Serializer extends JsonSerializer { + + @Override + public void serialize(TokenAmountU8 value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getAmount().toString()); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java new file mode 100644 index 000000000..2ed4be5de --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java @@ -0,0 +1,7 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +/** + * Tagging interface for identifying tokenIds + */ +public interface TokenId { +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java new file mode 100644 index 000000000..bf950d46f --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java @@ -0,0 +1,34 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.UInt32; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import org.apache.commons.codec.binary.Hex; + +import java.io.IOException; + +@Getter +@JsonSerialize(using = TokenIdU32.TokenIdU32Serializer.class) +public class TokenIdU32 implements TokenId { + + private final UInt32 id; + + private TokenIdU32(UInt32 id) { + this.id = id; + } + + public static TokenIdU32 from(int value) { + //if (Integer.toString(value).length() % 2 != 0) {throw new IllegalArgumentException("TokenIdU32 must be odd number of digits");} + return new TokenIdU32(UInt32.from(value)); + } + + public static class TokenIdU32Serializer extends JsonSerializer { + @Override + public void serialize(TokenIdU32 value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(Hex.encodeHexString(value.getId().getBytes())); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java new file mode 100644 index 000000000..ebd06c436 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java @@ -0,0 +1,24 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.UInt8; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class Transfer { + @JsonProperty("token_id") + private T tokenId; + private A amount; + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress from; + private Receiver to; + private List data; + + +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java new file mode 100644 index 000000000..08f485016 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java @@ -0,0 +1,47 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.types.AbstractAddress; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.IOException; + +@Getter +@AllArgsConstructor +public class UpdateOperator { + + private OperatorUpdate update; + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private AbstractAddress operator; + + + @JsonSerialize(using = OperatorUpdate.OperatorUpdateSerializer.class) + public enum OperatorUpdate { + @JsonProperty("Remove") + REMOVE, + @JsonProperty("Add") + ADD; + + public static class OperatorUpdateSerializer extends JsonSerializer { + @Override + public void serialize(OperatorUpdate operatorUpdate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + switch (operatorUpdate) { + case REMOVE: + jsonGenerator.writeStringField("Remove", ""); + break; + case ADD: + jsonGenerator.writeStringField("Add", ""); + break; + } + jsonGenerator.writeEndObject(); + } + } + } + +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8eb4f344c08d906a8d4505ef4d9559c4f42dd2 GIT binary patch literal 2975 zcmdT`U2oGc6m`5ZK2}&J*1n(uFZ==i!8UDDCAuNjJy#}nXhdvRw$m~GIv?d8CzXnX zMp|hPd2kfpYhB-aa_+fVt@aYe*b`b=;or|p9@tabV0{*)Fqyi__tWH<@#a{tUzM2^ za>O2!MM&wC_XBvbKglv%nUEmp0ivE+6P(CuOFvCsy(8nGM~@e@#%3wXLQWBLEcsD1 z`6|zgtWYLgR7QHd{>h1li{rL!RmO=;1TT)XnhpUD|!g+Igm% zk#PjhAF)yQ%72D>7s`oX-3A@DhG8ehB%Nc+A;INU80$r;G||{P-w+3FQph0#rHc)B z%KM$G65Z{q#lpJaNg;+TO$K{pgLGWl>)I3haQzNX^L~04TQ_ChtNS@s5qo)}f{-Ez zDt<)8*U|t4Dpw8@NXA_Fd6WojF0D~fNUp6`vHI6<$=u2BPLghXu3QggLk2*G2uhp` zkUOC<2%_Ah`rKLFRxQyb!L~S!gZ&z6e26sRokJ5-uv$>|>Z%dgh$$)qinS|3f$b-y z?NV`&>_kcq)YrP)0xk^Y?)4kkvn { + @Override + public void serialize(AddressParam addressParam, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + switch (addressParam.getAddress().getType()) { + case ADDRESS_ACCOUNT: + jsonGenerator.writeFieldName("Account"); + + break; + case ADDRESS_CONTRACT: + jsonGenerator.writeFieldName("Contract"); + break; + } + jsonGenerator.writeStartArray(); + jsonGenerator.writeObject(addressParam.getAddress()); + jsonGenerator.writeEndArray(); + jsonGenerator.writeEndObject(); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java new file mode 100644 index 000000000..cbf895aa0 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java @@ -0,0 +1,57 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.transactions.Hash; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.Bytes; +import lombok.Getter; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +@Getter +public class SetMetadataUrlParams extends SchemaParameter { + + private final String url; + + @JsonSerialize(using = SetMetadataUrlParamsHashSerializer.class) + private final Optional hash; + public SetMetadataUrlParams(Schema schema, ReceiveName receiveName, String url, Optional hash) { + super(schema, receiveName); + this.url = url; + this.hash = hash; + } + + public static class SetMetadataUrlParamsHashSerializer extends JsonSerializer> { + @Override + public void serialize(Optional hash, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + if (hash.isPresent()) { + jsonGenerator.writeFieldName("Some"); + jsonGenerator.writeStartArray(); + + jsonGenerator.writeStartArray(); + List bytes = Bytes.asList(hash.get().getBytes()); + bytes.forEach(b -> { + try { + jsonGenerator.writeNumber(Byte.toUnsignedInt(b)); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndArray(); + } else { + jsonGenerator.writeStringField("None", ""); + } + jsonGenerator.writeEndObject(); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java new file mode 100644 index 000000000..02daead5c --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import lombok.Getter; + +@Getter +public class SetPausedParams extends SchemaParameter { + + private final boolean paused; + public SetPausedParams(Schema schema, ReceiveName receiveName, boolean paused) { + super(schema, receiveName); + this.paused = paused; + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java new file mode 100644 index 000000000..1c5409f91 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java @@ -0,0 +1,33 @@ +package com.concordium.sdk.examples.contractexample.wccd; + + +import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.UInt8; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.util.List; + +@Getter +public class UnwrapParams extends SchemaParameter { + + private final String amount; + @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) + private final AbstractAddress owner; + private final Receiver receiver; + private final List data; + + + + public UnwrapParams(Schema schema, ReceiveName receiveName, String amount, AbstractAddress owner, Receiver receiver, List data) { + super(schema, receiveName); + this.amount = amount; + this.owner = owner; + this.receiver = receiver; + this.data = data; + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java new file mode 100644 index 000000000..a087015b6 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java @@ -0,0 +1,48 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import org.apache.commons.codec.binary.Hex; + +import java.io.IOException; + +@Getter +public class UpgradeParams extends SchemaParameter { + + private final String module; + + @JsonSerialize(using = MigrateSerializer.class) + private final SchemaParameter migrate; // Hex encode bytes , ReceiveName fås fra schemaparam, optional schema parameter + + public UpgradeParams(Schema schema, ReceiveName receiveName, String module, SchemaParameter migrate) { + super(schema, receiveName); + this.module = module; + migrate.initialize(true); + this.migrate = migrate; + } + + public static class MigrateSerializer extends JsonSerializer { + @Override + public void serialize(SchemaParameter migrate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeFieldName("Some"); + + jsonGenerator.writeStartArray(); + + jsonGenerator.writeStartArray(); + jsonGenerator.writeString(migrate.getReceiveName().getMethod()); + jsonGenerator.writeString(Hex.encodeHexString(migrate.toBytes())); + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndArray(); + jsonGenerator.writeEndObject(); + + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java new file mode 100644 index 000000000..c84c49904 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java @@ -0,0 +1,102 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; +import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.transactions.Hash; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.concordium.sdk.types.UInt8; +import lombok.SneakyThrows; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class WCCDExample { + + @SneakyThrows + public static void main(String[] args) { + AccountAddress accountAddress = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + ContractAddress contractAddress1 = ContractAddress.from(1, 0); + ContractAddress contractAddress2 = ContractAddress.from(2, 0); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/contractexample/wccd/cis2-wccd.schema.bin")), SchemaVersion.V3); + String cis2wccdContractName = "cis2_wCCD"; + + // Initialize UnwrapParams + + ReceiveName unwrapReceiveName = ReceiveName.from(cis2wccdContractName, "unwrap"); + String unwrapAmount = "2"; // TokenAmountU64 + Receiver unwrapReceiver = new Receiver(contractAddress2, "test"); + List unwrapData = new ArrayList<>(); + unwrapData.add(UInt8.from(1)); + unwrapData.add(UInt8.from(42)); + UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, accountAddress, unwrapReceiver, unwrapData); + unwrapParams.initialize(true); + + // Initialize WrapParams + + ReceiveName wrapReceiveName = ReceiveName.from(cis2wccdContractName, "wrap"); + Receiver wrapReceiver = new Receiver(accountAddress); + List wrapData = new ArrayList<>(); + WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); + wrapParams.initialize(true); + + // Initialize SetImplementorsParams + // Already exists and works + + // Initialize UpgradeParams + ReceiveName upgradeReceiveName = ReceiveName.from(cis2wccdContractName, "upgrade"); + ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); + SchemaParameter migrate = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); + UpgradeParams upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef.toString(), migrate); + upgradeParams.initialize(true); + + + // Initialize SetMetadataUrlParams + ReceiveName setMetadataUrlReceiveName = ReceiveName.from(cis2wccdContractName, "setMetadataUrl"); + String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; + Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); + SetMetadataUrlParams setMetadataUrlParams1 = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.of(hash)); + SetMetadataUrlParams setMetadataUrlParams2 = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.empty()); + setMetadataUrlParams1.initialize(true); + setMetadataUrlParams2.initialize(true); + + + // Initialize SetPausedParams + ReceiveName setPausedReceiveName = ReceiveName.from(cis2wccdContractName, "setPaused"); + SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); + setPausedParams.initialize(true); + + // Initialize Address as UpdateAdminParam + ReceiveName updateAdmninReceiveName = ReceiveName.from(cis2wccdContractName, "updateAdmin"); + AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, contractAddress1); + AddressParam updateAdminParam2 = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, accountAddress); + updateAdminParam.initialize(true); + updateAdminParam2.initialize(true); + + // Initialize TransferParameter + // Is done since no wrapper types are used e.g. no constraints on 'amount' and 'token_id' is being enforced + + // Initialize UpdateOperatorParams + // Is done + + // Initialize ContractBalanceOfQueryParams + // Same as TransferParameter + + // Initialize OperatorOfQueryParams + // Is done + + // Initialize ContractTokenMetadataQueryParams + // Same as TransferParameter + + // Initialize SupportsQueryParams + // Is done + + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java new file mode 100644 index 000000000..19a1f1e9f --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java @@ -0,0 +1,24 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.UInt8; +import lombok.Getter; + +import java.util.List; + +@Getter +public class WrapParams extends SchemaParameter { + + private final Receiver to; + private final List data; + + + public WrapParams(Schema schema, ReceiveName receiveName, Receiver to, List data) { + super(schema, receiveName); + this.to = to; + this.data = data; + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin new file mode 100644 index 0000000000000000000000000000000000000000..9e0441b684b5820f389c8ba21704962f0256d4ec GIT binary patch literal 6262 zcmeHL+iuf95VhTuTMG?plLw&C7k+?0Xakihk+z}@uhEj-v@7ggYj>Rpew|C1Gqyzn zDvB%e<_Aaicsrh+*_m@@Z*Df?D2g7^HPQafcs>}sjibFNA;Sh;g-iQMhiLZ?cO@+&8#8fx#gxf)toq$+uF%j?>C z0vMM5eq?-+=hg)!OCKMV^V*u^5v{bjaw1r_kc&;2=SI0zvAxB?~Zt)%SQ)-5-5n&g({P-)MsQ zV?vOXOWipL_;k7IO3zl(v2FT(4;puv zBrqctIcPe?}gUA5>;%Dgpf;N|~S@ z>RGSN&Kibk48cV?uvdcvvXJr6&diPlnWl+8C{6&n+}{T!JNSZpb4$I%aNvP*uV^(RRiFdj<#A2xBf#Yq_5(AbTVA6;95WI@hj|m7R#q<&aBO& zHwHqZ=Ho^s^bJE0AGOv)5a)4OiT|hK`VJZ#G1t{J$aRl@r)0<5DDX}ivMFc&z Date: Wed, 20 Sep 2023 14:47:22 +0200 Subject: [PATCH 19/53] ListParam is now abstract and needs wrapper --- .../contractexample/cis2nft/Cis2NftExample.java | 11 +++++------ .../cis2nft/NftBalanceOfQueryParams.java | 13 +++++++++++++ .../cis2nft/NftOperatorOfQueryParams.java | 13 +++++++++++++ .../cis2nft/NftSupportsQueryParams.java | 13 +++++++++++++ .../contractexample/cis2nft/NftTransferParam.java | 13 +++++++++++++ .../cis2nft/NftUpdateOperatorParams.java | 13 +++++++++++++ 6 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java index c2ba07524..9fee2a608 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java @@ -4,7 +4,6 @@ import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; -import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; import com.concordium.sdk.types.*; import lombok.SneakyThrows; @@ -46,7 +45,7 @@ public static void main(String[] args) { NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); List transfers = new ArrayList<>(); transfers.add(transfer); - SchemaParameter transferParameter = new ListParam(cis2nftSchema, nftTransferReceiveName, transfers); + SchemaParameter transferParameter = new NftTransferParam(cis2nftSchema, nftTransferReceiveName, transfers); transferParameter.initialize(true); @@ -58,7 +57,7 @@ public static void main(String[] args) { List updateOperatorList = new ArrayList<>(); updateOperatorList.add(update1); updateOperatorList.add(update2); - SchemaParameter updateOperatorsParams = new ListParam(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); + SchemaParameter updateOperatorsParams = new NftUpdateOperatorParams(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); updateOperatorsParams.initialize(true); @@ -70,7 +69,7 @@ public static void main(String[] args) { List operatorOfQueries = new ArrayList<>(); operatorOfQueries.add(operatorOfQuery1); operatorOfQueries.add(operatorOfQuery2); - SchemaParameter operatorOfQueryParams = new ListParam(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); + SchemaParameter operatorOfQueryParams = new NftOperatorOfQueryParams(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); operatorOfQueryParams.initialize(true); @@ -82,7 +81,7 @@ public static void main(String[] args) { List balanceOfQueries = new ArrayList<>(); balanceOfQueries.add(balanceOfQuery1); balanceOfQueries.add(balanceOfQuery2); - SchemaParameter contractBalanceOfQueryParams = new ListParam(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); + SchemaParameter contractBalanceOfQueryParams = new NftBalanceOfQueryParams(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); contractBalanceOfQueryParams.initialize(true); // Initialize ContractTokenMetadataQueryParams @@ -104,7 +103,7 @@ public static void main(String[] args) { List identifiers = new ArrayList<>(); identifiers.add(standardIdentifier1); identifiers.add(standardIdentifier2); - SchemaParameter supportsQueryParams = new ListParam(cis2nftSchema, supportsReceiveName, identifiers); + SchemaParameter supportsQueryParams = new NftSupportsQueryParams(cis2nftSchema, supportsReceiveName, identifiers); supportsQueryParams.initialize(true); // Initialize SetImplementorsParams diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java new file mode 100644 index 000000000..e02232e7f --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class NftBalanceOfQueryParams extends ListParam { + public NftBalanceOfQueryParams(Schema cis2nftSchema, ReceiveName balanceOfReceiveName, List balanceOfQueries) { + super(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java new file mode 100644 index 000000000..13a3e2b4e --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class NftOperatorOfQueryParams extends ListParam { + public NftOperatorOfQueryParams(Schema cis2nftSchema, ReceiveName operatorOfReceiveName, List operatorOfQueries) { + super(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java new file mode 100644 index 000000000..930f33bad --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class NftSupportsQueryParams extends ListParam { + public NftSupportsQueryParams(Schema cis2nftSchema, ReceiveName supportsReceiveName, List identifiers) { + super(cis2nftSchema, supportsReceiveName, identifiers); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java new file mode 100644 index 000000000..8cefcc7c0 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class NftTransferParam extends ListParam { + public NftTransferParam(Schema cis2nftSchema, ReceiveName nftTransferReceiveName, List transfers) { + super(cis2nftSchema, nftTransferReceiveName, transfers); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java new file mode 100644 index 000000000..30946db18 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class NftUpdateOperatorParams extends ListParam { + public NftUpdateOperatorParams(Schema cis2nftSchema, ReceiveName updateOperatorReceiveName, List updateOperatorList) { + super(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); + } +} From b81599fcd4ccbf18f039e1c0edf7c532e60caa17 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 20 Sep 2023 15:17:03 +0200 Subject: [PATCH 20/53] renaming --- .../examples/contractexample/cis2nft/Cis2NftExample.java | 6 +++--- ...peratorOfQueryParams.java => OperatorOfQueryParams.java} | 4 ++-- ...NftSupportsQueryParams.java => SupportsQueryParams.java} | 4 ++-- ...tUpdateOperatorParams.java => UpdateOperatorParams.java} | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/{NftOperatorOfQueryParams.java => OperatorOfQueryParams.java} (64%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/{NftSupportsQueryParams.java => SupportsQueryParams.java} (66%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/{NftUpdateOperatorParams.java => UpdateOperatorParams.java} (64%) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java index 9fee2a608..ef4c02650 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java @@ -57,7 +57,7 @@ public static void main(String[] args) { List updateOperatorList = new ArrayList<>(); updateOperatorList.add(update1); updateOperatorList.add(update2); - SchemaParameter updateOperatorsParams = new NftUpdateOperatorParams(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); + SchemaParameter updateOperatorsParams = new UpdateOperatorParams(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); updateOperatorsParams.initialize(true); @@ -69,7 +69,7 @@ public static void main(String[] args) { List operatorOfQueries = new ArrayList<>(); operatorOfQueries.add(operatorOfQuery1); operatorOfQueries.add(operatorOfQuery2); - SchemaParameter operatorOfQueryParams = new NftOperatorOfQueryParams(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); + SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); operatorOfQueryParams.initialize(true); @@ -103,7 +103,7 @@ public static void main(String[] args) { List identifiers = new ArrayList<>(); identifiers.add(standardIdentifier1); identifiers.add(standardIdentifier2); - SchemaParameter supportsQueryParams = new NftSupportsQueryParams(cis2nftSchema, supportsReceiveName, identifiers); + SchemaParameter supportsQueryParams = new SupportsQueryParams(cis2nftSchema, supportsReceiveName, identifiers); supportsQueryParams.initialize(true); // Initialize SetImplementorsParams diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java similarity index 64% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java index 13a3e2b4e..e1212bcfc 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftOperatorOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java @@ -6,8 +6,8 @@ import java.util.List; -public class NftOperatorOfQueryParams extends ListParam { - public NftOperatorOfQueryParams(Schema cis2nftSchema, ReceiveName operatorOfReceiveName, List operatorOfQueries) { +public class OperatorOfQueryParams extends ListParam { + public OperatorOfQueryParams(Schema cis2nftSchema, ReceiveName operatorOfReceiveName, List operatorOfQueries) { super(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java similarity index 66% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java index 930f33bad..4c3ccf2db 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftSupportsQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java @@ -6,8 +6,8 @@ import java.util.List; -public class NftSupportsQueryParams extends ListParam { - public NftSupportsQueryParams(Schema cis2nftSchema, ReceiveName supportsReceiveName, List identifiers) { +public class SupportsQueryParams extends ListParam { + public SupportsQueryParams(Schema cis2nftSchema, ReceiveName supportsReceiveName, List identifiers) { super(cis2nftSchema, supportsReceiveName, identifiers); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java similarity index 64% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java index 30946db18..c51c56171 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftUpdateOperatorParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java @@ -6,8 +6,8 @@ import java.util.List; -public class NftUpdateOperatorParams extends ListParam { - public NftUpdateOperatorParams(Schema cis2nftSchema, ReceiveName updateOperatorReceiveName, List updateOperatorList) { +public class UpdateOperatorParams extends ListParam { + public UpdateOperatorParams(Schema cis2nftSchema, ReceiveName updateOperatorReceiveName, List updateOperatorList) { super(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); } } From 7a4118941fdd7ae4f80bbf689701e60db7b44d85 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 20 Sep 2023 15:29:46 +0200 Subject: [PATCH 21/53] Updated concordium-base --- concordium-base | 2 +- crypto-jni/Cargo.lock | 161 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 4 deletions(-) diff --git a/concordium-base b/concordium-base index 7c94c5960..4e980f763 160000 --- a/concordium-base +++ b/concordium-base @@ -1 +1 @@ -Subproject commit 7c94c596000ad3353cb860bf68460891703f8ccf +Subproject commit 4e980f763b0014129529224fd22ed3d34e6304bd diff --git a/crypto-jni/Cargo.lock b/crypto-jni/Cargo.lock index 79920497c..d4a0e8d38 100644 --- a/crypto-jni/Cargo.lock +++ b/crypto-jni/Cargo.lock @@ -46,6 +46,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + [[package]] name = "block-buffer" version = "0.9.0" @@ -186,7 +192,7 @@ dependencies = [ "js-sys", "num-traits", "serde", - "time", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -215,6 +221,7 @@ dependencies = [ name = "concordium-contracts-common" version = "7.0.0" dependencies = [ + "base64", "bs58", "chrono", "concordium-contracts-common-derive", @@ -236,7 +243,7 @@ version = "3.0.0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.32", ] [[package]] @@ -270,6 +277,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", + "serde_with", "sha2 0.10.6", "sha3", "subtle", @@ -283,7 +291,7 @@ version = "1.0.0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.32", ] [[package]] @@ -432,6 +440,50 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.32", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +dependencies = [ + "serde", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -493,6 +545,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "ff" version = "0.5.2" @@ -585,6 +643,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -624,6 +688,34 @@ dependencies = [ "cxx-build", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", + "serde", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1145,6 +1237,35 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.0", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.28", +] + +[[package]] +name = "serde_with_macros" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "sha2" version = "0.9.9" @@ -1185,6 +1306,12 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" @@ -1265,6 +1392,34 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +dependencies = [ + "time-core", +] + [[package]] name = "toml" version = "0.5.11" From f8d5f4a115f63866894216960ff67f9b7f53733d Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 11 Oct 2023 13:11:13 +0200 Subject: [PATCH 22/53] Cis2Nft example --- .../contractexample/cis2nft/Cis2Nft.java | 170 ++++++++++++++++++ .../cis2nft/Cis2NftExample.java | 120 ------------- .../cis2nft/Cis2NftMethod.java | 16 ++ .../cis2nft/Cis2NftParameters.java | 154 ++++++++++++++++ .../contractexample/cis2nft/cis2-nft.wasm.v1 | Bin 0 -> 77916 bytes .../{wccd => parameters}/AddressParam.java | 2 +- .../BalanceOfQuery.java | 2 +- .../{cis2nft => parameters}/MintParams.java | 2 +- .../NftBalanceOfQuery.java | 2 +- .../NftBalanceOfQueryParams.java | 2 +- .../NftMetaDataQuery.java | 2 +- .../{cis2nft => parameters}/NftTransfer.java | 2 +- .../NftTransferParam.java | 2 +- .../OperatorOfQuery.java | 2 +- .../OperatorOfQueryParams.java | 2 +- .../{cis2nft => parameters}/Receiver.java | 2 +- .../SetImplementorsParams.java | 2 +- .../SetMetadataUrlParams.java | 2 +- .../{wccd => parameters}/SetPausedParams.java | 2 +- .../SupportsQueryParams.java | 2 +- .../{cis2nft => parameters}/TokenAmount.java | 2 +- .../TokenAmountU8.java | 2 +- .../{cis2nft => parameters}/TokenId.java | 2 +- .../{cis2nft => parameters}/TokenIdU32.java | 8 +- .../{cis2nft => parameters}/Transfer.java | 2 +- .../{wccd => parameters}/UnwrapParams.java | 3 +- .../UpdateOperator.java | 2 +- .../UpdateOperatorParams.java | 2 +- .../{wccd => parameters}/UpgradeParams.java | 2 +- .../{wccd => parameters}/WrapParams.java | 3 +- .../contractexample/wccd/Cis2WCCD.java | 4 + .../contractexample/wccd/WCCDExample.java | 2 +- 32 files changed, 375 insertions(+), 149 deletions(-) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/AddressParam.java (96%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/BalanceOfQuery.java (88%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/MintParams.java (94%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/NftBalanceOfQuery.java (84%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/NftBalanceOfQueryParams.java (88%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/NftMetaDataQuery.java (90%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/NftTransfer.java (87%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/NftTransferParam.java (87%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/OperatorOfQuery.java (87%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/OperatorOfQueryParams.java (88%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/Receiver.java (97%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/SetImplementorsParams.java (94%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/SetMetadataUrlParams.java (97%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/SetPausedParams.java (87%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/SupportsQueryParams.java (87%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/TokenAmount.java (59%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/TokenAmountU8.java (93%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/TokenId.java (56%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/TokenIdU32.java (81%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/Transfer.java (90%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/UnwrapParams.java (88%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/UpdateOperator.java (96%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{cis2nft => parameters}/UpdateOperatorParams.java (88%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/UpgradeParams.java (96%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/{wccd => parameters}/WrapParams.java (82%) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java new file mode 100644 index 000000000..d2c60b831 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -0,0 +1,170 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.ClientV2; +import com.concordium.sdk.Connection; +import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; +import com.concordium.sdk.exceptions.ClientInitializationException; +import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.transactions.*; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.concordium.sdk.types.Nonce; +import com.concordium.sdk.types.UInt64; +import lombok.SneakyThrows; +import lombok.var; +import picocli.CommandLine; + +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.Callable; + +/** + * Calls different methods on a cis2-nft smart contract deployed on the chain. + * See {@link Cis2NftParameters} for how to create and initialize custom smart contract parameters. + * TODO what values should user replace + */ +@CommandLine.Command(name = "Cis2Nft", mixinStandardHelpOptions = true) +public class Cis2Nft implements Callable { + + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // TODO dummy address + private static final String PATH_TO_MODULE = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1"; + private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address + + private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); + + private static final TransactionSigner SIGNER = TransactionSigner.from( + SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) + ); + + @CommandLine.Option( + names = {"-m", "--method"}, + required = true, + description = "Name of method. Valid names are: ${COMPLETION-CANDIDATES}") + private Cis2NftMethod methodName; + + @CommandLine.Option( + names = {"--endpoint"}, + description = "GRPC interface of the node.", + defaultValue = "http://localhost:20002") + private String endpoint; + + @CommandLine.Option( + names = {"--timeout"}, + description = "GRPC request timeout in milliseconds.", + defaultValue = "100000") + private int timeout; + + + @Override + public Integer call() throws IOException, ClientInitializationException { + var endpointUrl = new URL(this.endpoint); + Connection connection = Connection.newBuilder() + .host(endpointUrl.getHost()) + .port(endpointUrl.getPort()) + .timeout(timeout) + .build(); + var client = ClientV2.from(connection); + //Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); + Nonce nonce = Nonce.from(1); + + switch (this.methodName) { + case INIT: + handleInit(client, nonce); + break; + case MINT: + SchemaParameter mintParams = Cis2NftParameters.generateMintParams(); + handleMethod(client, nonce, mintParams); + break; + case TRANSFER: + SchemaParameter transferParams = Cis2NftParameters.generateTransferParams(); + handleMethod(client, nonce, transferParams); + break; + case UPDATE_OPERATOR: + SchemaParameter updateOperatorParams = Cis2NftParameters.generateUpdateOperatorParams(); + handleMethod(client, nonce, updateOperatorParams); + break; + case OPERATOR_OF: + SchemaParameter operatorOfParams = Cis2NftParameters.generateOperatorOfParams(); + handleMethod(client, nonce, operatorOfParams); + break; + case BALANCE_OF: + SchemaParameter balanceOfParams = Cis2NftParameters.generateBalanceOfParams(); + handleMethod(client, nonce, balanceOfParams); + break; + case TOKEN_METADATA: + SchemaParameter tokenMetadataParams = Cis2NftParameters.generateTokenMetadataParams(); + handleMethod(client, nonce, tokenMetadataParams); + break; + case SUPPORTS: + SchemaParameter supportsParams = Cis2NftParameters.generateSupportsParameter(); + handleMethod(client, nonce, supportsParams); + break; + case SET_IMPLEMENTORS: + SchemaParameter setImplementorsParams = Cis2NftParameters.generateSetImplementorsParams(); + handleMethod(client, nonce, setImplementorsParams); + break; + } + + + return 0; + } + + private void handleInit(ClientV2 client, Nonce nonce) { + ModuleRef ref = null; + InitName initName = InitName.from("init_cis2_nft"); + InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), ref, initName, Parameter.EMPTY); + InitContractTransaction initContractTransaction = TransactionFactory.newInitContract() + .sender(AccountAddress.from(SENDER_ADDRESS)) + .payload(payload) + .expiry(EXPIRY) + .nonce(AccountNonce.from(nonce)) + .signer(SIGNER) + .maxEnergyCost(UInt64.from(10000)) + .build(); + //Hash txHash = client.sendTransaction(initContractTransaction); + //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + //sleep(); + //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + //System.out.println("Transaction finalized in block with hash: " + blockHash); + System.out.println(this.methodName); + + } + + private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { + UpdateContractPayload payload = UpdateContractPayload.from(CONTRACT_ADDRESS, parameter); + UpdateContractTransaction transaction = TransactionFactory.newUpdateContract() + .sender(AccountAddress.from(SENDER_ADDRESS)) + .payload(payload) + .expiry(EXPIRY) + .nonce(AccountNonce.from(nonce)) + .signer(SIGNER) + .maxEnergyCost(UInt64.from(10000)) + .build(); + //Hash txHash = client.sendTransaction(transaction); + //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + //sleep(); + //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + //System.out.println("Transaction finalized in block with hash: " + blockHash); + System.out.println(this.methodName); + + + + } + + @SneakyThrows + private void sleep() { + for (int i = 0; i < 200; i++) { + System.out.print("."); + if (i % 50 == 0) { + System.out.println("\n"); + } + Thread.sleep(30); + } + } + public static void main(String[] args) { + int exitCode = new CommandLine(new Cis2Nft()).execute(args); + System.exit(exitCode); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java deleted file mode 100644 index ef4c02650..000000000 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftExample.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; - -import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.smartcontracts.Schema; -import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; -import com.concordium.sdk.types.*; -import lombok.SneakyThrows; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -public class Cis2NftExample { - - @SneakyThrows - public static void main(String[] args) { - AccountAddress accountAddress = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - ContractAddress contractAddress1 = ContractAddress.from(1, 0); - ContractAddress contractAddress2 = ContractAddress.from(2, 0); - Schema cis2nftSchema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); - String cis2nftContractName = "cis2_nft"; - - // Initialize MintParams - - ReceiveName mintParamsReceiveName = ReceiveName.from(cis2nftContractName, "mint"); - List tokens = new ArrayList<>(); - tokens.add(TokenIdU32.from(12)); - tokens.add(TokenIdU32.from(22)); - tokens.add(TokenIdU32.from(2132)); - SchemaParameter mintParameter = new MintParams(cis2nftSchema, mintParamsReceiveName, accountAddress, tokens); - mintParameter.initialize(true); - - - // Initialize TransferParameter - ReceiveName nftTransferReceiveName = ReceiveName.from(cis2nftContractName, "transfer"); - TokenIdU32 tokenId = TokenIdU32.from(12); - TokenAmountU8 amount = TokenAmountU8.from(1); - AbstractAddress from = contractAddress1; - Receiver to = new Receiver(contractAddress2, "mint"); - List data = new ArrayList<>(); - data.add(UInt8.from(123)); - data.add(UInt8.from(23)); - NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); - List transfers = new ArrayList<>(); - transfers.add(transfer); - SchemaParameter transferParameter = new NftTransferParam(cis2nftSchema, nftTransferReceiveName, transfers); - transferParameter.initialize(true); - - - // Initialize UpdateOperatorParams - - ReceiveName updateOperatorReceiveName = ReceiveName.from(cis2nftContractName, "updateOperator"); - UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, accountAddress); - UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, contractAddress1); - List updateOperatorList = new ArrayList<>(); - updateOperatorList.add(update1); - updateOperatorList.add(update2); - SchemaParameter updateOperatorsParams = new UpdateOperatorParams(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); - updateOperatorsParams.initialize(true); - - - // Initialize OperatorOfQueryParams - - ReceiveName operatorOfReceiveName = ReceiveName.from(cis2nftContractName, "operatorOf"); - OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(accountAddress, contractAddress1); - OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(contractAddress1, contractAddress2); - List operatorOfQueries = new ArrayList<>(); - operatorOfQueries.add(operatorOfQuery1); - operatorOfQueries.add(operatorOfQuery2); - SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); - operatorOfQueryParams.initialize(true); - - - // Initialize ContractBalanceOfQueryParams - - ReceiveName balanceOfReceiveName = ReceiveName.from(cis2nftContractName, "balanceOf"); - NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), accountAddress); - NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), contractAddress1); - List balanceOfQueries = new ArrayList<>(); - balanceOfQueries.add(balanceOfQuery1); - balanceOfQueries.add(balanceOfQuery2); - SchemaParameter contractBalanceOfQueryParams = new NftBalanceOfQueryParams(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); - contractBalanceOfQueryParams.initialize(true); - - // Initialize ContractTokenMetadataQueryParams - - ReceiveName tokenMetadataReceiveName = ReceiveName.from(cis2nftContractName, "tokenMetadata"); - TokenIdU32 token1 = TokenIdU32.from(21); - TokenIdU32 token2 = TokenIdU32.from(22); - List tokensForMetadataQuery = new ArrayList<>(); - tokensForMetadataQuery.add(token1); - tokensForMetadataQuery.add(token2); - SchemaParameter nftMetaDataQuery = new NftMetaDataQuery(cis2nftSchema, tokenMetadataReceiveName, tokensForMetadataQuery); - nftMetaDataQuery.initialize(true); - - // Initialize SupportsQueryParams - - ReceiveName supportsReceiveName = ReceiveName.from(cis2nftContractName, "supports"); - String standardIdentifier1 = "identifier1"; - String standardIdentifier2 = "identifier2"; - List identifiers = new ArrayList<>(); - identifiers.add(standardIdentifier1); - identifiers.add(standardIdentifier2); - SchemaParameter supportsQueryParams = new SupportsQueryParams(cis2nftSchema, supportsReceiveName, identifiers); - supportsQueryParams.initialize(true); - - // Initialize SetImplementorsParams - - ReceiveName setImplementorsReceiveName = ReceiveName.from(cis2nftContractName, "setImplementors"); - List implementors = new ArrayList<>(); - String identifier = "IdentifierID"; - implementors.add(contractAddress1); - implementors.add(contractAddress2); - SchemaParameter setImplementorsParams = new SetImplementorsParams(cis2nftSchema, setImplementorsReceiveName, identifier, implementors); - setImplementorsParams.initialize(); - - } -} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java new file mode 100644 index 000000000..f796d513c --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java @@ -0,0 +1,16 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +/** + * Represents the different possible methods able to be run by {@link Cis2Nft} + */ +public enum Cis2NftMethod { + INIT, + MINT, + TRANSFER, + UPDATE_OPERATOR, + OPERATOR_OF, + BALANCE_OF, + TOKEN_METADATA, + SUPPORTS, + SET_IMPLEMENTORS, +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java new file mode 100644 index 000000000..9cd04765a --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -0,0 +1,154 @@ +package com.concordium.sdk.examples.contractexample.cis2nft; + +import com.concordium.sdk.examples.contractexample.parameters.*; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; +import com.concordium.sdk.types.*; +import lombok.SneakyThrows; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class for creating and initializing parameters being used in {@link Cis2Nft}. + */ +public class Cis2NftParameters { + + private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); + private static final ContractAddress CONTRACT_ADDRESS_2 = ContractAddress.from(2, 0); + + private static final String CIS_2_NFT_CONTRACT_NAME = "cis2_nft"; + + @SneakyThrows + public static SchemaParameter generateMintParams() { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName mintParamsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "mint"); + List tokens = new ArrayList<>(); + tokens.add(TokenIdU32.from(2)); + tokens.add(TokenIdU32.from(22)); + tokens.add(TokenIdU32.from(2132)); + SchemaParameter mintParameter = new MintParams(schema, mintParamsReceiveName, ACCOUNT_ADDRESS, tokens); + mintParameter.initialize(true); + return mintParameter; + } + + @SneakyThrows + public static SchemaParameter generateTransferParams() { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName nftTransferReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "transfer"); + TokenIdU32 tokenId = TokenIdU32.from(12); + TokenAmountU8 amount = TokenAmountU8.from(1); + AbstractAddress from = CONTRACT_ADDRESS_1; + Receiver to = new Receiver(CONTRACT_ADDRESS_2, "mint"); + List data = new ArrayList<>(); + data.add(UInt8.from(123)); + data.add(UInt8.from(23)); + NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); + List transfers = new ArrayList<>(); + transfers.add(transfer); + SchemaParameter transferParameter = new NftTransferParam(schema, nftTransferReceiveName, transfers); + transferParameter.initialize(true); + + return transferParameter; + } + + @SneakyThrows + public static SchemaParameter generateUpdateOperatorParams() { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName updateOperatorReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "updateOperator"); + UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); + UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); + List updateOperatorList = new ArrayList<>(); + updateOperatorList.add(update1); + updateOperatorList.add(update2); + SchemaParameter updateOperatorsParams = new UpdateOperatorParams(schema, updateOperatorReceiveName, updateOperatorList); + updateOperatorsParams.initialize(true); + + return updateOperatorsParams; + } + + public static SchemaParameter generateOperatorOfParams() throws IOException { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName operatorOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "operatorOf"); + OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); + OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); + List operatorOfQueries = new ArrayList<>(); + operatorOfQueries.add(operatorOfQuery1); + operatorOfQueries.add(operatorOfQuery2); + SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(schema, operatorOfReceiveName, operatorOfQueries); + operatorOfQueryParams.initialize(true); + return operatorOfQueryParams; + } + + public static SchemaParameter generateBalanceOfParams() throws IOException { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName balanceOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "balanceOf"); + NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), ACCOUNT_ADDRESS); + NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), CONTRACT_ADDRESS_1); + List balanceOfQueries = new ArrayList<>(); + balanceOfQueries.add(balanceOfQuery1); + balanceOfQueries.add(balanceOfQuery2); + SchemaParameter contractBalanceOfQueryParams = new NftBalanceOfQueryParams(schema, balanceOfReceiveName, balanceOfQueries); + contractBalanceOfQueryParams.initialize(true); + return contractBalanceOfQueryParams; + } + + public static SchemaParameter generateTokenMetadataParams() throws IOException { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName tokenMetadataReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "tokenMetadata"); + TokenIdU32 token1 = TokenIdU32.from(21); + TokenIdU32 token2 = TokenIdU32.from(22); + List tokensForMetadataQuery = new ArrayList<>(); + tokensForMetadataQuery.add(token1); + tokensForMetadataQuery.add(token2); + SchemaParameter nftMetaDataQuery = new NftMetaDataQuery(schema, tokenMetadataReceiveName, tokensForMetadataQuery); + nftMetaDataQuery.initialize(true); + return nftMetaDataQuery; + } + + public static SchemaParameter generateSupportsParameter() throws IOException { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName supportsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "supports"); + String standardIdentifier1 = "identifier1"; + String standardIdentifier2 = "identifier2"; + List identifiers = new ArrayList<>(); + identifiers.add(standardIdentifier1); + identifiers.add(standardIdentifier2); + SchemaParameter supportsQueryParams = new SupportsQueryParams(schema, supportsReceiveName, identifiers); + supportsQueryParams.initialize(true); + return supportsQueryParams; + } + + public static SchemaParameter generateSetImplementorsParams() throws IOException { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); + List implementors = new ArrayList<>(); + String identifier = "IdentifierID"; + implementors.add(CONTRACT_ADDRESS_1); + implementors.add(CONTRACT_ADDRESS_2); + SchemaParameter setImplementorsParams = new SetImplementorsParams(schema, setImplementorsReceiveName, identifier, implementors); + setImplementorsParams.initialize(); + return setImplementorsParams; + } + @SneakyThrows + public static void main(String[] args) { + Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); + List implementors = new ArrayList<>(); + String identifier = "IdentifierID"; + implementors.add(CONTRACT_ADDRESS_1); + implementors.add(CONTRACT_ADDRESS_2); + SchemaParameter setImplementorsParams = new SetImplementorsParams(schema, setImplementorsReceiveName, identifier, implementors); + setImplementorsParams.initialize(); + + } + + + +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 new file mode 100644 index 0000000000000000000000000000000000000000..3b35e19bc58044aa505708998885cc3289be7bdf GIT binary patch literal 77916 zcmeFa3z%JZUGKdvd+*tqHJPrKv<*#tyY{9>C)&J39!^tRkIu?tDG`C{%X1Frea<;; zp}}^hv`ISD@>-ke1qe_eLV*Ak0u&pdXpkyZ5u%_5tQxgw(W*hQR;?PfK+$U7&-eHH zugl&ulcX2m@I0rN*=zl;zyI(4|NSp3ilR7*H@+yky-;T zUU|{gm;ZlTqqLRVyZp*)uA1K(by{gB{^-_)i*{^%>DJ4y*?Q4cKX&ET9Z|QHeNsF7 z>aAB^I+lO3^0!^GLD$K}9u)hiaZy<#DXTRA7S zq2007;GJmYkBnx=)=Msp`mNj(+qJEak?hd;OQ~03BwE#~9`dia>Z$MBfWUH4`#|q4E zU52j96Raac~qZe(x2G)p@^!D_9X_91dqJOd|i^cd+ly!NWin7(w^lJTY1>!7; z<0MYH$qCbOr2n$%=_r}*TIGo6X;Px@^fdn^NjJ))uKuCD?sODSPfzQA{!#fTixO2= zWqPM>r2oQ?5(Sg0TYfy9O_6(ImYtYPpA=;oeeqA${6nsH*X>Sq6AdG+|4F8MNkpGf zG^JJ zK*&_ojZW-FCo@WQqOnFN(M>WnHFYBYcc%oly0ceO$eKR27gHcQIf|%ZXi4HzrcY9( zWbJfvYNAe)rvs?})9J?B;-cuLadcwu>FLh6TwFX5Wjmwt{^a zcDyo)R$qSQ zy!vH`_}|B;)`_p!b}0=0!foR7t9C^H5I?QXx+)~T@MY0I#wXRuFS+E3ORjwBR#K0| zr_`wnsGcjIzjfgfn!6wl044)`cxE-*&~;m&37F?YKJn zmw57`i&Pa^yflroi!Qos>m}PRddVeMZ%va`KM+S{oSm^h{)PDG<2&P@jX#`zEdFTx zbMc4cuf=am?@N9?`K{z&^10+Ul3z19 zo%f|b5XU>qc#tHs<=1u{Sd7Yl)!!o85M8*gi1S@HE-pr^dFS~pi{ZJPnX6t0NmeA; zkI+amo6M>jrPW>$mr?!(s~s0{LE2ndwmD@`_Ev+iL*x0}fGX#&Mw&F%3kGRc zq}j!B8qi4*L(|&@sQ}y%oh3BWtU5K+3{zT9%C!rFj-jMeu6;!rJy&hod)mgl<7K9% z7rl0B1jYt-{wCqq3;rEaWkeB{^skke?sii2M#tJO5wOJwY&w-YDpNjNga|;Fv_(=! zN$=1&&R^Z7rW3HdVWc+raU#B11w)Y=M~bK|qx0KZMQ$1?!Z?-|xp|}rsPrQ5R4YE% z?V!EkmLzbCXbj!x79JUP&Woo5CX#YmLwfCvGysa>9NrG7Imj*41O}Q?sb95jBKW*! zq$0|;wF!MFY9UROe$kVnw5YyB#-6Z1JSO;85QsO%NW>Dv1uVrgNdbo#q=*!w&qc5n3J9?{iddi27x`T^eLV zvOeF{>7re_ zm^e2ACiPRI^MLmQ4zB>bLhN9mUN-0{VcTHB`Pkc`84EziVh!M9_`N&h>w`KdY7hmM|62&A3LrvpG2O;~ z;yCO#h+3b5Bx|Edq!p4krMUpwl=h)nEIPNT7g{RnmO`Z{rnGVP+Br26NpGGg-pZTz zReJ9??~z)sAr?mz6+;|MQcULcwMJYH1p$_$Az_3Wg|TY1JTFB-NJM-Qr#DL9&;`=d zsl^G-P(mN6g5sOfwful8VXSv{G{sMRb_C*z?%5HH=lENO5>Fxi+SH-PO15fDK4Crn zZzj%0o+aMfP?(X2DK#UnWEkZim#QtI{BHeb+3uD-+gLNOp|;kn!lj9H@D5z3n$o0w z6R%i0P<@!9LfYdUZC!dq#)_x@jk(x}P<1L-cGQohYus1C6?|OYI=P|4 z{91DrBXen8HiRDWvHahGMBY4O-tu8Le}~k2GV6`@g|E)~WNO&k40;!joN<%=7C(Zs z!#KKUC*q!#rM7mJz83RE`WiV%XD2y7J;|tC>R}p?pE~jxd_}RE4K7*MJU0IJ#w*YV zEdyNp+ZR^;_9w&-GREb`W&Q1!(gUMZ8zwL4ME6&r;JOo}m-=($4Pr0U873eD9gA=C zY_OJK>W7ILbpzjpN$A)dZ$f>mt?Y|Z+^P}Dt23>qpE_ygAD6x@&b{PkMy|}p%A4>QHt8V`^YJZF15aV|Ec zh1efm=IFeT@u%f3#4SY~=eJ9mEhn8x_QXR?v&cD&+aWGjK_1L*kY1$g(_OT6u^wlV z+u+m%9>K;o%Hmd8&HSBe)Jx}^(rZcWpPekq-Sd7QiRSX3(Qt}%L$oWF?}RPQKd)+d z4s=q$F?6uj_z^6NO{lQAXuOhc#*85_WqbjoPs_FP=iaZ{64FoFJAhsTvaT~CRH0=(bT@}D~99I5ZBliI~gnMu$b!!aM+@NyPtfM;fC zi#aMITWiD1_gi;1z3Re!&PQa=APeG6lab{{t?})z9jiY~k`y}{9En3wOA-6D<~45S zMB(ONsoohmv{?5I(Rz6^M3jhq(5(#2RIh$w5{f5*s9`e^j*X0g=t7as=eyLhn@^ZV z6T1{mRi5#@)kLw7IVRg8%WE4uyH@>)wisD)SIAUa{|?W~&GL2|@1(%;Vt_~8PB<60 zt%gxgYGmW4C}srarW}kKKg9eLeC*nBF-PT`=3S180A_OOf|LDTJTlD<@+1rvG1IjE zAc07ZP}IQ39=PY}&s!ZSvz)nN2s^#Nq)20gwf4I>z*9`*7ZXPi&|UCbV1%| zA+-b=(O^Y4e^@x93p@+b&^DxfHKZk3{(6}l0Pfn1TouWGT}T8It$Cn?G7RZmX*^Ns z2u+7ZbVLrDBG-K%q3Z|)qc7h!E$@lupjqmZksX5`>|ifNr_mo)6S=u|IN>S;gp0^t zYgC0?wn;5Wz^~J^Bh_5wLM3P>)Ycw|`HM+Kdt4lPOw0S)%Hy(OUk-$n0Az1Xpt?cM zyOqgA$Yi_v!wFbNn5FmrASz6kAZXGh8lym7pXNcGXbx0N;D~=#=!fRDlA^5+IWt$x z4ObO?7^qm~Dq(c8MO~~xUv2g;1Tiv3(q4VZaWg^sSWAH)L5fF+gYpn@iZ*e;0u9WJ zDe%iG{aquUatx`hzh7J<{|ZMw+8g9cT9@E|?Fjx&zYG08SLw&d!qzGS7zG&TNgE(BP zjh1P8SAS;myBg&y529AS8<$hQZP-P$BejzFaNJnkW&%?(%|w?d#$Y-S<}p=i)WacO zBThp~H$-b~nu~tzAP%k(twzzoBr)M^RP2BC8ea{PI0Tb zCg4M(O3KteD6C+Hib(;i5giN1{Ah}d9hB{q3m zZ1P&CorOx17Ant~TTYEVci3|^Rs=0}&bS<%gG5Sa%_KkMoCd>*(@f_TBWkR_DLqFy zXQSw)<<4n|P$cE0`OySQe3a?sYP-(rH99M=bQY7+N@qzh@hsXps|VX1Tvlh9&nt~f z+i1*MJ>_lnl#A0FbNGZOng1?HtNoeLC4%K6dexN02CsoDVQ24b3EXI02gHUr z?%nDU`C|5Zj+P&wF|K5Oi)`?)gAk$VU{90MZXL2wBpMe+^>9mmF|vu^@g z#^nBzaus5fkXMd&Hnv(|{n1=30!I06b?*W6l~!=P1|5j5TETft1NZ1Y-a_m{5QJi} zIKQ!Ja(PUCQ1w+_Y$QzHY&8s%Pne*Kfv121y*WzIxkeo})KT|iO9S9qE|1jX^jw+b zzY@?bA2QBASrM?bHGxkVwz0!4YM2$cG~$I0;R6RJ$Ns80j%YG)=Q9OaqmZk|w7sq=vT4D1dGm zBw{G^$V1bWF%$EcIKQb9vKE%pZ0ks;^)SVMBO{&ik@m+&8pcPbzV5aB&|XF_utOM! z9A;awbIvD2yzk4K;(aidLfOP9n+zkH3V1qrEG#Tv!ixoh#jB8-#o74_8VOfn+_5St;V48OsPicS8MR6AC25u<-Mr2q&rKOH!jv?%8p z#S@h~73PYGpS?ppSj$sO!fJF^g|kkmUCsXj+-0m0t3Dyl->BNx8&HfS$ijJo5BqCr zGi;g2ei(OOqY%cJJQTfRBEQ4tQq%pov@48Rm~E`~9<4Ie!2wiq>a;hyN$D8#d^T{C zW+)(j`E+LN>uS&icz?`~kPsGh5gxLH^v8_$cMZrdcK1uccZsSx`YySzV@2@0{ zOzdq|1_MV+Y&8Q8i+tj(5G7Nz>mf46{NOU5+FI1b`>7Z9LUC{MpfRB;;7cZo-3?=Y|A~kP z?1xfPZ_(wN%T?VlS8BDjM>Zg6H-n5h;%;<}7cbALmJ^e5%~Gz#p9oQ-_EJSXD@@A0 zb+qc5_Nvzt<;SRm)oQ*w9&UT(a9|nsYY+ry|Cwknf~9 zXKOZA`3XqQ1xx&dFDC5~kA&wG1js?~45;TPpUZzsWOR^bl5>m!4|ohkr2r3KLXvM3 zn$av?)%c@QZom5ZJ!(V_xAHujy0vbzR4IOMu}yPY%(H|>*^3~{XGN@iYp5#f6}|aU zwkOmJA6vcrHWN{rGS@_!MJ@>7Z=^)JIlitQyhG#`i(XL^(jo~#`EmV7Vy)X6>-egc zS!WU+RGgeF%J(aK&bT0)*7t$Kq{5c=(B%2wn)E~hF1MMAn9IaQJC96j)$d?VeB$r& z3G3QCjX?qBCNdtCv{+3SZR3N(o)H}b2~4$oD-^6(>yDPi`1)agS?6f`<`o$Yhn6rkY#ooM+jewnlXrU%JH- zXX7A?riT8hx%{^SwOEI6a>*|rNBMK9LJ(9GqueOTHU^Sak>QE|su39vu_D`00+GP$fdl2n1QZaNt~n6A%BWP16Ae&E zCHXJtBsFIk3h&mUF{O}0WA7E$XrZd?BT@40RiPrM9^L70Md-~i20e^JdciTqSIO76 z?)a{5yjo09&79)DHUY6nAXPIu{^TxrdYoYvFQV2+<({F42|axSB6 zf7`m@L4rwXuOU-1JuhqB%;iX={DH>w5&9*6j}$~3u9mTTYioWYJyRQ4G-i^2!BmTi z^QzwUr{(FW7sRbnp|;gQF=tg!E&i*dE*KL_t=t;G#Q{S06tc$Q;xFdpPrTEaP*vk?D72 z&p5L2pVW^nqdB(Mj$r$M8w0gQ`xOy{1!70y4O`Xo`p&=FAn{_w3=uo3Ft4*hOo77G zP6&_w`=(SY4=mFTmm-|mlFjWRxK3S#RdNMY1Zpks_UQ87TI6c5e@EKLgeJ|SOj+US z*i7k6g;K9(m1((Xdns!3XiS7Txz^dmS*)IfMw&SVJew&oq>Qq)bEg&)+eW2gY%!-X zHouq_pFV@=3k}guq@mV=zfjMh4b4C7L=wZ#n4{E;z=fdbRy4K!!IcAU=&UE$2F2{A zlr>l9|McSaI1fcttJ)Z4o{iRUwMAiEN<_YTa@`Q>?zA!E;^}5CBH61INJrczo?=yz zAN~tssR;*B9ijzc_F^SR%(G_d3ef-DGzc{>vuzGGYlT}J zj9MjiEZy34@B&5+D8dr6R1lw!&r-}=^j&&3E^E0heHvw3?5shc)F>gj!x7XRK>mQ# z93xzx&T8q}^i~C1g(nx+{ICzK{L)geq}aY_+2eBAY1WY&%Kh!=B(j#UUSvA^Ost)YL~2y2^CM0OK z4xREjwMcl_ z-JJayuQY#K_)R9H(c2op)Gr#qc|V|pt^XcAk&0(GSFMbtfiHx-U_c&66~FLkQUu|} zEeMO2nj9FeHjgi@WX z!xcq72JnsaWp&hslXdb@&0dgP;j#onitd_K50 z*-Z7tT=qaLfTDVpX&{@dVldfhqF!k&|F}A0yyaat99WFXXOIf(9k@v^_bDlV=S`GA zXcHJDbbfR#H+2PM4qEOzgKRIa4-Z9GGz#(Pjc#m}JbI%K9)F|BLIde9w_*wibM3Ti zQSSu96@N~c%l}0PD+TbWPCg=Yw3p=x>@@1t+LrQkURGQ&H#~{z@DguDHjX-vt=Fj=Usvc6%5?WEQ9O2F;F_36_A34e!hBuMqjJV zQCbO>LPz52EF9E3JTJGsB$PczPR~rTQ47)1sfhb+-X(bhb~KauY+Repg4`q9V$9Y- zsef~c&as_PilNrK{mIdEsbUi~3J}gFwbvuaHqN=1Cx;vZ7{vL7jV@_)xW-$=^n&ti z4z`)L(j@+C;?t(>k-6#l$1|QDO&0qS{=K4<5N#ZC2`G~KNG8}6=e|1N@?Z<}hGgo16ZT@z% zF_16U^i-Q<@#a`vXG>J5Rq+w%7Gfx~Hh)`HOQ8@_rb4YwmjAM{6hRHulRyV+wn(2D zug%}8A{<3Vxzd$_5Nq?F4QY02+g9~i)|NwIes9{Cu`joFnl_k$8AkO%SR|4@I2NZ= zM*tlXb9{sk&C%iNnj^aTFI1yOD+G?{;(poOS!JIj7x?x}A-QqWYlgUlSvLg6dYQ_^ z2Sv;u*Nq3SlDd+Qh6jOPCasHK23f+52e&898slO+0wb!ABKK{Lveh^^9)4!^|ecE~?YaY599LHGXDrgIyHa?_&N6BjKkFaeuBQqi1-1L}7M6}29ZT5oF+Wfs?yddsKg}5U%;=bPO z^=|L|Tb#X)tf1YN%3wIEAO*L)45nCR#O}S$P%yYW8cp0f6$6=q%WFC7=0DXikSn+~ zOjtR?7|uW#nV+0Q{ZqvlwPL%YB~S;BE>L>{gRMB^<%G@xM(>@ zG%$+=5%(}pK`>YtrP>2;1+di$gtoJmoHzI`W*0OPA~Q6a|D>EBygi12x%XEO%>2(4 zU^CM1S1$jySL`1bT*p}_?5q_op9G7j0msfZ zb50zjY>wsX0J!h!;gl)`8mv4{`d9J0W$15NOX&adk=bR(2M8iGBveLyYZpXeIYYAm zewYPt(i8@8V#Q)vHP!6ESMG9@r;!!n?jI2D1`)Ilvr)Z|2O^98N4~ zVe&-NIKR_^IN0gKSX7q?b)4Y#q=*@Qp#{mjmbU41T6bC~TO(i(*6G9UX5n}AP7BV{ zX#R#cS?oyhHSNKmHAz?gDT%U}!eFqLyhEC#FBL{%`8-l57RP{7<7_HYi8G}tbR$+G ziPMCkSZNhdQIp!@yrJcy61Yt(+tk<#^>wofLD+C=?gRC!T}t=UdUe}z zNdxfFEUHG`vZj8mTe94tBVkJ82^uTPUL7~nTDqv*CZJ@&!jv_4eE89+?uH0VTUuJ! z5h@m276!~N2QU<3(>MrdIxb~;MY;0_;rwu$7^nU;v99kHtAU{T3$i;_bRLpfr~G|bBab-0V+ z_gh+~;bChs#_WvU7x9jdJup>ajmZjL?{Qri@lL9J1JQPOYfK~Ck!@)-f4_KBBNW=W zPh^f2G21QxBDSBO<1hVj>HvR4=ck4f-9{00-8)AZk85xnzwPSYQVzJUZkCfa`QNu%wUT^xGSUA(@f z#v2nG7&XrSQXMELKdkxH9Ko6|`^bObOXEYPXYFf*j0eSv+CaAwE7s=z@#%$+-to|? zicN?L9Ar*i1)o*J|i^^LI!b)9WGxq=XX)E0Phj`up~*= zgQ4&q{BIO5*Ka?*doQqOpN}dMOdU4`Fle7gQomvMUK~@5e)~z2;Mp|^VuD7F`6cL{ za?-G(>d1cl`&O#B2g110zLo2$eJgL(pon|vsyJBUX!};43?MUCFpFDm1I>#oK+JhI zKxU2w$WD9@*FA8wVo<}xH#H<>y`cf0GR1TA>%imuHJUSV`rR%G$6{9RkLVh?*1H9N z%71I8%Au#kUm2q0jAoyV8|SB)7grET%EG3KB#L#qQBxQW1{A4pD{>#v?@KD8kJza_ z^0Z&VZ!7Rc!gwGv{@7zFGi9}LUaVuUDZApT>mBS~A5Cc4DW9QZS=*cr8_s+)|{ zdh%Pu+0VD&A9bvbH3p4<1-RD>n@mS^g9IbU-yGhVya$K@R1iLFla{2(uOc{bVf& z2Tb1`O%hImA<74DfOR0nTW(@#++NX+<+NbaJly6UOgXj9(555u=xk-2q%cDviH%s* zT!q_;_T5DLRxW?Lx_}*$HWkm5GSLL8>~O1w3Gi@Cd1u*oS|PS!D@+j8n;K!FC1sg| zF|P3z4kXJ?jMVRdww>97c6T}$Op5Hmj$!dw8JcnNs}P`>d9sy^OUhhdVX{QgfvM2s zV$PVX@x?_Oo}vfeznvw?9kx@4x85~%!nAN#PBjUuE#ahVxL&wCqAF8m$E3>At9I&Y zhpmX^wOUv$myh^EHMh@U9W|=6#W2ZyVxW9#bxRIe+W!KN)sYTx*~ydv3eWPpKf`}jeS5P z62l4%ZXtb>5yEiV-fEFCx(P93i-B4UU)xqV`*^q169S?2D3`7E$r|5hLse}Pw_u^| zy_1bF<_h6wHA;chYG8&{RDD|H7_(!yi%_O*CbGY4%~Tmg9Sj$UrxVGijkV}%qC7A= ze~3<|>`40!!KtwLns7HPk2?LC&L*=34vi00;cI$tuHO)dC07{P^^6Ey>k`>v)uH0Q z>XpuzT`cX<0?eos+u>n@T(%og({B4}qKSM50ZKYf842E$t>fZ-aKiz%S8yonHe^;g44`C_o_olZHa|HndKI zj?|J4x9F>>3hpA!*bBPMw<83(@U75u3h1cE{Feg<5qW7}&Yh-KPC@**{1P9~DAIM+ zR#S#YaF4?b1J-UFts0OW3Bi6tkR_i}U_ALJ)Kgmv;&>gp>A<4CmvEn4tLl3RHwt(` z8C6kVs++CQkFD9;IFjj<5TWGIx<4UfY}&~K=*Yvf1)-Ru1)@UWMggm#B`#}uO0=nR zY<)lbotPW0>kD19-?BE|Au24=4e7@yT^VV`g^9gbaQHVH%$`MHsv7Fu?V(cAV$Otc z>JuM{ctXwaOW1j6>|lZCnIZ9bu~p~$;0mtKGD+8p!BoAsP8Ww%K(%&Ao{70hX3J+o zL%Z^Hs7yKZmUaLz7Ypb7)f{xaefK7 z_(Ll^>lHnADmBV!@5lit2X?{5<0!P7cA*<*%ZF5{EXsYaZdES-`c+EZSng@3(s=?N^@*5g*|RR-)>m%?wJ51~ z)*x&Y@RUY~#v(WScIOu4ehIr+THu#=XeAKppp>AxpfrugS83Sfj4MgU#uaFFpN43E z0gKf|q|4u!mLWh6hloNXU*NHFEyxOaB-N1+h^;~N?C$fdJYvHPE70ZLdMjtj!|lQE zN#n_il}9HtrbFz0bGF`P@{v;|_47B#ordV9*ntMd(N&SAhu9sYcaXyhw%Z9Hhr&Vc zvxX%A`4Mupq&=~Y`*N8)Gm}C0{i>K_FqzC^!axC+M+sYsOvBoljdzt>w}PFu^BVd` z1P%+Gm?atmkg9<3AZ$8f-wiT|>P+X?RuvpwnG;xCHYH=jHKua|os8CSbp@a8PZ134 zP%#+#0R|TS+c1#tS6O=3rfnIb)_82xq8|HRjM>*fI8JB<8;?YTd<3hLF!s zV7b6#fG6G(d4p2!RpKYq4g0M76}l^hsz^VVIxiH-obDr0V8|s-%Vr{~R$Jq+21uxO zL6(I*P53w)eNU5ky{B2b{_Smn6h%+lID#IO18TYw788{AgL0IYC%!QP32DQ^4Mq*=ZkjBjJ0ZEJVYL{-LM<$ABgqK+rL<%V8*`^JJ2|L_C znl70}8W@UnR+qb`)k@XscxzR9Fa>=`0%WK%Rkp6YBV9Cn4g|s8aYzb2r+WZ5vjX%& z&Vdx*##l34#i|zxt^H4GNKqz$gl1WCKOze z?!uWefS_MVpieERUb&Mtk_+^Q%|l5Uv$7;Fjkvw-;;@}JNQ#V^q&oYmYkh06lG6IS z5ixYo&~^4f*S0fWaguNJAyc1>2o7b^IF$6tu9iX$C2Ex>wuGDQmllmo`@lG<>c9pJ zG@(Q4nvO%FpcnKMeCT657277GJBA$?eIi3@X4ngi3hmHZB0}KTDc)?~9^#`18lBiIZXUCX-;v_6 zK|j$hwpES>>`@ZfG&0F@Jy&GY>7+BR(ZY7(cm?eGl6*~Ac>Stiuq_KF_-QqwYK0bT z1fiF39c!6;>^kfxv&{VsTNF6PTGQB&p45`$H*8D~OWg$aZf5opAaR0i(L+OsM;hXw@P&%>dF(kX6_6mzj!(rBhJ3hYp$2`VCgk)}HykFH>M9XA=IsdR)D?c$8hXZV zhBK?S7MFz{v_DL9;ruRz(d6NC$uSLT0$~#g1W>}R57oe*=KH{=2(HVY&Zn3>OM|(d zuBXb`zdTi=W+_9XuD>*~@}RMVKIoZm`9a&Kj*Qf7GJ#W99&}CVjo++6KV|&QI7Mk` zf4_kLI7Xc;e3SV5DI2wYMb<_gHcG5K>YBkj->gwTWl}xD;Cw&kI0pSqWAF!BF~29E zz?s;VeN*5gF2I=9mNLewn*wXD$28ANPLio?nT2l!mCfp35aitUbQ}k9d*3XM9y<%w zap&_1Sm#kW9@W{zdTaYEXSijcO_WE;{B^d>oNaw-{1LYO8J+7reaAs(>U@(F_ER=& zZQ>Do*ISm3W7yRBCJlRZ;?u<1eQs68`5)91ALhAJPh{ihF}wKPuYVVx|N3`v@00Fg zi_H){ykcKJW>tNGNwdPd3Y0|5qoZ<#!+bxG2JuqAAk;E9DW*4HgX%UmWk z)4CC5b6t{6fwDR3Y@i7#COB4yOLj!rw=?7N!sF|Vo2%+OUB12UY&o#v>gt!HL(hFK zb%RGQ*=t>zHM*fZb~SGEBaM}CW;lRvSJKAZr)d*(t?pF;)RL)J$#RfwtYk~|bGY%N zh}RX-x=e&?0u-TfrbJQxOU@Lg-@z{UtWzz`A|Xv5D{Ts}{ZZMKO*aH^$KoJKem{;e zakN2_%<4J=U4?;b!F5d9rsOw(rlhd&%-x`AVXKgTq&f;I=!TCFSV>BvQpxu0&baBX zy$~0bk7_BcT$lfxO$-w`AOu)8%QNRvO`;H*HzwsnH&85p?@e?8NUobOO)`&wSu$X0G9u$* zHA2-fSylmTkt(vDtTAwX7Zoh#rqCN6r9y8^&I!FKo|gEWo>qNpn1bcwXqPtvoa886 zSuK8Nzmc@RO)L_`Z7I{|CUi)syah0?&2KfE_(i) zhF1{c-#GA=mZmGj33W!wTMcdMBQ)V>PVKtCreJ-mwB1{u%t|h2B|G|Tjs-vjb-hY# zsbI>+VhhE#Yan#PnJBB*d?2ShbIFaRc#n$y)i)Q#&AxuNGk$0l5%*^>*u|(^Oh>RN zmH*s&RSPP|b1#BeqBMjAR*5*QdJ^NvQ?6>yTlCrJ>tX1dK#BeeLmeq&8d#q*cxYT!0dikG7yD53Eo$%%1HpS+9EV#smyaUy> z1mIjNT28KUv{y*CbrUtWkLIANQ3;w*(|d(b0(^h?gt5%3F`TnWjX#j0Vw^8c!?2a~Vs)|c` z;qT#!xIj7RZ=q3F=UAghDkb>YMlBRUIe26+C3hOTcsLrpR9{ zdj|)l=p)~KR(gs3un2{UqCUG19oJ|{&o;q~e2O|QRoa1|)!bVp!Son;{*`KR!VD+A z5imES=r5~UWpf>uZk;oxP^rSL8xpuh6V6?Ld7BtTGN6CeJ?pjZT8R1`uBM{29}s??at*t_#I-^aEzzD(^{0VxYyR+l^1lk{9P(Ne zl9eC&(4D)g`ZK~ZGo$~|FO(37qrJ(y{e)`cN$%oTW4sfL+#SevH<&Ra&%9uagnMi> zS`>d!WSvRwqU=m^cancl)HlKlh)PT8xw^YOoNc?nI2HWmA8~#N7(ut@e{Ct?*ElZ0 z<#n>q3=h!TG^Vb+-6L3`W*dGRlZ?dI8Gd!$f?sdIZfqlDz?3#a?D};OUYNgNY-P2n z5o+De7^|f=edHm1soFI1G;H%}BM;mx{Dn_EruxLA7@Vfy75~hm-amoK9Q(e3M3?I$ zN~TwAVXf7m5ekE{Y&zR=s(UY-kJJ30ol9quThn1$Tf$p{6pal@2!oK3_;7tHTVR8N zjuL*?s>Ww*AG6^pl{S|0nDn_WJMV<7j1C83mOhXUZxUF|6U!T2K zDZ6?*)~schSJ!ZDVH3lcOY&4E_)cxyU0;H$djd->G|d+#QzH#cC$ zY^8WSkw>2-4o>0`{FdJ_H+UM4SWztPU=4h6G6YDAlfmnTC>osNj zA^$^DB2n25yLmWpVWv_cLi~1FsZ*Gcmc0R5u$6U+yHGGT4Tb(`{x4j9)~5$M`c8+d zz`Qt-{iGY+l^Op%Ok67z-sgo(q#&NHT z8_8sg{>Ca#2hBGfjP5Bm^Abl;36!)+&>o1Sp>jFAaGl$BISxoll;3x^MlOe{n#++D z;>)p4yfHCc?d(*H+L(Q?Pwk`&t91(RMkQC#qT3X-ev};AZ4Y#LbvXWtl|wF zEPeGbW$_l%;Eaf!1zzQh=-HeR2yluMny6_-g~}b-5ba~iCRPUb2bh>0pjAEJtx1~n z0QiPT!&BIc+&CpgW_)Y@h@?CW=ZJ>k$Q;4Kq{w_K!Xw6?RP%={K;ZbT7!0Yds?Q|1 zq{S&z*c|15XT)ZxM^a>OG7NAs5ZwT*2QB7s53FBKJZCkll<@t8oAOiEnPC7tAH38J zl3CZ)v)6@Rg_UlRh0M$|+@(Egop?zdG~t9K$ahy{j|T6 zjSAKoB46YPa(NjxE*Q{)b7p@{gu)4GQ)U|P67dlLXzgJ?Wc33tj6_HGcdLlQM7C!- zo#3vpRh6%Gc%`U=Y5ZkQ^j5m#&dru5>LtEC3jV{o;wJnyQ+_TEG@N;Jewa$n-E z)*)_x^9qftbtq}MT54*{)w-W$qfo~K73OLkFb~9fZo68ETrEm__7MuvU{NG3KMN+3 zpEW_wFd6Z)+D$f53JXKfQsqdoV&Q&PVSbk3yp>Ii(EKd?twA`g92_fbJCMC8kzc{> zC4zG%`j`0Z==D4aOGh+QwdeKGYoOV+uyFL%Slz6T9*YP4%s9swU(OXbJad-B@z2WV zB#%c3DNAL1fnPB&fZ<}hTg4+Dmdw||;8uYpxk$3L`{6lm49ZKgPApQJ=W9KRJ(+PS z2M{-*b$c|s;dOaXTuhuB9f-|ZQ>eaO+I^Z0(Sxk{7Ix(}bgHW(kr55zOg8HwL|;9_frL|4Xr90ym()2>a>- zI#WTCr-CFC6`NwomF_4ht!@!@{#5`C-TfEkVlz`h^_= zttMI#2#s?Iodf_gm~o3g8i6=mM<9~yo{6}&ihGkK5s2ki4G)???}0)~Y~g(@A&ZW- z_{lFt+hio!sHo&oOL&m=yp2>4@vVMi2swIg7p-_}V>aks4n=rBVY-jLXqn)tuTS2=aTA1u```5>6+qX)^~mD@Rw`${<+aXn9obK z3fQivY-F zUg|o2C?r}-_X;MU&EG9b8~18JhXtFgkAd12>3faXFVGZC9O2HcD{(LE<8C{Vh z5Y(BC2^x4rQ5-B@tK?bFrgzo*_bzdCmAW^n+}ou29N@?MaaQ@bi^nU?drg`jfz_5s z^Zqeurs#6gtmIK?-g`XKtZHM@e5Xq@IZuf+BZQ@TacL$@o&S7Wns0BUd2d^q_briT zF^)^~#pXcO@+?PB;(SQG>~M)T#y9T_K2mJTVc4P5#f^|pk`6@0sP{Hm$@nC}7FgN~ z)!rLI-}eBLMF>1N?fWd$iSOpBT)acLc<}zDGx38)BmzuOs@l2Gv!@450N{eq^k6b$ zPVdV%__boy%Z7kElU(fTLxy&;Q6HD70=btKToaYm>fTWm21+Yr69Rs@%v7Yo1*(Z#L_F4ctuBmk8BXek0~4n^=_d|vckHO)N%`}E7H zYjsidO%uGor3ns&VhdhMi~=!C6+p`T7fco4w;6P<3bax$)wfqwac`CYFQ?IpDzs-Z z3Qk*-z~@u}&{Ay5ZbKw>1&&>I4{T8mf!`;FodTUUxh&uzsq8FD6@ zRH8t>%22cv$72&5TYd(EUX059e99soU5F@_of4a$whyqE=#6633CNe#8l;XY4FYT% z8RStt04j~CjMGiIbLEOpL7$xYw;e^YT&^+L_mcl|TVq^NoBzvfGAGK(xXSqdR%84Z z#UidRu5I)MTO=2JJ;OBwdo)ZPz)j3}%~D=w)?3ENqQoxbyG%hV(UvD&A{S#F?Vd@l zb&(YUi+U^*FC6I{m7EfNkL z4;7-U?7kEsynh9B5bV7sEXiWw1 zm<(LxU&GKY2VsJtR5Jm24&u^E0qD7{0LDUp(n|ZQ@3OQNz!xUt6DkFuZ`s7hqW}t^ zv3*5L6u?GT00$V8X^CP)11QLYdnpT#>{lXHi)VfuEYg-3gr@b`fAbTdwib6?h zObOi6D1qH#IHZo{Jc!pRbZ%BYKkJi-aF_`~bvy(@;*4ASgK-r%J@8~ZdG-Sji5pL}5PDf%GnhcuMehARjGXEdZQWxV44!~}Pr!U{?M$*8aW#E&3j(T74ca#;-0=W`MIS^8 z$Ukl)@=o_pwCy=y+-O7jAPB2#L%7c!X!My;nsTerxc=o#pz3QWQtPyQIhCAFeHD$n z)n8PvrFK@k?tHw1Vd#LO+doh6t<=-D!C6{`wSrh(?{=jrnlCSp1uKJiZ$0VKf=^*+ zd4W*pd^vSxe!HVlu@hzq@-dj9*o4476x2ozcz5K~s6naQ+(KyfN|l2B3bQH}yEa50 zZWQbXQLy+ttftsrNcP=8*uc*FeP+ex96^DCT{tg#B~P&0BJbL>q?yx{Y1kj9GlWGv zr~-F}0wz47An%5Vx0-g<9{N@4W);NIo;67T++Erkby=C}OOo1?3Z~L>8=FJi?ieQi z+}In|uDON1B=!2k%_e<8vtDQ8u?1&isM;p^^-w@&(KrJ&3_+lZj0_`fxmFCM)~tH2 zHS0Z~c5Lg4c=*6_s`a1y&C$5sODAOsxBwf=dRRbCt8DIB>SFD}f9#TZuu^jxWozG# z(p#gigSS5R=TdWqw!MKy$ z{i3s)ZH~?g%2{Tcqv+Ta_?t>ASC&eX7$4RxVbfxzJrV?mf$XILnKMSIhecL9j_@Q+ z^pJj${0I3JU}{Htk5nq|SE~2S)Pv_5<@ukvs#kkKAVqLf#X;Rud_~q4zSWzVH!8MS zJ3wI_1I`$08%S`lHxNR>MqW0O1Jh!}mM}uWp@(`$n%+Ob^m9zCH>p-N#-8+pn#dKf9cT~K3PU}2^@TuRmP8IHoU z)#NzM763V!m930?`0FF&RCS&%=JF_V1S&Wt$Ge}Evv=;oj=2z9!Idat?4~9_m+6i^ z6^yIb2F@*GznxY_+K%#3kSnCYuU}6FiyIcBY|5zMSB_>KUb5>O)6!gWWMC&2`_Z*d z0MIey*LNSWgNW;!=JQ_?IqjmO^YwR%>tLb_w(Bx7Z8hR*GB~b~g=Y3g;?;xjVK1K> z6rJq9Eq8AzZR|$wgiI-YzZgrP09X=f8S7M8kb>_1s zRGf_-kWH&eBa$9F_UW#TeF0+FubXaRztyq`k@=m>a>S2Z|rpi`q(GHka z<5;G}6-O~r(GhUGqwtSb27!G%eU4OI7U{arU3_coOTb! z{p0WRvYWZ5?6DL6tJ=5#iX^ij7gr010|&Y2aI0U5iZstfa*U7hDvTsn53Nom83j9M z>|NvNMcIE#;_KCt6c>lX8fOXXSjM`rnLNS@Tp3B*#4L+Af3+HQdx7dj*OBR??91>- zEd|E|9&%634!%3QBp7f2&Na08YaGIIr*-INlL?tYY?oWMAeQ`RuUP(brme>$oO@xcY^#iH$8yGLtWTB>j?ri5 zfAk3BuI=HTOS|E%!eTd4HHpHdn9`VD_t$H`)yNlB-*{}WUiWndYXqJPO}a3_c55uZ zc4K#Lt}7uwzS$eK&SXzV5&EI(R&ZP!ngEv{JxF)@EZCAaDfv4=;Yn1O+DJMNN*9`&0vs$Fr&FJ<00CsPn zGeO%O%Dx+Hn;z5hiu^It51ssG13~gC^#X?>CGHgbM;z3j<1}D4c6^?3lieV&x!84w zxlj`maguhry$Op1Zl2k72P6dPe4mGQ#f)m#_Tt#JxA3si@u%c~*oD@Z$gwik!1kpj zn<`aZHD`@z25k?LM0?OlUb_=N1|$WrYx(^P9PtivRJ1O8MiVwR4D}-b;i>8GgG_7R=v7Oq!}3s{^>*r=_$#7 z(&(Sy79vaBqLRJ9#Zvyh<`Ss)c@<>kLKoVKHRJrl>eq5jNOUggUbl+|foOe*r& zx5fUv+7fg5OeuN%x5a)3)d5l0Wz%s31>`p)m+zAXjk0GjGO6tG(m$i@^JTU>KKbj@ zj=0)A1!oiUi?b8e1K405ntw=uXa94=W(7wbUmp2RYP##nTjUPp*<`SB4GJQS5TV8z zedz+a$}7w+jSMr2=f~kx3yM;A)LJ@oQC{Pbn`wC+y_uGTaM$h%H`5**6?AhY)x3A@ zH{xmpS~TUiGwiO8xmDRtz1AW;#RbV^qMM8YU(tNjjvVT%dbZM+1TgKRwZQGFCTIZZ zudt3_hY4#{1Rmv)KsWz9R#Q(>7}@kndfMEU`&;pnr}pl@@$3F@LJ<40OIqt2|2kin zOIlw7{|0Tubhe(2iPfA98c{Oq@dUmq3qp%V{+lbPjLW_(nr8M@1jvyjvo-~l&@uI- zM3Dzc5-qb|iP`xOn8?qEigo1NXh)hH>K-Z;b%M5h-mt%p`^I~7!^vXR7PzZhOmg?N zU2;n*9JQ*F5#lB~M|eo#EbgSo%19+ms3{tI-Z~1qWEL!0n;*)MYHkXaqgPCp_r8u6 z^0&HbC?>gi#8ckvDPZD9@eM6XrLoqdW$4;(h{L+X2<13HtfA?IrI@*;*5C87xUi~M3@Y`SVmt(}hA0~g>bT87T+RR7JDQZ--DNkB zvai}MA@6uSftD(oyB6B;vxXlbn>K~f5ET$DV^^jSMGU*Lss~AQVQzJ2 zzO$=o{KVN6uR-kUx`8$VyBZO=DHmZ7?>Fp<@$#$9c?c^6So#7!4(y72EX%G4#1eK* z8g^Z1>}NAZfn_iW1e_6DK|npTP+-9clH`K$r%Liw1eAILLziEY8L_I%e~2>7at(L- zQ&Y}9Ny?b8SIbi_Zaan)^N2(C>Da^xM$l|VB=UcO(Y{?U;;D7qQ!8+-xcvcrQMp@$ zVa!{T;)(OhTSFD#YFcTeL;%=VvM^J0x2#`AlhD&&83?(D<%lcQF}DyrlJaR z+GbS;g;?f<-5)SEj`^;u&1v)B(Yu`*X|f6F=LchOti(~)kMQ5n`2}d9og{1T`E)3Hjs} z#XI>|)RHY`cS8HX#Ddo_YF_iYJDF|n@w7Vh>U}Ub%zpXXlf0Q(qvvBcC=EmC3A}$< zW-?G3>2%&0q%BHw!FHX_BHI9JHz|SA`c{!*ouic2rXfD{A~N@!#8vxXn_K$cen8u_ z)Mg)8l5$b&b>$gM-z~6VAK6LD9&i0?esmbkUsH0+0PMXmUw$83&j`{oX(o=RFAJ5o z-b!nxvsfIZNu-9*VUit-yWI0^@FK|W6lC%k%JiCH?;1#D9A!}7rM%~_M$Xht7=`RC zDfxq<#ARdPlGonl1UIUTY{` zbiTm^=ZDlVYo0aLwy-g#<3(+ToaFyvMQA^NSWg;;4NLn~`Jh;N?e_Baw;lkU1Bk;- zY8vt&Z7{h5Vll_9!rYZz{7+0jP&BKI|>zf9(Z| z-oo}k4_1W%qq7Vca>0G1!;Zk6Qpk=A1r~ z1?z)PA9ZCG6AoznjR?ao@=7>UF-zd#pcADp7%)GwAAIkNXZSybZzoU{O;5`9>wQF?&D>uv>Yn^za}`HP$Gma{DsW7gC6&j%h+7MWlz)P2nEEOaUCGgM) z@au>uPYz6?RllX3QpSL^KHDv&a8qcP`q-dxZx(aQ&UYhgVjv~gXvNt(hHq& zdr|1@g!y6ajSbngZ6l>5ig}I;4yKCLb8|&LH$UX4mxZW1=kQcnwL)kXnL*qmCa_T%ZT*b^RMf2&IBB!^j)nnEh}`M8LP8UI$yC7-!B04GfQiVo^fJI&z= z3p~z~5xCsz7&SO{C2VFoE^6$n+;;#ZURCQjK#_fw zFCfa-4vPE~VC|b&$l+Izi$RJ%=tNT<8%dyRt*CI|Iw6fqm;-NUD?QD@Ug)2I5Sffh znPd5it}!3BeQw@^!nM%JX#v|ojp>qrDE~*3)2_zMn@=`60Y#D955}rY0v9rrU7p-6 z`l*SsZxVs-&aMChVIZKG~0kb|aI zhpyfoWPcWJU1JA{1!V4fG}4=LlNW^br&z_ANzIvwb7pI_I50_zM`7e-j7K&7;MkS% zC=m5+dCGV+sd<#SqOfK>YF=MpPW_l;*uctMh}i8JTy7!Jrk!I+tGmWrMeB0x{xj$f zujV-8i-y;`^b5L23tKAve!_DPjuy65azEp_heB>BY^mhluurHemNI5`g(hKwO{BPUhmW|^c~H$ zRIqWE=N=d>Y^mga!gCLX+)&t3$^DGy9tydku%(iFkLTVOazkNDCHG#>JsfgFVM`_V ze$Ra{8mfGaruH2)B@7VHCTOfSQ zmKRc6D+RzNU8zfLn;NC0HfAwp#4O>3OyY%93K%UERP0fEZU+uEaqD>(vO1biEa!!w zw-j}1O$oGQg{gR|^gltgI#gfuvfuBrHJ#Rp+RE5e5hC>Z-*A7xL9|IOzH=VWEO)jbNe)hHi$#g9$*pqd$l}k z0xeLO7C+`MSujckt{%4$S;g`>w!4W8afmV0%cTQ6QoPD$__C zJ}?FUUrpOvHDXbyo;<0Tk5_9Qt+BgFW#m>maG6TGpWvnaneHnat^!Rz^>j=K3SANz zO@i~|gfVa{Jn;!-4a)r>E#Sxx!j}nn@{i?Ic#<78?@+y(3yB{ziYK8aI0qwCZxK54 zEm9SsC~xy|MQ~egKq4^feu$mLWXlbR%?*Hw`WDxwVTM(^0g1L?;(5qbg#|@lsNp|g zyPw^k#9jNW`PxCOE|OW;`QL?uBJz3M8jF;!A!sLDr0X0dHdnR_rMT+VxEgNqifpsB z;D>r)Ikb8assxJGd2|nUI$NZ~URXmWTw^#UgRlblR!EanI_^~6;c*inQpg+#wI=4E z&LpQdQB`em0BkWFa$By^#F#aN=V)hwyl_@+?5HL5v{xw$p>)3~&Fkf2o-P)*ckzjY zajh^yJAOi%@n{2@wZH;e6e3M_dRpU9wk8X7u=a#3`%_^TEd})e$z~(Ou@$ypgPz5) z`LY>rieo1p$4;s^w*0rvOrx~xkmhufD5=8P;3q_weE+Odt{w}AUg9FDLN!`#(pF#( zw9$LF9h@rsV2m&GNC_yGV;F#ugmAjYi(IR~ni@625i)CHYD40Xkv90@XDXfs?X0_2 z1WcXiFiPMIu@Y;jE=Pt^84dU4uakP=EoYWZ(7#!740Ol`W?6YN40X;$Dsa zHaS+d+c3luQswb~1ivM=2?h+nD7uDQ{Ni6!4f>Uh7h>-+z9xT->sC!*ssKkbB_Eyt zPq;oA^n-z0Rh!Vs)-;v)K-iov+0=vI~jLWBE0w3nfhn6d~g=JsPPqFf0Z zFh{UI3fkOjwkFQrow1q-FNVc7c%_LF8)h6j^T~TS-ggQkts;5KTId$uV0=pkj1+(tT7`Pr?bhd z><$=dM=g0-617x+h+WW9m8ZCjCZjnZLA8W#;*>7%H$s3`=8|t;BJNci>Ry$GI2(AL z`KzQ82RzE@^NlH%Po9SeDeSsM3HDT@K}tBV`2c-Q$5k*jsnnv}_7Li7&n)N<8nIMe z#fa#8B&=CCu<}j>8>e~gs9F&uS#Cm6q_)G2&BMPhmu4RKyoO&7#&)d8!%90tB-GqA z8FuJfxo%?InGj83-vI{9)g?i4Z}>D$E`MX(yLZMuWjPwIjU1Tv2E!sx6(Cy~*(|eF zlmqd#Y++Z02}ic`{<6qs!*_&b5g+`Kux)3q+ec*MGl@7ak`Ei2lgO`6uFNzB?|eFm zVvJSFEa*{f2pS~FgB@?zVQ6zS_=7>yGr96&@Mp9M1EZ(WJ$wt*jE~{I+r;8}VY5O0 zZoTAx;m}bMq=b4?yd6HidT)rE%}*R!ow0mAp zw){=TBmp92Z%WQb8Axzy`DPaY-VS<(R{%C9P(!D=y8(?4N zx`I8Y+V+!bdsp3-w*9cZxaks@-QS2IVzq6i8z$uz(-(tO|5BowiNlSU48jr6HyB*| ztX%D4X*JYlwJa_4>a}N<)~LCKG=ApUhB9HUy!J`>Y*Cke1RszRmI)Xt%|L`l)nkKa zf6MA#rCfnreBGNTvuE>pj=QrzJa}eAA!Bkn*SWniSGVo2u z7fJ^3GbD4_3*4IOL&=t6{Oigoc!2EQX5&?@s)d(BGOg^D(&Z!UiVf>?Udxvhar5Ce zC=!+wr&eie09%n-^xvXO%j?)bQyiXsgOohe=E-*~DOz4l>>b(9KU#hD#R|Qm_Gl_* z0%m7sR+^EJOTQ5caa9c>Dz^<- zKOne^<6mzHs|U%@R!d=q-EwxJfLx)#!R56jHzK*ntg}sXBKDSbehR=Qo~AI0)Mm(n zLe5QHf?Z}oqv(Q;swFNG_Z6<}{0J(jH`742y%k+(;jMg^nB05|7w~Ft9L<1HPH8It zG~TkGXg1A`ZepXNXQBy*-;!Luqj?%}d;8!7Rd~s1$ofkUS; zDISg2QAAS4i`G$UM_rJ;lpbX$ESVuwVwXxtSi2%O5wa5vPQ7>SRJ^rgrD$6_1NhvI z>Trc$C|Y+!xWPKv$*`;ofVO!LyQnicF!YfBr3}vdg6IdyL!RI`#T(&2IZAy# zcA)a7QTsnpLoKMgN9A$hP1=#-B3Tz8p;Ra0kKfNR$97@hVQ;V<^e3pLm^~A?9e7Ok zP(<6alZ5f7L%{f&dH$Zk3C<1&ZOy5ILkQk-Hbp0V_%7#m3e_1LZ?ubx0Ef+t1ROh7 zP;aaQ#21)TtZHoY%f5pq3M9U((pvuEIQ`f`K;W$lfZnXsyJng7n)FUZ!&`~Gt6Ty{DLPi6&OF69AoY(t)6 z(J>{9$V#Fj!*4&JhAVKkH;>nF-i<2)Y&Na72tNB{n7Aak0_f-Yfh6@nwx?#_BWfpQ ze$6b>N!P{@{E(*kHmtn!Il~0!1uT+^+GT4dui}7mxj%8%i?n0Rhy)+r;-=xn^b`0H zDUHrFmb9U|`yScxW2wQYJopB&Iv1;I38p-x#L8ROaOmcd8y01ObXAXV zz&EDQHBi_uNC>M;G0yRHlEhN<gf z0YI?uLnGs=&POE%}m<2Ei*2`(qHkKXqX>KF40@TQ zZTW%AJ*CQ=Yq&Ur1JOW++F=e(AkCkmf~Isid0;37DCMx>mkrn|p3WAWK09+4< zvnI(tHfuH2$-Py6a*tMZL+L6VSR1U8vzKm&?Bt#jIk`7UhpYVL-lR_H_3fT>o!qlU zjJ}=b+YtH5J?&9nMHpgHa%;AtF@u%J=&%bh<6Zu;fLasvD1Hk+wAH~}&ZMv!P=-f>@pZ8{HKdla%@ zd$(HmUAEv;M=|tW20FJlre|~XT+TihVt{MhM+#^aM{@x@sdb1p4RiuCiA*Mqi1>-H z@nU4hRNMy+A7?~D-G@!`_lXw_TeOkLkX7F@N}-RDj}v*ENVJ`oP!0%0wWK6`Ci+{7 zsBZ}3$m0*cxsi38J_xz;t^M$ zA97!a08D04C8+uW9R=;5vku)oOsCT%iVcSxMsS$fB7Y6-@xv_t8f}(M#f?%_cA${U zYtdz=)3a3CATq8-Wnq2g!$R+3m255IwHV3#vcr!>QZPcB^-0h|1fX1neJv4(D@xf_ zrgc5mGPdBJSDi0ymaLtuOQ?`3SGC9k9%j|($~j_?H2Ys8iX;sRGKC9VK@va0%1S|| zmGaQk-&3S#PKUX8)2Yi8k67AL0f`XQs8z`wu1a)4z<<`-4Z8C~O3FUjjVCJ=jnCOY zz;$~wMY>rUo9p({0^|@FRnPRLAK(xGVb2s2?*Cc{Y1jpQa>8Yipa6)0AOmQ_CVy?` z7OU#k6XXrbGK<#QESv@B1S0D^1*2Aw$#9F@gVqMKtJxVZ?-F37rkyha$?anv=m_=4 z50vEQV{x!)3Wd7-$RLJd0WQ+XCqaWgXaU23dm{i@Ft-5+ksbv|1jVuA=thiL+n~$m zz#y%!@d--7qwTKu%a`-PBwa{(Oa#ouF8tGJ93_bED&cBM`K)UXU=XWi zBLAczp87s93KRgV75b3^$9o^l7hv92HlZzq_A%;of}v7`C#F-k1xaDEQN(IV&KK@u zxkqU|W5QD!IrO}{$5)N$M)TS-qOVu#$Q<(UJRK&$@#6#>4x*wkJD+1(F%^ZE{#!s? zQIO*#YZuD3ufU$z>BSycXL2x)=HiLPS*`)lUif&hivKZ*qyG{FJMxnUI15Bm<@IyZ zDVlCt17Mxstykg?52Tk97Pe{i|U~Xxf)OMmpp&90S_2OW?#cl>c%arS8+awls92X zCmAG<7jG~3a!J=J#E7@OJ72I`=39Nx+!@~76c#IVaQ*i3N-U%>!)Y06U}~&}Qh1%E zzDTQKCx($158H3sfT$i)lHh=7Q-83qYQ+x5Xy90k2^}aA!G;sCZMk^EjW=Jr zofzOm;OaU-ngV_xzS)x>*FfP1NCOOlUud+%rcbUj5Fn~#p)-S8eTrDPd^KN8ARMc{<0Q`aEqUg*$>em6c+KAG?y5@yy?1hDnnr zbi>FjXhW1|Yb`z0FiY!ZKKooR+~{GeZsm8GrB@qk6${utjMt$^5#Qi*!dg68KAKn>&{nIgT=p_dNDtZxRofM*s_Y7fZH5>*;y-7$Ujta4_K! z2?7ERaqmp;?s(_1+ugg~4G=lXg+qiA4q%}mMFL?72@#ORg&fR{6XJkG4naa99Jq0S zQ%ub7U)?i1vpY6MA&{}k)m2@OufF=8Rn@h!(KNOn3hR*A5ri~kv9D-#^lJEzTFDyi zf^Ez@7HYRxg(kJJbc7Mo`ZD%i253_IF7r?>mq}#Rzv((Zt!r?mzshS4T)=xfz)xh% zLJ*OTd1w|M71$@hg@(9jWzUO!gby?~ozwo&sb-wI7ryKxM7unT z8MU50&(L*j$6f$LZJQ;NFr_O4h_n|oc_|r>0amt9d81Vz9H?6Oq(Eb%#wM4cqTn31t1&H2<-V^_v2+kQg%aT|N-k*yAt|3MLK`We9tHyn4uo!6L*$;W3wp7905pu8YahZ zC9T0uXyiqcqe-^2BX;5`Whb6ecH${zCrXN)_@q+o1WQ0gGBhU}q2a7h%SYHEpSe`T z<}f7zbVi1$2Jnq7*8bCuF=~-08UUZ43_&oN<~*dyOrS9z|9M$?IPCf0$kI2arVb29 zyx#&z{KxlE35Mv017+xWdd~9)*tf*pjNP2l(@jCy7%o?aJ-euJ7;}5br{>y=xgDr) zb|>`EjPv>mJo#W{`nyCbOnoQ8G3^D1L#~()S&;L{6MfqTT2ZuI0if+0S>RdD?|FBg zxjnbVqlvGu*_ZFK28HHCG7GDTtinz|I6mp2)MLPB)ZAc^K_?l5mh8~$H8`2~ZtLJ+ zLLpfpB$Zi+=EwsVxhc4q{w~4A)OW(gv=`&JVAx}1Cig+ms3yx31{79FM$^K|i3ncz z6B%J)PMOGozZc??bFo60_*N*%8k8_iqqTrJtpjAlGZI`PH_nca_=TsGUwBISg{PEX zC^>`(eqo)GiIsId*$C5zZb_yYeqnh+Y_;&|jFvdlDM|#aR1n$));6o*iR#vZNpkT3 zo5VA6nMFJ*F?6FBwkDSQvnS=1TEe9cEhOSzn9?3GLmk^BGJ8v8jcpQ{TbI~gQZK4A z{brOGGC==P(~mdq7$=4noyr7~ML9B+a$3wZMpF)_N7>H_%B0-Q=WppTb>6kKlD<3% z6e>UT;dM=~+(wolZPWg~H~(J->G$tEkiI2v>3@kOv(S6biF@@vK}u&0ZaF-0FK6~Q z_O9W6j_4P^a4`o{TJRIhj|W9?yap40YzqZ&l=B|>D~V&kCH5jXoHMCVsgJyO46TaL zg!`_^E%2T(7k6<`KjZ!A+n}=Wf~-1A?4R*&D#v5@LLE`wgMl^*FR27AXO%VNtA)R2 zb6Iw8M@NnJIlw!WUPo+Qc>cH6SEUNgVF2al&I2G$4SzsDYld)`DRgaVMrEJ=<_-L5 z-Er-`ZuOCYnb`ZKV7gMYtWQ{4rFoj0Ly?)UTiuPM;K3p&T`d<`7w-J}55+G@zXCc6 z!>l>Z+@RY(o6~~{7_`R)IJWX>eAM&o-8)D%P;xQcL?ieRli*6KrX`ShbTf;?!&D(4 zLAP1y_cUP!AKodnVTx-lqYaN5ai=GnQd-CI{-#|w5629lHYWKV0*Q78A@DOz)WRtF z@?`QCCizO1t%6kGiZ*P>OK_qem}}Gna4yb3Fy=5mFYSyLxezzAkfP{J+om!`q+(gk zO1w*5n#p;RIhl3%6gkrarzx~@M4Rj*NYiEHp&n70qtY2D8(QP?knD!{FgN|lC^buJ zSkst8*d)?~9My^0j+4q$9rQe{;*Zj?S*$b7Voxt-0Mj7H2-L%+rE!e@!_3#xpV-2j zZ$QX1W;4i4I>^*apB$vM@Z*^jdm10r0cyjz;le+|CWA<8Sl~7TZf5{d-55S3oyRF3 z!!`DzaBWV4YV|b1HAkW*am_xCzU>&pHCFNv*ZCCJtTfy|u5)+8b#5B2WscuJu2uRV zuI2j39M+N=50J$ChHQ8{`Qy!C4RgfIf&LbU#+qV4Rvq>LM3A%!UD$FZMMN_jIws8b z+lyvx85*6#6j$TM05>~4thyxhhEx!}&Fs@#iUUo2vVQ^faKVfrI_P;PB|25a*3g}f zDGtoW5&kqz4Da@%*l8#;xq zQXJX)C1FOun;;O2JHAmThAu{wcW*8S1~^^pJxTH@Uu)`?MBs*&VPkQl76IiibQiN! zH%B3a-w}5*a^s*R93TlW&S;1GvM>j^Kh#Qkp}cWh@p|>`mvbR&Vldk#BPsZEBlZ^V9M7Nvuidg1{&D<`+y8v?j%8U{f_}v(q9BZlJ%6pg z9jyed^{btJyZCrGxDvGDsMs3xTZ6FO+3qce+flq6_53hiCN~cK1Mf$fyzcb|{qeeo z-bG=n*y(L{qqAXT75Miou(&gp^)ce{^an_PIqbxp{+b;RY~S7iu0d!=>x1oX+m5zd ztsrQh9o6{>ZG4D2r_WechWG(Oo}lsO(r4d(v=eQ1{XJVC1ihdi`*CN`x5FUb4*Nmd z_WO1ahIF&t4|X@{F=%)9ESfeywL42F3MH+gTWz^bw_UIK?bY&XrRmrFrdx9wtEJVz zX$2+6FR!@ml~%FaSqc4cujqHXgH}-}h~kie2?w9a6s*T+^Djp%>mg$GCAbyl2=fG9 zO~7!Jbc@CS`10pBHG*^Jw)3kmH9rq+|gEckGUhiT4xSQx0I^sjh6HJ1J^&nF4ljFnrDEAC4Pli{SM_z6t|6Z zF}0bz*LeRh@1KA#MJor(ZTkIAYa-p3FBo1hh)0)^ph<8AYlm8zHAKrt4|{AfxqQ%`mIj9XAgFQaJ4(Q zO8J|>DV$zU;e8PJ#BXN^f?GeeEtt>Qmh~sf>GyYHijMk2y9EYWtG&3`-|mUl=jRGW zhXj<;n^=iFVuh$!Ox87_xjZ&lBs5GjLTBF`*G~7nhb=;C$b}Mext+{o# z;ks_K35ZR)Z_;#=YE802zrPmPQH&C|(euHsZ4b6%8`?_VtV*+XJFP%j2)DI(-L|YZ z!H4F(Fki5ih?BBGzn!-6DEY$f@O{!k(!S{{vi%t9r6($xgw>{w=;JA3(QY)@4(T?j zn)ZxnZ4V&${vft{e%xBO+d+gSkTAq#(d)D$+WRT-$B8xHn*YrI`3DGZ@t3{lZ*0%o OJm&Qq>+w@EWBvtAtv5aZ literal 0 HcmV?d00001 diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/AddressParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java similarity index 96% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/AddressParam.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java index 1779be136..32b550901 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/AddressParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java similarity index 88% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java index b1ece595c..b2568db2f 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/BalanceOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java similarity index 94% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java index b6792c1cb..47636deaa 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/MintParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQuery.java similarity index 84% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQuery.java index 981db4feb..1aeaec5f9 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQuery.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java similarity index 88% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java index e02232e7f..13a107ba4 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftBalanceOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java similarity index 90% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java index f2c442b17..fd2cb07ac 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftMetaDataQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java similarity index 87% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java index 2f974dc40..0349fd97e 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.UInt8; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java similarity index 87% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java index 8cefcc7c0..d50ce7463 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/NftTransferParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java similarity index 87% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java index 41503c908..10393e8cd 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.databind.annotation.JsonSerialize; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java similarity index 88% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java index e1212bcfc..f17f79eea 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/OperatorOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java similarity index 97% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java index 332be94e1..ef1724150 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Receiver.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.AccountType; import com.concordium.sdk.types.AccountAddress; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetImplementorsParams.java similarity index 94% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetImplementorsParams.java index 0886f9842..3492205e7 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SetImplementorsParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetImplementorsParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java similarity index 97% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java index cbf895aa0..bd7830059 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetMetadataUrlParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java similarity index 87% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java index 02daead5c..2895e1d05 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/SetPausedParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java similarity index 87% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java index 4c3ccf2db..31b9449d9 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/SupportsQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmount.java similarity index 59% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmount.java index 377322ba2..4f50c721f 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmount.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmount.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; /** * Tagging interface for identifying token amounts diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java similarity index 93% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java index 958eb5989..a11ab2663 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenAmountU8.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.core.JsonGenerator; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenId.java similarity index 56% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenId.java index 2ed4be5de..00cfaa1e0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenId.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenId.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; /** * Tagging interface for identifying tokenIds diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdU32.java similarity index 81% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdU32.java index bf950d46f..420ca0518 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/TokenIdU32.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdU32.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.UInt32; import com.fasterxml.jackson.core.JsonGenerator; @@ -21,10 +21,14 @@ private TokenIdU32(UInt32 id) { } public static TokenIdU32 from(int value) { - //if (Integer.toString(value).length() % 2 != 0) {throw new IllegalArgumentException("TokenIdU32 must be odd number of digits");} return new TokenIdU32(UInt32.from(value)); } + public static TokenIdU32 from(String value) { + return new TokenIdU32(UInt32.from(value)); + } + + //TokenIdU32 is serialized as a hex of the uint32 value public static class TokenIdU32Serializer extends JsonSerializer { @Override public void serialize(TokenIdU32 value, JsonGenerator gen, SerializerProvider serializers) throws IOException { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java similarity index 90% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java index ebd06c436..497fb14d4 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Transfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.UInt8; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java similarity index 88% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java index 1c5409f91..604c10e74 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UnwrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java @@ -1,7 +1,6 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; -import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java similarity index 96% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java index 08f485016..063b79e43 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperator.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java similarity index 88% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java index c51c56171..e75a8aaad 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/UpdateOperatorParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.cis2nft; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java similarity index 96% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java index a087015b6..7bc3728a6 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/UpgradeParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java @@ -1,4 +1,4 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java similarity index 82% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java index 19a1f1e9f..d496890b8 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java @@ -1,6 +1,5 @@ -package com.concordium.sdk.examples.contractexample.wccd; +package com.concordium.sdk.examples.contractexample.parameters; -import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java new file mode 100644 index 000000000..213397d80 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -0,0 +1,4 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +public class Cis2WCCD { +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java index c84c49904..85d841f09 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java @@ -1,6 +1,6 @@ package com.concordium.sdk.examples.contractexample.wccd; -import com.concordium.sdk.examples.contractexample.cis2nft.Receiver; +import com.concordium.sdk.examples.contractexample.parameters.*; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; From 220fe5e2a571cd27e37dd65cfca624c4305d7da4 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 11 Oct 2023 14:53:34 +0200 Subject: [PATCH 23/53] Cis2WCCD example --- .../cis2nft/Cis2NftParameters.java | 14 -- .../parameters/AddressParam.java | 46 ---- .../parameters/TokenAmountU64.java | 30 +++ .../parameters/TokenIdUnit.java | 28 +++ .../parameters/WCCDBalanceOfQuery.java | 12 + .../parameters/WCCDBalanceOfQueryParams.java | 13 ++ .../parameters/WCCDMetadataQuery.java | 13 ++ .../parameters/WCCDTransfer.java | 15 ++ .../parameters/WCCDTransferParam.java | 13 ++ .../contractexample/wccd/Cis2WCCD.java | 182 ++++++++++++++- .../contractexample/wccd/Cis2WCCDMethod.java | 18 ++ .../wccd/Cis2WCCDParameters.java | 212 ++++++++++++++++++ .../contractexample/wccd/WCCDExample.java | 102 --------- 13 files changed, 535 insertions(+), 163 deletions(-) delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU64.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index 9cd04765a..0a2fb65ed 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -136,19 +136,5 @@ public static SchemaParameter generateSetImplementorsParams() throws IOException setImplementorsParams.initialize(); return setImplementorsParams; } - @SneakyThrows - public static void main(String[] args) { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); - ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); - List implementors = new ArrayList<>(); - String identifier = "IdentifierID"; - implementors.add(CONTRACT_ADDRESS_1); - implementors.add(CONTRACT_ADDRESS_2); - SchemaParameter setImplementorsParams = new SetImplementorsParams(schema, setImplementorsReceiveName, identifier, implementors); - setImplementorsParams.initialize(); - - } - - } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java deleted file mode 100644 index 32b550901..000000000 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/AddressParam.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.concordium.sdk.examples.contractexample.parameters; - -import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.smartcontracts.Schema; -import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.types.AbstractAddress; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import lombok.Getter; - -import java.io.IOException; - -@JsonSerialize(using = AddressParam.AddressParamSerializer.class) -@Getter -public class AddressParam extends SchemaParameter { - - private final AbstractAddress address; - - public AddressParam(Schema schema, ReceiveName receiveName, AbstractAddress address) { - super(schema, receiveName); - this.address = address; - } - - - public static class AddressParamSerializer extends JsonSerializer { - @Override - public void serialize(AddressParam addressParam, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeStartObject(); - switch (addressParam.getAddress().getType()) { - case ADDRESS_ACCOUNT: - jsonGenerator.writeFieldName("Account"); - - break; - case ADDRESS_CONTRACT: - jsonGenerator.writeFieldName("Contract"); - break; - } - jsonGenerator.writeStartArray(); - jsonGenerator.writeObject(addressParam.getAddress()); - jsonGenerator.writeEndArray(); - jsonGenerator.writeEndObject(); - } - } -} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU64.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU64.java new file mode 100644 index 000000000..a08b8b078 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU64.java @@ -0,0 +1,30 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.types.UInt64; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; + +import java.io.IOException; + +@Getter +@JsonSerialize(using = TokenAmountU64.TokenAmountU64Serializer.class) +public class TokenAmountU64 implements TokenAmount{ + + private final UInt64 amount; + + private TokenAmountU64(UInt64 amount) { + this.amount = amount; + } + + public static TokenAmountU64 from(int value) {return new TokenAmountU64(UInt64.from(value));} + + public static class TokenAmountU64Serializer extends JsonSerializer { + @Override + public void serialize(TokenAmountU64 value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getAmount().toString()); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java new file mode 100644 index 000000000..f302511d6 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java @@ -0,0 +1,28 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import org.apache.commons.codec.binary.Hex; + +import java.io.IOException; + +@Getter +@JsonSerialize(using = TokenIdUnit.TokenIdUnitSerializer.class) +public class TokenIdUnit implements TokenId { + + private final byte id; + + public TokenIdUnit() { + id = 0; + } + + public static class TokenIdUnitSerializer extends JsonSerializer { + @Override + public void serialize(TokenIdUnit value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(Hex.encodeHexString(new byte[]{value.id})); + } + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java new file mode 100644 index 000000000..a618d6dc5 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java @@ -0,0 +1,12 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.types.AbstractAddress; + +/** + * Wrapper class for {@link BalanceOfQuery} enforcing the correct Token id for cis2-wCCD contract. + */ +public class WCCDBalanceOfQuery extends BalanceOfQuery { + public WCCDBalanceOfQuery(TokenIdUnit tokenId, AbstractAddress address) { + super(tokenId, address); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java new file mode 100644 index 000000000..70b33a422 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class WCCDBalanceOfQueryParams extends ListParam { + public WCCDBalanceOfQueryParams(Schema schema, ReceiveName receiveName, List list) { + super(schema, receiveName, list); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java new file mode 100644 index 000000000..50ef9e682 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class WCCDMetadataQuery extends ListParam { + public WCCDMetadataQuery(Schema schema, ReceiveName receiveName, List list) { + super(schema, receiveName, list); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java new file mode 100644 index 000000000..f5bef9d1a --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java @@ -0,0 +1,15 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.UInt8; + +import java.util.List; + +/** + * Wrapper class for {@link Transfer} enforcing the correct Token amount/id for cis2-wCCD contract. + */ +public class WCCDTransfer extends Transfer { + public WCCDTransfer(TokenIdUnit tokenId, TokenAmountU64 amount, AbstractAddress from, Receiver to, List data) { + super(tokenId, amount, from, to, data); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java new file mode 100644 index 000000000..0955c5df1 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java @@ -0,0 +1,13 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.parameters.ListParam; + +import java.util.List; + +public class WCCDTransferParam extends ListParam { + public WCCDTransferParam(Schema schema, ReceiveName receiveName, List transfers) { + super(schema, receiveName, transfers); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index 213397d80..ef78efa19 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -1,4 +1,184 @@ package com.concordium.sdk.examples.contractexample.wccd; -public class Cis2WCCD { +import com.concordium.sdk.ClientV2; +import com.concordium.sdk.Connection; +import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; +import com.concordium.sdk.examples.contractexample.cis2nft.Cis2NftParameters; +import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.transactions.*; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.concordium.sdk.types.Nonce; +import com.concordium.sdk.types.UInt64; +import lombok.SneakyThrows; +import lombok.var; +import picocli.CommandLine; + +import java.net.URL; +import java.util.concurrent.Callable; + +/** + * Calls different methods on a cis2-wCCD smart contract deployed on the chain. + * See {@link Cis2NftParameters} for how to create and initialize custom smart contract parameters. + * TODO what values should user replace + */ +@CommandLine.Command(name = "Cis2WCCD", mixinStandardHelpOptions = true) +public class Cis2WCCD implements Callable { + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // TODO dummy address + private static final String PATH_TO_MODULE = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1"; + private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address + + private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); + + private static final TransactionSigner SIGNER = TransactionSigner.from( + SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) + ); + + @CommandLine.Option( + names = {"-m", "--method"}, + required = true, + description = "Name of method. Valid names are: ${COMPLETION-CANDIDATES}") + private Cis2WCCDMethod methodName; + + @CommandLine.Option( + names = {"--endpoint"}, + description = "GRPC interface of the node.", + defaultValue = "http://localhost:20002") + private String endpoint; + + @CommandLine.Option( + names = {"--timeout"}, + description = "GRPC request timeout in milliseconds.", + defaultValue = "100000") + private int timeout; + + @Override + public Integer call() throws Exception { + var endpointUrl = new URL(this.endpoint); + Connection connection = Connection.newBuilder() + .host(endpointUrl.getHost()) + .port(endpointUrl.getPort()) + .timeout(timeout) + .build(); + var client = ClientV2.from(connection); + //Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); + Nonce nonce = Nonce.from(1); + + switch (this.methodName) { + case INIT: + handleInit(client, nonce); + break; + case WRAP: + SchemaParameter wrapParams = Cis2WCCDParameters.generateWrapParams(); + handleMethod(client, nonce, wrapParams); + break; + case UNWRAP: + SchemaParameter unwrapParams = Cis2WCCDParameters.generateUnwrapParams(); + handleMethod(client, nonce, unwrapParams); + break; + case UPDATE_ADMIN: + SchemaParameter updateAdminParams = Cis2WCCDParameters.generateUpdateAdminParams(); + handleMethod(client, nonce, updateAdminParams); + break; + case SET_PAUSED: + SchemaParameter setPausedParams = Cis2WCCDParameters.generateSetPausedParams(); + handleMethod(client, nonce, setPausedParams); + break; + case SET_METADATA_URL: + SchemaParameter setMetadataUrlParams = Cis2WCCDParameters.generateSetMetadataUrlParams(); + handleMethod(client, nonce, setMetadataUrlParams); + break; + case TRANSFER: + SchemaParameter transferParams = Cis2WCCDParameters.generateTransferParams(); + handleMethod(client, nonce, transferParams); + break; + case UPDATE_OPERATOR: + SchemaParameter updateOperatorParams = Cis2WCCDParameters.generateUpdateOperatorParams(); + handleMethod(client, nonce, updateOperatorParams); + break; + case BALANCE_OF: + SchemaParameter balanceOfParams = Cis2WCCDParameters.generateBalanceOfParams(); + handleMethod(client, nonce, balanceOfParams); + break; + case OPERATOR_OF: + SchemaParameter operatorOfParams = Cis2WCCDParameters.generateOperatorOfParams(); + handleMethod(client, nonce, operatorOfParams); + break; + case TOKEN_METADATA: + SchemaParameter tokenMetadataParams = Cis2WCCDParameters.generateTokenMetadataParams(); + handleMethod(client, nonce, tokenMetadataParams); + break; + case SUPPORTS: + SchemaParameter supportsParams = Cis2WCCDParameters.generateSupportsParams(); + handleMethod(client, nonce, supportsParams); + break; + case SET_IMPLEMENTORS: + SchemaParameter setImplementorsParams = Cis2WCCDParameters.generateSetImplementorsParams(); + handleMethod(client, nonce, setImplementorsParams); + break; + case UPGRADE: + SchemaParameter upgradeParams = Cis2WCCDParameters.generateUpgradeParams(); + handleMethod(client, nonce, upgradeParams); + break; + } + return 0; + } + + private void handleInit(ClientV2 client, Nonce nonce) { + ModuleRef ref = null; + InitName initName = InitName.from("init_cis2_wCCD"); + InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), ref, initName, Parameter.EMPTY); + InitContractTransaction initContractTransaction = TransactionFactory.newInitContract() + .sender(AccountAddress.from(SENDER_ADDRESS)) + .payload(payload) + .expiry(EXPIRY) + .nonce(AccountNonce.from(nonce)) + .signer(SIGNER) + .maxEnergyCost(UInt64.from(10000)) + .build(); + //Hash txHash = client.sendTransaction(initContractTransaction); + //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + //sleep(); + //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + //System.out.println("Transaction finalized in block with hash: " + blockHash); + System.out.println(this.methodName); + + } + + private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { + UpdateContractPayload payload = UpdateContractPayload.from(CONTRACT_ADDRESS, parameter); + UpdateContractTransaction transaction = TransactionFactory.newUpdateContract() + .sender(AccountAddress.from(SENDER_ADDRESS)) + .payload(payload) + .expiry(EXPIRY) + .nonce(AccountNonce.from(nonce)) + .signer(SIGNER) + .maxEnergyCost(UInt64.from(10000)) + .build(); + //Hash txHash = client.sendTransaction(transaction); + //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + //sleep(); + //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + //System.out.println("Transaction finalized in block with hash: " + blockHash); + System.out.println(this.methodName); + + + + } + @SneakyThrows + private void sleep() { + for (int i = 0; i < 200; i++) { + System.out.print("."); + if (i % 50 == 0) { + System.out.println("\n"); + } + Thread.sleep(30); + } + } + public static void main(String[] args) { + int exitCode = new CommandLine(new Cis2WCCD()).execute(args); + System.exit(exitCode); + } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java new file mode 100644 index 000000000..1b08722aa --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java @@ -0,0 +1,18 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +public enum Cis2WCCDMethod { + INIT, + WRAP, + UNWRAP, + UPDATE_ADMIN, + SET_PAUSED, + SET_METADATA_URL, + TRANSFER, + UPDATE_OPERATOR, + BALANCE_OF, + OPERATOR_OF, + TOKEN_METADATA, + SUPPORTS, + SET_IMPLEMENTORS, + UPGRADE +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java new file mode 100644 index 000000000..4c86b0193 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -0,0 +1,212 @@ +package com.concordium.sdk.examples.contractexample.wccd; + +import com.concordium.sdk.examples.contractexample.parameters.*; +import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.transactions.Hash; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.Schema; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; +import com.concordium.sdk.transactions.smartcontracts.parameters.AddressParam; +import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; +import com.concordium.sdk.types.UInt8; +import lombok.SneakyThrows; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class Cis2WCCDParameters { + private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); + private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); + private static final ContractAddress CONTRACT_ADDRESS_2 = ContractAddress.from(2, 0); + private static final String CONTRACT_NAME = "cis2_wCCD"; + + private static final Path SCHEMA_PATH = Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin"); + @SneakyThrows + public static SchemaParameter generateWrapParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + + // Initialize WrapParams + + ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); + Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); + List wrapData = new ArrayList<>(); + wrapData.add(UInt8.from(1)); + wrapData.add(UInt8.from(42)); + WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); + wrapParams.initialize(true); + return wrapParams; + } + + @SneakyThrows + public static SchemaParameter generateUnwrapParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + // Initialize UnwrapParams + + ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); + String unwrapAmount = "2"; // TokenAmountU64 + Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); + List unwrapData = new ArrayList<>(); + unwrapData.add(UInt8.from(1)); + unwrapData.add(UInt8.from(42)); + UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, ACCOUNT_ADDRESS, unwrapReceiver, unwrapData); + unwrapParams.initialize(true); + return unwrapParams; + } + + @SneakyThrows + public static SchemaParameter generateUpdateAdminParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + + // Initialize Address as UpdateAdminParam + ReceiveName updateAdmninReceiveName = ReceiveName.from(CONTRACT_NAME, "updateAdmin"); + AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, CONTRACT_ADDRESS_1); + updateAdminParam.initialize(true); + return updateAdminParam; + } + + @SneakyThrows + public static SchemaParameter generateSetPausedParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + + // Initialize SetPausedParams + ReceiveName setPausedReceiveName = ReceiveName.from(CONTRACT_NAME, "setPaused"); + SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); + setPausedParams.initialize(true); + return setPausedParams; + } + + @SneakyThrows + public static SchemaParameter generateSetMetadataUrlParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + + // Initialize SetMetadataUrlParams + ReceiveName setMetadataUrlReceiveName = ReceiveName.from(CONTRACT_NAME, "setMetadataUrl"); + String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; + Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); + SetMetadataUrlParams setMetadataUrlParams = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.of(hash)); + setMetadataUrlParams.initialize(true); + return setMetadataUrlParams; + } + + @SneakyThrows + public static SchemaParameter generateTransferParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName nftTransferReceiveName = ReceiveName.from(CONTRACT_NAME, "transfer"); + TokenIdUnit tokenId = new TokenIdUnit(); + TokenAmountU64 amount = TokenAmountU64.from(1); + AbstractAddress from = CONTRACT_ADDRESS_1; + Receiver to = new Receiver(CONTRACT_ADDRESS_2, "mint"); + List data = new ArrayList<>(); + data.add(UInt8.from(123)); + data.add(UInt8.from(23)); + WCCDTransfer transfer = new WCCDTransfer(tokenId, amount, from, to, data); + List transfers = new ArrayList<>(); + transfers.add(transfer); + SchemaParameter transferParameter = new WCCDTransferParam(cis2wccdSchema, nftTransferReceiveName, transfers); + transferParameter.initialize(true); + + return transferParameter; + } + + @SneakyThrows + public static SchemaParameter generateUpdateOperatorParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName updateOperatorReceiveName = ReceiveName.from(CONTRACT_NAME, "updateOperator"); + UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); + UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); + List updateOperatorList = new ArrayList<>(); + updateOperatorList.add(update1); + updateOperatorList.add(update2); + SchemaParameter updateOperatorsParams = new UpdateOperatorParams(cis2wccdSchema, updateOperatorReceiveName, updateOperatorList); + updateOperatorsParams.initialize(true); + + return updateOperatorsParams; + } + + @SneakyThrows + public static SchemaParameter generateBalanceOfParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName balanceOfReceiveName = ReceiveName.from(CONTRACT_NAME, "balanceOf"); + WCCDBalanceOfQuery balanceOfQuery1 = new WCCDBalanceOfQuery(new TokenIdUnit(), ACCOUNT_ADDRESS); + WCCDBalanceOfQuery balanceOfQuery2 = new WCCDBalanceOfQuery(new TokenIdUnit(), CONTRACT_ADDRESS_1); + List balanceOfQueries = new ArrayList<>(); + balanceOfQueries.add(balanceOfQuery1); + balanceOfQueries.add(balanceOfQuery2); + SchemaParameter contractBalanceOfQueryParams = new WCCDBalanceOfQueryParams(cis2wccdSchema, balanceOfReceiveName, balanceOfQueries); + contractBalanceOfQueryParams.initialize(true); + return contractBalanceOfQueryParams; + } + + @SneakyThrows + public static SchemaParameter generateOperatorOfParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName operatorOfReceiveName = ReceiveName.from(CONTRACT_NAME, "operatorOf"); + OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); + OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); + List operatorOfQueries = new ArrayList<>(); + operatorOfQueries.add(operatorOfQuery1); + operatorOfQueries.add(operatorOfQuery2); + SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(cis2wccdSchema, operatorOfReceiveName, operatorOfQueries); + operatorOfQueryParams.initialize(true); + return operatorOfQueryParams; + } + + @SneakyThrows + public static SchemaParameter generateTokenMetadataParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName tokenMetadataReceiveName = ReceiveName.from(CONTRACT_NAME, "tokenMetadata"); + TokenIdUnit token = new TokenIdUnit(); + List tokensForMetadataQuery = new ArrayList<>(); + tokensForMetadataQuery.add(token); + SchemaParameter wccdMetadataQuery = new WCCDMetadataQuery(cis2wccdSchema, tokenMetadataReceiveName, tokensForMetadataQuery); + wccdMetadataQuery.initialize(true); + return wccdMetadataQuery; + } + + @SneakyThrows + public static SchemaParameter generateSupportsParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName supportsReceiveName = ReceiveName.from(CONTRACT_NAME, "supports"); + String standardIdentifier1 = "identifier1"; + String standardIdentifier2 = "identifier2"; + List identifiers = new ArrayList<>(); + identifiers.add(standardIdentifier1); + identifiers.add(standardIdentifier2); + SchemaParameter supportsQueryParams = new SupportsQueryParams(cis2wccdSchema, supportsReceiveName, identifiers); + supportsQueryParams.initialize(true); + return supportsQueryParams; + } + + @SneakyThrows + public static SchemaParameter generateSetImplementorsParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName setImplementorsReceiveName = ReceiveName.from(CONTRACT_NAME, "setImplementors"); + List implementors = new ArrayList<>(); + String identifier = "IdentifierID"; + implementors.add(CONTRACT_ADDRESS_1); + implementors.add(CONTRACT_ADDRESS_2); + SchemaParameter setImplementorsParams = new SetImplementorsParams(cis2wccdSchema, setImplementorsReceiveName, identifier, implementors); + setImplementorsParams.initialize(); + return setImplementorsParams; + } + + @SneakyThrows + public static SchemaParameter generateUpgradeParams() { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName upgradeReceiveName = ReceiveName.from(CONTRACT_NAME, "upgrade"); + ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); + SchemaParameter migrate = generateWrapParams(); + SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef.toString(), migrate); + upgradeParams.initialize(true); + return upgradeParams; + } + + +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java deleted file mode 100644 index 85d841f09..000000000 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/WCCDExample.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.concordium.sdk.examples.contractexample.wccd; - -import com.concordium.sdk.examples.contractexample.parameters.*; -import com.concordium.sdk.responses.modulelist.ModuleRef; -import com.concordium.sdk.transactions.Hash; -import com.concordium.sdk.transactions.ReceiveName; -import com.concordium.sdk.transactions.smartcontracts.Schema; -import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; -import com.concordium.sdk.types.AccountAddress; -import com.concordium.sdk.types.ContractAddress; -import com.concordium.sdk.types.UInt8; -import lombok.SneakyThrows; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -public class WCCDExample { - - @SneakyThrows - public static void main(String[] args) { - AccountAddress accountAddress = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - ContractAddress contractAddress1 = ContractAddress.from(1, 0); - ContractAddress contractAddress2 = ContractAddress.from(2, 0); - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/contractexample/wccd/cis2-wccd.schema.bin")), SchemaVersion.V3); - String cis2wccdContractName = "cis2_wCCD"; - - // Initialize UnwrapParams - - ReceiveName unwrapReceiveName = ReceiveName.from(cis2wccdContractName, "unwrap"); - String unwrapAmount = "2"; // TokenAmountU64 - Receiver unwrapReceiver = new Receiver(contractAddress2, "test"); - List unwrapData = new ArrayList<>(); - unwrapData.add(UInt8.from(1)); - unwrapData.add(UInt8.from(42)); - UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, accountAddress, unwrapReceiver, unwrapData); - unwrapParams.initialize(true); - - // Initialize WrapParams - - ReceiveName wrapReceiveName = ReceiveName.from(cis2wccdContractName, "wrap"); - Receiver wrapReceiver = new Receiver(accountAddress); - List wrapData = new ArrayList<>(); - WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); - wrapParams.initialize(true); - - // Initialize SetImplementorsParams - // Already exists and works - - // Initialize UpgradeParams - ReceiveName upgradeReceiveName = ReceiveName.from(cis2wccdContractName, "upgrade"); - ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); - SchemaParameter migrate = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); - UpgradeParams upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef.toString(), migrate); - upgradeParams.initialize(true); - - - // Initialize SetMetadataUrlParams - ReceiveName setMetadataUrlReceiveName = ReceiveName.from(cis2wccdContractName, "setMetadataUrl"); - String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; - Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); - SetMetadataUrlParams setMetadataUrlParams1 = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.of(hash)); - SetMetadataUrlParams setMetadataUrlParams2 = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.empty()); - setMetadataUrlParams1.initialize(true); - setMetadataUrlParams2.initialize(true); - - - // Initialize SetPausedParams - ReceiveName setPausedReceiveName = ReceiveName.from(cis2wccdContractName, "setPaused"); - SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); - setPausedParams.initialize(true); - - // Initialize Address as UpdateAdminParam - ReceiveName updateAdmninReceiveName = ReceiveName.from(cis2wccdContractName, "updateAdmin"); - AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, contractAddress1); - AddressParam updateAdminParam2 = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, accountAddress); - updateAdminParam.initialize(true); - updateAdminParam2.initialize(true); - - // Initialize TransferParameter - // Is done since no wrapper types are used e.g. no constraints on 'amount' and 'token_id' is being enforced - - // Initialize UpdateOperatorParams - // Is done - - // Initialize ContractBalanceOfQueryParams - // Same as TransferParameter - - // Initialize OperatorOfQueryParams - // Is done - - // Initialize ContractTokenMetadataQueryParams - // Same as TransferParameter - - // Initialize SupportsQueryParams - // Is done - - } -} From a06a4611e2a9da94a87ca811ab087bc5a59b323b Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 11 Oct 2023 15:41:57 +0200 Subject: [PATCH 24/53] Comments --- .../examples/contractexample/parameters/BalanceOfQuery.java | 3 +++ .../sdk/examples/contractexample/parameters/MintParams.java | 2 +- .../contractexample/parameters/NftBalanceOfQueryParams.java | 3 +++ .../examples/contractexample/parameters/NftTransferParam.java | 3 +++ .../examples/contractexample/parameters/OperatorOfQuery.java | 3 +++ .../contractexample/parameters/OperatorOfQueryParams.java | 3 +++ .../sdk/examples/contractexample/parameters/Receiver.java | 3 +++ .../contractexample/parameters/SetMetadataUrlParams.java | 3 +++ .../examples/contractexample/parameters/SetPausedParams.java | 3 +++ .../contractexample/parameters/SupportsQueryParams.java | 3 +++ .../sdk/examples/contractexample/parameters/Transfer.java | 4 ++++ .../sdk/examples/contractexample/parameters/UnwrapParams.java | 3 +++ .../examples/contractexample/parameters/UpdateOperator.java | 3 +++ .../contractexample/parameters/UpdateOperatorParams.java | 3 +++ .../examples/contractexample/parameters/UpgradeParams.java | 3 +++ .../contractexample/parameters/WCCDBalanceOfQueryParams.java | 3 +++ .../contractexample/parameters/WCCDMetadataQuery.java | 3 +++ .../contractexample/parameters/WCCDTransferParam.java | 3 +++ .../sdk/examples/contractexample/parameters/WrapParams.java | 3 +++ .../sdk/examples/contractexample/wccd/Cis2WCCD.java | 3 +-- .../sdk/examples/contractexample/wccd/Cis2WCCDMethod.java | 3 +++ .../sdk/examples/contractexample/wccd/Cis2WCCDParameters.java | 3 +++ .../concordium/sdk/transactions/UpdateContractPayload.java | 4 ++-- 23 files changed, 65 insertions(+), 5 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java index b2568db2f..cf6640f94 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java @@ -6,6 +6,9 @@ import lombok.AllArgsConstructor; import lombok.Getter; +/** + * Represents a 'BalanceOfQuery' used in different smart contracts + */ @Getter @AllArgsConstructor public class BalanceOfQuery { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java index 47636deaa..16c63f871 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/MintParams.java @@ -10,7 +10,7 @@ import java.util.List; /** - * Represents the parameter 'MintParams' in the cis2-nft example + * Represents the parameter 'MintParams' in the cis2-nft example * Used with contract function 'mint' which mints a number of tokens to a given {@link AbstractAddress}. */ @Getter diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java index 13a107ba4..c2b9b08e5 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftBalanceOfQueryParams.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} enforcing the correct {@link BalanceOfQuery} for cis2-nft contract. + */ public class NftBalanceOfQueryParams extends ListParam { public NftBalanceOfQueryParams(Schema cis2nftSchema, ReceiveName balanceOfReceiveName, List balanceOfQueries) { super(cis2nftSchema, balanceOfReceiveName, balanceOfQueries); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java index d50ce7463..91356e821 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} enforcing the correct {@link Transfer} id for cis2-nft contract. + */ public class NftTransferParam extends ListParam { public NftTransferParam(Schema cis2nftSchema, ReceiveName nftTransferReceiveName, List transfers) { super(cis2nftSchema, nftTransferReceiveName, transfers); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java index 10393e8cd..d32e6969b 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java @@ -5,6 +5,9 @@ import lombok.AllArgsConstructor; import lombok.Getter; +/** + * Represents a 'OperatorOfQuery' used in different smart contracts + */ @Getter @AllArgsConstructor public class OperatorOfQuery { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java index f17f79eea..8c1b82d20 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQueryParams.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} using {@link OperatorOfQuery}. + */ public class OperatorOfQueryParams extends ListParam { public OperatorOfQueryParams(Schema cis2nftSchema, ReceiveName operatorOfReceiveName, List operatorOfQueries) { super(cis2nftSchema, operatorOfReceiveName, operatorOfQueries); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java index ef1724150..415cdd47d 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java @@ -11,6 +11,9 @@ import java.io.IOException; +/** + * Represents a 'Receiver' used in {@link Transfer}. + */ @JsonSerialize(using = Receiver.ReceiverSerializer.class) @Getter public class Receiver { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java index bd7830059..709f8105a 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetMetadataUrlParams.java @@ -15,6 +15,9 @@ import java.util.List; import java.util.Optional; +/** + * Represents the parameter 'SetMetadataUrlParams' used in the cis2-wCCD contract + */ @Getter public class SetMetadataUrlParams extends SchemaParameter { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java index 2895e1d05..f753128df 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SetPausedParams.java @@ -5,6 +5,9 @@ import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import lombok.Getter; +/** + * Represents the parameter 'SetPausedParams' used in the cis2-wCCD contract + */ @Getter public class SetPausedParams extends SchemaParameter { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java index 31b9449d9..5e430a119 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/SupportsQueryParams.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} representing 'SupportsQueryParams used in different smart contracts + */ public class SupportsQueryParams extends ListParam { public SupportsQueryParams(Schema cis2nftSchema, ReceiveName supportsReceiveName, List identifiers) { super(cis2nftSchema, supportsReceiveName, identifiers); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java index 497fb14d4..0204251f9 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java @@ -9,6 +9,10 @@ import java.util.List; + +/** + * Represents a 'Transfer' used in different smart contracts + */ @Getter @AllArgsConstructor public class Transfer { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java index 604c10e74..cf890a0b5 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java @@ -11,6 +11,9 @@ import java.util.List; +/** + * Represents the parameter 'UnwrapParams' used in the cis2-wCCD contract + */ @Getter public class UnwrapParams extends SchemaParameter { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java index 063b79e43..8b7f42a98 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java @@ -11,6 +11,9 @@ import java.io.IOException; +/** + * Represents a 'UpdateOperator' used in different smart contracts + */ @Getter @AllArgsConstructor public class UpdateOperator { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java index e75a8aaad..ef4bbdde0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperatorParams.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} using {@link UpdateOperator}. + */ public class UpdateOperatorParams extends ListParam { public UpdateOperatorParams(Schema cis2nftSchema, ReceiveName updateOperatorReceiveName, List updateOperatorList) { super(cis2nftSchema, updateOperatorReceiveName, updateOperatorList); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java index 7bc3728a6..3f3bfe66d 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java @@ -12,6 +12,9 @@ import java.io.IOException; +/** + * Represents the parameter 'UpgradeParams' used in the cis2-wCCD contract + */ @Getter public class UpgradeParams extends SchemaParameter { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java index 70b33a422..d2c8f1e40 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} enforcing the correct {@link BalanceOfQuery} for cis2-wccd contract. + */ public class WCCDBalanceOfQueryParams extends ListParam { public WCCDBalanceOfQueryParams(Schema schema, ReceiveName receiveName, List list) { super(schema, receiveName, list); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java index 50ef9e682..f6a8345c3 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} enforcing the correct {@link TokenId} for cis2-wccd contract. + */ public class WCCDMetadataQuery extends ListParam { public WCCDMetadataQuery(Schema schema, ReceiveName receiveName, List list) { super(schema, receiveName, list); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java index 0955c5df1..d2d79c1c6 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Wrapper class for {@link ListParam} enforcing the correct {@link Transfer} id for cis2-wccd contract. + */ public class WCCDTransferParam extends ListParam { public WCCDTransferParam(Schema schema, ReceiveName receiveName, List transfers) { super(schema, receiveName, transfers); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java index d496890b8..a0f0fc122 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java @@ -8,6 +8,9 @@ import java.util.List; +/** + * Represents the parameter 'WrapParams' used in the cis2-wCCD contract + */ @Getter public class WrapParams extends SchemaParameter { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index ef78efa19..ef72fc573 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -3,7 +3,6 @@ import com.concordium.sdk.ClientV2; import com.concordium.sdk.Connection; import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; -import com.concordium.sdk.examples.contractexample.cis2nft.Cis2NftParameters; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.*; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -20,7 +19,7 @@ /** * Calls different methods on a cis2-wCCD smart contract deployed on the chain. - * See {@link Cis2NftParameters} for how to create and initialize custom smart contract parameters. + * See {@link Cis2WCCDParameters} for how to create and initialize custom smart contract parameters. * TODO what values should user replace */ @CommandLine.Command(name = "Cis2WCCD", mixinStandardHelpOptions = true) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java index 1b08722aa..80c019664 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java @@ -1,5 +1,8 @@ package com.concordium.sdk.examples.contractexample.wccd; +/** + * Represents the different possible methods able to be run by {@link Cis2WCCD} + */ public enum Cis2WCCDMethod { INIT, WRAP, diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 4c86b0193..9218f84b3 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -21,6 +21,9 @@ import java.util.List; import java.util.Optional; +/** + * Helper class for creating and initializing parameters being used in {@link Cis2WCCD}. + */ public class Cis2WCCDParameters { private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index 3673a0629..9ae05b4b4 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -71,7 +71,7 @@ public static UpdateContractPayload from(final long amount, */ public static UpdateContractPayload from(@NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with a ReceiveName");} return from(CCDAmount.fromMicro(0), contractAddress, schemaParameter.getReceiveName(), @@ -88,7 +88,7 @@ public static UpdateContractPayload from(@NonNull final ContractAddress contract public static UpdateContractPayload from(CCDAmount amount, @NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with a ReceiveName");} return from(amount, contractAddress, schemaParameter.getReceiveName(), Parameter.from(schemaParameter)); } From be79f45fddd75fa82e20bf6decd564aef85793a5 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 13 Oct 2023 15:49:14 +0200 Subject: [PATCH 25/53] Final run-through of all edited files --- .../contractexample/cis2nft/Cis2Nft.java | 44 +++++++---------- .../contractexample/cis2nft/cis2-nft.wasm.v1 | Bin 77916 -> 0 bytes .../contractexample/wccd/Cis2WCCD.java | 45 ++++++++---------- .../ConfigureBakerKeysJniInput.java | 7 +-- .../sdk/exceptions/CryptoJniException.java | 2 +- .../smartcontracts/InvokeInstanceRequest.java | 4 +- .../sdk/transactions/InitContractPayload.java | 2 +- .../transactions/UpdateContractPayload.java | 4 +- .../smartcontracts/ParameterType.java | 4 +- .../smartcontracts/SchemaParameter.java | 6 +-- .../smartcontracts/SchemaVersion.java | 2 +- .../SerializeParameterResult.java | 2 +- .../parameters/AccountAddressParam.java | 1 + .../parameters/AddressParam.java | 1 - .../smartcontracts/parameters/ListParam.java | 6 ++- 15 files changed, 58 insertions(+), 72 deletions(-) delete mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index d2c60b831..918ca98ab 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -4,6 +4,8 @@ import com.concordium.sdk.Connection; import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; import com.concordium.sdk.exceptions.ClientInitializationException; +import com.concordium.sdk.requests.AccountQuery; +import com.concordium.sdk.requests.BlockQuery; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.*; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -22,20 +24,20 @@ /** * Calls different methods on a cis2-nft smart contract deployed on the chain. * See {@link Cis2NftParameters} for how to create and initialize custom smart contract parameters. - * TODO what values should user replace + * SENDER_ADDRESS, MODULE_REF, CONTRACT_ADDRESS and the key in SIGNER are dummy values and should be replaced */ @CommandLine.Command(name = "Cis2Nft", mixinStandardHelpOptions = true) public class Cis2Nft implements Callable { - private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // TODO dummy address - private static final String PATH_TO_MODULE = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1"; + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address + private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); private static final TransactionSigner SIGNER = TransactionSigner.from( SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key - ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key ); @CommandLine.Option( @@ -66,8 +68,7 @@ public Integer call() throws IOException, ClientInitializationException { .timeout(timeout) .build(); var client = ClientV2.from(connection); - //Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); - Nonce nonce = Nonce.from(1); + Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); switch (this.methodName) { case INIT: @@ -106,15 +107,12 @@ public Integer call() throws IOException, ClientInitializationException { handleMethod(client, nonce, setImplementorsParams); break; } - - return 0; } private void handleInit(ClientV2 client, Nonce nonce) { - ModuleRef ref = null; InitName initName = InitName.from("init_cis2_nft"); - InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), ref, initName, Parameter.EMPTY); + InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), MODULE_REF, initName, Parameter.EMPTY); InitContractTransaction initContractTransaction = TransactionFactory.newInitContract() .sender(AccountAddress.from(SENDER_ADDRESS)) .payload(payload) @@ -123,13 +121,11 @@ private void handleInit(ClientV2 client, Nonce nonce) { .signer(SIGNER) .maxEnergyCost(UInt64.from(10000)) .build(); - //Hash txHash = client.sendTransaction(initContractTransaction); - //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - //sleep(); - //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - //System.out.println("Transaction finalized in block with hash: " + blockHash); - System.out.println(this.methodName); - + Hash txHash = client.sendTransaction(initContractTransaction); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + sleep(); + Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + System.out.println("Transaction finalized in block with hash: " + blockHash); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -142,15 +138,11 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .signer(SIGNER) .maxEnergyCost(UInt64.from(10000)) .build(); - //Hash txHash = client.sendTransaction(transaction); - //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - //sleep(); - //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - //System.out.println("Transaction finalized in block with hash: " + blockHash); - System.out.println(this.methodName); - - - + Hash txHash = client.sendTransaction(transaction); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + sleep(); + Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + System.out.println("Transaction finalized in block with hash: " + blockHash); } @SneakyThrows diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1 deleted file mode 100644 index 3b35e19bc58044aa505708998885cc3289be7bdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77916 zcmeFa3z%JZUGKdvd+*tqHJPrKv<*#tyY{9>C)&J39!^tRkIu?tDG`C{%X1Frea<;; zp}}^hv`ISD@>-ke1qe_eLV*Ak0u&pdXpkyZ5u%_5tQxgw(W*hQR;?PfK+$U7&-eHH zugl&ulcX2m@I0rN*=zl;zyI(4|NSp3ilR7*H@+yky-;T zUU|{gm;ZlTqqLRVyZp*)uA1K(by{gB{^-_)i*{^%>DJ4y*?Q4cKX&ET9Z|QHeNsF7 z>aAB^I+lO3^0!^GLD$K}9u)hiaZy<#DXTRA7S zq2007;GJmYkBnx=)=Msp`mNj(+qJEak?hd;OQ~03BwE#~9`dia>Z$MBfWUH4`#|q4E zU52j96Raac~qZe(x2G)p@^!D_9X_91dqJOd|i^cd+ly!NWin7(w^lJTY1>!7; z<0MYH$qCbOr2n$%=_r}*TIGo6X;Px@^fdn^NjJ))uKuCD?sODSPfzQA{!#fTixO2= zWqPM>r2oQ?5(Sg0TYfy9O_6(ImYtYPpA=;oeeqA${6nsH*X>Sq6AdG+|4F8MNkpGf zG^JJ zK*&_ojZW-FCo@WQqOnFN(M>WnHFYBYcc%oly0ceO$eKR27gHcQIf|%ZXi4HzrcY9( zWbJfvYNAe)rvs?})9J?B;-cuLadcwu>FLh6TwFX5Wjmwt{^a zcDyo)R$qSQ zy!vH`_}|B;)`_p!b}0=0!foR7t9C^H5I?QXx+)~T@MY0I#wXRuFS+E3ORjwBR#K0| zr_`wnsGcjIzjfgfn!6wl044)`cxE-*&~;m&37F?YKJn zmw57`i&Pa^yflroi!Qos>m}PRddVeMZ%va`KM+S{oSm^h{)PDG<2&P@jX#`zEdFTx zbMc4cuf=am?@N9?`K{z&^10+Ul3z19 zo%f|b5XU>qc#tHs<=1u{Sd7Yl)!!o85M8*gi1S@HE-pr^dFS~pi{ZJPnX6t0NmeA; zkI+amo6M>jrPW>$mr?!(s~s0{LE2ndwmD@`_Ev+iL*x0}fGX#&Mw&F%3kGRc zq}j!B8qi4*L(|&@sQ}y%oh3BWtU5K+3{zT9%C!rFj-jMeu6;!rJy&hod)mgl<7K9% z7rl0B1jYt-{wCqq3;rEaWkeB{^skke?sii2M#tJO5wOJwY&w-YDpNjNga|;Fv_(=! zN$=1&&R^Z7rW3HdVWc+raU#B11w)Y=M~bK|qx0KZMQ$1?!Z?-|xp|}rsPrQ5R4YE% z?V!EkmLzbCXbj!x79JUP&Woo5CX#YmLwfCvGysa>9NrG7Imj*41O}Q?sb95jBKW*! zq$0|;wF!MFY9UROe$kVnw5YyB#-6Z1JSO;85QsO%NW>Dv1uVrgNdbo#q=*!w&qc5n3J9?{iddi27x`T^eLV zvOeF{>7re_ zm^e2ACiPRI^MLmQ4zB>bLhN9mUN-0{VcTHB`Pkc`84EziVh!M9_`N&h>w`KdY7hmM|62&A3LrvpG2O;~ z;yCO#h+3b5Bx|Edq!p4krMUpwl=h)nEIPNT7g{RnmO`Z{rnGVP+Br26NpGGg-pZTz zReJ9??~z)sAr?mz6+;|MQcULcwMJYH1p$_$Az_3Wg|TY1JTFB-NJM-Qr#DL9&;`=d zsl^G-P(mN6g5sOfwful8VXSv{G{sMRb_C*z?%5HH=lENO5>Fxi+SH-PO15fDK4Crn zZzj%0o+aMfP?(X2DK#UnWEkZim#QtI{BHeb+3uD-+gLNOp|;kn!lj9H@D5z3n$o0w z6R%i0P<@!9LfYdUZC!dq#)_x@jk(x}P<1L-cGQohYus1C6?|OYI=P|4 z{91DrBXen8HiRDWvHahGMBY4O-tu8Le}~k2GV6`@g|E)~WNO&k40;!joN<%=7C(Zs z!#KKUC*q!#rM7mJz83RE`WiV%XD2y7J;|tC>R}p?pE~jxd_}RE4K7*MJU0IJ#w*YV zEdyNp+ZR^;_9w&-GREb`W&Q1!(gUMZ8zwL4ME6&r;JOo}m-=($4Pr0U873eD9gA=C zY_OJK>W7ILbpzjpN$A)dZ$f>mt?Y|Z+^P}Dt23>qpE_ygAD6x@&b{PkMy|}p%A4>QHt8V`^YJZF15aV|Ec zh1efm=IFeT@u%f3#4SY~=eJ9mEhn8x_QXR?v&cD&+aWGjK_1L*kY1$g(_OT6u^wlV z+u+m%9>K;o%Hmd8&HSBe)Jx}^(rZcWpPekq-Sd7QiRSX3(Qt}%L$oWF?}RPQKd)+d z4s=q$F?6uj_z^6NO{lQAXuOhc#*85_WqbjoPs_FP=iaZ{64FoFJAhsTvaT~CRH0=(bT@}D~99I5ZBliI~gnMu$b!!aM+@NyPtfM;fC zi#aMITWiD1_gi;1z3Re!&PQa=APeG6lab{{t?})z9jiY~k`y}{9En3wOA-6D<~45S zMB(ONsoohmv{?5I(Rz6^M3jhq(5(#2RIh$w5{f5*s9`e^j*X0g=t7as=eyLhn@^ZV z6T1{mRi5#@)kLw7IVRg8%WE4uyH@>)wisD)SIAUa{|?W~&GL2|@1(%;Vt_~8PB<60 zt%gxgYGmW4C}srarW}kKKg9eLeC*nBF-PT`=3S180A_OOf|LDTJTlD<@+1rvG1IjE zAc07ZP}IQ39=PY}&s!ZSvz)nN2s^#Nq)20gwf4I>z*9`*7ZXPi&|UCbV1%| zA+-b=(O^Y4e^@x93p@+b&^DxfHKZk3{(6}l0Pfn1TouWGT}T8It$Cn?G7RZmX*^Ns z2u+7ZbVLrDBG-K%q3Z|)qc7h!E$@lupjqmZksX5`>|ifNr_mo)6S=u|IN>S;gp0^t zYgC0?wn;5Wz^~J^Bh_5wLM3P>)Ycw|`HM+Kdt4lPOw0S)%Hy(OUk-$n0Az1Xpt?cM zyOqgA$Yi_v!wFbNn5FmrASz6kAZXGh8lym7pXNcGXbx0N;D~=#=!fRDlA^5+IWt$x z4ObO?7^qm~Dq(c8MO~~xUv2g;1Tiv3(q4VZaWg^sSWAH)L5fF+gYpn@iZ*e;0u9WJ zDe%iG{aquUatx`hzh7J<{|ZMw+8g9cT9@E|?Fjx&zYG08SLw&d!qzGS7zG&TNgE(BP zjh1P8SAS;myBg&y529AS8<$hQZP-P$BejzFaNJnkW&%?(%|w?d#$Y-S<}p=i)WacO zBThp~H$-b~nu~tzAP%k(twzzoBr)M^RP2BC8ea{PI0Tb zCg4M(O3KteD6C+Hib(;i5giN1{Ah}d9hB{q3m zZ1P&CorOx17Ant~TTYEVci3|^Rs=0}&bS<%gG5Sa%_KkMoCd>*(@f_TBWkR_DLqFy zXQSw)<<4n|P$cE0`OySQe3a?sYP-(rH99M=bQY7+N@qzh@hsXps|VX1Tvlh9&nt~f z+i1*MJ>_lnl#A0FbNGZOng1?HtNoeLC4%K6dexN02CsoDVQ24b3EXI02gHUr z?%nDU`C|5Zj+P&wF|K5Oi)`?)gAk$VU{90MZXL2wBpMe+^>9mmF|vu^@g z#^nBzaus5fkXMd&Hnv(|{n1=30!I06b?*W6l~!=P1|5j5TETft1NZ1Y-a_m{5QJi} zIKQ!Ja(PUCQ1w+_Y$QzHY&8s%Pne*Kfv121y*WzIxkeo})KT|iO9S9qE|1jX^jw+b zzY@?bA2QBASrM?bHGxkVwz0!4YM2$cG~$I0;R6RJ$Ns80j%YG)=Q9OaqmZk|w7sq=vT4D1dGm zBw{G^$V1bWF%$EcIKQb9vKE%pZ0ks;^)SVMBO{&ik@m+&8pcPbzV5aB&|XF_utOM! z9A;awbIvD2yzk4K;(aidLfOP9n+zkH3V1qrEG#Tv!ixoh#jB8-#o74_8VOfn+_5St;V48OsPicS8MR6AC25u<-Mr2q&rKOH!jv?%8p z#S@h~73PYGpS?ppSj$sO!fJF^g|kkmUCsXj+-0m0t3Dyl->BNx8&HfS$ijJo5BqCr zGi;g2ei(OOqY%cJJQTfRBEQ4tQq%pov@48Rm~E`~9<4Ie!2wiq>a;hyN$D8#d^T{C zW+)(j`E+LN>uS&icz?`~kPsGh5gxLH^v8_$cMZrdcK1uccZsSx`YySzV@2@0{ zOzdq|1_MV+Y&8Q8i+tj(5G7Nz>mf46{NOU5+FI1b`>7Z9LUC{MpfRB;;7cZo-3?=Y|A~kP z?1xfPZ_(wN%T?VlS8BDjM>Zg6H-n5h;%;<}7cbALmJ^e5%~Gz#p9oQ-_EJSXD@@A0 zb+qc5_Nvzt<;SRm)oQ*w9&UT(a9|nsYY+ry|Cwknf~9 zXKOZA`3XqQ1xx&dFDC5~kA&wG1js?~45;TPpUZzsWOR^bl5>m!4|ohkr2r3KLXvM3 zn$av?)%c@QZom5ZJ!(V_xAHujy0vbzR4IOMu}yPY%(H|>*^3~{XGN@iYp5#f6}|aU zwkOmJA6vcrHWN{rGS@_!MJ@>7Z=^)JIlitQyhG#`i(XL^(jo~#`EmV7Vy)X6>-egc zS!WU+RGgeF%J(aK&bT0)*7t$Kq{5c=(B%2wn)E~hF1MMAn9IaQJC96j)$d?VeB$r& z3G3QCjX?qBCNdtCv{+3SZR3N(o)H}b2~4$oD-^6(>yDPi`1)agS?6f`<`o$Yhn6rkY#ooM+jewnlXrU%JH- zXX7A?riT8hx%{^SwOEI6a>*|rNBMK9LJ(9GqueOTHU^Sak>QE|su39vu_D`00+GP$fdl2n1QZaNt~n6A%BWP16Ae&E zCHXJtBsFIk3h&mUF{O}0WA7E$XrZd?BT@40RiPrM9^L70Md-~i20e^JdciTqSIO76 z?)a{5yjo09&79)DHUY6nAXPIu{^TxrdYoYvFQV2+<({F42|axSB6 zf7`m@L4rwXuOU-1JuhqB%;iX={DH>w5&9*6j}$~3u9mTTYioWYJyRQ4G-i^2!BmTi z^QzwUr{(FW7sRbnp|;gQF=tg!E&i*dE*KL_t=t;G#Q{S06tc$Q;xFdpPrTEaP*vk?D72 z&p5L2pVW^nqdB(Mj$r$M8w0gQ`xOy{1!70y4O`Xo`p&=FAn{_w3=uo3Ft4*hOo77G zP6&_w`=(SY4=mFTmm-|mlFjWRxK3S#RdNMY1Zpks_UQ87TI6c5e@EKLgeJ|SOj+US z*i7k6g;K9(m1((Xdns!3XiS7Txz^dmS*)IfMw&SVJew&oq>Qq)bEg&)+eW2gY%!-X zHouq_pFV@=3k}guq@mV=zfjMh4b4C7L=wZ#n4{E;z=fdbRy4K!!IcAU=&UE$2F2{A zlr>l9|McSaI1fcttJ)Z4o{iRUwMAiEN<_YTa@`Q>?zA!E;^}5CBH61INJrczo?=yz zAN~tssR;*B9ijzc_F^SR%(G_d3ef-DGzc{>vuzGGYlT}J zj9MjiEZy34@B&5+D8dr6R1lw!&r-}=^j&&3E^E0heHvw3?5shc)F>gj!x7XRK>mQ# z93xzx&T8q}^i~C1g(nx+{ICzK{L)geq}aY_+2eBAY1WY&%Kh!=B(j#UUSvA^Ost)YL~2y2^CM0OK z4xREjwMcl_ z-JJayuQY#K_)R9H(c2op)Gr#qc|V|pt^XcAk&0(GSFMbtfiHx-U_c&66~FLkQUu|} zEeMO2nj9FeHjgi@WX z!xcq72JnsaWp&hslXdb@&0dgP;j#onitd_K50 z*-Z7tT=qaLfTDVpX&{@dVldfhqF!k&|F}A0yyaat99WFXXOIf(9k@v^_bDlV=S`GA zXcHJDbbfR#H+2PM4qEOzgKRIa4-Z9GGz#(Pjc#m}JbI%K9)F|BLIde9w_*wibM3Ti zQSSu96@N~c%l}0PD+TbWPCg=Yw3p=x>@@1t+LrQkURGQ&H#~{z@DguDHjX-vt=Fj=Usvc6%5?WEQ9O2F;F_36_A34e!hBuMqjJV zQCbO>LPz52EF9E3JTJGsB$PczPR~rTQ47)1sfhb+-X(bhb~KauY+Repg4`q9V$9Y- zsef~c&as_PilNrK{mIdEsbUi~3J}gFwbvuaHqN=1Cx;vZ7{vL7jV@_)xW-$=^n&ti z4z`)L(j@+C;?t(>k-6#l$1|QDO&0qS{=K4<5N#ZC2`G~KNG8}6=e|1N@?Z<}hGgo16ZT@z% zF_16U^i-Q<@#a`vXG>J5Rq+w%7Gfx~Hh)`HOQ8@_rb4YwmjAM{6hRHulRyV+wn(2D zug%}8A{<3Vxzd$_5Nq?F4QY02+g9~i)|NwIes9{Cu`joFnl_k$8AkO%SR|4@I2NZ= zM*tlXb9{sk&C%iNnj^aTFI1yOD+G?{;(poOS!JIj7x?x}A-QqWYlgUlSvLg6dYQ_^ z2Sv;u*Nq3SlDd+Qh6jOPCasHK23f+52e&898slO+0wb!ABKK{Lveh^^9)4!^|ecE~?YaY599LHGXDrgIyHa?_&N6BjKkFaeuBQqi1-1L}7M6}29ZT5oF+Wfs?yddsKg}5U%;=bPO z^=|L|Tb#X)tf1YN%3wIEAO*L)45nCR#O}S$P%yYW8cp0f6$6=q%WFC7=0DXikSn+~ zOjtR?7|uW#nV+0Q{ZqvlwPL%YB~S;BE>L>{gRMB^<%G@xM(>@ zG%$+=5%(}pK`>YtrP>2;1+di$gtoJmoHzI`W*0OPA~Q6a|D>EBygi12x%XEO%>2(4 zU^CM1S1$jySL`1bT*p}_?5q_op9G7j0msfZ zb50zjY>wsX0J!h!;gl)`8mv4{`d9J0W$15NOX&adk=bR(2M8iGBveLyYZpXeIYYAm zewYPt(i8@8V#Q)vHP!6ESMG9@r;!!n?jI2D1`)Ilvr)Z|2O^98N4~ zVe&-NIKR_^IN0gKSX7q?b)4Y#q=*@Qp#{mjmbU41T6bC~TO(i(*6G9UX5n}AP7BV{ zX#R#cS?oyhHSNKmHAz?gDT%U}!eFqLyhEC#FBL{%`8-l57RP{7<7_HYi8G}tbR$+G ziPMCkSZNhdQIp!@yrJcy61Yt(+tk<#^>wofLD+C=?gRC!T}t=UdUe}z zNdxfFEUHG`vZj8mTe94tBVkJ82^uTPUL7~nTDqv*CZJ@&!jv_4eE89+?uH0VTUuJ! z5h@m276!~N2QU<3(>MrdIxb~;MY;0_;rwu$7^nU;v99kHtAU{T3$i;_bRLpfr~G|bBab-0V+ z_gh+~;bChs#_WvU7x9jdJup>ajmZjL?{Qri@lL9J1JQPOYfK~Ck!@)-f4_KBBNW=W zPh^f2G21QxBDSBO<1hVj>HvR4=ck4f-9{00-8)AZk85xnzwPSYQVzJUZkCfa`QNu%wUT^xGSUA(@f z#v2nG7&XrSQXMELKdkxH9Ko6|`^bObOXEYPXYFf*j0eSv+CaAwE7s=z@#%$+-to|? zicN?L9Ar*i1)o*J|i^^LI!b)9WGxq=XX)E0Phj`up~*= zgQ4&q{BIO5*Ka?*doQqOpN}dMOdU4`Fle7gQomvMUK~@5e)~z2;Mp|^VuD7F`6cL{ za?-G(>d1cl`&O#B2g110zLo2$eJgL(pon|vsyJBUX!};43?MUCFpFDm1I>#oK+JhI zKxU2w$WD9@*FA8wVo<}xH#H<>y`cf0GR1TA>%imuHJUSV`rR%G$6{9RkLVh?*1H9N z%71I8%Au#kUm2q0jAoyV8|SB)7grET%EG3KB#L#qQBxQW1{A4pD{>#v?@KD8kJza_ z^0Z&VZ!7Rc!gwGv{@7zFGi9}LUaVuUDZApT>mBS~A5Cc4DW9QZS=*cr8_s+)|{ zdh%Pu+0VD&A9bvbH3p4<1-RD>n@mS^g9IbU-yGhVya$K@R1iLFla{2(uOc{bVf& z2Tb1`O%hImA<74DfOR0nTW(@#++NX+<+NbaJly6UOgXj9(555u=xk-2q%cDviH%s* zT!q_;_T5DLRxW?Lx_}*$HWkm5GSLL8>~O1w3Gi@Cd1u*oS|PS!D@+j8n;K!FC1sg| zF|P3z4kXJ?jMVRdww>97c6T}$Op5Hmj$!dw8JcnNs}P`>d9sy^OUhhdVX{QgfvM2s zV$PVX@x?_Oo}vfeznvw?9kx@4x85~%!nAN#PBjUuE#ahVxL&wCqAF8m$E3>At9I&Y zhpmX^wOUv$myh^EHMh@U9W|=6#W2ZyVxW9#bxRIe+W!KN)sYTx*~ydv3eWPpKf`}jeS5P z62l4%ZXtb>5yEiV-fEFCx(P93i-B4UU)xqV`*^q169S?2D3`7E$r|5hLse}Pw_u^| zy_1bF<_h6wHA;chYG8&{RDD|H7_(!yi%_O*CbGY4%~Tmg9Sj$UrxVGijkV}%qC7A= ze~3<|>`40!!KtwLns7HPk2?LC&L*=34vi00;cI$tuHO)dC07{P^^6Ey>k`>v)uH0Q z>XpuzT`cX<0?eos+u>n@T(%og({B4}qKSM50ZKYf842E$t>fZ-aKiz%S8yonHe^;g44`C_o_olZHa|HndKI zj?|J4x9F>>3hpA!*bBPMw<83(@U75u3h1cE{Feg<5qW7}&Yh-KPC@**{1P9~DAIM+ zR#S#YaF4?b1J-UFts0OW3Bi6tkR_i}U_ALJ)Kgmv;&>gp>A<4CmvEn4tLl3RHwt(` z8C6kVs++CQkFD9;IFjj<5TWGIx<4UfY}&~K=*Yvf1)-Ru1)@UWMggm#B`#}uO0=nR zY<)lbotPW0>kD19-?BE|Au24=4e7@yT^VV`g^9gbaQHVH%$`MHsv7Fu?V(cAV$Otc z>JuM{ctXwaOW1j6>|lZCnIZ9bu~p~$;0mtKGD+8p!BoAsP8Ww%K(%&Ao{70hX3J+o zL%Z^Hs7yKZmUaLz7Ypb7)f{xaefK7 z_(Ll^>lHnADmBV!@5lit2X?{5<0!P7cA*<*%ZF5{EXsYaZdES-`c+EZSng@3(s=?N^@*5g*|RR-)>m%?wJ51~ z)*x&Y@RUY~#v(WScIOu4ehIr+THu#=XeAKppp>AxpfrugS83Sfj4MgU#uaFFpN43E z0gKf|q|4u!mLWh6hloNXU*NHFEyxOaB-N1+h^;~N?C$fdJYvHPE70ZLdMjtj!|lQE zN#n_il}9HtrbFz0bGF`P@{v;|_47B#ordV9*ntMd(N&SAhu9sYcaXyhw%Z9Hhr&Vc zvxX%A`4Mupq&=~Y`*N8)Gm}C0{i>K_FqzC^!axC+M+sYsOvBoljdzt>w}PFu^BVd` z1P%+Gm?atmkg9<3AZ$8f-wiT|>P+X?RuvpwnG;xCHYH=jHKua|os8CSbp@a8PZ134 zP%#+#0R|TS+c1#tS6O=3rfnIb)_82xq8|HRjM>*fI8JB<8;?YTd<3hLF!s zV7b6#fG6G(d4p2!RpKYq4g0M76}l^hsz^VVIxiH-obDr0V8|s-%Vr{~R$Jq+21uxO zL6(I*P53w)eNU5ky{B2b{_Smn6h%+lID#IO18TYw788{AgL0IYC%!QP32DQ^4Mq*=ZkjBjJ0ZEJVYL{-LM<$ABgqK+rL<%V8*`^JJ2|L_C znl70}8W@UnR+qb`)k@XscxzR9Fa>=`0%WK%Rkp6YBV9Cn4g|s8aYzb2r+WZ5vjX%& z&Vdx*##l34#i|zxt^H4GNKqz$gl1WCKOze z?!uWefS_MVpieERUb&Mtk_+^Q%|l5Uv$7;Fjkvw-;;@}JNQ#V^q&oYmYkh06lG6IS z5ixYo&~^4f*S0fWaguNJAyc1>2o7b^IF$6tu9iX$C2Ex>wuGDQmllmo`@lG<>c9pJ zG@(Q4nvO%FpcnKMeCT657277GJBA$?eIi3@X4ngi3hmHZB0}KTDc)?~9^#`18lBiIZXUCX-;v_6 zK|j$hwpES>>`@ZfG&0F@Jy&GY>7+BR(ZY7(cm?eGl6*~Ac>Stiuq_KF_-QqwYK0bT z1fiF39c!6;>^kfxv&{VsTNF6PTGQB&p45`$H*8D~OWg$aZf5opAaR0i(L+OsM;hXw@P&%>dF(kX6_6mzj!(rBhJ3hYp$2`VCgk)}HykFH>M9XA=IsdR)D?c$8hXZV zhBK?S7MFz{v_DL9;ruRz(d6NC$uSLT0$~#g1W>}R57oe*=KH{=2(HVY&Zn3>OM|(d zuBXb`zdTi=W+_9XuD>*~@}RMVKIoZm`9a&Kj*Qf7GJ#W99&}CVjo++6KV|&QI7Mk` zf4_kLI7Xc;e3SV5DI2wYMb<_gHcG5K>YBkj->gwTWl}xD;Cw&kI0pSqWAF!BF~29E zz?s;VeN*5gF2I=9mNLewn*wXD$28ANPLio?nT2l!mCfp35aitUbQ}k9d*3XM9y<%w zap&_1Sm#kW9@W{zdTaYEXSijcO_WE;{B^d>oNaw-{1LYO8J+7reaAs(>U@(F_ER=& zZQ>Do*ISm3W7yRBCJlRZ;?u<1eQs68`5)91ALhAJPh{ihF}wKPuYVVx|N3`v@00Fg zi_H){ykcKJW>tNGNwdPd3Y0|5qoZ<#!+bxG2JuqAAk;E9DW*4HgX%UmWk z)4CC5b6t{6fwDR3Y@i7#COB4yOLj!rw=?7N!sF|Vo2%+OUB12UY&o#v>gt!HL(hFK zb%RGQ*=t>zHM*fZb~SGEBaM}CW;lRvSJKAZr)d*(t?pF;)RL)J$#RfwtYk~|bGY%N zh}RX-x=e&?0u-TfrbJQxOU@Lg-@z{UtWzz`A|Xv5D{Ts}{ZZMKO*aH^$KoJKem{;e zakN2_%<4J=U4?;b!F5d9rsOw(rlhd&%-x`AVXKgTq&f;I=!TCFSV>BvQpxu0&baBX zy$~0bk7_BcT$lfxO$-w`AOu)8%QNRvO`;H*HzwsnH&85p?@e?8NUobOO)`&wSu$X0G9u$* zHA2-fSylmTkt(vDtTAwX7Zoh#rqCN6r9y8^&I!FKo|gEWo>qNpn1bcwXqPtvoa886 zSuK8Nzmc@RO)L_`Z7I{|CUi)syah0?&2KfE_(i) zhF1{c-#GA=mZmGj33W!wTMcdMBQ)V>PVKtCreJ-mwB1{u%t|h2B|G|Tjs-vjb-hY# zsbI>+VhhE#Yan#PnJBB*d?2ShbIFaRc#n$y)i)Q#&AxuNGk$0l5%*^>*u|(^Oh>RN zmH*s&RSPP|b1#BeqBMjAR*5*QdJ^NvQ?6>yTlCrJ>tX1dK#BeeLmeq&8d#q*cxYT!0dikG7yD53Eo$%%1HpS+9EV#smyaUy> z1mIjNT28KUv{y*CbrUtWkLIANQ3;w*(|d(b0(^h?gt5%3F`TnWjX#j0Vw^8c!?2a~Vs)|c` z;qT#!xIj7RZ=q3F=UAghDkb>YMlBRUIe26+C3hOTcsLrpR9{ zdj|)l=p)~KR(gs3un2{UqCUG19oJ|{&o;q~e2O|QRoa1|)!bVp!Son;{*`KR!VD+A z5imES=r5~UWpf>uZk;oxP^rSL8xpuh6V6?Ld7BtTGN6CeJ?pjZT8R1`uBM{29}s??at*t_#I-^aEzzD(^{0VxYyR+l^1lk{9P(Ne zl9eC&(4D)g`ZK~ZGo$~|FO(37qrJ(y{e)`cN$%oTW4sfL+#SevH<&Ra&%9uagnMi> zS`>d!WSvRwqU=m^cancl)HlKlh)PT8xw^YOoNc?nI2HWmA8~#N7(ut@e{Ct?*ElZ0 z<#n>q3=h!TG^Vb+-6L3`W*dGRlZ?dI8Gd!$f?sdIZfqlDz?3#a?D};OUYNgNY-P2n z5o+De7^|f=edHm1soFI1G;H%}BM;mx{Dn_EruxLA7@Vfy75~hm-amoK9Q(e3M3?I$ zN~TwAVXf7m5ekE{Y&zR=s(UY-kJJ30ol9quThn1$Tf$p{6pal@2!oK3_;7tHTVR8N zjuL*?s>Ww*AG6^pl{S|0nDn_WJMV<7j1C83mOhXUZxUF|6U!T2K zDZ6?*)~schSJ!ZDVH3lcOY&4E_)cxyU0;H$djd->G|d+#QzH#cC$ zY^8WSkw>2-4o>0`{FdJ_H+UM4SWztPU=4h6G6YDAlfmnTC>osNj zA^$^DB2n25yLmWpVWv_cLi~1FsZ*Gcmc0R5u$6U+yHGGT4Tb(`{x4j9)~5$M`c8+d zz`Qt-{iGY+l^Op%Ok67z-sgo(q#&NHT z8_8sg{>Ca#2hBGfjP5Bm^Abl;36!)+&>o1Sp>jFAaGl$BISxoll;3x^MlOe{n#++D z;>)p4yfHCc?d(*H+L(Q?Pwk`&t91(RMkQC#qT3X-ev};AZ4Y#LbvXWtl|wF zEPeGbW$_l%;Eaf!1zzQh=-HeR2yluMny6_-g~}b-5ba~iCRPUb2bh>0pjAEJtx1~n z0QiPT!&BIc+&CpgW_)Y@h@?CW=ZJ>k$Q;4Kq{w_K!Xw6?RP%={K;ZbT7!0Yds?Q|1 zq{S&z*c|15XT)ZxM^a>OG7NAs5ZwT*2QB7s53FBKJZCkll<@t8oAOiEnPC7tAH38J zl3CZ)v)6@Rg_UlRh0M$|+@(Egop?zdG~t9K$ahy{j|T6 zjSAKoB46YPa(NjxE*Q{)b7p@{gu)4GQ)U|P67dlLXzgJ?Wc33tj6_HGcdLlQM7C!- zo#3vpRh6%Gc%`U=Y5ZkQ^j5m#&dru5>LtEC3jV{o;wJnyQ+_TEG@N;Jewa$n-E z)*)_x^9qftbtq}MT54*{)w-W$qfo~K73OLkFb~9fZo68ETrEm__7MuvU{NG3KMN+3 zpEW_wFd6Z)+D$f53JXKfQsqdoV&Q&PVSbk3yp>Ii(EKd?twA`g92_fbJCMC8kzc{> zC4zG%`j`0Z==D4aOGh+QwdeKGYoOV+uyFL%Slz6T9*YP4%s9swU(OXbJad-B@z2WV zB#%c3DNAL1fnPB&fZ<}hTg4+Dmdw||;8uYpxk$3L`{6lm49ZKgPApQJ=W9KRJ(+PS z2M{-*b$c|s;dOaXTuhuB9f-|ZQ>eaO+I^Z0(Sxk{7Ix(}bgHW(kr55zOg8HwL|;9_frL|4Xr90ym()2>a>- zI#WTCr-CFC6`NwomF_4ht!@!@{#5`C-TfEkVlz`h^_= zttMI#2#s?Iodf_gm~o3g8i6=mM<9~yo{6}&ihGkK5s2ki4G)???}0)~Y~g(@A&ZW- z_{lFt+hio!sHo&oOL&m=yp2>4@vVMi2swIg7p-_}V>aks4n=rBVY-jLXqn)tuTS2=aTA1u```5>6+qX)^~mD@Rw`${<+aXn9obK z3fQivY-F zUg|o2C?r}-_X;MU&EG9b8~18JhXtFgkAd12>3faXFVGZC9O2HcD{(LE<8C{Vh z5Y(BC2^x4rQ5-B@tK?bFrgzo*_bzdCmAW^n+}ou29N@?MaaQ@bi^nU?drg`jfz_5s z^Zqeurs#6gtmIK?-g`XKtZHM@e5Xq@IZuf+BZQ@TacL$@o&S7Wns0BUd2d^q_briT zF^)^~#pXcO@+?PB;(SQG>~M)T#y9T_K2mJTVc4P5#f^|pk`6@0sP{Hm$@nC}7FgN~ z)!rLI-}eBLMF>1N?fWd$iSOpBT)acLc<}zDGx38)BmzuOs@l2Gv!@450N{eq^k6b$ zPVdV%__boy%Z7kElU(fTLxy&;Q6HD70=btKToaYm>fTWm21+Yr69Rs@%v7Yo1*(Z#L_F4ctuBmk8BXek0~4n^=_d|vckHO)N%`}E7H zYjsidO%uGor3ns&VhdhMi~=!C6+p`T7fco4w;6P<3bax$)wfqwac`CYFQ?IpDzs-Z z3Qk*-z~@u}&{Ay5ZbKw>1&&>I4{T8mf!`;FodTUUxh&uzsq8FD6@ zRH8t>%22cv$72&5TYd(EUX059e99soU5F@_of4a$whyqE=#6633CNe#8l;XY4FYT% z8RStt04j~CjMGiIbLEOpL7$xYw;e^YT&^+L_mcl|TVq^NoBzvfGAGK(xXSqdR%84Z z#UidRu5I)MTO=2JJ;OBwdo)ZPz)j3}%~D=w)?3ENqQoxbyG%hV(UvD&A{S#F?Vd@l zb&(YUi+U^*FC6I{m7EfNkL z4;7-U?7kEsynh9B5bV7sEXiWw1 zm<(LxU&GKY2VsJtR5Jm24&u^E0qD7{0LDUp(n|ZQ@3OQNz!xUt6DkFuZ`s7hqW}t^ zv3*5L6u?GT00$V8X^CP)11QLYdnpT#>{lXHi)VfuEYg-3gr@b`fAbTdwib6?h zObOi6D1qH#IHZo{Jc!pRbZ%BYKkJi-aF_`~bvy(@;*4ASgK-r%J@8~ZdG-Sji5pL}5PDf%GnhcuMehARjGXEdZQWxV44!~}Pr!U{?M$*8aW#E&3j(T74ca#;-0=W`MIS^8 z$Ukl)@=o_pwCy=y+-O7jAPB2#L%7c!X!My;nsTerxc=o#pz3QWQtPyQIhCAFeHD$n z)n8PvrFK@k?tHw1Vd#LO+doh6t<=-D!C6{`wSrh(?{=jrnlCSp1uKJiZ$0VKf=^*+ zd4W*pd^vSxe!HVlu@hzq@-dj9*o4476x2ozcz5K~s6naQ+(KyfN|l2B3bQH}yEa50 zZWQbXQLy+ttftsrNcP=8*uc*FeP+ex96^DCT{tg#B~P&0BJbL>q?yx{Y1kj9GlWGv zr~-F}0wz47An%5Vx0-g<9{N@4W);NIo;67T++Erkby=C}OOo1?3Z~L>8=FJi?ieQi z+}In|uDON1B=!2k%_e<8vtDQ8u?1&isM;p^^-w@&(KrJ&3_+lZj0_`fxmFCM)~tH2 zHS0Z~c5Lg4c=*6_s`a1y&C$5sODAOsxBwf=dRRbCt8DIB>SFD}f9#TZuu^jxWozG# z(p#gigSS5R=TdWqw!MKy$ z{i3s)ZH~?g%2{Tcqv+Ta_?t>ASC&eX7$4RxVbfxzJrV?mf$XILnKMSIhecL9j_@Q+ z^pJj${0I3JU}{Htk5nq|SE~2S)Pv_5<@ukvs#kkKAVqLf#X;Rud_~q4zSWzVH!8MS zJ3wI_1I`$08%S`lHxNR>MqW0O1Jh!}mM}uWp@(`$n%+Ob^m9zCH>p-N#-8+pn#dKf9cT~K3PU}2^@TuRmP8IHoU z)#NzM763V!m930?`0FF&RCS&%=JF_V1S&Wt$Ge}Evv=;oj=2z9!Idat?4~9_m+6i^ z6^yIb2F@*GznxY_+K%#3kSnCYuU}6FiyIcBY|5zMSB_>KUb5>O)6!gWWMC&2`_Z*d z0MIey*LNSWgNW;!=JQ_?IqjmO^YwR%>tLb_w(Bx7Z8hR*GB~b~g=Y3g;?;xjVK1K> z6rJq9Eq8AzZR|$wgiI-YzZgrP09X=f8S7M8kb>_1s zRGf_-kWH&eBa$9F_UW#TeF0+FubXaRztyq`k@=m>a>S2Z|rpi`q(GHka z<5;G}6-O~r(GhUGqwtSb27!G%eU4OI7U{arU3_coOTb! z{p0WRvYWZ5?6DL6tJ=5#iX^ij7gr010|&Y2aI0U5iZstfa*U7hDvTsn53Nom83j9M z>|NvNMcIE#;_KCt6c>lX8fOXXSjM`rnLNS@Tp3B*#4L+Af3+HQdx7dj*OBR??91>- zEd|E|9&%634!%3QBp7f2&Na08YaGIIr*-INlL?tYY?oWMAeQ`RuUP(brme>$oO@xcY^#iH$8yGLtWTB>j?ri5 zfAk3BuI=HTOS|E%!eTd4HHpHdn9`VD_t$H`)yNlB-*{}WUiWndYXqJPO}a3_c55uZ zc4K#Lt}7uwzS$eK&SXzV5&EI(R&ZP!ngEv{JxF)@EZCAaDfv4=;Yn1O+DJMNN*9`&0vs$Fr&FJ<00CsPn zGeO%O%Dx+Hn;z5hiu^It51ssG13~gC^#X?>CGHgbM;z3j<1}D4c6^?3lieV&x!84w zxlj`maguhry$Op1Zl2k72P6dPe4mGQ#f)m#_Tt#JxA3si@u%c~*oD@Z$gwik!1kpj zn<`aZHD`@z25k?LM0?OlUb_=N1|$WrYx(^P9PtivRJ1O8MiVwR4D}-b;i>8GgG_7R=v7Oq!}3s{^>*r=_$#7 z(&(Sy79vaBqLRJ9#Zvyh<`Ss)c@<>kLKoVKHRJrl>eq5jNOUggUbl+|foOe*r& zx5fUv+7fg5OeuN%x5a)3)d5l0Wz%s31>`p)m+zAXjk0GjGO6tG(m$i@^JTU>KKbj@ zj=0)A1!oiUi?b8e1K405ntw=uXa94=W(7wbUmp2RYP##nTjUPp*<`SB4GJQS5TV8z zedz+a$}7w+jSMr2=f~kx3yM;A)LJ@oQC{Pbn`wC+y_uGTaM$h%H`5**6?AhY)x3A@ zH{xmpS~TUiGwiO8xmDRtz1AW;#RbV^qMM8YU(tNjjvVT%dbZM+1TgKRwZQGFCTIZZ zudt3_hY4#{1Rmv)KsWz9R#Q(>7}@kndfMEU`&;pnr}pl@@$3F@LJ<40OIqt2|2kin zOIlw7{|0Tubhe(2iPfA98c{Oq@dUmq3qp%V{+lbPjLW_(nr8M@1jvyjvo-~l&@uI- zM3Dzc5-qb|iP`xOn8?qEigo1NXh)hH>K-Z;b%M5h-mt%p`^I~7!^vXR7PzZhOmg?N zU2;n*9JQ*F5#lB~M|eo#EbgSo%19+ms3{tI-Z~1qWEL!0n;*)MYHkXaqgPCp_r8u6 z^0&HbC?>gi#8ckvDPZD9@eM6XrLoqdW$4;(h{L+X2<13HtfA?IrI@*;*5C87xUi~M3@Y`SVmt(}hA0~g>bT87T+RR7JDQZ--DNkB zvai}MA@6uSftD(oyB6B;vxXlbn>K~f5ET$DV^^jSMGU*Lss~AQVQzJ2 zzO$=o{KVN6uR-kUx`8$VyBZO=DHmZ7?>Fp<@$#$9c?c^6So#7!4(y72EX%G4#1eK* z8g^Z1>}NAZfn_iW1e_6DK|npTP+-9clH`K$r%Liw1eAILLziEY8L_I%e~2>7at(L- zQ&Y}9Ny?b8SIbi_Zaan)^N2(C>Da^xM$l|VB=UcO(Y{?U;;D7qQ!8+-xcvcrQMp@$ zVa!{T;)(OhTSFD#YFcTeL;%=VvM^J0x2#`AlhD&&83?(D<%lcQF}DyrlJaR z+GbS;g;?f<-5)SEj`^;u&1v)B(Yu`*X|f6F=LchOti(~)kMQ5n`2}d9og{1T`E)3Hjs} z#XI>|)RHY`cS8HX#Ddo_YF_iYJDF|n@w7Vh>U}Ub%zpXXlf0Q(qvvBcC=EmC3A}$< zW-?G3>2%&0q%BHw!FHX_BHI9JHz|SA`c{!*ouic2rXfD{A~N@!#8vxXn_K$cen8u_ z)Mg)8l5$b&b>$gM-z~6VAK6LD9&i0?esmbkUsH0+0PMXmUw$83&j`{oX(o=RFAJ5o z-b!nxvsfIZNu-9*VUit-yWI0^@FK|W6lC%k%JiCH?;1#D9A!}7rM%~_M$Xht7=`RC zDfxq<#ARdPlGonl1UIUTY{` zbiTm^=ZDlVYo0aLwy-g#<3(+ToaFyvMQA^NSWg;;4NLn~`Jh;N?e_Baw;lkU1Bk;- zY8vt&Z7{h5Vll_9!rYZz{7+0jP&BKI|>zf9(Z| z-oo}k4_1W%qq7Vca>0G1!;Zk6Qpk=A1r~ z1?z)PA9ZCG6AoznjR?ao@=7>UF-zd#pcADp7%)GwAAIkNXZSybZzoU{O;5`9>wQF?&D>uv>Yn^za}`HP$Gma{DsW7gC6&j%h+7MWlz)P2nEEOaUCGgM) z@au>uPYz6?RllX3QpSL^KHDv&a8qcP`q-dxZx(aQ&UYhgVjv~gXvNt(hHq& zdr|1@g!y6ajSbngZ6l>5ig}I;4yKCLb8|&LH$UX4mxZW1=kQcnwL)kXnL*qmCa_T%ZT*b^RMf2&IBB!^j)nnEh}`M8LP8UI$yC7-!B04GfQiVo^fJI&z= z3p~z~5xCsz7&SO{C2VFoE^6$n+;;#ZURCQjK#_fw zFCfa-4vPE~VC|b&$l+Izi$RJ%=tNT<8%dyRt*CI|Iw6fqm;-NUD?QD@Ug)2I5Sffh znPd5it}!3BeQw@^!nM%JX#v|ojp>qrDE~*3)2_zMn@=`60Y#D955}rY0v9rrU7p-6 z`l*SsZxVs-&aMChVIZKG~0kb|aI zhpyfoWPcWJU1JA{1!V4fG}4=LlNW^br&z_ANzIvwb7pI_I50_zM`7e-j7K&7;MkS% zC=m5+dCGV+sd<#SqOfK>YF=MpPW_l;*uctMh}i8JTy7!Jrk!I+tGmWrMeB0x{xj$f zujV-8i-y;`^b5L23tKAve!_DPjuy65azEp_heB>BY^mhluurHemNI5`g(hKwO{BPUhmW|^c~H$ zRIqWE=N=d>Y^mga!gCLX+)&t3$^DGy9tydku%(iFkLTVOazkNDCHG#>JsfgFVM`_V ze$Ra{8mfGaruH2)B@7VHCTOfSQ zmKRc6D+RzNU8zfLn;NC0HfAwp#4O>3OyY%93K%UERP0fEZU+uEaqD>(vO1biEa!!w zw-j}1O$oGQg{gR|^gltgI#gfuvfuBrHJ#Rp+RE5e5hC>Z-*A7xL9|IOzH=VWEO)jbNe)hHi$#g9$*pqd$l}k z0xeLO7C+`MSujckt{%4$S;g`>w!4W8afmV0%cTQ6QoPD$__C zJ}?FUUrpOvHDXbyo;<0Tk5_9Qt+BgFW#m>maG6TGpWvnaneHnat^!Rz^>j=K3SANz zO@i~|gfVa{Jn;!-4a)r>E#Sxx!j}nn@{i?Ic#<78?@+y(3yB{ziYK8aI0qwCZxK54 zEm9SsC~xy|MQ~egKq4^feu$mLWXlbR%?*Hw`WDxwVTM(^0g1L?;(5qbg#|@lsNp|g zyPw^k#9jNW`PxCOE|OW;`QL?uBJz3M8jF;!A!sLDr0X0dHdnR_rMT+VxEgNqifpsB z;D>r)Ikb8assxJGd2|nUI$NZ~URXmWTw^#UgRlblR!EanI_^~6;c*inQpg+#wI=4E z&LpQdQB`em0BkWFa$By^#F#aN=V)hwyl_@+?5HL5v{xw$p>)3~&Fkf2o-P)*ckzjY zajh^yJAOi%@n{2@wZH;e6e3M_dRpU9wk8X7u=a#3`%_^TEd})e$z~(Ou@$ypgPz5) z`LY>rieo1p$4;s^w*0rvOrx~xkmhufD5=8P;3q_weE+Odt{w}AUg9FDLN!`#(pF#( zw9$LF9h@rsV2m&GNC_yGV;F#ugmAjYi(IR~ni@625i)CHYD40Xkv90@XDXfs?X0_2 z1WcXiFiPMIu@Y;jE=Pt^84dU4uakP=EoYWZ(7#!740Ol`W?6YN40X;$Dsa zHaS+d+c3luQswb~1ivM=2?h+nD7uDQ{Ni6!4f>Uh7h>-+z9xT->sC!*ssKkbB_Eyt zPq;oA^n-z0Rh!Vs)-;v)K-iov+0=vI~jLWBE0w3nfhn6d~g=JsPPqFf0Z zFh{UI3fkOjwkFQrow1q-FNVc7c%_LF8)h6j^T~TS-ggQkts;5KTId$uV0=pkj1+(tT7`Pr?bhd z><$=dM=g0-617x+h+WW9m8ZCjCZjnZLA8W#;*>7%H$s3`=8|t;BJNci>Ry$GI2(AL z`KzQ82RzE@^NlH%Po9SeDeSsM3HDT@K}tBV`2c-Q$5k*jsnnv}_7Li7&n)N<8nIMe z#fa#8B&=CCu<}j>8>e~gs9F&uS#Cm6q_)G2&BMPhmu4RKyoO&7#&)d8!%90tB-GqA z8FuJfxo%?InGj83-vI{9)g?i4Z}>D$E`MX(yLZMuWjPwIjU1Tv2E!sx6(Cy~*(|eF zlmqd#Y++Z02}ic`{<6qs!*_&b5g+`Kux)3q+ec*MGl@7ak`Ei2lgO`6uFNzB?|eFm zVvJSFEa*{f2pS~FgB@?zVQ6zS_=7>yGr96&@Mp9M1EZ(WJ$wt*jE~{I+r;8}VY5O0 zZoTAx;m}bMq=b4?yd6HidT)rE%}*R!ow0mAp zw){=TBmp92Z%WQb8Axzy`DPaY-VS<(R{%C9P(!D=y8(?4N zx`I8Y+V+!bdsp3-w*9cZxaks@-QS2IVzq6i8z$uz(-(tO|5BowiNlSU48jr6HyB*| ztX%D4X*JYlwJa_4>a}N<)~LCKG=ApUhB9HUy!J`>Y*Cke1RszRmI)Xt%|L`l)nkKa zf6MA#rCfnreBGNTvuE>pj=QrzJa}eAA!Bkn*SWniSGVo2u z7fJ^3GbD4_3*4IOL&=t6{Oigoc!2EQX5&?@s)d(BGOg^D(&Z!UiVf>?Udxvhar5Ce zC=!+wr&eie09%n-^xvXO%j?)bQyiXsgOohe=E-*~DOz4l>>b(9KU#hD#R|Qm_Gl_* z0%m7sR+^EJOTQ5caa9c>Dz^<- zKOne^<6mzHs|U%@R!d=q-EwxJfLx)#!R56jHzK*ntg}sXBKDSbehR=Qo~AI0)Mm(n zLe5QHf?Z}oqv(Q;swFNG_Z6<}{0J(jH`742y%k+(;jMg^nB05|7w~Ft9L<1HPH8It zG~TkGXg1A`ZepXNXQBy*-;!Luqj?%}d;8!7Rd~s1$ofkUS; zDISg2QAAS4i`G$UM_rJ;lpbX$ESVuwVwXxtSi2%O5wa5vPQ7>SRJ^rgrD$6_1NhvI z>Trc$C|Y+!xWPKv$*`;ofVO!LyQnicF!YfBr3}vdg6IdyL!RI`#T(&2IZAy# zcA)a7QTsnpLoKMgN9A$hP1=#-B3Tz8p;Ra0kKfNR$97@hVQ;V<^e3pLm^~A?9e7Ok zP(<6alZ5f7L%{f&dH$Zk3C<1&ZOy5ILkQk-Hbp0V_%7#m3e_1LZ?ubx0Ef+t1ROh7 zP;aaQ#21)TtZHoY%f5pq3M9U((pvuEIQ`f`K;W$lfZnXsyJng7n)FUZ!&`~Gt6Ty{DLPi6&OF69AoY(t)6 z(J>{9$V#Fj!*4&JhAVKkH;>nF-i<2)Y&Na72tNB{n7Aak0_f-Yfh6@nwx?#_BWfpQ ze$6b>N!P{@{E(*kHmtn!Il~0!1uT+^+GT4dui}7mxj%8%i?n0Rhy)+r;-=xn^b`0H zDUHrFmb9U|`yScxW2wQYJopB&Iv1;I38p-x#L8ROaOmcd8y01ObXAXV zz&EDQHBi_uNC>M;G0yRHlEhN<gf z0YI?uLnGs=&POE%}m<2Ei*2`(qHkKXqX>KF40@TQ zZTW%AJ*CQ=Yq&Ur1JOW++F=e(AkCkmf~Isid0;37DCMx>mkrn|p3WAWK09+4< zvnI(tHfuH2$-Py6a*tMZL+L6VSR1U8vzKm&?Bt#jIk`7UhpYVL-lR_H_3fT>o!qlU zjJ}=b+YtH5J?&9nMHpgHa%;AtF@u%J=&%bh<6Zu;fLasvD1Hk+wAH~}&ZMv!P=-f>@pZ8{HKdla%@ zd$(HmUAEv;M=|tW20FJlre|~XT+TihVt{MhM+#^aM{@x@sdb1p4RiuCiA*Mqi1>-H z@nU4hRNMy+A7?~D-G@!`_lXw_TeOkLkX7F@N}-RDj}v*ENVJ`oP!0%0wWK6`Ci+{7 zsBZ}3$m0*cxsi38J_xz;t^M$ zA97!a08D04C8+uW9R=;5vku)oOsCT%iVcSxMsS$fB7Y6-@xv_t8f}(M#f?%_cA${U zYtdz=)3a3CATq8-Wnq2g!$R+3m255IwHV3#vcr!>QZPcB^-0h|1fX1neJv4(D@xf_ zrgc5mGPdBJSDi0ymaLtuOQ?`3SGC9k9%j|($~j_?H2Ys8iX;sRGKC9VK@va0%1S|| zmGaQk-&3S#PKUX8)2Yi8k67AL0f`XQs8z`wu1a)4z<<`-4Z8C~O3FUjjVCJ=jnCOY zz;$~wMY>rUo9p({0^|@FRnPRLAK(xGVb2s2?*Cc{Y1jpQa>8Yipa6)0AOmQ_CVy?` z7OU#k6XXrbGK<#QESv@B1S0D^1*2Aw$#9F@gVqMKtJxVZ?-F37rkyha$?anv=m_=4 z50vEQV{x!)3Wd7-$RLJd0WQ+XCqaWgXaU23dm{i@Ft-5+ksbv|1jVuA=thiL+n~$m zz#y%!@d--7qwTKu%a`-PBwa{(Oa#ouF8tGJ93_bED&cBM`K)UXU=XWi zBLAczp87s93KRgV75b3^$9o^l7hv92HlZzq_A%;of}v7`C#F-k1xaDEQN(IV&KK@u zxkqU|W5QD!IrO}{$5)N$M)TS-qOVu#$Q<(UJRK&$@#6#>4x*wkJD+1(F%^ZE{#!s? zQIO*#YZuD3ufU$z>BSycXL2x)=HiLPS*`)lUif&hivKZ*qyG{FJMxnUI15Bm<@IyZ zDVlCt17Mxstykg?52Tk97Pe{i|U~Xxf)OMmpp&90S_2OW?#cl>c%arS8+awls92X zCmAG<7jG~3a!J=J#E7@OJ72I`=39Nx+!@~76c#IVaQ*i3N-U%>!)Y06U}~&}Qh1%E zzDTQKCx($158H3sfT$i)lHh=7Q-83qYQ+x5Xy90k2^}aA!G;sCZMk^EjW=Jr zofzOm;OaU-ngV_xzS)x>*FfP1NCOOlUud+%rcbUj5Fn~#p)-S8eTrDPd^KN8ARMc{<0Q`aEqUg*$>em6c+KAG?y5@yy?1hDnnr zbi>FjXhW1|Yb`z0FiY!ZKKooR+~{GeZsm8GrB@qk6${utjMt$^5#Qi*!dg68KAKn>&{nIgT=p_dNDtZxRofM*s_Y7fZH5>*;y-7$Ujta4_K! z2?7ERaqmp;?s(_1+ugg~4G=lXg+qiA4q%}mMFL?72@#ORg&fR{6XJkG4naa99Jq0S zQ%ub7U)?i1vpY6MA&{}k)m2@OufF=8Rn@h!(KNOn3hR*A5ri~kv9D-#^lJEzTFDyi zf^Ez@7HYRxg(kJJbc7Mo`ZD%i253_IF7r?>mq}#Rzv((Zt!r?mzshS4T)=xfz)xh% zLJ*OTd1w|M71$@hg@(9jWzUO!gby?~ozwo&sb-wI7ryKxM7unT z8MU50&(L*j$6f$LZJQ;NFr_O4h_n|oc_|r>0amt9d81Vz9H?6Oq(Eb%#wM4cqTn31t1&H2<-V^_v2+kQg%aT|N-k*yAt|3MLK`We9tHyn4uo!6L*$;W3wp7905pu8YahZ zC9T0uXyiqcqe-^2BX;5`Whb6ecH${zCrXN)_@q+o1WQ0gGBhU}q2a7h%SYHEpSe`T z<}f7zbVi1$2Jnq7*8bCuF=~-08UUZ43_&oN<~*dyOrS9z|9M$?IPCf0$kI2arVb29 zyx#&z{KxlE35Mv017+xWdd~9)*tf*pjNP2l(@jCy7%o?aJ-euJ7;}5br{>y=xgDr) zb|>`EjPv>mJo#W{`nyCbOnoQ8G3^D1L#~()S&;L{6MfqTT2ZuI0if+0S>RdD?|FBg zxjnbVqlvGu*_ZFK28HHCG7GDTtinz|I6mp2)MLPB)ZAc^K_?l5mh8~$H8`2~ZtLJ+ zLLpfpB$Zi+=EwsVxhc4q{w~4A)OW(gv=`&JVAx}1Cig+ms3yx31{79FM$^K|i3ncz z6B%J)PMOGozZc??bFo60_*N*%8k8_iqqTrJtpjAlGZI`PH_nca_=TsGUwBISg{PEX zC^>`(eqo)GiIsId*$C5zZb_yYeqnh+Y_;&|jFvdlDM|#aR1n$));6o*iR#vZNpkT3 zo5VA6nMFJ*F?6FBwkDSQvnS=1TEe9cEhOSzn9?3GLmk^BGJ8v8jcpQ{TbI~gQZK4A z{brOGGC==P(~mdq7$=4noyr7~ML9B+a$3wZMpF)_N7>H_%B0-Q=WppTb>6kKlD<3% z6e>UT;dM=~+(wolZPWg~H~(J->G$tEkiI2v>3@kOv(S6biF@@vK}u&0ZaF-0FK6~Q z_O9W6j_4P^a4`o{TJRIhj|W9?yap40YzqZ&l=B|>D~V&kCH5jXoHMCVsgJyO46TaL zg!`_^E%2T(7k6<`KjZ!A+n}=Wf~-1A?4R*&D#v5@LLE`wgMl^*FR27AXO%VNtA)R2 zb6Iw8M@NnJIlw!WUPo+Qc>cH6SEUNgVF2al&I2G$4SzsDYld)`DRgaVMrEJ=<_-L5 z-Er-`ZuOCYnb`ZKV7gMYtWQ{4rFoj0Ly?)UTiuPM;K3p&T`d<`7w-J}55+G@zXCc6 z!>l>Z+@RY(o6~~{7_`R)IJWX>eAM&o-8)D%P;xQcL?ieRli*6KrX`ShbTf;?!&D(4 zLAP1y_cUP!AKodnVTx-lqYaN5ai=GnQd-CI{-#|w5629lHYWKV0*Q78A@DOz)WRtF z@?`QCCizO1t%6kGiZ*P>OK_qem}}Gna4yb3Fy=5mFYSyLxezzAkfP{J+om!`q+(gk zO1w*5n#p;RIhl3%6gkrarzx~@M4Rj*NYiEHp&n70qtY2D8(QP?knD!{FgN|lC^buJ zSkst8*d)?~9My^0j+4q$9rQe{;*Zj?S*$b7Voxt-0Mj7H2-L%+rE!e@!_3#xpV-2j zZ$QX1W;4i4I>^*apB$vM@Z*^jdm10r0cyjz;le+|CWA<8Sl~7TZf5{d-55S3oyRF3 z!!`DzaBWV4YV|b1HAkW*am_xCzU>&pHCFNv*ZCCJtTfy|u5)+8b#5B2WscuJu2uRV zuI2j39M+N=50J$ChHQ8{`Qy!C4RgfIf&LbU#+qV4Rvq>LM3A%!UD$FZMMN_jIws8b z+lyvx85*6#6j$TM05>~4thyxhhEx!}&Fs@#iUUo2vVQ^faKVfrI_P;PB|25a*3g}f zDGtoW5&kqz4Da@%*l8#;xq zQXJX)C1FOun;;O2JHAmThAu{wcW*8S1~^^pJxTH@Uu)`?MBs*&VPkQl76IiibQiN! zH%B3a-w}5*a^s*R93TlW&S;1GvM>j^Kh#Qkp}cWh@p|>`mvbR&Vldk#BPsZEBlZ^V9M7Nvuidg1{&D<`+y8v?j%8U{f_}v(q9BZlJ%6pg z9jyed^{btJyZCrGxDvGDsMs3xTZ6FO+3qce+flq6_53hiCN~cK1Mf$fyzcb|{qeeo z-bG=n*y(L{qqAXT75Miou(&gp^)ce{^an_PIqbxp{+b;RY~S7iu0d!=>x1oX+m5zd ztsrQh9o6{>ZG4D2r_WechWG(Oo}lsO(r4d(v=eQ1{XJVC1ihdi`*CN`x5FUb4*Nmd z_WO1ahIF&t4|X@{F=%)9ESfeywL42F3MH+gTWz^bw_UIK?bY&XrRmrFrdx9wtEJVz zX$2+6FR!@ml~%FaSqc4cujqHXgH}-}h~kie2?w9a6s*T+^Djp%>mg$GCAbyl2=fG9 zO~7!Jbc@CS`10pBHG*^Jw)3kmH9rq+|gEckGUhiT4xSQx0I^sjh6HJ1J^&nF4ljFnrDEAC4Pli{SM_z6t|6Z zF}0bz*LeRh@1KA#MJor(ZTkIAYa-p3FBo1hh)0)^ph<8AYlm8zHAKrt4|{AfxqQ%`mIj9XAgFQaJ4(Q zO8J|>DV$zU;e8PJ#BXN^f?GeeEtt>Qmh~sf>GyYHijMk2y9EYWtG&3`-|mUl=jRGW zhXj<;n^=iFVuh$!Ox87_xjZ&lBs5GjLTBF`*G~7nhb=;C$b}Mext+{o# z;ks_K35ZR)Z_;#=YE802zrPmPQH&C|(euHsZ4b6%8`?_VtV*+XJFP%j2)DI(-L|YZ z!H4F(Fki5ih?BBGzn!-6DEY$f@O{!k(!S{{vi%t9r6($xgw>{w=;JA3(QY)@4(T?j zn)ZxnZ4V&${vft{e%xBO+d+gSkTAq#(d)D$+WRT-$B8xHn*YrI`3DGZ@t3{lZ*0%o OJm&Qq>+w@EWBvtAtv5aZ diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index ef72fc573..cb5d418a5 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -3,6 +3,8 @@ import com.concordium.sdk.ClientV2; import com.concordium.sdk.Connection; import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; +import com.concordium.sdk.requests.AccountQuery; +import com.concordium.sdk.requests.BlockQuery; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.*; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -20,19 +22,19 @@ /** * Calls different methods on a cis2-wCCD smart contract deployed on the chain. * See {@link Cis2WCCDParameters} for how to create and initialize custom smart contract parameters. - * TODO what values should user replace + * SENDER_ADDRESS, MODULE_REF, CONTRACT_ADDRESS and the key in SIGNER are dummy values and should be replaced */ @CommandLine.Command(name = "Cis2WCCD", mixinStandardHelpOptions = true) public class Cis2WCCD implements Callable { - private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // TODO dummy address - private static final String PATH_TO_MODULE = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.wasm.v1"; + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address + private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); private static final TransactionSigner SIGNER = TransactionSigner.from( SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key - ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key ); @CommandLine.Option( @@ -62,9 +64,7 @@ public Integer call() throws Exception { .timeout(timeout) .build(); var client = ClientV2.from(connection); - //Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); - Nonce nonce = Nonce.from(1); - + Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce(); switch (this.methodName) { case INIT: handleInit(client, nonce); @@ -126,9 +126,8 @@ public Integer call() throws Exception { } private void handleInit(ClientV2 client, Nonce nonce) { - ModuleRef ref = null; InitName initName = InitName.from("init_cis2_wCCD"); - InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), ref, initName, Parameter.EMPTY); + InitContractPayload payload = InitContractPayload.from(CCDAmount.fromMicro(0), MODULE_REF, initName, Parameter.EMPTY); InitContractTransaction initContractTransaction = TransactionFactory.newInitContract() .sender(AccountAddress.from(SENDER_ADDRESS)) .payload(payload) @@ -137,13 +136,11 @@ private void handleInit(ClientV2 client, Nonce nonce) { .signer(SIGNER) .maxEnergyCost(UInt64.from(10000)) .build(); - //Hash txHash = client.sendTransaction(initContractTransaction); - //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - //sleep(); - //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - //System.out.println("Transaction finalized in block with hash: " + blockHash); - System.out.println(this.methodName); - + Hash txHash = client.sendTransaction(initContractTransaction); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + sleep(); + Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + System.out.println("Transaction finalized in block with hash: " + blockHash); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -156,16 +153,13 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .signer(SIGNER) .maxEnergyCost(UInt64.from(10000)) .build(); - //Hash txHash = client.sendTransaction(transaction); - //System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - //sleep(); - //Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - //System.out.println("Transaction finalized in block with hash: " + blockHash); - System.out.println(this.methodName); - - - + Hash txHash = client.sendTransaction(transaction); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + sleep(); + Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); + System.out.println("Transaction finalized in block with hash: " + blockHash); } + @SneakyThrows private void sleep() { for (int i = 0; i < 200; i++) { @@ -176,6 +170,7 @@ private void sleep() { Thread.sleep(30); } } + public static void main(String[] args) { int exitCode = new CommandLine(new Cis2WCCD()).execute(args); System.exit(exitCode); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java index 003128a3f..06e8a656f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/ConfigureBakerKeysJniInput.java @@ -8,6 +8,7 @@ * Configure the account as a baker. Only valid for protocol version 4 and up. */ @Data +@Builder public class ConfigureBakerKeysJniInput { /** @@ -19,10 +20,4 @@ public class ConfigureBakerKeysJniInput { * The baker keys that will be configured for the account */ private final BakerKeysJniOutput keys; - - @Builder - public ConfigureBakerKeysJniInput(AccountAddress sender, BakerKeysJniOutput keys) { - this.sender = sender; - this.keys = keys; - } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java index 755bbf578..cc8383edb 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/CryptoJniException.java @@ -8,7 +8,7 @@ */ public final class CryptoJniException extends RuntimeException { /** - * The type of the failed operation. + * The type of the error. */ @Getter private final JNIErrorType errorType; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 3f8b34b48..e7f07360b 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -132,7 +132,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, CCDAmount amount, SchemaParameter schemaParameter, Energy energy) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName");} return from(blockHash, invoker, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } @@ -151,7 +151,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, CCDAmount amount, SchemaParameter schemaParameter, Energy energy) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with an ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName");} return from(blockHash, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } public boolean hasInvoker() { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index aaa68ab27..ae9f35722 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -79,7 +79,7 @@ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, In * @param schemaParameter {@link SchemaParameter} message to invoke the initialization method with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. */ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.INIT)) {throw new IllegalArgumentException("SchemaParameter must be initialized with an InitName");} + if (! (schemaParameter.getType() == ParameterType.INIT)) {throw new IllegalArgumentException("SchemaParameter for InitContractPayload must be initialized with an InitName");} return new InitContractPayload(amount, moduleRef, schemaParameter.getInitName(), Parameter.from(schemaParameter)); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java index 9ae05b4b4..7b9821082 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContractPayload.java @@ -71,7 +71,7 @@ public static UpdateContractPayload from(final long amount, */ public static UpdateContractPayload from(@NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with a ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName");} return from(CCDAmount.fromMicro(0), contractAddress, schemaParameter.getReceiveName(), @@ -88,7 +88,7 @@ public static UpdateContractPayload from(@NonNull final ContractAddress contract public static UpdateContractPayload from(CCDAmount amount, @NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("Parameter must be initialized with a ReceiveName");} + if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName");} return from(amount, contractAddress, schemaParameter.getReceiveName(), Parameter.from(schemaParameter)); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java index 73c750127..3f4ef0941 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java @@ -9,11 +9,11 @@ */ public enum ParameterType { /** - * The parameter is to be used with {@link InitContractPayload}. + * A Parameter for {@link InitContractPayload}. */ INIT, /** - * The parameter is to be used with {@link UpdateContractPayload} or {@link InvokeInstanceRequest}. + * A Parameter for {@link UpdateContractPayload} or {@link InvokeInstanceRequest}. */ RECEIVE } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java index eaf5bf8d9..7c38d61e8 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java @@ -124,6 +124,7 @@ public void initialize() { * @param verboseErrors whether to return errors in a verbose format or not. Defaults to false if omitted. * @throws CryptoJniException if the serialization could not be performed. */ + // Should never get thrown assuming the parameter is serialized correctly by the rust layer @SneakyThrows(org.apache.commons.codec.DecoderException.class) public void initialize(boolean verboseErrors) { byte[] schemaBytes = schema.getSchemaBytes(); @@ -148,8 +149,7 @@ public void initialize(boolean verboseErrors) { private SerializeParameterResult getSerializeParameterResult(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion) { SerializeParameterResult result; String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - String resultJson; - resultJson = serializeUsingJNI(verboseErrors, schemaBytes, schemaVersion, parameterJson); + String resultJson = serializeUsingJNI(verboseErrors, schemaBytes, schemaVersion, parameterJson); result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); return result; } @@ -184,7 +184,7 @@ private String serializeUsingJNI(boolean verboseErrors, byte[] schemaBytes, Sche */ public byte[] toBytes() { if (!initialized) { - throw new IllegalStateException("Must initialize parameter before use"); + throw new IllegalStateException("Must initialize SchemaParameter before use"); } return serializedParameter; } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java index a808b1980..bda7b9463 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java @@ -3,7 +3,7 @@ import lombok.Getter; /** - * TODO comment. Where are the versions coming from (link?) + * The version of the {@link Schema}. */ @Getter public enum SchemaVersion { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java index f7c5c6063..457d2b63a 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java @@ -9,7 +9,7 @@ import java.util.Objects; /** - * Class that holds the result of serializing a parameter using the JNI. + * Represents the result of serializing a parameter using the JNI. */ @Data @ToString(doNotUseGetters = true) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java index ed6595e6f..4e11334c0 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java @@ -19,6 +19,7 @@ @Getter @JsonSerialize(using = AccountAddressParam.AccountAddressParamSerializer.class) public class AccountAddressParam extends SchemaParameter { + private final AccountAddress accountAddress; public AccountAddressParam(Schema schema, InitName initName, AccountAddress accountAddress) { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java index 0d54c32ae..e6651bc6f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AddressParam.java @@ -32,7 +32,6 @@ public AddressParam(Schema schema, ReceiveName receiveName, AbstractAddress addr this.address = address; } - public static class AddressParamSerializer extends JsonSerializer { @Override public void serialize(AddressParam addressParam, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java index 71a40987e..55289d999 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -16,12 +16,16 @@ /** * Wrapper for passing lists as smart contract parameters.

- * Contents of the list must be serializable according to the provided {@link Schema}.

+ * Classes extending {@link ListParam} are serializable as smart contract parameters. + * Contents of the list must be serializable according to the provided {@link Schema}. */ @Getter @JsonSerialize(using = ListParam.ListParamSerializer.class) public abstract class ListParam extends SchemaParameter { + /** + * The actual parameter to be serialized. Extending classes should specify the contents of the list. + */ private final List list; public ListParam(Schema schema, InitName initName, List list) { From 380ad5e8d5e6f9da44c1fed885f4d5b0cad58149 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 27 Oct 2023 13:43:13 +0200 Subject: [PATCH 26/53] Cleanup after merge with main --- .../contractexample/cis2nft/Cis2Nft.java | 2 +- .../contractexample/wccd/Cis2WCCD.java | 2 +- .../crypto/bakertransactions/BakerKeys.java | 3 -- .../bakertransactions/BakerKeysResult.java | 2 +- .../sdk/transactions/UpdateContract.java | 45 ++++++++++++++++++- .../smartcontracts/ParameterType.java | 4 +- 6 files changed, 49 insertions(+), 9 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index 918ca98ab..5faa58c41 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -129,7 +129,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { - UpdateContractPayload payload = UpdateContractPayload.from(CONTRACT_ADDRESS, parameter); + UpdateContract payload = UpdateContract.from(CONTRACT_ADDRESS, parameter); UpdateContractTransaction transaction = TransactionFactory.newUpdateContract() .sender(AccountAddress.from(SENDER_ADDRESS)) .payload(payload) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index cb5d418a5..11750a089 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -144,7 +144,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { - UpdateContractPayload payload = UpdateContractPayload.from(CONTRACT_ADDRESS, parameter); + UpdateContract payload = UpdateContract.from(CONTRACT_ADDRESS, parameter); UpdateContractTransaction transaction = TransactionFactory.newUpdateContract() .sender(AccountAddress.from(SENDER_ADDRESS)) .payload(payload) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java index 104bb7a79..f24835b9f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeys.java @@ -14,15 +14,12 @@ import com.concordium.sdk.responses.BakerId; import com.concordium.sdk.responses.accountinfo.Baker; import com.concordium.sdk.serializing.JsonMapper; -import com.concordium.sdk.transactions.TransactionFactory; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.*; import lombok.extern.jackson.Jacksonized; -import java.io.IOException; import java.io.Writer; @Jacksonized diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java index 45d333f83..fa1a98f1d 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/bakertransactions/BakerKeysResult.java @@ -15,7 +15,7 @@ @ToString(doNotUseGetters = true) public class BakerKeysResult { /** - * A {@link BakerKeysJniOutput} object, containing the output of the generate baker keys function if it succeeded. + * A {@link BakerKeys} object, containing the output of the generate baker keys function if it succeeded. * Populated iff {@link BakerKeysResult#isSuccess} is true. */ @JsonProperty("Ok") diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java index 50edcc63a..5a211b92d 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java @@ -1,7 +1,8 @@ package com.concordium.sdk.transactions; +import com.concordium.sdk.transactions.smartcontracts.ParameterType; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.ContractAddress; -import com.concordium.sdk.types.UInt64; import lombok.*; import java.nio.ByteBuffer; @@ -62,6 +63,15 @@ public static UpdateContract from(final long amount, Parameter.from(parameter)); } + /** + * Creates a {@link UpdateContract} from the given parameters. + * + * @param amount The amount of CCD to be sent to the contract. + * @param contractAddress Address of the contract instance to invoke. + * @param receiveName The {@link ReceiveName} of the smart contract instance to invoke. + * @param param The parameter of the contract method. + * @return A new UpdateContractPayload object. + */ public static UpdateContract from(@NonNull final CCDAmount amount, @NonNull final ContractAddress contractAddress, @NonNull final ReceiveName receiveName, @@ -69,6 +79,39 @@ public static UpdateContract from(@NonNull final CCDAmount amount, return new UpdateContract(amount, contractAddress, receiveName, param); } + /** + * Creates a {@link UpdateContract} with amount = 0 from the given parameters. + * + * @param contractAddress Address of the contract instance to invoke. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + */ + public static UpdateContract from(@NonNull final ContractAddress contractAddress, + SchemaParameter schemaParameter) { + if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { + throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName"); + } + return from(CCDAmount.fromMicro(0), + contractAddress, + schemaParameter.getReceiveName(), + Parameter.from(schemaParameter)); + } + + /** + * Creates a {@link UpdateContract} from the given parameters. + * + * @param amount The amount of CCD to be sent to the contract. + * @param contractAddress Address of the contract instance to invoke. + * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. + */ + public static UpdateContract from(CCDAmount amount, + @NonNull final ContractAddress contractAddress, + SchemaParameter schemaParameter) { + if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { + throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName"); + } + return from(amount, contractAddress, schemaParameter.getReceiveName(), Parameter.from(schemaParameter)); + } + @Override public TransactionType getTransactionType() { return TransactionType.UPDATE_SMART_CONTRACT_INSTANCE; diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java index 3f4ef0941..cd032252d 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/ParameterType.java @@ -2,7 +2,7 @@ import com.concordium.sdk.requests.smartcontracts.InvokeInstanceRequest; import com.concordium.sdk.transactions.InitContractPayload; -import com.concordium.sdk.transactions.UpdateContractPayload; +import com.concordium.sdk.transactions.UpdateContract; /** * The possible variants of {@link SchemaParameter}. @@ -13,7 +13,7 @@ public enum ParameterType { */ INIT, /** - * A Parameter for {@link UpdateContractPayload} or {@link InvokeInstanceRequest}. + * A Parameter for {@link UpdateContract} or {@link InvokeInstanceRequest}. */ RECEIVE } From 4a3f2989abb2f91c95ab87f24a0786af75cbff38 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 27 Oct 2023 13:54:58 +0200 Subject: [PATCH 27/53] Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a9c3ecb5..34186edba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## Unreleased changes +- Implemented custom serialization of `AbstractAddress` and added class `ListParam` for conveniently using lists of objects, `AbstractAddress`, `ContractAddress` and `AccountAddress` as smart contract parameters. +- Added support for creating and serializing smart contract parameters using the abstract class `SchemaParameter` and a provided `Schema`. ## 5.1.0 - Fixed a regression that made it harder to deserialize transactions from bytes. From 3005c98c6256d5143dc70a512d9a261f9c15ad8d Mon Sep 17 00:00:00 2001 From: magnusbechwind <93247743+magnusbechwind@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:44:59 +0100 Subject: [PATCH 28/53] Update concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java Co-authored-by: Emil Lai <39825288+EmilLa1@users.noreply.github.com> --- .../transactions/smartcontracts/SerializeParameterResult.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java index 457d2b63a..5d70b28e9 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java @@ -24,7 +24,7 @@ public class SerializeParameterResult { /** * A {@link JNIError} object, containing an error message if the serialize parameter function failed. - * Populated iff {@link SerializeParameterResult#isSuccess} is false. + * Populated if and only if {@link SerializeParameterResult#isSuccess} is false. */ @JsonProperty("Err") private final JNIError err; From b8da609e1e5fd4ebe8c03be77ac37d33e4f0d7b7 Mon Sep 17 00:00:00 2001 From: magnusbechwind <93247743+magnusbechwind@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:47:55 +0100 Subject: [PATCH 29/53] Apply suggestions from code review Co-authored-by: Emil Lai <39825288+EmilLa1@users.noreply.github.com> --- .../transactions/smartcontracts/SerializeParameterResult.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java index 5d70b28e9..59abdfc78 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SerializeParameterResult.java @@ -17,7 +17,7 @@ public class SerializeParameterResult { /** * The serialized parameter as hex encoded bytes if the serialize parameter function succeeded. - * Populated iff {@link SerializeParameterResult#isSuccess} is true. + * Populated if and only if {@link SerializeParameterResult#isSuccess} is true. */ @JsonProperty("Ok") private final String serializedParameter; @@ -30,7 +30,7 @@ public class SerializeParameterResult { private final JNIError err; /** - * Whether the function succeeded or not. + * Whether the serialization of the parameter succeeded or not. */ private boolean isSuccess; From 8cf10a35e54df065604218c2a59adac514dd6b2c Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 10 Nov 2023 15:32:35 +0100 Subject: [PATCH 30/53] Addressed review comments --- .../cis2nft/Cis2NftMethod.java | 31 +++++- .../cis2nft/Cis2NftParameters.java | 55 +++++++++-- .../parameters/BalanceOfQuery.java | 12 ++- ....java => NftTokenMetaDataQueryParams.java} | 4 +- .../parameters/OperatorOfQuery.java | 13 +++ .../contractexample/parameters/Receiver.java | 14 +++ .../contractexample/parameters/Transfer.java | 21 ++++ .../parameters/UnwrapParams.java | 18 +++- .../parameters/UpdateOperator.java | 7 ++ .../parameters/UpgradeParams.java | 58 ++++++++--- ...java => WCCDTokenMetadataQueryParams.java} | 4 +- .../contractexample/wccd/Cis2WCCDMethod.java | 48 ++++++++- .../wccd/Cis2WCCDParameters.java | 17 +++- .../sdk/crypto/CryptoJniNative.java | 36 ++++--- .../concordium/sdk/exceptions/JNIError.java | 7 +- .../sdk/exceptions/JNIErrorType.java | 2 +- .../smartcontracts/InvokeInstanceRequest.java | 70 +++++++------ .../com/concordium/sdk/transactions/Hash.java | 12 +++ .../sdk/transactions/InitContractPayload.java | 9 +- .../sdk/transactions/Parameter.java | 4 +- .../smartcontracts/SchemaParameter.java | 31 +++--- .../smartcontracts/SchemaVersion.java | 3 +- .../parameters/AccountAddressParam.java | 3 + .../parameters/ContractAddressParam.java | 3 + .../smartcontracts/parameters/ListParam.java | 2 +- .../sdk/smartcontract/IncorrectParams.java | 3 + .../testresources/smartcontractschema/lib.rs | 92 +----------------- .../smartcontractschema/unit-test.schema.bin | Bin 644 -> 629 bytes crypto-jni/Cargo.lock | 6 +- 29 files changed, 394 insertions(+), 191 deletions(-) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/{NftMetaDataQuery.java => NftTokenMetaDataQueryParams.java} (69%) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/{WCCDMetadataQuery.java => WCCDTokenMetadataQueryParams.java} (72%) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java index f796d513c..053b113e7 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftMethod.java @@ -1,16 +1,45 @@ package com.concordium.sdk.examples.contractexample.cis2nft; +import com.concordium.sdk.examples.contractexample.parameters.*; + /** - * Represents the different possible methods able to be run by {@link Cis2Nft} + * Represents the different possible methods able to be run by {@link Cis2Nft} representing a cis2-nft contract. */ public enum Cis2NftMethod { + /** + * The init method. + */ INIT, + /** + * The 'mint' method. Uses parameter {@link MintParams}. + */ MINT, + /** + * The 'transfer' method. Uses parameter {@link NftTransferParam}. + */ TRANSFER, + /** + * The 'updateOperator' method. Uses parameter {@link UpdateOperator}. + */ UPDATE_OPERATOR, + /** + * The 'operatorOf' of method. Uses parameter {@link OperatorOfQueryParams}. + */ OPERATOR_OF, + /** + * The 'balanceOf' method. Uses parameter {@link NftBalanceOfQueryParams}. + */ BALANCE_OF, + /** + * The 'tokenMetadata' method. Uses parameter {@link NftTokenMetaDataQueryParams}. + */ TOKEN_METADATA, + /** + * The 'supports' method. Uses parameter {@link SupportsQueryParams}. + */ SUPPORTS, + /** + * The 'setImplementors method. Uses parameter {@link SetImplementorsParams}. + */ SET_IMPLEMENTORS, } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index 0a2fb65ed..383cf1274 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -15,16 +15,20 @@ import java.util.List; /** - * Helper class for creating and initializing parameters being used in {@link Cis2Nft}. + * Helper class for creating and initializing parameters being used in {@link Cis2Nft} representing a cis2-nft contract. + * All values are dummy values and should be replaced to get valid results. */ public class Cis2NftParameters { private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); private static final ContractAddress CONTRACT_ADDRESS_2 = ContractAddress.from(2, 0); - private static final String CIS_2_NFT_CONTRACT_NAME = "cis2_nft"; + /** + * Generates and initializes {@link MintParams} for the 'mint' method of a cis2-nft contract. + * @return initialized {@link MintParams}. + */ @SneakyThrows public static SchemaParameter generateMintParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); @@ -38,6 +42,10 @@ public static SchemaParameter generateMintParams() { return mintParameter; } + /** + * Generates and initializes {@link NftTransferParam} for the 'transfer' method of a cis2-nft contract. + * @return initialized {@link NftTransferParam}. + */ @SneakyThrows public static SchemaParameter generateTransferParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); @@ -54,10 +62,13 @@ public static SchemaParameter generateTransferParams() { transfers.add(transfer); SchemaParameter transferParameter = new NftTransferParam(schema, nftTransferReceiveName, transfers); transferParameter.initialize(true); - return transferParameter; } + /** + * Generates and initializes {@link UpdateOperatorParams} for the 'updateOperator' method of a cis2-nft contract. + * @return initialized {@link UpdateOperatorParams}. + */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); @@ -69,11 +80,15 @@ public static SchemaParameter generateUpdateOperatorParams() { updateOperatorList.add(update2); SchemaParameter updateOperatorsParams = new UpdateOperatorParams(schema, updateOperatorReceiveName, updateOperatorList); updateOperatorsParams.initialize(true); - return updateOperatorsParams; } - public static SchemaParameter generateOperatorOfParams() throws IOException { + /** + * Generates and initializes {@link OperatorOfQueryParams} for the 'operatorOf' method of a cis2-nft contract. + * @return initialized {@link OperatorOfQueryParams}. + */ + @SneakyThrows + public static SchemaParameter generateOperatorOfParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); ReceiveName operatorOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); @@ -86,7 +101,12 @@ public static SchemaParameter generateOperatorOfParams() throws IOException { return operatorOfQueryParams; } - public static SchemaParameter generateBalanceOfParams() throws IOException { + /** + * Generates and initializes {@link NftBalanceOfQueryParams} for the 'balanceOf' method of a cis2-nft contract. + * @return initialized {@link NftBalanceOfQueryParams}. + */ + @SneakyThrows + public static SchemaParameter generateBalanceOfParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); ReceiveName balanceOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "balanceOf"); NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), ACCOUNT_ADDRESS); @@ -99,7 +119,12 @@ public static SchemaParameter generateBalanceOfParams() throws IOException { return contractBalanceOfQueryParams; } - public static SchemaParameter generateTokenMetadataParams() throws IOException { + /** + * Generates and initializes {@link NftTokenMetaDataQueryParams} for the 'tokenMetadata' method of a cis2-nft contract. + * @return initialized {@link NftTokenMetaDataQueryParams}. + */ + @SneakyThrows + public static SchemaParameter generateTokenMetadataParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "tokenMetadata"); TokenIdU32 token1 = TokenIdU32.from(21); @@ -107,12 +132,17 @@ public static SchemaParameter generateTokenMetadataParams() throws IOException { List tokensForMetadataQuery = new ArrayList<>(); tokensForMetadataQuery.add(token1); tokensForMetadataQuery.add(token2); - SchemaParameter nftMetaDataQuery = new NftMetaDataQuery(schema, tokenMetadataReceiveName, tokensForMetadataQuery); + SchemaParameter nftMetaDataQuery = new NftTokenMetaDataQueryParams(schema, tokenMetadataReceiveName, tokensForMetadataQuery); nftMetaDataQuery.initialize(true); return nftMetaDataQuery; } - public static SchemaParameter generateSupportsParameter() throws IOException { + /** + * Generates and initializes {@link SupportsQueryParams} for the 'supports' method of a cis2-nft contract. + * @return initialized {@link SupportsQueryParams}. + */ + @SneakyThrows + public static SchemaParameter generateSupportsParameter() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); ReceiveName supportsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; @@ -125,7 +155,12 @@ public static SchemaParameter generateSupportsParameter() throws IOException { return supportsQueryParams; } - public static SchemaParameter generateSetImplementorsParams() throws IOException { + /** + * Generates and initializes {@link SetImplementorsParams} for the 'setImplementors' method of a cis2-nft contract. + * @return initialized {@link SetImplementorsParams}. + */ + @SneakyThrows + public static SchemaParameter generateSetImplementorsParams() { Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java index cf6640f94..46f990123 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/BalanceOfQuery.java @@ -1,19 +1,29 @@ package com.concordium.sdk.examples.contractexample.parameters; -import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.*; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.AllArgsConstructor; import lombok.Getter; /** + * A query for the balance of a given address for a given token. * Represents a 'BalanceOfQuery' used in different smart contracts */ @Getter @AllArgsConstructor public class BalanceOfQuery { + /** + * The ID of the token for which to query the balance of. + * Field names must match field names in corresponding rust struct, therefore the annotation. + */ @JsonProperty("token_id") private T tokenId; + /** + * The address for which to query the balance of. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private AbstractAddress address; } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTokenMetaDataQueryParams.java similarity index 69% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTokenMetaDataQueryParams.java index fd2cb07ac..0f724a1c4 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftMetaDataQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTokenMetaDataQueryParams.java @@ -9,8 +9,8 @@ /** * Wrapper class for {@link ListParam} enforcing the correct Token id for cis2-nft contract. */ -public class NftMetaDataQuery extends ListParam { - public NftMetaDataQuery(Schema cis2nftSchema, ReceiveName tokenMetadataReceiveName, List tokensForMetadataQuery) { +public class NftTokenMetaDataQueryParams extends ListParam { + public NftTokenMetaDataQueryParams(Schema cis2nftSchema, ReceiveName tokenMetadataReceiveName, List tokensForMetadataQuery) { super(cis2nftSchema, tokenMetadataReceiveName, tokensForMetadataQuery); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java index d32e6969b..d16225ec3 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java @@ -1,19 +1,32 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.AllArgsConstructor; import lombok.Getter; /** + * A query for the operator of a given address for a given token. * Represents a 'OperatorOfQuery' used in different smart contracts */ @Getter @AllArgsConstructor public class OperatorOfQuery { + /** + * The ID of the token for which to query the balance of. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private AbstractAddress owner; + /** + * The address for which to check for being an operator of the owner. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private AbstractAddress address; } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java index 415cdd47d..2128a2b15 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java @@ -1,6 +1,7 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.transactions.AccountType; +import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; import com.fasterxml.jackson.core.JsonGenerator; @@ -12,15 +13,28 @@ import java.io.IOException; /** + * The receiving address for a {@link Transfer}, similar to the {@link AbstractAddress} type, but contains extra information when the receiver address is a {@link ContractAddress}. * Represents a 'Receiver' used in {@link Transfer}. */ @JsonSerialize(using = Receiver.ReceiverSerializer.class) @Getter public class Receiver { + /** + * The type of the account. + */ private final AccountType type; + /** + * The receiving address. Populated if and only if type is {@link AccountType#ADDRESS_ACCOUNT}. + */ private AccountAddress accountAddress; + /** + * The receiving address. Populated if and only if type is {@link AccountType#ADDRESS_CONTRACT}. + */ private ContractAddress contractAddress; + /** + * The function to call on the receiving contract. Populated if and only if type is {@link AccountType#ADDRESS_CONTRACT}. + */ private String ownedEntrypointName; public Receiver(AccountAddress accountAddress) { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java index 0204251f9..e4550d430 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java @@ -1,6 +1,8 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -11,17 +13,36 @@ /** + * A single transfer of some amount of a token. * Represents a 'Transfer' used in different smart contracts */ @Getter @AllArgsConstructor public class Transfer { + /** + * The ID of the token being transferred. + * Field names must match field names in corresponding rust struct, therefore the annotation. + */ @JsonProperty("token_id") private T tokenId; + /** + * The amount of tokens being transferred. + */ private A amount; + /** + * The address owning the tokens being transferred. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private AbstractAddress from; + /** + * The address receiving the tokens being transferred. A {@link Receiver} is either an {@link AccountAddress} or a {@link ContractAddress} alongside a function to call on the receiving contract. + */ private Receiver to; + /** + * Additional data to include in the transfer. Can be used for additional arguments + */ private List data; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java index cf890a0b5..963c9bb3f 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java @@ -1,10 +1,13 @@ package com.concordium.sdk.examples.contractexample.parameters; +import com.concordium.sdk.transactions.AccountType; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; @@ -16,11 +19,24 @@ */ @Getter public class UnwrapParams extends SchemaParameter { - + /** + * The amount of tokens to unwrap. + */ private final String amount; + /** + * The owner of the tokens. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private final AbstractAddress owner; + /** + * The address to receive these unwrapped CCD. A {@link Receiver} is either an {@link AccountAddress} or a {@link ContractAddress} alongside a function to call on the receiving contract. + */ private final Receiver receiver; + /** + * If the {@link Receiver} is a {@link AccountType#ADDRESS_CONTRACT} the unwrapped CCD together with these additional data bytes are sent to the function entrypoint specified in the {@link Receiver}. + */ private final List data; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java index 8b7f42a98..b61818146 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpdateOperator.java @@ -1,6 +1,8 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; +import com.concordium.sdk.types.AccountAddress; +import com.concordium.sdk.types.ContractAddress; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; @@ -19,6 +21,11 @@ public class UpdateOperator { private OperatorUpdate update; + /** + * The address which is either added or removed as an operator. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' + * to ensure correct serialization. + */ @JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class) private AbstractAddress operator; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java index 3f3bfe66d..fb5123300 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UpgradeParams.java @@ -1,51 +1,77 @@ package com.concordium.sdk.examples.contractexample.parameters; +import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.serializing.JsonMapper; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; +import lombok.ToString; import org.apache.commons.codec.binary.Hex; import java.io.IOException; +import java.util.Optional; /** + * The parameter type for the contract function `upgrade`. + * Takes the new module and optionally an entrypoint to call in the new module after triggering the upgrade. + * The upgrade is reverted if the entrypoint fails. + * This is useful for doing migration in the same transaction triggering the upgrade. * Represents the parameter 'UpgradeParams' used in the cis2-wCCD contract */ @Getter +@ToString public class UpgradeParams extends SchemaParameter { - private final String module; - + /** + * The new module reference. + */ + private final ModuleRef module; + /** + * Optional entrypoint to call in the new module after upgrade. + */ @JsonSerialize(using = MigrateSerializer.class) - private final SchemaParameter migrate; // Hex encode bytes , ReceiveName fås fra schemaparam, optional schema parameter + private final Optional migrate; - public UpgradeParams(Schema schema, ReceiveName receiveName, String module, SchemaParameter migrate) { + public UpgradeParams(Schema schema, ReceiveName receiveName, ModuleRef module, SchemaParameter migrate) { super(schema, receiveName); this.module = module; - migrate.initialize(true); - this.migrate = migrate; + if (migrate != null) { + migrate.initialize(true); + this.migrate = Optional.of(migrate); + } + else { + this.migrate = Optional.empty(); + } } - public static class MigrateSerializer extends JsonSerializer { + public static class MigrateSerializer extends JsonSerializer> { @Override - public void serialize(SchemaParameter migrate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + public void serialize(Optional migrate, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { jsonGenerator.writeStartObject(); - jsonGenerator.writeFieldName("Some"); + if (migrate.isPresent()) { + SchemaParameter param = migrate.get(); + jsonGenerator.writeFieldName("Some"); - jsonGenerator.writeStartArray(); + jsonGenerator.writeStartArray(); - jsonGenerator.writeStartArray(); - jsonGenerator.writeString(migrate.getReceiveName().getMethod()); - jsonGenerator.writeString(Hex.encodeHexString(migrate.toBytes())); - jsonGenerator.writeEndArray(); + jsonGenerator.writeStartArray(); + jsonGenerator.writeString(param.getReceiveName().getMethod()); + jsonGenerator.writeString(Hex.encodeHexString(param.toBytes())); + jsonGenerator.writeEndArray(); - jsonGenerator.writeEndArray(); + jsonGenerator.writeEndArray(); + } else { + jsonGenerator.writeFieldName("None"); + jsonGenerator.writeStartArray(); + jsonGenerator.writeEndArray(); + } jsonGenerator.writeEndObject(); - } } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTokenMetadataQueryParams.java similarity index 72% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTokenMetadataQueryParams.java index f6a8345c3..723eac2e2 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDMetadataQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTokenMetadataQueryParams.java @@ -9,8 +9,8 @@ /** * Wrapper class for {@link ListParam} enforcing the correct {@link TokenId} for cis2-wccd contract. */ -public class WCCDMetadataQuery extends ListParam { - public WCCDMetadataQuery(Schema schema, ReceiveName receiveName, List list) { +public class WCCDTokenMetadataQueryParams extends ListParam { + public WCCDTokenMetadataQueryParams(Schema schema, ReceiveName receiveName, List list) { super(schema, receiveName, list); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java index 80c019664..152c22926 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDMethod.java @@ -1,21 +1,67 @@ package com.concordium.sdk.examples.contractexample.wccd; +import com.concordium.sdk.examples.contractexample.parameters.*; +import com.concordium.sdk.transactions.smartcontracts.parameters.AddressParam; +import com.concordium.sdk.types.AbstractAddress; + /** - * Represents the different possible methods able to be run by {@link Cis2WCCD} + * Represents the different possible methods able to be run by {@link Cis2WCCD} representing a cis2-wCCD contract. */ public enum Cis2WCCDMethod { + /** + * The init method. + */ INIT, + /** + * The 'wrap' method. Uses parameter {@link WrapParams}. + */ WRAP, + /** + * The 'unwrap' method. Uses parameter {@link UnwrapParams}. + */ UNWRAP, + /** + * The 'updateAdmin' method. Uses parameter {@link AddressParam} to pass an {@link AbstractAddress} as a parameter. + */ UPDATE_ADMIN, + /** + * The 'setPaused' method. Uses parameter {@link SetPausedParams}. + */ SET_PAUSED, + /** + * The 'setMetadataUrl' method. Uses parameter {@link SetMetadataUrlParams}. + */ SET_METADATA_URL, + /** + * The 'transfer' method. Uses parameter {@link WCCDTransferParam}. + */ TRANSFER, + /** + * The 'updateOperator' method. Uses parameter {@link UpdateOperatorParams}. + */ UPDATE_OPERATOR, + /** + * The 'balanceOf' method. Uses parameter {@link WCCDBalanceOfQueryParams}. + */ BALANCE_OF, + /** + * The 'operatorOf' method. Uses parameter {@link OperatorOfQueryParams}. + */ OPERATOR_OF, + /** + * The 'tokenMetadata' method. Uses parameter {@link WCCDTokenMetadataQueryParams}. + */ TOKEN_METADATA, + /** + * The 'supports' method. Uses parameter {@link SupportsQueryParams}. + */ SUPPORTS, + /** + * The 'setImplementors' method. Uses parameter {@link SetImplementorsParams}. + */ SET_IMPLEMENTORS, + /** + * The 'upgrade' method. Uses parameter {@link UpgradeParams}. + */ UPGRADE } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 9218f84b3..18871cdb8 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -2,6 +2,7 @@ import com.concordium.sdk.examples.contractexample.parameters.*; import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.serializing.JsonMapper; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; @@ -22,7 +23,8 @@ import java.util.Optional; /** - * Helper class for creating and initializing parameters being used in {@link Cis2WCCD}. + * Helper class for creating and initializing parameters being used in {@link Cis2WCCD} representing a cis2-wCCD contract. + * All values are dummy values and should be replaced to get valid results. */ public class Cis2WCCDParameters { private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); @@ -168,7 +170,7 @@ public static SchemaParameter generateTokenMetadataParams() { TokenIdUnit token = new TokenIdUnit(); List tokensForMetadataQuery = new ArrayList<>(); tokensForMetadataQuery.add(token); - SchemaParameter wccdMetadataQuery = new WCCDMetadataQuery(cis2wccdSchema, tokenMetadataReceiveName, tokensForMetadataQuery); + SchemaParameter wccdMetadataQuery = new WCCDTokenMetadataQueryParams(cis2wccdSchema, tokenMetadataReceiveName, tokensForMetadataQuery); wccdMetadataQuery.initialize(true); return wccdMetadataQuery; } @@ -206,10 +208,19 @@ public static SchemaParameter generateUpgradeParams() { ReceiveName upgradeReceiveName = ReceiveName.from(CONTRACT_NAME, "upgrade"); ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); SchemaParameter migrate = generateWrapParams(); - SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef.toString(), migrate); + SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef, migrate); upgradeParams.initialize(true); return upgradeParams; } + @SneakyThrows + public static void main(String[] args) { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName upgradeReceiveName = ReceiveName.from("CONTRACT_NAME", "upgrade"); + ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); + SchemaParameter migrate = generateWrapParams(); + SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef, migrate); + upgradeParams.initialize(true); + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 71b721658..71e666371 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -1,6 +1,12 @@ package com.concordium.sdk.crypto; +import com.concordium.sdk.exceptions.JNIError; +import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.ReceiveName; +import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; +import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; import com.concordium.sdk.transactions.smartcontracts.SerializeParameterResult; +import lombok.SneakyThrows; public class CryptoJniNative { @@ -74,26 +80,34 @@ public class CryptoJniNative { public static native String generateConfigureBakerKeysPayload(String input); /** - * Serializes json representation of a parameter for a receive function using a schema of the module. - * @param parameterJson json representation of the parameter. - * @param contractName name of the contract. - * @param methodName name of the method. + * Serializes a parameter for a receive function using a schema of the module. + * @param parameter the parameter. + * @param receiveName the name of the contract and the method. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. * @param verboseErrors whether errors are returned in verbose format or not. - * @return JSON representing {@link SerializeParameterResult} + * @return JSON representing {@link SerializeParameterResult}. If the serialization was successful, the field 'serializedParameter' contains the serialized parameter as hex encoded bytes. + * If not successful, the 'err' field contains a {@link JNIError} detailing what went wrong. */ - public static native String serializeReceiveParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); + @SneakyThrows + public static String serializeReceiveParameter(SchemaParameter parameter, ReceiveName receiveName, byte[] schemaBytes, SchemaVersion schemaVersion, boolean verboseErrors) { + return serializeReceiveParameter(parameter.toJson(), receiveName.getContractName(), receiveName.getMethod(), schemaBytes, schemaVersion.getVersion(), verboseErrors); + } + private static native String serializeReceiveParameter(String parameterJson, String contractName, String methodName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); /** - * Serializes json representation of a parameter for an init function using a schema of the module. - * @param parameterJson json representation of the parameter. - * @param contractName name of the contract. + * Serializes a parameter for an init function using a schema of the module. + * @param parameter the parameter. + * @param initName name of the contract. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. * @param verboseErrors whether errors are returned in verbose format or not. - * @return JSON representing {@link SerializeParameterResult} + * @return JSON representing {@link SerializeParameterResult}. If the serialization was successful, the field 'serializedParameter' contains the serialized parameter as hex encoded bytes. + * If not successful, the 'err' field contains a {@link JNIError} detailing what went wrong. */ - public static native String serializeInitParameter(String parameterJson, String contractName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); + public static String serializeInitParameter(SchemaParameter parameter, InitName initName, byte[] schemaBytes, SchemaVersion schemaVersion, boolean verboseErrors) { + return serializeInitParameter(parameter.toJson(), initName.getName(), schemaBytes, schemaVersion.getVersion(), verboseErrors); + } + private static native String serializeInitParameter(String parameterJson, String contractName, byte[] schemaBytes, int schemaVersion, boolean verboseErrors); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java index d2a52381b..998c14886 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIError.java @@ -12,8 +12,13 @@ @Getter @ToString public class JNIError { - + /** + * The error message returned from the JNI. + */ private final String errorMessage; + /** + * The type of the error. + */ private final JNIErrorType errorType; @JsonCreator diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java index f8dc0337d..eddcc3433 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * Represents the different types of possible errors when performing operations using the JNI. + * Represents the different types of possible errors when performing operations using the JNI. Should match the errors defined in the rust code in crypto-jni. */ public enum JNIErrorType { @JsonProperty("ParameterSerializationError") diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index e7f07360b..50c47d670 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -62,23 +62,23 @@ public class InvokeInstanceRequest { /** * Creates a {@link InvokeInstanceRequest} from the given parameters. * - * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. - * @param invoker Invoker of the contract, must exist in the blockstate. - * If this is not supplied then the contract will be invoked by an account with address 0, - * no credentials and sufficient amount of CCD to cover the transfer amount. - * @param instance Address of the contract instance to invoke. - * @param amount Amount to invoke the smart contract instance with. + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param invoker Invoker of the contract, must exist in the blockstate. + * If this is not supplied then the contract will be invoked by an account with address 0, + * no credentials and sufficient amount of CCD to cover the transfer amount. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. - * @param parameter The parameter bytes to include in the invocation of the entrypoint. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param parameter The parameter bytes to include in the invocation of the entrypoint. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. */ public static InvokeInstanceRequest from(BlockQuery blockHash, - AbstractAddress invoker, - ContractAddress instance, - CCDAmount amount, - ReceiveName entrypoint, - Parameter parameter, - Energy energy) { + AbstractAddress invoker, + ContractAddress instance, + CCDAmount amount, + ReceiveName entrypoint, + Parameter parameter, + Energy energy) { return InvokeInstanceRequest.builder() .blockHash(blockHash) .invoker(invoker) @@ -88,16 +88,17 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, .parameter(parameter) .energy(energy).build(); } + /** * Creates a {@link InvokeInstanceRequest} from the given parameters. * The contract will be invoked by an account with address 0, no credentials and sufficient CCD to cover the transfer amount. * - * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. - * @param instance Address of the contract instance to invoke. - * @param amount Amount to invoke the smart contract instance with. + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. - * @param parameter The parameter bytes to include in the invocation of the entrypoint. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param parameter The parameter bytes to include in the invocation of the entrypoint. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, @@ -117,14 +118,14 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, /** * Creates a {@link InvokeInstanceRequest} from the given parameters. * - * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. - * @param invoker Invoker of the contract, must exist in the blockstate. - * If this is not supplied then the contract will be invoked by an account with address 0, - * no credentials and sufficient amount of CCD to cover the transfer amount. - * @param instance Address of the contract instance to invoke. - * @param amount Amount to invoke the smart contract instance with. + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param invoker Invoker of the contract, must exist in the blockstate. + * If this is not supplied then the contract will be invoked by an account with address 0, + * no credentials and sufficient amount of CCD to cover the transfer amount. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. */ public static InvokeInstanceRequest from(BlockQuery blockHash, AbstractAddress invoker, @@ -132,7 +133,9 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, CCDAmount amount, SchemaParameter schemaParameter, Energy energy) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName");} + if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { + throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName"); + } return from(blockHash, invoker, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } @@ -140,20 +143,23 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, * Creates a {@link InvokeInstanceRequest} from the given parameters. * The contract will be invoked by an account with address 0, no credentials and sufficient CCD to cover the transfer amount. * - * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. - * @param instance Address of the contract instance to invoke. - * @param amount Amount to invoke the smart contract instance with. + * @param blockHash Block to invoke the contract. The invocation will be at the end of the given block. + * @param instance Address of the contract instance to invoke. + * @param amount Amount to invoke the smart contract instance with. * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, CCDAmount amount, SchemaParameter schemaParameter, Energy energy) { - if (! (schemaParameter.getType() == ParameterType.RECEIVE)) {throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName");} + if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { + throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName"); + } return from(blockHash, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } + public boolean hasInvoker() { return !Objects.isNull(this.invoker); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Hash.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Hash.java index 9fe179ac3..ee8cc22bc 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Hash.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Hash.java @@ -4,7 +4,11 @@ import com.concordium.grpc.v2.TransactionHash; import com.concordium.sdk.serializing.JsonMapper; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.collect.ImmutableList; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -12,12 +16,14 @@ import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; +import java.io.IOException; import java.util.Optional; /** * A common hash (SHA256) used on the chain. */ @EqualsAndHashCode +@JsonSerialize(using = Hash.HashSerializer.class) public class Hash { @Getter private final byte[] bytes; @@ -69,4 +75,10 @@ public String toString() { return this.asHex(); } + public static class HashSerializer extends JsonSerializer { + @Override + public void serialize(Hash value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.asHex()); + } + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index ae9f35722..11cee4513 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -74,12 +74,15 @@ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, In /** * Create a new instance of {@link InitContractPayload} from the given parameters. - * @param amount CCD amount to deposit. - * @param moduleRef HAsh of the smart contract module reference. + * + * @param amount CCD amount to deposit. + * @param moduleRef HAsh of the smart contract module reference. * @param schemaParameter {@link SchemaParameter} message to invoke the initialization method with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. */ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaParameter schemaParameter) { - if (! (schemaParameter.getType() == ParameterType.INIT)) {throw new IllegalArgumentException("SchemaParameter for InitContractPayload must be initialized with an InitName");} + if (!(schemaParameter.getType() == ParameterType.INIT)) { + throw new IllegalArgumentException("SchemaParameter for InitContractPayload must be initialized with an InitName"); + } return new InitContractPayload(amount, moduleRef, schemaParameter.getInitName(), Parameter.from(schemaParameter)); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java index 9cb308520..85e3db23a 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/Parameter.java @@ -1,5 +1,6 @@ package com.concordium.sdk.transactions; +import com.concordium.sdk.responses.ProtocolVersion; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import com.concordium.sdk.types.UInt16; import com.fasterxml.jackson.annotation.JsonCreator; @@ -15,7 +16,8 @@ * The parameters are used for updating the smart contract instance. * i.e. calling a "receive" function exposed in the smart contract with the parameters. * Buffer of the parameters message. - * In the current supported protocols the size is limited to be 64kb. + * For protocol versions below {@link ProtocolVersion#V5} the size is limited to 1kb. + * From protocol version {@link ProtocolVersion#V5} and onwards the size is limited to be 64kb. */ @Getter diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java index 7c38d61e8..e87a50976 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java @@ -1,5 +1,6 @@ package com.concordium.sdk.transactions.smartcontracts; +import com.concordium.grpc.v2.UpdateContractPayload; import com.concordium.sdk.crypto.CryptoJniNative; import com.concordium.sdk.crypto.NativeResolver; import com.concordium.sdk.exceptions.CryptoJniException; @@ -48,18 +49,18 @@ public abstract class SchemaParameter { private final Schema schema; /** * {@link InitName} containing the name of the contract to be initialized with the parameter. - * Populated iff type is {@link ParameterType#INIT} + * Populated if and only if type is {@link ParameterType#INIT} */ @JsonIgnore private final InitName initName; /** * {@link ReceiveName} containing the name of the contract and method to be updated/invoked with the parameter. - * Populated iff type is {@link ParameterType#RECEIVE}. + * Populated if and only if type is {@link ParameterType#RECEIVE}. */ @JsonIgnore private final ReceiveName receiveName; /** - * Whether the parameter has been initialized. Parameter should always be initialized with {@link SchemaParameter#initialize()} before being used to create initialize/update/invoke requests. + * Whether the parameter has been initialized. Parameter should always be initialized with {@link SchemaParameter#initialize()} before being used to create initialize/update/invoke transactions/requests. */ @JsonIgnore private boolean initialized; @@ -138,7 +139,7 @@ public void initialize(boolean verboseErrors) { } /** - * Helper method for {@link SchemaParameter#initialize()}. Json serializes the parameter, performs the JNI call and deserializes the resulting json to {@link SerializeParameterResult}. + * Helper method for {@link SchemaParameter#initialize()}. Performs the JNI call and deserializes the resulting json to {@link SerializeParameterResult}. * * @param verboseErrors whether to return verbose errors. * @param schemaBytes byte[] containing the schema. @@ -148,8 +149,7 @@ public void initialize(boolean verboseErrors) { @SneakyThrows private SerializeParameterResult getSerializeParameterResult(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion) { SerializeParameterResult result; - String parameterJson = JsonMapper.INSTANCE.writeValueAsString(this); - String resultJson = serializeUsingJNI(verboseErrors, schemaBytes, schemaVersion, parameterJson); + String resultJson = serializeUsingJNI(verboseErrors, schemaBytes, schemaVersion); result = JsonMapper.INSTANCE.readValue(resultJson, SerializeParameterResult.class); return result; } @@ -160,18 +160,14 @@ private SerializeParameterResult getSerializeParameterResult(boolean verboseErro * @param verboseErrors whether to return verbose errors. * @param schemaBytes byte[] containing the schema. * @param schemaVersion version of the schema. - * @param parameterJson the parameter serialized as json. * @return json representing a {@link SerializeParameterResult}. */ - private String serializeUsingJNI(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion, String parameterJson) { + private String serializeUsingJNI(boolean verboseErrors, byte[] schemaBytes, SchemaVersion schemaVersion) { String resultJson; if (this.type == ParameterType.INIT) { - String contractName = initName.getName(); - resultJson = CryptoJniNative.serializeInitParameter(parameterJson, contractName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + resultJson = CryptoJniNative.serializeInitParameter(this, initName, schemaBytes, schemaVersion, verboseErrors); } else { - String contractName = receiveName.getContractName(); - String methodName = receiveName.getMethod(); - resultJson = CryptoJniNative.serializeReceiveParameter(parameterJson, contractName, methodName, schemaBytes, schemaVersion.getVersion(), verboseErrors); + resultJson = CryptoJniNative.serializeReceiveParameter(this, receiveName, schemaBytes, schemaVersion, verboseErrors); } return resultJson; } @@ -188,4 +184,13 @@ public byte[] toBytes() { } return serializedParameter; } + + /** + * Returns the JSON representation of the parameter. This is the excactly what is sent to the rust layer for serialization when {@link SchemaParameter#initialize()} is called. + * @return the JSON representation of the parameter. + */ + @SneakyThrows + public String toJson() { + return JsonMapper.INSTANCE.writeValueAsString(this); + } } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java index bda7b9463..5e395eadc 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java @@ -4,7 +4,8 @@ /** * The version of the {@link Schema}. - */ + * If this is updated, the corresponding code in the rust layer must also be updated accordingly to ensure correct deserialization. + */ @Getter public enum SchemaVersion { V0(0), diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java index 4e11334c0..a9d0be4a4 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/AccountAddressParam.java @@ -1,6 +1,7 @@ package com.concordium.sdk.transactions.smartcontracts.parameters; import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.Parameter; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -15,6 +16,8 @@ /** * Wrapper class allowing {@link AccountAddress} to be passed directly as a smart contract parameter. + * This is needed, as smart contract parameters must be either a {@link Parameter} or extend {@link SchemaParameter}. + * The custom serialization just serializes the {@link AccountAddress} contained within, i.e. the serialized version of this class is exactly equal to the serialized version of {@link AccountAddress}. */ @Getter @JsonSerialize(using = AccountAddressParam.AccountAddressParamSerializer.class) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java index 06e56614f..d1a025703 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ContractAddressParam.java @@ -1,6 +1,7 @@ package com.concordium.sdk.transactions.smartcontracts.parameters; import com.concordium.sdk.transactions.InitName; +import com.concordium.sdk.transactions.Parameter; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -15,6 +16,8 @@ /** * Wrapper class allowing {@link ContractAddress} to be passed directly as a smart contract parameter. + * This is needed, as smart contract parameters must be either a {@link Parameter} or extend {@link SchemaParameter}. + * The custom serialization just serializes the {@link ContractAddress} contained within, i.e. the serialized version of this class is exactly equal to the serialized version of {@link ContractAddress}. */ @Getter @JsonSerialize(using = ContractAddressParam.ContractAddressParamSerializer.class) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java index 55289d999..c423fa270 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/parameters/ListParam.java @@ -15,7 +15,7 @@ import java.util.List; /** - * Wrapper for passing lists as smart contract parameters.

+ * Wrapper for passing lists directly as smart contract parameters. * Classes extending {@link ListParam} are serializable as smart contract parameters. * Contents of the list must be serializable according to the provided {@link Schema}. */ diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java index 9c3dc2041..76746ebb8 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java @@ -5,6 +5,9 @@ import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; import lombok.Getter; +/** + * Parameters not matching the provided {@link Schema}. Used in {@link SerializeParameterTest} to ensure serialization of incorrect parameters throws an exception. + */ @Getter public class IncorrectParams extends SchemaParameter { diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs index 57a9dfb57..7cf78b524 100644 --- a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs +++ b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs @@ -1,16 +1,16 @@ #![cfg_attr(not(feature = "std"), no_std)] -//! # A Concordium V1 smart contract +//! # A Concordium V1 smart contract. This contract is only for genereating a schema to test serialization of `SchemaParameter` and is never meant to be excecuted, hence the dummy state/error/init. use concordium_std::*; use core::fmt::Debug; /// Your smart contract state. #[derive(Serialize, SchemaType)] pub struct State { - // Your state + // Dummy state. } -/// Your smart contract errors. +/// Dummy errors #[derive(Debug, PartialEq, Eq, Reject, Serial, SchemaType)] enum Error { /// Failed parsing the parameter. @@ -20,7 +20,7 @@ enum Error { YourError, } -/// Init function that creates a new smart contract. +/// Dummy init functions #[init(contract = "java_sdk_schema_unit_test")] fn init( _ctx: &impl HasInitContext, @@ -31,7 +31,7 @@ fn init( Ok(State {}) } -// + #[derive(Serialize, SchemaType)] #[concordium(transparent)] struct ListParam ( @@ -41,19 +41,16 @@ struct ListParam ( #[derive(Serialize, SchemaType)] struct AbstractAddressContainer { - /// The amount of tokens to unwrap. address: Address, } #[derive(Serialize, SchemaType)] struct AccountAddressContainer { - /// The amount of tokens to unwrap. address: AccountAddress, } #[derive(Serialize, SchemaType)] struct ContractAddressContainer { - /// The amount of tokens to unwrap. address: ContractAddress, } @@ -161,82 +158,3 @@ fn account_address_test( Ok(()) } -/// View function that returns the content of the state. -#[receive(contract = "java_sdk_schema_unit_test", name = "view", return_value = "State")] -fn view<'b, S: HasStateApi>( - _ctx: &impl HasReceiveContext, - host: &'b impl HasHost, -) -> ReceiveResult<&'b State> { - Ok(host.state()) -} - -#[concordium_cfg_test] -mod tests { - use super::*; - use test_infrastructure::*; - - type ContractResult = Result; - - #[concordium_test] - /// Test that initializing the contract succeeds with some state. - fn test_init() { - let ctx = TestInitContext::empty(); - - let mut state_builder = TestStateBuilder::new(); - - let state_result = init(&ctx, &mut state_builder); - state_result.expect_report("Contract initialization results in error"); - } - - #[concordium_test] - /// Test that invoking the `receive` endpoint with the `false` parameter - /// succeeds in updating the contract. - fn test_throw_no_error() { - let ctx = TestInitContext::empty(); - - let mut state_builder = TestStateBuilder::new(); - - // Initializing state - let initial_state = init(&ctx, &mut state_builder).expect("Initialization should pass"); - - let mut ctx = TestReceiveContext::empty(); - - let throw_error = false; - let parameter_bytes = to_bytes(&throw_error); - ctx.set_parameter(¶meter_bytes); - - let mut host = TestHost::new(initial_state, state_builder); - - // Call the contract function. - let result: ContractResult<()> = receive(&ctx, &mut host); - - // Check the result. - claim!(result.is_ok(), "Results in rejection"); - } - - #[concordium_test] - /// Test that invoking the `receive` endpoint with the `true` parameter - /// results in the `YourError` being thrown. - fn test_throw_error() { - let ctx = TestInitContext::empty(); - - let mut state_builder = TestStateBuilder::new(); - - // Initializing state - let initial_state = init(&ctx, &mut state_builder).expect("Initialization should pass"); - - let mut ctx = TestReceiveContext::empty(); - - let throw_error = true; - let parameter_bytes = to_bytes(&throw_error); - ctx.set_parameter(¶meter_bytes); - - let mut host = TestHost::new(initial_state, state_builder); - - // Call the contract function. - let error: ContractResult<()> = receive(&ctx, &mut host); - - // Check the result. - claim_eq!(error, Err(Error::YourError), "Function should throw an error."); - } -} diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin b/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin index c3ffaf3bd5085d5ecf188cc82aa52c751a4af2fb..4ffdf86eb8c902c30841cb6245d28121e5f347f6 100644 GIT binary patch delta 14 VcmZo+{mL>ym63g;njaG*0{|d-184vM delta 29 hcmey$(!x4Hm62nknjez@3j+f~S!QZEqX>`z1ORA;1xx?{ diff --git a/crypto-jni/Cargo.lock b/crypto-jni/Cargo.lock index d4a0e8d38..f2b10c7da 100644 --- a/crypto-jni/Cargo.lock +++ b/crypto-jni/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common" -version = "7.0.0" +version = "8.1.0" dependencies = [ "base64", "bs58", @@ -239,7 +239,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common-derive" -version = "3.0.0" +version = "4.0.1" dependencies = [ "proc-macro2", "quote", @@ -248,7 +248,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "2.0.0" +version = "3.1.1" dependencies = [ "anyhow", "bs58", From d1755c5846ff35487dfb10cee9ebe3b696723a1c Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 10 Nov 2023 15:34:50 +0100 Subject: [PATCH 31/53] addressed review comments in crypto-native --- crypto-jni/src/lib.rs | 51 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 4094fa563..884948562 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -182,12 +182,12 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generatePu #[derive(SerdeSerialize, SerdeDeserialize)] enum CryptoJniResult { Ok(T), - Err(JNIError), + Err(JNIErrorResponse), } #[derive(SerdeSerialize, SerdeDeserialize)] #[allow(non_snake_case)] -enum JNIErrorType { +enum JNIErrorResponseType { ParameterSerializationError, Utf8DecodeError, JsonDeserializationError, @@ -198,16 +198,16 @@ enum JNIErrorType { #[derive(SerdeSerialize, SerdeDeserialize)] #[allow(non_snake_case)] -struct JNIError { - errorType: JNIErrorType, +struct JNIErrorResponse { + errorType: JNIErrorResponseType, errorMessage: String, } impl From for CryptoJniResult { fn from(e: serde_json::Error) -> Self { - let error = JNIError { - errorType: JNIErrorType::JsonDeserializationError, + let error = JNIErrorResponse { + errorType: JNIErrorResponseType::JsonDeserializationError, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -216,8 +216,8 @@ impl From for CryptoJniResult { impl From for CryptoJniResult { fn from(e: Utf8Error) -> Self { - let error = JNIError { - errorType: JNIErrorType::Utf8DecodeError, + let error = JNIErrorResponse { + errorType: JNIErrorResponseType::Utf8DecodeError, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -226,8 +226,8 @@ impl From for CryptoJniResult { impl From for CryptoJniResult { fn from(e: jni::errors::Error) -> Self { - let error = JNIError { - errorType: JNIErrorType::NativeConversionError, + let error = JNIErrorResponse { + errorType: JNIErrorResponseType::NativeConversionError, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -240,8 +240,8 @@ impl From for CryptoJniResult { */ impl From<&str> for CryptoJniResult { fn from(e: &str) -> Self { - let error = JNIError { - errorType: JNIErrorType::PayloadCreationError, + let error = JNIErrorResponse { + errorType: JNIErrorResponseType::PayloadCreationError, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -250,8 +250,8 @@ impl From<&str> for CryptoJniResult { impl From for CryptoJniResult { fn from(e: anyhow::Error) -> Self { - let error = JNIError { - errorType: JNIErrorType::ParameterSerializationError, + let error = JNIErrorResponse { + errorType: JNIErrorResponseType::ParameterSerializationError, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -472,9 +472,17 @@ type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] +/// The JNI wrapper for serializing receive parameters. /** - * The JNI wrapper for serializing receive parameters. - * Constructs a SerializeParamResult containg the hex encoded serialized parameter. + * The `parameter` parameter must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. + * The `contractName` parameter must be a properly initalized `java.lang.String` that is non-null. + * The `methodName` parameter must be a properly initalized `java.lang.String` that is non-null. + * The `schemaBytes` parameter must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName` and `methodName`. + * The `schemaVersion` must be a integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + */ +/// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. +/** + * Returns a SerializeParamResult containg the hex encoded serialized parameter. */ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeReceiveParameter( env: JNIEnv, @@ -573,9 +581,16 @@ pub fn serialize_receive_contract_parameters_aux( return Ok(res?); } +/// The JNI wrapper for serializing init parameters. +/** + * The `parameter` parameter must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. + * The `contractName` parameter must be a properly initalized `java.lang.String` that is non-null. + * The `schemaBytes` parameter must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. + * The `schemaVersion` must be a integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + */ +/// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. /** - * The JNI wrapper for serializing init parameters. - * Constructs a SerializeParamResult containg the hex encoded serialized parameter. + * Returns a SerializeParamResult containg the hex encoded serialized parameter. */ #[no_mangle] #[allow(non_snake_case)] From c686ce695d9f236f665cf3e3b1b78feeed2dc88f Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 15 Nov 2023 10:30:26 +0100 Subject: [PATCH 32/53] Addressed review comments --- .../contractexample/wccd/Cis2WCCDParameters.java | 10 ---------- .../src/main/java/com/concordium/sdk/types/UInt8.java | 3 +++ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 18871cdb8..00a971f49 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -213,14 +213,4 @@ public static SchemaParameter generateUpgradeParams() { return upgradeParams; } - @SneakyThrows - public static void main(String[] args) { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - ReceiveName upgradeReceiveName = ReceiveName.from("CONTRACT_NAME", "upgrade"); - ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); - SchemaParameter migrate = generateWrapParams(); - SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef, migrate); - upgradeParams.initialize(true); - } - } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java index 6ca5a4807..3763ff056 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -10,6 +10,9 @@ import java.io.IOException; +/** + * An unsigned byte + */ @EqualsAndHashCode @Getter @JsonSerialize(using = UInt8.UInt8Serializer.class) From 4ac234cc28eba0cc4803674830db78ca72345c31 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 15 Nov 2023 14:42:46 +0100 Subject: [PATCH 33/53] Addressed review comments --- CHANGELOG.md | 1 + .../contractexample/cis2nft/Cis2Nft.java | 24 ++++------------ .../{Transfer.java => Cis2Transfer.java} | 2 +- .../parameters/NftTransfer.java | 4 +-- .../parameters/NftTransferParam.java | 2 +- .../contractexample/parameters/Receiver.java | 4 +-- .../parameters/WCCDTransfer.java | 4 +-- .../parameters/WCCDTransferParam.java | 2 +- .../contractexample/wccd/Cis2WCCD.java | 24 ++++------------ .../java/com/concordium/sdk/ClientV2.java | 28 +++++++++++++++++++ .../smartcontracts/InvokeInstanceRequest.java | 4 +-- .../sdk/transactions/UpdateContract.java | 4 +-- 12 files changed, 54 insertions(+), 49 deletions(-) rename concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/{Transfer.java => Cis2Transfer.java} (96%) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8d09fe92..885165384 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased changes +- Added method `waitUntilFinalized` for waiting until a given transaction is finalized. - Added support for GRPC V2 `GetBakerRewardPeriodInfo` for getting all the bakers in the reward period of a block. Only available when querying a node with version at least 6.1. - Added support for GRPC V2 `GetBlockCertificates` for retrieving certificates for a block supporting ConcordiumBF, i.e. a node with at least version 6.1. - Extended `CurrentPaydayStatus` with `CommissionRates` that apply for the current reward period. Requires at least node version 6.1. diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index 5faa58c41..5c81a0f4c 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -6,6 +6,7 @@ import com.concordium.sdk.exceptions.ClientInitializationException; import com.concordium.sdk.requests.AccountQuery; import com.concordium.sdk.requests.BlockQuery; +import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.*; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -13,7 +14,6 @@ import com.concordium.sdk.types.ContractAddress; import com.concordium.sdk.types.Nonce; import com.concordium.sdk.types.UInt64; -import lombok.SneakyThrows; import lombok.var; import picocli.CommandLine; @@ -36,7 +36,7 @@ public class Cis2Nft implements Callable { private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); private static final TransactionSigner SIGNER = TransactionSigner.from( - SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key + SignerEntry.from(Index.from(0), Index.from(0), ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key ); @@ -123,9 +123,8 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - sleep(); - Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - System.out.println("Transaction finalized in block with hash: " + blockHash); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -140,21 +139,10 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - sleep(); - Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - System.out.println("Transaction finalized in block with hash: " + blockHash); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } - @SneakyThrows - private void sleep() { - for (int i = 0; i < 200; i++) { - System.out.print("."); - if (i % 50 == 0) { - System.out.println("\n"); - } - Thread.sleep(30); - } - } public static void main(String[] args) { int exitCode = new CommandLine(new Cis2Nft()).execute(args); System.exit(exitCode); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java similarity index 96% rename from concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java rename to concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java index e4550d430..001bb127d 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Transfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java @@ -18,7 +18,7 @@ */ @Getter @AllArgsConstructor -public class Transfer { +public class Cis2Transfer { /** * The ID of the token being transferred. * Field names must match field names in corresponding rust struct, therefore the annotation. diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java index 0349fd97e..f1cee3fb4 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java @@ -6,9 +6,9 @@ import java.util.List; /** - * Wrapper class for {@link Transfer} enforcing the correct Token amount/id for cis2-nft contract. + * Wrapper class for {@link Cis2Transfer} enforcing the correct Token amount/id for cis2-nft contract. */ -public class NftTransfer extends Transfer { +public class NftTransfer extends Cis2Transfer { public NftTransfer(TokenIdU32 tokenId, TokenAmountU8 amount, AbstractAddress from, Receiver to, List data) { super(tokenId, amount, from, to, data); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java index 91356e821..ef3e9c15f 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransferParam.java @@ -7,7 +7,7 @@ import java.util.List; /** - * Wrapper class for {@link ListParam} enforcing the correct {@link Transfer} id for cis2-nft contract. + * Wrapper class for {@link ListParam} enforcing the correct {@link Cis2Transfer} id for cis2-nft contract. */ public class NftTransferParam extends ListParam { public NftTransferParam(Schema cis2nftSchema, ReceiveName nftTransferReceiveName, List transfers) { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java index 2128a2b15..74ca17dfb 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Receiver.java @@ -13,8 +13,8 @@ import java.io.IOException; /** - * The receiving address for a {@link Transfer}, similar to the {@link AbstractAddress} type, but contains extra information when the receiver address is a {@link ContractAddress}. - * Represents a 'Receiver' used in {@link Transfer}. + * The receiving address for a {@link Cis2Transfer}, similar to the {@link AbstractAddress} type, but contains extra information when the receiver address is a {@link ContractAddress}. + * Represents a 'Receiver' used in {@link Cis2Transfer}. */ @JsonSerialize(using = Receiver.ReceiverSerializer.class) @Getter diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java index f5bef9d1a..360821edb 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java @@ -6,9 +6,9 @@ import java.util.List; /** - * Wrapper class for {@link Transfer} enforcing the correct Token amount/id for cis2-wCCD contract. + * Wrapper class for {@link Cis2Transfer} enforcing the correct Token amount/id for cis2-wCCD contract. */ -public class WCCDTransfer extends Transfer { +public class WCCDTransfer extends Cis2Transfer { public WCCDTransfer(TokenIdUnit tokenId, TokenAmountU64 amount, AbstractAddress from, Receiver to, List data) { super(tokenId, amount, from, to, data); } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java index d2d79c1c6..f8a04129d 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransferParam.java @@ -7,7 +7,7 @@ import java.util.List; /** - * Wrapper class for {@link ListParam} enforcing the correct {@link Transfer} id for cis2-wccd contract. + * Wrapper class for {@link ListParam} enforcing the correct {@link Cis2Transfer} id for cis2-wccd contract. */ public class WCCDTransferParam extends ListParam { public WCCDTransferParam(Schema schema, ReceiveName receiveName, List transfers) { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index 11750a089..2150e105b 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -5,6 +5,7 @@ import com.concordium.sdk.crypto.ed25519.ED25519SecretKey; import com.concordium.sdk.requests.AccountQuery; import com.concordium.sdk.requests.BlockQuery; +import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem; import com.concordium.sdk.responses.modulelist.ModuleRef; import com.concordium.sdk.transactions.*; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; @@ -12,7 +13,6 @@ import com.concordium.sdk.types.ContractAddress; import com.concordium.sdk.types.Nonce; import com.concordium.sdk.types.UInt64; -import lombok.SneakyThrows; import lombok.var; import picocli.CommandLine; @@ -33,7 +33,7 @@ public class Cis2WCCD implements Callable { private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); private static final TransactionSigner SIGNER = TransactionSigner.from( - SignerEntry.from(Index.from(0), Index.from(0), // TODO dummy key + SignerEntry.from(Index.from(0), Index.from(0), ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key ); @@ -138,9 +138,8 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - sleep(); - Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - System.out.println("Transaction finalized in block with hash: " + blockHash); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -155,21 +154,10 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - sleep(); - Hash blockHash = client.getBlockItemStatus(txHash).getFinalizedBlockItem().get().getBlockHash(); - System.out.println("Transaction finalized in block with hash: " + blockHash); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } - @SneakyThrows - private void sleep() { - for (int i = 0; i < 200; i++) { - System.out.print("."); - if (i % 50 == 0) { - System.out.println("\n"); - } - Thread.sleep(30); - } - } public static void main(String[] args) { int exitCode = new CommandLine(new Cis2WCCD()).execute(args); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index 973a8f42c..e01e9e68d 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -16,6 +16,7 @@ import com.concordium.sdk.responses.blockcertificates.BlockCertificates; import com.concordium.sdk.responses.blockinfo.BlockInfo; import com.concordium.sdk.responses.blockitemstatus.BlockItemStatus; +import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem; import com.concordium.sdk.responses.blockitemsummary.Summary; import com.concordium.sdk.responses.blocksummary.FinalizationData; import com.concordium.sdk.responses.blocksummary.specialoutcomes.SpecialOutcome; @@ -32,6 +33,7 @@ import com.concordium.sdk.responses.poolstatus.BakerPoolStatus; import com.concordium.sdk.responses.rewardstatus.RewardsOverview; import com.concordium.sdk.responses.smartcontracts.InvokeInstanceResult; +import com.concordium.sdk.responses.transactionstatus.Status; import com.concordium.sdk.transactions.AccountTransaction; import com.concordium.sdk.transactions.BlockItem; import com.concordium.sdk.transactions.*; @@ -808,6 +810,32 @@ public BlockCertificates getBlockCertificates(BlockQuery block) { return BlockCertificates.from(res); } + /** + * Waits until a given transaction is finalized and returns the corresponding {@link FinalizedBlockItem}. + * @param transactionHash the {@link Hash} of the transaction to wait for. + * @param timeoutMillis the number of milliseconds to wait before throwing an exception. + * @return {@link FinalizedBlockItem} of the transaction. + * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:

    + *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the timeout is exceeded. + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node. + *
+ */ + public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMillis) { + BlockItemStatus status = this.getBlockItemStatus(transactionHash); + if (status.getStatus() == Status.FINALIZED) { + return status.getFinalizedBlockItem().get(); + } + Iterator finalizedBlockStream = this.getFinalizedBlocks(timeoutMillis); + while (finalizedBlockStream.hasNext()) { + finalizedBlockStream.next(); // We check if the transaction is finalized every time a new block is finalized. + BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); + if (newStatus.getStatus() == Status.FINALIZED) { + return newStatus.getFinalizedBlockItem().get(); + } + } + throw new IllegalStateException("No more finalized blocks"); // This should never happen as finalized blocks keep being streamed. + } + /** * Get a {@link QueriesGrpc.QueriesBlockingStub} with a timeout * The timeout is the one specified in via the {@link Connection} object used to diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 50c47d670..371ac2982 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -134,7 +134,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, SchemaParameter schemaParameter, Energy energy) { if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { - throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName"); + throw new IllegalArgumentException("Cannot initialize smart contract with InvokeInstance. SchemaParameter for InvokeInstanceRequest must be initialized with a ReceiveName"); } return from(blockHash, invoker, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } @@ -155,7 +155,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, SchemaParameter schemaParameter, Energy energy) { if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { - throw new IllegalArgumentException("SchemaParameter for InvokeInstanceRequest must be initialized with an ReceiveName"); + throw new IllegalArgumentException("Cannot initialize smart contract with InvokeInstance. SchemaParameter for InvokeInstanceRequest must be initialized with a ReceiveName"); } return from(blockHash, instance, amount, schemaParameter.getReceiveName(), Parameter.from(schemaParameter), energy); } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java index 5a211b92d..9cd6783e7 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/UpdateContract.java @@ -88,7 +88,7 @@ public static UpdateContract from(@NonNull final CCDAmount amount, public static UpdateContract from(@NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { - throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName"); + throw new IllegalArgumentException("Cannot initialize smart contract with UpdateContractTransaction. SchemaParameter for UpdateContract must be initialized with a ReceiveName"); } return from(CCDAmount.fromMicro(0), contractAddress, @@ -107,7 +107,7 @@ public static UpdateContract from(CCDAmount amount, @NonNull final ContractAddress contractAddress, SchemaParameter schemaParameter) { if (!(schemaParameter.getType() == ParameterType.RECEIVE)) { - throw new IllegalArgumentException("SchemaParameter for UpdateContractPayload must be initialized with a ReceiveName"); + throw new IllegalArgumentException("Cannot initialize smart contract with UpdateContractTransaction. SchemaParameter for UpdateContract must be initialized with a ReceiveName"); } return from(amount, contractAddress, schemaParameter.getReceiveName(), Parameter.from(schemaParameter)); } From c3f71a2d25c5e979a2c159045cb888a71dfc4271 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 15 Nov 2023 15:44:23 +0100 Subject: [PATCH 34/53] Missing documentation --- .../contractexample/cis2nft/Cis2Nft.java | 25 +++--- .../cis2nft/Cis2NftParameters.java | 29 ++++--- .../contractexample/wccd/Cis2WCCD.java | 23 +++--- .../wccd/Cis2WCCDParameters.java | 80 +++++++++++++++---- .../java/com/concordium/sdk/ClientV2.java | 3 +- 5 files changed, 106 insertions(+), 54 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index 5c81a0f4c..d942e0e96 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -28,18 +28,6 @@ */ @CommandLine.Command(name = "Cis2Nft", mixinStandardHelpOptions = true) public class Cis2Nft implements Callable { - - private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address - private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref - private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address - - private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); - - private static final TransactionSigner SIGNER = TransactionSigner.from( - SignerEntry.from(Index.from(0), Index.from(0), - ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key - ); - @CommandLine.Option( names = {"-m", "--method"}, required = true, @@ -57,7 +45,14 @@ public class Cis2Nft implements Callable { description = "GRPC request timeout in milliseconds.", defaultValue = "100000") private int timeout; - + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address + private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref + private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address + private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); + private static final TransactionSigner SIGNER = TransactionSigner.from( + SignerEntry.from(Index.from(0), Index.from(0), + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key + ); @Override public Integer call() throws IOException, ClientInitializationException { @@ -122,7 +117,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { .maxEnergyCost(UInt64.from(10000)) .build(); Hash txHash = client.sendTransaction(initContractTransaction); - System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } @@ -138,7 +133,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .maxEnergyCost(UInt64.from(10000)) .build(); Hash txHash = client.sendTransaction(transaction); - System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index 383cf1274..d10cb2bc7 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -8,7 +8,6 @@ import com.concordium.sdk.types.*; import lombok.SneakyThrows; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -19,19 +18,20 @@ * All values are dummy values and should be replaced to get valid results. */ public class Cis2NftParameters { - private static final AccountAddress ACCOUNT_ADDRESS = AccountAddress.from("3XSLuJcXg6xEua6iBPnWacc3iWh93yEDMCqX8FbE3RDSbEnT9P"); - private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); + private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); private static final ContractAddress CONTRACT_ADDRESS_2 = ContractAddress.from(2, 0); private static final String CIS_2_NFT_CONTRACT_NAME = "cis2_nft"; + private static final String SCHEMA_PATH = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin"; /** * Generates and initializes {@link MintParams} for the 'mint' method of a cis2-nft contract. + * * @return initialized {@link MintParams}. */ @SneakyThrows public static SchemaParameter generateMintParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName mintParamsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "mint"); List tokens = new ArrayList<>(); tokens.add(TokenIdU32.from(2)); @@ -44,11 +44,12 @@ public static SchemaParameter generateMintParams() { /** * Generates and initializes {@link NftTransferParam} for the 'transfer' method of a cis2-nft contract. + * * @return initialized {@link NftTransferParam}. */ @SneakyThrows public static SchemaParameter generateTransferParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName nftTransferReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "transfer"); TokenIdU32 tokenId = TokenIdU32.from(12); TokenAmountU8 amount = TokenAmountU8.from(1); @@ -67,11 +68,12 @@ public static SchemaParameter generateTransferParams() { /** * Generates and initializes {@link UpdateOperatorParams} for the 'updateOperator' method of a cis2-nft contract. + * * @return initialized {@link UpdateOperatorParams}. */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName updateOperatorReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "updateOperator"); UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); @@ -85,11 +87,12 @@ public static SchemaParameter generateUpdateOperatorParams() { /** * Generates and initializes {@link OperatorOfQueryParams} for the 'operatorOf' method of a cis2-nft contract. + * * @return initialized {@link OperatorOfQueryParams}. */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName operatorOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); @@ -103,11 +106,12 @@ public static SchemaParameter generateOperatorOfParams() { /** * Generates and initializes {@link NftBalanceOfQueryParams} for the 'balanceOf' method of a cis2-nft contract. + * * @return initialized {@link NftBalanceOfQueryParams}. */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName balanceOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "balanceOf"); NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), ACCOUNT_ADDRESS); NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), CONTRACT_ADDRESS_1); @@ -121,11 +125,12 @@ public static SchemaParameter generateBalanceOfParams() { /** * Generates and initializes {@link NftTokenMetaDataQueryParams} for the 'tokenMetadata' method of a cis2-nft contract. + * * @return initialized {@link NftTokenMetaDataQueryParams}. */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "tokenMetadata"); TokenIdU32 token1 = TokenIdU32.from(21); TokenIdU32 token2 = TokenIdU32.from(22); @@ -139,11 +144,12 @@ public static SchemaParameter generateTokenMetadataParams() { /** * Generates and initializes {@link SupportsQueryParams} for the 'supports' method of a cis2-nft contract. + * * @return initialized {@link SupportsQueryParams}. */ @SneakyThrows public static SchemaParameter generateSupportsParameter() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName supportsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; String standardIdentifier2 = "identifier2"; @@ -157,11 +163,12 @@ public static SchemaParameter generateSupportsParameter() { /** * Generates and initializes {@link SetImplementorsParams} for the 'setImplementors' method of a cis2-nft contract. + * * @return initialized {@link SetImplementorsParams}. */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin")), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); String identifier = "IdentifierID"; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index 2150e105b..764ab43f0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -26,17 +26,6 @@ */ @CommandLine.Command(name = "Cis2WCCD", mixinStandardHelpOptions = true) public class Cis2WCCD implements Callable { - private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address - private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref - private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address - - private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); - - private static final TransactionSigner SIGNER = TransactionSigner.from( - SignerEntry.from(Index.from(0), Index.from(0), - ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key - ); - @CommandLine.Option( names = {"-m", "--method"}, required = true, @@ -54,6 +43,14 @@ public class Cis2WCCD implements Callable { description = "GRPC request timeout in milliseconds.", defaultValue = "100000") private int timeout; + private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address + private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref + private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address + private static final Expiry EXPIRY = Expiry.createNew().addMinutes(5); + private static final TransactionSigner SIGNER = TransactionSigner.from( + SignerEntry.from(Index.from(0), Index.from(0), + ED25519SecretKey.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")) // Dummy key + ); @Override public Integer call() throws Exception { @@ -137,7 +134,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { .maxEnergyCost(UInt64.from(10000)) .build(); Hash txHash = client.sendTransaction(initContractTransaction); - System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } @@ -153,7 +150,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .maxEnergyCost(UInt64.from(10000)) .build(); Hash txHash = client.sendTransaction(transaction); - System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); + System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 00a971f49..6a0c21883 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -2,7 +2,6 @@ import com.concordium.sdk.examples.contractexample.parameters.*; import com.concordium.sdk.responses.modulelist.ModuleRef; -import com.concordium.sdk.serializing.JsonMapper; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; @@ -31,14 +30,16 @@ public class Cis2WCCDParameters { private static final ContractAddress CONTRACT_ADDRESS_1 = ContractAddress.from(1, 0); private static final ContractAddress CONTRACT_ADDRESS_2 = ContractAddress.from(2, 0); private static final String CONTRACT_NAME = "cis2_wCCD"; - private static final Path SCHEMA_PATH = Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin"); + + /** + * Generates and initializes {@link WrapParams} for the 'wrap' method of a cis2-wCCD contract. + * + * @return initialized {@link WrapParams}. + */ @SneakyThrows public static SchemaParameter generateWrapParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - - // Initialize WrapParams - ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); List wrapData = new ArrayList<>(); @@ -49,11 +50,14 @@ public static SchemaParameter generateWrapParams() { return wrapParams; } + /** + * Generates and initializes {@link UnwrapParams} for the 'unwrap' method of a cis2-wCCD contract. + * + * @return initialized {@link UnwrapParams}. + */ @SneakyThrows public static SchemaParameter generateUnwrapParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - // Initialize UnwrapParams - ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); String unwrapAmount = "2"; // TokenAmountU64 Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); @@ -65,33 +69,42 @@ public static SchemaParameter generateUnwrapParams() { return unwrapParams; } + /** + * Generates and initializes {@link AddressParam} for the 'updateAdmin' method of a cis2-wCCD contract. + * + * @return initialized {@link AddressParam}. + */ @SneakyThrows public static SchemaParameter generateUpdateAdminParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - - // Initialize Address as UpdateAdminParam ReceiveName updateAdmninReceiveName = ReceiveName.from(CONTRACT_NAME, "updateAdmin"); AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, CONTRACT_ADDRESS_1); updateAdminParam.initialize(true); return updateAdminParam; } + /** + * Generates and initializes {@link SetPausedParams} for the 'setPaused' method of a cis2-wCCD contract. + * + * @return initialized {@link SetPausedParams}. + */ @SneakyThrows public static SchemaParameter generateSetPausedParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - - // Initialize SetPausedParams ReceiveName setPausedReceiveName = ReceiveName.from(CONTRACT_NAME, "setPaused"); SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); setPausedParams.initialize(true); return setPausedParams; } + /** + * Generates and initializes {@link SetMetadataUrlParams} for the 'setMetadataUrl' method of a cis2-wCCD contract. + * + * @return initialized {@link SetMetadataUrlParams}. + */ @SneakyThrows public static SchemaParameter generateSetMetadataUrlParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - - // Initialize SetMetadataUrlParams ReceiveName setMetadataUrlReceiveName = ReceiveName.from(CONTRACT_NAME, "setMetadataUrl"); String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); @@ -100,6 +113,11 @@ public static SchemaParameter generateSetMetadataUrlParams() { return setMetadataUrlParams; } + /** + * Generates and initializes {@link WCCDTransferParam} for the 'transfer' method of a cis2-wCCD contract. + * + * @return initialized {@link WCCDTransferParam}. + */ @SneakyThrows public static SchemaParameter generateTransferParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -116,10 +134,14 @@ public static SchemaParameter generateTransferParams() { transfers.add(transfer); SchemaParameter transferParameter = new WCCDTransferParam(cis2wccdSchema, nftTransferReceiveName, transfers); transferParameter.initialize(true); - return transferParameter; } + /** + * Generates and initializes {@link UpdateOperatorParams} for the 'updateOperator' method of a cis2-wCCD contract. + * + * @return initialized {@link UpdateOperatorParams}. + */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -135,6 +157,11 @@ public static SchemaParameter generateUpdateOperatorParams() { return updateOperatorsParams; } + /** + * Generates and initializes {@link WCCDBalanceOfQueryParams} for the 'balanceOf' method of a cis2-wCCD contract. + * + * @return initialized {@link WCCDBalanceOfQueryParams}. + */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -149,6 +176,11 @@ public static SchemaParameter generateBalanceOfParams() { return contractBalanceOfQueryParams; } + /** + * Generates and initializes {@link OperatorOfQueryParams} for the 'operatorOf' method of a cis2-wCCD contract. + * + * @return initialized {@link OperatorOfQueryParams}. + */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -163,6 +195,11 @@ public static SchemaParameter generateOperatorOfParams() { return operatorOfQueryParams; } + /** + * Generates and initializes {@link WCCDTokenMetadataQueryParams} for the 'tokenMetadata' method of a cis2-wCCD contract. + * + * @return initialized {@link WCCDTokenMetadataQueryParams}. + */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -175,6 +212,11 @@ public static SchemaParameter generateTokenMetadataParams() { return wccdMetadataQuery; } + /** + * Generates and initializes {@link SupportsQueryParams} for the 'supports' method of a cis2-wCCD contract. + * + * @return initialized {@link SupportsQueryParams}. + */ @SneakyThrows public static SchemaParameter generateSupportsParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -189,6 +231,11 @@ public static SchemaParameter generateSupportsParams() { return supportsQueryParams; } + /** + * Generates and initializes {@link SetImplementorsParams} for the 'setImplementors' method of a cis2-wCCD contract. + * + * @return initialized {@link SetImplementorsParams}. + */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); @@ -202,6 +249,11 @@ public static SchemaParameter generateSetImplementorsParams() { return setImplementorsParams; } + /** + * Generates and initializes {@link UpgradeParams} for the 'upgrade' method of a cis2-wCCD contract. + * + * @return initialized {@link UpgradeParams}. + */ @SneakyThrows public static SchemaParameter generateUpgradeParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index e00ab46b4..b78aa3b02 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -900,7 +900,8 @@ public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMi } Iterator finalizedBlockStream = this.getFinalizedBlocks(timeoutMillis); while (finalizedBlockStream.hasNext()) { - finalizedBlockStream.next(); // We check if the transaction is finalized every time a new block is finalized. + finalizedBlockStream.next(); + // We check if the transaction is finalized every time a new block is finalized. BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); if (newStatus.getStatus() == Status.FINALIZED) { return newStatus.getFinalizedBlockItem().get(); From 98d3eaaf57547ce0c0ab1799762d76c8d2be0220 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 22 Nov 2023 13:14:50 +0100 Subject: [PATCH 35/53] Review comments. --- CHANGELOG.md | 2 +- .../parameters/OperatorOfQuery.java | 2 +- .../parameters/TokenIdUnit.java | 2 +- .../parameters/UnwrapParams.java | 4 ++-- .../parameters/WCCDBalanceOfQuery.java | 4 ++-- .../parameters/WCCDBalanceOfQueryParams.java | 2 +- .../parameters/WrapParams.java | 4 ++-- .../wccd/Cis2WCCDParameters.java | 23 ++++++++++++------- .../smartcontracts/InvokeInstanceRequest.java | 8 +++---- .../smartcontracts/SchemaParameter.java | 2 +- .../java/com/concordium/sdk/types/UInt8.java | 2 +- 11 files changed, 31 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edf63c41a..9b6fe4bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ - Added support for GRPC V2 `GetBakerRewardPeriodInfo` for getting all the bakers in the reward period of a block. Only available when querying a node with version at least 6.1. - Added support for GRPC V2 `GetBlockCertificates` for retrieving certificates for a block supporting ConcordiumBF, i.e. a node with at least version 6.1. - Extended `CurrentPaydayStatus` with `CommissionRates` that apply for the current reward period. Requires at least node version 6.1. -- Implemented custom serialization of `AbstractAddress` and added class `ListParam` for conveniently using lists of objects, `AbstractAddress`, `ContractAddress` and `AccountAddress` as smart contract parameters. +- Implemented custom JSON serialization of `AbstractAddress` to enable `AbstractAddress` as a smart contract parameter, and added class `ListParam` for conveniently using lists of objects, `AbstractAddress`, `ContractAddress` and `AccountAddress` as smart contract parameters. - Added support for creating and serializing smart contract parameters using the abstract class `SchemaParameter` and a provided `Schema`. ## 5.1.0 diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java index d16225ec3..790a99d3b 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/OperatorOfQuery.java @@ -16,7 +16,7 @@ public class OperatorOfQuery { /** - * The ID of the token for which to query the balance of. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. + * An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' * to ensure correct serialization. */ diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java index f302511d6..503c45ba5 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java @@ -22,7 +22,7 @@ public TokenIdUnit() { public static class TokenIdUnitSerializer extends JsonSerializer { @Override public void serialize(TokenIdUnit value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(Hex.encodeHexString(new byte[]{value.id})); + gen.writeString(""); } } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java index 963c9bb3f..7442e6714 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java @@ -37,11 +37,11 @@ public class UnwrapParams extends SchemaParameter { /** * If the {@link Receiver} is a {@link AccountType#ADDRESS_CONTRACT} the unwrapped CCD together with these additional data bytes are sent to the function entrypoint specified in the {@link Receiver}. */ - private final List data; + private final UInt8[] data; - public UnwrapParams(Schema schema, ReceiveName receiveName, String amount, AbstractAddress owner, Receiver receiver, List data) { + public UnwrapParams(Schema schema, ReceiveName receiveName, String amount, AbstractAddress owner, Receiver receiver, UInt8[] data) { super(schema, receiveName); this.amount = amount; this.owner = owner; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java index a618d6dc5..4be8a35e2 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQuery.java @@ -6,7 +6,7 @@ * Wrapper class for {@link BalanceOfQuery} enforcing the correct Token id for cis2-wCCD contract. */ public class WCCDBalanceOfQuery extends BalanceOfQuery { - public WCCDBalanceOfQuery(TokenIdUnit tokenId, AbstractAddress address) { - super(tokenId, address); + public WCCDBalanceOfQuery(AbstractAddress address) { + super(new TokenIdUnit(), address); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java index d2c8f1e40..8d565a707 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDBalanceOfQueryParams.java @@ -10,7 +10,7 @@ * Wrapper class for {@link ListParam} enforcing the correct {@link BalanceOfQuery} for cis2-wccd contract. */ public class WCCDBalanceOfQueryParams extends ListParam { - public WCCDBalanceOfQueryParams(Schema schema, ReceiveName receiveName, List list) { + public WCCDBalanceOfQueryParams(Schema schema, ReceiveName receiveName, List list) { super(schema, receiveName, list); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java index a0f0fc122..df81922ca 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java @@ -15,10 +15,10 @@ public class WrapParams extends SchemaParameter { private final Receiver to; - private final List data; + private final UInt8[] data; - public WrapParams(Schema schema, ReceiveName receiveName, Receiver to, List data) { + public WrapParams(Schema schema, ReceiveName receiveName, Receiver to, UInt8[] data) { super(schema, receiveName); this.to = to; this.data = data; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 6a0c21883..3f3647ce2 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -2,6 +2,7 @@ import com.concordium.sdk.examples.contractexample.parameters.*; import com.concordium.sdk.responses.modulelist.ModuleRef; +import com.concordium.sdk.serializing.JsonMapper; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; @@ -42,9 +43,7 @@ public static SchemaParameter generateWrapParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); - List wrapData = new ArrayList<>(); - wrapData.add(UInt8.from(1)); - wrapData.add(UInt8.from(42)); + UInt8[] wrapData = new UInt8[]{UInt8.from(1), UInt8.from(42)}; WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); wrapParams.initialize(true); return wrapParams; @@ -61,9 +60,7 @@ public static SchemaParameter generateUnwrapParams() { ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); String unwrapAmount = "2"; // TokenAmountU64 Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); - List unwrapData = new ArrayList<>(); - unwrapData.add(UInt8.from(1)); - unwrapData.add(UInt8.from(42)); + UInt8[] unwrapData = new UInt8[]{UInt8.from(1),UInt8.from(42)}; UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, ACCOUNT_ADDRESS, unwrapReceiver, unwrapData); unwrapParams.initialize(true); return unwrapParams; @@ -166,8 +163,8 @@ public static SchemaParameter generateUpdateOperatorParams() { public static SchemaParameter generateBalanceOfParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); ReceiveName balanceOfReceiveName = ReceiveName.from(CONTRACT_NAME, "balanceOf"); - WCCDBalanceOfQuery balanceOfQuery1 = new WCCDBalanceOfQuery(new TokenIdUnit(), ACCOUNT_ADDRESS); - WCCDBalanceOfQuery balanceOfQuery2 = new WCCDBalanceOfQuery(new TokenIdUnit(), CONTRACT_ADDRESS_1); + WCCDBalanceOfQuery balanceOfQuery1 = new WCCDBalanceOfQuery(ACCOUNT_ADDRESS); + WCCDBalanceOfQuery balanceOfQuery2 = new WCCDBalanceOfQuery(CONTRACT_ADDRESS_1); List balanceOfQueries = new ArrayList<>(); balanceOfQueries.add(balanceOfQuery1); balanceOfQueries.add(balanceOfQuery2); @@ -265,4 +262,14 @@ public static SchemaParameter generateUpgradeParams() { return upgradeParams; } + @SneakyThrows + public static void main(String[] args) { + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); + Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); + UInt8[] wrapData = new UInt8[]{UInt8.from(1), UInt8.from(42)}; + WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); + wrapParams.initialize(true); + } + } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java index 371ac2982..adec23194 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/requests/smartcontracts/InvokeInstanceRequest.java @@ -70,7 +70,7 @@ public class InvokeInstanceRequest { * @param amount Amount to invoke the smart contract instance with. * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. * @param parameter The parameter bytes to include in the invocation of the entrypoint. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. */ public static InvokeInstanceRequest from(BlockQuery blockHash, AbstractAddress invoker, @@ -98,7 +98,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, * @param amount Amount to invoke the smart contract instance with. * @param entrypoint The {@link ReceiveName} of the smart contract instance to invoke. * @param parameter The parameter bytes to include in the invocation of the entrypoint. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, @@ -125,7 +125,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, * @param instance Address of the contract instance to invoke. * @param amount Amount to invoke the smart contract instance with. * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. */ public static InvokeInstanceRequest from(BlockQuery blockHash, AbstractAddress invoker, @@ -147,7 +147,7 @@ public static InvokeInstanceRequest from(BlockQuery blockHash, * @param instance Address of the contract instance to invoke. * @param amount Amount to invoke the smart contract instance with. * @param schemaParameter {@link SchemaParameter} message to invoke the contract with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. - * @param energy The amount of energy to allow for execution. This cannot exceed `100_000_000_000`. + * @param energy The amount of energy to allow for execution. */ public static InvokeInstanceRequest from(BlockQuery blockHash, ContractAddress instance, diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java index e87a50976..1a0fd2fcd 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java @@ -186,7 +186,7 @@ public byte[] toBytes() { } /** - * Returns the JSON representation of the parameter. This is the excactly what is sent to the rust layer for serialization when {@link SchemaParameter#initialize()} is called. + * Returns the JSON representation of the parameter. This is the exactly what is sent to the rust layer for serialization when {@link SchemaParameter#initialize()} is called. * @return the JSON representation of the parameter. */ @SneakyThrows diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java index 3763ff056..3c0cc4236 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -26,7 +26,7 @@ private UInt8(int value) { public byte[] getBytes() { val bytes = new byte[1]; - bytes[0] = (byte) (value & 0xff); + bytes[0] = (byte) (value); return bytes; } From 67873d88c8ddb984f6a65b0e62829ee5945f2102 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 22 Nov 2023 14:16:05 +0100 Subject: [PATCH 36/53] Review comments. --- .../sdk/crypto/CryptoJniNative.java | 4 +-- .../smartcontracts/SchemaParameter.java | 2 +- crypto-jni/src/lib.rs | 36 ++++++++++--------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java index 71e666371..659a96480 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/crypto/CryptoJniNative.java @@ -85,7 +85,7 @@ public class CryptoJniNative { * @param receiveName the name of the contract and the method. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. - * @param verboseErrors whether errors are returned in verbose format or not. + * @param verboseErrors whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. * @return JSON representing {@link SerializeParameterResult}. If the serialization was successful, the field 'serializedParameter' contains the serialized parameter as hex encoded bytes. * If not successful, the 'err' field contains a {@link JNIError} detailing what went wrong. */ @@ -101,7 +101,7 @@ public static String serializeReceiveParameter(SchemaParameter parameter, Receiv * @param initName name of the contract. * @param schemaBytes schema of the contract. * @param schemaVersion version of the schema. - * @param verboseErrors whether errors are returned in verbose format or not. + * @param verboseErrors whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. * @return JSON representing {@link SerializeParameterResult}. If the serialization was successful, the field 'serializedParameter' contains the serialized parameter as hex encoded bytes. * If not successful, the 'err' field contains a {@link JNIError} detailing what went wrong. */ diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java index 1a0fd2fcd..1e7e1dc88 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaParameter.java @@ -122,7 +122,7 @@ public void initialize() { /** * Initializes the parameter by ensuring serialization is performed correctly. This is required before the parameter is used. * - * @param verboseErrors whether to return errors in a verbose format or not. Defaults to false if omitted. + * @param verboseErrors whether to return errors in a verbose format or not, can be useful when debugging why serialization fails. Defaults to false if omitted. * @throws CryptoJniException if the serialization could not be performed. */ // Should never get thrown assuming the parameter is serialized correctly by the rust layer diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 884948562..2bd5cff60 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -472,13 +472,14 @@ type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] -/// The JNI wrapper for serializing receive parameters. +/// The JNI wrapper for serializing ia parameter for a recieve function according to a specified Schema. /** - * The `parameter` parameter must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. - * The `contractName` parameter must be a properly initalized `java.lang.String` that is non-null. - * The `methodName` parameter must be a properly initalized `java.lang.String` that is non-null. - * The `schemaBytes` parameter must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName` and `methodName`. - * The `schemaVersion` must be a integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + * `parameter` The parameter to serialize. `parameter` must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. + * `contractName` The name of the contract. `contractName` must be a properly initalized `java.lang.String` that is non-null. + * `methodName` The name of the method. `methodName` must be a properly initalized `java.lang.String` that is non-null. + * `schemaBytes` The bytes of the schema. `schemaBytes` must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. + * `schemaVersion` The version of the Schema. `schemaVersion` must be an integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + * `verboseErrors` Whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. */ /// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. /** @@ -540,7 +541,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeR &contractName, &methodName, &schema, - &version, + version, verboseErrors ); @@ -567,11 +568,11 @@ pub fn serialize_receive_contract_parameters_aux( contractName: &str, methodName: &str, schemaBytes: &Vec, - schemaVersion: &Option, + schemaVersion: Option, verboseErrors: bool, ) -> Result> { - let module_schema = VersionedModuleSchema::new(schemaBytes, schemaVersion)?; + let module_schema = VersionedModuleSchema::new(schemaBytes, &schemaVersion)?; let parameter_type = module_schema.get_receive_param_schema(contractName, methodName)?; let value: serde_json::Value = from_str(parameter)?; @@ -581,12 +582,13 @@ pub fn serialize_receive_contract_parameters_aux( return Ok(res?); } -/// The JNI wrapper for serializing init parameters. +/// The JNI wrapper for serializing a parameter for an init function according to a specified Schema. /** - * The `parameter` parameter must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. - * The `contractName` parameter must be a properly initalized `java.lang.String` that is non-null. - * The `schemaBytes` parameter must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. - * The `schemaVersion` must be a integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + * `parameter` The parameter to serialize. `parameter` must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. + * `contractName` The name of the contract. `contractName` must be a properly initalized `java.lang.String` that is non-null. + * `schemaBytes` The bytes of the schema. `schemaBytes` must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. + * `schemaVersion` The version of the Schema. `schemaVersion` must be an integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. + * `verboseErrors` Whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. */ /// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. /** @@ -640,7 +642,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI ¶meter, &contractName, &schema, - &version, + version, verboseErrors ); @@ -665,11 +667,11 @@ pub fn serialize_init_parameters_aux( parameter: &str, contractName: &str, schemaBytes: &Vec, - schemaVersion: &Option, + schemaVersion: Option, verboseErrors: bool, ) -> Result> { - let module_schema = VersionedModuleSchema::new(schemaBytes, schemaVersion)?; + let module_schema = VersionedModuleSchema::new(schemaBytes, &schemaVersion)?; let parameter_type = module_schema.get_init_param_schema(contractName)?; let value: serde_json::Value = from_str(parameter)?; From 75726e843f7ea524902ed937ca9d31efa2be7f8b Mon Sep 17 00:00:00 2001 From: magnusbechwind <93247743+magnusbechwind@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:17:20 +0100 Subject: [PATCH 37/53] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleš Bizjak --- .../com/concordium/sdk/transactions/InitContractPayload.java | 2 +- crypto-jni/src/lib.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java index 11cee4513..51642cddf 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/InitContractPayload.java @@ -76,7 +76,7 @@ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, In * Create a new instance of {@link InitContractPayload} from the given parameters. * * @param amount CCD amount to deposit. - * @param moduleRef HAsh of the smart contract module reference. + * @param moduleRef Hash of the smart contract module reference. * @param schemaParameter {@link SchemaParameter} message to invoke the initialization method with. Must be initialized with {@link SchemaParameter#initialize()} beforehand. */ public static InitContractPayload from(CCDAmount amount, ModuleRef moduleRef, SchemaParameter schemaParameter) { diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 2bd5cff60..4eb63ce1f 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -23,13 +23,11 @@ use std::convert::{From, TryFrom}; use std::i8; use std::str::Utf8Error; use hex; - use jni::{ objects::{JClass, JString}, sys::{jbyteArray, jint}, JNIEnv, }; - use anyhow::{anyhow, Result}; const SUCCESS: i32 = 0; From 4b4e96edb6f5c77acc3256f7a12bf8c703cc2782 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 22 Nov 2023 16:51:00 +0100 Subject: [PATCH 38/53] waitUntilFinalized keeps trying if transaction is not found immediately. --- .../java/com/concordium/sdk/ClientV2.java | 74 ++++++++++++++++--- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index b78aa3b02..e6b49d7eb 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -140,6 +140,7 @@ public Iterator getBlocks(int timeoutMillis) { * * @param timeoutMillis Timeout for the request in Milliseconds. * @return {@link Iterator} + * */ public Iterator getFinalizedBlocks(int timeoutMillis) { val grpcOutput = this.server(timeoutMillis) @@ -308,6 +309,9 @@ public AccountNonce getNextAccountSequenceNumber(AccountAddress address) { * * @param transactionHash The transaction {@link Hash} * @return The {@link BlockItemStatus} + * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node. + *
*/ public BlockItemStatus getBlockItemStatus(Hash transactionHash) { val grpcOutput = this.server() @@ -889,27 +893,73 @@ public ImmutableList getWinningBakersEpoch(EpochQuery epochQuery) * @param timeoutMillis the number of milliseconds to wait before throwing an exception. * @return {@link FinalizedBlockItem} of the transaction. * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    - *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the timeout is exceeded. - *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node. + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node after the timeout is exceeded. + *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized after the timeout is exceeded. *
*/ public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMillis) { - BlockItemStatus status = this.getBlockItemStatus(transactionHash); - if (status.getStatus() == Status.FINALIZED) { - return status.getFinalizedBlockItem().get(); + try { + BlockItemStatus status = this.getBlockItemStatus(transactionHash); + if (status.getStatus() == Status.FINALIZED) { + return status.getFinalizedBlockItem().get(); + } + } catch (io.grpc.StatusRuntimeException e) { + // If the transaction is not found we wait for it. + ignoreExceptionIfCode(e, io.grpc.Status.Code.NOT_FOUND); } - Iterator finalizedBlockStream = this.getFinalizedBlocks(timeoutMillis); - while (finalizedBlockStream.hasNext()) { - finalizedBlockStream.next(); - // We check if the transaction is finalized every time a new block is finalized. - BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); - if (newStatus.getStatus() == Status.FINALIZED) { - return newStatus.getFinalizedBlockItem().get(); + return listenForFinalizedTransaction(transactionHash, timeoutMillis); + } + + /** + * Helper function for {@link ClientV2#waitUntilFinalized(Hash, int)}. Listens for finalized blocks and returns the {@link FinalizedBlockItem} of the transaction when available. + * @param transactionHash the {@link Hash} of the transaction to wait for. + * @param timeoutMillis the number of milliseconds to wait before throwing an exception. + * @return {@link FinalizedBlockItem} of the transaction. + * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node after the timeout is exceeded. + *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized after the timeout is exceeded. + *
+ */ + private FinalizedBlockItem listenForFinalizedTransaction(Hash transactionHash, int timeoutMillis) { + io.grpc.StatusRuntimeException notFound = null; + try { + Iterator finalizedBlockStream = this.getFinalizedBlocks(timeoutMillis); + while (finalizedBlockStream.hasNext()) { + finalizedBlockStream.next(); + // We check if the transaction is finalized every time a new block is finalized. + try { + BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); + if (newStatus.getStatus() == Status.FINALIZED) { + return newStatus.getFinalizedBlockItem().get(); + } + } catch (io.grpc.StatusRuntimeException e) { + ignoreExceptionIfCode(e, io.grpc.Status.Code.NOT_FOUND); + notFound = e; // If the transaction is still not found after the timeout is exceeded, we throw this exception. + } + } + } catch (io.grpc.StatusRuntimeException e) { + ignoreExceptionIfCode(e, io.grpc.Status.Code.DEADLINE_EXCEEDED); + if (notFound != null ) { // The block was not found. + throw notFound; } + throw e; } throw new IllegalStateException("No more finalized blocks"); // This should never happen as finalized blocks keep being streamed. } + /** + * Helper method for allowing {@link io.grpc.StatusRuntimeException} with specified {@link io.grpc.Status.Code} without throwing the exception. + * @param e the {@link io.grpc.StatusRuntimeException}. + * @param code the {@link io.grpc.Status.Code} to allow. + * @throws io.grpc.StatusRuntimeException if the code of the exception does not match the provided code. + */ + private void ignoreExceptionIfCode(io.grpc.StatusRuntimeException e, io.grpc.Status.Code code) { + if (e.getStatus().getCode().equals(code)) { + return; + } + throw e; + } + /** * Get a {@link QueriesGrpc.QueriesBlockingStub} with a timeout * The timeout is the one specified in via the {@link Connection} object used to From 95093d3ee07236cb3b96e856fd45bc2761dbc432 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 24 Nov 2023 10:54:57 +0100 Subject: [PATCH 39/53] Adressed review comments. --- .../src/main/java/com/concordium/sdk/types/UInt8.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java index 3c0cc4236..7f0291bcb 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java @@ -11,7 +11,7 @@ import java.io.IOException; /** - * An unsigned byte + * An unsigned byte. Used in the smart contract examples to ensure proper json serialization. */ @EqualsAndHashCode @Getter From 46638178a9e15f0084479866e6784db4693ff860 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Fri, 24 Nov 2023 12:53:51 +0100 Subject: [PATCH 40/53] Removed custom errors from unit test SC. Now uses predefined ParseError --- .../testresources/smartcontractschema/lib.rs | 40 +++++------------- .../smartcontractschema/unit-test.schema.bin | Bin 629 -> 384 bytes 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs index 7cf78b524..892bf6f0a 100644 --- a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs +++ b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs @@ -2,7 +2,6 @@ //! # A Concordium V1 smart contract. This contract is only for genereating a schema to test serialization of `SchemaParameter` and is never meant to be excecuted, hence the dummy state/error/init. use concordium_std::*; -use core::fmt::Debug; /// Your smart contract state. #[derive(Serialize, SchemaType)] @@ -10,16 +9,6 @@ pub struct State { // Dummy state. } -/// Dummy errors -#[derive(Debug, PartialEq, Eq, Reject, Serial, SchemaType)] -enum Error { - /// Failed parsing the parameter. - #[from(ParseError)] - ParseParams, - /// Your error - YourError, -} - /// Dummy init functions #[init(contract = "java_sdk_schema_unit_test")] fn init( @@ -31,14 +20,12 @@ fn init( Ok(State {}) } - #[derive(Serialize, SchemaType)] #[concordium(transparent)] struct ListParam ( Vec ); - #[derive(Serialize, SchemaType)] struct AbstractAddressContainer { address: Address, @@ -54,18 +41,19 @@ struct ContractAddressContainer { address: ContractAddress, } +// The `ParseError` in the following result types is never thrown, as the functions only exist to generate a schema for serialization of SC parameters. + /// Takes ListParam as parameter for ensuring correct serialization of ListParam #[receive( contract = "java_sdk_schema_unit_test", name = "list_param_test", parameter = "ListParam", - error = "Error", mutable )] fn list_param_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } @@ -74,13 +62,12 @@ fn list_param_test( contract = "java_sdk_schema_unit_test", name = "abstract_address_container_test", parameter = "AbstractAddressContainer", - error = "Error", mutable )] fn abstract_address_container_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } @@ -89,13 +76,12 @@ fn abstract_address_container_test( contract = "java_sdk_schema_unit_test", name = "abstract_address_test", parameter = "Address", - error = "Error", mutable )] fn abstract_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } @@ -104,27 +90,26 @@ fn abstract_address_test( contract = "java_sdk_schema_unit_test", name = "contract_address_container_test", parameter = "ContractAddressContainer", - error = "Error", mutable )] fn contract_address_container_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } + /// Takes Address as parameter for ensuring correct serialization of Address when passed directly #[receive( contract = "java_sdk_schema_unit_test", name = "contract_address_test", parameter = "ContractAddress", - error = "Error", mutable )] fn contract_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } @@ -133,13 +118,12 @@ fn contract_address_test( contract = "java_sdk_schema_unit_test", name = "account_address_container_test", parameter = "AccountAddressContainer", - error = "Error", mutable )] fn account_address_container_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) } @@ -148,13 +132,11 @@ fn account_address_container_test( contract = "java_sdk_schema_unit_test", name = "account_address_test", parameter = "AccountAddress", - error = "Error", mutable )] fn account_address_test( ctx: &impl HasReceiveContext, _host: &mut impl HasHost, -) -> Result<(), Error> { +) -> Result<(), ParseError> { Ok(()) -} - +} \ No newline at end of file diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin b/concordium-sdk/src/test/testresources/smartcontractschema/unit-test.schema.bin index 4ffdf86eb8c902c30841cb6245d28121e5f347f6..445b9f1a9ffcb686c21fff2c78b08c6dd6142873 100644 GIT binary patch delta 151 zcmey$(!e~yhmm2TuazVN14Cj`aY<2Pa!Gt*N=i{`adCV}YH-MHTOBZQ;F9}z?;a2OewGO# zwsh|B28H!Qp}v_GRA-x@g25o>)ZNp8D+UibD5z_15S4Z|Kx2)Mb9pJ4i>JqdN{;zK zYuDM3alcqlI1-YnVr3QQ3M!w$qoDvT$|dC&*ZGt8&dZ9j$$nOs|8dEVmkd&q?^q;= oFTe0c?I~b(o{j#=`BY0M#8FlXdQGyP4F>h%=Ndl1My4Re2e99xTL1t6 From 22a5f6d14f933e2fe9ad909635ff154ba1bcf119 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 11:05:27 +0100 Subject: [PATCH 41/53] Addressed review comments --- .../contractexample/parameters/TokenIdUnit.java | 9 ++++----- .../contractexample/wccd/Cis2WCCDParameters.java | 10 ---------- .../main/java/com/concordium/sdk/ClientV2.java | 15 +++++++++------ .../sdk/smartcontract/IncorrectParams.java | 3 +++ 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java index 503c45ba5..037618bb1 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenIdUnit.java @@ -9,15 +9,14 @@ import java.io.IOException; +/** + * Represents TokenIdUnit used in the cis2 smart contract examples. + */ @Getter @JsonSerialize(using = TokenIdUnit.TokenIdUnitSerializer.class) public class TokenIdUnit implements TokenId { - private final byte id; - - public TokenIdUnit() { - id = 0; - } + public TokenIdUnit() {} public static class TokenIdUnitSerializer extends JsonSerializer { @Override diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 3f3647ce2..24b6709e0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -262,14 +262,4 @@ public static SchemaParameter generateUpgradeParams() { return upgradeParams; } - @SneakyThrows - public static void main(String[] args) { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); - ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); - Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); - UInt8[] wrapData = new UInt8[]{UInt8.from(1), UInt8.from(42)}; - WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); - wrapParams.initialize(true); - } - } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index e6b49d7eb..8d5938458 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -889,12 +889,14 @@ public ImmutableList getWinningBakersEpoch(EpochQuery epochQuery) /** * Waits until a given transaction is finalized and returns the corresponding {@link FinalizedBlockItem}. + * If the transaction is unknown to the node, or not finalized, the client starts listening for newly finalized blocks, + * and returns the corresponding {@link FinalizedBlockItem} once the transaction is finalized. * @param transactionHash the {@link Hash} of the transaction to wait for. - * @param timeoutMillis the number of milliseconds to wait before throwing an exception. + * @param timeoutMillis the number of milliseconds to listen for newly finalized blocks. * @return {@link FinalizedBlockItem} of the transaction. * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    - *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node after the timeout is exceeded. - *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized after the timeout is exceeded. + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node when the timeout is exceeded. + *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized when the timeout is exceeded. *
*/ public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMillis) { @@ -912,12 +914,13 @@ public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMi /** * Helper function for {@link ClientV2#waitUntilFinalized(Hash, int)}. Listens for finalized blocks and returns the {@link FinalizedBlockItem} of the transaction when available. + * Keeps listening even if the transaction is unknown to the node. * @param transactionHash the {@link Hash} of the transaction to wait for. - * @param timeoutMillis the number of milliseconds to wait before throwing an exception. + * @param timeoutMillis the number of milliseconds to listen for newly finalized blocks. * @return {@link FinalizedBlockItem} of the transaction. * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    - *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node after the timeout is exceeded. - *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized after the timeout is exceeded. + *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node when the timeout is exceeded. + *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized when the timeout is exceeded. *
*/ private FinalizedBlockItem listenForFinalizedTransaction(Hash transactionHash, int timeoutMillis) { diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java index 76746ebb8..50118f284 100644 --- a/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java +++ b/concordium-sdk/src/test/java/com/concordium/sdk/smartcontract/IncorrectParams.java @@ -11,6 +11,9 @@ @Getter public class IncorrectParams extends SchemaParameter { + /** + * Has no special meaning, just some value that does not adhere to the {@link Schema} provided in the test. + */ private final int value; protected IncorrectParams(Schema schema, ReceiveName receiveName) { From 19764984222314dfa4be3b8cbf66e3e5ac7db8ca Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 11:27:35 +0100 Subject: [PATCH 42/53] Added wait parameter to the examples to control how long to wait for finalized transactions --- .../sdk/examples/contractexample/cis2nft/Cis2Nft.java | 10 ++++++++-- .../sdk/examples/contractexample/wccd/Cis2WCCD.java | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index d942e0e96..bd8af68a3 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -45,6 +45,12 @@ public class Cis2Nft implements Callable { description = "GRPC request timeout in milliseconds.", defaultValue = "100000") private int timeout; + + @CommandLine.Option( + names = {"--wait"}, + description = "How long to wait for transaction finalization.", + defaultValue = "100000") + private int wait; private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address @@ -118,7 +124,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } @@ -134,7 +140,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index 764ab43f0..bac7fe64c 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -43,6 +43,12 @@ public class Cis2WCCD implements Callable { description = "GRPC request timeout in milliseconds.", defaultValue = "100000") private int timeout; + + @CommandLine.Option( + names = {"--wait"}, + description = "How long to wait for transaction finalization.", + defaultValue = "100000") + private int wait; private static final String SENDER_ADDRESS = "3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE"; // Dummy address private static final ModuleRef MODULE_REF = ModuleRef.from("247a7ac6efd2e46f72fd18741a6d1a0254ec14f95639df37079a576b2033873e"); // Dummy module ref private static final ContractAddress CONTRACT_ADDRESS = ContractAddress.from(1, 0); // Dummy contract address @@ -135,7 +141,7 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } @@ -151,7 +157,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, timeout); + FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); } From a4ec4fd11b46e09244f3aed1fc28b70c48e578c0 Mon Sep 17 00:00:00 2001 From: magnusbechwind <93247743+magnusbechwind@users.noreply.github.com> Date: Wed, 29 Nov 2023 13:08:57 +0100 Subject: [PATCH 43/53] Apply suggestions from code review Co-authored-by: Emil Lai <39825288+EmilLa1@users.noreply.github.com> --- concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index 8d5938458..f49371ff7 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -902,7 +902,7 @@ public ImmutableList getWinningBakersEpoch(EpochQuery epochQuery) public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMillis) { try { BlockItemStatus status = this.getBlockItemStatus(transactionHash); - if (status.getStatus() == Status.FINALIZED) { + if (status.getFinalizedBlockItem().isPresent()) { return status.getFinalizedBlockItem().get(); } } catch (io.grpc.StatusRuntimeException e) { @@ -932,7 +932,7 @@ private FinalizedBlockItem listenForFinalizedTransaction(Hash transactionHash, i // We check if the transaction is finalized every time a new block is finalized. try { BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); - if (newStatus.getStatus() == Status.FINALIZED) { + if (newStatus.getFinalizedBlockItem().isPresent()) { return newStatus.getFinalizedBlockItem().get(); } } catch (io.grpc.StatusRuntimeException e) { From 04b760c2a015ec1ba2dea3c52fe6f74324f6e999 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 13:22:22 +0100 Subject: [PATCH 44/53] Refactored waitUntilFinalized according to review comments. --- .../java/com/concordium/sdk/ClientV2.java | 94 ++++++++----------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java index f49371ff7..78bd87dae 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java @@ -34,7 +34,6 @@ import com.concordium.sdk.responses.poolstatus.BakerPoolStatus; import com.concordium.sdk.responses.rewardstatus.RewardsOverview; import com.concordium.sdk.responses.smartcontracts.InvokeInstanceResult; -import com.concordium.sdk.responses.transactionstatus.Status; import com.concordium.sdk.responses.winningbaker.WinningBaker; import com.concordium.sdk.transactions.AccountTransaction; import com.concordium.sdk.transactions.BlockItem; @@ -46,6 +45,7 @@ import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; import io.grpc.ManagedChannel; +import io.grpc.Status; import lombok.val; import java.io.File; @@ -888,79 +888,63 @@ public ImmutableList getWinningBakersEpoch(EpochQuery epochQuery) } /** - * Waits until a given transaction is finalized and returns the corresponding {@link FinalizedBlockItem}. - * If the transaction is unknown to the node, or not finalized, the client starts listening for newly finalized blocks, - * and returns the corresponding {@link FinalizedBlockItem} once the transaction is finalized. + * Waits until a given transaction is finalized and returns the corresponding {@link Optional}. + * If the transaction is unknown to the node or not finalized, the client starts listening for newly finalized blocks, + * and returns the corresponding {@link Optional} once the transaction is finalized. * @param transactionHash the {@link Hash} of the transaction to wait for. * @param timeoutMillis the number of milliseconds to listen for newly finalized blocks. - * @return {@link FinalizedBlockItem} of the transaction. - * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    - *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node when the timeout is exceeded. - *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized when the timeout is exceeded. - *
+ * @return {@link Optional} of the transaction if it was finalized before exceeding the timeout, Empty otherwise. */ - public FinalizedBlockItem waitUntilFinalized(Hash transactionHash, int timeoutMillis) { - try { - BlockItemStatus status = this.getBlockItemStatus(transactionHash); - if (status.getFinalizedBlockItem().isPresent()) { - return status.getFinalizedBlockItem().get(); - } - } catch (io.grpc.StatusRuntimeException e) { - // If the transaction is not found we wait for it. - ignoreExceptionIfCode(e, io.grpc.Status.Code.NOT_FOUND); + public Optional waitUntilFinalized(Hash transactionHash, int timeoutMillis) { + Optional maybeStatus = getFinalizedTransaction(transactionHash); + // if it's finalized return it. + if (maybeStatus.isPresent()) { + return maybeStatus; } - return listenForFinalizedTransaction(transactionHash, timeoutMillis); - } - - /** - * Helper function for {@link ClientV2#waitUntilFinalized(Hash, int)}. Listens for finalized blocks and returns the {@link FinalizedBlockItem} of the transaction when available. - * Keeps listening even if the transaction is unknown to the node. - * @param transactionHash the {@link Hash} of the transaction to wait for. - * @param timeoutMillis the number of milliseconds to listen for newly finalized blocks. - * @return {@link FinalizedBlockItem} of the transaction. - * @throws io.grpc.StatusRuntimeException with {@link io.grpc.Status.Code}:
    - *
  • {@link io.grpc.Status#NOT_FOUND} if the transaction is not known to the node when the timeout is exceeded. - *
  • {@link io.grpc.Status#DEADLINE_EXCEEDED} if the transaction is not finalized when the timeout is exceeded. - *
- */ - private FinalizedBlockItem listenForFinalizedTransaction(Hash transactionHash, int timeoutMillis) { - io.grpc.StatusRuntimeException notFound = null; + // check newly finalized blocks until we time out + Optional result = Optional.empty(); try { Iterator finalizedBlockStream = this.getFinalizedBlocks(timeoutMillis); while (finalizedBlockStream.hasNext()) { finalizedBlockStream.next(); - // We check if the transaction is finalized every time a new block is finalized. - try { - BlockItemStatus newStatus = this.getBlockItemStatus(transactionHash); - if (newStatus.getFinalizedBlockItem().isPresent()) { - return newStatus.getFinalizedBlockItem().get(); - } - } catch (io.grpc.StatusRuntimeException e) { - ignoreExceptionIfCode(e, io.grpc.Status.Code.NOT_FOUND); - notFound = e; // If the transaction is still not found after the timeout is exceeded, we throw this exception. + Optional finalizedBlockItem = getFinalizedTransaction(transactionHash); + if (finalizedBlockItem.isPresent()) { + // the transaction is included in a finalized block, break and return the finalized status. + result = finalizedBlockItem; + break; } } } catch (io.grpc.StatusRuntimeException e) { - ignoreExceptionIfCode(e, io.grpc.Status.Code.DEADLINE_EXCEEDED); - if (notFound != null ) { // The block was not found. - throw notFound; + // we timed out. Return empty to indicate that the transaction could not be found. + if (e.getStatus().getCode().equals(Status.Code.DEADLINE_EXCEEDED)) { + return Optional.empty(); } throw e; } - throw new IllegalStateException("No more finalized blocks"); // This should never happen as finalized blocks keep being streamed. + return result; } /** - * Helper method for allowing {@link io.grpc.StatusRuntimeException} with specified {@link io.grpc.Status.Code} without throwing the exception. - * @param e the {@link io.grpc.StatusRuntimeException}. - * @param code the {@link io.grpc.Status.Code} to allow. - * @throws io.grpc.StatusRuntimeException if the code of the exception does not match the provided code. + * Helper function for {@link ClientV2#waitUntilFinalized(Hash, int)}. Retrieves the {@link Optional} of the transaction if it is finalized. + * @param transactionHash the {@link Hash} of the transaction to wait for. + * @return {@link Optional} of the transaction if it is finalized, Empty otherwise. */ - private void ignoreExceptionIfCode(io.grpc.StatusRuntimeException e, io.grpc.Status.Code code) { - if (e.getStatus().getCode().equals(code)) { - return; + private Optional getFinalizedTransaction(Hash transactionHash) { + try { + BlockItemStatus status = this.getBlockItemStatus(transactionHash); + if (status.getFinalizedBlockItem().isPresent()) { + return Optional.of(status.getFinalizedBlockItem().get()); + } + // Only return a finalized transaction. + return Optional.empty(); + } catch (io.grpc.StatusRuntimeException e) { + // If the transaction is not found then return empty. + if (e.getStatus().getCode().equals(Status.Code.NOT_FOUND)) { + return Optional.empty(); + } + // report back any other exceptions. + throw e; } - throw e; } /** From 97aaf32d85c5e09a0e9c25d272aec7b57ae647f0 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 13:26:56 +0100 Subject: [PATCH 45/53] Fixed examples wrt. refactored waitUntilFinalized --- .../sdk/examples/contractexample/cis2nft/Cis2Nft.java | 9 +++++---- .../sdk/examples/contractexample/wccd/Cis2WCCD.java | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java index bd8af68a3..c7278f0f9 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2Nft.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.net.URL; +import java.util.Optional; import java.util.concurrent.Callable; /** @@ -124,8 +125,8 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); - System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); + Optional finalizedTransaction = client.waitUntilFinalized(txHash, wait); + finalizedTransaction.ifPresent(finalizedBlockItem -> System.out.println("Transaction finalized in block with hash: " + finalizedBlockItem.getBlockHash())); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -140,8 +141,8 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); - System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); + Optional finalizedTransaction = client.waitUntilFinalized(txHash, wait); + finalizedTransaction.ifPresent(finalizedBlockItem -> System.out.println("Transaction finalized in block with hash: " + finalizedBlockItem.getBlockHash())); } public static void main(String[] args) { diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java index bac7fe64c..f439f4e9a 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCD.java @@ -17,6 +17,7 @@ import picocli.CommandLine; import java.net.URL; +import java.util.Optional; import java.util.concurrent.Callable; /** @@ -141,8 +142,8 @@ private void handleInit(ClientV2 client, Nonce nonce) { .build(); Hash txHash = client.sendTransaction(initContractTransaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); - System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); + Optional finalizedTransaction = client.waitUntilFinalized(txHash, wait); + finalizedTransaction.ifPresent(finalizedBlockItem -> System.out.println("Transaction finalized in block with hash: " + finalizedBlockItem.getBlockHash())); } private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter parameter) { @@ -157,8 +158,8 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete .build(); Hash txHash = client.sendTransaction(transaction); System.out.println("Submitted transaction for " + this.methodName + " with hash: " + txHash); - FinalizedBlockItem finalizedTransaction = client.waitUntilFinalized(txHash, wait); - System.out.println("Transaction finalized in block with hash: " + finalizedTransaction.getBlockHash()); + Optional finalizedTransaction = client.waitUntilFinalized(txHash, wait); + finalizedTransaction.ifPresent(finalizedBlockItem -> System.out.println("Transaction finalized in block with hash: " + finalizedBlockItem.getBlockHash())); } From 31b9f6717f71809d7a32c3d4a67269a03a3f05b4 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 14:56:28 +0100 Subject: [PATCH 46/53] Removed UInt8 wrapper class and refactored the examples accordingly. --- .../cis2nft/Cis2NftParameters.java | 4 +- .../parameters/Cis2Transfer.java | 9 ++- .../parameters/NftTransfer.java | 5 +- .../parameters/TokenAmountU8.java | 15 +++-- .../UInt8ByteArrrayJsonSerializer.java | 22 +++++++ .../parameters/UnwrapParams.java | 11 ++-- .../parameters/WCCDTransfer.java | 5 +- .../parameters/WrapParams.java | 16 +++-- .../wccd/Cis2WCCDParameters.java | 12 ++-- .../java/com/concordium/sdk/types/UInt8.java | 60 ------------------- .../com/concordium/sdk/types/UInt8Test.java | 54 ----------------- 11 files changed, 59 insertions(+), 154 deletions(-) create mode 100644 concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UInt8ByteArrrayJsonSerializer.java delete mode 100644 concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java delete mode 100644 concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index d10cb2bc7..1cad764e0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -55,9 +55,7 @@ public static SchemaParameter generateTransferParams() { TokenAmountU8 amount = TokenAmountU8.from(1); AbstractAddress from = CONTRACT_ADDRESS_1; Receiver to = new Receiver(CONTRACT_ADDRESS_2, "mint"); - List data = new ArrayList<>(); - data.add(UInt8.from(123)); - data.add(UInt8.from(23)); + byte[] data = new byte[]{123, -23}; NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); List transfers = new ArrayList<>(); transfers.add(transfer); diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java index 001bb127d..b4f43e94b 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/Cis2Transfer.java @@ -3,14 +3,11 @@ import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; -import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.AllArgsConstructor; import lombok.Getter; -import java.util.List; - /** * A single transfer of some amount of a token. @@ -41,9 +38,11 @@ public class Cis2Transfer { */ private Receiver to; /** - * Additional data to include in the transfer. Can be used for additional arguments + * Additional data to include in the transfer. Can be used for additional arguments. + * Must be serialized as a json array of unsigned bytes. This serialization is implemented in {@link UInt8ByteArrrayJsonSerializer}. */ - private List data; + @JsonSerialize(using = UInt8ByteArrrayJsonSerializer.class) + private byte[] data; } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java index f1cee3fb4..5b0fb0333 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/NftTransfer.java @@ -1,16 +1,13 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; -import com.concordium.sdk.types.UInt8; - -import java.util.List; /** * Wrapper class for {@link Cis2Transfer} enforcing the correct Token amount/id for cis2-nft contract. */ public class NftTransfer extends Cis2Transfer { - public NftTransfer(TokenIdU32 tokenId, TokenAmountU8 amount, AbstractAddress from, Receiver to, List data) { + public NftTransfer(TokenIdU32 tokenId, TokenAmountU8 amount, AbstractAddress from, Receiver to, byte[] data) { super(tokenId, amount, from, to, data); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java index a11ab2663..aabf4b3c8 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/TokenAmountU8.java @@ -1,6 +1,5 @@ package com.concordium.sdk.examples.contractexample.parameters; -import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; @@ -13,21 +12,27 @@ @JsonSerialize(using = TokenAmountU8.TokenAmountU8Serializer.class) public class TokenAmountU8 implements TokenAmount { - private final UInt8 amount; + private final int amount; - private TokenAmountU8(UInt8 amount) { + private TokenAmountU8(int amount) { this.amount = amount; } public static TokenAmountU8 from(int value) { - return new TokenAmountU8(UInt8.from(value)); + if (value < 0) { + throw new NumberFormatException("Value of TokenAmountU8 cannot be negative"); + } + if (value > 255) { + throw new NumberFormatException("Value of TokenAmountU8 cannot exceed 2^8"); + } + return new TokenAmountU8(value); } public static class TokenAmountU8Serializer extends JsonSerializer { @Override public void serialize(TokenAmountU8 value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(value.getAmount().toString()); + gen.writeString(String.valueOf(value.getAmount())); } } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UInt8ByteArrrayJsonSerializer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UInt8ByteArrrayJsonSerializer.java new file mode 100644 index 000000000..ecc9378c5 --- /dev/null +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UInt8ByteArrrayJsonSerializer.java @@ -0,0 +1,22 @@ +package com.concordium.sdk.examples.contractexample.parameters; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Serializes a byte[] interpreted as unsigned bytes. + */ +public class UInt8ByteArrrayJsonSerializer extends JsonSerializer { + @Override + public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartArray(); + for (byte b : value) { + int unsigned = b & 0xff; // The unsigned value of the byte + gen.writeNumber(unsigned); + } + gen.writeEndArray(); + } +} diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java index 7442e6714..913618fb5 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/UnwrapParams.java @@ -8,12 +8,9 @@ import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; -import com.concordium.sdk.types.UInt8; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; -import java.util.List; - /** * Represents the parameter 'UnwrapParams' used in the cis2-wCCD contract */ @@ -22,7 +19,7 @@ public class UnwrapParams extends SchemaParameter { /** * The amount of tokens to unwrap. */ - private final String amount; + private final TokenAmountU64 amount; /** * The owner of the tokens. An {@link AbstractAddress} is either an {@link AccountAddress} or a {@link ContractAddress}. * Fields of smart contract parameters containing {@link AbstractAddress} must be annotated with '@JsonSerialize(using = AbstractAddress.AbstractAddressJsonSerializer.class)' @@ -36,12 +33,14 @@ public class UnwrapParams extends SchemaParameter { private final Receiver receiver; /** * If the {@link Receiver} is a {@link AccountType#ADDRESS_CONTRACT} the unwrapped CCD together with these additional data bytes are sent to the function entrypoint specified in the {@link Receiver}. + * Must be serialized as a json array of unsigned bytes. This serialization is implemented in {@link UInt8ByteArrrayJsonSerializer}. */ - private final UInt8[] data; + @JsonSerialize(using = UInt8ByteArrrayJsonSerializer.class) + private final byte[] data; - public UnwrapParams(Schema schema, ReceiveName receiveName, String amount, AbstractAddress owner, Receiver receiver, UInt8[] data) { + public UnwrapParams(Schema schema, ReceiveName receiveName, TokenAmountU64 amount, AbstractAddress owner, Receiver receiver, byte[] data) { super(schema, receiveName); this.amount = amount; this.owner = owner; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java index 360821edb..fa7f6c1f0 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WCCDTransfer.java @@ -1,15 +1,12 @@ package com.concordium.sdk.examples.contractexample.parameters; import com.concordium.sdk.types.AbstractAddress; -import com.concordium.sdk.types.UInt8; - -import java.util.List; /** * Wrapper class for {@link Cis2Transfer} enforcing the correct Token amount/id for cis2-wCCD contract. */ public class WCCDTransfer extends Cis2Transfer { - public WCCDTransfer(TokenIdUnit tokenId, TokenAmountU64 amount, AbstractAddress from, Receiver to, List data) { + public WCCDTransfer(TokenIdUnit tokenId, TokenAmountU64 amount, AbstractAddress from, Receiver to, byte[] data) { super(tokenId, amount, from, to, data); } } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java index df81922ca..a2061320c 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/parameters/WrapParams.java @@ -3,22 +3,28 @@ import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.types.UInt8; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; -import java.util.List; - /** * Represents the parameter 'WrapParams' used in the cis2-wCCD contract */ @Getter public class WrapParams extends SchemaParameter { + /** + * The address to receive these tokens. + */ private final Receiver to; - private final UInt8[] data; + /** + * If the {@link Receiver} is a contract and the {@link Receiver} is not the invoker of the wrap function, the receive hook function is invoked with these additional data bytes as part of the input parameters. + * Must be serialized as a json array of unsigned bytes. This serialization is implemented in {@link UInt8ByteArrrayJsonSerializer}. + */ + @JsonSerialize(using = UInt8ByteArrrayJsonSerializer.class) + private final byte[] data; - public WrapParams(Schema schema, ReceiveName receiveName, Receiver to, UInt8[] data) { + public WrapParams(Schema schema, ReceiveName receiveName, Receiver to, byte[] data) { super(schema, receiveName); this.to = to; this.data = data; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 24b6709e0..93a1a517f 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -2,7 +2,6 @@ import com.concordium.sdk.examples.contractexample.parameters.*; import com.concordium.sdk.responses.modulelist.ModuleRef; -import com.concordium.sdk.serializing.JsonMapper; import com.concordium.sdk.transactions.Hash; import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; @@ -12,7 +11,6 @@ import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; import com.concordium.sdk.types.ContractAddress; -import com.concordium.sdk.types.UInt8; import lombok.SneakyThrows; import java.nio.file.Files; @@ -43,7 +41,7 @@ public static SchemaParameter generateWrapParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); - UInt8[] wrapData = new UInt8[]{UInt8.from(1), UInt8.from(42)}; + byte[] wrapData = new byte[]{1, 42}; WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); wrapParams.initialize(true); return wrapParams; @@ -58,9 +56,9 @@ public static SchemaParameter generateWrapParams() { public static SchemaParameter generateUnwrapParams() { Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); - String unwrapAmount = "2"; // TokenAmountU64 + TokenAmountU64 unwrapAmount = TokenAmountU64.from(2); Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); - UInt8[] unwrapData = new UInt8[]{UInt8.from(1),UInt8.from(42)}; + byte[] unwrapData = new byte[]{1, 42}; UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, ACCOUNT_ADDRESS, unwrapReceiver, unwrapData); unwrapParams.initialize(true); return unwrapParams; @@ -123,9 +121,7 @@ public static SchemaParameter generateTransferParams() { TokenAmountU64 amount = TokenAmountU64.from(1); AbstractAddress from = CONTRACT_ADDRESS_1; Receiver to = new Receiver(CONTRACT_ADDRESS_2, "mint"); - List data = new ArrayList<>(); - data.add(UInt8.from(123)); - data.add(UInt8.from(23)); + byte[] data = new byte[]{123, 23}; WCCDTransfer transfer = new WCCDTransfer(tokenId, amount, from, to, data); List transfers = new ArrayList<>(); transfers.add(transfer); diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java b/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java deleted file mode 100644 index 7f0291bcb..000000000 --- a/concordium-sdk/src/main/java/com/concordium/sdk/types/UInt8.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.concordium.sdk.types; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.val; - -import java.io.IOException; - -/** - * An unsigned byte. Used in the smart contract examples to ensure proper json serialization. - */ -@EqualsAndHashCode -@Getter -@JsonSerialize(using = UInt8.UInt8Serializer.class) -public class UInt8 { - - private final int value; - - private UInt8(int value) { - this.value = value; - } - - public byte[] getBytes() { - val bytes = new byte[1]; - bytes[0] = (byte) (value); - return bytes; - } - - public static UInt8 from(String value) { - return UInt8.from(Integer.parseUnsignedInt(value)); - } - - public static UInt8 from(int value) { - if (value < 0) { - throw new NumberFormatException("Value of UInt8 cannot be negative"); - } - if (value > 255) { - throw new NumberFormatException("Value of UInt8 cannot exceed 2^8"); - } - return new UInt8(value); - } - - public static UInt8 from(byte b) { - return new UInt8(b & 0xff); - } - - @Override - public String toString() {return String.valueOf(value);} - - public static class UInt8Serializer extends JsonSerializer { - @Override - public void serialize(UInt8 uInt8, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { - jsonGenerator.writeNumber(uInt8.getValue()); - } - } -} diff --git a/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java b/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java deleted file mode 100644 index ba20c5c72..000000000 --- a/concordium-sdk/src/test/java/com/concordium/sdk/types/UInt8Test.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.concordium.sdk.types; - -import lombok.val; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class UInt8Test { - - @Test - public void testCreation() { - checkNegativeNumber(); - UInt8.from("255"); //(2^8)-1 - checkTooLargeNumber(); - } - - - private void checkNegativeNumber() { - try { - UInt8.from(-13); - fail("Should not be able to create negative UInt8"); - } catch (RuntimeException e) { - if (!e.getMessage().equals("Value of UInt8 cannot be negative")) { - fail("Unexpected error when creating negative UInt8 " + e.getMessage()); - } - } - } - - private void checkTooLargeNumber() { - try { - UInt8.from("256"); //(2^8) - fail("This should exceed the range."); - } catch (NumberFormatException e) { - if (!e.getMessage().equals("Value of UInt8 cannot exceed 2^8")) { - fail("Unexpected error when creating too big UInt8: " + e.getMessage()); - } - } - } - - @Test - public void testSerializeDeserialize() { - val expected = UInt8.from("250"); - val bytes = expected.getBytes(); - val deserialized = UInt8.from(bytes[0]); - assertEquals(expected, deserialized); - assertNotEquals(expected, UInt8.from("42")); - } - - @Test - public void testFromSignedByte() { - UInt8 from = UInt8.from((byte)-32); - assertEquals(UInt8.from(224), from); - } -} From 093846ac7b426dab685c388cde4b44e3793ba4a6 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Wed, 29 Nov 2023 15:21:19 +0100 Subject: [PATCH 47/53] Documentation cleanup --- .../test/testresources/smartcontractschema/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs index 892bf6f0a..3cbee86bc 100644 --- a/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs +++ b/concordium-sdk/src/test/testresources/smartcontractschema/lib.rs @@ -43,7 +43,7 @@ struct ContractAddressContainer { // The `ParseError` in the following result types is never thrown, as the functions only exist to generate a schema for serialization of SC parameters. -/// Takes ListParam as parameter for ensuring correct serialization of ListParam +/// Takes [`ListParam`] as parameter for ensuring correct serialization of the java class ListParam. #[receive( contract = "java_sdk_schema_unit_test", name = "list_param_test", @@ -57,7 +57,7 @@ fn list_param_test( Ok(()) } -/// Takes AddressContainer as parameter for ensuring correct serialization of Address +/// Takes [`AbstractAddressContainer`] as parameter for ensuring correct serialization of the java class AbstractAddress when used inside other parameters. #[receive( contract = "java_sdk_schema_unit_test", name = "abstract_address_container_test", @@ -71,7 +71,7 @@ fn abstract_address_container_test( Ok(()) } -/// Takes Address as parameter for ensuring correct serialization of Address when passed directly +/// Takes [`Address`] as parameter for ensuring correct serialization of the java class AbstractAddressParam for passing AbstractAddress directly as a parameter. #[receive( contract = "java_sdk_schema_unit_test", name = "abstract_address_test", @@ -85,7 +85,7 @@ fn abstract_address_test( Ok(()) } -/// Takes a ContractAddressContainer as parameter for ensuring correct serialization of ContractAddress +/// Takes a [`ContractAddressContainer`] as parameter for ensuring correct serialization of the java class ContractAddress when used inside other parameters. #[receive( contract = "java_sdk_schema_unit_test", name = "contract_address_container_test", @@ -99,7 +99,7 @@ fn contract_address_container_test( Ok(()) } -/// Takes Address as parameter for ensuring correct serialization of Address when passed directly +/// Takes [`ContractAddress`] as parameter for ensuring correct serialization of the java class ContractAddressParam for passing ContractAddress directly as a parameter. #[receive( contract = "java_sdk_schema_unit_test", name = "contract_address_test", @@ -113,7 +113,7 @@ fn contract_address_test( Ok(()) } -/// Takes an AccountAddressContainer as parameter for ensuring correct serialization of AccountAddress +/// Takes an [`AccountAddressContainer`] as parameter for ensuring correct serialization of the java class AccountAddress when used inside other parameters. #[receive( contract = "java_sdk_schema_unit_test", name = "account_address_container_test", @@ -127,7 +127,7 @@ fn account_address_container_test( Ok(()) } -/// Takes Address as parameter for ensuring correct serialization of Address when passed directly +/// Takes [`AccoountAddress`] as parameter for ensuring correct serialization of the java class AccountAddressParam for passing AccountAddress directly as a parameter. #[receive( contract = "java_sdk_schema_unit_test", name = "account_address_test", From 60ca75a90759944e4419d4de871513ea74102816 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Mon, 11 Dec 2023 11:10:07 +0100 Subject: [PATCH 48/53] Added default SchemaVersion. --- .../concordium/sdk/transactions/smartcontracts/Schema.java | 6 +++--- .../sdk/transactions/smartcontracts/SchemaVersion.java | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java index 40ac0db0e..6ddc8b0f2 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/Schema.java @@ -29,7 +29,7 @@ public class Schema { } /** - * Creates a {@link Schema} from the provided bytes and {@link SchemaVersion}. + * Creates a {@link Schema} from the provided bytes and {@link SchemaVersion}. If no version is provided, {@link SchemaVersion#DEFAULT} is used. * @param schemaBytes the bytes of the schema. * @param version the version of the schema. * @return {@link Schema} containing the provided bytes. @@ -39,9 +39,9 @@ public static Schema from(byte[] schemaBytes, SchemaVersion version) { } /** - * Creates a schema from the provided bytes. + * Creates a schema from the provided bytes. If no version is provided, {@link SchemaVersion#DEFAULT} is used. * @param schemaBytes the bytes of the schema. * @return {@link Schema} containing the provided bytes. */ - public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.UNKNOWN);} + public static Schema from(byte[] schemaBytes) {return new Schema(schemaBytes, SchemaVersion.DEFAULT);} } diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java index 5e395eadc..af663ee7f 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/transactions/smartcontracts/SchemaVersion.java @@ -14,7 +14,13 @@ public enum SchemaVersion { V3(3), UNKNOWN(-1); + /** + * The default Schema Version. Used when instantiating {@link Schema} if no specific version is provided. + */ + public static final SchemaVersion DEFAULT = V3; + private final int version; + SchemaVersion(int version) { this.version = version; } From f835238b8d96ebd82b0197ddb4d2ef0f2e482745 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Mon, 11 Dec 2023 11:14:15 +0100 Subject: [PATCH 49/53] Refactored examples to use default SchemaVersion --- .../cis2nft/Cis2NftParameters.java | 17 ++++++------ .../wccd/Cis2WCCDParameters.java | 27 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index 1cad764e0..8a76cd7dd 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -4,7 +4,6 @@ import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; import com.concordium.sdk.types.*; import lombok.SneakyThrows; @@ -31,7 +30,7 @@ public class Cis2NftParameters { */ @SneakyThrows public static SchemaParameter generateMintParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName mintParamsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "mint"); List tokens = new ArrayList<>(); tokens.add(TokenIdU32.from(2)); @@ -49,7 +48,7 @@ public static SchemaParameter generateMintParams() { */ @SneakyThrows public static SchemaParameter generateTransferParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName nftTransferReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "transfer"); TokenIdU32 tokenId = TokenIdU32.from(12); TokenAmountU8 amount = TokenAmountU8.from(1); @@ -71,7 +70,7 @@ public static SchemaParameter generateTransferParams() { */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName updateOperatorReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "updateOperator"); UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); @@ -90,7 +89,7 @@ public static SchemaParameter generateUpdateOperatorParams() { */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName operatorOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); @@ -109,7 +108,7 @@ public static SchemaParameter generateOperatorOfParams() { */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName balanceOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "balanceOf"); NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), ACCOUNT_ADDRESS); NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), CONTRACT_ADDRESS_1); @@ -128,7 +127,7 @@ public static SchemaParameter generateBalanceOfParams() { */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "tokenMetadata"); TokenIdU32 token1 = TokenIdU32.from(21); TokenIdU32 token2 = TokenIdU32.from(22); @@ -147,7 +146,7 @@ public static SchemaParameter generateTokenMetadataParams() { */ @SneakyThrows public static SchemaParameter generateSupportsParameter() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName supportsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; String standardIdentifier2 = "identifier2"; @@ -166,7 +165,7 @@ public static SchemaParameter generateSupportsParameter() { */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH)), SchemaVersion.V3); + Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); String identifier = "IdentifierID"; diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 93a1a517f..495ffafdd 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -6,7 +6,6 @@ import com.concordium.sdk.transactions.ReceiveName; import com.concordium.sdk.transactions.smartcontracts.Schema; import com.concordium.sdk.transactions.smartcontracts.SchemaParameter; -import com.concordium.sdk.transactions.smartcontracts.SchemaVersion; import com.concordium.sdk.transactions.smartcontracts.parameters.AddressParam; import com.concordium.sdk.types.AbstractAddress; import com.concordium.sdk.types.AccountAddress; @@ -38,7 +37,7 @@ public class Cis2WCCDParameters { */ @SneakyThrows public static SchemaParameter generateWrapParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); byte[] wrapData = new byte[]{1, 42}; @@ -54,7 +53,7 @@ public static SchemaParameter generateWrapParams() { */ @SneakyThrows public static SchemaParameter generateUnwrapParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); TokenAmountU64 unwrapAmount = TokenAmountU64.from(2); Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); @@ -71,7 +70,7 @@ public static SchemaParameter generateUnwrapParams() { */ @SneakyThrows public static SchemaParameter generateUpdateAdminParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName updateAdmninReceiveName = ReceiveName.from(CONTRACT_NAME, "updateAdmin"); AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, CONTRACT_ADDRESS_1); updateAdminParam.initialize(true); @@ -85,7 +84,7 @@ public static SchemaParameter generateUpdateAdminParams() { */ @SneakyThrows public static SchemaParameter generateSetPausedParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setPausedReceiveName = ReceiveName.from(CONTRACT_NAME, "setPaused"); SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); setPausedParams.initialize(true); @@ -99,7 +98,7 @@ public static SchemaParameter generateSetPausedParams() { */ @SneakyThrows public static SchemaParameter generateSetMetadataUrlParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setMetadataUrlReceiveName = ReceiveName.from(CONTRACT_NAME, "setMetadataUrl"); String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); @@ -115,7 +114,7 @@ public static SchemaParameter generateSetMetadataUrlParams() { */ @SneakyThrows public static SchemaParameter generateTransferParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName nftTransferReceiveName = ReceiveName.from(CONTRACT_NAME, "transfer"); TokenIdUnit tokenId = new TokenIdUnit(); TokenAmountU64 amount = TokenAmountU64.from(1); @@ -137,7 +136,7 @@ public static SchemaParameter generateTransferParams() { */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName updateOperatorReceiveName = ReceiveName.from(CONTRACT_NAME, "updateOperator"); UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); @@ -157,7 +156,7 @@ public static SchemaParameter generateUpdateOperatorParams() { */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName balanceOfReceiveName = ReceiveName.from(CONTRACT_NAME, "balanceOf"); WCCDBalanceOfQuery balanceOfQuery1 = new WCCDBalanceOfQuery(ACCOUNT_ADDRESS); WCCDBalanceOfQuery balanceOfQuery2 = new WCCDBalanceOfQuery(CONTRACT_ADDRESS_1); @@ -176,7 +175,7 @@ public static SchemaParameter generateBalanceOfParams() { */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName operatorOfReceiveName = ReceiveName.from(CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); @@ -195,7 +194,7 @@ public static SchemaParameter generateOperatorOfParams() { */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CONTRACT_NAME, "tokenMetadata"); TokenIdUnit token = new TokenIdUnit(); List tokensForMetadataQuery = new ArrayList<>(); @@ -212,7 +211,7 @@ public static SchemaParameter generateTokenMetadataParams() { */ @SneakyThrows public static SchemaParameter generateSupportsParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName supportsReceiveName = ReceiveName.from(CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; String standardIdentifier2 = "identifier2"; @@ -231,7 +230,7 @@ public static SchemaParameter generateSupportsParams() { */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setImplementorsReceiveName = ReceiveName.from(CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); String identifier = "IdentifierID"; @@ -249,7 +248,7 @@ public static SchemaParameter generateSetImplementorsParams() { */ @SneakyThrows public static SchemaParameter generateUpgradeParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH), SchemaVersion.V3); + Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName upgradeReceiveName = ReceiveName.from(CONTRACT_NAME, "upgrade"); ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); SchemaParameter migrate = generateWrapParams(); From 35ecdceb89748b331e73d25290f4274719d244bc Mon Sep 17 00:00:00 2001 From: magnusbechwind <93247743+magnusbechwind@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:57:42 +0100 Subject: [PATCH 50/53] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleš Bizjak --- crypto-jni/src/lib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 4eb63ce1f..7a55422ad 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -470,7 +470,7 @@ type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] -/// The JNI wrapper for serializing ia parameter for a recieve function according to a specified Schema. +/// The JNI wrapper for serializing ia parameter for a receive function according to a specified Schema. /** * `parameter` The parameter to serialize. `parameter` must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. * `contractName` The name of the contract. `contractName` must be a properly initalized `java.lang.String` that is non-null. @@ -652,8 +652,6 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI }; return SerializeParamResult::Ok(result).to_jstring(&env); - - } /** @@ -673,8 +671,7 @@ pub fn serialize_init_parameters_aux( let parameter_type = module_schema.get_init_param_schema(contractName)?; let value: serde_json::Value = from_str(parameter)?; - let res = parameter_type + parameter_type .serial_value(&value) - .map_err(|e| anyhow!("{}", e.display(verboseErrors))); - return Ok(res?); + .map_err(|e| anyhow!("{}", e.display(verboseErrors))) } \ No newline at end of file From f7c2cb28a0cc344e8310a6521767027589198868 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Tue, 12 Dec 2023 10:58:28 +0100 Subject: [PATCH 51/53] Refactored examples --- .../cis2nft/Cis2NftParameters.java | 36 +++++++------ .../wccd/Cis2WCCDParameters.java | 51 +++++++++---------- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java index 8a76cd7dd..00f0f1360 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/Cis2NftParameters.java @@ -7,6 +7,7 @@ import com.concordium.sdk.types.*; import lombok.SneakyThrows; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -23,6 +24,17 @@ public class Cis2NftParameters { private static final String CIS_2_NFT_CONTRACT_NAME = "cis2_nft"; private static final String SCHEMA_PATH = "./src/main/java/com/concordium/sdk/examples/contractexample/cis2nft/cis2-nft.schema.bin"; + + private static final Schema SCHEMA; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * Generates and initializes {@link MintParams} for the 'mint' method of a cis2-nft contract. * @@ -30,13 +42,12 @@ public class Cis2NftParameters { */ @SneakyThrows public static SchemaParameter generateMintParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName mintParamsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "mint"); List tokens = new ArrayList<>(); tokens.add(TokenIdU32.from(2)); tokens.add(TokenIdU32.from(22)); tokens.add(TokenIdU32.from(2132)); - SchemaParameter mintParameter = new MintParams(schema, mintParamsReceiveName, ACCOUNT_ADDRESS, tokens); + SchemaParameter mintParameter = new MintParams(SCHEMA, mintParamsReceiveName, ACCOUNT_ADDRESS, tokens); mintParameter.initialize(true); return mintParameter; } @@ -48,7 +59,6 @@ public static SchemaParameter generateMintParams() { */ @SneakyThrows public static SchemaParameter generateTransferParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName nftTransferReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "transfer"); TokenIdU32 tokenId = TokenIdU32.from(12); TokenAmountU8 amount = TokenAmountU8.from(1); @@ -58,7 +68,7 @@ public static SchemaParameter generateTransferParams() { NftTransfer transfer = new NftTransfer(tokenId, amount, from, to, data); List transfers = new ArrayList<>(); transfers.add(transfer); - SchemaParameter transferParameter = new NftTransferParam(schema, nftTransferReceiveName, transfers); + SchemaParameter transferParameter = new NftTransferParam(SCHEMA, nftTransferReceiveName, transfers); transferParameter.initialize(true); return transferParameter; } @@ -70,14 +80,13 @@ public static SchemaParameter generateTransferParams() { */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName updateOperatorReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "updateOperator"); UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); List updateOperatorList = new ArrayList<>(); updateOperatorList.add(update1); updateOperatorList.add(update2); - SchemaParameter updateOperatorsParams = new UpdateOperatorParams(schema, updateOperatorReceiveName, updateOperatorList); + SchemaParameter updateOperatorsParams = new UpdateOperatorParams(SCHEMA, updateOperatorReceiveName, updateOperatorList); updateOperatorsParams.initialize(true); return updateOperatorsParams; } @@ -89,14 +98,13 @@ public static SchemaParameter generateUpdateOperatorParams() { */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName operatorOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); List operatorOfQueries = new ArrayList<>(); operatorOfQueries.add(operatorOfQuery1); operatorOfQueries.add(operatorOfQuery2); - SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(schema, operatorOfReceiveName, operatorOfQueries); + SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(SCHEMA, operatorOfReceiveName, operatorOfQueries); operatorOfQueryParams.initialize(true); return operatorOfQueryParams; } @@ -108,14 +116,13 @@ public static SchemaParameter generateOperatorOfParams() { */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName balanceOfReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "balanceOf"); NftBalanceOfQuery balanceOfQuery1 = new NftBalanceOfQuery(TokenIdU32.from(22222), ACCOUNT_ADDRESS); NftBalanceOfQuery balanceOfQuery2 = new NftBalanceOfQuery(TokenIdU32.from(42), CONTRACT_ADDRESS_1); List balanceOfQueries = new ArrayList<>(); balanceOfQueries.add(balanceOfQuery1); balanceOfQueries.add(balanceOfQuery2); - SchemaParameter contractBalanceOfQueryParams = new NftBalanceOfQueryParams(schema, balanceOfReceiveName, balanceOfQueries); + SchemaParameter contractBalanceOfQueryParams = new NftBalanceOfQueryParams(SCHEMA, balanceOfReceiveName, balanceOfQueries); contractBalanceOfQueryParams.initialize(true); return contractBalanceOfQueryParams; } @@ -127,14 +134,13 @@ public static SchemaParameter generateBalanceOfParams() { */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "tokenMetadata"); TokenIdU32 token1 = TokenIdU32.from(21); TokenIdU32 token2 = TokenIdU32.from(22); List tokensForMetadataQuery = new ArrayList<>(); tokensForMetadataQuery.add(token1); tokensForMetadataQuery.add(token2); - SchemaParameter nftMetaDataQuery = new NftTokenMetaDataQueryParams(schema, tokenMetadataReceiveName, tokensForMetadataQuery); + SchemaParameter nftMetaDataQuery = new NftTokenMetaDataQueryParams(SCHEMA, tokenMetadataReceiveName, tokensForMetadataQuery); nftMetaDataQuery.initialize(true); return nftMetaDataQuery; } @@ -146,14 +152,13 @@ public static SchemaParameter generateTokenMetadataParams() { */ @SneakyThrows public static SchemaParameter generateSupportsParameter() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName supportsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; String standardIdentifier2 = "identifier2"; List identifiers = new ArrayList<>(); identifiers.add(standardIdentifier1); identifiers.add(standardIdentifier2); - SchemaParameter supportsQueryParams = new SupportsQueryParams(schema, supportsReceiveName, identifiers); + SchemaParameter supportsQueryParams = new SupportsQueryParams(SCHEMA, supportsReceiveName, identifiers); supportsQueryParams.initialize(true); return supportsQueryParams; } @@ -165,13 +170,12 @@ public static SchemaParameter generateSupportsParameter() { */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { - Schema schema = Schema.from(Files.readAllBytes(Paths.get(SCHEMA_PATH))); ReceiveName setImplementorsReceiveName = ReceiveName.from(CIS_2_NFT_CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); String identifier = "IdentifierID"; implementors.add(CONTRACT_ADDRESS_1); implementors.add(CONTRACT_ADDRESS_2); - SchemaParameter setImplementorsParams = new SetImplementorsParams(schema, setImplementorsReceiveName, identifier, implementors); + SchemaParameter setImplementorsParams = new SetImplementorsParams(SCHEMA, setImplementorsReceiveName, identifier, implementors); setImplementorsParams.initialize(); return setImplementorsParams; } diff --git a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java index 495ffafdd..d6ff41295 100644 --- a/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java +++ b/concordium-sdk-examples/src/main/java/com/concordium/sdk/examples/contractexample/wccd/Cis2WCCDParameters.java @@ -12,6 +12,7 @@ import com.concordium.sdk.types.ContractAddress; import lombok.SneakyThrows; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -30,6 +31,16 @@ public class Cis2WCCDParameters { private static final String CONTRACT_NAME = "cis2_wCCD"; private static final Path SCHEMA_PATH = Paths.get("./src/main/java/com/concordium/sdk/examples/contractexample/wccd/cis2-wccd.schema.bin"); + private static final Schema SCHEMA; + + static { + try { + SCHEMA = Schema.from(Files.readAllBytes(SCHEMA_PATH)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * Generates and initializes {@link WrapParams} for the 'wrap' method of a cis2-wCCD contract. * @@ -37,11 +48,10 @@ public class Cis2WCCDParameters { */ @SneakyThrows public static SchemaParameter generateWrapParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName wrapReceiveName = ReceiveName.from(CONTRACT_NAME, "wrap"); Receiver wrapReceiver = new Receiver(ACCOUNT_ADDRESS); byte[] wrapData = new byte[]{1, 42}; - WrapParams wrapParams = new WrapParams(cis2wccdSchema, wrapReceiveName, wrapReceiver, wrapData); + WrapParams wrapParams = new WrapParams(SCHEMA, wrapReceiveName, wrapReceiver, wrapData); wrapParams.initialize(true); return wrapParams; } @@ -53,12 +63,11 @@ public static SchemaParameter generateWrapParams() { */ @SneakyThrows public static SchemaParameter generateUnwrapParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName unwrapReceiveName = ReceiveName.from(CONTRACT_NAME, "unwrap"); TokenAmountU64 unwrapAmount = TokenAmountU64.from(2); Receiver unwrapReceiver = new Receiver(CONTRACT_ADDRESS_2, "test"); byte[] unwrapData = new byte[]{1, 42}; - UnwrapParams unwrapParams = new UnwrapParams(cis2wccdSchema, unwrapReceiveName, unwrapAmount, ACCOUNT_ADDRESS, unwrapReceiver, unwrapData); + UnwrapParams unwrapParams = new UnwrapParams(SCHEMA, unwrapReceiveName, unwrapAmount, ACCOUNT_ADDRESS, unwrapReceiver, unwrapData); unwrapParams.initialize(true); return unwrapParams; } @@ -70,9 +79,8 @@ public static SchemaParameter generateUnwrapParams() { */ @SneakyThrows public static SchemaParameter generateUpdateAdminParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName updateAdmninReceiveName = ReceiveName.from(CONTRACT_NAME, "updateAdmin"); - AddressParam updateAdminParam = new AddressParam(cis2wccdSchema, updateAdmninReceiveName, CONTRACT_ADDRESS_1); + AddressParam updateAdminParam = new AddressParam(SCHEMA, updateAdmninReceiveName, CONTRACT_ADDRESS_1); updateAdminParam.initialize(true); return updateAdminParam; } @@ -84,9 +92,8 @@ public static SchemaParameter generateUpdateAdminParams() { */ @SneakyThrows public static SchemaParameter generateSetPausedParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setPausedReceiveName = ReceiveName.from(CONTRACT_NAME, "setPaused"); - SetPausedParams setPausedParams = new SetPausedParams(cis2wccdSchema, setPausedReceiveName, true); + SetPausedParams setPausedParams = new SetPausedParams(SCHEMA, setPausedReceiveName, true); setPausedParams.initialize(true); return setPausedParams; } @@ -98,11 +105,10 @@ public static SchemaParameter generateSetPausedParams() { */ @SneakyThrows public static SchemaParameter generateSetMetadataUrlParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setMetadataUrlReceiveName = ReceiveName.from(CONTRACT_NAME, "setMetadataUrl"); String metadataUrl = "https://github.com/Concordium/concordium-contracts-common/blob/9d1f254e52a6bc730e4f8d92e353096cebe02f0a/concordium-contracts-common/src/types.rs"; Hash hash = Hash.from("688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"); - SetMetadataUrlParams setMetadataUrlParams = new SetMetadataUrlParams(cis2wccdSchema, setMetadataUrlReceiveName, metadataUrl, Optional.of(hash)); + SetMetadataUrlParams setMetadataUrlParams = new SetMetadataUrlParams(SCHEMA, setMetadataUrlReceiveName, metadataUrl, Optional.of(hash)); setMetadataUrlParams.initialize(true); return setMetadataUrlParams; } @@ -114,7 +120,6 @@ public static SchemaParameter generateSetMetadataUrlParams() { */ @SneakyThrows public static SchemaParameter generateTransferParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName nftTransferReceiveName = ReceiveName.from(CONTRACT_NAME, "transfer"); TokenIdUnit tokenId = new TokenIdUnit(); TokenAmountU64 amount = TokenAmountU64.from(1); @@ -124,7 +129,7 @@ public static SchemaParameter generateTransferParams() { WCCDTransfer transfer = new WCCDTransfer(tokenId, amount, from, to, data); List transfers = new ArrayList<>(); transfers.add(transfer); - SchemaParameter transferParameter = new WCCDTransferParam(cis2wccdSchema, nftTransferReceiveName, transfers); + SchemaParameter transferParameter = new WCCDTransferParam(SCHEMA, nftTransferReceiveName, transfers); transferParameter.initialize(true); return transferParameter; } @@ -136,14 +141,13 @@ public static SchemaParameter generateTransferParams() { */ @SneakyThrows public static SchemaParameter generateUpdateOperatorParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName updateOperatorReceiveName = ReceiveName.from(CONTRACT_NAME, "updateOperator"); UpdateOperator update1 = new UpdateOperator(UpdateOperator.OperatorUpdate.ADD, ACCOUNT_ADDRESS); UpdateOperator update2 = new UpdateOperator(UpdateOperator.OperatorUpdate.REMOVE, CONTRACT_ADDRESS_1); List updateOperatorList = new ArrayList<>(); updateOperatorList.add(update1); updateOperatorList.add(update2); - SchemaParameter updateOperatorsParams = new UpdateOperatorParams(cis2wccdSchema, updateOperatorReceiveName, updateOperatorList); + SchemaParameter updateOperatorsParams = new UpdateOperatorParams(SCHEMA, updateOperatorReceiveName, updateOperatorList); updateOperatorsParams.initialize(true); return updateOperatorsParams; @@ -156,14 +160,13 @@ public static SchemaParameter generateUpdateOperatorParams() { */ @SneakyThrows public static SchemaParameter generateBalanceOfParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName balanceOfReceiveName = ReceiveName.from(CONTRACT_NAME, "balanceOf"); WCCDBalanceOfQuery balanceOfQuery1 = new WCCDBalanceOfQuery(ACCOUNT_ADDRESS); WCCDBalanceOfQuery balanceOfQuery2 = new WCCDBalanceOfQuery(CONTRACT_ADDRESS_1); List balanceOfQueries = new ArrayList<>(); balanceOfQueries.add(balanceOfQuery1); balanceOfQueries.add(balanceOfQuery2); - SchemaParameter contractBalanceOfQueryParams = new WCCDBalanceOfQueryParams(cis2wccdSchema, balanceOfReceiveName, balanceOfQueries); + SchemaParameter contractBalanceOfQueryParams = new WCCDBalanceOfQueryParams(SCHEMA, balanceOfReceiveName, balanceOfQueries); contractBalanceOfQueryParams.initialize(true); return contractBalanceOfQueryParams; } @@ -175,14 +178,13 @@ public static SchemaParameter generateBalanceOfParams() { */ @SneakyThrows public static SchemaParameter generateOperatorOfParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName operatorOfReceiveName = ReceiveName.from(CONTRACT_NAME, "operatorOf"); OperatorOfQuery operatorOfQuery1 = new OperatorOfQuery(ACCOUNT_ADDRESS, CONTRACT_ADDRESS_1); OperatorOfQuery operatorOfQuery2 = new OperatorOfQuery(CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2); List operatorOfQueries = new ArrayList<>(); operatorOfQueries.add(operatorOfQuery1); operatorOfQueries.add(operatorOfQuery2); - SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(cis2wccdSchema, operatorOfReceiveName, operatorOfQueries); + SchemaParameter operatorOfQueryParams = new OperatorOfQueryParams(SCHEMA, operatorOfReceiveName, operatorOfQueries); operatorOfQueryParams.initialize(true); return operatorOfQueryParams; } @@ -194,12 +196,11 @@ public static SchemaParameter generateOperatorOfParams() { */ @SneakyThrows public static SchemaParameter generateTokenMetadataParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName tokenMetadataReceiveName = ReceiveName.from(CONTRACT_NAME, "tokenMetadata"); TokenIdUnit token = new TokenIdUnit(); List tokensForMetadataQuery = new ArrayList<>(); tokensForMetadataQuery.add(token); - SchemaParameter wccdMetadataQuery = new WCCDTokenMetadataQueryParams(cis2wccdSchema, tokenMetadataReceiveName, tokensForMetadataQuery); + SchemaParameter wccdMetadataQuery = new WCCDTokenMetadataQueryParams(SCHEMA, tokenMetadataReceiveName, tokensForMetadataQuery); wccdMetadataQuery.initialize(true); return wccdMetadataQuery; } @@ -211,14 +212,13 @@ public static SchemaParameter generateTokenMetadataParams() { */ @SneakyThrows public static SchemaParameter generateSupportsParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName supportsReceiveName = ReceiveName.from(CONTRACT_NAME, "supports"); String standardIdentifier1 = "identifier1"; String standardIdentifier2 = "identifier2"; List identifiers = new ArrayList<>(); identifiers.add(standardIdentifier1); identifiers.add(standardIdentifier2); - SchemaParameter supportsQueryParams = new SupportsQueryParams(cis2wccdSchema, supportsReceiveName, identifiers); + SchemaParameter supportsQueryParams = new SupportsQueryParams(SCHEMA, supportsReceiveName, identifiers); supportsQueryParams.initialize(true); return supportsQueryParams; } @@ -230,13 +230,12 @@ public static SchemaParameter generateSupportsParams() { */ @SneakyThrows public static SchemaParameter generateSetImplementorsParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName setImplementorsReceiveName = ReceiveName.from(CONTRACT_NAME, "setImplementors"); List implementors = new ArrayList<>(); String identifier = "IdentifierID"; implementors.add(CONTRACT_ADDRESS_1); implementors.add(CONTRACT_ADDRESS_2); - SchemaParameter setImplementorsParams = new SetImplementorsParams(cis2wccdSchema, setImplementorsReceiveName, identifier, implementors); + SchemaParameter setImplementorsParams = new SetImplementorsParams(SCHEMA, setImplementorsReceiveName, identifier, implementors); setImplementorsParams.initialize(); return setImplementorsParams; } @@ -248,13 +247,11 @@ public static SchemaParameter generateSetImplementorsParams() { */ @SneakyThrows public static SchemaParameter generateUpgradeParams() { - Schema cis2wccdSchema = Schema.from(Files.readAllBytes(SCHEMA_PATH)); ReceiveName upgradeReceiveName = ReceiveName.from(CONTRACT_NAME, "upgrade"); ModuleRef upgradeModuleRef = ModuleRef.from("67d568433bd72e4326241f262213d77f446db8ba03dfba351ae35c1b2e7e5109"); SchemaParameter migrate = generateWrapParams(); - SchemaParameter upgradeParams = new UpgradeParams(cis2wccdSchema, upgradeReceiveName, upgradeModuleRef, migrate); + SchemaParameter upgradeParams = new UpgradeParams(SCHEMA, upgradeReceiveName, upgradeModuleRef, migrate); upgradeParams.initialize(true); return upgradeParams; } - } From 0f7f6f5c4f57a46dba8db3cd4551801b96ddaa5f Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Tue, 12 Dec 2023 12:48:27 +0100 Subject: [PATCH 52/53] Cleanup of rust bindings --- .../sdk/exceptions/JNIErrorType.java | 8 +- crypto-jni/src/lib.rs | 240 +++++++++--------- 2 files changed, 119 insertions(+), 129 deletions(-) diff --git a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java index eddcc3433..1e70967e3 100644 --- a/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java +++ b/concordium-sdk/src/main/java/com/concordium/sdk/exceptions/JNIErrorType.java @@ -6,14 +6,14 @@ * Represents the different types of possible errors when performing operations using the JNI. Should match the errors defined in the rust code in crypto-jni. */ public enum JNIErrorType { - @JsonProperty("ParameterSerializationError") + @JsonProperty("ParameterSerialization") PARAMETER_SERIALIZATION_ERROR, @JsonProperty("Utf8DecodeError") UTF8_DECODE_ERROR, - @JsonProperty("JsonDeserializationError") + @JsonProperty("JsonDeserialization") JSON_DESERIALIZATION_ERROR , - @JsonProperty("NativeConversionError") + @JsonProperty("NativeConversion") NATIVE_CONVERSION_ERROR, - @JsonProperty("PayloadCreationError") + @JsonProperty("PayloadCreation") PAYLOAD_CREATION_ERROR } diff --git a/crypto-jni/src/lib.rs b/crypto-jni/src/lib.rs index 7a55422ad..06e5f212d 100644 --- a/crypto-jni/src/lib.rs +++ b/crypto-jni/src/lib.rs @@ -1,34 +1,33 @@ +use anyhow::{anyhow, Result}; pub use concordium_base::common::types::{AccountAddress, ACCOUNT_ADDRESS_SIZE}; -use concordium_base::common::Serialize; -use concordium_base::contracts_common::{Amount, schema::VersionedModuleSchema}; -use concordium_base::encrypted_transfers; -use concordium_base::encrypted_transfers::types::{ - AggregatedDecryptedAmount, EncryptedAmount, EncryptedAmountTransferData, - IndexedEncryptedAmount, SecToPubAmountTransferData, -}; -use concordium_base::id; -use concordium_base::id::curve_arithmetic::Curve; -use concordium_base::id::elgamal; -use concordium_base::id::{constants::ArCurve, types::GlobalContext}; -use concordium_base::transactions::{ - AddBakerKeysMarker, BakerKeysPayload, ConfigureBakerKeysPayload, +use concordium_base::{ + base, + common::{Serialize, *}, + contracts_common::{schema::VersionedModuleSchema, Amount}, + encrypted_transfers, + encrypted_transfers::types::{ + AggregatedDecryptedAmount, EncryptedAmount, EncryptedAmountTransferData, + IndexedEncryptedAmount, SecToPubAmountTransferData, + }, + id, + id::{constants::ArCurve, curve_arithmetic::Curve, elgamal, types::GlobalContext}, + transactions::{AddBakerKeysMarker, BakerKeysPayload, ConfigureBakerKeysPayload}, }; -use concordium_base::{base, common::*}; use core::slice; use ed25519_dalek::*; -use jni::sys::{jstring, jboolean, JNI_FALSE}; -use rand::thread_rng; -use serde_json::{from_str, to_string}; -use std::convert::{From, TryFrom}; -use std::i8; -use std::str::Utf8Error; -use hex; + use jni::{ objects::{JClass, JString}, - sys::{jbyteArray, jint}, + sys::{jboolean, jbyteArray, jint, jstring, JNI_FALSE}, JNIEnv, }; -use anyhow::{anyhow, Result}; +use rand::thread_rng; +use serde_json::{from_str, to_string}; +use std::{ + convert::{From, TryFrom}, + i8, + str::Utf8Error, +}; const SUCCESS: i32 = 0; const NATIVE_CONVERSION_ERROR: i32 = 1; @@ -186,26 +185,24 @@ enum CryptoJniResult { #[derive(SerdeSerialize, SerdeDeserialize)] #[allow(non_snake_case)] enum JNIErrorResponseType { - ParameterSerializationError, - Utf8DecodeError, - JsonDeserializationError, - NativeConversionError, - PayloadCreationError, + ParameterSerialization, + Utf8Decode, + JsonDeserialization, + NativeConversion, + PayloadCreation, } - #[derive(SerdeSerialize, SerdeDeserialize)] #[allow(non_snake_case)] struct JNIErrorResponse { - errorType: JNIErrorResponseType, + errorType: JNIErrorResponseType, errorMessage: String, - } impl From for CryptoJniResult { fn from(e: serde_json::Error) -> Self { let error = JNIErrorResponse { - errorType: JNIErrorResponseType::JsonDeserializationError, + errorType: JNIErrorResponseType::JsonDeserialization, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -215,7 +212,7 @@ impl From for CryptoJniResult { impl From for CryptoJniResult { fn from(e: Utf8Error) -> Self { let error = JNIErrorResponse { - errorType: JNIErrorResponseType::Utf8DecodeError, + errorType: JNIErrorResponseType::Utf8Decode, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -225,21 +222,19 @@ impl From for CryptoJniResult { impl From for CryptoJniResult { fn from(e: jni::errors::Error) -> Self { let error = JNIErrorResponse { - errorType: JNIErrorResponseType::NativeConversionError, + errorType: JNIErrorResponseType::NativeConversion, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) } } -/** - * Creates errors from strings. - * Used when payload creation fails as no error to be passed on is generated. - */ +/// Creates errors from strings. Used when payload creation fails as no error to +/// be passed on is generated. impl From<&str> for CryptoJniResult { fn from(e: &str) -> Self { let error = JNIErrorResponse { - errorType: JNIErrorResponseType::PayloadCreationError, + errorType: JNIErrorResponseType::PayloadCreation, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -249,7 +244,7 @@ impl From<&str> for CryptoJniResult { impl From for CryptoJniResult { fn from(e: anyhow::Error) -> Self { let error = JNIErrorResponse { - errorType: JNIErrorResponseType::ParameterSerializationError, + errorType: JNIErrorResponseType::ParameterSerialization, errorMessage: e.to_string(), }; CryptoJniResult::Err(error) @@ -288,9 +283,9 @@ fn decrypt_encrypted_amount( #[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))] #[serde(rename_all = "camelCase")] struct JniInput { - global: GlobalContext, - amount: Amount, - sender_secret_key: elgamal::SecretKey, + global: GlobalContext, + amount: Amount, + sender_secret_key: elgamal::SecretKey, input_encrypted_amount: IndexedEncryptedAmount, } @@ -323,15 +318,15 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT input.sender_secret_key.clone(), ) { CryptoJniResult::Ok(amount) => amount, - CryptoJniResult::Err(err) => return EncryptedTransferResult::Err(err).to_jstring(&env) + CryptoJniResult::Err(err) => return EncryptedTransferResult::Err(err).to_jstring(&env), }; let input_amount: AggregatedDecryptedAmount = AggregatedDecryptedAmount { agg_encrypted_amount: input.input_encrypted_amount.encrypted_chunks, - agg_index: encrypted_transfers::types::EncryptedAmountAggIndex { + agg_index: encrypted_transfers::types::EncryptedAmountAggIndex { index: input.input_encrypted_amount.index.index, }, - agg_amount: decrypted_amount, + agg_amount: decrypted_amount, }; let mut csprng = thread_rng(); @@ -346,8 +341,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT match payload { Some(payload) => CryptoJniResult::Ok(payload).to_jstring(&env), - None => - return EncryptedTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env) + None => EncryptedTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env), } } @@ -355,10 +349,10 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_createSecT #[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))] #[serde(rename_all = "camelCase")] struct TransferJniInput { - global: GlobalContext, - receiver_public_key: elgamal::PublicKey, - sender_secret_key: elgamal::SecretKey, - amount_to_send: Amount, + global: GlobalContext, + receiver_public_key: elgamal::PublicKey, + sender_secret_key: elgamal::SecretKey, + amount_to_send: Amount, input_encrypted_amount: IndexedEncryptedAmount, } @@ -391,15 +385,17 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateEn input.sender_secret_key.clone(), ) { CryptoJniResult::Ok(amount) => amount, - CryptoJniResult::Err(err) => return EncryptedAmountTransferResult::Err(err).to_jstring(&env), + CryptoJniResult::Err(err) => { + return EncryptedAmountTransferResult::Err(err).to_jstring(&env) + } }; let input_amount: AggregatedDecryptedAmount = AggregatedDecryptedAmount { agg_encrypted_amount: input.input_encrypted_amount.encrypted_chunks, - agg_index: encrypted_transfers::types::EncryptedAmountAggIndex { + agg_index: encrypted_transfers::types::EncryptedAmountAggIndex { index: input.input_encrypted_amount.index.index, }, - agg_amount: decrypted_amount, + agg_amount: decrypted_amount, }; let mut csprng = thread_rng(); @@ -415,7 +411,7 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateEn match payload { Some(payload) => CryptoJniResult::Ok(payload).to_jstring(&env), - None => return EncryptedAmountTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env) + None => EncryptedAmountTransferResult::from(PAYLOAD_CREATION_ERROR).to_jstring(&env), } } @@ -427,14 +423,14 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateBa ) -> jstring { let mut csprng = thread_rng(); let payload = base::BakerKeyPairs::generate(&mut csprng); - return CryptoJniResult::Ok(payload).to_jstring(&env); + CryptoJniResult::Ok(payload).to_jstring(&env) } #[derive(Serialize, SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] struct AddBakerPayloadInput { pub sender: AccountAddress, - pub keys: base::BakerKeyPairs, + pub keys: base::BakerKeyPairs, } type AddBakerResult = CryptoJniResult>; @@ -463,26 +459,35 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_generateCo let payload = ConfigureBakerKeysPayload::new(&input.keys, input.sender, &mut csprng); - return CryptoJniResult::Ok(payload).to_jstring(&env); + CryptoJniResult::Ok(payload).to_jstring(&env) } type SerializeParamResult = CryptoJniResult; #[no_mangle] #[allow(non_snake_case)] -/// The JNI wrapper for serializing ia parameter for a receive function according to a specified Schema. -/** - * `parameter` The parameter to serialize. `parameter` must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. - * `contractName` The name of the contract. `contractName` must be a properly initalized `java.lang.String` that is non-null. - * `methodName` The name of the method. `methodName` must be a properly initalized `java.lang.String` that is non-null. - * `schemaBytes` The bytes of the schema. `schemaBytes` must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. - * `schemaVersion` The version of the Schema. `schemaVersion` must be an integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. - * `verboseErrors` Whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. - */ -/// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. -/** - * Returns a SerializeParamResult containg the hex encoded serialized parameter. - */ +/// The JNI wrapper for serializing ia parameter for a receive function +/// according to a specified Schema. Returns a SerializeParamResult containg the +/// hex encoded serialized parameter. +/// +/// - `parameter` is the parameter to serialize and must be a properly +/// initalized `java.lang.String` that is non-null. The parameter must be +/// valid JSON according to the provided schema. +/// - `contractName` is the name of the contract and must be a properly +/// initalized `java.lang.String` that is non-null. +/// - `methodName` is the name of the method and must be a properly initalized +/// `java.lang.String` that is non-null. +/// - `schemaBytes` is the bytes of the schema and must be a properly initalized +/// `byte[]` containing bytes representing a valid schema. The schema must +/// match the provided `contractName`. +/// - `schemaVersion` is the version of the Schema and must be an integer +/// representing a valid +/// `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. +/// - `verboseErrors`, whether errors are returned in verbose format or not, can +/// be useful when debugging why serialization fails. +/// +/// If serialization fails returns a SerializeParamResult containing a JNIError +/// detailing what went wrong. pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeReceiveParameter( env: JNIEnv, _: JClass, @@ -493,13 +498,11 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeR schemaVersion: jint, verboseErrors: jboolean, ) -> jstring { - let schema = match env.convert_byte_array(schemaBytes) { Ok(x) => x, Err(err) => return SerializeParamResult::from(err).to_jstring(&env), }; - let parameter: String = match env.get_string(parameter) { Ok(java_str) => match java_str.to_str() { Ok(rust_str) => String::from(rust_str), @@ -535,63 +538,62 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeR let verboseErrors = verboseErrors != JNI_FALSE; let serializedParameter = serialize_receive_contract_parameters_aux( - ¶meter, - &contractName, - &methodName, - &schema, + ¶meter, + &contractName, + &methodName, + &schema, version, - verboseErrors + verboseErrors, ); - let result = match serializedParameter { Ok(serializedParameter) => hex::encode(serializedParameter), Err(err) => return SerializeParamResult::from(err).to_jstring(&env), - }; - return SerializeParamResult::Ok(result).to_jstring(&env); - - + SerializeParamResult::Ok(result).to_jstring(&env) } - #[allow(non_snake_case)] -/** - * Helper method for serialize_receive_parameters. - * Performs the actual serialization. - */ +/// Helper method for serialize_receive_parameters. Performs the actual +/// serialization. pub fn serialize_receive_contract_parameters_aux( parameter: &str, contractName: &str, methodName: &str, - schemaBytes: &Vec, + schemaBytes: &[u8], schemaVersion: Option, verboseErrors: bool, ) -> Result> { - let module_schema = VersionedModuleSchema::new(schemaBytes, &schemaVersion)?; let parameter_type = module_schema.get_receive_param_schema(contractName, methodName)?; let value: serde_json::Value = from_str(parameter)?; - let res = parameter_type + parameter_type .serial_value(&value) - .map_err(|e| anyhow!("{}", e.display(verboseErrors))); - return Ok(res?); + .map_err(|e| anyhow!("{}", e.display(verboseErrors))) } -/// The JNI wrapper for serializing a parameter for an init function according to a specified Schema. -/** - * `parameter` The parameter to serialize. `parameter` must be a properly initalized `java.lang.String` that is non-null. The parameter must be valid JSON according to the provided schema. - * `contractName` The name of the contract. `contractName` must be a properly initalized `java.lang.String` that is non-null. - * `schemaBytes` The bytes of the schema. `schemaBytes` must be a properly initalized `byte[]` containing bytes representing a valid schema. The schema must match the provided `contractName`. - * `schemaVersion` The version of the Schema. `schemaVersion` must be an integer representing a valid `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. - * `verboseErrors` Whether errors are returned in verbose format or not, can be useful when debugging why serialization fails. - */ -/// If serialization fails returns a SerializeParamResult containing a JNIError detailing what went wrong. -/** - * Returns a SerializeParamResult containg the hex encoded serialized parameter. - */ +/// The JNI wrapper for serializing a parameter for an init function according +/// to a specified Schema. Returns a SerializeParamResult containg the hex +/// encoded serialized parameter. +/// +/// - `parameter` is the parameter to serialize and must be a properly +/// initalized `java.lang.String` that is non-null. The parameter must be +/// valid JSON according to the provided schema. +/// - `contractName` is the name of the contract and must be a properly +/// initalized `java.lang.String` that is non-null. +/// - `schemaBytes` is the bytes of the schema and must be a properly initalized +/// `byte[]` containing bytes representing a valid schema. The schema must +/// match the provided `contractName`. +/// - `schemaVersion` is the version of the Schema and must be an integer +/// representing a valid +/// `com.concordium.sdk.transactions.smartcontracts.SchemaVersion`. +/// - `verboseErrors`, whether errors are returned in verbose format or not, can +/// be useful when debugging why serialization fails. +/// +/// If serialization fails returns a SerializeParamResult containing a JNIError +/// detailing what went wrong. #[no_mangle] #[allow(non_snake_case)] pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeInitParameter( @@ -603,13 +605,11 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI schemaVersion: jint, verboseErrors: jboolean, ) -> jstring { - let schema = match env.convert_byte_array(schemaBytes) { Ok(x) => x, Err(err) => return SerializeParamResult::from(err).to_jstring(&env), }; - let parameter: String = match env.get_string(parameter) { Ok(java_str) => match java_str.to_str() { Ok(rust_str) => String::from(rust_str), @@ -636,37 +636,27 @@ pub extern "system" fn Java_com_concordium_sdk_crypto_CryptoJniNative_serializeI let verboseErrors = verboseErrors != JNI_FALSE; - let serializedParameter = serialize_init_parameters_aux( - ¶meter, - &contractName, - &schema, - version, - verboseErrors - ); - + let serializedParameter = + serialize_init_parameters_aux(¶meter, &contractName, &schema, version, verboseErrors); let result = match serializedParameter { Ok(serializedParameter) => hex::encode(serializedParameter), Err(err) => return SerializeParamResult::from(err).to_jstring(&env), - }; - return SerializeParamResult::Ok(result).to_jstring(&env); + SerializeParamResult::Ok(result).to_jstring(&env) } -/** - * Helper method for serialize_init_parameters. - * Performs the actual serialization. - */ +/// Helper method for serialize_init_parameters. Performs the actual +/// serialization. #[allow(non_snake_case)] pub fn serialize_init_parameters_aux( parameter: &str, contractName: &str, - schemaBytes: &Vec, + schemaBytes: &[u8], schemaVersion: Option, verboseErrors: bool, ) -> Result> { - let module_schema = VersionedModuleSchema::new(schemaBytes, &schemaVersion)?; let parameter_type = module_schema.get_init_param_schema(contractName)?; let value: serde_json::Value = from_str(parameter)?; @@ -674,4 +664,4 @@ pub fn serialize_init_parameters_aux( parameter_type .serial_value(&value) .map_err(|e| anyhow!("{}", e.display(verboseErrors))) -} \ No newline at end of file +} From c409ba0286021311b6c910fa3b9afefdc945cac6 Mon Sep 17 00:00:00 2001 From: magnusbechwind Date: Tue, 12 Dec 2023 12:54:33 +0100 Subject: [PATCH 53/53] Added rustfmt to crypto-native --- crypto-jni/rustfmt.toml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 crypto-jni/rustfmt.toml diff --git a/crypto-jni/rustfmt.toml b/crypto-jni/rustfmt.toml new file mode 100644 index 000000000..c01b534a6 --- /dev/null +++ b/crypto-jni/rustfmt.toml @@ -0,0 +1,21 @@ +edition="2018" +combine_control_expr = false +wrap_comments = true +brace_style = "PreferSameLine" +enum_discrim_align_threshold = 20 +fn_single_line = true +format_strings = true +format_macro_matchers = true +format_macro_bodies = true +imports_granularity = "Crate" +normalize_comments = true +reorder_impl_items = true +reorder_imports = true +struct_field_align_threshold = 20 +trailing_semicolon = true +type_punctuation_density = "Wide" +use_field_init_shorthand = true +use_try_shorthand = true +format_code_in_doc_comments = true +overflow_delimited_expr = true +normalize_doc_attributes = true \ No newline at end of file