diff --git a/developers/fundamentals/avm-concepts/initializable-fields.md b/developers/fundamentals/avm-concepts/initializable-fields.md index 6e900b89..32366195 100644 --- a/developers/fundamentals/avm-concepts/initializable-fields.md +++ b/developers/fundamentals/avm-concepts/initializable-fields.md @@ -1,20 +1,14 @@ --- title: Initializable Fields -description: A static field can be labelled @Initializable if it should be initialized through a deployment argument. +description: When deploying a contract, you can specify certain variables to be initialized during the deployment. This allows you to specify things like environment variables during the deploying of a contract, without having to hardcode them into the contract itself. table_of_contents: true --- -> **Important:** -> -> - An `@Initializable` field must be static. -> - The type of an `@Initializable` field must be a supported [AVM ABI type](/developers/fundamentals/avm-concepts/abi-types/). -> - Data supplied in the data field must be supplied in the exact same order as the `@Initializable` field are defined. If not, an _ABIException_ will be thrown. +When a contract is deployed, the network looks for the `static{}` function. This function is also called a [``](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.9). Anything specified within `static{}` will only ever be run once. For example, if your contract requires some environment variables to be specified at deployment time, you can declare them within `static{}`. However, if you want to declare them _outside_ of `static{}`, you can use the `@Initializeable` annotation. This allows you to declare the variables higher up in your contract, or inside a method within your contract. -During deployment, the `static{}` (also called [``](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.9)) will first try to decode the `data` field that is passed into the contract to set the values of the `@Initializable` fields. +All `@Initializable` fields must be static. The _type_ of an `@Initializable` field must be a supported [AVM ABI type](/developers/fundamentals/avm-concepts/abi-types/). The data supplied to the data field when deploying your contract must be supplied in the **exact same order** as the `@Initializable` field are defined. If not, an _ABIException_ will be thrown. The AVM uses the [ABIDecoder](/developers/fundamentals/packages/abi/#abidecoder-https-avm-api-aion-network-org-aion-avm-userlib-abi-abidecoder) or order to parse all `@Initializeable` annotations. -It decodes the values in the **same order** as the fields marked `@Initializable` in the contract using an [ABIDecoder](/developers/fundamentals/packages/abi/#abidecoder-https-avm-api-aion-network-org-aion-avm-userlib-abi-abidecoder). - -For example: +If you have two variables `myInt` and `myString` that you want to declare and _initialize_ them then you would use the `@Initializable` annotation. ```java @Initializable @@ -24,41 +18,60 @@ private static int myInt; private static String myString; ``` -The `static{}` for this class would look something like: +Within the `static{}` for this contract, you would _decode_ the variables using the `ABIDecoder` class. Again, any variable you want to initialize need to be decoded in the order that you declared them: ```java static { - ABIDecoder decoder = new ABIDecoder(Blockchain.getData()); - myInt = decoder.decodeOneInteger(); - myString = decoder.decodeOneString(); + ABIDecoder decoder = new ABIDecoder(Blockchain.getData()); + myInt = decoder.decodeOneInteger(); + myString = decoder.decodeOneString(); } ``` -Any instructions in a user-provided `static{}` block will run after decoding and setting the `@Initializable fields`. +### Example -For example: +Below is an example of how to use the `@Initializable` annotation to supply environment variables into a contract in order to interact with an external API. The API call logic has been ignored here to keep this example simple. ```java +// Define environment variables apiKey and Region. @Initializable -private static int myInt; +private static String apiKey; @Initializable -private static String myString; +private static int region; +// Set a placeholder for the owner of the contract and API response. private static Address owner; +private static String initialApiResponse; +// Decode the arguments supplied when deploying the contract. static { - owner = Blockchain.getCaller(); - increaceMyIntByOne(); + apiKey = decoder.decodeOneString(); + region = decoder.decodeOneInt(); + owner = Blockchain.getCaller(); + initialiApiResponse = callApi(apiKey, region); +} + +// Can an external API using the onetime API key and region. +private static String callApi(String suppliedApiKey, int suppliedRegion) { + // API call logic. + return apiResponse; +} + +// Have the owner of this contract return the response of the API. +public static String returnMessage() { + onlyOwner(); + return initialiApiResponse; } -private static void increaseMyIntByOne() { - myInt += 1; +// A modifer function that halts a function if it is not called by the owner of this contract. +private static void onlyOwner() { + Blockchain.require(Blockchain.getCaller().equals(owner)); } ``` -The `static{}` function will do the following **in order**: +This contract can be deployed using the Maven CLI and the Aion4J plugin: -1. Instantiate an `ABIDecoder` with [Blockchain.getData()](https://avm-api.aion.network/avm/blockchain#getData%28%29) and try to decode an `Integer` and a `string`; -2. Set `owner` as the address that deployed the contract. -3. Execute `increaseMyIntByOne()` and increase the value of myInt by one. +```bash +mvn aion4j:deploy -Dargs="-T 'ABAF21E45B23C00AA12311C32E' -I 3" +```