Deploying Contract
Install zksync-ethers
The zksync-ethers package provides a modified version of the ethers library that is compatible with Abstract and the ZKsync VM. Install the package by running the following command:
npm install -D zksync-ethers
Set the deployer account private key
Create a new configuration variable
called DEPLOYER_PRIVATE_KEY
.
npx hardhat vars set DEPLOYER_PRIVATE_KEY
Enter the private key of a new wallet you created for this step.
✔ Enter value: · ****************************************************************
Do NOT use a private key associated with real funds. Create a new wallet for this step.
Get ETH in the deployer account
The deployer account requires ETH to deploy a smart contract.
- Testnet: Claim ETH via a faucet, or
bridge ETH from Sepolia.
- Mainnet: Use a bridge to transfer ETH to Abstract mainnet.
Write the deployment script
Create a new Hardhat script located at /deploy/deploy.ts
:
mkdir deploy && touch deploy/deploy.ts
Add the following code to the deploy.ts
file:
import { Wallet } from "zksync-ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync";
import { vars } from "hardhat/config";
// An example of a deploy script that will deploy and call a simple contract.
export default async function (hre: HardhatRuntimeEnvironment) {
console.log(`Running deploy script`);
// Initialize the wallet using your private key.
const wallet = new Wallet(vars.get("DEPLOYER_PRIVATE_KEY"));
// Create deployer object and load the artifact of the contract we want to deploy.
const deployer = new Deployer(hre, wallet);
// Load contract
const artifact = await deployer.loadArtifact("HelloAbstract");
// Deploy this contract. The returned object will be of a `Contract` type,
// similar to the ones in `ethers`.
const tokenContract = await deployer.deploy(artifact);
console.log(
`${
artifact.contractName
} was deployed to ${await tokenContract.getAddress()}`
);
}
Deploy your smart contract
Run the following command to deploy your smart contracts:
npx hardhat deploy-zksync --script deploy.ts --network abstractTestnet
If successful, your output should look similar to the following:
Running deploy script
HelloAbstract was deployed to YOUR_CONTRACT_ADDRESS
Providing constructor arguments
The second argument to the deploy
function is an array of constructor arguments.
To deploy your smart contract with constructor arguments, provide an array containing your constructor arguments as the second argument to the deploy
function.
import { Wallet } from "zksync-ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync";
import { vars } from "hardhat/config";
// An example of a deploy script that will deploy and call a simple contract.
export default async function (hre: HardhatRuntimeEnvironment) {
const wallet = new Wallet(vars.get("DEPLOYER_PRIVATE_KEY"));
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("HelloAbstract");
// Provide the constructor arguments
const constructorArgs = ["Hello, Abstract!"];
const tokenContract = await deployer.deploy(artifact, constructorArgs);
console.log(
`${
artifact.contractName
} was deployed to ${await tokenContract.getAddress()}`
);
}
Create2 & Smart Wallet Deployments
Specify different deployment types through using the third deploymentType
parameter:
- create: Standard contract deployment (default)
- create2: Deterministic deployment using CREATE2
- createAccount: Deploy a smart contract wallet.
- create2Account: Deterministic deployment of a smart contract wallet.
import { Wallet } from "zksync-ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync";
import { vars } from "hardhat/config";
export default async function (hre: HardhatRuntimeEnvironment) {
const wallet = new Wallet(vars.get("DEPLOYER_PRIVATE_KEY"));
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("HelloAbstract");
const deploymentType = "create2";
const tokenContract = await deployer.deploy(artifact, [], deploymentType);
console.log(
`${
artifact.contractName
} was deployed to ${await tokenContract.getAddress()}`
);
}
Additional Factory Dependencies
Factory smart contracts (contracts that can deploy other contracts) require the bytecode of the contracts they can deploy
to be provided within the factory dependencies array.
Learn more about factory dependencies.
import { Wallet } from "zksync-ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync";
// Additional bytecode dependencies (typically imported from artifacts)
const contractBytecode = "0x..."; // Your contract bytecode
const wallet = new Wallet(vars.get("DEPLOYER_PRIVATE_KEY"));
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("FactoryContract");
const contract = await deployer.deploy(
artifact,
["Hello world!"],
"create",
{},
[contractBytecode]
);