@layerzerolabs/hardhat-deploy
Version:
Hardhat Plugin For Replicable Deployments And Tests
140 lines • 6.67 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeploymentFactory = void 0;
const ethers_1 = require("ethers");
const zk = __importStar(require("zksync-web3"));
const address_1 = require("@ethersproject/address");
const solidity_1 = require("@ethersproject/solidity");
const bytes_1 = require("@ethersproject/bytes");
const contract_1 = require("./tron/contract");
class DeploymentFactory {
constructor(getArtifact, artifact, args, network, ethersSigner, overrides = {}) {
this.overrides = overrides;
this.getArtifact = getArtifact;
this.isZkSync = network.zksync;
this.isTron = network.tron;
this.artifact = artifact;
if (this.isZkSync) {
this.factory = new zk.ContractFactory(artifact.abi, artifact.bytecode, ethersSigner);
}
else if (this.isTron) {
let contractName = '';
if ('contractName' in artifact)
({ contractName } = artifact);
this.factory = new contract_1.TronContractFactory(artifact.abi, artifact.bytecode, ethersSigner, contractName);
}
else {
this.factory = new ethers_1.ContractFactory(artifact.abi, artifact.bytecode, ethersSigner);
}
const numArguments = this.factory.interface.deploy.inputs.length;
if (args.length !== numArguments) {
throw new Error(`expected ${numArguments} constructor arguments, got ${args.length}`);
}
this.args = args;
}
// TODO add ZkSyncArtifact
async extractFactoryDeps(artifact) {
// Load all the dependency bytecodes.
// We transform it into an array of bytecodes.
const factoryDeps = [];
for (const dependencyHash in artifact.factoryDeps) {
const dependencyContract = artifact.factoryDeps[dependencyHash];
const dependencyBytecodeString = (await this.getArtifact(dependencyContract)).bytecode;
factoryDeps.push(dependencyBytecodeString);
}
return factoryDeps;
}
async getDeployTransaction() {
let overrides = this.overrides;
if (this.isZkSync) {
const factoryDeps = await this.extractFactoryDeps(this.artifact);
const customData = {
customData: {
factoryDeps,
feeToken: zk.utils.ETH_ADDRESS,
},
};
overrides = {
...overrides,
...customData,
};
}
return this.factory.getDeployTransaction(...this.args, overrides);
}
// TVM formula is identical than EVM except for the prefix: keccak256( 0x41 ++ address ++ salt ++ keccak256(init_code))[12:]
// https://developers.tron.network/v4.4.0/docs/vm-vs-evm#tvm-is-basically-compatible-with-evm-with-some-differences-in-details
async calculateEvmCreate2Address(create2DeployerAddress, salt, isTron) {
const deploymentTx = await this.getDeployTransaction();
if (typeof deploymentTx.data !== 'string') {
throw Error('unsigned tx data as bytes not supported');
}
const prefix = isTron ? '0x41' : '0xff';
return (0, address_1.getAddress)('0x' +
(0, solidity_1.keccak256)(['bytes'], [
`${prefix}${create2DeployerAddress.slice(2)}${salt.slice(2)}${(0, solidity_1.keccak256)(['bytes'], [deploymentTx.data]).slice(2)}`,
]).slice(-40));
}
async calculateZkCreate2Address(create2DeployerAddress, salt) {
const bytecodeHash = zk.utils.hashBytecode(this.artifact.bytecode);
const constructor = this.factory.interface.encodeDeploy(this.args);
return zk.utils.create2Address(create2DeployerAddress, bytecodeHash, salt, constructor);
}
async getCreate2Address(create2DeployerAddress, create2Salt) {
if (this.isZkSync)
return await this.calculateZkCreate2Address(create2DeployerAddress, create2Salt);
return await this.calculateEvmCreate2Address(create2DeployerAddress, create2Salt, this.isTron);
}
async compareDeploymentTransaction(transaction) {
const newTransaction = await this.getDeployTransaction();
const newData = newTransaction.data?.toString();
if (this.isZkSync) {
const EIP712_TX_TYPE = 0x71;
const bytes = (0, bytes_1.arrayify)(transaction.data);
// zk.utils.parseTransaction cannot parse tx others than eip712
if (bytes[0] != EIP712_TX_TYPE) {
return transaction.data !== newData;
}
const deserialize = zk.utils.parseTransaction(transaction.data);
const desFlattened = (0, bytes_1.hexConcat)(deserialize.customData.factoryDeps);
const factoryDeps = await this.extractFactoryDeps(this.artifact);
const newFlattened = (0, bytes_1.hexConcat)(factoryDeps);
return deserialize.data !== newData || desFlattened != newFlattened;
}
else if (this.isTron) {
const tronDeployTx = newTransaction;
const res = await this.factory.signer.getTronWebTransaction(transaction.hash);
const contract = res.raw_data.contract[0];
const deployed_bytecode = contract.parameter.value.new_contract?.bytecode;
const newBytecode = tronDeployTx.bytecode + tronDeployTx.rawParameter;
return deployed_bytecode !== newBytecode;
}
else {
return transaction.data !== newData;
}
}
}
exports.DeploymentFactory = DeploymentFactory;
//# sourceMappingURL=DeploymentFactory.js.map