Skip to content

Contract deployment#116

Merged
jkilpatr merged 3 commits intomasterfrom
c/contract-deploy
Mar 19, 2026
Merged

Contract deployment#116
jkilpatr merged 3 commits intomasterfrom
c/contract-deploy

Conversation

@ChristianBorst
Copy link
Copy Markdown
Contributor

Add contract representation to clarity and contract deployment function to web30, along with example use in web30/examples for deploying a compiled contract JSON file.

Add contract representation to clarity and contract deployment function
to web30, along with example use in web30/examples for deploying a
compiled contract JSON file.
@jkilpatr
Copy link
Copy Markdown
Member

this needs integration with the ethereum unit tests repo used by the rest of the clarity code

@jkilpatr jkilpatr requested a review from Copilot March 18, 2026 23:06
@jkilpatr
Copy link
Copy Markdown
Member

ok I patched in ethereum unit tests and fixed the included tests.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds first-class contract deployment support by introducing contract/address derivation utilities in clarity and high-level deployment helpers + examples in web30, along with JSON-RPC transaction request changes needed to represent contract creation (to: None).

Changes:

  • Make TransactionRequest.to optional to support contract creation JSON-RPC semantics.
  • Add clarity::contract utilities (CREATE/CREATE2 address calculation, init-code hashing/validation, EIP-3860 gas helper) plus Transaction helpers for contract creation.
  • Add web30 deployment APIs (deploy_contract, gas estimation, receipt-based deployment waiting), a deployment builder module, and an example that deploys from a compiled JSON artifact.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
web30/src/types.rs Allows contract creation requests by making to optional; adds conversions/helpers that must correctly omit to for CREATE.
web30/src/lib.rs Exposes the new contract_deployment module.
web30/src/contract_deployment.rs Adds a deployment transaction builder around clarity::Transaction.
web30/src/client/transactions.rs Adds high-level deployment, deploy gas estimation, and receipt-based deployment waiting.
web30/examples/deploy_from_json.rs New example: deploy a contract from a JSON artifact (bytecode + ABI-based constructor arg encoding).
web30/Cargo.toml Adds dev deps needed by the new example (e.g., hex).
README.md Documents deployment and address prediction usage.
clarity/tests/transaction_tests/structs.rs Updates fixture handling to support Merge/Shanghai results and empty exception strings.
clarity/tests/transaction_tests/main.rs Improves intrinsic gas checks for pre-Istanbul data costs and Shanghai EIP-3860 init-code rules.
clarity/src/transaction.rs Adds is_contract_creation and created_contract_address; fixes intrinsic gas byte counting variable naming/logic.
clarity/src/opcodes.rs Adds pre-Istanbul non-zero-byte gas constant.
clarity/src/lib.rs Exposes the new contract module + re-exports key helpers.
clarity/src/contract.rs New module for contract address derivation + init-code helpers (incl. EIP-3860 size/gas).
Comments suppressed due to low confidence (1)

web30/src/types.rs:705

  • TransactionRequest::from_transaction always sets to: Some(*to). For contract-creation transactions encoded in clarity::Transaction via to == Address::default(), JSON-RPC expects to to be omitted/null; sending "to": "0x000..." makes eth_estimateGas simulate a CALL to the zero address instead of CREATE, producing incorrect gas estimates and call behavior. Consider mapping to == Address::default() to to: None (for all tx types) when building a TransactionRequest.
            } => TransactionRequest::Legacy {
                from,
                to: Some(*to),
                gas: Some((*gas_limit).into()),
                gas_price: Some((*gas_price).into()),
                value: Some((*value).into()),
                data: Some(data.clone().into()),
                nonce: Some((*nonce).into()),
            },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@jkilpatr jkilpatr force-pushed the c/contract-deploy branch from 4cbf32b to 4daef9f Compare March 19, 2026 13:00
@jkilpatr jkilpatr requested a review from Copilot March 19, 2026 13:00
@jkilpatr jkilpatr force-pushed the c/contract-deploy branch from 4daef9f to a44d729 Compare March 19, 2026 13:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds first-class contract deployment support by introducing contract address/creation utilities in clarity, exposing them publicly, and adding high-level deployment helpers + an example workflow in web30.

Changes:

  • Add clarity::contract module for CREATE/CREATE2 address calculation and EIP-3860 init code utilities (plus transaction helpers/tests).
  • Update web30 transaction request types to support contract creation (to: None) and add Web3 helpers for deploy + deploy gas estimation.
  • Add a deploy_from_json example and expand README documentation around deployment/address prediction.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
web30/src/types.rs Makes TransactionRequest.to optional to support contract creation in JSON-RPC.
web30/src/client/transactions.rs Adds deploy_contract, estimate_deploy_gas, and wait_for_deployment helpers.
web30/examples/deploy_from_json.rs New CLI-style example to deploy from a compiled JSON artifact with constructor arg encoding.
web30/Cargo.toml Adds dev dependencies needed by the new example.
README.md Adds feature lists and examples for deployment/address prediction.
clarity/tests/transaction_tests/structs.rs Extends fixture parsing to handle Merge/Shanghai results and empty exception strings.
clarity/tests/transaction_tests/main.rs Adds EIP-2028 (pre-Istanbul) and EIP-3860 (Shanghai) assertions and skips missing-network fixtures.
clarity/src/transaction.rs Adds is_contract_creation and created_contract_address; fixes intrinsic gas byte counting variable naming.
clarity/src/opcodes.rs Adds pre-EIP-2028 non-zero byte gas constant.
clarity/src/lib.rs Exposes contract module and re-exports key helpers.
clarity/src/contract.rs New module implementing contract address derivation + init code helpers and tests.
Comments suppressed due to low confidence (3)

web30/src/types.rs:705

  • TransactionRequest::from_transaction() always sets to: Some(*to). For contract-creation transactions represented by to == Address::default() (empty to in RLP), JSON-RPC requires omitting to (i.e., to: None). As-is, eth_estimateGas/eth_call for deployments will send to: 0x000… and be interpreted as a call/transfer to the zero address rather than contract creation. Map zero-address to to None here.
                to,
                value,
                data,
                signature: _,
            } => TransactionRequest::Legacy {
                from,
                to: Some(*to),
                gas: Some((*gas_limit).into()),
                gas_price: Some((*gas_price).into()),
                value: Some((*value).into()),
                data: Some(data.clone().into()),
                nonce: Some((*nonce).into()),
            },

web30/src/types.rs:724

  • Same issue as the Legacy arm: for contract creation to must be omitted in the JSON-RPC request. to: Some(*to) will serialize 0x000… and break eth_estimateGas for EIP-2930 contract deployments; map zero-address to to None.
                gas_limit,
                to,
                value,
                data,
            } => TransactionRequest::Eip2930 {
                from,
                chain_id: Some((*chain_id).into()),
                to: Some(*to),
                gas: Some((*gas_limit).into()),
                gas_price: Some((*gas_price).into()),
                value: Some((*value).into()),
                data: Some(data.clone().into()),
                nonce: Some((*nonce).into()),

web30/src/types.rs:752

  • Same issue as the Legacy arm: to should serialize as absent/None for contract creation. Consider mapping to == Address::default() to None so EIP-1559 deployment gas estimation works.
                gas_limit,
                to,
                value,
                data,
                signature: _,
                access_list,
            } => TransactionRequest::Eip1559 {
                from,
                chain_id: Some((*chain_id).into()),
                to: Some(*to),
                gas: Some((*gas_limit).into()),
                max_fee_per_gas: Some((*max_fee_per_gas).into()),
                max_priority_fee_per_gas: Some((*max_priority_fee_per_gas).into()),
                value: Some((*value).into()),
                data: Some(data.clone().into()),
                nonce: Some((*nonce).into()),
                access_list: if access_list.is_empty() {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@jkilpatr jkilpatr force-pushed the c/contract-deploy branch from a44d729 to 6ce3979 Compare March 19, 2026 13:23
This patch fixes the tests for contract deployment and also runs the
Ethereum test cases.
@jkilpatr jkilpatr force-pushed the c/contract-deploy branch from 6ce3979 to 3b51693 Compare March 19, 2026 13:34
@jkilpatr jkilpatr merged commit 3b51693 into master Mar 19, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants