Contract deployment functionality with comprehensive options for deployment strategies, transaction settings, and artifact management.
Deploy a contract with full tracking and redeployment detection.
/**
* Deploy a contract with the given name and options
* @param name - Unique name for the deployment
* @param options - Deployment configuration options
* @returns Promise resolving to deployment result with status
*/
deploy(name: string, options: DeployOptions): Promise<DeployResult>;
interface DeployOptions {
/** Address to deploy from (required) */
from: string;
/** Contract artifact name or ArtifactData object */
contract?: string | ArtifactData;
/** Constructor arguments array */
args?: any[];
/** Enable deterministic deployment using CREATE2 */
deterministicDeployment?: boolean | string;
/** Proxy deployment configuration */
proxy?: boolean | string | ProxyOptions;
/** Library addresses for linking */
libraries?: Libraries;
/** Skip deployment if already deployed */
skipIfAlreadyDeployed?: boolean;
/** Gas limit for deployment transaction */
gasLimit?: string | number | BigNumber;
/** Gas price for deployment transaction */
gasPrice?: string | BigNumber;
/** EIP-1559 max fee per gas */
maxFeePerGas?: string | BigNumber;
/** EIP-1559 max priority fee per gas */
maxPriorityFeePerGas?: string | BigNumber;
/** Transaction nonce */
nonce?: string | number | BigNumber;
/** Ether value to send with deployment */
value?: string | BigNumber;
/** Enable deployment logging */
log?: boolean;
/** Auto-mine transaction on development networks */
autoMine?: boolean;
/** Number of confirmations to wait for */
waitConfirmations?: number;
/** Estimated gas limit for optimization */
estimatedGasLimit?: string | number | BigNumber;
/** Extra gas to add to estimates */
estimateGasExtra?: string | number | BigNumber;
/** Additional data for deployment tracking */
linkedData?: any;
/** Custom data for transaction (zksync support) */
customData?: Record<string, any>;
}Usage Examples:
import { deployments, getNamedAccounts } from "hardhat";
// Basic deployment
const { deployer } = await getNamedAccounts();
const result = await deployments.deploy("MyContract", {
from: deployer,
args: ["arg1", "arg2"],
log: true,
});
console.log(`Deployed at: ${result.address}`);
console.log(`Newly deployed: ${result.newlyDeployed}`);
// Deployment with libraries
await deployments.deploy("ContractWithLibrary", {
from: deployer,
libraries: {
MyLibrary: "0x1234567890123456789012345678901234567890",
},
log: true,
skipIfAlreadyDeployed: true,
});
// Custom contract artifact
await deployments.deploy("CustomContract", {
from: deployer,
contract: "contracts/Custom.sol:CustomContract",
args: [42],
gasLimit: 5000000,
});Get deterministic address and deploy function for CREATE2 deployments.
/**
* Get deterministic deployment address and deploy function
* @param name - Contract deployment name
* @param options - CREATE2 deployment options
* @returns Promise with address and deploy function
*/
deterministic(
name: string,
options: Create2DeployOptions
): Promise<{
address: Address;
implementationAddress?: Address;
deploy(): Promise<DeployResult>;
}>;
interface Create2DeployOptions extends DeployOptionsBase {
/** Salt for CREATE2 deployment */
salt?: string;
}
interface DeployOptionsBase extends TxOptions {
contract?: string | ArtifactData;
args?: any[];
skipIfAlreadyDeployed?: boolean;
linkedData?: any;
libraries?: Libraries;
proxy?: boolean | string | ProxyOptions;
}Usage Examples:
// Get deterministic address before deployment
const { address, deploy } = await deployments.deterministic("MyContract", {
from: deployer,
args: ["constructor", "args"],
salt: "0x1234567890123456789012345678901234567890123456789012345678901234",
});
console.log(`Will deploy to: ${address}`);
// Deploy when ready
const result = await deploy();
console.log(`Deployed to: ${result.address}`); // Same as address above
// Deterministic proxy deployment
const proxyInfo = await deployments.deterministic("ProxiedContract", {
from: deployer,
proxy: {
proxyContract: "OptimizedTransparentProxy",
execute: {
methodName: "initialize",
args: ["init", "args"],
},
},
salt: "0x1111111111111111111111111111111111111111111111111111111111111111",
});
console.log(`Proxy address: ${proxyInfo.address}`);
console.log(`Implementation address: ${proxyInfo.implementationAddress}`);Check if deployment would be different from existing deployment without deploying.
/**
* Check if deployment would be different from existing deployment
* @param name - Deployment name to check
* @param options - Deployment options to compare
* @returns Promise with difference status and address
*/
fetchIfDifferent(
name: string,
options: DeployOptions
): Promise<{ differences: boolean; address?: string }>;Usage Examples:
// Check if redeployment needed
const { differences, address } = await deployments.fetchIfDifferent("MyContract", {
from: deployer,
args: ["new", "args"],
});
if (differences) {
console.log("Contract needs redeployment");
await deployments.deploy("MyContract", {
from: deployer,
args: ["new", "args"],
});
} else {
console.log(`Contract unchanged at ${address}`);
}
// Check deterministic deployment
const deterministicCheck = await deployments.fetchIfDifferent("DeterministicContract", {
from: deployer,
deterministicDeployment: "0x1234567890123456789012345678901234567890123456789012345678901234",
args: ["test"],
});
if (!deterministicCheck.differences && deterministicCheck.address) {
console.log(`Already deployed at deterministic address: ${deterministicCheck.address}`);
}interface DeployResult extends Deployment {
/** Whether this deployment was newly created */
newlyDeployed: boolean;
}
interface Deployment {
/** Deployed contract address */
address: Address;
/** Contract ABI */
abi: ABI;
/** Deployment transaction receipt */
receipt?: Receipt;
/** Deployment transaction hash */
transactionHash?: string;
/** Constructor arguments used */
args?: any[];
/** Additional deployment data */
linkedData?: any;
/** Implementation address for proxies */
implementation?: string;
/** Diamond facets for diamond contracts */
facets?: Facet[];
/** Linked library addresses */
libraries?: Libraries;
/** Contract metadata */
metadata?: string;
/** Contract bytecode */
bytecode?: string;
/** Deployed bytecode */
deployedBytecode?: string;
/** Deployment history for upgrades */
history?: Deployment[];
/** Number of times deployed */
numDeployments?: number;
}
interface ArtifactData {
abi: ABI;
bytecode: string;
deployedBytecode?: string;
metadata?: string;
methodIdentifiers?: any;
storageLayout?: any;
userdoc?: any;
devdoc?: any;
gasEstimates?: any;
}
interface TxOptions extends CallOptions {
from: string;
log?: boolean;
autoMine?: boolean;
estimatedGasLimit?: string | number | BigNumber;
estimateGasExtra?: string | number | BigNumber;
waitConfirmations?: number;
}
interface CallOptions {
from?: string;
gasLimit?: string | number | BigNumber;
gasPrice?: string | BigNumber;
maxFeePerGas?: string | BigNumber;
maxPriorityFeePerGas?: string | BigNumber;
value?: string | BigNumber;
nonce?: string | number | BigNumber;
to?: string;
data?: string;
customData?: Record<string, any>;
}
type Libraries = { [libraryName: string]: Address };
type Address = string;
type ABI = any[];