英文:
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');
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论