Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cast) add creation-code method [#8973] #9029

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

pawurb
Copy link

@pawurb pawurb commented Oct 4, 2024

Motivation

As described in #8973, currently there's no simple way to obtain contract creation code without compiling them locally. It is needed to deploy contracts with sol! macro.

If this is accepted I'll add artifact method generating file that can be used directly with sol! macro.

Solution

This PR adds cast creation-code method. It outputs the contract creation code.

Example usage

cast creation-code 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 --etherscan-api-key API_KEY --rpc-url RPC_URL

@zerosnacks zerosnacks linked an issue Oct 4, 2024 that may be closed by this pull request
async fn fetch_creation_code(
contract: Address,
client: Client,
provider: &Arc<RetryProvider>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
provider: &Arc<RetryProvider>,
provider: &RetryProvider,

// Extract creation code from tx traces
let mut creation_bytecode = None;

let traces = provider.trace_transaction(creation_tx_hash).await?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will work, but is usually not available on the free tier, so this can fail with a serde rpc error "method not found" or "unavailable", we should add an eyre context here like "failed to trace tx 0x..."

}
}

/// Fetches the creation code of a contract from Etherscan and RPC.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document whether or not this includes constructor args appended to initcode

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mds1 right, I should probably strip them to make the bytecode useful for local deployment. Maybe worth returning constructor args separately?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reading up there's is no a single unified convention for encoding constructor args with different solidity versions. So I think I'll just add a comment that they are appended.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use case for this method? I think that impacts whether or not you want to strip the constructor args. If you do want to strip them you'll likely need to use blockscout or etherscan to fetch constructor args

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to get bytecode that I can use for deploying contracts locally, without compiling them myself. So prefer creation code without constructor args appended. But, optionally knowing what were the args values is also useful.

Eventually I want to add artifact method that will combine creation bytecode with JSON ABI, for simply use with sol! Alloy macro.

I'm thinking to add --without-args and --only-args flags. I think it's possible to know the size of appended args from the ABI. WDYT?

@pawurb
Copy link
Author

pawurb commented Oct 10, 2024

I've added --only-args and --without-args flags to creation-code and creation-args method. With these tools it's possible to get bytecode for local deployment and also inspect args that were used in the original contract deployment.

cast creation-code 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419 --only-args --etherscan-api-key API_KEY --rpc-url RPC_URL

# 0x000000000000000000000000f79d6afbb6da890132f9d7c355e3015f15f3406f0000000000000000000000000000000000000000000000000000000000000000
cast creation-args 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419  --etherscan-api-key API_KEY --rpc-url RPC_URL

# address 0x000000000000000000000000f79d6afbb6da890132f9d7c355e3015f15f3406f
# address 0x0000000000000000000000000000000000000000000000000000000000000000

@pawurb pawurb force-pushed the cast_bytecode branch 2 times, most recently from c224c30 to e1df312 Compare October 10, 2024 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

feat(cast) add deploydata method
3 participants