Skip to content

Commit

Permalink
Addressing example issue.
Browse files Browse the repository at this point in the history
  • Loading branch information
John committed Aug 19, 2019
1 parent f2687a1 commit 97f53fd
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions developers/fundamentals/avm-concepts/initializable-fields.md
Original file line number Diff line number Diff line change
@@ -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 [`<clinit>`](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 [`<clinit>`](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
Expand All @@ -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) {

This comment has been minimized.

Copy link
@fulldecent

fulldecent Aug 20, 2019

Contributor

Why is somebody passing an API key through a blockchain transaction?

This comment has been minimized.

Copy link
@johnnymatthews

johnnymatthews Aug 21, 2019

Contributor

That's a good point, it could get sniffed out. I understand why this is a strange example now.

// 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"
```

0 comments on commit 97f53fd

Please sign in to comment.