Skip to content

Compilation artifacts formats

This is the reference documentation for the artifacts formats generated by Hardhat 3 when building Solidity files.

For the examples in this document, we’ll use this project:

  • Directoryexample-project
    • package.json
    • hardhat.config.ts
    • Directorycontracts/
      • Foo.sol with Foo and Foo2 contracts
      • Foo.t.sol with FooTest test contract
      • Directoryutils
        • Bar.sol with Bar contract
    • Directorytest/
      • Directoryutils
        • Bar.sol with BarTest test contract

If you run a clean build on this project with:

Terminal window
npx hardhat clean
npx hardhat build

you’ll get these new files:

  • Directoryexample-project
    • Directoryartifacts Contract artifacts and build infos
      • artifacts.d.ts
      • Directorybuild-info Build Info and Build Info Output files
        • solc-<solc-version>-<hash>.json
        • solc-<solc-version>-<hash>.output.json
      • Directorycontracts
        • DirectoryFoo.sol
          • artifacts.d.ts
          • Foo2.json
          • Foo.json
        • Directoryutils
          • DirectoryBar.sol
            • artifacts.d.ts
            • Bar.json
    • Directorycache
      • Directorytest-artifacts/ Test artifacts

Compiling with Hardhat generates a JSON artifact file per contract that it compiles. For example, the project above generates:

  • artifacts/contracts/Foo.sol/Foo.json
  • artifacts/contracts/Foo.sol/Foo2.json
  • artifacts/contracts/utils/Bar.sol/Bar.json

An artifact has all the information that is necessary to deploy and interact with the contract, and to identify which build it came from. These are compatible with most external tools, and mostly backwards compatible with Hardhat 2.

Each artifact consists of a JSON with the following properties:

  • _format: Always "hh3-artifact-1". This should only change in a new major version of Hardhat.

  • contractName: A string with the contract’s name.

  • sourceName: The name used to identify the file where the contract was located.

    • For local files, including those of git submodules, this is the path from the root of the project.
    • For npm artifacts, this is the npm module name as it would be used in an import in Node.js (e.g. before resolving package.json#exports), like @openzeppelin/contracts/token/ERC20/ERC20.sol.
  • abi: A JSON description of the contract’s ABI as provided by solc.

  • bytecode: A "0x"-prefixed hex string of the unlinked deployment bytecode. If the contract is not deployable, this has the string "0x".

  • deployedBytecode: A "0x"-prefixed hex string of the unlinked runtime/deployed bytecode. If the contract is not deployable, this has the string "0x".

  • linkReferences: The bytecode’s link references object as returned by solc. If the contract doesn’t need to be linked, this value contains an empty object. Note that the source names in this map are inputSourceNames (see below).

  • deployedLinkReferences: The deployed bytecode’s link references object as returned by solc. If the contract doesn’t need to be linked, this value contains an empty object. Note that the source names in this map are inputSourceNames (see below).

  • immutableReferences: The map of immutable references in the deployed bytecode, as returned by solc.

  • inputSourceName: The source name used to identify the file containing this contract in the solc input json used to build it.

    • For local files, including those of git submodules, this is the path from the root of the project, prefixed with project/.
    • For npm artifacts, this will have a different format which includes the package name, its version, and whether it comes from your monorepo or not.
  • buildInfoId: The id of the build that compiled this contract. This is a string with the format solc-<solc-version>-<hash>, where solc-version is the short version of solc with underscores instead of dots (e.g. 0_8_28 instead of 0.8.28), and the hash is a commitment to the entire build input.

Most of the time you’ll only work with sourceNames, as this is how Hardhat identifies Solidity files.

However, when you’re working with compilation-related concepts (like running solc or verifying a contract on a block explorer, which in turn runs solc), you need to understand the difference between them.

This is abstracted away from most users, who can ignore the distinction. It’s mainly relevant for plugin authors and advanced users.

Hardhat 3 generates TypeScript types for all of its artifacts automatically. This is done by creating an artifacts.d.ts file in each directory corresponding to a Solidity file, and a global one in artifacts/.

The artifacts.d.ts in each of the nested directories defines the types of each of its artifacts, and a Type Extension to the type ArtifactMap defined in hardhat/types/artifacts, mapping the bare contract name (e.g. Foo) and fully qualified contract name (e.g. contracts/Foo.sol:Foo) to their artifacts type.

This means that the types defined here will have concrete artifacts types, instead of just a generic one:

artifact-map-example.ts
import type { ArtifactMap } from "hardhat/types/artifacts";
type FooUsingBareName = ArtifactMap["Foo"];
type FooUsingFullyQualifiedName = ArtifactMap["contracts/Foo.sol:Foo"];

This is used to ensure that the APIs to deal with artifacts are well-typed. For example, FooArtifact and FooArtifactWithFQN here have concrete artifact types:

read-artifact-example.ts
import { artifacts } from "hardhat";
const FooArtifact = await artifacts.readArtifact("Foo");
const FooArtifactWithFQN = await artifacts.readArtifact(
"contracts/Foo.sol:Foo",
);

This is used by plugins like hardhat-viem to ensure that their contract interactions are typed.

The artifacts/artifacts.d.ts file is used to resolve name clashes between different contracts. It extends the ArtifactMap to make sure that the clashed bare contract name (e.g. Repeated if it were repeated) maps to never.

Each time Hardhat runs a Solidity compilation job successfully, it stores two files for it:

  • A Build Info file with all the information necessary to precisely reproduce the build.
  • A Build Info Output file which we use to provide extra debugging information when running your tests.

These are stored in the artifacts/build-info/ directory. In the example above they are:

  • artifacts/build-info/solc-<solc-version>-<hash>.json
  • artifacts/build-info/solc-<solc-version>-<hash>.output.json

As explained above, solc-version is the short version of solc with underscores instead of dots (e.g. 0_8_28 instead of 0.8.28), and the hash is a commitment to the entire build input.

These files always come in pairs, with their only difference in their name being the extension: .json for Build Info files, and .output.json for Build Info Output files.

Build Info files are JSON objects with the following properties:

  • _format: Always "hh3-sol-build-info-1". This may change for other compilers.

  • id: The identifier of this Build Info, which matches its file name, without an extension, and is used in the buildInfoId field of the artifact files. This field is a cryptographic commitment to the entirety of this file, except for the id itself.

  • solcVersion: The short version of solc used to compile this build (e.g. "0.8.28").

  • solcLongVersion: The long version as provided in the repository of solc official binaries, which includes more information about it (e.g. "0.8.28+commit.7893614a").

  • userSourceNameMap: A map from userSourceName to inputSourceName that includes the files for which this build was created, and whose artifacts were emitted as a result. We also call these files the “root files” or “entrypoints” of the build job.

  • input: The input JSON provided to solc.

Build Info Output files are JSON objects with the following properties:

  • _format: Always "hh3-sol-build-info-output-1".

  • id: Matches the id of the Build Info this file corresponds to.

  • output: The output JSON returned by solc.

The artifacts of Solidity test files are not considered part of the public API of Hardhat, and we may change them without previous notice to improve compilation performance or development experience.

They are stored in cache/test-artifacts and are untyped. No artifacts.d.ts are generated for them.