#
Custom initialization
When deploying a Diamond for the first time, it's possible to run additional initialization code at the end of the cut call, in order to setup your Diamond's internal state.
This is specified as a specific contract and method to call within the configuration file. For example:
// file: gemforge.config.cjs
module.exports = {
// ...
diamond: {
// ...
// custom initialization call
init: {
// The diamond initialization contract name
contract: 'InitDiamond',
// The diamond initialization function name
function: 'init',
},
// ...
},
// ...
}
We would then create an InitDiamond.sol
file somewhere within our source tree, and it must contain the init()
method which may or may not take arguments. For this example, let's have a single uint
argument:
// file: src/init/InitDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.21;
import { AppStorage, LibAppStorage } from "../libs/LibAppStorage.sol";
contract InitDiamond {
function init(uint initialValue) external {
AppStorage storage s = LibAppStorage.diamondStorage();
// update storage here
s.var1 = initialValue
// s.var2 = ...
}
}
When deploying to any target we will need to specify the values for the init()
method arguments. This allows to specify different initialization parameters (and thus initialize our Diamond different) for different target.
For example, for the above init()
method we need to specify one argument:
// file: gemforge.config.cjs
module.exports = {
...
targets: {
local: {
network: 'local',
wallet: 'wallet1',
initArgs: [1] // initialValue = 1
},
testnet: {
network: 'sepolia',
wallet: 'wallet2',
initArgs: [2] // initialValue = 2
}
}
...
}
#
Initialization during an upgrade
Sometimes you may wish to run some initialization code during an upgrade. To do this will require using the "pause and resume" deployment flow.
When pausing a deployment a JSON file is created that contains the data for the diamondCut()
call, e.g:
{
"cuts": [
{
"facetAddress": "0x0000000000000000000000000000000000000000",
"action": 2,
"functionSelectors": [
"0xbf9f7311"
]
},
// ...
],
"initContractAddress": "0x0000000000000000000000000000000000000000",
"initData": "0x"
}
The initContractAddress
and initData
values get passed to the diamondCut()
call. By modifying them you can run custom initialization code when the deployment is resumed.
Note: The initData
value must the ABI-encoded function selector and arguments to be passed to it.