Developer Quickstart

Getting starting developing with ZKsync OS
You can use all standard EVM tooling for ZKsync OS. You can find instructions for bridging testnet ETH to ZKsync OS Developer Preview testnet in the Network Details page.

To get started with Foundry or Hardhat, follow the steps below:

  1. Create a new foundry project:
    forge init Counter
    cd Counter
    
  2. Build the project
    forge build
    
  3. Set your private key for deploying:
    export TESTNET_PRIVATE_KEY="0x..."
    
  4. Deploy the contract:
    forge script script/Counter.s.sol --rpc-url https://zksync-os-testnet-alpha.zksync.dev --broadcast --private-key $TESTNET_PRIVATE_KEY
    
  5. Set the number value:
    cast send 0xCA1386680bfd9D89c7cc6Fc3ba11938ba6E44fef \
    "setNumber(uint256)" 5 \
    --rpc-url https://zksync-os-testnet-alpha.zksync.dev \
    --private-key $TESTNET_PRIVATE_KEY
    
  6. Get the latest number value:
    cast call 0xCA1386680bfd9D89c7cc6Fc3ba11938ba6E44fef \
    "number()" \
    --rpc-url https://zksync-os-testnet-alpha.zksync.dev
    
  1. Create a new project folder
    mkdir hardhat-example
    cd hardhat-example
    
  1. Initialize a new Hardhat 3 project with Node Test Runner and Viem.
    npx hardhat --init
    
  1. Add ZKsync OS to the hardhat.config.ts file and configure the ignition required confirmations.
      ignition: {
        requiredConfirmations: 1,
      },
      networks: {
        zksyncOS: {
          type: 'http',
          chainType: 'generic',
          url: 'https://zksync-os-testnet-alpha.zksync.dev',
          accounts: [configVariable('TESTNET_PRIVATE_KEY')],
        },
      },
    
  2. Add your private key to the keystore as TESTNET_PRIVATE_KEY.
    npx hardhat keystore set TESTNET_PRIVATE_KEY
    
  3. Compile and deploy the example contract.
    npx hardhat compile
    
    npx hardhat ignition deploy ignition/modules/Counter.ts --network zksyncOS
    
  4. Create a new script file in the scripts folder called increment.ts.
    touch scripts/increment.ts
    
  1. Copy/paste the script below.
    increment.ts
    import { network } from 'hardhat';
    import { type Abi, defineChain } from 'viem';
    
    const CONTRACT_ADDRESS = '0x7Be3f2d08500Fe75B92b9561287a16962C697cb7';
    
    const { viem } = await network.connect('zksyncOS');
    
    const zksyncOS = defineChain({
      id: 8022833,
      name: 'ZKsync OS',
      network: 'zksyncOS',
      nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
      rpcUrls: { default: { http: ['https://zksync-os-testnet-alpha.zksync.dev'] } },
    });
    
    const publicClient = await viem.getPublicClient({ chain: zksyncOS });
    const [senderClient] = await viem.getWalletClients({ chain: zksyncOS });
    if (!senderClient) throw new Error('No wallet client. Set TESTNET_PRIVATE_KEY in hardhat config.');
    
    const counterContract = await viem.getContractAt('Counter', CONTRACT_ADDRESS, {
      client: { public: publicClient, wallet: senderClient },
    });
    
    const initialCount = await publicClient.readContract({
      address: CONTRACT_ADDRESS,
      abi: counterContract.abi as Abi,
      functionName: 'x',
    });
    console.log('Initial count:', initialCount);
    
    const tx = await senderClient.writeContract({
      address: CONTRACT_ADDRESS,
      abi: counterContract.abi as Abi,
      functionName: 'inc',
    });
    await publicClient.waitForTransactionReceipt({ hash: tx });
    console.log('Transaction sent successfully');
    
    const newCount = await publicClient.readContract({
      address: CONTRACT_ADDRESS,
      abi: counterContract.abi as Abi,
      functionName: 'x',
    });
    console.log('New count:', newCount);
    
  1. Run the script
    npx hardhat run scripts/increment.ts
    
  1. Create a new project folder
    mkdir hardhat-example
    cd hardhat-example
    
  1. Initialize a new Hardhat 3 project with Mocha and Ethers.js.
    npx hardhat --init
    
  1. Add ZKsync OS to the hardhat.config.ts file and configure the ignition required confirmations.
      ignition: {
        requiredConfirmations: 1,
      },
      networks: {
        zksyncOS: {
          type: 'http',
          chainType: 'generic',
          url: 'https://zksync-os-testnet-alpha.zksync.dev',
          accounts: [configVariable('TESTNET_PRIVATE_KEY')],
        },
      },
    
  2. Add your private key to the keystore as TESTNET_PRIVATE_KEY.
    npx hardhat keystore set TESTNET_PRIVATE_KEY
    
  3. Compile and deploy the example contract.
    npx hardhat compile
    
    npx hardhat ignition deploy ignition/modules/Counter.ts --network zksyncOS
    
  4. Create a new script file in the scripts folder called increment.ts.
    touch scripts/increment.ts
    
  1. Copy/paste the script below.
    increment.ts
    import { network } from 'hardhat';
    
    const CONTRACT_ADDRESS = '0x8e882b31Fe1d3942c57408D354E754d1659400a7';
    
    const { ethers } = await network.connect({
      network: 'zksyncOS',
      chainType: 'generic',
    });
    
    const [sender] = await ethers.getSigners();
    
    const contract = await ethers.getContractAt('Counter', CONTRACT_ADDRESS, sender);
    
    const initialCount = await contract.x();
    console.log('Initial count:', initialCount);
    
    const tx = await contract.inc();
    await tx.wait();
    console.log('Transaction sent successfully');
    
    const newCount = await contract.x();
    console.log('New count:', newCount);
    
  1. Run the script
    npx hardhat run scripts/increment.ts
    

Made with ❤️ by the ZKsync Community