Skip to content

Commit

Permalink
feat: add README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
omurovec committed Feb 19, 2023
1 parent e103f42 commit 9e7f58f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PRIVATE_KEY=""
OS=""
ARCH=""
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ out/

# Dotenv file
.env

# Any zksolc compilers
lib/zksolc*
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Foundry Plugin for zkSync Era

## Overview

This plugin allows for the compilation & deployment of contracts to the zkSync Era network within a foundry project. zkSync Era uses a custom compiler and deployment process different from other EVM networks, this plugin simplifies this process.

## Requirements

This plugin assumes you have [solc](https://docs.soliditylang.org/en/latest/installing-solidity.html) installed and in your path.

## Installation / Setup

Install this project as a dependancy:

```sh
forge install omurovec/foundry-zksync-era
```

Import `Deployer.sol` into your deployment script and use as follows:

```solidity
// Script.s.sol
import "lib/foundry-zksync-era/Deployer.sol";
...
// Provide zkSync compiler version and address of the diamond proxy on L1
Deployer deployer = new Deployer("1.3.4", address(0x1908e2BF4a88F91E4eF0DC72f02b8Ea36BEa2319));
// Provide path to contract, input params, salt & whether it should be broadcasted
// Returns deployment address on L2
deployer.deployFromL1("src/Counter.sol", new bytes(0), bytes32(uint256(1337)), true);
```

> Note: The Diamond Proxy address is the address of the L1 contract that handles all interactions with the zkSync network. At the time of writing, the diamond proxy for goerli was used in the example however this can change after regenesis & other network upgrades. This address will always be the same as the bridge and can be found by attempting to bridge assets at https://portal.zksync.io/bridge
Ensure the following values are in your env:

```sh
PRIVATE_KEY=""
OS="" # macosx | windows | linux
ARCH="" # arm64 | amd64
```

Deploy your contracts using the script you created

```sh
forge script scripts/Script.s.sol --ffi --broadcast --rpc-url L1_RPC_URL
```

The transaction hash of the deployment on L2 will be returned by the broadcast. It is dependant on the block timestamp so it can not be accurately derrived within the script (before execution).

> Note: It's also recommended to add `lib/zksolc*` to your project's `.gitignore`
## Notes

This is a work in progress so it does not have all the features of it's counterparty [hardhat-zksync](https://github.com/matter-labs/hardhat-zksync). Some things to note:

- This project currently **only supports deployment from L1**. Direct deployment from L2 requires custom data to be passed in to the EIP-712 transaction (see [zkSync docs](https://era.zksync.io/docs/api/api.html#eip712)).

- The `_l2GasLimit` & `_l2GasPerPubdataByteLimit` params for `requestL2Transaction()` are currently hardcoded to their max values for convenience.

## Contribution

This has just been a quick passion project so far but would love any help on making this a more feature rich project & a go-to for anyone using foundry + zksync era so feel free to open any issues or PRs that you think would be useful.
10 changes: 2 additions & 8 deletions script/Counter.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@ import "forge-std/Script.sol";
import "./Deployer.sol";

contract CounterScript is Script {
Deployer public deployer;

function setUp() public {
deployer = new Deployer("1.3.1", address(0x1908e2BF4a88F91E4eF0DC72f02b8Ea36BEa2319));
}

function run() public {
bytes memory params;
address counter = deployer.deployFromL1("src/Counter.sol", params, bytes32(uint256(1337)), true);
Deployer deployer = new Deployer("1.3.4", address(0x1908e2BF4a88F91E4eF0DC72f02b8Ea36BEa2319));
deployer.deployFromL1("src/Counter.sol", new bytes(0), bytes32(uint256(1337)), true);
}
}
17 changes: 8 additions & 9 deletions script/Deployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ contract Deployer {
/* address constant HEVM_ADDRESS = address(bytes20(uint160(uint256(keccak256("hevm cheat code"))))); */
_CheatCodes cheatCodes = _CheatCodes(address(uint160(uint256(keccak256("hevm cheat code")))));


///@notice Compiler & deployment config
string constant zksolcRepo = "https://github.com/matter-labs/zksolc-bin";
string public projectRoot;
Expand Down Expand Up @@ -63,7 +62,10 @@ contract Deployer {
bytecode = cheatCodes.ffi(echoCmds);
}

function deployFromL1(string memory fileName, bytes calldata params, bytes32 salt, bool broadcast) public returns (address) {
function deployFromL1(string memory fileName, bytes calldata params, bytes32 salt, bool broadcast)
public
returns (address)
{
bytes memory bytecode = compileContract(fileName);

bytes32 bytecodeHash = L2ContractHelper.hashL2Bytecode(bytecode);
Expand Down Expand Up @@ -92,27 +94,24 @@ contract Deployer {
}

function _installCompiler(string memory version) internal returns (string memory path) {

///@notice Ensure correct compiler bin is installed
string memory os = cheatCodes.envString("OS");
string memory arch = cheatCodes.envString("ARCH");
string memory extension = keccak256(bytes(os)) == keccak256(bytes("win32")) ? "exe" : "";
string memory extension = keccak256(bytes(os)) == keccak256(bytes("windows")) ? "exe" : "";

///@notice Get toolchain
string memory toolchain = "";
if (keccak256(bytes(os)) == keccak256(bytes("win32"))) {
if (keccak256(bytes(os)) == keccak256(bytes("windows"))) {
toolchain = "-gnu";
}else if (keccak256(bytes(os)) ==keccak256(bytes( "linux"))) {
} else if (keccak256(bytes(os)) == keccak256(bytes("linux"))) {
toolchain = "-musl";
}

///@notice Construct urls/paths
string memory fileName = string(abi.encodePacked("zksolc-", os, "-", arch, toolchain, "-v", version, extension));
string memory zksolcUrl =
string(abi.encodePacked(zksolcRepo, "/raw/main/", os, "-", arch, "/", fileName));
string memory zksolcUrl = string(abi.encodePacked(zksolcRepo, "/raw/main/", os, "-", arch, "/", fileName));
path = string(abi.encodePacked(projectRoot, "/lib/", fileName));


///@notice Download zksolc compiler bin
string[] memory curl_cmds = new string[](6);
curl_cmds[0] = "curl";
Expand Down

0 comments on commit 9e7f58f

Please sign in to comment.