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.
- Generating Artifacts
- Directory Structure
- Contract Deployment Artifact
- Execution Artifact
- Compiler Input File
- Committing to Version Control
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.
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>
--org-id <ORG_ID>
: Required. Your Sphinx organization ID. You can either retrieve this from the Sphinx UI (under "Options" -> "API Credentials") or from thesphinxConfig.orgId
config option in your deployment script.--project-name <PROJECT_NAME>
: Required. The name of your project. You can retrieve this from thesphinxConfig.projectName
config option in your deployment script.--silent
: Optional. Silence the output except for error messages.
- 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"
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.
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.
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 issphinxConfig.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 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
}
- _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 thecontractName
. For example, if a project deploys a contract named "MyContract" in three separate deployments, then the first element in thehistory
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).
{
"_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
},
}
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.
Sphinx writes execution artifacts to the file system at the following location:
deployments/<PROJECT_NAME>/<NETWORK_NAME>/execution/<MERKLE_ROOT>.json
<PROJECT_NAME>
: See the Contract Deployment Artifacts section.<NETWORK_NAME>
: See the Contract Deployment Artifacts section.<MERKLE_ROOT>
: The Merkle root of the deployment. This is the deployment's unique identifier.
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 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
}
- _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
orEIP-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.
{
"_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
}
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.
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 CompilerInput = {
id: string
solcVersion: string
solcLongVersion: string
input: SolcInput
}
- 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.
{
"solcVersion": "0.8.21",
"solcLongVersion": "0.8.21+commit.d9974bed",
"id": "4f272ce1ce80603b2d5182ac007dd7b0",
"input": {
"language": "Solidity",
"settings": { ... },
"sources": { ... }
}
}
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/