6 个版本
0.1.5 | 2020 年 7 月 4 日 |
---|---|
0.1.4 | 2020 年 4 月 19 日 |
0.1.1 | 2020 年 3 月 13 日 |
0.1.0 | 2020 年 2 月 27 日 |
#55 in #solidity
120KB
2.5K SLoC
Solidity
为 Rust 提供的 Solidity 编码和解码框架。
// Basic usage using the built in `Encode` derive macro.
// (Requires the `derive` feature.)
#[derive(Encode)]
struct ContractCallEncode<'a> {
pub name: &'a str,
pub number: u128,
pub bytes10: Bytes10,
pub bytes: Bytes<'a>,
}
// Basic usage using serde. (Requires the `serde` feature).
// Note: Serde only supports a subset of the types that Solidity supports.
// If you need to support more types you'll have to use the `Encode` derive
// macro, or use the `solid::Builder` manually.
#[derive(Serialize)]
pub struct ContractCallSerde<'a> {
// String is also supported, but it's recommened you use &str when possible.
// pub name: String,
pub name: &'a str,
pub number: u128,
pub bytes: Bytes<'a>,
// Bytes10 cannot be serialized correctly using serde.
// pub bytes: Bytes10,
}
// Use the `#[solid(constructor)]` attribute to declare a struct as a constructor.
// This is important because constructors do not have the function name prefix,
// unlike all other functions. Usually the struct name is used as the function
// name. To rename the function use the `#[solid(name = "<function_name>")]`
// where `<function_name>` is the name of your function.
// ie. `#[solid(name = "transfer")]`.
#[derive(Encode)]
struct ContractConstructorEncode<'a> {
pub value: u128,
pub string: &'a str,
}
// Basic usage with the built in `Decode` derive macro.
// (Requires the `derive` feature.)
// Note: `Uint256` and all other `Int`/`Uint` types are simple
// wrappers around `[u8; 32]`. The point of them is to support all
// `int`/`uint` Solidity types.
#[derive(Decode)]
#[solid(error)]
struct ContractCallResponse<'a> {
int: Uint256,
// Note: &'a [u8] is *not* the same as `Bytes<'a>`. The former is is `uint8[]` in solidity
// while the latter is `bytes`. The two types are encoded very differently so decoding
// `bytes` as `uint8[]` array will give you invalid data if not fail outright.
bytes: Bytes<'a>,
memo: &'a str,
address: Address,
}
// Basic usage with serde's `Deserialize` derive macro.
// (Requires the `serde` feature.)
// Note: Serde only supports a subset of the types that Solidity supports.
// If you need to support more types you'll have to use the `Encode` derive
// macro, or use the `solid::Builder` manually.
#[derive(Deserialize)]
struct ContractCallResponseSerde<'a> {
int: u128,
bytes: &'a [u8],
memo: &'a str,
// There is no way to read `Address` with serde.
// address: Address
}
// Support for composite types and `Vec`
#[derive(Encode)]
struct ContractCallComposite<'a> {
to: (&'a str, u128),
memos: &'a [&'a str],
matrix: &'a [&'a [&'a [u8]]],
}
// If you want to manually build the contract you can use the provided `Builder`
let function = Builder::new()
.name("transfer")
.push("daniel")
.push(10u128)
.push(Bytes10([1u8; 10]))
.build();
num_bigint 支持
如果您需要支持 num_bigint
,请启用 bigint
功能。
// Note: BigInt is variable sized and encodes to `int256`.
// To encode to `uint256` use the `BigUint` struct.
// Also, BigInt supports numbers larger than the max value a uint256 can store, so the value
// will be truncated to 32 bytes before it's encoded.
#[derive(Encode)]
#[solid(rename = "transfer")]
struct ContractTransfer<'a> {
amount: BigInt,
to: &'a str
}
ethereum_types 支持
如果您需要支持 ethereum_types
,请启用 ethereum_types
功能。
// Support for Address, U256, U128 from `ethereum_types` crate.
#[derive(Encode)]
#[solid(rename = "transfer")]
struct ContractTransfer<'a> {
amount: ethereum_types::U256,
to: ethereum_types::Address,
}
安装
# Cargo.toml
# Default features which includes `derive`, and `serde`
solid = "0.1.4"
# num_bigint support
solid = { version = "0.1.4", default-features = false, features = [ "derive", "serde", "bigint" ] }
# ethereum_types support
solid = { version = "0.1.4", default-features = false, features = [ "derive", "serde", "ethereum_types" ] }
使用 cargo-edit
cargo add solid
功能
- derive: 添加对
Encode
和Decode
derive 宏的支持。(推荐) - derse: 添加对
serde
的Serialize
和Deserialize
derive 宏以及to_bytes
函数的支持。 - bigint: 添加对
num_bigint
crate 的支持。 - ethereum_types: 添加对
ethereum_types
crate 的支持。 - nightly: 实验性 const 泛型支持。
cargo-solid 子命令
cargo-solid 是一个 cargo 子命令,允许您为关联 Solidity 方法的命名返回类型生成编码函数和解码结构定义。 示例
子命令安装
cargo install cargo-solid
以下命令生成合约的 Solidity ABI。
solc --combined-json abi solidity_contract.sol > solidity_contract.json
然后运行以下命令生成 Rust 定义。
cargo solid solidity_contract.json
输出文件的名称将与输入文件相同,扩展名为 .rs
,并将位于本地 src
目录中。如果您想移动文件,可以自由移动,但无论如何,您仍然需要将文件添加为模块。
mod solidity_contract;
从版本 cargo-solidv0.1.4 开始,您还可以将文件生成到目录,例如 src/generated
,并且还支持使用 BytesFix
和 Int
的夜间定义生成代码。
cargo solid --nightly -o generated stateful.json
依赖项
~1.8–2.6MB
~40K SLoC