Skip to content

Commit

Permalink
feat: use deployment type in the deploy function (#1089)
Browse files Browse the repository at this point in the history
* feat: use deployment type in the deploy function

* fix: change tests to support new deployment type impl

* fix: change tests to support new deployment type impl

* fix: delete deposit from the script

---------

Co-authored-by: Marko Arambasic <[email protected]>
  • Loading branch information
kiriyaga-txfusion and kiriyaga authored May 28, 2024
1 parent 1d03e91 commit e335357
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 94 deletions.
18 changes: 11 additions & 7 deletions examples/basic-example/deploy/001_deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@ module.exports = async function (hre) {
const deployer = new Deployer(hre, zkWallet);

// Deposit some funds to L2 in order to be able to perform deposits.
const depositHandle = await deployer.zkWallet.deposit({
to: deployer.zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.001'),
});
await depositHandle.wait();
// const depositHandle = await deployer.zkWallet.deposit({
// to: deployer.zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.001'),
// });
// await depositHandle.wait();

// Load the artifact we want to deploy.
const artifact = await deployer.loadArtifact('Greeter');

// Deploy this contract. The returned object will be of a `Contract` type, similarly to ones in `ethers`.
// `greeting` is an argument for contract constructor.
const greeting = 'Hi there!';
const greeterContract = await deployer.deploy(artifact, [greeting]);
const greeterContract = await deployer.deploy(artifact, [greeting], 'create2', {
customData: {
salt: '0x7935910912126667836566922594852029127629416664760357073852948630',
}
});

// Show the contract info.
const contractAddress = greeterContract.address;
Expand Down
13 changes: 6 additions & 7 deletions examples/basic-example/deploy/002_factory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import * as ethers from 'ethers';
import * as zk from 'zksync-ethers';
import { Deployer } from '@matterlabs/hardhat-zksync-deploy';
import chalk from 'chalk';
Expand All @@ -21,12 +20,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
const deployer = new Deployer(hre, zkWallet);

// Deposit some funds to L2 in order to be able to perform deposits.
const depositHandle = await deployer.zkWallet.deposit({
to: deployer.zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.01'),
});
await depositHandle.wait();
// const depositHandle = await deployer.zkWallet.deposit({
// to: deployer.zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.01'),
// });
// await depositHandle.wait();

// Load the artifact we want to deploy.
const artifact = await deployer.loadArtifact('Import');
Expand Down
27 changes: 13 additions & 14 deletions examples/basic-example/deploy/003_account_abstraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,36 @@ export default async function (hre: HardhatRuntimeEnvironment) {
const zkWallet = zk.Wallet.fromMnemonic(testMnemonic, "m/44'/60'/0'/0/0");

// Create deployer objects and load desired artifacts.
const contractDeployer = new Deployer(hre, zkWallet, 'create');
const aaDeployer = new Deployer(hre, zkWallet, 'createAccount');
const greeterArtifact = await contractDeployer.loadArtifact('Greeter');
const aaArtifact = await aaDeployer.loadArtifact('TwoUserMultisig');
const deployer = new Deployer(hre, zkWallet);
const greeterArtifact = await deployer.loadArtifact('Greeter');
const aaArtifact = await deployer.loadArtifact('TwoUserMultisig');

const provider = aaDeployer.zkWallet.provider;
const provider = deployer.zkWallet.provider;

// Deposit some funds to L2 in order to be able to perform L2 transactions.
const depositHandle = await contractDeployer.zkWallet.deposit({
to: contractDeployer.zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.001'),
});
await depositHandle.wait();
// const depositHandle = await deployer.zkWallet.deposit({
// to: deployer.zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.001'),
// });
// await depositHandle.wait();

const greeterContract = await contractDeployer.deploy(greeterArtifact, ['Hi there!']);
const greeterContract = await deployer.deploy(greeterArtifact, ['Hi there!']);

console.info(chalk.green(`Greeter was deployed to ${greeterContract.address}`));

// The two owners of the multisig
const owner1 = zk.Wallet.createRandom();
const owner2 = zk.Wallet.createRandom();

const aa = await aaDeployer.deploy(aaArtifact, [owner1.address, owner2.address], undefined, []);
const aa = await deployer.deploy(aaArtifact, [owner1.address, owner2.address], 'createAccount', undefined, []);

const multisigAddress = aa.address;

console.info(chalk.green(`Multisig was deployed to ${multisigAddress}`));

await (
await contractDeployer.zkWallet.sendTransaction({
await deployer.zkWallet.sendTransaction({
to: multisigAddress,
// You can increase the amount of ETH sent to the multisig
value: ethers.utils.parseEther('0.003'),
Expand Down
12 changes: 6 additions & 6 deletions examples/deploy-example/deploy-zkSync/000_deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ const deployScript = async function (hre: HardhatRuntimeEnvironment) {
hre.deployer.setWallet(zkWallet);

// Deposit some funds to L2 in order to be able to perform deposits.
const depositHandle = await zkWallet.deposit({
to: zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.01'),
});
await depositHandle.wait();
// const depositHandle = await zkWallet.deposit({
// to: zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.01'),
// });
// await depositHandle.wait();

// Load the artifact we want to deploy.
const artifact = await hre.deployer.loadArtifact('Foo');
Expand Down
2 changes: 1 addition & 1 deletion examples/deploy-example/deploy-zkSync/001_deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var deployScript = async function (hre) {
// Deploy this contract. The returned object will be of a `Contract` type, similarly to ones in `ethers`.
// `greeting` is an argument for contract constructor.
const greeting = 'Hi there!';
const greeterContract = await hre.deployer.deploy(artifact, [greeting], true);
const greeterContract = await hre.deployer.deploy(artifact, [greeting]);

// Show the contract info.
const contractAddress = greeterContract.address;
Expand Down
12 changes: 6 additions & 6 deletions examples/node-example/deploy/001_deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ module.exports = async function (hre) {
const deployer = new Deployer(hre, zkWallet);

// Deposit some funds to L2 in order to be able to perform deposits.
const depositHandle = await deployer.zkWallet.deposit({
to: deployer.zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.001'),
});
await depositHandle.wait();
// const depositHandle = await deployer.zkWallet.deposit({
// to: deployer.zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.001'),
// });
// await depositHandle.wait();

// Load the artifact we want to deploy.
const artifact = await deployer.loadArtifact('Greeter');
Expand Down
12 changes: 6 additions & 6 deletions examples/vyper-example/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
const deployer = new Deployer(hre, zkWallet);

// Deposit some funds to L2 in order to be able to perform deposits.
const depositHandle = await deployer.zkWallet.deposit({
to: deployer.zkWallet.address,
token: zk.utils.ETH_ADDRESS,
amount: ethers.utils.parseEther('0.01'),
});
await depositHandle.wait();
// const depositHandle = await deployer.zkWallet.deposit({
// to: deployer.zkWallet.address,
// token: zk.utils.ETH_ADDRESS,
// amount: ethers.utils.parseEther('0.01'),
// });
// await depositHandle.wait();

// Load the artifact we want to deploy.
const createForwarder = await deployer.loadArtifact('CreateForwarder');
Expand Down
10 changes: 8 additions & 2 deletions packages/hardhat-zksync-chai-matchers/test/reverted/reverted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ describe('INTEGRATION: Reverted', function () {
artifact = await deployer.loadArtifact('Matchers');
matchers = await deployer.deploy(artifact);

aaDeployer = new Deployer(this.hre, wallet1, 'createAccount');
aaDeployer = new Deployer(this.hre, wallet1);
artifact = await deployer.loadArtifact('TwoUserMultisig');
aaAccount = await aaDeployer.deploy(artifact, [wallet1.address, wallet2.address], undefined, []);
aaAccount = await aaDeployer.deploy(
artifact,
[wallet1.address, wallet2.address],
'createAccount',
undefined,
[],
);
});

// helpers
Expand Down
23 changes: 7 additions & 16 deletions packages/hardhat-zksync-deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,16 @@ It's main methods are:
```
* @param hre Hardhat runtime environment. This object is provided to scripts by hardhat itself.
* @param zkWallet The wallet which will be used to deploy the contracts.
* @param deploymentType Optional deployment type that relates to the ContractDeployer system contract function to be called. Defaults to deploying regular smart contracts.
```
- `constructor(hre: HardhatRuntimeEnvironment, zkWallet: zk.Wallet, deploymentType?: zk.types.DeploymentType)`
- `constructor(hre: HardhatRuntimeEnvironment, zkWallet: zk.Wallet)`

```
* Created a `Deployer` object on ethers.Wallet object.
*
* @param hre Hardhat runtime environment. This object is provided to scripts by hardhat itself.
* @param ethWallet The wallet used to deploy smart contracts.
* @param deploymentType The optional deployment type that relates to the `ContractDeployer` system contract function to be called. Defaults to deploying regular smart contracts.
```
- `static fromEthWallet(hre: HardhatRuntimeEnvironment, ethWallet: ethers.Wallet, deploymentType?: zk.types.DeploymentType)`
- `static fromEthWallet(hre: HardhatRuntimeEnvironment, ethWallet: ethers.Wallet)`

```
* Loads an artifact and verifies that it was compiled by `zksolc`.
Expand All @@ -80,25 +78,26 @@ It's main methods are:
*
* @param artifact The previously loaded artifact object.
* @param constructorArguments The list of arguments to be passed to the contract constructor.
*
* @param deploymentType Optional deployment type that relates to the ContractDeployer system contract function to be called. Defaults to deploying regular smart contracts.
* @returns Calculated fee in ETH wei.
*/
```
- `public async estimateDeployFee(artifact: ZkSyncArtifact, constructorArguments: any[]): Promise<ethers.BigNumber>`
- `public async estimateDeployFee(artifact: ZkSyncArtifact, constructorArguments: any[], deploymentType?: zk.types.DeploymentType): Promise<ethers.BigNumber>`

```
* Sends a deploy transaction to the zkSync network.
* For now it uses defaults values for the transaction parameters:
*
* @param contractNameOrArtifact The previously loaded artifact object, or contract name that will be resolved to artifact in the background.
* @param constructorArguments The list of arguments to be passed to the contract constructor.
*@param deploymentType Optional deployment type that relates to the ContractDeployer system contract function to be called. Defaults to deploying regular smart contracts.
* @param overrides Optional object with additional deploy transaction parameters.
* @param additionalFactoryDeps Additional contract bytecodes to be added to the factory dependencies list.
* The fee amount is requested automatically from the zkSync Era server.
*
* @returns A contract object.
```
- `public async deploy(contractNameOrArtifact: ZkSyncArtifact | strin, constructorArguments: any[],o verrides?: OverridesAdditionalFactoryDeps?: ethers.BytesLike[]): Promise<zk.Contract>`
- `public async deploy(contractNameOrArtifact: ZkSyncArtifact | strin, constructorArguments: any[], deploymentType?: zk.types.DeploymentType, overrides?: OverridesAdditionalFactoryDeps?: ethers.BytesLike[]): Promise<zk.Contract>`

In the `deploy` method description, it's evident that `contractNameOrArtifact` can accept two types of objects. One type represents a loaded artifact, while the other type is a string representing a contract name, which the `deploy` method will internally convert to the corresponding artifact.

Expand Down Expand Up @@ -182,15 +181,6 @@ The described objects work together to provide users with a better deployment ex

Methods available for use in `hre.deployer` are the same as those available in the `Deployer` class object, as described above. Additionally, `hre.deployer` is extended with specific methods to facilitate the deployment process, making it more straightforward.

```
* Set deployment type
*
* @param deployment type for future deployments
*
*/
```
- `public setDeploymentType(deploymentType: zk.types.DeploymentType): void`

```
/**
* Set a new Wallet
Expand Down Expand Up @@ -477,6 +467,7 @@ module.exports = [
```
- To allows the task to skip the compilation process, add `--no-compile` argument, e.g. `hardhat deploy-zksync:contract --contract-name Contract --no-compile`.
- To allows the task to specify which deployer smart contract function will be called, add `--deployment-type` argument. Permissible values for this parameter include `create`, `create2`, `createAccount`, and `create2Account`. If this parameter is omitted, the default value assumed will be `create`, e.g. `hardhat deploy-zksync:contract --contract-name Greeter 'Hello' --deployment-type create2`.
- To specify which salt will be used in deployment, add `--salt` argument. If the salt parameters are ommited, the default value will be `0x0000000000000000000000000000000000000000000000000000000000000000`.

The account used for deployment will be the one specified by the `deployerAccount` configuration within the `hardhat.config.ts` file. If no such configuration is present, the account with index `0` will be used.

Expand Down
20 changes: 9 additions & 11 deletions packages/hardhat-zksync-deploy/src/deployer-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,7 @@ export class DeployerExtension implements AbstractDeployer {
private zkWeb3Provider?: zk.Provider;
private wallet?: zk.Wallet;

constructor(
private _hre: HardhatRuntimeEnvironment,
private _deploymentType?: zk.types.DeploymentType,
) {}

public setDeploymentType(deploymentType: zk.types.DeploymentType) {
this._deploymentType = deploymentType;
}
constructor(private _hre: HardhatRuntimeEnvironment) {}

public async loadArtifact(contractNameOrFullyQualifiedName: string): Promise<ZkSyncArtifact> {
return await loadArtifact(this._hre, contractNameOrFullyQualifiedName);
Expand All @@ -28,6 +21,7 @@ export class DeployerExtension implements AbstractDeployer {
public async deploy(
contractNameOrArtifact: ZkSyncArtifact | string,
constructorArguments: any[] = [],
deploymentType?: zk.types.DeploymentType,
overrides?: ethers.Overrides,
additionalFactoryDeps?: ethers.BytesLike[],
): Promise<zk.Contract> {
Expand All @@ -40,7 +34,7 @@ export class DeployerExtension implements AbstractDeployer {
contractNameOrArtifact,
constructorArguments,
this.wallet,
this._deploymentType,
deploymentType,
overrides,
additionalFactoryDeps,
);
Expand All @@ -54,12 +48,16 @@ export class DeployerExtension implements AbstractDeployer {
return await estimateDeployFee(this._hre, artifact, constructorArguments, this.wallet);
}

public async estimateDeployGas(artifact: ZkSyncArtifact, constructorArguments: any[]): Promise<ethers.BigNumber> {
public async estimateDeployGas(
artifact: ZkSyncArtifact,
constructorArguments: any[],
deploymentType?: zk.types.DeploymentType,
): Promise<ethers.BigNumber> {
if (!this.wallet) {
this.wallet = await this.getWallet();
}

return await estimateDeployGas(this._hre, artifact, constructorArguments, this.wallet, this._deploymentType);
return await estimateDeployGas(this._hre, artifact, constructorArguments, this.wallet, deploymentType);
}

public setWallet(wallet: zk.Wallet): void {
Expand Down
23 changes: 10 additions & 13 deletions packages/hardhat-zksync-deploy/src/deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ import { AbstractDeployer } from './abstract-deployer';
export class Deployer implements AbstractDeployer {
public ethWallet: ethers.Wallet;
public zkWallet: zk.Wallet;
public deploymentType?: zk.types.DeploymentType;

constructor(
private _hre: HardhatRuntimeEnvironment,
zkWallet: zk.Wallet,
deploymentType?: zk.types.DeploymentType,
) {
this.deploymentType = deploymentType;

// Initalize two providers: one for the Ethereum RPC (layer 1), and one for the zkSync RPC (layer 2).
const { ethWeb3Provider, zkWeb3Provider } = createProviders(_hre.config.networks, _hre.network);

Expand All @@ -30,12 +26,8 @@ export class Deployer implements AbstractDeployer {
this.ethWallet = this.zkWallet.ethWallet();
}

public static fromEthWallet(
hre: HardhatRuntimeEnvironment,
ethWallet: ethers.Wallet,
deploymentType?: zk.types.DeploymentType,
) {
return new Deployer(hre, new zk.Wallet(ethWallet.privateKey), deploymentType);
public static fromEthWallet(hre: HardhatRuntimeEnvironment, ethWallet: ethers.Wallet) {
return new Deployer(hre, new zk.Wallet(ethWallet.privateKey));
}

public async loadArtifact(contractNameOrFullyQualifiedName: string): Promise<ZkSyncArtifact> {
Expand All @@ -46,13 +38,18 @@ export class Deployer implements AbstractDeployer {
return await estimateDeployFee(this._hre, artifact, constructorArguments, this.zkWallet);
}

public async estimateDeployGas(artifact: ZkSyncArtifact, constructorArguments: any[]): Promise<ethers.BigNumber> {
return await estimateDeployGas(this._hre, artifact, constructorArguments, this.zkWallet, this.deploymentType);
public async estimateDeployGas(
artifact: ZkSyncArtifact,
constructorArguments: any[],
deploymentType?: zk.types.DeploymentType,
): Promise<ethers.BigNumber> {
return await estimateDeployGas(this._hre, artifact, constructorArguments, this.zkWallet, deploymentType);
}

public async deploy(
contractNameOrArtifact: ZkSyncArtifact | string,
constructorArguments: any[] = [],
deploymentType?: zk.types.DeploymentType,
overrides?: ethers.Overrides,
additionalFactoryDeps?: ethers.BytesLike[],
): Promise<zk.Contract> {
Expand All @@ -61,7 +58,7 @@ export class Deployer implements AbstractDeployer {
contractNameOrArtifact,
constructorArguments,
this.zkWallet,
this.deploymentType,
deploymentType,
overrides,
additionalFactoryDeps,
);
Expand Down
1 change: 1 addition & 0 deletions packages/hardhat-zksync-deploy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ task(TASK_DEPLOY_ZKSYNC_CONTRACT, 'Runs the deploy scripts for zkSync network')
types.inputFile,
)
.addOptionalParam('deploymentType', 'Type of deployment', undefined)
.addOptionalParam('salt', 'Salt for deployment', undefined)
.addFlag('noCompile', 'Flag to disable auto compilation')
.setAction(deployZkSyncContract);
Loading

0 comments on commit e335357

Please sign in to comment.