Hardhat plugin providing comprehensive deployment system for Ethereum smart contracts with replicable deployments and enhanced testing capabilities.
npx @tessl/cli install tessl/npm-hardhat-deploy@1.0.0Hardhat Deploy is a comprehensive Hardhat plugin that provides advanced deployment capabilities for Ethereum smart contracts. It enables replicable deployments across networks, enhanced testing with fixtures, proxy and diamond pattern support, named accounts for cleaner scripts, and automated contract verification.
npm install hardhat-deployhardhat ^2.22.18import "hardhat-deploy/type-extensions";For deploy scripts and configuration:
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";For use in tests:
import { deployments, getNamedAccounts } from "hardhat";Add to your hardhat.config.ts:
import "hardhat-deploy";
export default {
namedAccounts: {
deployer: {
default: 0, // Use first account as deployer
1: "0x...", // Override for mainnet
},
user: {
default: 1,
},
},
networks: {
localhost: {
live: false,
saveDeployments: true,
tags: ["local"],
},
},
};Create deploy/001_deploy_contract.ts:
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
await deploy("MyContract", {
from: deployer,
args: ["constructor", "arguments"],
log: true,
});
};
func.tags = ["MyContract"];
export default func;import { deployments, getNamedAccounts } from "hardhat";
describe("MyContract", function () {
beforeEach(async function () {
await deployments.fixture(["MyContract"]);
});
it("should work", async function () {
const { deployer } = await getNamedAccounts();
const contract = await deployments.get("MyContract");
// Test logic here
});
});Hardhat Deploy extends the Hardhat Runtime Environment with several key components:
Contract deployment with tracking, redeployment detection, and comprehensive deployment options including proxy and diamond patterns.
interface DeploymentsExtension {
deploy(name: string, options: DeployOptions): Promise<DeployResult>;
deterministic(
name: string,
options: Create2DeployOptions
): Promise<{
address: Address;
implementationAddress?: Address;
deploy(): Promise<DeployResult>;
}>;
fetchIfDifferent(
name: string,
options: DeployOptions
): Promise<{ differences: boolean; address?: string }>;
}
interface DeployOptions {
from: string;
contract?: string | ArtifactData;
args?: any[];
deterministicDeployment?: boolean | string;
proxy?: boolean | string | ProxyOptions;
libraries?: Libraries;
skipIfAlreadyDeployed?: boolean;
gasLimit?: string | number | BigNumber;
gasPrice?: string | BigNumber;
maxFeePerGas?: string | BigNumber;
maxPriorityFeePerGas?: string | BigNumber;
log?: boolean;
autoMine?: boolean;
waitConfirmations?: number;
}
interface DeployResult extends Deployment {
newlyDeployed: boolean;
}Deploy and upgrade transparent proxies with automatic implementation change detection and admin management.
interface ProxyOptions {
owner?: Address;
proxyContract?: string | ArtifactData;
implementationName?: string;
upgradeIndex?: number;
execute?: {
methodName: string;
args: any[];
} | {
init: { methodName: string; args: any[] };
onUpgrade?: { methodName: string; args: any[] };
};
}Full EIP-2535 diamond pattern support with automatic facet management and upgrade functionality.
interface DeploymentsExtension {
diamond: {
deploy(name: string, options: DiamondOptions): Promise<DeployResult>;
};
}
interface DiamondOptions extends TxOptions {
owner?: Address;
facets: DiamondFacets;
diamondContract?: string | ArtifactData;
execute?: {
methodName: string;
args: any[];
};
deterministicSalt?: string;
}
type DiamondFacets = Array<string | FacetOptions>;
interface FacetOptions {
name?: string;
contract?: string | ArtifactData;
args?: any[];
libraries?: Libraries;
deterministic?: boolean | string;
}Execute transactions and read contract state using deployed contract names with full type safety.
interface DeploymentsExtension {
execute(
name: string,
options: TxOptions,
methodName: string,
...args: any[]
): Promise<Receipt>;
read(
name: string,
options: CallOptions,
methodName: string,
...args: any[]
): Promise<any>;
read(name: string, methodName: string, ...args: any[]): Promise<any>;
rawTx(tx: SimpleTx): Promise<Receipt>;
}
interface TxOptions extends CallOptions {
from: string;
log?: boolean;
autoMine?: boolean;
waitConfirmations?: number;
}Fast test execution using EVM snapshots with automatic deployment and state management.
interface DeploymentsExtension {
fixture(
tags?: string | string[],
options?: {
fallbackToGlobal?: boolean;
keepExistingDeployments?: boolean;
}
): Promise<{ [name: string]: Deployment }>;
createFixture<T, O>(
func: FixtureFunc<T, O>,
id?: string
): (options?: O) => Promise<T>;
}
type FixtureFunc<T, O> = (
env: HardhatRuntimeEnvironment,
options?: O
) => Promise<T>;Address management system for cleaner deployment scripts and network-specific configurations.
interface HardhatRuntimeEnvironment {
getNamedAccounts(): Promise<{ [name: string]: Address }>;
getUnnamedAccounts(): Promise<string[]>;
getChainId(): Promise<string>;
}Store, retrieve, and manage deployment artifacts with comprehensive metadata tracking.
interface DeploymentsExtension {
save(name: string, deployment: DeploymentSubmission): Promise<void>;
get(name: string): Promise<Deployment>;
getOrNull(name: string): Promise<Deployment | null>;
delete(name: string): Promise<void>;
all(): Promise<{ [name: string]: Deployment }>;
run(
tags?: string | string[],
options?: {
resetMemory?: boolean;
deletePreviousDeployments?: boolean;
writeDeploymentsToFiles?: boolean;
export?: string;
exportAll?: string;
}
): Promise<{ [name: string]: Deployment }>;
// Utility functions
log(...args: any[]): void;
getNetworkName(): string;
getGasUsed(): number;
// File operations
readDotFile(name: string): Promise<string>;
saveDotFile(name: string, content: string): Promise<void>;
deleteDotFile(name: string): Promise<void>;
}
interface Deployment {
address: Address;
abi: ABI;
receipt?: Receipt;
transactionHash?: string;
args?: any[];
linkedData?: any;
implementation?: string;
facets?: Facet[];
libraries?: Libraries;
}Automated contract verification with Etherscan and Sourcify for source code transparency and public access.
function submitSources(
deploymentName: string,
options?: EtherscanVerificationOptions
): Promise<void>;
function submitSourcesToSourcify(
deploymentName: string,
options?: SourcifyVerificationOptions
): Promise<void>;
function etherscanVerify(options?: EtherscanVerificationOptions): Promise<void>;
function sourcifyVerify(options?: SourcifyVerificationOptions): Promise<void>;
interface EtherscanVerificationOptions {
apiKey?: string;
apiUrl?: string;
license?: string;
forceLicense?: boolean;
solcInput?: boolean;
sleep?: number;
}
interface SourcifyVerificationOptions {
endpoint?: string;
writeFailingMetadata?: boolean;
}type Address = string;
type ABI = any[];
type Libraries = { [libraryName: string]: Address };
interface Receipt {
from: Address;
transactionHash: string;
blockHash: string;
blockNumber: number;
gasUsed: BigNumber | string | number;
contractAddress?: string;
logs?: Log[];
status?: number;
}
interface DeployFunction {
(env: HardhatRuntimeEnvironment): Promise<void | boolean>;
skip?: (env: HardhatRuntimeEnvironment) => Promise<boolean>;
tags?: string[];
dependencies?: string[];
runAtTheEnd?: boolean;
id?: string;
}
interface ArtifactData {
abi: ABI;
bytecode: string;
deployedBytecode?: string;
metadata?: string;
}