ZKSync 时代和 create2 地址

huangapple go评论58阅读模式
英文:

ZKSync Era and create2 address

问题

I have a very simple contract that acts as a factory to deploy a child contract. I cannot for the life of me get the create2Address calculated ahead of time to be the actual value that the child contract deploys to. Can anyone see where I'm going wrong? Thank you!

Factory.sol

import "./Child.sol";

contract Factory {
    event ContractDeployed(address indexed contractAddress);

    function deployContract(bytes32 _salt) public returns (address) {
        Child c = new Child{salt: _salt}();
        address addr = address(c);

        emit ContractDeployed(addr);

        return addr;
    }
}

Child.sol

contract Child {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function getOwner() public view returns (address) {
        return owner;
    }
}

Deploy script

import { Wallet, utils, Provider, Contract } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import { Factory } from "../typechain-types/Factory";
import { ContractDeployer } from "../typechain-types/ContractDeployer";
import { bytecode as childBytecode } from "../artifacts-zk/contracts/Child.sol/Child.json";
import { abi as contractDeployerABI } from "../artifacts-zk/contracts/ContractDeployer.sol/ContractDeployer.json";

// yarn hardhat deploy-zksync --script

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";

if (!PRIVATE_KEY)
  throw "⛔️ Private key not detected! Add it to the .env file!";

// 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 for the Factory contract`);

  // Initialize the wallet.
  const provider = new Provider('http://localhost:3050');
  const wallet = new Wallet(PRIVATE_KEY, provider);

  // Create deployer object and load the artifact of the contract you want to deploy.
  const deployer = new Deployer(hre, wallet);

  /* *** DEPLOY FACTORY *** */
  const artifact = await deployer.loadArtifact("Factory");
  const factory = await deployer.deploy(artifact, []) as Factory;

  // Show the contract info
  const contractAddress = factory.address;
  console.log(`${artifact.contractName} was deployed to ${contractAddress}`);

  console.log(' ')
  console.log('------------------------------------------------------------------------------------------')
  console.log(' ')

  const salt = '0x0000000000000000000000000000000000000000000000000000000000000001';

  console.log(`wallet.address: ${factory.address}`);
  console.log('bytecode keccak256: ' + ethers.utils.keccak256(childBytecode));
  console.log('salt: ' + salt);
  console.log('input: 0x');

  const contractDeployer = new Contract(utils.CONTRACT_DEPLOYER_ADDRESS, contractDeployerABI, wallet) as ContractDeployer;
  let calc_address1 = await contractDeployer.getNewAddressCreate2(factory.address, ethers.utils.keccak256(childBytecode), salt, '0x');
  console.log(`Calculated create2 address from contract deployer: ${calc_address1}`);

  const calc_address2 = utils.create2Address(factory.address, ethers.utils.keccak256(childBytecode), salt, '0x');
  console.log('Calculated create2 address from sdk: ' + calc_address2);

  let nonce = await wallet.getNonce();

  let calc_address3 = await contractDeployer.getNewAddressCreate(factory.address, nonce);
  console.log(`Calculated create address from contract deployer: ${calc_address3}`);

  const calc_address4 = utils.createAddress(factory.address, nonce);
  console.log('Calculated create address from sdk: ' + calc_address4);

  let tx = await factory.deployContract(salt);
  let receipt = await tx.wait();

  console.log(`Deployed address: ${receipt.events[2].args[0]}`);
}

Output

Running deploy script for the Factory contract
Factory was deployed to 0x506D7fee857E5aaea623916880975d133bb2b8e1
------------------------------------------------------------------------------------------
factory.address: 0x506D7fee857E5aaea623916880975d133bb2b8e1
bytecode keccak256: 0x59d901a05c8205d98ffe460633af71ae85d2575403ff114fa174966955402589
salt: 0x0000000000000000000000000000000000000000000000000000000000000001
input: 0x
Calculated create2 address from contract deployer: 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7
Calculated create2 address from sdk: 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7
Calculated create address from contract deployer: 0xE15D9682F868245dEAe7a243ca2CeD50A9BFc110
Calculated create address from sdk: 0xE15D9682F868245dEAe7a243ca2CeD50A9BFc110
Deployed address: 0xdc6B8789E7eC924e137e4258F044c4766EbB2b6b
Done in 2.89s.

I was expecting to see address 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7 deployed to. Instead, it deploys to 0xdc6B8789E7eC924e137e4258F044c4766EbB2b6b.

英文:

I have a very simple contract that acts as a factory to deploy a child contract. I cannot for the life of me get the create2Address calculated ahead of time to be the actual value that the child contract deploys to. Can anyone see where I'm going wrong? Thank you!

Factory.sol

import "./Child.sol";

contract Factory {
    event ContractDeployed(address indexed contractAddress);

    function deployContract(bytes32 _salt) public returns (address) {
        Child c = new Child{salt: _salt}();
        address addr = address(c);

        emit ContractDeployed(addr);

        return addr;
    }
}

Child.sol

contract Child {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function getOwner() public view returns (address) {
        return owner;
    }
}

Deploy script

import { Wallet, utils, Provider, Contract } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import { Factory } from "../typechain-types/Factory";
import { ContractDeployer } from "../typechain-types/ContractDeployer";
import { bytecode as childBytecode } from "../artifacts-zk/contracts/Child.sol/Child.json";
import { abi as contractDeployerABI } from "../artifacts-zk/contracts/ContractDeployer.sol/ContractDeployer.json";

// yarn hardhat deploy-zksync --script

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";

if (!PRIVATE_KEY)
  throw "⛔️ Private key not detected! Add it to the .env file!";

// 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 for the Factory contract`);

  // Initialize the wallet.
  const provider = new Provider('http://localhost:3050');
  const wallet = new Wallet(PRIVATE_KEY, provider);

  // Create deployer object and load the artifact of the contract you want to deploy.
  const deployer = new Deployer(hre, wallet);

  /* *** DEPLOY FACTORY *** */
  const artifact = await deployer.loadArtifact("Factory");
  const factory = await deployer.deploy(artifact, []) as Factory;

  // Show the contract info
  const contractAddress = factory.address;
  console.log(`${artifact.contractName} was deployed to ${contractAddress}`);

  console.log(' ')
  console.log('------------------------------------------------------------------------------------------')
  console.log(' ')

  const salt = '0x0000000000000000000000000000000000000000000000000000000000000001';

  console.log(`wallet.address: ${factory.address}`);
  console.log('bytecode keccak256: ' + ethers.utils.keccak256(childBytecode));
  console.log('salt: ' + salt);
  console.log('input: 0x');

  const contractDeployer = new Contract(utils.CONTRACT_DEPLOYER_ADDRESS, contractDeployerABI, wallet) as ContractDeployer;
  let calc_address1 = await contractDeployer.getNewAddressCreate2(factory.address, ethers.utils.keccak256(childBytecode), salt, '0x');
  console.log(`Calculated create2 address from contract deployer: ${calc_address1}`);

  const calc_address2 = utils.create2Address(factory.address, ethers.utils.keccak256(childBytecode), salt, '0x');
  console.log('Calculated create2 address from sdk: ' + calc_address2);

  let nonce = await wallet.getNonce();

  let calc_address3 = await contractDeployer.getNewAddressCreate(factory.address, nonce);
  console.log(`Calculated create address from contract deployer: ${calc_address3}`);

  const calc_address4 = utils.createAddress(factory.address, nonce);
  console.log('Calculated create address from sdk: ' + calc_address4);

  let tx = await factory.deployContract(salt);
  let receipt = await tx.wait();

  console.log(`Deployed address: ${receipt.events[2].args[0]}`);
}

Output

Running deploy script for the Factory contract
Factory was deployed to 0x506D7fee857E5aaea623916880975d133bb2b8e1
------------------------------------------------------------------------------------------
factory.address: 0x506D7fee857E5aaea623916880975d133bb2b8e1
bytecode keccak256: 0x59d901a05c8205d98ffe460633af71ae85d2575403ff114fa174966955402589
salt: 0x0000000000000000000000000000000000000000000000000000000000000001
input: 0x
Calculated create2 address from contract deployer: 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7
Calculated create2 address from sdk: 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7
Calculated create address from contract deployer: 0xE15D9682F868245dEAe7a243ca2CeD50A9BFc110
Calculated create address from sdk: 0xE15D9682F868245dEAe7a243ca2CeD50A9BFc110
Deployed address: 0xdc6B8789E7eC924e137e4258F044c4766EbB2b6b
Done in 2.89s.

I was expecting to see address 0x9b0dFF8F40c7dEb76754730eC348d849b747aba7 deployed to. Instead, it deploys to 0xdc6B8789E7eC924e137e4258F044c4766EbB2b6b.

答案1

得分: 1

Replacing ethers.utils.keccak256(childBytecode) with utils.hashBytecode() from zksync-web3 works.

const calc_address2 = utils.create2Address(factory.address, utils.hashBytecode(childBytecode), salt, '0x');

英文:

Replacing ethers.utils.keccak256(childBytecode) with utils.hashBytecode() from zksync-web3 works.

const calc_address2 = utils.create2Address(factory.address, utils.hashBytecode(childBytecode), salt, '0x');

huangapple
  • 本文由 发表于 2023年5月7日 07:04:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定