Implement JSON ABI generation for contracts#1346
Conversation
c2c98cc to d5797c1 Compare | @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eed3c8889d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
f2a0e17 to 7cadbab Compare | @codex review |
There was a problem hiding this comment.
💡 Codex Review
Lines 622 to 624 in 7cadbab
build_workspace only calls check_workspace_artifact_name_collisions when emit.writes_any_bytecode() is true. If a workspace build uses --emit abi (or --emit ir,abi) and two selected members define the same contract name, write_abi_artifacts still writes both outputs into the shared flat out_dir as <contract>.abi.json, so the later member silently overwrites the earlier ABI. The same collision guard needs to run whenever ABI artifacts are requested.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce0a4cc535
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e0e6b81e53
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ea5ce0d to 64b5322 Compare | @codex review |
1 similar comment
| @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64b5322e27
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ae86237 to dd74cfc Compare | @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd74cfc763
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if is_std_address_ty(db, ty, adt_ref) { | ||
| return Ok(AbiTypeDesc::simple("address")); | ||
| } | ||
| if let Some(sol_type) = std_sol_compat_abi_type(db, ty, adt_ref) { | ||
| return Ok(AbiTypeDesc::simple(&sol_type)); |
There was a problem hiding this comment.
Honor
SolCompat::SOL_TYPE before flattening ADTs
semantic_ty_to_abi_desc only recognizes Address and the built-in Uint*/Int* wrappers, then treats every other ADT as a tuple. That breaks user-defined types implementing std::abi::sol::SolCompat: ingots/std/src/abi/sol.fe:188-200 explicitly documents those as valid event-field types, and recv selectors can also be authored against their Solidity type names. For those contracts the emitted JSON ABI no longer matches the runtime topic/selector shape, and ensure_selector_matches_signature will reject otherwise valid sol("...") selectors during the now-default ABI build.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Acknowledged. There doesn't seem to be an easy fix for this but it's also less big of an issue than the P1 makes it sound.
| @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b21e109fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
e1d16df to cf47108 Compare | @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf47108ecd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Add `--emit abi` support to the Fe compiler, emitting Ethereum-compatible JSON ABI files (<contract>.abi.json) alongside bytecode artifacts. The ABI is derived from: - msg variant recv arms → function entries (name, inputs, outputs, stateMutability) - init blocks → constructor entries (inputs, stateMutability) - #[event] structs → event entries (inputs with indexed flags) State mutability derivation: - #[payable] → "payable" - no effects → "pure" - read-only effects → "view" - any mut effects → "nonpayable" ABI is emitted by default alongside bytecode and runtime-bytecode.
| @sbillig I think this one is good to go |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf60b4d256
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if args.len() == 1 | ||
| && args[0].label.is_none() | ||
| && let Partial::Present(Expr::Lit(LitKind::String(signature))) = | ||
| args[0].expr.data(db, body) | ||
| { |
There was a problem hiding this comment.
Evaluate non-literal
sol(...) args before omitting ABI entries
This branch only recovers a selector signature when std::abi::sol is called with a direct string literal. sol itself accepts any AsBytes constant (ingots/core/src/bytes.fe implements that for String<N>, tuples, etc.), so selectors like #[selector = sol(SIG)] or sol(("ping", "()")) still CTFE correctly. Here they fall through to None, and recv_arm_to_abi_entry later drops the function from *.abi.json, so a harmless refactor from a literal to another constant AsBytes expression silently removes public methods from the generated ABI.
Useful? React with 👍 / 👎.
| if emit.abi { | ||
| had_errors |= write_abi_artifacts(db, top_mod, &names_to_build, out_dir, report_dir); |
There was a problem hiding this comment.
Avoid MIR-lowering the whole module for ABI-only builds
The new ABI path here still depends on build_top_mod having called collect_contract_names() first, and that helper enumerates contracts by running lower_module() over the entire file. In practice, fe build --emit abi --contract Foo will now fail if some other contract in the same file/ingot hits a MIR-lowering limitation, even though generate_contract_abi() only reads HIR for the selected contract. That makes ABI-only builds regress on unrelated lowering errors instead of remaining a frontend-only operation.
Useful? React with 👍 / 👎.
Summary
Adds Ethereum-compatible JSON ABI generation to the Fe compiler. ABI files (
<contract>.abi.json) are now emitted by default alongside bytecode artifacts. The ABI is derived from the contract's semantic types,ensuring correctness even for generic msg variants.
What it does
ABI entries are generated from:
recvarms →"function"entries (name, inputs, outputs, stateMutability)initblocks →"constructor"entries (inputs, stateMutability)#[event]structs reachable from the contract →"event"entries (inputs with indexed flags)Type mapping uses the semantic type system (not HIR), so generic msg variants like
GenericMsg<u8>correctly emituint8rather than an unresolved type parameter.Selector validation ensures the ABI is consistent with on-chain behavior:
sol("name(types)")selector signatureGraceful handling of hex selectors: Recv arms with raw hex selectors (
#[selector = 0x...]) are skipped with a warning rather than failing the build, so the rest of the ABI can still be generated.Event collection is scope-aware: only event structs actually reachable from the contract's init/recv bodies (including transitively called functions) are included — unused events defined elsewhere in the
ingot are excluded.
State mutability is derived from effects:
#[payable]→"payable", no effects →"pure", read-only →"view", any mutation →"nonpayable".Default emit: ABI is included in the default
--emitset (bytecode,runtime-bytecode,abi), sofe buildproduces ABI files without extra flags.Test plan
sol()alias naming, const alias resolution, generic variant types, event/function name collisions, tuple/array type encodingcargo test -p fe— all 57 tests pass