#solidity #parser #abi #evm #ethereum

no-std alloy-sol-type-parser

Simple and light-weight Solidity type strings parser

17 releases (4 breaking)

0.7.0 Mar 30, 2024
0.6.2 Jan 25, 2024
0.5.4 Dec 28, 2023
0.5.1 Nov 30, 2023
0.3.1 Jul 30, 2023

#1022 in Magic Beans

Download history 3221/week @ 2023-12-22 3147/week @ 2023-12-29 4565/week @ 2024-01-05 5619/week @ 2024-01-12 6620/week @ 2024-01-19 7686/week @ 2024-01-26 8108/week @ 2024-02-02 7492/week @ 2024-02-09 9761/week @ 2024-02-16 8456/week @ 2024-02-23 8970/week @ 2024-03-01 8832/week @ 2024-03-08 12207/week @ 2024-03-15 7553/week @ 2024-03-22 9316/week @ 2024-03-29 7996/week @ 2024-04-05

38,270 downloads per month
Used in 26 crates (2 directly)

MIT/Apache

47KB
1K SLoC

alloy-sol-type-parser

Simple and light-weight Solidity type strings parser.

This library is primarily a dependency for the user-facing APIs in alloy-json-abi and alloy-dyn-abi. Please see the documentation for those crates for more information.

This parser generally follows the Solidity spec, however, it supports only a subset of possible types, chosen to support ABI coding.

Usage

The TypeSpecifier is the top-level type in this crate. It is a wrapper around a section of a string (called a span). It progressively breaks the strings down into subspans, and adds metadata about the type. E.g. it tracks the stem type as well as the sizes of array dimensions. A TypeSpecifier is expected to handle any valid Solidity type string.

use alloy_sol_type_parser::TypeSpecifier;
use core::num::NonZeroUsize;

// Parse a type specifier from a string
let my_type = TypeSpecifier::parse("uint8[2][]").unwrap();

// Read the total span
assert_eq!(
    my_type.span(),
    "uint8[2][]"
);

// A type specifier has a stem type. This is the type string, stripped of its
// array dimensions.
assert_eq!(my_type.stem.span(), "uint8");

// Arrays are represented as a vector of sizes. This allows for deep nesting.
assert_eq!(
    my_type.sizes,
    // `None` is used for dynamic sizes. This is equivalent to `[2][]`
    vec![NonZeroUsize::new(2), None]
);

// Type specifiers also work for complex tuples!
let my_tuple = TypeSpecifier::parse("(uint8,(uint8[],bool))[39]").unwrap();
assert_eq!(
    my_tuple.stem.span(),
    "(uint8,(uint8[],bool))"
);

// Types are NOT resolved, so you can parse custom structs just by name.
let my_struct = TypeSpecifier::parse("MyStruct").unwrap();

Why not support parse()?

The core::str::FromStr trait is not implemented for TypeSpecifier because of lifetime constraints. Unfortunately, it is impossible to implement this for a type with a lifetime dependent on the input str. Instead, we recommend using the parse associated functions, or TryFrom::<&str>::try_from if a trait is needed.

Why not use syn?

This is NOT a full syntax library, and is not intended to be used as a replacement for syn-solidity. This crate is intended to be used for parsing type strings present in existing ecosystem tooling, and nothing else. It is not intended to be used for parsing Solidity source code.

This crate is useful for:

  • syntax-checking JSON ABI files
  • providing known-good input to alloy-dyn-abi
  • porting ethers.js code to rust

It is NOT useful for:

  • parsing Solidity source code
  • generating Rust code from Solidity source code
  • generating Solidity source code from rust code

Dependencies

~1MB
~16K SLoC