# Design Pattern Solidity: Initialize Contract after Deployment

Author: Markus Waas

Published: 2019-09-01T07:00:37.000Z

Updated: 2026-09-13T14:25:30.000Z

Source: [https://soliditydeveloper.com/design-pattern-solidity-initialize-contract-after-deployment](<https://soliditydeveloper.com/design-pattern-solidity-initialize-contract-after-deployment>)

## Compatibility and review

Before you start

The snippets illustrate initialization, not a complete deployable contract. A one-time initializer also needs a safe deployment and authorization strategy; initialize proxy instances atomically and lock implementation contracts.

[Official reference](<https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable>)

There are a few reasons why you might want to initialize a contract after deployment and not directly by passing constructor arguments. But first let's look at an example:

The first snippet deliberately omits the guard to introduce the pattern. It accepts repeat calls from anyone. The later flag is still schematic and must be combined with the deployment and authorization rules below.

```solidity
contract MyCrowdsale {
  uint256 rate;

  function initialize(uint256 _rate) public {
    rate = _rate;
  }
}
```

What's the advantage over `constructor(uint256 _rate)`?

- Deployment and configuration does not need to happen at the same time. This can be useful when your workflow requires it.
- Easier [Etherscan verification](<https://etherscan.io/verifyContract>) as you do not have to deal with messy constructor arguments.
- Can help reorganize configuration when a particular function produces a stack-too-deep compiler error; there is no universal 13-argument cutoff.
- Is used by proxy-based upgradeable contracts, where the proxy needs its own initialized storage. An initializer alone does not make a contract upgradeable.

## Avoid multiple initializations

Make sure that you do not allow multiple initializations. A parameter check such as `require(rate == 0)` is insufficient when zero is a valid configured value. Use an explicit initialization flag, or the [OpenZeppelin Initializable](<https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable>) pattern. The first call must also be controlled: initialize through the deployment transaction or apply suitable authorization. For proxies, initialize the proxy during deployment and lock the implementation with `_disableInitializers()`. Here is a schematic one-time flag:

```solidity
contract MyContract {
  bool isInitialized = false;

  function initialize(
    uint256 _param1,
    uint256 _param2,  
    uint256 _param3,
    address _param4,
    address _param5,
    bytes32 _param6,
    bytes32 _param7
  ) public {
    require(!isInitialized, 'Contract is already initialized!');
    isInitialized = true;

    param1 = _param1;
    ...
    param7 = _param7;
  }
}
```
