Initializable Fields
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.
When a contract is deployed, the network looks for the static{}
function. This function is also called a <clinit>
. 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.
All @Initializable
fields must be static. The type of an @Initializable
field must be a supported AVM ABI type. 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 or order to parse all @Initializeable
annotations.
If you have two variables myInt
and myString
that you want to declare and initialize them then you would use the @Initializable
annotation.
@Initializable
private static int myInt;
@Initializable
private static String myString;
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:
static {
ABIDecoder decoder = new ABIDecoder(Blockchain.getData());
myInt = decoder.decodeOneInteger();
myString = decoder.decodeOneString();
}
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.
// Define environment variables apiKey and Region.
@Initializable
private static String apiKey;
@Initializable
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 {
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;
}
// 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));
}
This contract can be deployed using the Maven CLI and the Aion4J plugin:
mvn aion4j:deploy -Dargs="-T 'ABAF21E45B23C00AA12311C32E' -I 3"