-
Notifications
You must be signed in to change notification settings - Fork 227
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: wrap deploy script run with era test node for the hardhat network
- Loading branch information
Showing
10 changed files
with
327 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import chalk from 'chalk'; | ||
import { Signer } from 'ethers'; | ||
import hre from 'hardhat'; | ||
|
||
async function main(){ | ||
console.info(chalk.yellow(`Running deploy script 002_deploy.ts`)); | ||
|
||
console.log(await hre.network.provider.send('eth_chainId')); | ||
console.info(chalk.yellow(`Running deploy script 002_deploy.ts`)); | ||
//Deploy Greeter contract with provided signer and name | ||
const signer = await hre.ethers.getSigner('0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'); | ||
const greets = await hre.ethers.deployContract('Greeter', ['Hello, world with loadArtifact!'], signer); | ||
await greets.waitForDeployment(); | ||
const greetsRunner = greets.runner as Signer; | ||
console.info(chalk.green(`Greeter deployed to: ${await greets.getAddress()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets.greet()}`)); | ||
const tx1 = await greets.setGreeting('Hello, world again with loadArtifact!'); | ||
await tx1.wait(); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets.greet()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greetsRunner.getAddress()}`)); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter contract deployed with name factory'); | ||
const greeterFactory1 = await hre.ethers.getContractFactory('Greeter', signer,); | ||
const greets2 = await greeterFactory1.deploy('Hello, world with name!'); | ||
await greets2.waitForDeployment(); | ||
const greets2Runner = greets2.runner as Signer; | ||
console.info(chalk.green(`Greeter deployed to: ${await greets2.getAddress()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets2.greet()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets2Runner.getAddress()}`)); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter contract deployed with abi and bytecode'); | ||
const artifact = await hre.artifacts.readArtifact('Greeter'); | ||
const greeterFactory2 = await hre.ethers.getContractFactory(artifact.abi, artifact.bytecode); | ||
const greets3 = await greeterFactory2.deploy('Hello, world with abi and bytecode!'); | ||
await greets3.waitForDeployment(); | ||
const greets3Runner = greets3.runner as Signer; | ||
console.info(chalk.green(`Greeter deployed to: ${await greets3.getAddress()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets3.greet()}`)); | ||
const tx = await greets3.setGreeting('Hello, world again with abi and bytecode!'); | ||
await tx.wait(); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets3.greet()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets3Runner.getAddress()}`)); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter contract deployed with artifact'); | ||
const greeterFactory3 = await hre.ethers.getContractFactoryFromArtifact(artifact); | ||
const greets4 = await greeterFactory3.deploy('Hello, world with artifact!'); | ||
await greets4.waitForDeployment(); | ||
const greets4Runner = greets4.runner as Signer; | ||
console.info(chalk.green(`Greeter deployed to: ${await greets4.getAddress()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets4.greet()}`)); | ||
const tx2 = await greets4.setGreeting('Hello, world again with artifact!'); | ||
await tx2.wait(); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets4.greet()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets4Runner.getAddress()}`)); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter contract deployed with factory and signer2'); | ||
const [,,signer2] = await hre.ethers.getSigners(); | ||
const greeterFactory4 = await hre.ethers.getContractFactory( | ||
'Greeter', | ||
signer2 | ||
); | ||
const greets5 = await greeterFactory4.deploy('Hello, world with name!'); | ||
await greets5.waitForDeployment(); | ||
const greets5Runner = greets5.runner as Signer; | ||
console.info(chalk.green(`Greeter deployed to: ${await greets5.getAddress()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets5.greet()}`)); | ||
const tx3 = await greets5.setGreeting('Hello, world again with name!'); | ||
await tx3.wait(); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets5.greet()}`)); | ||
console.info(chalk.green(`Greeter greeting set to: ${await greets5Runner.getAddress()}`)); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter get contract with name'); | ||
const signer3 = await hre.ethers.provider.getSigner('0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'); | ||
const contract1 = await hre.ethers.getContractAt('Greeter', await greets2.getAddress(), signer3); | ||
const contract1Runner = contract1.runner as Signer; | ||
console.info(chalk.green(`Greeter from getContractAt set to: ${await contract1.greet()}`)); | ||
console.info(chalk.green('Runner from getContractAt set to: ', await contract1Runner.getAddress())); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter get contract with abi'); | ||
const contract2 = await hre.ethers.getContractAt(artifact.abi, await greets3.getAddress()); | ||
console.info(chalk.green(`Greeter from getContractAt set to: ${await contract2.greet()}`)); | ||
const contract2Runner = contract2.runner as Signer; | ||
console.info(chalk.green('Runner from getContractAt set to: ', await contract2Runner.getAddress())); | ||
|
||
console.log('----------------------------------') | ||
|
||
console.log('Greeter get contract with artifact'); | ||
const contract3 = await hre.ethers.getContractAtFromArtifact(artifact, await greets4.getAddress()); | ||
console.info(chalk.green(`Greeter from getContractAt set to: ${await contract3.greet()}`)); | ||
const contract3Runner = contract3.runner as Signer; | ||
console.info(chalk.green('Runner from getContractAt set to: ', await contract3Runner.getAddress())); | ||
|
||
const newContractFactory = new hre.ethers.ContractFactory(artifact.abi, artifact.bytecode, signer); | ||
const deployedContract = await newContractFactory.deploy("Hello World with new contract factory."); | ||
console.info(chalk.green(`Contract with new ContractFactory deployed to ${await deployedContract.getAddress()}`)) | ||
|
||
const newContract = new hre.ethers.Contract(await deployedContract.getAddress(),artifact.abi,signer); | ||
console.info(await newContract.greet()); | ||
} | ||
|
||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Network } from 'hardhat/types'; | ||
|
||
export type ZKSyncTasksWithWrappedNode = typeof global & { | ||
_zkSyncTasksForWrapping: ZKSyncTasksForWrapping; | ||
_zkSyncNodeNetwork?: Network; | ||
}; | ||
|
||
export class ZKSyncTasksForWrapping { | ||
public taskNames: string[] = []; | ||
|
||
constructor() {} | ||
|
||
public addTask(taskName: string) { | ||
this.taskNames.push(taskName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
packages/hardhat-zksync-node/src/core/global-interceptor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { RunSuperFunction, TaskArguments } from 'hardhat/types'; | ||
import { GlobalWithHardhatContext } from 'hardhat/src/internal/context'; | ||
import { HARDHAT_NETWORK_NAME } from 'hardhat/plugins'; | ||
import { configureNetwork, startServer, waitForNodeToBeReady } from '../utils'; | ||
import { ZKSyncTasksWithWrappedNode } from './global-task'; | ||
|
||
export function interceptAndWrapTasksWithNode() { | ||
const zkSyncGlobal = global as ZKSyncTasksWithWrappedNode & GlobalWithHardhatContext; | ||
const taskMap = zkSyncGlobal.__hardhatContext.tasksDSL.getTaskDefinitions(); | ||
|
||
if (!zkSyncGlobal._zkSyncTasksForWrapping) { | ||
return; | ||
} | ||
|
||
zkSyncGlobal._zkSyncTasksForWrapping.taskNames.forEach((taskName) => { | ||
const foundTask = taskMap[taskName]; | ||
|
||
if (!foundTask) { | ||
return; | ||
} | ||
|
||
if (foundTask.isSubtask) { | ||
zkSyncGlobal.__hardhatContext.tasksDSL.subtask(foundTask.name, foundTask.description, wrapTaskWithNode); | ||
} | ||
|
||
zkSyncGlobal.__hardhatContext.tasksDSL.task(foundTask.name, foundTask.description, wrapTaskWithNode); | ||
}); | ||
} | ||
|
||
async function wrapTaskWithNode(taskArgs: TaskArguments, env: any, runSuper: RunSuperFunction<TaskArguments>) { | ||
if (env.network.zksync !== true || env.network.name !== HARDHAT_NETWORK_NAME) { | ||
return await runSuper(taskArgs); | ||
} | ||
const zkSyncGlobal = global as ZKSyncTasksWithWrappedNode; | ||
const { commandArgs, server, port } = await startServer(); | ||
try { | ||
await server.listen(commandArgs, false); | ||
await waitForNodeToBeReady(port); | ||
const oldNetwork = env.network; | ||
await configureNetwork(env.config, env.network, port); | ||
env.injectToGlobal(); | ||
zkSyncGlobal._zkSyncNodeNetwork = env.network; | ||
const result = await runSuper(taskArgs); | ||
env.network = oldNetwork; | ||
delete zkSyncGlobal._zkSyncNodeNetwork; | ||
env.injectToGlobal(); | ||
return result; | ||
} finally { | ||
await server.stop(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Network } from 'hardhat/types'; | ||
|
||
export type ZKSyncTasksWithWrappedNode = typeof global & { | ||
_zkSyncTasksForWrapping: ZKSyncTasksForWrapping; | ||
_zkSyncNodeNetwork?: Network; | ||
}; | ||
|
||
export class ZKSyncTasksForWrapping { | ||
public taskNames: string[] = []; | ||
|
||
constructor() {} | ||
|
||
public addTask(taskName: string) { | ||
this.taskNames.push(taskName); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { isRunningHardhatCoreTests } from 'hardhat/internal/core/execution-mode'; | ||
import { HardhatArguments } from 'hardhat/types'; | ||
import { getEnvVariablesMap } from 'hardhat/internal/core/params/env-variables'; | ||
import { HardhatContext } from 'hardhat/internal/context'; | ||
import { request } from 'http'; | ||
import { configureNetwork, startServer, waitForNodeToBeReady } from '../utils'; | ||
|
||
export async function runScript( | ||
scriptPath: string, | ||
scriptArgs: string[] = [], | ||
extraNodeArgs: string[] = [], | ||
extraEnvVars: { [name: string]: string } = {}, | ||
): Promise<number> { | ||
const { fork } = await import('child_process'); | ||
const processExecArgv = withFixedInspectArg(process.execArgv); | ||
|
||
const nodeArgs = [ | ||
...processExecArgv, | ||
...getTsNodeArgsIfNeeded(scriptPath, extraEnvVars.HARDHAT_TYPECHECK === 'true'), | ||
...extraNodeArgs, | ||
]; | ||
|
||
const envVars = { ...process.env, ...extraEnvVars }; | ||
|
||
return new Promise((resolve, reject) => { | ||
const childProcess = fork(scriptPath, scriptArgs, { | ||
stdio: 'inherit', | ||
execArgv: nodeArgs, | ||
env: envVars, | ||
}); | ||
|
||
let runnedServer: any; | ||
|
||
childProcess.on('spawn', () => { | ||
return new Promise(async (_, rejectChild) => { | ||
try { | ||
request('hardhat/register'); | ||
const ctx = HardhatContext.getHardhatContext(); | ||
const { commandArgs, server, port } = await startServer(); | ||
runnedServer = server; | ||
await server.listen(commandArgs, false); | ||
await waitForNodeToBeReady(port); | ||
await configureNetwork(ctx.environment!.config, ctx.environment!.network, port); | ||
} catch (error) { | ||
rejectChild(error); | ||
} | ||
}); | ||
}); | ||
|
||
childProcess.once('close', (status) => { | ||
runnedServer?.stop(); | ||
resolve(status as number); | ||
}); | ||
|
||
childProcess.once('error', (error) => { | ||
runnedServer?.stop(); | ||
reject(error); | ||
}); | ||
}); | ||
} | ||
|
||
export async function runScriptWithHardhat( | ||
hardhatArguments: HardhatArguments, | ||
scriptPath: string, | ||
scriptArgs: string[] = [], | ||
extraNodeArgs: string[] = [], | ||
extraEnvVars: { [name: string]: string } = {}, | ||
): Promise<number> { | ||
return runScript(scriptPath, scriptArgs, [...extraNodeArgs], { | ||
...getEnvVariablesMap(hardhatArguments), | ||
...extraEnvVars, | ||
}); | ||
} | ||
|
||
function withFixedInspectArg(argv: string[]) { | ||
const fixIfInspectArg = (arg: string) => { | ||
if (arg.toLowerCase().includes('--inspect-brk=')) { | ||
return '--inspect'; | ||
} | ||
return arg; | ||
}; | ||
return argv.map(fixIfInspectArg); | ||
} | ||
|
||
function getTsNodeArgsIfNeeded(scriptPath: string, shouldTypecheck: boolean): string[] { | ||
if (process.execArgv.includes('ts-node/register')) { | ||
return []; | ||
} | ||
|
||
// if we are running the tests we only want to transpile, or these tests | ||
// take forever | ||
if (isRunningHardhatCoreTests()) { | ||
return ['--require', 'ts-node/register/transpile-only']; | ||
} | ||
|
||
// If the script we are going to run is .ts we need ts-node | ||
if (/\.tsx?$/i.test(scriptPath)) { | ||
return ['--require', `ts-node/register${shouldTypecheck ? '' : '/transpile-only'}`]; | ||
} | ||
|
||
return []; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.