Skip to content

Latest commit

 

History

History
495 lines (435 loc) · 20.8 KB

deployment-artifacts.md

File metadata and controls

495 lines (435 loc) · 20.8 KB

Deployment Artifacts

Deployment artifacts contain the information for deployments executed with Sphinx. This guide will describe how to generate deployment artifacts, how they're written to the file system, and what they contain.

Table of Contents

Usage

CLI Deploy Command

If you're using Sphinx to execute a deployment from your local machine instead of the DevOps Platform, Sphinx will automatically write deployment artifacts to your file system after the deployment completes. The deployment artifacts have the same format as artifacts generated by the DevOps Platform.

DevOps Platform

You can retrieve deployment artifacts from the DevOps Platform with a CLI command. This command fetches the deployment artifacts from Sphinx's backend then writes them to your file system. Sphinx will generate deployment artifacts for all of the previous deployments for a given project name and organization ID, which are the config options projectName and orgId in your deployment script.

To run this command, you must have a Sphinx API Key as an environment variable:

SPHINX_API_KEY=<your_key>

To generate artifacts, run one of the following commands on your command line, replacing the placeholders with your values.

Using Yarn or npm:

npx sphinx artifacts --org-id <ORG_ID> --project-name <PROJECT_NAME>

Using pnpm:

pnpm sphinx artifacts --org-id <ORG_ID> --project-name <PROJECT_NAME>

CLI Options

  • --org-id <ORG_ID>: Required. Your Sphinx organization ID. You can either retrieve this from the Sphinx UI (under "Options" -> "API Credentials") or from the sphinxConfig.orgId config option in your deployment script.
  • --project-name <PROJECT_NAME>: Required. The name of your project. You can retrieve this from the sphinxConfig.projectName config option in your deployment script.
  • --silent: Optional. Silence the output except for error messages.

Example Usage

  1. Retrieve deployment artifacts for the project named "MyFirstProject" with the organization ID "my-org-id":
    npx sphinx artifacts --org-id "my-org-id" --project-name "MyFirstProject"

Directory Structure

Deployment artifacts are stored in a deployments/ directory in your project root. A typical directory will look like this:

deployments
├── MyFirstProject
│   ├── ethereum
│   │   ├── MyEthereumContract.json
│   │   ├── MyToken.json
│   │   └── execution
│   │       └── d20413df61249264cb87e816a7e4b2cff094f8ee9cb4f13cb6166539410a5d57.json
│   └── sepolia
│       ├── MySepoliaContract.json
│       └── execution
│           └── 7624778dedc75f8b322b9fa1632a610d40b85e106c7d9bf0e743a9ce291b9c6f.json
└── compiler-inputs
    └── 81b63eb8d29060639640c5317310fa04.json

We'll describe each aspect below.

Contract Deployment Artifact

A contract deployment artifact represents a contract that was deployed on a network. It includes detailed information about the contract, such as the transaction receipt of the deployment, ABI, bytecode, and other relevant data. It also includes the artifacts for previous versions of the contract; see the history field for more details.

File Path

Sphinx writes contract deployment artifacts to the file system at the following location:

deployments/<PROJECT_NAME>/<NETWORK_NAME>/<CONTRACT_NAME>.json
  • <PRROJECT_NAME>: The name of your project, which is sphinxConfig.projectName in your deployment script.
  • <NETWORK_NAME>: The string name of the network, which is determined by the network's chain ID. If you're deploying on Anvil, the network name will be appended with -local (e.g. ethereum-local).
  • <CONTRACT_NAME>: The name of the contract. If a single deployment contains more than one contract with the same name, the contract deployed first will have a standard file name (e.g. MyContract.json), then the next contract will be appended with _1 (e.g. MyContract_1.json), then the next will be appended with _2, etc.

Example file path: deployments/ethereum/MyContract.json

Type Definition

type ContractDeploymentArtifact = {
  _format: 'sphinx-sol-ct-artifact-1'
  merkleRoot: string
  address: string
  sourceName: string
  contractName: string
  chainId: string
  receipt: SphinxTransactionReceipt
  args: Array<any>
  solcInputHash: string
  abi: Array<any>
  bytecode: string
  deployedBytecode: string
  linkReferences: LinkReferences
  deployedLinkReferences: LinkReferences
  history: Array<Omit<ContractDeploymentArtifact, 'history'>>
  metadata: string
  gitCommit: string | null
  devdoc?: any
  userdoc?: any
}

Properties

  • _format: The format of the contract deployment artifact.
  • merkleRoot: The Merkle root of the deployment.
  • contractName: The name of the contract.
  • address: The address of the contract.
  • abi: The ABI of the contract.
  • solcInputHash: The hash of the Solidity compiler input that contains this contract.
  • receipt: The transaction receipt of the contract deployment.
  • metadata: The metadata of the contract as returned by the Solidity compiler.
  • args: The constructor arguments.
  • bytecode: The creation bytecode of the contract. This does not include the constructor arguments.
  • deployedBytecode: The deployed bytecode. This was fetched on-chain after the contract was deployed.
  • gitCommit: The full git commit hash on the machine that initiated the deployment. If the deployment was executed via the DevOps Platform, this is recorded on the machine that proposed the deployment. If the deployment was executed from the user's local machine instead of the DevOps Platform, this is recorded on the user's machine when they run the deploy CLI command. This is undefined if the repository was not a git repository when the deployment was initiated.
  • sourceName: The source name of the contract.
  • chainId: The chain ID.
  • linkReferences: The creation bytecode's link references object as returned by the Solidity compiler. If the contract doesn't need to be linked, this value contains an empty object.
  • deployedLinkReferences: The deployed bytecode's link references object as returned by the Solidity compiler. If the contract doesn't need to be linked, this value contains an empty object.
  • history: The history of the contract. Each element in the array is a previous contract deployment artifact with the history field omitted to avoid nesting. The elements are sorted chronologically from earliest to latest. Sphinx organizes the history according to the contractName. For example, if a project deploys a contract named "MyContract" in three separate deployments, then the first element in the history array will be the first deployment, the second element in the array will be the second deployment, and the top-level artifact will be the most recent deployment.
  • devdoc (optional): The developer documentation of the contract as returned by the Solidity compiler (optional).
  • userdoc (optional): The user documentation of the contract as returned by the Solidity compiler (optional).

Example

{
  "_format": "sphinx-sol-ct-artifact-1",
  "merkleRoot": "0x82a1b9e8a08f2cb3d2e27436cd04c431e483664adea8205dcf803fdd88a933bd",
  "contractName": "MyContract1",
  "address": "0x08c8165165622cDd39f7AE82d5713Fc64f505c58",
  "abi": [
    {
      "type": "constructor",
      "inputs": [
        {
          "name": "_intArg",
          "type": "int256",
          "internalType": "int256"
        }
      ],
      "stateMutability": "nonpayable"
    }
  ],
  "solcInputHash": "4f272ce1ce80603b2d5182ac007dd7b0",
  "receipt": {
    "blockHash": "0xb423cadaeba522a2c64145a2461201ec7c8e17d4449f9e83a275820dedc93ce5",
    "blockNumber": 20,
    "contractAddress": null,
    "cumulativeGasUsed": "2355953",
    "from": "0xedEaEec55fD20Ab348a934b1a4E8c9B26EE1645b",
    "gasPrice": "1293848917",
    "gasUsed": "2355953",
    "hash": "0xb5e63fd29bf5cda827a52515f756a22734c4fa852912f6df526c7ecabda6fc7c",
    "index": 0,
    "logs": [
      {
        "address": "0xB5E96127D417b1B3ef8438496a38A143167209c7",
        "blockHash": "0xb423cadaeba522a2c64145a2461201ec7c8e17d4449f9e83a275820dedc93ce5",
        "blockNumber": 20,
        "data": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "index": 0,
        "topics": [
          "0x572f161235911da04685a68c06adf558fc7e4a36909dca394650e0adc19cc93d",
          "0x000000000000000000000000edeaeec55fd20ab348a934b1a4e8c9b26ee1645b",
          "0x000000000000000000000000c7758246bb22b2012c81459d7084f1a890374452",
          "0x489a6f103fcaaf93acfa3368a0152c3ea81f3d1e24cbd33b97237f468e39c58c"
        ],
        "transactionHash": "0xb5e63fd29bf5cda827a52515f756a22734c4fa852912f6df526c7ecabda6fc7c",
        "transactionIndex": 0
      }
    ],
    "logsBloom": "0x00000000004030000000000000080000000000000008...", // Truncated for conciseness
    "status": 1,
    "to": "0xB5E96127D417b1B3ef8438496a38A143167209c7"
  },
  "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\"...", // Truncated for conciseness
  "args": [
    "Hi",
    "0x0000000000000000000000000000000000000003"
  ],
  "bytecode": "0x60806040523480156200001157600080fd5b5060405162000052...", // Truncated for conciseness
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004375c...", // Truncated for conciseness
  "gitCommit": "88a023502161a4be85b4b4340e1066c03f60ce54",
  "sourceName": "contracts/test/MyContracts.sol",
  "chainId": "11155111",
  "linkReferences": {},
  "deployedLinkReferences": {},
  "history": [],
  "devdoc": {
    "kind": "dev",
    "methods": {},
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
}

Execution Artifact

An execution artifact contains detailed information about a deployment that was executed on a network. Each artifact includes the transaction receipts, configuration settings, and contract addresses, such as the Gnosis Safe and Sphinx Module. For multi-chain deployments, there will be one execution artifact for each network.

File Path

Sphinx writes execution artifacts to the file system at the following location:

deployments/<PROJECT_NAME>/<NETWORK_NAME>/execution/<MERKLE_ROOT>.json

An example of an execution artifact path:

deployments/MyProject/ethereum/execution/d20413df61249264cb87e816a7e4b2cff094f8ee9cb4f13cb6166539410a5d57.json

The artifact in this example contains the deployment executed on Ethereum that has a Merkle root of d20413....

Type Definition

type ExecutionArtifact = {
  _format: 'sphinx-sol-execution-artifact-1'
  transactions: Array<{
    response: SphinxTransactionResponse
    receipt: SphinxTransactionReceipt
  }>
  merkleRoot: string
  solcInputHashes: Array<string>
  safeAddress: string
  moduleAddress: string
  executorAddress: string
  nonce: string
  chainId: string
  actions: Array<SphinxTransaction>
  sphinxConfig: {
    projectName: string
    orgId: string
    owners: Array<string>
    mainnets: Array<string>
    testnets: Array<string>
    threshold: string
    saltNonce: string
  }
  executionMode: number
  initialState: {
    isSafeDeployed: boolean
    isModuleDeployed: boolean
    isExecuting: boolean
  }
  unlabeledContracts: Array<{
    address: string
    initCodeWithArgs: string
  }>
  arbitraryChain: boolean
  libraries: Array<string>
  gitCommit: string | null
  safeInitData: string | null
}

Properties

  • _format: The format of the execution artifact.
  • transactions: This array includes each transaction response with its receipt, sorted in ascending order chronologically. For new Gnosis Safe deployments, the first transaction deploys the Safe, the second approves the deployment, and the rest execute the deployment. For existing Safes, the first transaction approves the deployment, and the rest execute the deployment.
  • merkleRoot: The Merkle root of the deployment.
  • solcInputHashes: The full list of Solidity compiler hashes used for the deployment.
  • safeAddress: The address of the Gnosis Safe.
  • moduleAddress: The address of the Sphinx Module.
  • executorAddress: The address of the executor.
  • nonce: The nonce.
  • chainId: The chain ID.
  • actions: An array of Sphinx transactions, which are the encoded inputs to the deployment.
  • sphinxConfig: The configuration options in the deployment script.
  • executionMode: Whether the deployment was executed on a local network via the CLI (0), on a live network via the CLI (1), or via the DevOps Platform (2).
  • initialState: On-chain state variables that were recorded before the deployment was executed.
  • unlabeledContracts: An array of contracts Sphinx couldn't find an artifact for. These contracts won't be verified on block explorers, and Sphinx will not create a deployment artifact for them. If a contract does not have a source file, it will be in this array. Common examples are minimal CREATE3 or EIP-1167 proxies.
  • arbitraryChain: Indicates whether the deployment can be executed on an arbitrary chain. Currently always false.
  • libraries: An array of libraries that were used in the deployment. These are in the format that the Solidity compiler expects. For example, path/to/file.sol:MyLibrary=0x1234567890123456789012345678901234567890.
  • gitCommit: The full git commit hash on the machine that initiated the deployment. If the deployment was executed via the DevOps Platform, this is recorded on the machine that proposed the deployment. If the deployment was executed from the user's local machine instead of the DevOps Platform, this is recorded on the user's machine when they run the deploy CLI command. This is null if the repository was not a git repository when the deployment was initiated.
  • safeInitData: The raw data that deployed and initialized the Gnosis Safe. This is null for deployments that use a previously deployed Gnosis Safe.

Example

{
  "_format": "sphinx-sol-execution-artifact-1",
  "transactions": [
    {
      "receipt": {
        "blockHash": "0x92c3ce29670ecd049aceb6bebf53df4c2431e7eab6a106194ce95dae443e86f8",
        "blockNumber": 16,
        "contractAddress": null,
        "cumulativeGasUsed": "392352",
        "from": "0xedEaEec55fD20Ab348a934b1a4E8c9B26EE1645b",
        "gasPrice": "1497905281",
        "gasUsed": "392352",
        "hash": "0xb657fcbae9ba25700fb67d5b16aba343d21f342e575e04e6570ffc4228518937",
        "index": 0,
        "logs": [
          {
            "address": "0x8f3301c9Eada5642B5bB12FD047D3EBb2932E619",
            "blockHash": "0x92c3ce29670ecd049aceb6bebf53df4c2431e7eab6a106194ce95dae443e86f8",
            "blockNumber": 16,
            "data": "0x",
            "index": 0,
            "topics": [
              "0x0b28c2323855bc15db8c13b56a44651fbce72c8c916fd653f08851fb9ab1c62a",
              "0x000000000000000000000000c7758246bb22b2012c81459d7084f1a890374452",
              "0x0000000000000000000000006e667164e47986ff1108425153f32b02fc2f5af2"
            ],
            "transactionHash": "0xb657fcbae9ba25700fb67d5b16aba343d21f342e575e04e6570ffc4228518937",
            "transactionIndex": 0
          }
        ],
        "logsBloom": "0x00000000004020000001000000000040800000400000000000000000...", // Truncated for conciseness
        "status": 1,
        "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2"
      },
      "response": {
        "accessList": [],
        "blockNumber": 16,
        "blockHash": "0x92c3ce29670ecd049aceb6bebf53df4c2431e7eab6a106194ce95dae443e86f8",
        "chainId": "11155111",
        "data": "0x1688f0b9000000000000000000000000d9db270c1b5e3bd",
        "from": "0xedEaEec55fD20Ab348a934b1a4E8c9B26EE1645b",
        "gasLimit": "400769",
        "gasPrice": "1497905281",
        "hash": "0xb657fcbae9ba25700fb67d5b16aba343d21f342e575e04e6570ffc4228518937",
        "maxFeePerGas": "1711217402",
        "maxPriorityFeePerGas": "1331936854",
        "nonce": 15,
        "signature": {
          "networkV": null,
          "r": "0x12f72f5d69fcbf96535b077f8950add2774be6842cf99cac9c5eb8caa7ef5e62",
          "s": "0x48aaca053f36564d06d872e0b74e03bf975d886905bd7c38d85c87ff78130d49",
          "v": 28
        },
        "to": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
        "type": 2,
        "value": "0"
      }
    }
  ],
  "merkleRoot": "0x82a1b9e8a08f2cb3d2e27436cd04c431e483664adea8205dcf803fdd88a933bd",
  "solcInputHashes": [
    "4f272ce1ce80603b2d5182ac007dd7b0"
  ],
  "safeAddress": "0x6e667164e47986fF1108425153f32B02Fc2f5af2",
  "moduleAddress": "0xc7758246BB22B2012C81459d7084f1A890374452",
  "executorAddress": "0xB5E96127D417b1B3ef8438496a38A143167209c7",
  "nonce": "0",
  "chainId": "11155111",
  "actions": [
    {
      "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
      "value": "0x0",
      "txData": "0x0000000000000000000000000000000000000000000...",  // Truncated for conciseness
      "gas": "5000000",
      "operation": 0,
      "requireSuccess": true
    }
  ],
  "sphinxConfig": {
    "projectName": "My_Project",
    "orgId": "test-org-id",
    "owners": [
      "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
    ],
    "mainnets": [],
    "testnets": [
      "sepolia",
      "optimism_sepolia"
    ],
    "threshold": "1",
    "saltNonce": "0"
  },
  "executionMode": 2,
  "initialState": {
    "isSafeDeployed": false,
    "isModuleDeployed": false,
    "isExecuting": false
  },
  "unlabeledContracts": [],
  "arbitraryChain": false,
  "libraries": [],
  "gitCommit": "88a023502161a4be85b4b4340e1066c03f60ce54",
  "safeInitData": "0xb63e800d0000000000000000000000000000000000000..." // Truncated for conciseness
}

Compiler Input File

The compiler input file contains the Solidity compiler inputs and settings of your deployment, which makes it possible to reproduce the exact compilation process that resulted in your deployment.

This file does not include the compiler output because it can be very large.

File Path

Sphinx writes compiler input files to the file system at the following location:

deployments/compiler-inputs/<SOLC_INPUT_HASH>.json
  • <SOLC_INPUT_HASH>: A unique identifier for the compiler input file to distinguish between different compilations. This is autogenerated by Foundry during compilation.

On Anvil, Sphinx uses the file name compiler-inputs-local instead of compiler-inputs.

Example file path: deployments/compiler-inputs/81b63eb8d29060639640c5317310fa04.json

Type Definition

type CompilerInput = {
  id: string
  solcVersion: string
  solcLongVersion: string
  input: SolcInput
}

Properties

  • id: A unique identifier for the compiler inputs.
  • solcVersion: The version of the Solidity compiler used for compiling the contract, represented as a short version string like "0.8.4".
  • solcLongVersion: A detailed version string of the Solidity compiler, often including build and commit details to provide exact information about the compiler build used.
  • input: The input data provided to the Solidity compiler, including details, such as source code, optimization settings, and other configurations necessary for the compilation process. See the Compiler Input section of the Solidity documentation for more details.

Example

{
  "solcVersion": "0.8.21",
  "solcLongVersion": "0.8.21+commit.d9974bed",
  "id": "4f272ce1ce80603b2d5182ac007dd7b0",
  "input": {
    "language": "Solidity",
    "settings": { ... },
    "sources": { ... }
  }
}

Committing to Version Control

If you want to commit your deployment artifacts to version control, we recommend committing the entire deployments/ directory except for artifacts generated on Anvil nodes.

You can ignore artifacts generated on Anvil if you include the following in your .gitignore:

deployments/*-local/