#solidity #abi #ethereum #evm #encoding

no-std linera-alloy-dyn-abi

运行时 ABI 和 EIP-712 实现

1 个不稳定版本

0.7.4 2024 年 5 月 30 日

#199魔法豆

Download history 142/week @ 2024-05-26 105/week @ 2024-06-02 77/week @ 2024-06-09 95/week @ 2024-06-16 18/week @ 2024-06-23 72/week @ 2024-06-30 23/week @ 2024-07-07 86/week @ 2024-07-14 83/week @ 2024-07-21 102/week @ 2024-07-28

294 每月下载量
8 个 crate 中使用(5 个直接使用)

MIT/Apache

1MB
23K SLoC

linera-alloy-dyn-abi

动态 Solidity 类型编码器。

带有 ABI 编码和解码的 Ethereum 类型系统的运行时表示。

此库提供对 Solidity 类型的运行时编码器/解码器。当 Solidity 类型在编译时未知时,它很有用。这对于 EIP-712 签名接口特别有用。

我们**强烈**建议在可能的情况下使用静态编码器/解码器。动态编码器/解码器成本更高,特别是对于复杂类型。它还更容易出错,因为 Rust 编译器不强制执行 Solidity 类型与 Rust 类型之间的映射。

示例

基本用法

use linera_alloy_dyn_abi::{DynSolType, DynSolValue};
use linera_alloy_primitives::hex;

// parse a type from a string
// note: eip712 `CustomStruct`s cannot be parsed this way.
let my_type: DynSolType = "uint16[2][]".parse().unwrap();

// decode
let my_data = hex!(
    "0000000000000000000000000000000000000000000000000000000000000020" // offset
    "0000000000000000000000000000000000000000000000000000000000000001" // length
    "0000000000000000000000000000000000000000000000000000000000000002" // .[0][0]
    "0000000000000000000000000000000000000000000000000000000000000003" // .[0][1]
);
let decoded = my_type.abi_decode(&my_data)?;

let expected = DynSolValue::Array(vec![DynSolValue::FixedArray(vec![2u16.into(), 3u16.into()])]);
assert_eq!(decoded, expected);

// roundtrip
let encoded = decoded.abi_encode();
assert_eq!(encoded, my_data);
# Ok::<(), linera_alloy_dyn_abi::Error>(())

EIP-712

todo!()

工作原理

动态编码器/解码器实现为一组枚举,这些枚举代表solidity类型、solidity值(以Rust表示形式)和ABI令牌。与静态编码器不同,这些枚举必须在运行时实例化。枚举DynSolType代表solidity类型,相当于实现了crate::SolType特质的枚举。枚举DynSolValue代表solidity值,描述了可能的solidity值的Rust形状。它与crate::SolType::RustType类似,但不完全等价。枚举DynToken代表ABI令牌,相当于实现了linera_alloy_sol_types::abi::Token特质的枚举。

静态编码系统将预期的类型信息编码到Rust类型系统中,而动态编码器/解码器则将其编码为DynSolType的具体实例。

  • 去令牌化:DynSolType + DynToken = DynSolValue

用户必须手动处理DynSolValue和自己的Rust类型之间的转换。我们提供了几个From实现,但它们在处理数组、元组和结构体时表现不佳。我们还提供了将每个变体的内容进行可失败转换的方法。

DynToken::decode_populate

因为数据形状只在运行时才知道,所以我们无法在编译时分配存储解码数据的内存。相反,我们预先分配一个与预期类型形状相同的DynToken,并用空值填充。然后我们用解码数据填充这些空值。

这与静态解码器的行为有显著不同。我们不推荐直接使用DynToken类型。相反,我们建议使用DynSolType上的编码和解码方法。

许可

这个crate是对parity团队编写的ethabi crate的广泛重写。该代码库是在MIT许可条款下使用的。我们在包含ethabi代码的文件中保留了原始许可通知。

依赖

~6–8.5MB
~170K SLoC