1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
// Copyright 2015-2020 Parity Technologies
// Copyright 2023-2023 Alloy Contributors
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Solidity type modeling and [ABI] and [EIP-712] codec implementation.
//!
//! This crate provides tools for expressing Solidity types in Rust, and for
//! encoding these representations into ABI blobs suitable for smart contract
//! processing. In other words, you can represent your smart contract args in
//! native Rust, easily encode them to pass to a smart contract, and easily
//! decode the smart contract return values.
//!
//! We do this by representing Solidity types in rust via the [`SolType`] trait.
//! This trait maps Solidity types to Rust types via the associated
//! [`SolType::RustType`].
//!
//! The ABI encoding and decoding is implemented in the [`abi`] module, see [its
//! documentation](abi) to learn how it works.
//!
//! [ABI]: https://docs.soliditylang.org/en/latest/abi-spec.html
//! [EIP-712]: https://eips.ethereum.org/EIPS/eip-712
//!
//! ```
//! use alloy_sol_types::{sol_data::*, SolType, SolValue};
//!
//! // Represent a Solidity type in rust
//! type MySolType = FixedArray<Bool, 2>;
//!
//! let data = [true, false];
//! let validate = true;
//!
//! // SolTypes expose their Solidity name :)
//! assert_eq!(&MySolType::sol_type_name(), "bool[2]");
//!
//! // SolTypes are used to transform Rust into ABI blobs, and back.
//! let encoded: Vec<u8> = MySolType::abi_encode(&data);
//! let decoded: [bool; 2] = MySolType::abi_decode(&encoded, validate)?;
//! assert_eq!(data, decoded);
//!
//! // This is more easily done with the `SolValue` trait:
//! let encoded: Vec<u8> = data.abi_encode();
//! let decoded: [bool; 2] = <[bool; 2]>::abi_decode(&encoded, validate)?;
//! assert_eq!(data, decoded);
//! # Ok::<_, alloy_sol_types::Error>(())
//! ```
//!
//! ## [`sol!`]
//!
//! The [`sol!`] procedural macro provides a convenient way to define
//! custom [`SolType`]s and reference primitive ones. See
//! [its documentation][sol!] for details on how to use it.
//!
//! ## [`SolStruct`]
//!
//! The [`SolStruct`] trait primarily provides EIP-712 signing support.
//!
//! ```
//! # use alloy_sol_types::{sol, SolStruct};
//! # use alloy_primitives::U256;
//! // `sol!` allows you to define struct types!
//! // You can just paste Solidity into the macro and it should work :)
//! sol! {
//! struct MyStruct {
//! uint256 a;
//! bytes32 b;
//! address[] c;
//! }
//! }
//!
//! sol! {
//! struct MyStruct2 {
//! MyStruct a;
//! bytes32 b;
//! address[] c;
//! }
//! }
//!
//! // All structs generated with `sol!` implement `crate::SolType` &
//! // `crate::SolStruct`. This means you get eip-712 signing for freeeeee
//! let my_struct = MyStruct {
//! a: U256::from(1),
//! b: [0; 32].into(),
//! c: vec![Default::default()],
//! };
//!
//! // The `eip712_domain` macro lets you easily define an EIP-712 domain
//! // object :)
//! let my_domain = alloy_sol_types::eip712_domain!(
//! name: "MyDomain",
//! version: "1",
//! );
//!
//! // Because all the hard work is done by the `sol!` macro, EIP-712 is as easy
//! // as calling `eip712_signing_hash` with your domain
//! let signing_hash = my_struct.eip712_signing_hash(&my_domain);
//! ```
//!
//! ### [`sol!`] User-defined Value Types
//!
//! Support for user-defined value types is new! These are currently
//! implemented as wrapper types. Watch this space for more
//! features!
//!
//! ```
//! # use alloy_sol_types::{sol, sol_data, SolType};
//! # use alloy_primitives::U256;
//! // We also also support Solidity value types
//! sol! {
//! type MyValueType is uint256;
//! }
//!
//! // UDTs are encoded as their underlying type
//! let mvt = MyValueType::from(U256::from(1));
//! assert_eq!(mvt.abi_encode(), sol_data::Uint::<256>::abi_encode(&U256::from(1)));
//! ```
//!
//! ## Tokenization/Detokenization
//!
//! The process of converting from a Rust type to a to an abi token is called
//! "Tokenization". Typical users will not access tokenizaiton directly.
//! Power users should use the [`SolType::tokenize()`] and
//! [`SolType::detokenize()`] methods.
//!
//! When implementing your own [`SolType`], a variety of `From` impls have been
//! provided on the token structs to aid in converting from Rust data to tokens.
//!
//! ## Encoding/Decoding
//!
//! The process of converting from a [`Token`] to a serialized ABI blob is
//! called "Encoding". It is the reciprocal of decoding.
//!
//! ABI encoding and decoding operates on sequences of tokens.
//!
//! The [`SolType`] encoding and decoding methods operate on Rust types. We
//! recommend users use them wherever possible. We do not recommend that users
//! interact with Tokens, except when implementing their own [`SolType`].
//!
//! [`Token`]: abi::Token
#![doc(
html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg",
html_favicon_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/favicon.ico"
)]
#![warn(
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
unreachable_pub,
clippy::missing_const_for_fn,
rustdoc::all
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![deny(unused_must_use, rust_2018_idioms)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#[allow(unused_extern_crates)]
extern crate self as alloy_sol_types;
#[macro_use]
extern crate alloc;
#[macro_use]
mod macros;
pub mod abi;
mod errors;
pub use errors::{Error, Result};
#[cfg(feature = "json")]
mod ext;
#[cfg(feature = "json")]
pub use ext::JsonAbiExt;
mod impl_core;
mod types;
pub use types::{
data_type as sol_data, decode_revert_reason, ContractError, EventTopic, GenericContractError,
GenericRevertReason, Panic, PanicKind, Revert, Selectors, SolCall, SolEnum, SolError, SolEvent,
SolEventInterface, SolInterface, SolStruct, SolType, SolValue, TopicList,
};
pub mod utils;
mod eip712;
pub use eip712::Eip712Domain;
/// The ABI word type.
pub type Word = alloy_primitives::B256;
#[doc(no_inline)]
pub use alloy_sol_macro::sol;
// Not public API.
#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub mod private {
pub use super::utils::{just_ok, next_multiple_of_32, words_for, words_for_len};
pub use alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
collections::BTreeMap,
string::{String, ToString},
vec,
vec::Vec,
};
pub use alloy_primitives::{
bytes, keccak256, Address, Bytes, FixedBytes, Function, Log, Signed, Uint, B256, I256, U256,
};
pub use core::{
borrow::{Borrow, BorrowMut},
convert::From,
default::Default,
option::Option,
result::Result,
};
pub use Option::{None, Some};
pub use Result::{Err, Ok};
#[cfg(feature = "json")]
pub use alloy_json_abi;
/// An ABI-encodable is any type that may be encoded via a given `SolType`.
///
/// The `SolType` trait contains encoding logic for a single associated
/// `RustType`. This trait allows us to plug in encoding logic for other
/// `RustTypes`.
///
/// **Note:** this trait is an implementation detail. As such, it should not
/// be implemented directly unless implementing a custom
/// [`SolType`](crate::SolType), which is also discouraged. Consider
/// using [`SolValue`](crate::SolValue) instead.
pub trait SolTypeValue<T: super::SolType> {
// Note: methods are prefixed with `stv_` to avoid name collisions with
// the `SolValue` trait.
fn stv_to_tokens(&self) -> T::Token<'_>;
#[inline(always)]
fn stv_abi_encoded_size(&self) -> usize {
T::ENCODED_SIZE.unwrap()
}
fn stv_abi_encode_packed_to(&self, out: &mut Vec<u8>);
fn stv_eip712_data_word(&self) -> super::Word;
}
#[inline(always)]
pub const fn u256(n: u64) -> U256 {
U256::from_limbs([n, 0, 0, 0])
}
pub struct AssertTypeEq<T>(pub T);
}