Crate solabi

Source
Expand description

Solidity ABI encoding and decoding implementation.

At a high level, this crate provides Solidity ABI encode()-ing and decode()-ing implementations for a collection of primitive types, as well as generic implementations for various collections and tuple types.

let encoded = solabi::encode(&(42_i32, true, Bytes::borrowed(&[0, 1, 2, 3])));
let (a, b, c): (i32, bool, Bytes<Vec<u8>>) = solabi::decode(&encoded).unwrap();
assert_eq!(a, 42);
assert_eq!(b, true);
assert_eq!(c.as_bytes(), [0, 1, 2, 3]);

§Encoders

Furthermore, this library provides encoders for various Solidity ABI items:

These encoders provide a type-safe interface for Solidity encoding and decoding their parameters.

const TRANSFER: FunctionEncoder<(Address, U256), (bool,)> =
    FunctionEncoder::new(selector!("transfer(address,uint256)"));

let call = TRANSFER.encode_params(&(
    address!("0x0101010101010101010101010101010101010101"),
    uint!("4_200_000_000_000_000_000"),
));

§Dynamic Values

The value::Value type provides dynamic Solidity values. This allows Solidity ABI encoding and decoding when types are not known at compile-time.

let event = abi::EventDescriptor::parse_declaration(
    "event Transfer(address indexed to, address indexed from, uint256 value)",
)
.unwrap();
let encoder = value::EventEncoder::new(&event).unwrap();
let log = encoder
    .encode(&[
        Value::Address(address!("0x0101010101010101010101010101010101010101")),
        Value::Address(address!("0x0202020202020202020202020202020202020202")),
        Value::Uint(value::Uint::new(256, uint!("4_200_000_000_000_000_000")).unwrap()),
    ])
    .unwrap();

§Custom Encoding Implementation

It can be useful to define custom types that encode and decode to the Solidity ABI. This can be done by implementing the encode::Encode and decode::Decode traits.

use solabi::{
    encode::{Encode, Encoder, Size},
    decode::{Decode, DecodeError, Decoder},
};

#[derive(Debug, Eq, PartialEq)]
struct MyStruct {
    a: u64,
    b: String,
}

impl Encode for MyStruct {
    fn size(&self) -> Size {
        (self.a, self.b.as_str()).size()
    }

    fn encode(&self, encoder: &mut Encoder) {
        (self.a, self.b.as_str()).encode(encoder);
    }
}

impl Decode for MyStruct {
    fn is_dynamic() -> bool {
        <(u64, String)>::is_dynamic()
    }

    fn decode(decoder: &mut Decoder) -> Result<Self, DecodeError> {
        let (a, b) = Decode::decode(decoder)?;
        Ok(Self { a, b })
    }
}

let my_struct = MyStruct {
    a: 42,
    b: "The Answer to Life the Universe and Everything".to_string(),
};

let encoded = solabi::encode(&my_struct);
let decoded = solabi::decode(&encoded).unwrap();

assert_eq!(my_struct, decoded);

There are plans to provide Encode and Decode procedural macros to automatically implement these traits in the future.

Re-exports§

pub use self::decode::decode;
pub use self::decode::decode_with_prefix;
pub use self::decode::decode_with_selector;
pub use self::encode::encode;
pub use self::encode::encode_to;
pub use self::encode::encode_with_prefix;
pub use self::encode::encode_with_selector;
pub use ethprim;
pub use self::prelude::*;

Modules§

abi
Solidity ABI descriptors.
bytes
Solidity bytes type.
constructor
Solidity ABI constructor encoding.
decode
Solidity ABI decoding.
encode
Module implementing ABI encoding.
error
Solidity ABI error encoding.
event
Module containing Solidity event related traits and logic.
function
Solidity ABI function pointer type.
keccak
A const fn Keccak-256 implementation.
log
Module implementing an EVM log datatype.
prelude
The solabi prelude.
primitive
Solidity primitive type trait and implementations.
value
Module containing dynamic Solidity value.

Macros§

address
Macro to create Ethereum public address values from string literals that get verified at compile time. A compiler error will be generated if an invalid address is specified.
digest
Macro to create Ethereum digest values from string literals that get parsed at compile time. A compiler error will be generated if an invalid digest is specified.
int
Macro for 256-bit signed integer literal.
keccak
Macro to create Ethereum digest values for compile-time hashed input.
selector
Macro for creating a compile-time computed function selector.
uint
Macro for 256-bit unsigned integer literal.