This is the process for deploying a new proxy and implementation (as opposed to upgrading an existing proxy).
Since the proxy uses delegatecall
to forward calls to the implementation,
initialization of the contracts becomes a little tricky because we cannot
initialize fields in the implementation contract via the constructor. Instead
there is an initialize method in the implementation contract, which is publicly
available, but can only be called once per proxy.
-
Deploy FiatTokenV2_2
-
Initialize the fields in FiatTokenV2_2 via the
initialize*
methods. The values are not important, but this will stop anyone else initializing the roles and trying to use it as a token or pass it off as a real Circle token.initialize( "", "", "", 0, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS ); initializeV2(""); initializeV2_1(THROWAWAY_ADDRESS); initializeV2_2([], "");
-
Verify that all fields in the FiatToken have been initialized correctly and have the expected values. See README.validate.md.
-
Obtain addresses for the following contract roles. Ensure that the keys for these addresses are securely stored.
admin masterMinter pauser blacklister owner
For details on what these roles can do, see the Token Design Doc
-
Deploy FiatTokenProxy, passing the address of the deployed implementation contract to the constructor, which will initialize the
_implementation
field. -
The
admin
of the proxy contract defaults tomsg.sender
. You must either change theadmin
now, or send the remaining transactions from a different address. Theadmin
can only see methods in the Proxy, any method calls fromadmin
will not be forwarded to the implementation contract. Theadmin
address can be changed by callingchangeAdmin
. Note that change admin must be called by the current admin.changeAdmin(adminAddress)
-
Initialize the proxy via the
initialize*
methods. This call will get forwarded to the implementation contract, but since it is viadelegatecall
it will run in the context of the Proxy contract, so the fields it is initializing will be stored in the storage of the Proxy. The values passed here are important, especially for the roles that will control the contract.initialize( tokenName, tokenSymbol, tokenCurrency, tokenDecimals, masterMinterAddress, pauserAddress, blacklisterAddress, ownerAddress ); initializeV2(newTokenName); initializeV2_1(lostAndFoundAddress); initializeV2_2(accountsToBlacklist, newTokenSymbol);
-
Verify the fields have been properly initialized. Verification should be performed independently by multiple people to make sure that the contract has been deployed correctly. The following fields should be verified:
admin
is the expected addressimplementation
is the address of the implementation contractname
,symbol
,currency
anddecimals
are as expectedversion
is 2owner
,masterMinter
,pauser
,blacklister
are the expected addressestotalSupply
is 0initialized
istrue
-
If all verification is successful, the contract is deployed and ready to go. If any verification steps failed, restart the process.