-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
John
committed
Aug 19, 2019
1 parent
f2687a1
commit 97f53fd
Showing
1 changed file
with
39 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
@@ -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.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
johnnymatthews
Contributor
|
||
// 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" | ||
``` |
Why is somebody passing an API key through a blockchain transaction?