> For the complete documentation index, see [llms.txt](https://validium.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://validium.gitbook.io/docs/tooling/foundary/migration-guide/deployment.md).

# Deployment

***

#### Address Derivation <a href="#address-derivation" id="address-derivation"></a>

**Issue**

ZKsync uses a different strategy for deriving addresses in `CREATE` and `CREATE2` operations compared to Ethereum. This can cause discrepancies if your project relies on hardcoded Ethereum-style addresses for contract deployment.

**Problematic Code**

In Ethereum, you might have code that calculates the address of a contract deployed using `CREATE2` based on a salt and bytecode hash:

```solidity
  function computeCreate2Address(
      address deployer,
      bytes32 salt,
      bytes memory bytecode
  ) public pure returns (address) {
      return address(uint160(uint(keccak256(abi.encodePacked(
          bytes1(0xff),
          deployer,
          salt,
          keccak256(bytecode)
      )))));
  }
```

This method won’t work in ZKsync because the address derivation logic is different. To learn more about these differences refer to the documentation on [Differences with address derivation](/docs/developer-reference/ethereum-differences/evm-instructions.md#address-derivation).

**Error**

When deploying contracts using `CREATE2`, the actual address of the deployed contract may differ from the expected address derived using Ethereum’s method. This can cause failures when interacting with contracts by their derived address.

**Solution**

To derive ZKsync-compatible `CREATE2` addresses, you need to use ZKsync's specific hashing mechanism that includes a `zksyncCreate2` prefix.

**Fixed Code Example**

The following is an example of how you can compute a valid `CREATE2` address for ZKSync. This function uses ZKsync’s specific address derivation logic and ensures the contract addresses are correctly computed.

```solidity
    function computeCreate2Address(
        address _sender,
        bytes32 _salt,
        bytes32 _bytecodeHash,
        bytes32 _constructorInputHash
    ) external pure returns (address) {
        bytes32 senderBytes = bytes32(uint256(uint160(_sender)));
        bytes32 data = keccak256(
            bytes.concat(keccak256("zksyncCreate2"), senderBytes, _salt, _bytecodeHash, _constructorInputHash)
        );

        return address(uint160(uint256(data)));
    }
```

#### Batch Transactions <a href="#batch-transactions" id="batch-transactions"></a>

**Issue**

In Foundry ZKsync, batched transactions may be executed out of order, which can cause failures if subsequent transactions depend on the execution of prior transactions.

**Problematic Code**

In Ethereum, you might use batched transactions within your scripts like this:

```solidity
contract Calculator {
    function add(uint8 a, uint8 b) public pure returns (uint8) {
        return a + b;
    }
}

contract FooScript is Script {
    function run() public {
        vm.startBroadcast();
        Calculator calc = new Calculator();     // tx1
        uint8 sum = calc.add(1, 2);             // tx2
        vm.stopBroadcast();
    }
}
```

In this example, the deployment of the `Calculator` contract (tx1) and the invocation of `add` (tx2) are batched together. However, on ZKsync, tx2 might execute before tx1, causing the script to fail.

**Error**

The error occurs when the second transaction (`tx2`) is executed before the first transaction (`tx1`), leading to a failure since the contract isn't deployed yet:

```bash
Error: Transaction reverted: contract not deployed
```

**Solution**

To ensure transactions are executed correctly on ZKsync using Foundry ZKsync, use the `--slow` flag, which sends transactions one at a time and keeps them in order.

**Fixed Code Example**

Here’s how you can run the script with proper transaction execution:

{% code overflow="wrap" %}

```bash
forge script script/FooTest.s.sol:FooScript --zksync --rpc-url https://sepolia.era.zksync.dev --broadcast --slow
```

{% endcode %}

The `--slow` flag forces transactions to be sent individually to the RPC endpoint, ensuring they are executed in the correct order.

#### Bytecode Hash <a href="#bytecode-hash" id="bytecode-hash"></a>

[Bytecode hashes output by `zksolc` are fundamentally different](https://docs.zksync.io/zk-stack/components/zksync-evm/bootloader#bytecode-hashes) from the hash obtained via solc. The most glaring difference is the first (most-significant) byte denotes the version of the format, which at present is `1`. This leads to all `zksolc` bytecode hashes to begin with `1`, whereas `solc` bytecodes are merely the `keccak` hash of the bytecode.

Any code making assumptions about bytecode hashes around EVM-scope will need to be migrated to accommodate for ZKsync's bytecode hashes.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://validium.gitbook.io/docs/tooling/foundary/migration-guide/deployment.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
