6 releases
0.1.5 | Jul 4, 2020 |
---|---|
0.1.4 | Apr 19, 2020 |
0.1.1 | Mar 13, 2020 |
0.1.0 | Feb 27, 2020 |
#55 in #solidity
120KB
2.5K
SLoC
Solidity
A Solidity encoding and decoding framework for Rust.
// 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 Support
If you'd like support for num_bigint
enable the bigint
feature.
// 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 Support
If you'd like support for ethereum_types
enable the ethereum_types
feature.
// 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,
}
Install
# 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" ] }
Using cargo-edit
cargo add solid
Features
- derive: Add support for the
Encode
andDecode
derive macros. (Recommended) - derse: Add support for
serde
sSerialize
andDeserialize
derive macros, andto_bytes
function. - bigint: Add suport for
num_bigint
crate. - ethereum_types: Add support for
ethereum_types
crate. - nightly: Experimental const generic support.
cargo-solid Subcommand
cargo-solid is a cargo subcommand that allows you to generate the encoding functions and decodable struct definitions for named return types of associated Solidity methods. example
Subcommand Install
cargo install cargo-solid
The following command generates the solidity abi for a contract.
solc --combined-json abi solidity_contract.sol > solidity_contract.json
Then run the following command to generate the rust definition.
cargo solid solidity_contract.json
The name of the output file will the be same name as the input file with the extension set to .rs
, and will be
located in the local src
directory. You can freely move the file if you would like, but either way you will
still need to add the file as a module:
mod solidity_contract;
As of version cargo-solidv0.1.4 you can also generate the files into a directory such as src/generated
, and
there is also support for generating code using nightly definitions of BytesFix
and Int
.
cargo solid --nightly -o generated stateful.json
Dependencies
~1.8–2.6MB
~40K SLoC