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

Prestwich/crate readmes #41

Merged
merged 7 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions crates/abi/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,55 @@
# ethers-rs ABI Encoding
# ethers-sol-types

Compile-time representation of Ethereum's type system with ABI encoding &
decoding.
Compile-time representation of Ethereum's type system with ABI coding and
EIP-712 support.

This crate provides a developer-friendly interface to Ethereum's type system,
by representing Solidity types. See [type_system.md] for a rundown, and the
[crate docs] for more information

[type_system.md]: https://github.com/ethers-rs/core/blob/main/crates/abi/type_system.md
[crate docs]: https://docs.rs/ethers-sol-types/latest/ethers_sol_types/

### Features

- static representation of Solidity types
- ABI encoding and decoding
- EIP-712 encoding and decoding
- EIP-712 Domain object w/ `serde` support

### Usage

See the [crate docs] for more details.

```rust
// Declare a solidity type in standard solidity
sol! {
struct Foo {
bar: u256;
baz: bool;
}
}

// A corresponding Rust struct is generated!
let foo = Foo {
bar: 42.into(),
baz: true,
};

// Works for UDTs
sol! { type MyType is uint8; }
let my_type = MyType::from(42u8);

// For errors
sol! {
error MyError(
string message,
);
}

// And for functions!
sol! { function myFunc() external returns (uint256); }
```

## Licensing

Expand Down
77 changes: 74 additions & 3 deletions crates/dyn-abi/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,78 @@
# ethers-rs Dynamic ABI Encoding
# ethers-dyn-abi

Run-time representation of Ethereum's type system with ABI encoding &
decoding.
Dynamic Solidity type encoder: Run-time representation of Ethereum's type
system with ABI encoding & decoding.

This library provides a runtime encoder/decoder for solidity types. It is
intended to be used when the solidity type is not known at compile time.
This is particularly useful for EIP-712 signing interfaces.

We **strongly** recommend using the [static encoder/decoder][abi] when possible.
The dyanmic encoder/decoder is significantly more expensive, especially for
complex types. It is also significantly more error prone, as the mapping
between solidity types and rust types is not enforced by the compiler.

[abi]: https://docs.rs/ethers-sol-types/latest/ethers_sol_types/

## Usage

```rust
use ethers_dyn_abi::{DynSolType, DynSolValue};

// parse a type from a string
// limitation: custom structs cannot currently be parsed this way.
let my_type: DynSolType = "uint8[2][]".parse().unwrap();

// set values
let uints = DynSolValue::FixedArray(vec![0u8.into(), 1u8.into()]);
let my_values = DynSolValue::Array(vec![uints]);

// encode
let encoded = my_type.encode_single(my_values.clone()).unwrap();

// decode
let decoded = my_type.decode_single(&encoded).unwrap();

assert_eq!(decoded, my_values);
```

## How it works

The dynamic encoder/decoder is implemented as a set of enums that represent
solidity types, solidity values (in rust representation form), and ABI
tokens. Unlike the static encoder, each of these must be instantiated at
runtime. The [`DynSolType`] enum represents a solidity type, and is
equivalent to an enum over types implementing the [`crate::SolType`] trait.
The [`DynSolValue`] enum represents a solidity value, and describes the
rust shapes of possible solidity values. It is similar to, but not
equivalent to an enum over types used as [`crate::SolType::RustType`]. The
[`DynToken`] enum represents an ABI token, and is equivalent to an enum over
the types implementing the [`ethers_abi_enc::TokenType`] trait.

Where the static encoding system encodes the expected type information into
the rust type system, the dynamic encoder/decoder encodes it as a concrete
instance of [`DynSolType`]. This type is used to tokenize and detokenize
[`DynSolValue`] instances. The [`std::str::FromStr`] impl is used to parse a
solidity type string into a [`DynSolType`] object.

- Tokenizing - `DynSolType + `DynSolValue`=`DynToken`
- Detokenizing -`DynSolType`+`DynToken`=`DynSolValue`

Users must manually handle the conversions between [`DynSolValue`] and their
own rust types. We provide several `From`implementations, but they fall
short when dealing with arrays and tuples. We also provide fallible casts
into the contents of each variant.

## `DynToken::decode_populate`

Because the shape of the data is known only at runtime, we cannot
compile-time allocate the memory needed to hold decoded data. Instead, we
pre-allocate a [`DynToken`] with the same shape as the expected type, and
empty values. We then populate the empty values with the decoded data.

This is a significant behavior departure from the static decoder. We do not
recommend using the [`DynToken`] type directly. Instead, we recommend using
the encoding and decoding methods on [`DynSolType`].

## Licensing

Expand Down
71 changes: 1 addition & 70 deletions crates/dyn-abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,76 +21,7 @@
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]

//! Dynamic Solidity Type Encoder
//!
//! This library provides a runtime encoder/decoder for Solidity types. It is
//! intended to be used when the Solidity type is not known at compile time.
//! This is particularly useful for EIP-712 signing interfaces.
//!
//! We **strongly** recommend using the static encoder/decoder when possible.
//! The dyanmic encoder/decoder is significantly more expensive, especially for
//! complex types. It is also significantly more error prone, as the mapping
//! between Solidity types and rust types is not enforced by the compiler.
//!
//! ## Example
//!
//! ```
//! # use ethers_dyn_abi::{DynSolType, DynSolValue};
//! // parse a type from a string
//! // limitation: custom structs cannot currently be parsed this way.
//! let my_type: DynSolType = "uint8[2][]".parse().unwrap();
//!
//! // set values
//! let uints = DynSolValue::FixedArray(vec![0u8.into(), 1u8.into()]);
//! let my_values = DynSolValue::Array(vec![uints]);
//!
//! // encode
//! let encoded = my_type.encode_single(my_values.clone()).unwrap();
//!
//! // decode
//! let decoded = my_type.decode_single(&encoded).unwrap();
//!
//! assert_eq!(decoded, my_values);
//! ```
//!
//! ## How it works
//!
//! The dynamic encoder/decoder is implemented as a set of enums that represent
//! Solidity types, Solidity values (in rust representation form), and ABI
//! tokens. Unlike the static encoder, each of these must be instantiated at
//! runtime. The [`DynSolType`] enum represents a Solidity type, and is
//! equivalent to an enum over types implementing the [`crate::SolType`] trait.
//! The [`DynSolValue`] enum represents a Solidity value, and describes the
//! rust shapes of possible Solidity values. It is similar to, but not
//! equivalent to an enum over types used as [`crate::SolType::RustType`]. The
//! [`DynToken`] enum represents an ABI token, and is equivalent to an enum over
//! the types implementing the [`ethers_abi_enc::TokenType`] trait.
//!
//! Where the static encoding system encodes the expected type information into
//! the rust type system, the dynamic encoder/decoder encodes it as a concrete
//! instance of [`DynSolType`]. This type is used to tokenize and detokenize
//! [`DynSolValue`] instances. The [`std::str::FromStr`] impl is used to parse a
//! Solidity type string into a [`DynSolType`] object.
//!
//! Tokenizing - `DynSolType + `DynSolValue` = `DynToken`
//! Detokenizing - `DynSolType` + `DynToken` = `DynSolValue`
//!
//! Users must manually handle the conversions between [`DynSolValue`] and their
//! own rust types. We provide several `From` implementations, but they fall
//! short when dealing with arrays and tuples. We also provide fallible casts
//! into the contents of each variant.
//!
//! ## `DynToken::decode_populate`
//!
//! Because the shape of the data is known only at runtime, we cannot
//! compile-time allocate the memory needed to hold decoded data. Instead, we
//! pre-allocate a [`DynToken`] with the same shape as the expected type, and
//! empty values. We then populate the empty values with the decoded data.
//!
//! This is a significant behavior departure from the static decoder. We do not
//! recommend using the [`DynToken`] type directly. Instead, we recommend using
//! the encoding and decoding methods on [`DynSolType`].
#![doc = include_str!("../README.md")]

#[macro_use]
extern crate alloc;
Expand Down
51 changes: 51 additions & 0 deletions crates/primitives/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# ethers-types

Fundamental types shared by [reth], [revm], [ethers], and [foundry].

[reth]: https://github.com/paradigmxyz/reth
[revm]: https://github.com/bluealloy/revm
[ethers]: https://github.com/ethers-rs/core
[foundry]: https://github.com/foundry-rs/foundry

## Types

- Unsigned integers re-exported from [ruint](https://docs.rs/ruint)
- Signed integers, as a wrapper around `ruint` integers
- Fixed-size byte arrays via [`FixedBytes`]
- a macro [`wrap_fixed_bytes`] for constructing named fixed bytes types
- [`Address`], which is a fixed-size byte array of 20 bytes, with EIP-55 and
EIP-1191 checksum support

## Examples

This library has straightforward, basic, types. Usage is correspondingly simple. Please consult [the documentation][docs] for more information.

[docs]: https://docs.rs/ethers-types/latest/ethers-types/

```rust
use ethers_primitives::{U256, Address, FixedBytes, I256};

// FixedBytes
let n: FixedBytes<6> = "0x1234567890ab".parse().unwrap();
assert_eq!(n.to_string(), "0x1234567890ab");

// Uint
let mut n: U256 = "42".parse().unwrap();
n += U256::from(10);
assert_eq!(n.to_string(), "52");

// Signed
let mut n: I256 = "-42".parse().unwrap();
n = -n;
assert_eq!(n.to_string(), "42");

// Address
let addr_str = "0x66f9664f97F2b50F62D13eA064982f936dE76657";
let addr: Address = Address::parse_checksummed(addr_str, None).unwrap();
assert_eq!(addr.to_checksum(None), addr_str);

// Address with custom chain id
let addr_str = "0x66F9664f97f2B50F62d13EA064982F936de76657";
let addr: Address = Address::parse_checksummed(addr_str, Some(30)).unwrap();
assert_eq!(addr.to_checksum(Some(30)), addr_str);
```
4 changes: 1 addition & 3 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]

//! Fundamental types shared by [reth](https://github.com/paradigmxyz/reth) [revm](https://github.com/bluealloy/revm) and [ethers](https://github.com/gakonst/ethers-rs).

#![cfg_attr(not(feature = "std"), no_std)]
#![doc = include_str!("../README.md")]

#[macro_use]
extern crate alloc;
Expand Down
16 changes: 14 additions & 2 deletions crates/rlp-derive/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
## RLP derive crate

Forked from an earlier Apache licenced version of the `fastrlp-derive` crate, before it changed licence to GPL.
NOTE: The Rust fastrlp implementation is itself a port of the [Golang Apache licensed fastrlp](https://github.com/umbracle/fastrlp)
This crate provides derive macros for traits defined in
[`ethers-rlp`](https://docs.rs/ethers-rlp). See that crate's documentation for
more information.

### Provenance notes

This crate was originally part of the
[reth](https://github.com/paradigmxyz/reth/) project. Maintenance has been
taken over by the ethers developers.

Forked from an earlier Apache licenced version of the `fastrlp-derive` crate,
before it changed licence to GPL. NOTE: The Rust fastrlp implementation is
itself a port of the
[Golang Apache licensed fastrlp](https://github.com/umbracle/fastrlp)
2 changes: 1 addition & 1 deletion crates/rlp-derive/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(crate) fn impl_decodable(ast: &syn::DeriveInput) -> Result<TokenStream> {
if !rlp_head.list {
return Err(ethers_rlp::DecodeError::UnexpectedString);
}
if b.remaining() < rlp_head.payload_length {
if ethers_rlp::Buf::remaining(b) < rlp_head.payload_length {
return Err(ethers_rlp::DecodeError::InputTooShort);
}

Expand Down
27 changes: 27 additions & 0 deletions crates/rlp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## ethers-rlp

This crate provides Ethereum RLP (de)serialization functionality. RLP is
commonly used for Ethereum EL datastructures, and its documentation can be
found [at ethereum.org][ref].

[ref]: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/

### Usage

We strongly recommend deriving RLP traits via the `RlpEncodable` and
`RlpDecodable` derive macros.

Trait methods can then be accessed via the `Encodable` and `Decodable`
traits.

### Provenance note

This crate was originally part of the
[reth](https://github.com/paradigmxyz/reth/) project. Maintenance has been
taken over by the ethers developers.

Forked from an earlier Apache licenced version of the `fastrlp` crate, before
it changed licence to GPL. NOTE: The Rust fastrlp implementation is itself a
port of the [Golang Apache licensed fastrlp][gofastrlp].

[gofastrlp]: https://github.com/umbracle/fastrlp
31 changes: 30 additions & 1 deletion crates/rlp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,37 @@
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]
#![doc = include_str!("../README.md")]
// This doctest uses derive and alloc, so it cannot be in the README :(
#![cfg_attr(
all(feature = "derive", feature = "std"),
doc = r##"

//! RLP Encoding and Decoding
## Usage Example

```rust
use ethers_rlp::{RlpEncodable, RlpDecodable, Decodable, Encodable};

#[derive(Debug, RlpEncodable, RlpDecodable, PartialEq)]
pub struct MyStruct {
pub a: u64,
pub b: Vec<u8>,
}

fn main() {
let my_struct = MyStruct {
a: 42,
b: vec![1, 2, 3],
};

let mut buffer = Vec::<u8>::new();
let encoded = my_struct.encode(&mut buffer);
let decoded = MyStruct::decode(&mut buffer.as_slice()).unwrap();
assert_eq!(my_struct, decoded);
}
```
"##
)]

#[cfg(feature = "alloc")]
extern crate alloc;
Expand Down
2 changes: 1 addition & 1 deletion crates/sol-type/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ethers-sol-type
# ethers-sol-macro

This crate provides the [`sol`][sol] proc macro, which parses Solidity syntax
to generate types that implement [`ethers-abi-enc`] traits.
Expand Down