├── rust-toolchain ├── .gitattributes ├── book ├── guide │ ├── tables.md │ ├── actions.md │ ├── hello-world.md │ ├── macros.md │ ├── rust.md │ ├── secondary-indexes.md │ ├── testing.md │ ├── traits.md │ ├── compiling.md │ ├── deploying.md │ ├── optimization.md │ ├── secondary-keys.md │ └── index.md ├── examples │ ├── eosio.forum.md │ ├── eosio.token.md │ ├── url-shortener.md │ ├── elemental-battles.md │ ├── eosio.contracts │ │ ├── eosio.bios.md │ │ ├── eosio.forum.md │ │ ├── eosio.msig.md │ │ ├── eosio.token.md │ │ ├── eosio.wrap.md │ │ ├── index.md │ │ └── eosio.assert.md │ ├── index.md │ ├── addressbook.md │ ├── hello.md │ ├── hello-bare.md │ └── tic-tac-toe.md ├── api-documentation.md ├── install │ ├── index.md │ ├── rust.md │ ├── optional.md │ └── eos.md ├── book.toml ├── SUMMARY.md ├── getting-help.md ├── index.md └── quick-start.md ├── crates ├── eosio_rpc │ ├── src │ │ ├── dbsize │ │ │ ├── mod.rs │ │ │ └── get.rs │ │ ├── net │ │ │ ├── connect.rs │ │ │ ├── disconnect.rs │ │ │ ├── mod.rs │ │ │ ├── status.rs │ │ │ └── connections.rs │ │ ├── producer │ │ │ ├── pause.rs │ │ │ ├── mod.rs │ │ │ ├── paused.rs │ │ │ ├── resume.rs │ │ │ ├── get_greylist.rs │ │ │ ├── get_runtime_options.rs │ │ │ ├── add_greylist_accounts.rs │ │ │ ├── get_whitelist_accounts.rs │ │ │ ├── remove_greylist_accounts.rs │ │ │ ├── set_whitelist_accounts.rs │ │ │ └── update_runtime_options.rs │ │ ├── history │ │ │ ├── mod.rs │ │ │ ├── get_actions.rs │ │ │ ├── get_key_accounts.rs │ │ │ ├── get_transaction.rs │ │ │ └── get_controlled_accounts.rs │ │ ├── chain │ │ │ ├── push_block.rs │ │ │ ├── get_required_keys.rs │ │ │ ├── push_transaction.rs │ │ │ ├── push_transactions.rs │ │ │ ├── get_block_header_state.rs │ │ │ ├── get_code.rs │ │ │ ├── get_raw_code_and_abi.rs │ │ │ ├── abi_bin_to_json.rs │ │ │ ├── abi_json_to_bin.rs │ │ │ ├── get_producers.rs │ │ │ ├── mod.rs │ │ │ ├── get_abi.rs │ │ │ ├── get_currency_balance.rs │ │ │ ├── get_currency_stats.rs │ │ │ ├── get_info.rs │ │ │ └── get_table_rows.rs │ │ ├── clients │ │ │ ├── mod.rs │ │ │ ├── server.rs │ │ │ └── browser.rs │ │ ├── client.rs │ │ ├── error.rs │ │ └── lib.rs │ ├── README.md │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ └── Cargo.toml ├── eosio │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── src │ │ ├── account.rs │ │ ├── varint │ │ │ └── mod.rs │ │ ├── crypto │ │ │ ├── mod.rs │ │ │ └── keys.rs │ │ ├── time │ │ │ ├── mod.rs │ │ │ ├── time_point_sec.rs │ │ │ └── time_point.rs │ │ ├── symbol │ │ │ ├── mod.rs │ │ │ └── extended_symbol.rs │ │ ├── resources.rs │ │ ├── table │ │ │ ├── primary_table_index.rs │ │ │ ├── secondary_table_name.rs │ │ │ ├── secondary_table_index.rs │ │ │ ├── mod.rs │ │ │ └── secondary_key.rs │ │ ├── bytes │ │ │ ├── marker.rs │ │ │ ├── option.rs │ │ │ ├── collections.rs │ │ │ ├── num.rs │ │ │ └── alloc.rs │ │ ├── ops.rs │ │ ├── binary_extension.rs │ │ ├── abi.rs │ │ ├── block.rs │ │ ├── transaction.rs │ │ ├── name │ │ │ ├── mod.rs │ │ │ └── name_type.rs │ │ ├── producer_schedule.rs │ │ ├── lib.rs │ │ └── blockchain_parameters.rs │ ├── README.md │ ├── benches │ │ └── bytes.rs │ └── Cargo.toml ├── eosio_cli │ ├── README.md │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── src │ │ ├── lib.rs │ │ ├── main.rs │ │ └── opts │ │ │ ├── version.rs │ │ │ ├── sign.rs │ │ │ ├── transfer.rs │ │ │ ├── wrap.rs │ │ │ ├── net.rs │ │ │ ├── push.rs │ │ │ ├── create.rs │ │ │ └── convert.rs │ └── Cargo.toml ├── eosio_cdt │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── README.md │ ├── Cargo.toml │ └── src │ │ ├── time.rs │ │ ├── check.rs │ │ ├── lib.rs │ │ ├── permissions.rs │ │ ├── singleton_index.rs │ │ └── table.rs ├── eosio_macros │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── tests │ │ ├── test.rs │ │ └── ui │ │ │ ├── name-bad-char.rs │ │ │ ├── symbol-bad-char.rs │ │ │ ├── symbol-bad-format.rs │ │ │ ├── name-too-long.rs │ │ │ ├── symbol-bad-precision.rs │ │ │ ├── symbol-too-long.rs │ │ │ ├── symbol-bad-format.stderr │ │ │ ├── symbol-bad-precision.stderr │ │ │ ├── name-bad-char.stderr │ │ │ ├── symbol-bad-char.stderr │ │ │ ├── name-too-long.stderr │ │ │ └── symbol-too-long.stderr │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── eosio_numstr │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── README.md │ ├── Cargo.toml │ ├── src │ │ └── lib.rs │ └── benches │ │ └── benches.rs ├── eosio_cdt_sys │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── wrapper.hpp │ ├── README.md │ ├── Cargo.toml │ ├── src │ │ └── lib.rs │ └── generate.sh └── eosio_macros_internal │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── README.md │ ├── src │ ├── n.rs │ ├── s.rs │ ├── table.rs │ └── abi.rs │ ├── Cargo.toml │ └── tests │ └── tests.rs ├── contracts ├── eosio_bios │ ├── README.md │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ └── Cargo.toml ├── eosio_msig │ ├── README.md │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ └── Cargo.toml ├── eosio_wrap │ ├── README.md │ ├── LICENSE-MIT │ ├── LICENSE-APACHE │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── eosio_assert │ ├── LICENSE-MIT │ ├── README.md │ ├── LICENSE-APACHE │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── eosio_forum │ ├── LICENSE-MIT │ ├── README.md │ ├── LICENSE-APACHE │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── eosio_system │ ├── LICENSE-MIT │ ├── README.md │ ├── LICENSE-APACHE │ ├── Cargo.toml │ └── src │ │ ├── producer_pay.rs │ │ ├── native.rs │ │ ├── exchange_state.rs │ │ ├── lib.rs │ │ └── name_bidding.rs └── eosio_token │ ├── LICENSE-MIT │ ├── README.md │ ├── LICENSE-APACHE │ └── Cargo.toml ├── .gitmodules ├── docker ├── push.sh ├── build.sh ├── eosio.cdt.dockerfile ├── eos.dockerfile ├── eosio.contracts.dockerfile ├── genesis.json └── docker-compose.yml ├── examples ├── hello │ ├── src │ │ └── lib.rs │ ├── Cargo.toml │ └── hello.abi.json ├── hello_bare │ ├── Cargo.toml │ ├── hello_bare.abi.json │ └── src │ │ └── lib.rs ├── addressbook │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── tictactoe │ ├── Cargo.toml │ └── tictactoe.abi.json ├── internal ├── bench_rs │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── bench_cpp │ ├── Cargo.toml │ ├── build.sh │ └── src │ │ ├── contract.cpp │ │ └── main.rs ├── util │ └── Cargo.toml ├── scripts │ ├── Cargo.toml │ └── src │ │ ├── opts.rs │ │ ├── main.rs │ │ ├── docker_up.rs │ │ ├── deploy_examples.rs │ │ ├── run_examples.rs │ │ ├── docker_tests.rs │ │ ├── build_docs.rs │ │ └── shared.rs └── bench │ ├── Cargo.toml │ └── src │ └── scenario.rs ├── .gitignore ├── .cargo └── config ├── rustfmt.toml ├── .travis.yml ├── .github ├── CONTRIBUTING.md └── PULL_REQUEST_TEMPLATE.md ├── Cargo.toml ├── LICENSE-MIT └── README.md /rust-toolchain: -------------------------------------------------------------------------------- 1 | stable 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /book/guide/tables.md: -------------------------------------------------------------------------------- 1 | # Tables 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/dbsize/mod.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/net/connect.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/net/disconnect.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/net/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/net/status.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/pause.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_cli/README.md: -------------------------------------------------------------------------------- 1 | # eosio_cli 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/README.md: -------------------------------------------------------------------------------- 1 | # eosio_rpc 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/history/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/net/connections.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/paused.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/resume.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /book/examples/eosio.forum.md: -------------------------------------------------------------------------------- 1 | # eosio.forum 2 | -------------------------------------------------------------------------------- /book/examples/eosio.token.md: -------------------------------------------------------------------------------- 1 | # eosio.token 2 | -------------------------------------------------------------------------------- /book/guide/actions.md: -------------------------------------------------------------------------------- 1 | # Declaring Actions 2 | -------------------------------------------------------------------------------- /book/guide/hello-world.md: -------------------------------------------------------------------------------- 1 | # Hello, World! 2 | -------------------------------------------------------------------------------- /contracts/eosio_bios/README.md: -------------------------------------------------------------------------------- 1 | # eosio_bios 2 | -------------------------------------------------------------------------------- /contracts/eosio_msig/README.md: -------------------------------------------------------------------------------- 1 | # eosio_msig 2 | -------------------------------------------------------------------------------- /contracts/eosio_wrap/README.md: -------------------------------------------------------------------------------- 1 | # eosio_wrap 2 | -------------------------------------------------------------------------------- /crates/eosio/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_cdt/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_cli/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_macros/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_numstr/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_rpc/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/get_greylist.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /book/api-documentation.md: -------------------------------------------------------------------------------- 1 | # API Documentation 2 | -------------------------------------------------------------------------------- /book/examples/url-shortener.md: -------------------------------------------------------------------------------- 1 | # URL Shortener 2 | -------------------------------------------------------------------------------- /book/guide/macros.md: -------------------------------------------------------------------------------- 1 | # Tables, Actions, and ABIs 2 | -------------------------------------------------------------------------------- /book/guide/rust.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Rust 2 | -------------------------------------------------------------------------------- /book/guide/secondary-indexes.md: -------------------------------------------------------------------------------- 1 | # Secondary Keys 2 | -------------------------------------------------------------------------------- /book/guide/testing.md: -------------------------------------------------------------------------------- 1 | # Testing Smart Contracts 2 | -------------------------------------------------------------------------------- /book/guide/traits.md: -------------------------------------------------------------------------------- 1 | # Deriving Common Traits 2 | -------------------------------------------------------------------------------- /contracts/eosio_assert/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_assert/README.md: -------------------------------------------------------------------------------- 1 | # eosio_assert 2 | -------------------------------------------------------------------------------- /contracts/eosio_bios/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_forum/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_forum/README.md: -------------------------------------------------------------------------------- 1 | # eosio_forum 2 | -------------------------------------------------------------------------------- /contracts/eosio_msig/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_system/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_system/README.md: -------------------------------------------------------------------------------- 1 | # eosio_system 2 | -------------------------------------------------------------------------------- /contracts/eosio_token/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /contracts/eosio_token/README.md: -------------------------------------------------------------------------------- 1 | # eosio_token 2 | -------------------------------------------------------------------------------- /contracts/eosio_wrap/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_cdt/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_cli/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_rpc/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/get_runtime_options.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /book/examples/elemental-battles.md: -------------------------------------------------------------------------------- 1 | # Elemental Battles 2 | -------------------------------------------------------------------------------- /book/guide/compiling.md: -------------------------------------------------------------------------------- 1 | # Compiling Smart Contracts 2 | -------------------------------------------------------------------------------- /book/guide/deploying.md: -------------------------------------------------------------------------------- 1 | # Deploying Smart Contracts 2 | -------------------------------------------------------------------------------- /book/guide/optimization.md: -------------------------------------------------------------------------------- 1 | # Optimizing WASM files 2 | -------------------------------------------------------------------------------- /book/guide/secondary-keys.md: -------------------------------------------------------------------------------- 1 | # Using Secondary Keys 2 | -------------------------------------------------------------------------------- /contracts/eosio_assert/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_bios/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_forum/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_msig/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_system/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_token/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /contracts/eosio_wrap/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_macros/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_macros_internal/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../../LICENSE-MIT -------------------------------------------------------------------------------- /crates/eosio_numstr/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/add_greylist_accounts.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/get_whitelist_accounts.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/remove_greylist_accounts.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/set_whitelist_accounts.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/producer/update_runtime_options.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.bios.md: -------------------------------------------------------------------------------- 1 | # eosio.bios 2 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.forum.md: -------------------------------------------------------------------------------- 1 | # eosio.forum 2 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.msig.md: -------------------------------------------------------------------------------- 1 | # eosio.msig 2 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.token.md: -------------------------------------------------------------------------------- 1 | # eosio.token 2 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.wrap.md: -------------------------------------------------------------------------------- 1 | # eosio.wrap 2 | -------------------------------------------------------------------------------- /book/examples/eosio.contracts/index.md: -------------------------------------------------------------------------------- 1 | # eosio.contracts 2 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../../LICENSE-APACHE -------------------------------------------------------------------------------- /book/examples/eosio.contracts/eosio.assert.md: -------------------------------------------------------------------------------- 1 | # eosio.assert 2 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod opts; 2 | 3 | pub use self::opts::*; 4 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/dbsize/get.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/db_size/get"; 2 | -------------------------------------------------------------------------------- /crates/eosio/src/account.rs: -------------------------------------------------------------------------------- 1 | use crate::name_type; 2 | 3 | name_type!(AccountName); 4 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/push_block.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/push_block"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/history/get_actions.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/history/get_actions"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_required_keys.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/get_required_keys"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/push_transaction.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/push_transaction"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/push_transactions.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/push_transactions"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/history/get_key_accounts.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/history/get_key_accounts"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/history/get_transaction.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/history/get_transaction"; 2 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/history/get_controlled_accounts.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/history/get_controlled_accounts"; 2 | -------------------------------------------------------------------------------- /crates/eosio/src/varint/mod.rs: -------------------------------------------------------------------------------- 1 | mod signed; 2 | mod unsigned; 3 | 4 | pub use self::{signed::SignedInt, unsigned::UnsignedInt}; 5 | -------------------------------------------------------------------------------- /book/install/index.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | To write EOS smart contracts in Rust we will need to install Rust and setup an EOS local node. 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "crates/eosio_cdt_sys/eosio.cdt"] 2 | path = crates/eosio_cdt_sys/eosio.cdt 3 | url = https://github.com/EOSIO/eosio.cdt.git 4 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn ui() { 3 | let t = trybuild::TestCases::new(); 4 | t.compile_fail("tests/ui/*.rs"); 5 | } 6 | -------------------------------------------------------------------------------- /book/examples/index.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Examples can be found in the [`examples`](https://github.com/sagan-software/eosio-rust/tree/master/examples) directory. -------------------------------------------------------------------------------- /docker/push.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | docker push sagansoftware/eos:2.0.3 3 | docker push sagansoftware/eosio.cdt:1.7.0 4 | docker push sagansoftware/eosio.contracts:1.9.1 5 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/name-bad-char.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::n; 4 | 5 | fn main() { 6 | let _ = n!("test1230"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-char.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::s; 4 | 5 | fn main() { 6 | let _ = s!(4, "Test"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-format.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::s; 4 | 5 | fn main() { 6 | let _ = s!("EOS"); 7 | } 8 | -------------------------------------------------------------------------------- /examples/hello/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[eosio::action] 2 | fn hi(name: eosio::AccountName) { 3 | eosio_cdt::print!("Hello, ", name, "!"); 4 | } 5 | 6 | eosio::abi!(hi); 7 | -------------------------------------------------------------------------------- /internal/bench_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | use core::marker::PhantomData; 3 | 4 | pub fn noop(_: PhantomData<()>) {} 5 | 6 | eosio::abi! { 7 | noop 8 | } 9 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/name-too-long.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::n; 4 | 5 | fn main() { 6 | let _ = n!("12345123451234"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-precision.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::s; 4 | 5 | fn main() { 6 | let _ = s!(256, "EOS"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-too-long.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_macros; 2 | 3 | use eosio_macros::s; 4 | 5 | fn main() { 6 | let _ = s!(4, "ABCDEFGH"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate eosio_cli; 2 | 3 | use eosio_cli::*; 4 | use structopt::StructOpt; 5 | 6 | fn main() { 7 | let opt = Opt::from_args(); 8 | } 9 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_block_header_state.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/get_block_header_state"; 2 | 3 | struct Params { 4 | block_num_or_id: String, 5 | } 6 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_code.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | 3 | const PATH: &str = "/v1/chain/get_code"; 4 | 5 | struct Params { 6 | account_name: AccountName, 7 | } 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-format.stderr: -------------------------------------------------------------------------------- 1 | error: expected integer literal 2 | --> $DIR/symbol-bad-format.rs:6:16 3 | | 4 | 6 | let _ = s!("EOS"); 5 | | ^^^^^ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .DS_Store 3 | *_gc.wasm 4 | *_gc_opt.wasm 5 | *_gc_opt.wat 6 | *_gc_opt_wat.wasm 7 | node_modules 8 | Cargo.lock 9 | /gh-pages 10 | .vscode 11 | proptest-regressions 12 | -------------------------------------------------------------------------------- /examples/hello_bare/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello_bare" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | doc = false 10 | -------------------------------------------------------------------------------- /crates/eosio/src/crypto/mod.rs: -------------------------------------------------------------------------------- 1 | mod checksums; 2 | mod keys; 3 | 4 | pub use self::{ 5 | checksums::{Checksum160, Checksum256, Checksum512}, 6 | keys::{PrivateKey, PublicKey, Signature}, 7 | }; 8 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_raw_code_and_abi.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | 3 | const PATH: &str = "/v1/chain/get_raw_code_and_abi"; 4 | 5 | struct Params { 6 | account_name: AccountName, 7 | } 8 | -------------------------------------------------------------------------------- /internal/bench_cpp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench_cpp" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | util = { path = "../util" } -------------------------------------------------------------------------------- /book/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Liam Curry"] 3 | multilingual = false 4 | src = "." 5 | title = "eosio-rust" 6 | 7 | [build] 8 | build-dir = "../target/doc" 9 | 10 | [output.html] 11 | default-theme = "ayu" -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-precision.stderr: -------------------------------------------------------------------------------- 1 | error: number too large to fit in target type 2 | --> $DIR/symbol-bad-precision.rs:6:16 3 | | 4 | 6 | let _ = s!(256, "EOS"); 5 | | ^^^ 6 | -------------------------------------------------------------------------------- /crates/eosio/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/sagan-software/eosio-rust.svg?branch=master)](https://travis-ci.org/sagan-software/eosio-rust) 2 | 3 | # eosio 4 | 5 | TODO docs 6 | 7 | License: MIT OR Apache-2.0 8 | -------------------------------------------------------------------------------- /crates/eosio/src/time/mod.rs: -------------------------------------------------------------------------------- 1 | mod block_timestamp; 2 | mod time_point; 3 | mod time_point_sec; 4 | 5 | pub use self::{ 6 | block_timestamp::BlockTimestamp, time_point::TimePoint, 7 | time_point_sec::TimePointSec, 8 | }; 9 | -------------------------------------------------------------------------------- /book/examples/addressbook.md: -------------------------------------------------------------------------------- 1 | # Address Book 2 | 3 | ```toml 4 | {{#include ../../examples/addressbook/Cargo.toml}} 5 | ``` 6 | 7 | ```rust,no_run,noplaypen 8 | {{#include ../../examples/addressbook/src/lib.rs}} 9 | ``` 10 | -------------------------------------------------------------------------------- /book/guide/index.md: -------------------------------------------------------------------------------- 1 | # User Guide 2 | 3 | In this guide we will go through the basics of developing EOSIO smart contracts with Rust. For other guides on EOSIO software please see block.one's [EOSIO developer portal](https://developers.eos.io/). -------------------------------------------------------------------------------- /crates/eosio_cdt/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/sagan-software/eosio-rust.svg?branch=master)](https://travis-ci.org/sagan-software/eosio-rust) 2 | 3 | # eosio_cdt 4 | 5 | TODO docs 6 | 7 | License: MIT OR Apache-2.0 8 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/version.rs: -------------------------------------------------------------------------------- 1 | use structopt::StructOpt; 2 | 3 | /// Retrieve version information 4 | #[derive(StructOpt, Debug)] 5 | pub enum Version { 6 | /// Retrieve version information of the client 7 | Client, 8 | } 9 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/abi_bin_to_json.rs: -------------------------------------------------------------------------------- 1 | use eosio::{AccountName, ActionName}; 2 | 3 | const PATH: &str = "/v1/chain/abi_bin_to_json"; 4 | 5 | struct Params { 6 | code: AccountName, 7 | action: ActionName, 8 | binargs: String, 9 | } 10 | -------------------------------------------------------------------------------- /crates/eosio/src/symbol/mod.rs: -------------------------------------------------------------------------------- 1 | mod extended_symbol; 2 | mod symbol; 3 | mod symbol_code; 4 | 5 | pub use eosio_numstr::{ParseSymbolCodeError, ParseSymbolError}; 6 | pub use extended_symbol::ExtendedSymbol; 7 | pub use symbol::Symbol; 8 | pub use symbol_code::SymbolCode; 9 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | docker build --tag sagansoftware/eos:2.0.3 --file ./eos.dockerfile . 3 | docker build --tag sagansoftware/eosio.cdt:1.7.0 --file ./eosio.cdt.dockerfile . 4 | docker build --tag sagansoftware/eosio.contracts:1.9.1 --file ./eosio.contracts.dockerfile . 5 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/clients/mod.rs: -------------------------------------------------------------------------------- 1 | // #[cfg(feature = "server")] 2 | // mod server; 3 | // #[cfg(feature = "server")] 4 | // pub use self::server::*; 5 | 6 | // #[cfg(feature = "browser")] 7 | // mod browser; 8 | // #[cfg(feature = "browser")] 9 | // pub use self::browser::*; 10 | -------------------------------------------------------------------------------- /examples/hello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | doc = false 10 | 11 | [dependencies] 12 | eosio = { path = "../../crates/eosio" } 13 | eosio_cdt = { path = "../../crates/eosio_cdt" } 14 | -------------------------------------------------------------------------------- /examples/addressbook/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "addressbook" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | doc = false 10 | 11 | [dependencies] 12 | eosio = { path = "../../crates/eosio" } 13 | eosio_cdt = { path = "../../crates/eosio_cdt" } 14 | -------------------------------------------------------------------------------- /internal/util/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "util" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | regex = "1" 11 | lazy_static = "1.3" 12 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/abi_json_to_bin.rs: -------------------------------------------------------------------------------- 1 | use eosio::{AccountName, ActionName}; 2 | use serde::Serialize; 3 | 4 | const PATH: &str = "/v1/chain/abi_json_to_bin"; 5 | 6 | struct Params 7 | where 8 | Args: Serialize, 9 | { 10 | code: AccountName, 11 | action: ActionName, 12 | args: Args, 13 | } 14 | -------------------------------------------------------------------------------- /examples/tictactoe/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tictactoe" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | doc = false 11 | 12 | [dependencies] 13 | eosio = { path = "../../crates/eosio" } 14 | eosio_cdt = { path = "../../crates/eosio_cdt" } 15 | -------------------------------------------------------------------------------- /internal/bench_cpp/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | mkdir -p ./build 6 | 7 | winpty docker run --entrypoint eosio-cpp --rm -it sagansoftware/eosio.cdt:1.7.0 -v ../bench_contract_cpp:/bench_contract_cpp \ 8 | -o=/build/bench_cpp.wasm \ 9 | -abigen \ 10 | -abigen_output=/build/bench_cpp.json \ 11 | -contract=hello \ 12 | /src/bench_contract.cpp -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/name-bad-char.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of input, name contains invalid character '0' 2 | --> $DIR/name-bad-char.rs:6:13 3 | | 4 | 6 | let _ = n!("test1230"); 5 | | ^^^^^^^^^^^^^^ 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /contracts/eosio_bios/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_bios" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /contracts/eosio_forum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_forum" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /contracts/eosio_msig/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_msig" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /contracts/eosio_token/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_token" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /contracts/eosio_wrap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_wrap" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-bad-char.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of input, symbol contains invalid character 't' 2 | --> $DIR/symbol-bad-char.rs:6:13 3 | | 4 | 6 | let _ = s!(4, "Test"); 5 | | ^^^^^^^^^^^^^ 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /contracts/eosio_assert/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_assert" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 13 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_producers.rs: -------------------------------------------------------------------------------- 1 | const PATH: &str = "/v1/chain/get_producers"; 2 | 3 | struct Params { 4 | #[serde(skip_serializing_if = "Option::is_none")] 5 | limit: Option, 6 | #[serde(skip_serializing_if = "Option::is_none")] 7 | lower_bound: Option, 8 | #[serde(skip_serializing_if = "Option::is_none")] 9 | json: Option, 10 | } 11 | -------------------------------------------------------------------------------- /examples/hello/hello.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "eosio::abi/1.0", 3 | "structs": [ 4 | { 5 | "name": "hi", 6 | "base": "", 7 | "fields": [ 8 | { 9 | "name": "user", 10 | "type": "name" 11 | } 12 | ] 13 | } 14 | ], 15 | "actions": [ 16 | { 17 | "name": "hi", 18 | "type": "hi" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /internal/bench_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench_contract_rs" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | eosio = { path = "../../crates/eosio" } 11 | eosio_cdt = { path = "../../crates/eosio_cdt" } 12 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/name-too-long.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of input, name is too long, must be 13 chars or less 2 | --> $DIR/name-too-long.rs:6:13 3 | | 4 | 6 | let _ = n!("12345123451234"); 5 | | ^^^^^^^^^^^^^^^^^^^^ 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /crates/eosio_macros/tests/ui/symbol-too-long.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of input, symbol code is too long, must be 7 chars or less 2 | --> $DIR/symbol-too-long.rs:6:13 3 | | 4 | 6 | let _ = s!(4, "ABCDEFGH"); 5 | | ^^^^^^^^^^^^^^^^^ 6 | | 7 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /examples/hello_bare/hello_bare.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "eosio::abi/1.0", 3 | "structs": [ 4 | { 5 | "name": "hi", 6 | "base": "", 7 | "fields": [ 8 | { 9 | "name": "user", 10 | "type": "name" 11 | } 12 | ] 13 | } 14 | ], 15 | "actions": [ 16 | { 17 | "name": "hi", 18 | "type": "hi" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /internal/scripts/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scripts" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | 8 | [dependencies] 9 | plotters = "0.2.1" 10 | regex = "1" 11 | lazy_static = "1.3" 12 | rand = "0.6" 13 | eosio = { path = "../../crates/eosio" } 14 | log = "0.4" 15 | pretty_env_logger = "0.3" 16 | structopt = "0.3" 17 | path-slash = "0.1" 18 | util = { path = "../util" } 19 | -------------------------------------------------------------------------------- /book/install/rust.md: -------------------------------------------------------------------------------- 1 | # Install Rust 2 | 3 | EOSIO Rust works with stable Rust 1.31 and above. 4 | 5 | Install Rust with `rustup` per the [official instructions](https://www.rust-lang.org/en-US/install.html): 6 | 7 | ```sh 8 | curl https://sh.rustup.rs -sSf | sh 9 | ``` 10 | 11 | We will also need the `wasm32-unknown-unknown` target, which can be installed with `rustup`: 12 | 13 | ```sh 14 | rustup target add wasm32-unknown-unknown 15 | ``` 16 | -------------------------------------------------------------------------------- /contracts/eosio_system/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_system" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | path = "src/lib.rs" 10 | 11 | [dependencies] 12 | serde = "1.0" 13 | serde_derive = "1.0" 14 | eosio = { version = "0.3.1", path = "../../crates/eosio" } 15 | eosio_cdt = { version = "0.3.1", path = "../../crates/eosio_cdt" } 16 | lazy_static = "1.4" -------------------------------------------------------------------------------- /contracts/eosio_system/src/producer_pay.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | 3 | // TODO this relies on eosio_bios::BlockHeader 4 | // 5 | // pub fn onblock(header: PhantomData) {} 6 | 7 | /// 8 | #[eosio::action] 9 | pub fn claimrewards(owner: AccountName) {} 10 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/mod.rs: -------------------------------------------------------------------------------- 1 | // pub mod abi_bin_to_json; 2 | // pub mod abi_json_to_bin; 3 | pub mod get_abi; 4 | pub mod get_account; 5 | pub mod get_block; 6 | // pub mod get_block_header_state; 7 | pub mod get_currency_balance; 8 | pub mod get_currency_stats; 9 | pub mod get_info; 10 | pub mod get_table_rows; 11 | 12 | pub use self::{ 13 | get_abi::*, get_account::*, get_block::*, get_currency_balance::*, get_currency_stats::*, 14 | get_info::*, get_table_rows::*, 15 | }; 16 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/client.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use serde::{Deserialize, Serialize}; 3 | use std::future::Future; 4 | use std::pin::Pin; 5 | 6 | pub trait Client { 7 | fn node(&self) -> &str; 8 | 9 | fn fetch( 10 | &self, 11 | path: &str, 12 | params: Params, 13 | ) -> Pin> + Send>> 14 | where 15 | Output: 'static + for<'b> Deserialize<'b> + Send, 16 | Params: Serialize; 17 | } 18 | -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/wrapper.hpp: -------------------------------------------------------------------------------- 1 | typedef unsigned __int128 uint128_t; 2 | typedef __int128 int128_t; 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include -------------------------------------------------------------------------------- /book/examples/hello.md: -------------------------------------------------------------------------------- 1 | # Hello, World! 2 | 3 | This example shows how to create a smart contract in Rust that prints a greeting. 4 | 5 | ## Usage 6 | 7 | ```sh 8 | cleos push action hello hi '["world"]' -p 'hello@active' 9 | ``` 10 | 11 | ## Cargo.toml 12 | 13 | ```toml 14 | {{#include ../../examples/hello/Cargo.toml}} 15 | ``` 16 | 17 | ## Source 18 | 19 | ```rust,no_run,noplaypen 20 | {{#include ../../examples/hello/src/lib.rs}} 21 | ``` 22 | 23 | ## ABI 24 | 25 | ```json 26 | {{#include ../../examples/hello/hello.abi.json}} 27 | ``` 28 | -------------------------------------------------------------------------------- /docker/eosio.cdt.dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagansoftware/eos:2.0.3 2 | # Arguments 3 | ARG fork=EOSIO 4 | ARG branch=v1.7.0 5 | 6 | # Build 7 | RUN git clone \ 8 | --recursive \ 9 | --branch $branch \ 10 | --single-branch \ 11 | https://github.com/$fork/eosio.cdt \ 12 | /eosio.cdt 13 | WORKDIR /eosio.cdt 14 | RUN echo 1 | ./scripts/eosiocdt_build.sh 15 | RUN ./scripts/eosiocdt_install.sh 16 | WORKDIR / 17 | 18 | # Environment variables 19 | ENV EOSIO_CDT_ROOT /root/opt/eosio.cdt 20 | ENV PATH "${EOSIO_CDT_ROOT}/bin:${PATH}" 21 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_abi.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | use eosio_abi::Abi; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | crate::builder!("/v1/chain/get_abi", GetAbiParams, GetAbi); 6 | 7 | #[derive(Serialize, Clone)] 8 | pub struct GetAbiParams { 9 | account_name: AccountName, 10 | } 11 | 12 | pub const fn get_abi(account_name: AccountName) -> GetAbiParams { 13 | GetAbiParams { account_name } 14 | } 15 | 16 | #[derive(Serialize, Deserialize, Debug)] 17 | pub struct GetAbi { 18 | pub account_name: AccountName, 19 | pub abi: Abi, 20 | } 21 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/README.md: -------------------------------------------------------------------------------- 1 | # eosio_macros_internal 2 | 3 | Internal use only. 4 | 5 | This crate is an implementation detail that will hopefully go away 6 | once the [`proc_macro_hygiene`] feature is stabilized. In the meantime 7 | we must use this crate (and [`proc_macro_hack`]) to allow for 8 | function-like procedural macros in expression positions. 9 | 10 | [`proc_macro_hygiene`]: https://doc.rust-lang.org/beta/unstable-book/language-features/proc-macro-hygiene.html 11 | [`proc_macro_hack`]: https://github.com/dtolnay/proc-macro-hack 12 | 13 | License: MIT OR Apache-2.0 14 | -------------------------------------------------------------------------------- /.cargo/config: -------------------------------------------------------------------------------- 1 | [alias] 2 | build-contracts = "run -p scripts -- build-contracts" 3 | build-docs = "run -p scripts -- build-docs" 4 | build-bench = "build -p bench --release" 5 | deploy-examples = "run -p scripts -- deploy-examples" 6 | docker-init = "run -p scripts -- docker-init" 7 | docker-tests = "run -p scripts -- run-tests" 8 | docker-up = "run -p scripts -- docker-up" 9 | eosrs = "run -p eosio-cli --" 10 | run-bench = "run -p scripts -- run-bench" 11 | run-examples = "run -p scripts -- run-examples" 12 | unit-tests = "test -p eosio -p eosio_macros -p eosio_macros_internal -p eosio_numstr" 13 | -------------------------------------------------------------------------------- /contracts/eosio_system/src/native.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use std::marker::PhantomData; 3 | 4 | /// 5 | #[eosio::action] 6 | pub fn newaccount( 7 | creator: AccountName, 8 | newact: AccountName, 9 | owner: PhantomData, 10 | active: PhantomData, 11 | ) { 12 | } 13 | 14 | /// 15 | #[eosio::action] 16 | pub fn setabi(acnt: AccountName, abi: Vec) {} 17 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | condense_wildcard_suffixes = true 2 | edition = "2018" 3 | force_explicit_abi = true 4 | format_code_in_doc_comments = true 5 | format_macro_matchers = true 6 | format_strings = true 7 | hard_tabs = false 8 | max_width = 80 9 | merge_derives = true 10 | merge_imports = true 11 | newline_style = "Unix" 12 | normalize_comments = true 13 | overflow_delimited_expr = true 14 | remove_nested_parens = true 15 | reorder_impl_items = true 16 | reorder_imports = true 17 | reorder_modules = true 18 | tab_spaces = 4 19 | unstable_features = true 20 | use_field_init_shorthand = true 21 | use_try_shorthand = true 22 | wrap_comments = true 23 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/sign.rs: -------------------------------------------------------------------------------- 1 | use structopt::StructOpt; 2 | 3 | /// Sign a transaction 4 | #[derive(StructOpt, Debug)] 5 | pub struct Sign { 6 | /// The JSON string or filename defining the transaction to sign 7 | pub transaction: String, 8 | /// The private key that will be used to sign the transaction 9 | #[structopt(short = "k", long)] 10 | pub private_key: Option, 11 | /// The chain id that will be used to sign the transaction 12 | #[structopt(short, long)] 13 | pub chain_id: Option, 14 | /// Push transaction after signing 15 | #[structopt(short, long)] 16 | pub push_transaction: bool, 17 | } 18 | -------------------------------------------------------------------------------- /internal/bench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | # plotters = "0.2.1" 11 | regex = "1" 12 | lazy_static = "1.3" 13 | rand_regex = "0.14" 14 | rand = "0.7" 15 | rand_xorshift = "0.2" 16 | # eosio = { path = "../../crates/eosio" } 17 | # log = "0.4" 18 | # pretty_env_logger = "0.3" 19 | # structopt = "0.3" 20 | # path-slash = "0.1" 21 | util = { path = "../util" } 22 | serde = { version = "1.0", features = ["derive"] } 23 | serde_json = "1.0" 24 | -------------------------------------------------------------------------------- /docker/eos.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | # Arguments 4 | ARG fork=EOSIO 5 | ARG branch=v2.0.3 6 | 7 | # Build 8 | RUN apt-get update && \ 9 | apt-get install -y git sudo 10 | RUN git clone \ 11 | --recursive \ 12 | --branch $branch \ 13 | --single-branch \ 14 | https://github.com/$fork/eos.git \ 15 | /eos 16 | WORKDIR /eos 17 | RUN git submodule update --init --recursive 18 | RUN yes | ./scripts/eosio_build.sh 19 | RUN ./scripts/eosio_install.sh 20 | 21 | # Environment variables 22 | ENV EOSIO_ROOT /root/eosio/2.0 23 | ENV BOOST_ROOT "${EOSIO_ROOT}/src/boost_1_71_0" 24 | ENV PATH "${EOSIO_ROOT}/bin:${PATH}" 25 | 26 | ENTRYPOINT [ "nodeos" ] 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | matrix: 7 | fast_finish: true 8 | git: 9 | submodules: false 10 | before_install: 11 | - docker pull sagansoftware/eosio.contracts:1.9.0 12 | install: 13 | - rustup target add wasm32-unknown-unknown 14 | - rustup component add rustfmt 15 | - cargo install wasm-gc 16 | - cargo install mdbook 17 | - cargo install cargo-readme 18 | services: 19 | - docker 20 | script: 21 | - cargo unit-tests 22 | - cargo docker-tests 23 | - cargo build-docs 24 | deploy: 25 | provider: pages 26 | skip_cleanup: true 27 | github_token: $GITHUB_TOKEN 28 | keep_history: true 29 | local_dir: target/doc 30 | -------------------------------------------------------------------------------- /crates/eosio/src/resources.rs: -------------------------------------------------------------------------------- 1 | //! TODO docs 2 | 3 | /// RAM in bytes 4 | pub struct RamBytes(i64); 5 | 6 | impl From for RamBytes { 7 | #[inline] 8 | #[must_use] 9 | fn from(value: i64) -> Self { 10 | Self(value) 11 | } 12 | } 13 | 14 | /// Net Weight 15 | pub struct NetWeight(i64); 16 | 17 | impl From for NetWeight { 18 | #[inline] 19 | #[must_use] 20 | fn from(value: i64) -> Self { 21 | Self(value) 22 | } 23 | } 24 | 25 | /// CPU Weight 26 | pub struct CpuWeight(i64); 27 | 28 | impl From for CpuWeight { 29 | #[inline] 30 | #[must_use] 31 | fn from(value: i64) -> Self { 32 | Self(value) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /book/examples/hello-bare.md: -------------------------------------------------------------------------------- 1 | # Hello, World! 2 | 3 | This example shows how to create a smart contract in Rust that prints a greeting, **without using the `eosio` crate**. This is used to demonstrate the code that is being abstracted away, and to compare the abstraction overhead. 4 | 5 | ## Usage 6 | 7 | ```sh 8 | cleos push action hello hi '["world"]' -p 'hello@active' 9 | ``` 10 | 11 | ## Cargo.toml 12 | 13 | ```toml 14 | {{#include ../../examples/hello_bare/Cargo.toml}} 15 | ``` 16 | 17 | ## Source 18 | 19 | ```rust,no_run,noplaypen 20 | {{#include ../../examples/hello_bare/src/lib.rs}} 21 | ``` 22 | 23 | ## ABI 24 | 25 | ```json 26 | {{#include ../../examples/hello_bare/hello_bare.abi.json}} 27 | ``` 28 | -------------------------------------------------------------------------------- /crates/eosio_macros/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/sagan-software/eosio-rust.svg?branch=master)](https://travis-ci.org/sagan-software/eosio-rust) 2 | 3 | # eosio_macros 4 | 5 | Macros for creating compile-time EOSIO names and symbols. 6 | 7 | Creating EOSIO names: 8 | 9 | ```rust 10 | use eosio_macros::n; 11 | assert_eq!(n!("test"), 14_605_613_396_213_628_928); 12 | assert_eq!(n!("1234"), 614_248_767_926_829_056); 13 | assert_eq!(n!("123451234512"), 614_251_535_012_020_768); 14 | assert_eq!(n!("eosio.token"), 6_138_663_591_592_764_928); 15 | ``` 16 | 17 | Creating EOSIO symbols: 18 | 19 | ```rust 20 | use eosio_macros::s; 21 | assert_eq!(s!(4, "EOS"), 1397703940); 22 | ``` 23 | 24 | License: MIT OR Apache-2.0 25 | -------------------------------------------------------------------------------- /crates/eosio_cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_cli" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "src/lib.rs" 9 | 10 | [[bin]] 11 | name = "eosrs" 12 | path = "src/main.rs" 13 | doc = false 14 | 15 | [dependencies] 16 | # clap = "2.32.0" 17 | # futures = "0.1.20" 18 | eosio = { version = "0.3", path = "../eosio" } 19 | # eosio_rpc = { path = "../eosio_rpc", features = ["use-hyper"] } 20 | # hyper = { version = "0.12" } 21 | quote = "1.0" 22 | structopt = "0.3" 23 | 24 | [dependencies.syn] 25 | version = "1.0" 26 | default-features = false 27 | features = [ 28 | "full", 29 | "parsing", 30 | "visit", 31 | "clone-impls", 32 | "extra-traits", 33 | ] -------------------------------------------------------------------------------- /crates/eosio_numstr/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/sagan-software/eosio-rust.svg?branch=master)](https://travis-ci.org/sagan-software/eosio-rust) 2 | 3 | # eosio_numstr 4 | 5 | This crate provides functions for converting EOSIO names and 6 | symbols to and from string representations. 7 | 8 | Creating an EOSIO name: 9 | 10 | ```rust 11 | use eosio_numstr::name_from_bytes; 12 | let name = name_from_bytes("eosio".bytes()).unwrap(); 13 | assert_eq!(name, 6138663577826885632); 14 | ``` 15 | 16 | Creating an EOSIO symbol: 17 | 18 | ```rust 19 | use eosio_numstr::symbol_from_bytes; 20 | let symbol = symbol_from_bytes(4, "EOS".bytes()).unwrap(); 21 | assert_eq!(symbol, 1397703940); 22 | ``` 23 | 24 | License: MIT OR Apache-2.0 25 | -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/sagan-software/eosio-rust.svg?branch=master)](https://travis-ci.org/sagan-software/eosio-rust) 2 | 3 | # eosio_cdt_sys 4 | 5 | This crate provides low-level FFI bindings for EOSIO smart contract 6 | development. Bindings are automatically generated with [`bindgen`] 7 | from header files in the [`EOSIO/eosio.cdt`] repository. 8 | 9 | For more idiomatic Rust wrappers please see the [`eosio`] and 10 | [`eosio_cdt`] crates. 11 | 12 | [`bindgen`]: https://github.com/rust-lang/rust-bindgen 13 | [`EOSIO/eosio.cdt`]: https://github.com/EOSIO/eosio.cdt 14 | [`eosio`]: https://crates.io/crates/eosio 15 | [`eosio_cdt`]: https://crates.io/crates/eosio_cdt 16 | 17 | License: MIT OR Apache-2.0 18 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/src/n.rs: -------------------------------------------------------------------------------- 1 | use eosio_numstr::name_from_bytes; 2 | use proc_macro2::{Literal, TokenStream}; 3 | use quote::{ToTokens, TokenStreamExt}; 4 | use syn::{ 5 | parse::{Parse, ParseStream, Result as ParseResult}, 6 | LitStr, 7 | }; 8 | 9 | pub struct EosioName(u64); 10 | 11 | impl Parse for EosioName { 12 | fn parse(input: ParseStream) -> ParseResult { 13 | let name = input.parse::()?.value(); 14 | name_from_bytes(name.bytes()) 15 | .map(Self) 16 | .map_err(|e| input.error(e)) 17 | } 18 | } 19 | 20 | impl ToTokens for EosioName { 21 | fn to_tokens(&self, tokens: &mut TokenStream) { 22 | tokens.append(Literal::u64_suffixed(self.0)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/eosio_wrap/src/lib.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use eosio_cdt::*; 3 | use std::marker::PhantomData; 4 | 5 | #[eosio::action] 6 | pub fn exec( 7 | executer: PhantomData, 8 | trx: PhantomData>>, 9 | ) { 10 | require_auth(current_receiver()); 11 | let mut ds = current_data_stream(); 12 | let executer = ds.read::().expect("read"); 13 | require_auth(executer); 14 | 15 | let id: TransactionId = { 16 | let now = current_time_point().as_micros() as u128; 17 | let value = u128::from(executer.as_u64()) << 64 | now; 18 | value.into() 19 | }; 20 | 21 | let bytes = ds.as_remaining_bytes().unwrap(); 22 | send_deferred_bytes(id, executer, bytes, false); 23 | } 24 | 25 | eosio::abi!(exec); 26 | -------------------------------------------------------------------------------- /book/examples/tic-tac-toe.md: -------------------------------------------------------------------------------- 1 | # Tic-Tac-Toe 2 | 3 | This example shows how to create a smart contract that reads and writes tables. 4 | 5 | ## Usage 6 | 7 | ```sh 8 | cleos push action tictactoe create '["alice","bob"]' -p 'alice@active' 9 | cleos push action tictactoe makemove '["alice","bob",1,0,1]' -p 'alice@active' 10 | cleos push action tictactoe restart '["alice","bob",1]' -p 'alice@active' 11 | cleos push action tictactoe close '["alice","bob"]' -p 'alice@active' 12 | ``` 13 | 14 | ## Cargo.toml 15 | 16 | ```toml 17 | {{#include ../../examples/hello/Cargo.toml}} 18 | ``` 19 | 20 | ## Source 21 | 22 | ```rust,no_run,noplaypen 23 | {{#include ../../examples/hello/src/lib.rs}} 24 | ``` 25 | 26 | ## ABI 27 | 28 | ```json 29 | {{#include ../../examples/hello/hello.abi.json}} 30 | ``` 31 | -------------------------------------------------------------------------------- /book/install/optional.md: -------------------------------------------------------------------------------- 1 | # Optional Dependencies 2 | 3 | ## wasm-gc 4 | 5 | [wasm-gc](https://github.com/alexcrichton/wasm-gc) is a command-line tool that removes unused code in WASM files. It can be installed with Cargo: 6 | 7 | ```sh 8 | cargo install wasm-gc 9 | ``` 10 | 11 | ## Binaryen 12 | 13 | [Binaryen](https://github.com/WebAssembly/binaryen) comes with a command-line tool called `wasm-opt` that optimizes WASM file sizes. Binaryen can be installed with most system package managers. 14 | 15 | ## WebAssembly Binary Toolkit (WABT) 16 | 17 | [WABT](https://github.com/WebAssembly/wabt) comes with a command-line tool `wasm2wat` that can be used to create textual representations of WASM files, which can be useful for debugging. WABT can be installed with most system package managers. 18 | -------------------------------------------------------------------------------- /docker/eosio.contracts.dockerfile: -------------------------------------------------------------------------------- 1 | FROM sagansoftware/eosio.contracts:1.8.3 AS old_contracts 2 | 3 | FROM sagansoftware/eosio.cdt:1.7.0 4 | 5 | # Arguments 6 | ARG fork=EOSIO 7 | ARG branch=v1.9.1 8 | 9 | # Build 10 | RUN git clone \ 11 | --recursive \ 12 | --branch $branch \ 13 | --single-branch \ 14 | https://github.com/$fork/eosio.contracts.git \ 15 | /eosio.contracts 16 | WORKDIR /eosio.contracts 17 | RUN ./build.sh -y -t -e ${EOSIO_ROOT} -c ${EOSIO_CDT_ROOT} 18 | RUN ./build/tests/unit_test --show_progress=yes 19 | WORKDIR / 20 | 21 | ENV EOSIO_CONTRACTS_DIRECTORY /eosio.contracts/build/contracts 22 | ENV EOSIO_OLD_CONTRACTS_DIRECTORY /eosio.contracts/build/old_contracts 23 | 24 | COPY --from=old_contracts ${EOSIO_CONTRACTS_DIRECTORY} ${EOSIO_OLD_CONTRACTS_DIRECTORY} 25 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributor Quickstart 2 | 3 | Want to help? Great! Here's how you can get started: 4 | 5 | ```bash 6 | git clone git@github.com:sagan-software/rust-eos.git 7 | cd rust-eos 8 | make 9 | ``` 10 | 11 | That will clone the repo, install Rust, build crates, and run unit tests. 12 | 13 | ### Optional Dependencies 14 | 15 | Please be sure to install all the [optional dependencies](README.md#optional-dependencies) listed in the README. 16 | 17 | ### Hello World 18 | 19 | To test out the `hello` example on-chain, first startup a local node with Docker: 20 | 21 | ```bash 22 | make docker 23 | ``` 24 | 25 | Then in a new terminal window: 26 | 27 | ```bash 28 | make wallet 29 | make accounts 30 | make examples 31 | make say_hi 32 | ``` 33 | 34 | If all goes well you should see "Hello, contributor" in the console. 35 | -------------------------------------------------------------------------------- /crates/eosio/src/table/primary_table_index.rs: -------------------------------------------------------------------------------- 1 | use super::{ScopeName, Table}; 2 | use crate::AccountName; 3 | use core::marker::PhantomData; 4 | 5 | /// TODO docs 6 | #[derive(Copy, Clone, Debug)] 7 | pub struct PrimaryTableIndex 8 | where 9 | T: Table, 10 | { 11 | /// TODO docs 12 | pub code: AccountName, 13 | /// TODO docs 14 | pub scope: ScopeName, 15 | /// TODO docs 16 | _data: PhantomData, 17 | } 18 | 19 | impl PrimaryTableIndex 20 | where 21 | T: Table, 22 | { 23 | /// TODO docs 24 | #[inline] 25 | pub fn new(code: C, scope: S) -> Self 26 | where 27 | C: Into, 28 | S: Into, 29 | { 30 | Self { 31 | code: code.into(), 32 | scope: scope.into(), 33 | _data: PhantomData, 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/transfer.rs: -------------------------------------------------------------------------------- 1 | use eosio::{AccountName, Asset}; 2 | use structopt::StructOpt; 3 | 4 | /// Transfer tokens from account to account 5 | #[derive(StructOpt, Debug)] 6 | pub struct Transfer { 7 | /// The account sending tokens 8 | pub sender: AccountName, 9 | /// The account receiving tokens 10 | pub recipient: AccountName, 11 | /// The amount of tokens to send 12 | pub amount: Asset, 13 | /// The memo for the transfer 14 | pub memo: Option, 15 | /// The contract which controls the token 16 | #[structopt(short, long, default_value = "eosio.token")] 17 | pub contract: AccountName, 18 | /// Pay ram to open recipient's token balance row 19 | #[structopt(long)] 20 | pub pay_ram_to_open: bool, 21 | #[structopt(flatten)] 22 | pub transaction_opts: super::TransactionOpts, 23 | } 24 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/wrap.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | use structopt::StructOpt; 3 | 4 | #[derive(StructOpt, Debug)] 5 | pub enum Wrap { 6 | /// Execute a transaction while bypassing authorization checks 7 | Exec(Exec), 8 | } 9 | 10 | /// Execute a transaction while bypassing authorization checks 11 | #[derive(StructOpt, Debug)] 12 | pub struct Exec { 13 | /// Account executing the transaction and paying for the deferred 14 | /// transaction RAM 15 | pub executer: AccountName, 16 | /// The JSON string or filename defining the transaction to execute 17 | pub transaction: String, 18 | /// The account which controls the wrap contract 19 | #[structopt(short, long, default_value = "eosio.wrap")] 20 | pub contract: AccountName, 21 | #[structopt(flatten)] 22 | pub transaction_opts: super::TransactionOpts, 23 | } 24 | -------------------------------------------------------------------------------- /crates/eosio/src/bytes/marker.rs: -------------------------------------------------------------------------------- 1 | //! 2 | use crate::{NumBytes, Read, ReadError, Write, WriteError}; 3 | use core::marker::PhantomData; 4 | 5 | impl NumBytes for PhantomData { 6 | #[inline] 7 | #[must_use] 8 | fn num_bytes(&self) -> usize { 9 | 0 10 | } 11 | } 12 | 13 | impl Read for PhantomData { 14 | #[inline] 15 | fn read(_bytes: &[u8], _pos: &mut usize) -> Result { 16 | Ok(Self) 17 | } 18 | } 19 | 20 | impl Write for PhantomData { 21 | #[inline] 22 | fn write( 23 | &self, 24 | _bytes: &mut [u8], 25 | _pos: &mut usize, 26 | ) -> Result<(), WriteError> { 27 | Ok(()) 28 | } 29 | } 30 | 31 | // TODO PhantomPinned 32 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/src/s.rs: -------------------------------------------------------------------------------- 1 | use eosio_numstr::symbol_from_bytes; 2 | use proc_macro2::{Literal, TokenStream}; 3 | use quote::{ToTokens, TokenStreamExt}; 4 | use syn::{ 5 | parse::{Parse, ParseStream, Result}, 6 | LitInt, LitStr, Token, 7 | }; 8 | 9 | pub struct EosioSymbol(u64); 10 | 11 | impl Parse for EosioSymbol { 12 | fn parse(input: ParseStream) -> Result { 13 | let precision = input.parse::()?.base10_parse::()?; 14 | input.parse::()?; 15 | let code = input.parse::()?.value(); 16 | symbol_from_bytes(precision, code.bytes()) 17 | .map(Self) 18 | .map_err(|e| input.error(e)) 19 | } 20 | } 21 | 22 | impl ToTokens for EosioSymbol { 23 | fn to_tokens(&self, tokens: &mut TokenStream) { 24 | tokens.append(Literal::u64_suffixed(self.0)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## Change Description 5 | 6 | 7 | 8 | ## API Changes 9 | - [ ] API Changes 10 | 11 | 12 | 13 | 14 | ## Documentation Additions 15 | - [ ] Documentation Additions 16 | 17 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_currency_balance.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | use serde::Serialize; 3 | 4 | crate::builder!( 5 | "/v1/chain/get_currency_balance", 6 | GetCurrencyBalanceParams, 7 | GetCurrencyBalance 8 | ); 9 | 10 | #[derive(Serialize, Clone)] 11 | pub struct GetCurrencyBalanceParams { 12 | code: AccountName, 13 | account: AccountName, 14 | #[serde(skip_serializing_if = "Option::is_none")] 15 | symbol: Option, 16 | } 17 | 18 | pub fn get_currency_balance< 19 | C: Into, 20 | A: Into, 21 | S: ToString, 22 | >( 23 | code: C, 24 | account: A, 25 | symbol: Option, 26 | ) -> GetCurrencyBalanceParams { 27 | GetCurrencyBalanceParams { 28 | code: code.into(), 29 | account: account.into(), 30 | symbol: symbol.map(|s| s.to_string()), 31 | } 32 | } 33 | 34 | pub type GetCurrencyBalance = Vec; 35 | -------------------------------------------------------------------------------- /internal/scripts/src/opts.rs: -------------------------------------------------------------------------------- 1 | use structopt::StructOpt; 2 | 3 | #[derive(StructOpt, Debug)] 4 | #[structopt(name = "scripts")] 5 | pub struct Opt { 6 | #[structopt(subcommand)] 7 | pub cmd: Cmd, 8 | } 9 | 10 | #[derive(StructOpt, Debug)] 11 | #[structopt(about = "which subcommand to run")] 12 | pub enum Cmd { 13 | DeployExamples, 14 | DockerInit, 15 | DockerUp, 16 | RunBench, 17 | BuildContracts(BuildContracts), 18 | BuildDocs, 19 | RunExamples, 20 | RunTests(RunTestsCmd), 21 | } 22 | 23 | #[derive(StructOpt, Debug)] 24 | pub struct BuildContracts { 25 | /// The package to build 26 | #[structopt(short = "p", long = "package")] 27 | pub package: Option, 28 | #[structopt(long = "wasm-opt")] 29 | pub wasm_opt: bool, 30 | } 31 | 32 | #[derive(StructOpt, Debug)] 33 | pub struct RunTestsCmd { 34 | #[structopt(long = "wasm-opt")] 35 | pub wasm_opt: bool, 36 | } 37 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [profile.release] 2 | opt-level = "z" 3 | debug = false 4 | rpath = false 5 | lto = true 6 | debug-assertions = false 7 | codegen-units = 1 8 | 9 | [workspace] 10 | members = [ 11 | # "contracts/eosio-assert", 12 | "contracts/eosio_bios", 13 | "contracts/eosio_forum", 14 | "contracts/eosio_msig", 15 | "contracts/eosio_system", 16 | "contracts/eosio_token", 17 | "contracts/eosio_wrap", 18 | "crates/eosio", 19 | "crates/eosio_cdt_sys", 20 | "crates/eosio_cdt", 21 | # "crates/eosio_cli", 22 | "crates/eosio_macros_internal", 23 | "crates/eosio_macros", 24 | "crates/eosio_numstr", 25 | # "crates/eosio_rpc", 26 | "examples/addressbook", 27 | "examples/hello_bare", 28 | "examples/hello", 29 | "examples/tictactoe", 30 | "internal/bench", 31 | "internal/bench_cpp", 32 | "internal/bench_rs", 33 | "internal/scripts", 34 | "internal/util", 35 | ] 36 | -------------------------------------------------------------------------------- /internal/scripts/src/main.rs: -------------------------------------------------------------------------------- 1 | mod build_contracts; 2 | mod build_docs; 3 | mod deploy_examples; 4 | mod docker_init; 5 | mod docker_tests; 6 | mod docker_up; 7 | mod opts; 8 | mod run_examples; 9 | 10 | use self::opts::{Cmd, Opt}; 11 | use structopt::StructOpt; 12 | 13 | fn main() { 14 | // std::env::set_var("RUST_LOG", "info"); 15 | // pretty_env_logger::init(); 16 | let opt = Opt::from_args(); 17 | match opt.cmd { 18 | Cmd::RunBench => (), 19 | Cmd::BuildContracts(opts) => build_contracts::build_contracts(opts), 20 | Cmd::BuildDocs => build_docs::build_docs().unwrap(), 21 | Cmd::RunExamples => run_examples::run_examples(), 22 | Cmd::RunTests(opts) => docker_tests::run_test(opts), 23 | Cmd::DockerUp => docker_up::run_docker_up(), 24 | Cmd::DockerInit => docker_init::docker_init(), 25 | Cmd::DeployExamples => deploy_examples::run_deploy_examples().unwrap(), 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /internal/scripts/src/docker_up.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io, 3 | path::Path, 4 | process::{Command, ExitStatus}, 5 | }; 6 | 7 | fn docker_compose() -> Command { 8 | let mut cmd = Command::new("docker-compose"); 9 | let yaml = Path::new(".").join("docker").join("docker-compose.yml"); 10 | cmd.arg("--file").arg(yaml); 11 | cmd 12 | } 13 | 14 | fn docker_volume(name: &str) -> io::Result { 15 | Command::new("docker") 16 | .arg("volume") 17 | .arg("rm") 18 | .arg(name) 19 | .status()?; 20 | Command::new("docker") 21 | .arg("volume") 22 | .arg("create") 23 | .arg(format!("--name={}", name)) 24 | .status() 25 | } 26 | 27 | pub fn run_docker_up() { 28 | docker_compose().arg("down").status().unwrap(); 29 | docker_volume("nodeos-data-volume").unwrap(); 30 | docker_volume("keosd-data-volume").unwrap(); 31 | docker_compose().arg("up").status().unwrap(); 32 | } 33 | -------------------------------------------------------------------------------- /book/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # eosio-rust 2 | 3 | [Introduction](index.md) 4 | 5 | --- 6 | 7 | - [Getting Help](getting-help.md) 8 | - [Install](install/index.md) 9 | - [Install Rust](install/rust.md) 10 | - [Install EOS](install/eos.md) 11 | - [Optional Dependencies](install/optional.md) 12 | - [Quick Start](quick-start.md) 13 | - [Examples](examples/index.md) 14 | - [Hello, World!](examples/hello-bare.md) 15 | - [Hello, EOSIO Rust!](examples/hello.md) 16 | - [Tic-Tac-Toe](examples/tic-tac-toe.md) 17 | - [Address Book](examples/addressbook.md) 18 | - [User Guide](guide/index.md) 19 | - [Declaring Actions](guide/actions.md) 20 | - [Declaring Tables](guide/tables.md) 21 | - [Secondary Keys](guide/secondary-keys.md) 22 | - [Deriving Common Traits](guide/traits.md) 23 | - [Compiling Smart Contracts](guide/compiling.md) 24 | - [Deploying Smart Contracts](guide/deploying.md) 25 | - [Optimizing WASM files](guide/optimization.md) -------------------------------------------------------------------------------- /book/getting-help.md: -------------------------------------------------------------------------------- 1 | # Getting Help 2 | 3 | If you find a bug or think of an improvement please [open an issue] and let us know! 4 | 5 | Otherwise if you are stuck on something or run into problems, here are some resources that could help: 6 | 7 | - For questions about this project: 8 | - [Join our Telegram group][telegram] 9 | - [Open an issue] 10 | - For questions about EOS development: 11 | - [Join the EOS Developers Telegram group](https://t.me/joinchat/Esi1OkPktgcFeJ3Lmlcrqg) 12 | - [Ask on the EOS.IO Stack Exchange](https://eosio.stackexchange.com/) 13 | - [Ask on r/eosdev](https://www.reddit.com/r/eosdev) 14 | - For questions about Rust: 15 | - [Join Mozilla's IRC server](https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-beginners) 16 | - [Ask on the Rust user forums](https://users.rust-lang.org/) 17 | - [Ask on r/rust](https://www.reddit.com/r/rust) 18 | 19 | [open an issue]: https://github.com/sagan-software/eosio-rust/issues/new 20 | [telegram]: https://t.me/eosio_rs -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/net.rs: -------------------------------------------------------------------------------- 1 | use structopt::StructOpt; 2 | 3 | /// Interact with local p2p network connections 4 | #[derive(StructOpt, Debug)] 5 | pub enum Net { 6 | /// start a new connection to a peer 7 | Connect(Connect), 8 | /// close an existing connection 9 | Disconnect(Disconnect), 10 | /// status of existing connection 11 | Status(Status), 12 | /// status of all existing peers 13 | Peers, 14 | } 15 | 16 | /// start a new connection to a peer 17 | #[derive(StructOpt, Debug)] 18 | pub struct Connect { 19 | /// The hostname:port to connect to. 20 | pub host: String, 21 | } 22 | 23 | /// close an existing connection 24 | #[derive(StructOpt, Debug)] 25 | pub struct Disconnect { 26 | /// The hostname:port to disconnect from. 27 | pub host: String, 28 | } 29 | 30 | /// status of existing connection 31 | #[derive(StructOpt, Debug)] 32 | pub struct Status { 33 | /// The hostname:port to query status of connection 34 | pub host: String, 35 | } 36 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_currency_stats.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | crate::builder!( 5 | "/v1/chain/get_currency_stats", 6 | GetCurrencyStatsParams, 7 | GetCurrencyStats 8 | ); 9 | 10 | #[derive(Serialize, Clone)] 11 | pub struct GetCurrencyStatsParams { 12 | code: AccountName, 13 | #[serde(skip_serializing_if = "Option::is_none")] 14 | symbol: Option, 15 | } 16 | 17 | pub type GetCurrencyStats = ::std::collections::HashMap; 18 | 19 | pub fn get_currency_stats, S: ToString>( 20 | code: C, 21 | symbol: Option, 22 | ) -> GetCurrencyStatsParams { 23 | GetCurrencyStatsParams { 24 | code: code.into(), 25 | symbol: symbol.map(|s| s.to_string()), 26 | } 27 | } 28 | 29 | #[derive(Serialize, Deserialize, Debug)] 30 | pub struct CurrencyStats { 31 | pub supply: String, 32 | pub max_supply: String, 33 | pub issuer: AccountName, 34 | } 35 | -------------------------------------------------------------------------------- /docker/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "initial_timestamp": "2018-12-05T08:55:11.000", 3 | "initial_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", 4 | "initial_configuration": { 5 | "max_block_net_usage": 1048576, 6 | "target_block_net_usage_pct": 1000, 7 | "max_transaction_net_usage": 524288, 8 | "base_per_transaction_net_usage": 12, 9 | "net_usage_leeway": 500, 10 | "context_free_discount_net_usage_num": 20, 11 | "context_free_discount_net_usage_den": 100, 12 | "max_block_cpu_usage": 200000, 13 | "target_block_cpu_usage_pct": 500, 14 | "max_transaction_cpu_usage": 150000, 15 | "min_transaction_cpu_usage": 100, 16 | "max_transaction_lifetime": 3600, 17 | "deferred_trx_expiration_window": 600, 18 | "max_transaction_delay": 3888000, 19 | "max_inline_action_size": 4096, 20 | "max_inline_action_depth": 4, 21 | "max_authority_depth": 6 22 | }, 23 | "initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000" 24 | } 25 | -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_cdt_sys" 3 | version = "0.3.0" 4 | authors = ["Liam Curry "] 5 | license = "MIT OR Apache-2.0" 6 | description = "Low-level FFI bindings for EOSIO smart contract development." 7 | edition = "2018" 8 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 9 | categories = [ 10 | "cryptography::cryptocurrencies", 11 | "external-ffi-bindings", 12 | "wasm" 13 | ] 14 | repository = "https://github.com/sagan-software/eosio-rust" 15 | homepage = "https://sagan-software.github.io/eosio-rust/" 16 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-cdt-sys/" 17 | readme = "README.md" 18 | include = [ 19 | "/Cargo.toml", 20 | "/src/**/*.rs", 21 | "/README.md", 22 | "/LICENSE-APACHE", 23 | "/LICENSE-MIT" 24 | ] 25 | 26 | [badges] 27 | maintenance = { status = "actively-developed" } 28 | travis-ci = { repository = "sagan-software/eosio-rust", branch = "master" } 29 | 30 | [features] 31 | default = [] 32 | mock = [] -------------------------------------------------------------------------------- /internal/scripts/src/deploy_examples.rs: -------------------------------------------------------------------------------- 1 | use crate::build_contracts::build_contract; 2 | use std::{io, process::ExitStatus}; 3 | use util::cleos; 4 | 5 | fn deploy_example_contract(account: &str, bin: &str) -> io::Result { 6 | cleos() 7 | .arg("set") 8 | .arg("abi") 9 | .arg(account) 10 | .arg(format!("mnt/dev/examples/{}/{}.abi.json", bin, bin)) 11 | .status()?; 12 | cleos() 13 | .arg("set") 14 | .arg("code") 15 | .arg(account) 16 | .arg(format!("mnt/dev/release/{}_gc.wasm", bin)) 17 | .status() 18 | } 19 | 20 | pub fn run_deploy_examples() -> io::Result<()> { 21 | for (package, bin, account) in &[ 22 | ("addressbook", "addressbook", "addressbook"), 23 | ("hello", "hello", "hello"), 24 | ("hello_bare", "hello_bare", "hellobare"), 25 | ("tictactoe", "tictactoe", "tictactoe"), 26 | ] { 27 | build_contract(package); 28 | deploy_example_contract(account, bin)?; 29 | } 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /crates/eosio/benches/bytes.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate criterion; 3 | extern crate eosio; 4 | 5 | use criterion::{black_box, Criterion}; 6 | use eosio::*; 7 | 8 | fn u8_write(c: &mut Criterion) { 9 | c.bench_function_over_inputs( 10 | "u8::write", 11 | |b, input| b.iter(|| black_box(input).write(&mut [0_u8; 1], &mut 0)), 12 | vec![0_u8, 100, 255], 13 | ); 14 | } 15 | 16 | fn vec_u8_write(c: &mut Criterion) { 17 | c.bench_function_over_inputs( 18 | "Vec::write", 19 | |b, input| b.iter(|| black_box(input).write(&mut [0_u8; 4], &mut 0)), 20 | vec![vec![], vec![0_u8], vec![0_u8, 100], vec![0_u8, 100, 255]], 21 | ); 22 | } 23 | 24 | fn str_write(c: &mut Criterion) { 25 | c.bench_function_over_inputs( 26 | "&str::write", 27 | |b, input| b.iter(|| black_box(input).write(&mut [0_u8; 13], &mut 0)), 28 | vec!["", "Hello", "Hello World!"], 29 | ); 30 | } 31 | 32 | criterion_group!(benches, u8_write, vec_u8_write, str_write,); 33 | criterion_main!(benches); 34 | -------------------------------------------------------------------------------- /crates/eosio/src/ops.rs: -------------------------------------------------------------------------------- 1 | //! TODO docs 2 | /// TODO docs 3 | pub trait CheckedAdd: Sized { 4 | /// TODO docs 5 | type Output; 6 | /// TODO docs 7 | fn checked_add(self, other: Other) -> Self::Output; 8 | } 9 | 10 | /// TODO docs 11 | pub trait CheckedSub: Sized { 12 | /// TODO docs 13 | type Output; 14 | /// TODO docs 15 | fn checked_sub(self, other: Other) -> Self::Output; 16 | } 17 | 18 | /// TODO docs 19 | pub trait CheckedMul: Sized { 20 | /// TODO docs 21 | type Output; 22 | /// TODO docs 23 | fn checked_mul(self, other: Other) -> Self::Output; 24 | } 25 | 26 | /// TODO docs 27 | pub trait CheckedDiv: Sized { 28 | /// TODO docs 29 | type Output; 30 | /// TODO docs 31 | fn checked_div(self, other: Other) -> Self::Output; 32 | } 33 | 34 | /// TODO docs 35 | pub trait CheckedRem: Sized { 36 | /// TODO docs 37 | type Output; 38 | /// TODO docs 39 | fn checked_rem(self, other: Other) -> Self::Output; 40 | } 41 | -------------------------------------------------------------------------------- /crates/eosio_cdt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_cdt" 3 | version = "0.3.1" 4 | authors = ["Liam Curry "] 5 | license = "MIT OR Apache-2.0" 6 | description = "Idiomatic Rust bindings for EOSIO smart contracts." 7 | edition = "2018" 8 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 9 | categories = [ 10 | "api-bindings", 11 | "cryptography::cryptocurrencies", 12 | "wasm" 13 | ] 14 | repository = "https://github.com/sagan-software/eosio-rust" 15 | homepage = "https://sagan-software.github.io/eosio-rust/" 16 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-cdt/" 17 | readme = "README.md" 18 | include = [ 19 | "/Cargo.toml", 20 | "/src/**/*.rs", 21 | "/README.md", 22 | "/LICENSE-APACHE", 23 | "/LICENSE-MIT" 24 | ] 25 | 26 | [badges] 27 | maintenance = { status = "actively-developed" } 28 | travis-ci = { repository = "sagan-software/eosio-rust", branch = "master" } 29 | 30 | [dependencies] 31 | eosio = { version = "0.3.1", path = "../eosio" } 32 | eosio_cdt_sys = { version = "0.3", path = "../eosio_cdt_sys" } 33 | -------------------------------------------------------------------------------- /crates/eosio_rpc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_rpc" 3 | version = "0.1.0" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | cfg-if = "0.1.2" 9 | serde = { version = "1.0", features = ["derive"] } 10 | serde_json = "1.0" 11 | eosio = { path = "../eosio" } 12 | eosio_abi = { path = "../eosio_abi" } 13 | futures-preview = { version = "=0.3.0-alpha.16", features = ["compat"] } 14 | wasm-bindgen = { version = "0.2", features = ["serde-serialize"], optional = true } 15 | js-sys = { version = "0.3.5", optional = true } 16 | wasm-bindgen-futures = { version = "0.3.5", optional = true } 17 | hyper = { version = "0.12", optional = true } 18 | hyper-tls = { version = "0.3", optional = true } 19 | stdweb = { version = "0.4.14", optional = true } 20 | 21 | [dependencies.web-sys] 22 | version = "0.3.4" 23 | optional = true 24 | features = [ 25 | 'Headers', 26 | 'Request', 27 | 'RequestInit', 28 | 'RequestMode', 29 | 'Response', 30 | 'Window', 31 | ] 32 | 33 | [features] 34 | browser = ["wasm-bindgen", "wasm-bindgen-futures", "js-sys", "web-sys"] 35 | server = ["hyper", "hyper-tls"] -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_info.rs: -------------------------------------------------------------------------------- 1 | use crate::builder; 2 | use eosio::AccountName; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | builder!("/v1/chain/get_info", GetInfo, Info); 6 | 7 | #[derive(Serialize, Clone)] 8 | pub struct GetInfo {} 9 | 10 | pub const fn get_info() -> GetInfo { 11 | GetInfo {} 12 | } 13 | 14 | pub type ChainId = String; 15 | 16 | pub type BlockId = String; 17 | 18 | pub type BlockNum = u32; 19 | 20 | pub type ServerVersion = String; 21 | 22 | pub type BlockTimestamp = String; 23 | 24 | #[derive(Deserialize, Serialize, Debug, PartialEq)] 25 | pub struct Info { 26 | pub server_version: ServerVersion, 27 | pub server_version_string: String, 28 | pub chain_id: ChainId, 29 | pub head_block_num: BlockNum, 30 | pub head_block_id: BlockId, 31 | pub head_block_time: BlockTimestamp, 32 | pub head_block_producer: AccountName, 33 | pub last_irreversible_block_num: BlockNum, 34 | pub last_irreversible_block_id: BlockId, 35 | pub virtual_block_cpu_limit: u32, 36 | pub virtual_block_net_limit: u32, 37 | pub block_cpu_limit: u32, 38 | pub block_net_limit: u32, 39 | } 40 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_macros_internal" 3 | version = "0.3.1" 4 | authors = ["Liam Curry "] 5 | license = "MIT OR Apache-2.0" 6 | description = "Internal use only." 7 | edition = "2018" 8 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 9 | categories = ["development-tools::procedural-macro-helpers"] 10 | repository = "https://github.com/sagan-software/eosio-rust" 11 | homepage = "https://sagan-software.github.io/eosio-rust/" 12 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-core-macros-internal/" 13 | readme = "README.md" 14 | include = [ 15 | "/Cargo.toml", 16 | "/src/**/*.rs", 17 | "/README.md", 18 | "/LICENSE-APACHE", 19 | "/LICENSE-MIT" 20 | ] 21 | 22 | [lib] 23 | proc-macro = true 24 | path = "src/lib.rs" 25 | 26 | [dependencies] 27 | eosio_numstr = { version = "0.3", path = "../eosio_numstr" } 28 | heck = "0.3" 29 | proc-macro-hack = "0.5" 30 | proc-macro2 = "1.0" 31 | quote = "1.0" 32 | syn = { version = "1.0.13", features = ["full"] } 33 | 34 | [dev-dependencies] 35 | eosio = { version = ">= 0.2, <= 0.3", path = "../eosio" } 36 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /crates/eosio_macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_macros" 3 | version = "0.3.1" 4 | authors = ["Liam Curry "] 5 | license = "MIT OR Apache-2.0" 6 | description = "Macros for creating compile-time EOSIO names and symbols." 7 | edition = "2018" 8 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 9 | categories = [ 10 | "cryptography::cryptocurrencies", 11 | "encoding", 12 | "parsing", 13 | "value-formatting" 14 | ] 15 | repository = "https://github.com/sagan-software/eosio-rust" 16 | homepage = "https://sagan-software.github.io/eosio-rust/" 17 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-core-macros/" 18 | readme = "README.md" 19 | include = [ 20 | "/Cargo.toml", 21 | "/src/**/*.rs", 22 | "/README.md", 23 | "/LICENSE-APACHE", 24 | "/LICENSE-MIT" 25 | ] 26 | 27 | [badges] 28 | maintenance = { status = "actively-developed" } 29 | travis-ci = { repository = "sagan-software/eosio-rust", branch = "master" } 30 | 31 | [dependencies] 32 | eosio_macros_internal = { version = "0.3.1", path = "../eosio_macros_internal" } 33 | proc-macro-hack = "0.5" 34 | 35 | [dev-dependencies] 36 | trybuild = "1.0" -------------------------------------------------------------------------------- /crates/eosio_numstr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio_numstr" 3 | version = "0.3.1" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | description = "Basic helper functions to work with EOSIO names and symbols" 7 | readme = "README.md" 8 | license = "MIT OR Apache-2.0" 9 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 10 | categories = [ 11 | "cryptography::cryptocurrencies", 12 | "algorithms", 13 | "encoding", 14 | "parsing", 15 | "value-formatting" 16 | ] 17 | repository = "https://github.com/sagan-software/eosio-rust" 18 | homepage = "https://sagan-software.github.io/eosio-rust/" 19 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-numstr/" 20 | include = [ 21 | "/Cargo.toml", 22 | "/README.md", 23 | "/src/**/*.rs", 24 | "/LICENSE-APACHE", 25 | "/LICENSE-MIT" 26 | ] 27 | 28 | [badges] 29 | maintenance = { status = "actively-developed" } 30 | travis-ci = { repository = "sagan-software/eosio-rust", branch = "master" } 31 | 32 | [dev-dependencies] 33 | criterion = "0.3" 34 | proptest = "0.9.5" 35 | 36 | [[bench]] 37 | name = "benches" 38 | harness = false 39 | path = "benches/benches.rs" -------------------------------------------------------------------------------- /crates/eosio/src/table/secondary_table_name.rs: -------------------------------------------------------------------------------- 1 | use super::TableName; 2 | 3 | /// TODO docs 4 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Hash, PartialOrd, Ord)] 5 | pub struct SecondaryTableName(TableName, usize); 6 | 7 | impl SecondaryTableName { 8 | /// TODO docs 9 | #[inline] 10 | #[must_use] 11 | pub const fn new(primary: TableName, index: usize) -> Self { 12 | Self(primary, index) 13 | } 14 | 15 | /// TODO docs 16 | #[inline] 17 | #[must_use] 18 | pub const fn primary(&self) -> TableName { 19 | self.0 20 | } 21 | 22 | /// TODO docs 23 | #[inline] 24 | #[must_use] 25 | pub const fn index(&self) -> usize { 26 | self.1 27 | } 28 | 29 | /// TODO docs 30 | #[must_use] 31 | pub const fn as_u64(&self) -> u64 { 32 | let index = self.1 as u64; 33 | let table = self.0.as_u64(); 34 | (table & 0xFFFF_FFFF_FFFF_FFF0_u64) 35 | | (index & 0x0000_0000_0000_000F_u64) 36 | } 37 | } 38 | 39 | impl From for u64 { 40 | #[inline] 41 | #[must_use] 42 | fn from(t: SecondaryTableName) -> Self { 43 | t.as_u64() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /internal/scripts/src/run_examples.rs: -------------------------------------------------------------------------------- 1 | use util::push_action; 2 | 3 | const TICTACTOE_ACTIONS: &[(&str, &str, &str)] = &[ 4 | ("create", "[\"alice\",\"bob\"]", "alice@active"), 5 | ("makemove", "[\"alice\",\"bob\",1,0,0]", "alice@active"), 6 | ("makemove", "[\"alice\",\"bob\",2,1,0]", "bob@active"), 7 | ("makemove", "[\"alice\",\"bob\",1,0,1]", "alice@active"), 8 | ("makemove", "[\"alice\",\"bob\",2,1,1]", "bob@active"), 9 | ("makemove", "[\"alice\",\"bob\",1,0,2]", "alice@active"), 10 | ("restart", "[\"alice\",\"bob\",1]", "alice@active"), 11 | ("makemove", "[\"alice\",\"bob\",1,0,0]", "alice@active"), 12 | ("makemove", "[\"alice\",\"bob\",2,1,0]", "bob@active"), 13 | ("makemove", "[\"alice\",\"bob\",1,0,1]", "alice@active"), 14 | ("makemove", "[\"alice\",\"bob\",2,1,1]", "bob@active"), 15 | ("makemove", "[\"alice\",\"bob\",1,0,2]", "alice@active"), 16 | ("close", "[\"alice\",\"bob\"]", "alice@active"), 17 | ]; 18 | 19 | pub fn run_examples() { 20 | push_action("hello", "hi", "[\"contributor\"]", "hello@active"); 21 | for (action, data, auth) in TICTACTOE_ACTIONS { 22 | push_action("tictactoe", action, data, auth); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /crates/eosio/src/bytes/option.rs: -------------------------------------------------------------------------------- 1 | use super::{NumBytes, Read, ReadError, Write, WriteError}; 2 | 3 | impl NumBytes for Option 4 | where 5 | T: NumBytes, 6 | { 7 | #[inline] 8 | fn num_bytes(&self) -> usize { 9 | let mut count = self.is_some().num_bytes(); 10 | if let Some(t) = self { 11 | count += t.num_bytes(); 12 | } 13 | count 14 | } 15 | } 16 | 17 | impl Read for Option 18 | where 19 | T: Read, 20 | { 21 | #[inline] 22 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 23 | let is_some = bool::read(bytes, pos)?; 24 | if is_some { 25 | Ok(Some(T::read(bytes, pos)?)) 26 | } else { 27 | Ok(None) 28 | } 29 | } 30 | } 31 | 32 | impl Write for Option 33 | where 34 | T: Write + Default, 35 | { 36 | #[inline] 37 | fn write( 38 | &self, 39 | bytes: &mut [u8], 40 | pos: &mut usize, 41 | ) -> Result<(), WriteError> { 42 | self.is_some().write(bytes, pos)?; 43 | match self { 44 | Some(item) => item.write(bytes, pos), 45 | None => Ok(()), 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/time.rs: -------------------------------------------------------------------------------- 1 | use eosio::{BlockTimestamp, TimePoint, TimePointSec}; 2 | 3 | /// Returns the time in microseconds from 1970 of the current block as a 4 | /// `TimePoint` 5 | #[must_use] 6 | #[inline] 7 | #[allow(clippy::cast_possible_wrap)] 8 | pub fn current_time_point() -> TimePoint { 9 | let micros = unsafe { eosio_cdt_sys::current_time() } as i64; 10 | TimePoint::from_micros(micros) 11 | } 12 | 13 | /// Gets the current time as seconds 14 | #[must_use] 15 | #[inline] 16 | pub fn current_time_point_sec() -> TimePointSec { 17 | current_time_point().as_time_point_sec() 18 | } 19 | 20 | /// Gets the current time as a block timestamp 21 | #[must_use] 22 | #[inline] 23 | pub fn current_block_time() -> BlockTimestamp { 24 | current_time_point().into() 25 | } 26 | 27 | /// Gets the publication time 28 | #[must_use] 29 | #[inline] 30 | #[allow(clippy::cast_possible_wrap)] 31 | pub fn publication() -> TimePoint { 32 | let micros = unsafe { eosio_cdt_sys::publication_time() } as i64; 33 | TimePoint::from_micros(micros) 34 | } 35 | 36 | /// Gets the expiration time 37 | #[must_use] 38 | #[inline] 39 | pub fn expiration() -> TimePointSec { 40 | let secs = unsafe { eosio_cdt_sys::expiration() }; 41 | TimePointSec::from_secs(secs) 42 | } 43 | -------------------------------------------------------------------------------- /contracts/eosio_system/src/exchange_state.rs: -------------------------------------------------------------------------------- 1 | use crate::SELF; 2 | use eosio::{ 3 | n, s, Asset, NumBytes, PrimaryTableIndex, Read, Symbol, Table, TableName, 4 | Write, 5 | }; 6 | use lazy_static::lazy_static; 7 | 8 | #[derive(Read, Write, NumBytes, Default)] 9 | pub struct ExchangeState { 10 | pub supply: Asset, 11 | pub base: Connector, 12 | pub quote: Connector, 13 | } 14 | 15 | #[derive(Read, Write, NumBytes)] 16 | pub struct Connector { 17 | pub balance: Asset, 18 | pub weight: f64, 19 | } 20 | 21 | impl Default for Connector { 22 | fn default() -> Self { 23 | Self { 24 | balance: Asset::default(), 25 | weight: 0.5, 26 | } 27 | } 28 | } 29 | 30 | pub struct RamMarket; 31 | 32 | impl Table for RamMarket { 33 | type Row = ExchangeState; 34 | 35 | const NAME: TableName = TableName::new(n!("rammarket")); 36 | 37 | fn primary_key(row: &Self::Row) -> u64 { 38 | row.supply.symbol.as_u64() 39 | } 40 | } 41 | 42 | pub const RAMCORE_SYMBOL: Symbol = Symbol::new(s!(4, "RAMCORE")); 43 | pub const RAM_SYMBOL: Symbol = Symbol::new(s!(0, "RAM")); 44 | 45 | lazy_static! { 46 | pub static ref RAMMARKET: PrimaryTableIndex = 47 | RamMarket::table(*SELF, *SELF); 48 | } 49 | -------------------------------------------------------------------------------- /examples/hello_bare/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Declare the EOSIO externs to read action data and print to the console. 2 | #[cfg(target_arch = "wasm32")] 3 | extern "C" { 4 | pub fn read_action_data(msg: *mut CVoid, len: u32) -> u32; 5 | pub fn prints_l(cstr: *const u8, len: u32); 6 | pub fn printn(name: u64); 7 | } 8 | 9 | #[repr(u8)] 10 | pub enum CVoid { 11 | // Two dummy variants so the #[repr] attribute can be used. 12 | Variant1, 13 | Variant2, 14 | } 15 | 16 | // EOSIO smart contracts are expected to have an `apply` function. 17 | #[cfg(target_arch = "wasm32")] 18 | #[no_mangle] 19 | pub extern "C" fn apply(_receiver: u64, _code: u64, _action: u64) { 20 | // First print "Hi, " to the console. 21 | { 22 | let msg = "Hi, "; 23 | let ptr = msg.as_ptr(); 24 | let len = msg.len() as u32; 25 | unsafe { prints_l(ptr, len) }; 26 | } 27 | 28 | // Read the action data, which is one EOSIO name (a u64, or 8 bytes). 29 | let name = { 30 | let mut bytes = [0u8; 8]; 31 | let ptr: *mut CVoid = &mut bytes[..] as *mut _ as *mut CVoid; 32 | unsafe { read_action_data(ptr, 8) }; 33 | u64::from_le_bytes(bytes) 34 | }; 35 | 36 | // Finally, print the name to the console. 37 | unsafe { printn(name) }; 38 | } 39 | -------------------------------------------------------------------------------- /crates/eosio/src/table/secondary_table_index.rs: -------------------------------------------------------------------------------- 1 | use super::{ 2 | PrimaryTableIndex, ScopeName, SecondaryTableName, Table, TableName, 3 | }; 4 | use crate::AccountName; 5 | use core::marker::PhantomData; 6 | 7 | /// TODO docs 8 | #[derive(Copy, Clone, Debug)] 9 | pub struct SecondaryTableIndex 10 | where 11 | T: Table, 12 | { 13 | /// TODO docs 14 | pub code: AccountName, 15 | /// TODO docs 16 | pub scope: ScopeName, 17 | /// TODO docs 18 | pub table: SecondaryTableName, 19 | /// TODO docs 20 | _data: PhantomData<(K, T)>, 21 | } 22 | 23 | impl SecondaryTableIndex 24 | where 25 | T: Table, 26 | { 27 | /// TODO docs 28 | #[inline] 29 | pub fn new(code: C, scope: S, name: N, index: usize) -> Self 30 | where 31 | C: Into, 32 | S: Into, 33 | N: Into, 34 | { 35 | Self { 36 | code: code.into(), 37 | scope: scope.into(), 38 | table: SecondaryTableName::new(name.into(), index), 39 | _data: PhantomData, 40 | } 41 | } 42 | 43 | /// TODO docs 44 | #[must_use] 45 | pub fn primary_index(&self) -> PrimaryTableIndex { 46 | PrimaryTableIndex::new(self.code, self.scope) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /crates/eosio/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eosio" 3 | version = "0.3.1" 4 | authors = ["Liam Curry "] 5 | edition = "2018" 6 | license = "MIT OR Apache-2.0" 7 | description = "Core types and traits related to EOSIO blockchains" 8 | repository = "https://github.com/sagan-software/eosio-rust" 9 | keywords = ["eos", "eosio", "blockchain", "crypto", "dapp"] 10 | categories = [ 11 | "api-bindings", 12 | "cryptography::cryptocurrencies", 13 | "data-structures", 14 | "parsing", 15 | "value-formatting" 16 | ] 17 | homepage = "https://sagan-software.github.io/eosio-rust/" 18 | documentation = "https://sagan-software.github.io/eosio-rust/eosio-core/" 19 | readme = "README.md" 20 | include = [ 21 | "Cargo.toml", 22 | "src/**/*.rs", 23 | "README.md", 24 | "LICENSE-APACHE", 25 | "LICENSE-MIT" 26 | ] 27 | 28 | [badges] 29 | maintenance = { status = "actively-developed" } 30 | travis-ci = { repository = "sagan-software/eosio-rust", branch = "master" } 31 | 32 | [dependencies] 33 | eosio_numstr = { version = "0.3.1", path = "../eosio_numstr" } 34 | eosio_macros = { version = "0.3.1", path = "../eosio_macros" } 35 | 36 | [dev-dependencies] 37 | criterion = "0.3" 38 | proptest = "0.9.5" 39 | 40 | [[bench]] 41 | name = "bytes" 42 | harness = false 43 | path = "benches/bytes.rs" -------------------------------------------------------------------------------- /crates/eosio_rpc/src/error.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug)] 4 | pub enum Error { 5 | BadRequestJson(::serde_json::Error), 6 | BadRequest, 7 | NoWindow, 8 | BadResponse, 9 | BadResponseJson(::serde_json::Error), 10 | EosError(ErrorResponse), 11 | } 12 | 13 | #[cfg(feature = "use-hyper")] 14 | impl From for Error { 15 | fn from(err: hyper::Error) -> Self { 16 | println!("HYPER ERROR: {:#?}", err); 17 | Error::BadResponse 18 | } 19 | } 20 | 21 | impl From for Error { 22 | fn from(err: serde_json::Error) -> Self { 23 | println!("SERDE ERROR: {:#?}", err); 24 | Error::BadResponse 25 | } 26 | } 27 | 28 | #[derive(Debug, Deserialize, Serialize, Clone)] 29 | pub struct ErrorResponse { 30 | pub code: u16, 31 | pub message: String, 32 | pub error: ErrorMessage, 33 | } 34 | 35 | #[derive(Debug, Deserialize, Serialize, Clone)] 36 | pub struct ErrorMessage { 37 | pub code: u16, 38 | pub name: String, 39 | pub what: String, 40 | pub details: Vec, 41 | } 42 | 43 | #[derive(Debug, Deserialize, Serialize, Clone)] 44 | pub struct ErrorDetails { 45 | pub message: String, 46 | pub file: String, 47 | pub line_number: u32, 48 | pub method: String, 49 | } 50 | -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides low-level FFI bindings for EOSIO smart contract 2 | //! development. Bindings are automatically generated with [`bindgen`] 3 | //! from header files in the [`EOSIO/eosio.cdt`] repository. 4 | //! 5 | //! For more idiomatic Rust wrappers please see the [`eosio`] and 6 | //! [`eosio_cdt`] crates. 7 | //! 8 | //! [`bindgen`]: https://github.com/rust-lang/rust-bindgen 9 | //! [`EOSIO/eosio.cdt`]: https://github.com/EOSIO/eosio.cdt 10 | //! [`eosio`]: https://crates.io/crates/eosio 11 | //! [`eosio_cdt`]: https://crates.io/crates/eosio_cdt 12 | #![no_std] 13 | #![allow( 14 | non_upper_case_globals, 15 | non_camel_case_types, 16 | non_snake_case, 17 | improper_ctypes, 18 | dead_code, 19 | clippy::missing_docs_in_private_items, 20 | clippy::missing_inline_in_public_items, 21 | clippy::missing_const_for_fn, 22 | clippy::op_ref, 23 | clippy::use_self, 24 | clippy::unseparated_literal_suffix 25 | )] 26 | 27 | // #[cfg(target_arch = "wasm32")] 28 | mod bindings; 29 | 30 | // #[cfg(target_arch = "wasm32")] 31 | pub use self::bindings::*; 32 | 33 | // #[cfg(any(not(target_arch = "wasm32"), feature = "mock"))] 34 | // mod mock_bindings; 35 | 36 | // #[cfg(any(not(target_arch = "wasm32"), feature = "mock"))] 37 | // pub use self::mock_bindings::*; 38 | 39 | pub use core::ffi::c_void; 40 | pub type c_char = u8; 41 | pub type c_int = i32; 42 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/tests/tests.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | 3 | #[test] 4 | fn struct_named_fields() { 5 | #[derive(Read, Write, NumBytes, PartialEq, Debug)] 6 | struct Thing { 7 | a: u64, 8 | b: u64, 9 | c: u32, 10 | } 11 | 12 | let thing1 = Thing { a: 1, b: 2, c: 3 }; 13 | 14 | let mut bytes = [0u8; 100]; 15 | let mut write_pos = 0; 16 | thing1.write(&mut bytes, &mut write_pos).unwrap(); 17 | assert_eq!(write_pos, 20); 18 | 19 | let mut read_pos = 0; 20 | let thing2 = Thing::read(&bytes, &mut read_pos).unwrap(); 21 | assert_eq!(read_pos, write_pos); 22 | 23 | assert_eq!(thing1, thing2); 24 | assert_eq!(thing1.a, 1); 25 | assert_eq!(thing1.b, 2); 26 | assert_eq!(thing1.c, 3); 27 | } 28 | 29 | #[test] 30 | fn struct_unnamed_fields() { 31 | #[derive(Read, Write, NumBytes, PartialEq, Debug)] 32 | struct Thing(u64, u64, u32); 33 | 34 | let thing1 = Thing(1, 2, 3); 35 | 36 | let mut bytes = [0u8; 100]; 37 | 38 | let mut write_pos = 0; 39 | thing1.write(&mut bytes, &mut write_pos).unwrap(); 40 | assert_eq!(write_pos, 20); 41 | 42 | let mut read_pos = 0; 43 | let thing2 = Thing::read(&bytes, &mut read_pos).unwrap(); 44 | assert_eq!(read_pos, write_pos); 45 | 46 | assert_eq!(thing1, thing2); 47 | assert_eq!(thing1.0, 1); 48 | assert_eq!(thing1.1, 2); 49 | assert_eq!(thing1.2, 3); 50 | } 51 | -------------------------------------------------------------------------------- /contracts/eosio_assert/src/lib.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | 3 | pub struct StoredChainParams { 4 | pub chain_id: Checksum256, 5 | pub chain_name: String, 6 | pub icon: Checksum256, 7 | pub hash: Checksum256, 8 | pub next_unique_id: u64, 9 | } 10 | 11 | pub struct ContractAction { 12 | pub contract: AccountName, 13 | pub action: ActionName, 14 | } 15 | 16 | pub struct StoredManifest { 17 | pub unique_id: u64, 18 | pub id: Checksum256, 19 | pub account: AccountName, 20 | pub domain: String, 21 | pub appmeta: String, 22 | pub whitelist: Vec, 23 | } 24 | 25 | pub struct AbiHash { 26 | pub owner: AccountName, 27 | pub hash: Checksum256, 28 | } 29 | 30 | #[eosio::action] 31 | pub fn setchain( 32 | _chain_id: Ignore, 33 | _chain_name: Ignore, 34 | _icon: Ignore, 35 | ) { 36 | require_auth(n!("eosio")); 37 | } 38 | 39 | // #[eosio::action("add.manifest")] 40 | pub fn add_manifest( 41 | account: Ignore, 42 | domain: Ignore, 43 | appmeta: Ignore, 44 | whitelist: Ignore>, 45 | ) { 46 | } 47 | 48 | // #[eosio::action("del.manifest")] 49 | pub fn del_manifest(id: Checksum256) {} 50 | 51 | // #[eosio::action] 52 | pub fn require( 53 | chain_params_hash: Checksum256, 54 | manifest_id: Checksum256, 55 | actions: Vec, 56 | abi_hashes: Vec, 57 | ) { 58 | } 59 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn( 2 | clippy::all, 3 | clippy::complexity, 4 | clippy::style, 5 | clippy::perf, 6 | clippy::nursery, 7 | clippy::cargo 8 | )] 9 | 10 | pub mod chain; 11 | pub mod history; 12 | pub mod net; 13 | pub mod producer; 14 | 15 | mod client; 16 | mod clients; 17 | mod error; 18 | 19 | pub use self::client::*; 20 | pub use self::clients::*; 21 | pub use self::error::*; 22 | 23 | #[macro_export] 24 | macro_rules! builder { 25 | ($path:expr, $params:ty, $output:ty) => { 26 | impl $params { 27 | pub fn fetch( 28 | self, 29 | client: &C, 30 | ) -> impl std::future::Future> { 31 | client.fetch::<$output, $params>($path, self) 32 | } 33 | } 34 | }; 35 | } 36 | 37 | // mod builder { 38 | // use crate::client::Client; 39 | // use crate::error::Error; 40 | // use futures::future::Future; 41 | // use serde::{Deserialize, Serialize}; 42 | 43 | // pub trait Builder: Serialize { 44 | // const PATH: &'static str; 45 | 46 | // type Output: 'static + for<'de> Deserialize<'de>; 47 | 48 | // fn fetch(&self, client: &Client) -> Box> { 49 | // Box::new(client.fetch(Self::PATH, Some(self))) 50 | // } 51 | // } 52 | // } 53 | 54 | // pub use self::builder::*; 55 | -------------------------------------------------------------------------------- /book/index.md: -------------------------------------------------------------------------------- 1 | # EOSIO Rust 2 | 3 | > **DISCLAIMER:** _This project is in early development and we looking for feedback on all APIs and features. All APIs and features should be considered unstable and insecure until version `1.0` is released. This code is not yet suitable for production environments where user funds are at risk. Thank you._ 4 | 5 | This project intends to enable developers to write full-stack EOSIO applications using the Rust programming language. We believe Rust is an excellent choice for EOSIO smart contract development with its focus on safety, speed, and WebAssembly. Furthermore, projects like [wasm-bindgen][wasm_bindgen] and [stdweb] make it possible to write full-stack Rust web applications, limiting the need for Javascript and enabling code reuse between browsers, servers, and smart contracts. 6 | 7 | The primary goals of this project are to provide Rust crates that: 8 | 9 | - Enable developers to write secure EOSIO smart contracts. 10 | - Streamline the development of full-stack EOSIO web applications. 11 | - Simplify managing and updating EOSIO table schemas. 12 | - Allow developers to publish reusable smart contract code. 13 | 14 | [wasm_bindgen]: https://github.com/rustwasm/wasm-bindgen/ 15 | [stdweb]: https://github.com/koute/stdweb/ 16 | [eosio]: https://sagan-software.github.io/eosio-rust/eosio/ 17 | [eosio_macros]: https://sagan-software.github.io/eosio-rust/eosio_macros/ 18 | [eosio_sys]: https://sagan-software.github.io/eosio-rust/eosio_sys/ 19 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/push.rs: -------------------------------------------------------------------------------- 1 | use eosio::{AccountName, ActionName}; 2 | use structopt::StructOpt; 3 | 4 | /// Push arbitrary transactions to the blockchain 5 | #[derive(StructOpt, Debug)] 6 | pub enum Push { 7 | /// Push a transaction with a single action 8 | Action(Action), 9 | /// Push an arbitrary JSON transaction 10 | Transaction(Transaction), 11 | /// Push an array of arbitrary JSON transactions 12 | Transactions(Transactions), 13 | } 14 | 15 | /// Push a transaction with a single action 16 | #[derive(StructOpt, Debug)] 17 | pub struct Action { 18 | /// The account providing the contract to execute 19 | pub account: AccountName, 20 | /// A JSON string or filename defining the action to execute on the 21 | /// contract 22 | pub action: ActionName, 23 | /// The arguments to the contract 24 | pub data: String, 25 | #[structopt(flatten)] 26 | pub transaction_opts: super::TransactionOpts, 27 | } 28 | 29 | /// Push an arbitrary JSON transaction 30 | #[derive(StructOpt, Debug)] 31 | pub struct Transaction { 32 | /// The JSON string or filename defining the transaction to push 33 | pub transaction: String, 34 | #[structopt(flatten)] 35 | pub transaction_opts: super::TransactionOpts, 36 | } 37 | 38 | /// Push an array of arbitrary JSON transactions 39 | #[derive(StructOpt, Debug)] 40 | pub struct Transactions { 41 | /// The JSON string or filename defining the transactions to push 42 | pub transactions: String, 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # EOSIO SDK for Rust 4 | 5 | ![Travis (.org)](https://img.shields.io/travis/sagan-software/eosio-rust.svg) ![Crates.io](https://img.shields.io/crates/l/eosio.svg) ![Crates.io](https://img.shields.io/crates/v/eosio.svg) 6 | 7 | _EOSIO SDK for Rust_ is a suite of APIs for building smart contracts and full-stack applications on EOSIO-based blockchains using the Rust programming language. 8 | 9 | ## [Read the Book](https://sagan-software.github.io/eosio-rust/) 10 | 11 | ## [Documentation](https://sagan-software.github.io/eosio-rust/eosio/) 12 | 13 | ## [Benchmarks](https://sagan-software.github.io/eosio-rust/benchmarks/report/) 14 | 15 | ## [Roadmap](https://sagan-software.github.io/eosio-rust/roadmap.html) 16 | 17 | ## License 18 | 19 | Licensed under either of these: 20 | 21 | - Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or 22 | https://www.apache.org/licenses/LICENSE-2.0) 23 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or 24 | https://opensource.org/licenses/MIT) 25 | 26 | ## Contributing 27 | 28 | Unless you explicitly state otherwise, any contribution you intentionally submit 29 | for inclusion in the work, as defined in the Apache-2.0 license, shall be 30 | dual-licensed as above, without any additional terms or conditions. 31 | 32 | [guide]: https://sagan-software.github.io/eosio-rust/ 33 | [telegram]: https://t.me/rust_eos 34 | [website]: https://sagan-software.github.io/eosio-rust/ 35 | [docs]: https://sagan-software.github.io/eosio-rust/docs/ 36 | -------------------------------------------------------------------------------- /crates/eosio/src/binary_extension.rs: -------------------------------------------------------------------------------- 1 | use crate::{NumBytes, Read, ReadError, Write, WriteError}; 2 | 3 | #[derive(Clone, Default, Debug)] 4 | pub struct BinaryExtension(Option); 5 | 6 | impl NumBytes for BinaryExtension 7 | where 8 | T: NumBytes, 9 | { 10 | fn num_bytes(&self) -> usize { 11 | self.0.as_ref().map(|t| t.num_bytes()).unwrap_or_default() 12 | } 13 | } 14 | 15 | impl Read for BinaryExtension 16 | where 17 | T: Read, 18 | { 19 | #[inline] 20 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 21 | if bytes.len() - *pos > 0 { 22 | T::read(bytes, pos).map(|t| Self(Some(t))) 23 | } else { 24 | Ok(Self(None)) 25 | } 26 | } 27 | } 28 | 29 | impl Write for BinaryExtension 30 | where 31 | T: Write, 32 | { 33 | #[inline] 34 | fn write( 35 | &self, 36 | bytes: &mut [u8], 37 | pos: &mut usize, 38 | ) -> Result<(), WriteError> { 39 | match &self.0 { 40 | Some(t) => t.write(bytes, pos), 41 | None => Ok(()), 42 | } 43 | } 44 | } 45 | 46 | impl BinaryExtension { 47 | #[inline] 48 | pub const fn new(t: Option) -> Self { 49 | Self(t) 50 | } 51 | 52 | #[inline] 53 | pub fn as_value(&self) -> Option<&T> { 54 | self.0.as_ref() 55 | } 56 | 57 | #[allow(clippy::missing_const_for_fn)] 58 | #[inline] 59 | pub fn into_value(self) -> Option { 60 | self.0 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /crates/eosio/src/bytes/collections.rs: -------------------------------------------------------------------------------- 1 | use crate::{NumBytes, Read, ReadError, Write, WriteError}; 2 | use alloc::collections::VecDeque; 3 | 4 | impl NumBytes for VecDeque 5 | where 6 | T: NumBytes, 7 | { 8 | #[inline] 9 | #[must_use] 10 | fn num_bytes(&self) -> usize { 11 | let mut count = self.len().num_bytes(); 12 | for item in self.iter() { 13 | count += item.num_bytes(); 14 | } 15 | count 16 | } 17 | } 18 | 19 | impl Read for VecDeque 20 | where 21 | T: Read + Default + Clone, 22 | { 23 | #[inline] 24 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 25 | let capacity = usize::read(bytes, pos)?; 26 | 27 | let mut results = Self::new(); 28 | results.resize(capacity, T::default()); 29 | 30 | for item in &mut results { 31 | let r = T::read(bytes, pos)?; 32 | *item = r; 33 | } 34 | 35 | Ok(results) 36 | } 37 | } 38 | 39 | impl Write for VecDeque 40 | where 41 | T: Write, 42 | { 43 | #[inline] 44 | fn write( 45 | &self, 46 | bytes: &mut [u8], 47 | pos: &mut usize, 48 | ) -> Result<(), WriteError> { 49 | self.len().write(bytes, pos)?; 50 | for item in self.iter() { 51 | item.write(bytes, pos)?; 52 | } 53 | Ok(()) 54 | } 55 | } 56 | 57 | // TODO BinaryHeap 58 | // TODO BTreeMap 59 | // TODO BTreeSet 60 | // TODO HashMap 61 | // TODO HashSet 62 | // TODO LinkedList 63 | -------------------------------------------------------------------------------- /book/install/eos.md: -------------------------------------------------------------------------------- 1 | # Install EOS 2 | 3 | To test and deploy smart contracts you will want to have a local EOS node running. The easiest way to setup a node is with Docker. See the [official Docker quickstart guide](https://developers.eos.io/eosio-nodeos/docs/docker-quickstart) for instructions. 4 | 5 | We recommend using `docker-compose` to manage `nodeos` and `keosd` containers. You can download the official [`docker-compose-latest.yml`](https://raw.githubusercontent.com/EOSIO/eos/master/Docker/docker-compose-latest.yml) file and start the containers using these commands: 6 | 7 | ```sh 8 | wget https://raw.githubusercontent.com/EOSIO/eos/master/Docker/docker-compose-latest.yml 9 | docker volume create --name=nodeos-data-volume 10 | docker volume create --name=keosd-data-volume 11 | docker-compose -f docker-compose-latest.yml up 12 | ``` 13 | 14 | **Note #1!** If you are using `cleos` within a Docker container, you need to mount your project directory as a volume so that `cleos` can deploy your files. If you're using Docker Compose, add your project directory to the `volumes` section of the `keosd` container like so (abbreviated): 15 | 16 | ```yaml 17 | services: 18 | keosd: 19 | volumes: 20 | - ./:mnt/dev/project:ro 21 | ``` 22 | 23 | **Note #2!** If you are expecting to see console output from `nodeos` then be sure to add `--contracts-console` to the end of the `nodeosd` command like so (abbreviated): 24 | 25 | ```yaml 26 | services: 27 | nodeosd: 28 | command: /opt/eosio/bin/nodeosd.sh ... --contracts-console 29 | ``` 30 | -------------------------------------------------------------------------------- /crates/eosio/src/bytes/num.rs: -------------------------------------------------------------------------------- 1 | use super::{NumBytes, Read, ReadError, Write, WriteError}; 2 | use core::num::{ 3 | NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize, NonZeroU16, NonZeroU32, 4 | NonZeroU64, NonZeroU8, NonZeroUsize, 5 | }; 6 | 7 | macro_rules! impl_non_zero_nums { 8 | ($($t:ty, $non_zero:ty)*) => ($( 9 | impl NumBytes for $non_zero { 10 | #[inline] 11 | #[must_use] 12 | fn num_bytes(&self) -> usize { 13 | self.get().num_bytes() 14 | } 15 | } 16 | 17 | impl Read for $non_zero { 18 | #[inline] 19 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 20 | let n = <$t as Read>::read(bytes, pos)?; 21 | // TODO don't panic 22 | let num = Self::new(n).expect("got zero for non-zero number"); 23 | Ok(num) 24 | } 25 | } 26 | 27 | impl Write for $non_zero { 28 | #[inline] 29 | fn write( 30 | &self, 31 | bytes: &mut [u8], 32 | pos: &mut usize, 33 | ) -> Result<(), WriteError> { 34 | self.get().write(bytes, pos) 35 | } 36 | } 37 | )*) 38 | } 39 | 40 | impl_non_zero_nums! { 41 | i16, NonZeroI16 42 | i32, NonZeroI32 43 | i64, NonZeroI64 44 | isize, NonZeroIsize 45 | u16, NonZeroU16 46 | u32, NonZeroU32 47 | u64, NonZeroU64 48 | u8, NonZeroU8 49 | usize, NonZeroUsize 50 | } // TODO i8 u128 i128 51 | -------------------------------------------------------------------------------- /internal/scripts/src/docker_tests.rs: -------------------------------------------------------------------------------- 1 | use crate::{build_contracts::build_contract, opts::RunTestsCmd}; 2 | use std::{ 3 | io, 4 | process::{Command, ExitStatus}, 5 | }; 6 | use util::get_target_dir; 7 | 8 | const CONTRACTS: &[&str] = &["bios", "msig", "token", "wrap"]; 9 | 10 | fn eosio_contract_tests() -> io::Result { 11 | let target_dir = get_target_dir()?; 12 | let mut cmd = Command::new("docker"); 13 | cmd.arg("run").arg("--rm"); 14 | 15 | for name in CONTRACTS { 16 | let crate_name = format!("eosio_{}", name); 17 | let contract_name = format!("eosio.{}", name); 18 | build_contract(&crate_name); 19 | let volume = { 20 | let name = format!("{}_gc.wasm", crate_name); 21 | let path = target_dir.join(name); 22 | format!( 23 | "{}:/eosio.contracts/build/contracts/{}/{}.wasm:ro", 24 | path.to_string_lossy(), 25 | contract_name, 26 | contract_name 27 | ) 28 | }; 29 | cmd.arg("--volume").arg(volume); 30 | } 31 | 32 | cmd.arg("--entrypoint") 33 | .arg("/eosio.contracts/build/tests/unit_test") 34 | .arg("sagansoftware/eosio.contracts:1.9.0") 35 | .arg("--show_progress=yes"); 36 | 37 | for name in CONTRACTS { 38 | cmd.arg(format!("--run_test=eosio_{}_tests", name)); 39 | } 40 | 41 | // cmd.arg("--run_test=eosio_system_tests"); 42 | 43 | cmd.status() 44 | } 45 | 46 | pub fn run_test(_opts: RunTestsCmd) { 47 | eosio_contract_tests().unwrap(); 48 | } 49 | -------------------------------------------------------------------------------- /crates/eosio_macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Macros for creating compile-time EOSIO names and symbols. 2 | //! 3 | //! Creating EOSIO names: 4 | //! 5 | //! ``` 6 | //! use eosio_macros::n; 7 | //! assert_eq!(n!("test"), 14_605_613_396_213_628_928); 8 | //! assert_eq!(n!("1234"), 614_248_767_926_829_056); 9 | //! assert_eq!(n!("123451234512"), 614_251_535_012_020_768); 10 | //! assert_eq!(n!("eosio.token"), 6_138_663_591_592_764_928); 11 | //! ``` 12 | //! 13 | //! Creating EOSIO symbols: 14 | //! 15 | //! ``` 16 | //! use eosio_macros::s; 17 | //! assert_eq!(s!(4, "EOS"), 1397703940); 18 | //! ``` 19 | #![no_std] 20 | #![allow(clippy::missing_docs_in_private_items)] 21 | 22 | use proc_macro_hack::proc_macro_hack; 23 | 24 | /// Macro for converting EOSIO names into `u64` representations at compile 25 | /// time. 26 | /// 27 | /// # Examples 28 | /// 29 | /// ``` 30 | /// use eosio_macros::n; 31 | /// assert_eq!(n!("test"), 14_605_613_396_213_628_928); 32 | /// assert_eq!(n!("1234"), 614_248_767_926_829_056); 33 | /// assert_eq!(n!("123451234512"), 614_251_535_012_020_768); 34 | /// assert_eq!(n!("eosio.token"), 6_138_663_591_592_764_928); 35 | /// ``` 36 | #[proc_macro_hack] 37 | pub use eosio_macros_internal::n; 38 | 39 | /// Macro for converting EOSIO symbols into `u64` representations at 40 | /// compile time. 41 | /// 42 | /// # Examples 43 | /// 44 | /// ``` 45 | /// use eosio_macros::s; 46 | /// assert_eq!(s!(4, "EOS"), 1397703940); 47 | /// ``` 48 | #[proc_macro_hack] 49 | pub use eosio_macros_internal::s; 50 | 51 | pub use eosio_macros_internal::{ 52 | abi, action, table, NumBytes, Read, Table, Write, 53 | }; 54 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/create.rs: -------------------------------------------------------------------------------- 1 | use eosio::AccountName; 2 | use structopt::StructOpt; 3 | 4 | /// Create various items, on and off the blockchain 5 | #[derive(StructOpt, Debug)] 6 | pub enum Create { 7 | /// Create a new keypair and print the public and private keys 8 | Key(CreateKey), 9 | /// Create a new account on the blockchain (assumes system contract does 10 | /// not restrict RAM usage) 11 | Account(CreateAccount), 12 | } 13 | 14 | /// Create a new keypair and print the public and private keys 15 | #[derive(StructOpt, Debug)] 16 | pub struct CreateKey { 17 | /// Generate a key using the R1 curve (iPhone), instead of the K1 curve 18 | /// (Bitcoin) 19 | #[structopt(long)] 20 | pub r1: bool, 21 | /// Name of file to write private/public key output to. (Must be set, 22 | /// unless "--to-console" is passed) 23 | #[structopt(short, long, required_unless = "to-console")] 24 | pub file: Option, 25 | /// Print private/public keys to console. 26 | #[structopt(long)] 27 | pub to_console: bool, 28 | } 29 | 30 | /// Create a new account on the blockchain (assumes system contract does not 31 | /// restrict RAM usage) 32 | #[derive(StructOpt, Debug)] 33 | pub struct CreateAccount { 34 | /// The name of the account creating the new account 35 | pub creator: AccountName, 36 | /// The name of the new account 37 | pub name: AccountName, 38 | /// The owner public key for the new account 39 | pub owner_key: String, 40 | /// The active public key for the new account 41 | pub active_key: Option, 42 | #[structopt(flatten)] 43 | pub transaction_opts: super::TransactionOpts, 44 | } 45 | -------------------------------------------------------------------------------- /crates/eosio/src/abi.rs: -------------------------------------------------------------------------------- 1 | use alloc::{string::String, vec::Vec}; 2 | 3 | #[derive(Debug, PartialEq)] 4 | pub struct Abi { 5 | pub version: String, 6 | pub types: Vec, 7 | pub structs: Vec, 8 | pub actions: Vec, 9 | pub tables: Vec, 10 | pub ricardian_clauses: Vec, 11 | pub error_messages: Vec, 12 | pub abi_extensions: Vec, 13 | // TODO variants: Vec, 14 | } 15 | 16 | #[derive(Debug, PartialEq)] 17 | pub struct AbiType { 18 | pub new_type_name: String, 19 | pub type_: String, 20 | } 21 | 22 | #[derive(Debug, PartialEq)] 23 | pub struct AbiStruct { 24 | pub name: String, 25 | pub base: String, 26 | pub fields: Vec, 27 | } 28 | 29 | #[derive(Debug, PartialEq)] 30 | pub struct AbiField { 31 | pub name: String, 32 | pub type_: String, 33 | } 34 | 35 | #[derive(Debug, PartialEq)] 36 | pub struct AbiAction { 37 | pub name: String, 38 | pub type_: String, 39 | pub ricardian_contract: String, 40 | } 41 | 42 | #[derive(Debug, PartialEq)] 43 | pub struct AbiTable { 44 | pub name: String, 45 | pub index_type: String, 46 | pub key_names: Vec, 47 | pub key_types: Vec, 48 | pub type_: String, 49 | } 50 | 51 | #[derive(Debug, PartialEq)] 52 | pub struct AbiRicardianClause { 53 | pub id: String, 54 | pub body: String, 55 | } 56 | 57 | #[derive(Debug, PartialEq)] 58 | pub struct AbiErrorMessage { 59 | pub error_code: u64, 60 | pub error_msg: String, 61 | } 62 | 63 | #[derive(Debug, PartialEq)] 64 | pub struct AbiExtension { 65 | pub type_: u16, 66 | pub data: String, 67 | } 68 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/check.rs: -------------------------------------------------------------------------------- 1 | /// Aborts processing of this action and unwinds all pending changes if the test 2 | /// condition is true 3 | #[inline] 4 | pub fn check(pred: bool, msg: &str) { 5 | if !pred { 6 | let msg_ptr = msg.as_ptr(); 7 | #[allow(clippy::cast_possible_truncation)] 8 | let msg_len = msg.len() as u32; 9 | unsafe { eosio_cdt_sys::eosio_assert_message(0, msg_ptr, msg_len) } 10 | } 11 | } 12 | 13 | /// Aborts processing of this action and unwinds all pending changes if the test 14 | /// condition is true 15 | #[inline] 16 | pub fn check_code(pred: bool, code: C) 17 | where 18 | C: Into, 19 | { 20 | if !pred { 21 | unsafe { eosio_cdt_sys::eosio_assert_code(0, code.into()) } 22 | } 23 | } 24 | 25 | pub trait Check { 26 | type Output; 27 | fn check(self, msg: &str) -> Self::Output; 28 | } 29 | 30 | impl Check for Result { 31 | type Output = T; 32 | 33 | #[inline] 34 | fn check(self, msg: &str) -> Self::Output { 35 | if let Ok(t) = self { 36 | t 37 | } else { 38 | check(false, msg); 39 | unreachable!(); 40 | } 41 | } 42 | } 43 | 44 | impl Check for Option { 45 | type Output = T; 46 | 47 | #[inline] 48 | fn check(self, msg: &str) -> Self::Output { 49 | if let Some(t) = self { 50 | t 51 | } else { 52 | check(false, msg); 53 | unreachable!(); 54 | } 55 | } 56 | } 57 | 58 | impl Check for bool { 59 | type Output = Self; 60 | 61 | #[inline] 62 | fn check(self, msg: &str) -> Self::Output { 63 | check(self, msg); 64 | self 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /internal/bench/src/scenario.rs: -------------------------------------------------------------------------------- 1 | use serde_json::Value; 2 | 3 | pub trait Scenario { 4 | const DESC: &'static str; 5 | const ABI: &'static str; 6 | fn new() -> Self; 7 | fn wasm(&self) -> Vec; 8 | fn actions(&mut self, contract: &str) -> Vec; 9 | } 10 | 11 | #[derive(Debug)] 12 | pub struct Wasm { 13 | pub desc: String, 14 | pub lang: String, 15 | pub path: String, 16 | } 17 | 18 | #[derive(Debug)] 19 | pub struct Action { 20 | pub name: String, 21 | pub data: Value, 22 | pub scope: String, 23 | } 24 | 25 | #[derive(Debug)] 26 | pub struct Run { 27 | pub action: String, 28 | pub bytes: u64, 29 | pub time: u64, 30 | } 31 | 32 | pub struct WasmBenchResults { 33 | pub wasm: Wasm, 34 | pub ram: u64, 35 | pub runs: Vec, 36 | } 37 | 38 | impl Action { 39 | pub fn new( 40 | name: impl ToString, 41 | data: impl Into, 42 | scope: impl ToString, 43 | ) -> Self { 44 | Self { 45 | name: name.to_string(), 46 | data: data.into(), 47 | scope: scope.to_string(), 48 | } 49 | } 50 | 51 | pub fn run(&self, contract: impl AsRef) -> Run { 52 | let contract = contract.as_ref(); 53 | let data = serde_json::to_string(&self.data).unwrap(); 54 | println!( 55 | "push action {} {} {} -p {}", 56 | contract, self.name, data, self.scope 57 | ); 58 | let metrics = 59 | util::push_action_metrics(contract, &self.name, data, &self.scope); 60 | Run { 61 | action: self.name.clone(), 62 | bytes: metrics.bytes, 63 | time: metrics.time, 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! TODO docs 2 | #![no_std] 3 | #![recursion_limit = "128"] 4 | #![deny( 5 | clippy::correctness, 6 | clippy::indexing_slicing, 7 | clippy::option_unwrap_used, 8 | clippy::result_unwrap_used, 9 | clippy::unimplemented, 10 | clippy::wrong_pub_self_convention, 11 | clippy::wrong_self_convention 12 | )] 13 | #![warn( 14 | clippy::complexity, 15 | clippy::pedantic, 16 | clippy::nursery, 17 | clippy::style, 18 | clippy::perf, 19 | clippy::dbg_macro, 20 | clippy::else_if_without_else, 21 | clippy::float_cmp_const, 22 | clippy::mem_forget, 23 | clippy::missing_inline_in_public_items, 24 | clippy::use_debug 25 | )] 26 | #![allow(clippy::module_name_repetitions)] 27 | 28 | #[macro_use] 29 | extern crate alloc; 30 | 31 | mod account; 32 | pub use self::account::*; 33 | 34 | mod action; 35 | pub use self::action::*; 36 | 37 | mod check; 38 | pub use self::check::*; 39 | 40 | mod crypto; 41 | pub use self::crypto::*; 42 | 43 | mod permissions; 44 | pub use self::permissions::*; 45 | 46 | #[macro_use] 47 | mod print; 48 | pub use self::print::*; 49 | 50 | mod privileged; 51 | pub use self::privileged::*; 52 | 53 | mod singleton_index; 54 | pub use self::singleton_index::*; 55 | 56 | mod table; 57 | pub use self::table::*; 58 | 59 | mod table_primary; 60 | pub use self::table_primary::*; 61 | 62 | mod table_secondary; 63 | pub use self::table_secondary::*; 64 | 65 | mod time; 66 | pub use self::time::*; 67 | 68 | pub use eosio_cdt_sys as sys; 69 | 70 | // pub use self::{ 71 | // account::*, action::*, check::*, crypto::*, permissions::*, print::*, 72 | // privileged::*, singleton_index::*, table::*, table_primary::*, 73 | // table_secondary::*, time::*, 74 | // }; 75 | -------------------------------------------------------------------------------- /crates/eosio/src/table/mod.rs: -------------------------------------------------------------------------------- 1 | mod primary_table_index; 2 | mod secondary_key; 3 | mod secondary_keys; 4 | mod secondary_table_index; 5 | mod secondary_table_name; 6 | 7 | pub use self::{ 8 | primary_table_index::PrimaryTableIndex, secondary_key::SecondaryKey, 9 | secondary_keys::SecondaryKeys, secondary_table_index::SecondaryTableIndex, 10 | secondary_table_name::SecondaryTableName, 11 | }; 12 | pub use eosio_macros::Table; 13 | 14 | use crate::{ 15 | account::AccountName, 16 | bytes::{NumBytes, Read, Write}, 17 | name_type, 18 | symbol::{Symbol, SymbolCode}, 19 | }; 20 | 21 | name_type!(TableName); 22 | name_type!(ScopeName); 23 | 24 | impl From for ScopeName { 25 | #[must_use] 26 | fn from(value: AccountName) -> Self { 27 | Self::new(value.as_u64()) 28 | } 29 | } 30 | 31 | impl From for ScopeName { 32 | #[must_use] 33 | fn from(value: Symbol) -> Self { 34 | Self::new(value.as_u64()) 35 | } 36 | } 37 | 38 | impl From for ScopeName { 39 | #[must_use] 40 | fn from(value: SymbolCode) -> Self { 41 | Self::new(value.as_u64()) 42 | } 43 | } 44 | 45 | /// TODO docs 46 | pub trait Table: Sized { 47 | /// TODO docs 48 | const NAME: TableName; 49 | /// TODO docs 50 | type Row: Read + Write + NumBytes; 51 | /// TODO docs 52 | fn primary_key(row: &Self::Row) -> u64; 53 | /// TODO docs 54 | fn secondary_keys(_row: &Self::Row) -> SecondaryKeys { 55 | SecondaryKeys::default() 56 | } 57 | /// TODO docs 58 | #[inline] 59 | fn table(code: C, scope: S) -> PrimaryTableIndex 60 | where 61 | C: Into, 62 | S: Into, 63 | { 64 | PrimaryTableIndex::new(code, scope) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/eosio_system/src/lib.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use lazy_static::lazy_static; 3 | 4 | pub const ACTIVE_PERMISSION: PermissionName = PermissionName::new(n!("active")); 5 | pub const TOKEN_ACCOUNT: AccountName = AccountName::new(n!("eosio.token")); 6 | pub const RAM_ACCOUNT: AccountName = AccountName::new(n!("eosio.ram")); 7 | pub const RAMFEE_ACCOUNT: AccountName = AccountName::new(n!("eosio.ramfee")); 8 | pub const STAKE_ACCOUNT: AccountName = AccountName::new(n!("eosio.stake")); 9 | pub const BPAY_ACCOUNT: AccountName = AccountName::new(n!("eosio.bpay")); 10 | pub const VPAY_ACCOUNT: AccountName = AccountName::new(n!("eosio.vpay")); 11 | pub const NAMES_ACCOUNT: AccountName = AccountName::new(n!("eosio.names")); 12 | pub const SAVING_ACCOUNT: AccountName = AccountName::new(n!("eosio.saving")); 13 | pub const REX_ACCOUNT: AccountName = AccountName::new(n!("eosio.rex")); 14 | pub const NULL_ACCOUNT: AccountName = AccountName::new(n!("eosio.null")); 15 | pub const REX_SYMBOL: Symbol = Symbol::new(s!(4, "REX")); 16 | 17 | lazy_static! { 18 | pub static ref SELF: AccountName = eosio_cdt::current_receiver(); 19 | } 20 | 21 | mod core; 22 | pub use self::core::*; 23 | 24 | mod delegate_bandwidth; 25 | pub use self::delegate_bandwidth::*; 26 | 27 | mod exchange_state; 28 | pub use self::exchange_state::*; 29 | 30 | mod name_bidding; 31 | pub use self::name_bidding::*; 32 | 33 | mod native; 34 | pub use self::native::*; 35 | 36 | mod producer_pay; 37 | pub use self::producer_pay::*; 38 | 39 | mod rex; 40 | pub use self::rex::*; 41 | 42 | mod voting; 43 | pub use self::voting::*; 44 | 45 | eosio::abi!( 46 | setram, 47 | setramrate, 48 | setparams, 49 | setpriv, 50 | setalimits, 51 | setacctram, 52 | setacctnet, 53 | activate, 54 | rmvproducer, 55 | updtrevision, 56 | setinflation, 57 | init 58 | ); 59 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/permissions.rs: -------------------------------------------------------------------------------- 1 | use eosio::{PermissionLevel, PublicKey, Transaction, Write, WriteError}; 2 | 3 | /// Checks if a transaction is authorized by a provided set of keys and 4 | /// permissions 5 | /// 6 | /// # Errors 7 | /// 8 | /// Returns `Err` if there as a problem serializing the public keys or 9 | /// permission levels. 10 | #[inline] 11 | pub fn has_transaction_authority( 12 | trx: T, 13 | public_keys: K, 14 | permission_levels: L, 15 | ) -> Result 16 | where 17 | T: AsRef, 18 | K: AsRef<[PublicKey]>, 19 | L: AsRef<[PermissionLevel]>, 20 | { 21 | let trx = trx.as_ref().pack()?; 22 | has_transaction_authority_bytes(trx, public_keys, permission_levels) 23 | } 24 | 25 | /// Checks if a transaction is authorized by a provided set of keys and 26 | /// permissions 27 | /// 28 | /// # Errors 29 | /// 30 | /// Returns `Err` if there as a problem serializing the public keys or 31 | /// permission levels. 32 | #[inline] 33 | #[allow(clippy::cast_possible_truncation)] 34 | pub fn has_transaction_authority_bytes( 35 | trx: T, 36 | public_keys: K, 37 | permission_levels: L, 38 | ) -> Result 39 | where 40 | T: AsRef<[u8]>, 41 | K: AsRef<[PublicKey]>, 42 | L: AsRef<[PermissionLevel]>, 43 | { 44 | let trx = trx.as_ref(); 45 | let public_keys = public_keys.as_ref().pack()?; 46 | let permission_levels = permission_levels.as_ref().pack()?; 47 | let result = unsafe { 48 | eosio_cdt_sys::check_transaction_authorization( 49 | trx.as_ptr(), 50 | trx.len() as u32, 51 | public_keys.as_ptr(), 52 | public_keys.len() as u32, 53 | permission_levels.as_ptr(), 54 | permission_levels.len() as u32, 55 | ) 56 | }; 57 | Ok(result == 1) 58 | } 59 | -------------------------------------------------------------------------------- /crates/eosio_numstr/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides functions for converting EOSIO names and 2 | //! symbols to and from string representations. 3 | //! 4 | //! Creating an EOSIO name: 5 | //! 6 | //! ``` 7 | //! use eosio_numstr::name_from_bytes; 8 | //! let name = name_from_bytes("eosio".bytes()).unwrap(); 9 | //! assert_eq!(name, 6138663577826885632); 10 | //! ``` 11 | //! 12 | //! Creating an EOSIO symbol: 13 | //! 14 | //! ``` 15 | //! use eosio_numstr::symbol_from_bytes; 16 | //! let symbol = symbol_from_bytes(4, "EOS".bytes()).unwrap(); 17 | //! assert_eq!(symbol, 1397703940); 18 | //! ``` 19 | #![no_std] 20 | #![deny( 21 | clippy::correctness, 22 | clippy::indexing_slicing, 23 | clippy::option_unwrap_used, 24 | clippy::result_unwrap_used, 25 | clippy::unimplemented, 26 | clippy::wrong_pub_self_convention, 27 | clippy::wrong_self_convention 28 | )] 29 | #![warn( 30 | clippy::complexity, 31 | clippy::pedantic, 32 | clippy::nursery, 33 | clippy::style, 34 | clippy::perf, 35 | clippy::dbg_macro, 36 | clippy::else_if_without_else, 37 | clippy::float_cmp_const, 38 | clippy::mem_forget, 39 | clippy::use_debug 40 | )] 41 | #![allow(clippy::module_name_repetitions)] 42 | #![cfg_attr( 43 | test, 44 | allow(clippy::option_unwrap_used, clippy::result_unwrap_used) 45 | )] 46 | 47 | #[cfg(test)] 48 | #[macro_use] 49 | extern crate std; 50 | 51 | mod name; 52 | mod symbol; 53 | mod symbol_code; 54 | 55 | pub use name::{ 56 | name_from_bytes, name_to_bytes, ParseNameError, NAME_CHARS, NAME_MAX_LEN, 57 | }; 58 | pub use symbol::{ 59 | symbol_from_bytes, symbol_from_code, symbol_to_code, symbol_to_precision, 60 | ParseSymbolError, 61 | }; 62 | pub use symbol_code::{ 63 | symbol_code_from_bytes, symbol_code_to_bytes, ParseSymbolCodeError, 64 | SYMBOL_CODE_CHARS, SYMBOL_CODE_MAX_LEN, 65 | }; 66 | -------------------------------------------------------------------------------- /crates/eosio/src/bytes/alloc.rs: -------------------------------------------------------------------------------- 1 | use super::{NumBytes, Read, ReadError, Write, WriteError}; 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | impl NumBytes for String { 5 | #[inline] 6 | #[must_use] 7 | fn num_bytes(&self) -> usize { 8 | self.as_str().num_bytes() 9 | } 10 | } 11 | 12 | impl Read for String { 13 | #[inline] 14 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 15 | // TODO: may need to read this as a cstr 16 | let utf8 = Vec::::read(bytes, pos)?; 17 | let s = Self::from_utf8_lossy(&utf8); 18 | Ok(s.into_owned()) 19 | } 20 | } 21 | 22 | impl Write for String { 23 | #[inline] 24 | fn write( 25 | &self, 26 | bytes: &mut [u8], 27 | pos: &mut usize, 28 | ) -> Result<(), WriteError> { 29 | self.as_bytes().write(bytes, pos) 30 | } 31 | } 32 | 33 | impl NumBytes for Vec 34 | where 35 | T: NumBytes, 36 | { 37 | #[inline] 38 | #[must_use] 39 | fn num_bytes(&self) -> usize { 40 | self.as_slice().num_bytes() 41 | } 42 | } 43 | 44 | impl Read for Vec 45 | where 46 | T: Read + Default + Clone, 47 | { 48 | #[inline] 49 | fn read(bytes: &[u8], pos: &mut usize) -> Result { 50 | let capacity = usize::read(bytes, pos)?; 51 | 52 | let mut results = Self::new(); 53 | results.resize(capacity, T::default()); 54 | 55 | for item in &mut results { 56 | let r = T::read(bytes, pos)?; 57 | *item = r; 58 | } 59 | 60 | Ok(results) 61 | } 62 | } 63 | 64 | impl Write for Vec 65 | where 66 | T: Write, 67 | { 68 | #[inline] 69 | fn write( 70 | &self, 71 | bytes: &mut [u8], 72 | pos: &mut usize, 73 | ) -> Result<(), WriteError> { 74 | self.as_slice().write(bytes, pos) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /contracts/eosio_system/src/name_bidding.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use eosio_cdt::*; 3 | use std::{collections::VecDeque, marker::PhantomData}; 4 | 5 | /// A name bid, which consists of: 6 | /// - a `newname` name that the bid is for 7 | /// - a `high_bidder` account name that is the one with the highest bid so far 8 | /// - the `high_bid` which is amount of highest bid 9 | /// - and `last_bid_time` which is the time of the highest bid 10 | /// 11 | /// [Reference implementation](https://github.com/EOSIO/eosio.contracts/blob/v1.9.0-rc3/contracts/eosio.system/include/eosio.system/eosio.system.hpp#L90-L103) 12 | pub struct NameBid { 13 | /// name that the bid is for 14 | pub newname: AccountName, 15 | /// account name that is the one with the highest bid so far 16 | pub high_bidder: AccountName, 17 | /// amount of highest bid. negative high_bid == closed auction waiting to 18 | /// be claimed 19 | pub high_bid: i64, 20 | /// time of the highest bid 21 | pub last_bid_time: TimePoint, 22 | } 23 | 24 | /// A bid refund, which is defined by: 25 | /// - the `bidder` account name owning the refund 26 | /// - the `amount` to be refunded 27 | /// [Reference implementation](https://github.com/EOSIO/eosio.contracts/blob/v1.9.0-rc3/contracts/eosio.system/include/eosio.system/eosio.system.hpp#L105-L113) 28 | pub struct BidRefund { 29 | /// account name owning the refund 30 | pub bidder: AccountName, 31 | /// to be refunded 32 | pub amount: Asset, 33 | } 34 | 35 | /// 36 | #[eosio::action] 37 | pub fn bidname(bidder: AccountName, newname: AccountName, bid: Asset) {} 38 | 39 | /// 40 | #[eosio::action] 41 | pub fn bidrefund(bidder: AccountName, newname: AccountName) {} 42 | -------------------------------------------------------------------------------- /crates/eosio_numstr/benches/benches.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate criterion; 3 | extern crate eosio_numstr; 4 | 5 | use criterion::{black_box, Criterion}; 6 | 7 | fn name_from_bytes(c: &mut Criterion) { 8 | c.bench_function_over_inputs( 9 | "name_from_bytes", 10 | |b, input| { 11 | b.iter(|| eosio_numstr::name_from_bytes(black_box(input.bytes()))) 12 | }, 13 | vec![ 14 | "", 15 | "aaaaaa", 16 | "111111", 17 | "......", 18 | "aaaaaaaaaaaa", 19 | "111111111111", 20 | "............", 21 | "AAAAAAAAAAAA", 22 | "666666666666", 23 | "aaaaaaaaaaaaa", 24 | ], 25 | ); 26 | } 27 | 28 | fn name_to_bytes(c: &mut Criterion) { 29 | c.bench_function_over_inputs( 30 | "name_to_bytes", 31 | |b, input| b.iter(|| eosio_numstr::name_to_bytes(black_box(*input))), 32 | vec![0, 3_458_764_513_820_540_928, 614_251_535_012_020_768], 33 | ); 34 | } 35 | 36 | fn symbol_code_from_bytes(c: &mut Criterion) { 37 | c.bench_function_over_inputs( 38 | "symbol_code_from_bytes", 39 | |b, input| { 40 | b.iter(|| { 41 | eosio_numstr::symbol_code_from_bytes(black_box(input.bytes())) 42 | }) 43 | }, 44 | vec!["", "A", "AB", "ABC", "a", "ab", "abc"], 45 | ); 46 | } 47 | 48 | fn symbol_code_to_bytes(c: &mut Criterion) { 49 | c.bench_function_over_inputs( 50 | "symbol_code_to_bytes", 51 | |b, input| { 52 | b.iter(|| eosio_numstr::symbol_code_to_bytes(black_box(*input))) 53 | }, 54 | vec![0, 1_397_703_940, 5_138_124_851_399_447_552], 55 | ); 56 | } 57 | 58 | criterion_group!( 59 | benches, 60 | name_from_bytes, 61 | name_to_bytes, 62 | symbol_code_from_bytes, 63 | symbol_code_to_bytes 64 | ); 65 | criterion_main!(benches); 66 | -------------------------------------------------------------------------------- /book/quick-start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | In this quick-start tutorial we will create a simple EOSIO smart contract in Rust that accepts an account name and prints a greeting message. 4 | 5 | Create a new Rust library: 6 | 7 | ```sh 8 | cargo new hello --lib 9 | ``` 10 | 11 | Edit `Cargo.toml`: 12 | 13 | ```toml 14 | {{#include ../examples/hello/Cargo.toml}} 15 | ``` 16 | 17 | Edit `src/lib.rs`: 18 | 19 | ```rust,no_run,noplaypen 20 | {{#include ../examples/hello/src/lib.rs}} 21 | ``` 22 | 23 | Compile with the following command: 24 | 25 | ```sh 26 | RUSTFLAGS="-C link-args=-zstack-size=48000" \ 27 | cargo build --release -target=wasm32-unknown-unknown 28 | ``` 29 | 30 | The smart contract should now be built at `target/wasm32-unknown-unknown/release/hello.wasm` 31 | 32 | ## Deploying 33 | 34 | 35 | Create a new file called `abi.json` (in future versions this will be automatically generated): 36 | 37 | ```json 38 | { 39 | "version": "eosio::abi/1.0", 40 | "structs": [ 41 | { 42 | "name": "hi", 43 | "base": "", 44 | "fields": [ 45 | { 46 | "name": "name", 47 | "type": "name" 48 | } 49 | ] 50 | } 51 | ], 52 | "actions": [ 53 | { 54 | "name": "hi", 55 | "type": "hi" 56 | } 57 | ] 58 | } 59 | ``` 60 | 61 | Assuming you have `cleos` setup and have created the `hello` account: 62 | 63 | ```sh 64 | cleos set abi hello abi.json 65 | cleos set code hello target/wasm32-unknown-unknown/release/hello.wasm 66 | ``` 67 | 68 | ## Say Hello 69 | 70 | Finally, say hello: 71 | 72 | ```sh 73 | cleos push action hello hi '["world"]' -p 'hello@active' 74 | ``` 75 | 76 | If all went well you should see `Hello, world` in the console. Otherwise, if the transaction was sent successfully but you don't see any output, you may need to use the `--contract-console` option with `nodeos`. -------------------------------------------------------------------------------- /crates/eosio/src/time/time_point_sec.rs: -------------------------------------------------------------------------------- 1 | use super::TimePoint; 2 | use crate::bytes::{NumBytes, Read, Write}; 3 | use core::ops::Add; 4 | 5 | /// A lower resolution `TimePoint` accurate only to seconds from 1970 6 | /// 7 | #[derive( 8 | Read, 9 | Write, 10 | NumBytes, 11 | PartialEq, 12 | Eq, 13 | PartialOrd, 14 | Ord, 15 | Debug, 16 | Clone, 17 | Copy, 18 | Hash, 19 | Default, 20 | )] 21 | #[eosio(crate_path = "crate::bytes")] 22 | pub struct TimePointSec(u32); 23 | 24 | impl TimePointSec { 25 | /// Create a new `TimePointSec` 26 | #[inline] 27 | #[must_use] 28 | pub const fn from_secs(secs: u32) -> Self { 29 | Self(secs) 30 | } 31 | 32 | /// Gets the seconds 33 | #[inline] 34 | #[must_use] 35 | pub const fn as_secs(self) -> u32 { 36 | self.0 37 | } 38 | } 39 | 40 | impl From for TimePointSec { 41 | #[inline] 42 | #[must_use] 43 | fn from(i: u32) -> Self { 44 | Self(i) 45 | } 46 | } 47 | 48 | impl From for u32 { 49 | #[inline] 50 | #[must_use] 51 | fn from(t: TimePointSec) -> Self { 52 | t.0 53 | } 54 | } 55 | 56 | impl From for TimePointSec { 57 | #[inline] 58 | #[must_use] 59 | #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] 60 | fn from(t: TimePoint) -> Self { 61 | Self((t.as_micros() as u32) / 1_000_000_u32) 62 | } 63 | } 64 | 65 | impl Add for TimePointSec { 66 | type Output = Self; 67 | 68 | #[must_use] 69 | fn add(self, rhs: u32) -> Self::Output { 70 | Self(self.0 + rhs) 71 | } 72 | } 73 | 74 | impl Add for u32 { 75 | type Output = TimePointSec; 76 | 77 | #[must_use] 78 | fn add(self, rhs: TimePointSec) -> Self::Output { 79 | TimePointSec(rhs.0 + self) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /internal/bench_cpp/src/contract.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace eosio; 7 | using std::string; 8 | using std::vector; 9 | 10 | #define TYPE_ACTIONS(SUFFIX, TYPE) \ 11 | TABLE t##SUFFIX \ 12 | { \ 13 | uint64_t pk; \ 14 | TYPE data; \ 15 | uint64_t primary_key() const { return pk; } \ 16 | }; \ 17 | ACTION read##SUFFIX(TYPE data) {} \ 18 | ACTION write##SUFFIX(uint64_t pk, TYPE data) \ 19 | { \ 20 | } \ 21 | ACTION chg##SUFFIX(uint64_t pk, TYPE data) \ 22 | { \ 23 | } \ 24 | ACTION del##SUFFIX(uint64_t pk) \ 25 | { \ 26 | } 27 | 28 | CONTRACT bench : public contract 29 | { 30 | public: 31 | using contract::contract; 32 | 33 | ACTION noop(ignore data) {} 34 | 35 | TYPE_ACTIONS(u1, uint8_t) 36 | TYPE_ACTIONS(u2, uint16_t) 37 | TYPE_ACTIONS(u3, uint32_t) 38 | TYPE_ACTIONS(u4, uint64_t) 39 | TYPE_ACTIONS(u5, uint128_t) 40 | TYPE_ACTIONS(i1, int8_t) 41 | TYPE_ACTIONS(i2, int16_t) 42 | TYPE_ACTIONS(i3, int32_t) 43 | TYPE_ACTIONS(i4, int64_t) 44 | TYPE_ACTIONS(i5, int128_t) 45 | TYPE_ACTIONS(string, string) 46 | TYPE_ACTIONS(name, name) 47 | TYPE_ACTIONS(asset, asset) 48 | TYPE_ACTIONS(easset, extended_asset) 49 | TYPE_ACTIONS(symbol, symbol) 50 | TYPE_ACTIONS(esymbl, extended_symbol) 51 | TYPE_ACTIONS(c1, checksum160) 52 | TYPE_ACTIONS(c2, checksum256) 53 | TYPE_ACTIONS(c3, checksum512) 54 | }; -------------------------------------------------------------------------------- /crates/eosio_rpc/src/clients/server.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use crate::Client; 3 | use futures::compat::Future01CompatExt; 4 | use futures::future::FutureExt; 5 | use hyper::rt::{Future, Stream}; 6 | use hyper_tls::HttpsConnector; 7 | use serde::{Deserialize, Serialize}; 8 | use std::pin::Pin; 9 | 10 | pub struct HyperClient { 11 | node: String, 12 | } 13 | 14 | impl HyperClient { 15 | pub fn new(node: &str) -> Self { 16 | Self { 17 | node: node.to_owned(), 18 | } 19 | } 20 | } 21 | 22 | impl Client for HyperClient { 23 | fn node(&self) -> &str { 24 | &self.node 25 | } 26 | 27 | fn fetch( 28 | &self, 29 | path: &str, 30 | params: Params, 31 | ) -> Pin> + Send>> 32 | where 33 | Output: 'static + for<'b> Deserialize<'b> + Send, 34 | Params: Serialize, 35 | { 36 | let https = HttpsConnector::new(4).unwrap(); 37 | let client = hyper::Client::builder().build::<_, hyper::Body>(https); 38 | 39 | let mut url = self.node.to_owned(); 40 | url.push_str(path); 41 | 42 | let uri: hyper::Uri = url.parse().unwrap(); 43 | 44 | let json = serde_json::to_string(¶ms).unwrap(); 45 | let mut req = hyper::Request::new(hyper::Body::from(json)); 46 | *req.method_mut() = hyper::Method::POST; 47 | *req.uri_mut() = uri; 48 | req.headers_mut().insert( 49 | hyper::header::CONTENT_TYPE, 50 | hyper::header::HeaderValue::from_static("application/json"), 51 | ); 52 | 53 | client 54 | .request(req) 55 | .and_then(|res| res.into_body().concat2()) 56 | .from_err::() 57 | .and_then(|body| { 58 | let s = std::str::from_utf8(&body).unwrap(); 59 | println!("!!!!!!!!!!!!!!!!!!! {}", s); 60 | let res = serde_json::from_slice(&body)?; 61 | Ok(res) 62 | }) 63 | .from_err() 64 | .compat() 65 | .boxed() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /internal/scripts/src/build_docs.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs, io, os, 3 | path::{Path, PathBuf}, 4 | process::Command, 5 | }; 6 | use util::{get_project_dir, RunOr}; 7 | 8 | fn build_readme(crate_root: &Path) -> io::Result<()> { 9 | let output = crate_root.join("README.md"); 10 | println!("building README.md for {:?} ({:?})", crate_root, output); 11 | Command::new("cargo") 12 | .arg("readme") 13 | .arg("--project-root") 14 | .arg(crate_root) 15 | .arg("--output") 16 | .arg(output) 17 | .run_or_panic(); 18 | Ok(()) 19 | } 20 | 21 | fn symlink_licenses(crate_root: &Path) -> io::Result<()> { 22 | for license in &["LICENSE-APACHE", "LICENSE-MIT"] { 23 | let src = Path::new("..").join("..").join(license); 24 | let dst = crate_root.join(license); 25 | println!("Creating symlink: src={:?}, dst={:?}", src, dst); 26 | if dst.exists() { 27 | fs::remove_file(&dst)?; 28 | } 29 | #[cfg(target_os = "linux")] 30 | { 31 | os::unix::fs::symlink(src, dst)?; 32 | } 33 | #[cfg(target_os = "windows")] 34 | { 35 | os::windows::fs::symlink_file(src, dst)?; 36 | } 37 | } 38 | Ok(()) 39 | } 40 | 41 | fn build_docs_for_dir(dir: PathBuf) { 42 | println!("Building docs for all crates in dir: {:?}", dir); 43 | for dir_entry in fs::read_dir(dir).unwrap() { 44 | let dir_entry = dir_entry.unwrap(); 45 | let crate_root = dir_entry.path(); 46 | symlink_licenses(&crate_root).unwrap(); 47 | build_readme(&crate_root).unwrap(); 48 | } 49 | } 50 | 51 | pub fn build_docs() -> io::Result<()> { 52 | println!("building docs"); 53 | let root_dir = get_project_dir().unwrap(); 54 | Command::new("mdbook") 55 | .arg("build") 56 | .arg("book") 57 | .run_or_panic(); 58 | Command::new("cargo") 59 | .arg("doc") 60 | .arg("--all") 61 | .arg("--all-features") 62 | .arg("--no-deps") 63 | .run_or_panic(); 64 | build_docs_for_dir(root_dir.join("crates")); 65 | build_docs_for_dir(root_dir.join("contracts")); 66 | Ok(()) 67 | } 68 | -------------------------------------------------------------------------------- /internal/scripts/src/shared.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs::remove_file, 3 | io, 4 | path::{Path, PathBuf}, 5 | process::{Command, ExitStatus}, 6 | }; 7 | 8 | pub fn cleos() -> Command { 9 | let mut cmd = Command::new("docker"); 10 | cmd.args(&[ 11 | "exec", 12 | "docker_keosd_1", 13 | "cleos", 14 | "--url", 15 | "http://nodeosd:8888", 16 | "--wallet-url", 17 | "http://127.0.0.1:8900", 18 | ]); 19 | cmd 20 | } 21 | 22 | pub fn project_dir() -> io::Result { 23 | let mut path = std::env::current_exe()?; 24 | path.pop(); 25 | path.pop(); 26 | path.pop(); 27 | Ok(path) 28 | } 29 | 30 | pub fn get_target_dir() -> io::Result { 31 | Ok(project_dir()? 32 | .join("target") 33 | .join("wasm32-unknown-unknown") 34 | .join("release")) 35 | } 36 | 37 | pub fn remove_file_if_exists>(path: P) -> io::Result<()> { 38 | match remove_file(path) { 39 | Ok(()) => Ok(()), 40 | Err(err) => { 41 | if err.kind() == io::ErrorKind::NotFound { 42 | Ok(()) 43 | } else { 44 | Err(err) 45 | } 46 | } 47 | } 48 | } 49 | 50 | pub fn push_action( 51 | account: &str, 52 | action: &str, 53 | data: &str, 54 | auth: &str, 55 | ) -> io::Result { 56 | cleos() 57 | .arg("push") 58 | .arg("action") 59 | .arg(account) 60 | .arg(action) 61 | .arg(data) 62 | .arg("-p") 63 | .arg(auth) 64 | .status() 65 | } 66 | 67 | pub trait RunOr { 68 | fn run_or_none(&mut self) -> Option<()>; 69 | fn run_or_panic(&mut self); 70 | } 71 | 72 | impl RunOr for Command { 73 | fn run_or_none(&mut self) -> Option<()> { 74 | let status = self.status().expect("failed to execute process"); 75 | if status.success() { 76 | Some(()) 77 | } else { 78 | None 79 | } 80 | } 81 | 82 | fn run_or_panic(&mut self) { 83 | if self.run_or_none().is_none() { 84 | panic!("Failed to run command: {:?}", self); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /crates/eosio_cli/src/opts/convert.rs: -------------------------------------------------------------------------------- 1 | use eosio::{AccountName, ActionName}; 2 | use structopt::StructOpt; 3 | 4 | /// Pack and unpack transactions 5 | #[derive(StructOpt, Debug)] 6 | pub enum Convert { 7 | /// From plain signed json to packed form 8 | PackTransaction(ConvertPackTransaction), 9 | /// From packed to plain signed json form 10 | UnpackTransaction(ConvertUnpackTransaction), 11 | /// From json action data to packed form 12 | PackActionData(ConvertPackActionData), 13 | /// From packed to json action data form 14 | UnpackActionData(ConvertUnpackActionData), 15 | } 16 | 17 | /// From plain signed json to packed form 18 | #[derive(StructOpt, Debug)] 19 | pub struct ConvertPackTransaction { 20 | /// The plain signed json 21 | pub transaction: String, 22 | /// Pack all action data within transaction, needs interaction with nodeos 23 | #[structopt(long)] 24 | pub pack_action_data: bool, 25 | } 26 | 27 | /// From packed to plain signed json form 28 | #[derive(StructOpt, Debug)] 29 | pub struct ConvertUnpackTransaction { 30 | /// The packed transaction json (string containing packed_trx and 31 | /// optionally compression fields) 32 | pub transaction: String, 33 | /// Unpack all action data within transaction, needs interaction with 34 | /// nodeos 35 | #[structopt(long)] 36 | pub unpack_action_data: bool, 37 | } 38 | 39 | /// From json action data to packed form 40 | #[derive(StructOpt, Debug)] 41 | pub struct ConvertPackActionData { 42 | /// The name of the account that hosts the contract 43 | pub account: AccountName, 44 | /// The name of the function that's called by this action 45 | pub name: ActionName, 46 | /// The action data expressed as json 47 | pub unpacked_action_data: String, 48 | } 49 | 50 | /// From json action data to packed form 51 | #[derive(StructOpt, Debug)] 52 | pub struct ConvertUnpackActionData { 53 | /// The name of the account that hosts the contract 54 | pub account: AccountName, 55 | /// The name of the function that's called by this action 56 | pub name: ActionName, 57 | /// The action data expressed as packed hex string 58 | pub packed_action_data: String, 59 | } 60 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/clients/browser.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use crate::Client; 3 | use futures::future::{self, Future}; 4 | use js_sys::Promise; 5 | use serde::{Deserialize, Serialize}; 6 | use wasm_bindgen::prelude::*; 7 | use wasm_bindgen::JsCast; 8 | use wasm_bindgen_futures::JsFuture; 9 | use web_sys::{Request, RequestInit, RequestMode, Response, Window}; 10 | 11 | pub struct WebSysClient { 12 | node: String, 13 | } 14 | 15 | impl Client for WebSysClient { 16 | fn node(&self) -> &str { 17 | &self.node 18 | } 19 | 20 | fn fetch( 21 | &self, 22 | path: &str, 23 | params: Params, 24 | ) -> Box> 25 | where 26 | Output: 'static + for<'b> Deserialize<'b>, 27 | Params: Serialize, 28 | { 29 | let mut url = self.node.to_owned(); 30 | url.push_str(path); 31 | 32 | let mut opts = RequestInit::new(); 33 | opts.method("POST"); 34 | opts.mode(RequestMode::Cors); 35 | 36 | let body_string = serde_json::to_string(¶ms).unwrap(); 37 | opts.body(Some(&JsValue::from_str(body_string.as_str()))); 38 | 39 | let request = 40 | Request::new_with_str_and_init(url.as_str(), &opts).unwrap(); 41 | let window = web_sys::window().expect("no window object available"); 42 | let request_promise = window.fetch_with_request(&request); 43 | 44 | let fut = JsFuture::from(request_promise) 45 | .map_err(|_| Error::BadResponse) 46 | .and_then(|resp_value| { 47 | assert!(resp_value.is_instance_of::()); 48 | let resp = resp_value.dyn_into::().unwrap(); 49 | resp.json().map_err(|_| Error::BadResponse) 50 | }) 51 | .and_then(|json_value: Promise| { 52 | JsFuture::from(json_value).map_err(|_| Error::BadResponse) 53 | }) 54 | .and_then(|json| match json.into_serde::() { 55 | Ok(output) => future::ok(output), 56 | Err(err) => future::err(Error::BadResponseJson(err)), 57 | }); 58 | Box::new(fut) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /crates/eosio/src/table/secondary_key.rs: -------------------------------------------------------------------------------- 1 | use crate::{Checksum160, Checksum256}; 2 | 3 | /// TODO docs 4 | #[derive(Clone, Copy, Debug)] 5 | pub enum SecondaryKey { 6 | /// TODO docs 7 | U64(u64), 8 | /// TODO docs 9 | F64(f64), 10 | /// TODO docs 11 | U128(u128), 12 | /// TODO docs 13 | H256([u128; 2]), 14 | } 15 | 16 | impl From for SecondaryKey { 17 | #[must_use] 18 | fn from(v: u64) -> Self { 19 | Self::U64(v) 20 | } 21 | } 22 | 23 | impl From for SecondaryKey { 24 | #[must_use] 25 | fn from(v: f64) -> Self { 26 | Self::F64(v) 27 | } 28 | } 29 | 30 | impl From for SecondaryKey { 31 | #[must_use] 32 | fn from(v: u128) -> Self { 33 | Self::U128(v) 34 | } 35 | } 36 | 37 | impl From<[u128; 2]> for SecondaryKey { 38 | #[must_use] 39 | fn from(b: [u128; 2]) -> Self { 40 | Self::H256([b[0], b[1]]) 41 | } 42 | } 43 | 44 | impl From for SecondaryKey { 45 | #[must_use] 46 | fn from(v: Checksum256) -> Self { 47 | v.words().into() 48 | } 49 | } 50 | 51 | impl From for SecondaryKey { 52 | #[must_use] 53 | fn from(v: Checksum160) -> Self { 54 | v.words().into() 55 | } 56 | } 57 | 58 | macro_rules! impl_into_type { 59 | ($($t:ty, $x:ty)*) => ($( 60 | impl From<$x> for SecondaryKey { 61 | #[must_use] 62 | fn from(v: $x) -> Self { 63 | let v: $t = v.into(); 64 | v.into() 65 | } 66 | } 67 | )*) 68 | } 69 | 70 | impl_into_type! { 71 | u64, u8 72 | u64, u16 73 | u64, u32 74 | } 75 | 76 | macro_rules! impl_as_u64_type { 77 | ($($t:ty)*) => ($( 78 | impl From<$t> for SecondaryKey { 79 | #[must_use] 80 | fn from(v: $t) -> Self { 81 | Self::U64(v.as_u64()) 82 | } 83 | } 84 | )*) 85 | } 86 | 87 | impl_as_u64_type! { 88 | crate::account::AccountName 89 | crate::action::ActionName 90 | crate::action::PermissionName 91 | crate::name::Name 92 | crate::symbol::Symbol 93 | crate::symbol::SymbolCode 94 | crate::table::ScopeName 95 | crate::table::TableName 96 | } 97 | -------------------------------------------------------------------------------- /crates/eosio/src/block.rs: -------------------------------------------------------------------------------- 1 | //! 2 | use crate::bytes::{NumBytes, Read, Write}; 3 | use alloc::string::{String, ToString}; 4 | use core::{ 5 | fmt, 6 | num::{NonZeroU64, ParseIntError}, 7 | str::FromStr, 8 | }; 9 | 10 | /// TODO docs 11 | #[derive( 12 | Read, 13 | Write, 14 | NumBytes, 15 | PartialEq, 16 | Eq, 17 | PartialOrd, 18 | Ord, 19 | Debug, 20 | Clone, 21 | Hash, 22 | Default, 23 | )] 24 | #[eosio(crate_path = "crate::bytes")] 25 | pub struct BlockId(String); 26 | 27 | impl fmt::Display for BlockId { 28 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 29 | write!(f, "{}", self.0) 30 | } 31 | } 32 | 33 | /// TODO docs 34 | #[derive( 35 | Read, 36 | Write, 37 | NumBytes, 38 | PartialEq, 39 | Eq, 40 | PartialOrd, 41 | Ord, 42 | Debug, 43 | Clone, 44 | Copy, 45 | Hash, 46 | )] 47 | #[eosio(crate_path = "crate::bytes")] 48 | pub struct BlockNum(NonZeroU64); 49 | 50 | impl fmt::Display for BlockNum { 51 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 52 | write!(f, "{}", self.0) 53 | } 54 | } 55 | 56 | impl FromStr for BlockNum { 57 | type Err = ParseIntError; 58 | 59 | fn from_str(s: &str) -> Result { 60 | s.parse::().map(Self) 61 | } 62 | } 63 | 64 | /// TODO docs 65 | #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Hash)] 66 | pub enum BlockNumOrId { 67 | /// TODO docs 68 | Id(BlockId), 69 | /// TODO docs 70 | Num(BlockNum), 71 | } 72 | 73 | impl FromStr for BlockNumOrId { 74 | type Err = ParseIntError; 75 | 76 | fn from_str(s: &str) -> Result { 77 | match s.parse::() { 78 | Ok(num) => Ok(Self::Num(num)), 79 | Err(_) => Ok(Self::Id(BlockId(s.to_string()))), 80 | } 81 | } 82 | } 83 | 84 | impl fmt::Display for BlockNumOrId { 85 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 86 | match self { 87 | Self::Num(num) => write!(f, "{}", num), 88 | Self::Id(id) => write!(f, "{}", id), 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/src/table.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::TokenStream as TokenStream2; 2 | use quote::{quote, ToTokens}; 3 | use syn::{ 4 | parse::{Parse, ParseStream, Result as ParseResult}, 5 | token::Comma, 6 | DeriveInput, Error, Ident, LitStr, 7 | }; 8 | 9 | pub struct Table { 10 | input: DeriveInput, 11 | args: TableArgs, 12 | } 13 | 14 | impl Table { 15 | pub const fn new(args: TableArgs, input: DeriveInput) -> Self { 16 | Self { args, input } 17 | } 18 | } 19 | 20 | pub struct TableArgs { 21 | name: LitStr, 22 | is_singleton: bool, 23 | } 24 | 25 | impl Parse for TableArgs { 26 | fn parse(input: ParseStream) -> ParseResult { 27 | let name = input.parse::()?; 28 | 29 | if input.parse::().is_ok() { 30 | let ident = input.parse::()?; 31 | if ident == "singleton" { 32 | Ok(Self { 33 | name, 34 | is_singleton: true, 35 | }) 36 | } else { 37 | Err(Error::new(ident.span(), "expected `singleton`")) 38 | } 39 | } else { 40 | Ok(Self { 41 | name, 42 | is_singleton: false, 43 | }) 44 | } 45 | } 46 | } 47 | 48 | impl ToTokens for Table { 49 | fn to_tokens(&self, tokens: &mut TokenStream2) { 50 | let input = &self.input; 51 | let name = &self.args.name; 52 | let expanded = quote! { 53 | #[derive( 54 | Clone, 55 | Debug, 56 | eosio::NumBytes, 57 | eosio::Read, 58 | eosio::Write, 59 | eosio::Table, 60 | PartialEq, 61 | PartialOrd 62 | )] 63 | }; 64 | let expanded = if self.args.is_singleton { 65 | quote! { 66 | #expanded 67 | #[eosio(table_name = #name, singleton)] 68 | } 69 | } else { 70 | quote! { 71 | #expanded 72 | #[eosio(table_name = #name)] 73 | } 74 | }; 75 | let expanded = quote! { 76 | #expanded 77 | #input 78 | }; 79 | expanded.to_tokens(tokens); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /internal/bench_cpp/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{fs, process::Command}; 2 | use util::{get_project_dir, get_target_dir, RunOr}; 3 | 4 | fn main() { 5 | println!("Building bench.cpp"); 6 | 7 | let build_dir = get_target_dir().unwrap(); 8 | fs::create_dir_all(&build_dir).unwrap(); 9 | 10 | let mut src_dir = get_project_dir().unwrap(); 11 | src_dir.push(file!()); 12 | src_dir.pop(); 13 | 14 | let container = "bench_cpp_builder"; 15 | 16 | let container_exists = Command::new("docker") 17 | .arg("container") 18 | .arg("inspect") 19 | .arg(container) 20 | .run_or_none() 21 | .is_some(); 22 | 23 | if container_exists { 24 | Command::new("docker") 25 | .arg("kill") 26 | .arg(container) 27 | .run_or_panic(); 28 | // Command::new("docker") 29 | // .arg("rm") 30 | // .arg(container) 31 | // .run_or_panic(); 32 | } 33 | 34 | Command::new("docker") 35 | .arg("run") 36 | .arg(format!("--name={}", container)) 37 | .arg(format!("--volume={}:/src:ro", src_dir.to_str().unwrap())) 38 | .arg(format!("--volume={}:/build", build_dir.to_str().unwrap())) 39 | .arg("--detach") 40 | .arg("--entrypoint=sleep") 41 | .arg("--rm") 42 | .arg("sagansoftware/eosio.cdt:1.7.0") 43 | .arg("30") 44 | .run_or_panic(); 45 | 46 | Command::new("docker") 47 | .arg("exec") 48 | .arg(container) 49 | .arg("eosio-cpp") 50 | .arg("-o=/tmp/bench_cpp.wasm") 51 | .arg("-abigen") 52 | .arg("-abigen_output=/tmp/bench.json") 53 | .arg("-contract=bench") 54 | .arg("/src/contract.cpp") 55 | .run_or_panic(); 56 | 57 | Command::new("docker") 58 | .arg("exec") 59 | .arg(container) 60 | .arg("mv") 61 | .arg("/tmp/bench_cpp.wasm") 62 | .arg("/build") 63 | .run_or_panic(); 64 | 65 | Command::new("docker") 66 | .arg("exec") 67 | .arg(container) 68 | .arg("mv") 69 | .arg("/tmp/bench_cpp.abi") 70 | .arg("/build/bench.abi.json") 71 | .run_or_panic(); 72 | 73 | Command::new("docker") 74 | .arg("kill") 75 | .arg(container) 76 | .run_or_panic(); 77 | } 78 | -------------------------------------------------------------------------------- /crates/eosio/src/transaction.rs: -------------------------------------------------------------------------------- 1 | //! TODO docs 2 | use crate::{ 3 | action::Action, 4 | bytes::{NumBytes, Read, Write}, 5 | time::TimePointSec, 6 | varint::UnsignedInt, 7 | }; 8 | use alloc::vec::Vec; 9 | 10 | /// TODO docs 11 | #[derive( 12 | Read, 13 | Write, 14 | NumBytes, 15 | PartialEq, 16 | Eq, 17 | PartialOrd, 18 | Ord, 19 | Debug, 20 | Clone, 21 | Hash, 22 | Default, 23 | )] 24 | #[eosio(crate_path = "crate::bytes")] 25 | pub struct TransactionExtension(u16, Vec); 26 | 27 | /// TODO docs 28 | #[derive( 29 | Read, 30 | Write, 31 | NumBytes, 32 | PartialEq, 33 | Eq, 34 | PartialOrd, 35 | Ord, 36 | Debug, 37 | Clone, 38 | Hash, 39 | Default, 40 | )] 41 | #[eosio(crate_path = "crate::bytes")] 42 | pub struct TransactionHeader { 43 | /// TODO docs 44 | pub expiration: TimePointSec, 45 | /// TODO docs 46 | pub ref_block_num: u16, 47 | /// TODO docs 48 | pub ref_block_prefix: u32, 49 | /// number of 8 byte words this transaction can serialize into after 50 | /// compressions 51 | pub max_net_usage_words: UnsignedInt, 52 | /// number of CPU usage units to bill transaction for 53 | pub max_cpu_usage_ms: u8, 54 | /// number of seconds to delay transaction, default: 0 55 | pub delay_sec: UnsignedInt, 56 | } 57 | 58 | /// TODO docs 59 | #[derive(Clone, Debug, Read, Write, NumBytes, Default)] 60 | #[eosio(crate_path = "crate::bytes")] 61 | pub struct Transaction> { 62 | /// TODO docs 63 | pub header: TransactionHeader, 64 | /// TODO docs 65 | pub context_free_actions: Vec>, 66 | /// TODO docs 67 | pub actions: Vec>, 68 | /// TODO docs 69 | pub transaction_extensions: Vec, 70 | } 71 | 72 | /// TODO docs 73 | /// TODO represet this as a String for RPC 74 | #[derive(Clone, Debug)] 75 | pub struct TransactionId(u128); 76 | 77 | impl TransactionId { 78 | /// TODO docs 79 | #[must_use] 80 | pub const fn as_u128(&self) -> u128 { 81 | self.0 82 | } 83 | } 84 | 85 | impl From for TransactionId { 86 | #[must_use] 87 | fn from(value: u128) -> Self { 88 | Self(value) 89 | } 90 | } 91 | 92 | impl AsRef for TransactionId { 93 | fn as_ref(&self) -> &Self { 94 | self 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /crates/eosio/src/crypto/keys.rs: -------------------------------------------------------------------------------- 1 | use crate::{NumBytes, Read, UnsignedInt, Write}; 2 | use alloc::string::String; 3 | use core::fmt; 4 | 5 | macro_rules! key_type { 6 | ($ident:ident, $bytes:literal) => { 7 | /// TODO depreciate, newer signature types cannot be represented as a 8 | /// fixed size structure EOSIO Public Key 9 | /// 10 | #[derive(Read, Write, NumBytes, Clone)] 11 | #[eosio(crate_path = "crate::bytes")] 12 | pub struct $ident { 13 | /// Type of the public key, could be either K1 or R1 14 | pub type_: UnsignedInt, 15 | /// Bytes of the public key 16 | pub data: [u8; $bytes], 17 | } 18 | 19 | impl $ident { 20 | /// TODO docs. 21 | #[must_use] 22 | pub const fn as_bytes(&self) -> &[u8; $bytes] { 23 | &self.data 24 | } 25 | 26 | /// TODO docs. 27 | #[must_use] 28 | pub const fn to_bytes(&self) -> [u8; $bytes] { 29 | self.data 30 | } 31 | 32 | /// TODO docs. 33 | #[must_use] 34 | pub fn as_slice(&self) -> &[u8] { 35 | &self.data 36 | } 37 | } 38 | 39 | impl Default for $ident { 40 | #[must_use] 41 | fn default() -> Self { 42 | Self { 43 | type_: UnsignedInt::default(), 44 | data: [0_u8; $bytes], 45 | } 46 | } 47 | } 48 | 49 | impl PartialEq for $ident { 50 | #[must_use] 51 | fn eq(&self, other: &Self) -> bool { 52 | self.type_ == other.type_ && self.as_slice() == other.as_slice() 53 | } 54 | } 55 | 56 | impl fmt::Debug for $ident { 57 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 58 | fmt::Debug::fmt(&self.type_, f)?; 59 | fmt::Debug::fmt(self.as_slice(), f) 60 | } 61 | } 62 | }; 63 | } 64 | 65 | key_type!(PublicKey, 34); 66 | key_type!(Signature, 66); 67 | 68 | /// TODO docs 69 | #[derive(Read, Write, NumBytes, Clone)] 70 | #[eosio(crate_path = "crate::bytes")] 71 | pub struct PrivateKey(String); 72 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | nodeosd: 5 | # build: 6 | # dockerfile: ./eos.dockerfile 7 | # context: . 8 | image: sagansoftware/eos:2.0.3 9 | hostname: nodeosd 10 | entrypoint: nodeos 11 | command: > 12 | --access-control-allow-origin=* 13 | --contracts-console 14 | --data-dir /eos/build/data-dir 15 | --enable-stale-production 16 | --genesis-json /genesis.json 17 | --http-alias=127.0.0.1:8888 18 | --http-alias=localhost:8888 19 | --http-alias=nodeosd:8888 20 | --http-max-bytes-in-flight-mb=1000 21 | --http-max-response-time-ms=1000 22 | --http-server-address=0.0.0.0:8888 23 | --http-validate-host=false 24 | --max-transaction-time=1000 25 | --plugin eosio::chain_api_plugin 26 | --plugin eosio::chain_plugin 27 | --plugin eosio::history_api_plugin 28 | --plugin eosio::history_plugin 29 | --plugin eosio::http_plugin 30 | --plugin eosio::producer_api_plugin 31 | --plugin eosio::producer_plugin 32 | --producer-name eosio 33 | --verbose-http-errors 34 | ports: 35 | - 8888:8888 36 | - 8889:8889 37 | - 9876:9876 38 | expose: 39 | - "8888" 40 | - "8889" 41 | volumes: 42 | - nodeos-data-volume:/opt/eosio/bin/data-dir 43 | - ./genesis.json:/genesis.json:ro 44 | cap_add: 45 | - IPC_LOCK 46 | stop_grace_period: 10m 47 | 48 | keosd: 49 | # build: 50 | # dockerfile: ./eos.dockerfile 51 | # context: . 52 | image: sagansoftware/eosio.contracts:1.9.1 53 | hostname: keosd 54 | entrypoint: keosd 55 | command: > 56 | --wallet-dir /opt/eosio/bin/data-dir 57 | --unlock-timeout 9999999 58 | --http-server-address=127.0.0.1:8900 59 | --http-alias=keosd:8900 60 | --http-alias=localhost:8900 61 | ports: 62 | - 8900:8900 63 | expose: 64 | - "8900" 65 | volumes: 66 | - keosd-data-volume:/opt/eosio/bin/data-dir 67 | - ../target/release:/mnt/dev/build 68 | - ../target/wasm32-unknown-unknown/release:/mnt/dev/release:ro 69 | - ../examples:/mnt/dev/examples:ro 70 | - ../:/mnt/dev/project:ro 71 | links: 72 | - nodeosd 73 | stop_grace_period: 10m 74 | 75 | volumes: 76 | nodeos-data-volume: 77 | external: true 78 | keosd-data-volume: 79 | external: true 80 | -------------------------------------------------------------------------------- /crates/eosio/src/time/time_point.rs: -------------------------------------------------------------------------------- 1 | use super::TimePointSec; 2 | use crate::bytes::{NumBytes, Read, Write}; 3 | use core::{ 4 | convert::{TryFrom, TryInto}, 5 | num::TryFromIntError, 6 | }; 7 | 8 | /// High resolution time point in microseconds 9 | /// 10 | #[derive( 11 | Read, 12 | Write, 13 | NumBytes, 14 | PartialEq, 15 | Eq, 16 | PartialOrd, 17 | Ord, 18 | Debug, 19 | Clone, 20 | Copy, 21 | Hash, 22 | Default, 23 | )] 24 | #[eosio(crate_path = "crate::bytes")] 25 | pub struct TimePoint(i64); 26 | 27 | impl TimePoint { 28 | #[inline] 29 | #[must_use] 30 | pub const fn from_micros(micros: i64) -> Self { 31 | Self(micros) 32 | } 33 | 34 | #[inline] 35 | #[must_use] 36 | pub const fn from_millis(millis: i64) -> Self { 37 | Self::from_micros(millis * 1_000) 38 | } 39 | 40 | /// Gets the microseconds 41 | #[inline] 42 | #[must_use] 43 | pub const fn as_micros(&self) -> i64 { 44 | self.0 45 | } 46 | 47 | /// Gets the milliseconds 48 | #[inline] 49 | #[must_use] 50 | pub const fn as_millis(&self) -> i64 { 51 | self.0 / 1_000 52 | } 53 | 54 | #[inline] 55 | #[must_use] 56 | #[allow(clippy::cast_possible_truncation)] 57 | pub const fn as_secs(&self) -> i32 { 58 | (self.0 / 1_000_000) as i32 59 | } 60 | 61 | #[inline] 62 | #[must_use] 63 | #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] 64 | pub const fn as_time_point_sec(&self) -> TimePointSec { 65 | TimePointSec::from_secs(self.as_secs() as u32) 66 | } 67 | } 68 | 69 | impl From for TimePoint { 70 | #[inline] 71 | #[must_use] 72 | fn from(i: i64) -> Self { 73 | Self(i) 74 | } 75 | } 76 | 77 | impl From for i64 { 78 | #[inline] 79 | #[must_use] 80 | fn from(t: TimePoint) -> Self { 81 | t.0 82 | } 83 | } 84 | 85 | impl TryFrom for TimePoint { 86 | type Error = TryFromIntError; 87 | 88 | #[inline] 89 | fn try_from(i: u64) -> Result { 90 | Ok(i64::try_from(i)?.into()) 91 | } 92 | } 93 | 94 | impl TryFrom for u64 { 95 | type Error = TryFromIntError; 96 | 97 | #[inline] 98 | fn try_from(t: TimePoint) -> Result { 99 | t.as_micros().try_into() 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/singleton_index.rs: -------------------------------------------------------------------------------- 1 | use crate::{Payer, TableCursor, TableIndex}; 2 | use eosio::{ 3 | AccountName, PrimaryTableIndex, ReadError, ScopeName, Table, WriteError, 4 | }; 5 | 6 | /// TODO docs 7 | pub struct SingletonIndex(PrimaryTableIndex); 8 | 9 | impl SingletonIndex { 10 | /// TODO docs 11 | #[inline] 12 | pub fn new(code: C, scope: S) -> Self 13 | where 14 | C: Into, 15 | S: Into, 16 | { 17 | Self(PrimaryTableIndex::new(code, scope)) 18 | } 19 | 20 | /// Checks if the singleton entry exists 21 | #[inline] 22 | #[must_use] 23 | pub fn exists(&self) -> bool { 24 | self.0.find(T::NAME).is_some() 25 | } 26 | 27 | /// Gets the value stored inside the singleton. Returns `None` if no value 28 | /// is found, or `ReadError` if there was an issue reading the data. 29 | #[inline] 30 | #[must_use] 31 | pub fn get(&self) -> Option> { 32 | self.0.find(T::NAME).map(|c| c.get()) 33 | } 34 | 35 | /// Gets the value stored inside the singleton or returns the default value. 36 | /// 37 | /// # Errors 38 | /// 39 | /// Will return `Err` if there was an issue deserializing the stored value. 40 | #[inline] 41 | pub fn get_or_default(&self) -> Result 42 | where 43 | T::Row: Default, 44 | { 45 | self.0 46 | .find(T::NAME) 47 | .map_or_else(|| Ok(T::Row::default()), |c| c.get()) 48 | } 49 | 50 | /// Sets the singleton value 51 | /// 52 | /// # Errors 53 | /// 54 | /// Will return `Err` if there was an issue serializing the value. 55 | #[inline] 56 | pub fn set( 57 | &self, 58 | value: &T::Row, 59 | payer: AccountName, 60 | ) -> Result<(), WriteError> { 61 | match self.0.find(T::NAME) { 62 | Some(cursor) => { 63 | cursor.modify(Payer::New(payer), value)?; 64 | Ok(()) 65 | } 66 | None => self.0.emplace(payer, value), 67 | } 68 | } 69 | 70 | /// Removes the singleton value if it exists. Returns `ReadError` if there 71 | /// was an issue reading the data, and None if there was no entry found 72 | /// 73 | /// # Errors 74 | /// 75 | /// Will return `Err` if there was an issue reading the stored value. 76 | #[inline] 77 | pub fn remove(&self) -> Result, ReadError> { 78 | match self.0.find(T::NAME) { 79 | Some(cursor) => cursor.erase().map(Some), 80 | None => Ok(None), 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /crates/eosio/src/name/mod.rs: -------------------------------------------------------------------------------- 1 | //! 2 | mod name_type; 3 | 4 | use crate::bytes::{NumBytes, Read, Write}; 5 | use core::{ 6 | cmp::PartialEq, 7 | fmt, 8 | str::{self, FromStr}, 9 | }; 10 | pub use eosio_numstr::ParseNameError; 11 | use eosio_numstr::{name_from_bytes, name_to_bytes}; 12 | 13 | /// TODO docs 14 | /// TODO use `NonZeroU64` 15 | #[derive( 16 | Debug, 17 | PartialEq, 18 | Eq, 19 | Clone, 20 | Copy, 21 | Default, 22 | Hash, 23 | PartialOrd, 24 | Ord, 25 | Read, 26 | Write, 27 | NumBytes, 28 | )] 29 | #[eosio(crate_path = "crate::bytes")] 30 | pub struct Name(u64); 31 | 32 | impl Name { 33 | /// Creates a new name 34 | #[inline] 35 | #[must_use] 36 | pub const fn new(value: u64) -> Self { 37 | Self(value) 38 | } 39 | 40 | /// TODO docs 41 | #[inline] 42 | #[must_use] 43 | pub const fn as_u64(&self) -> u64 { 44 | self.0 45 | } 46 | } 47 | 48 | impl From for Name { 49 | #[inline] 50 | #[must_use] 51 | fn from(n: u64) -> Self { 52 | Self(n) 53 | } 54 | } 55 | 56 | impl From for u64 { 57 | #[inline] 58 | #[must_use] 59 | fn from(i: Name) -> Self { 60 | i.0 61 | } 62 | } 63 | 64 | impl FromStr for Name { 65 | type Err = ParseNameError; 66 | 67 | #[inline] 68 | fn from_str(s: &str) -> Result { 69 | let name = name_from_bytes(s.bytes())?; 70 | Ok(name.into()) 71 | } 72 | } 73 | 74 | impl fmt::Display for Name { 75 | #[inline] 76 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 77 | let bytes = name_to_bytes(self.0); 78 | let value = str::from_utf8(&bytes) 79 | .map(|s| s.trim_end_matches('.')) 80 | .map_err(|_| fmt::Error)?; 81 | write!(f, "{}", value) 82 | } 83 | } 84 | 85 | impl PartialEq for Name { 86 | fn eq(&self, other: &u64) -> bool { 87 | &self.0 == other 88 | } 89 | } 90 | 91 | #[cfg(test)] 92 | mod tests { 93 | use super::{FromStr, Name}; 94 | use alloc::string::ToString; 95 | use proptest::prelude::*; 96 | 97 | proptest! { 98 | #[test] 99 | fn from_str_to_string(input in "[[1-5][a-z]]{0,12}[a-j]{0,1}") { 100 | let name = Name::from_str(&input).expect("Failed to parse name from str"); 101 | let string = name.to_string(); 102 | prop_assert_eq!(string, input); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /crates/eosio_rpc/src/chain/get_table_rows.rs: -------------------------------------------------------------------------------- 1 | use crate::Client; 2 | use eosio::{AccountName, ScopeName, TableName}; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Serialize, Clone, Copy)] 6 | pub struct GetTableRowsParams { 7 | pub scope: ScopeName, 8 | pub code: AccountName, 9 | pub table: TableName, 10 | pub json: bool, 11 | #[serde(skip_serializing_if = "Option::is_none")] 12 | pub lower_bound: Option, 13 | #[serde(skip_serializing_if = "Option::is_none")] 14 | pub upper_bound: Option, 15 | #[serde(skip_serializing_if = "Option::is_none")] 16 | pub limit: Option, 17 | } 18 | 19 | impl GetTableRowsParams { 20 | pub fn json(&mut self, value: bool) -> &mut Self { 21 | self.json = value; 22 | self 23 | } 24 | 25 | pub fn lower_bound>(&mut self, value: V) -> &mut Self { 26 | self.lower_bound = Some(value.into()); 27 | self 28 | } 29 | 30 | pub fn no_lower_bound(&mut self) -> &mut Self { 31 | self.lower_bound = None; 32 | self 33 | } 34 | 35 | pub fn upper_bound>(&mut self, value: V) -> &mut Self { 36 | self.upper_bound = Some(value.into()); 37 | self 38 | } 39 | 40 | pub fn no_upper_bound(&mut self) -> &mut Self { 41 | self.upper_bound = None; 42 | self 43 | } 44 | 45 | pub fn limit(&mut self, value: u32) -> &mut Self { 46 | self.limit = Some(value); 47 | self 48 | } 49 | 50 | pub fn no_limit(&mut self) -> &mut Self { 51 | self.limit = None; 52 | self 53 | } 54 | 55 | // TODO re-enable 56 | // pub fn fetch( 57 | // self, 58 | // client: Box, 59 | // ) -> impl std::future::Future, crate::Error>> 60 | // where 61 | // Row: for<'a> Deserialize<'a> + 'static + Send, 62 | // { 63 | // client.fetch::, GetTableRowsParams>( 64 | // "/v1/chain/get_table_rows", 65 | // self, 66 | // ) 67 | // } 68 | } 69 | 70 | pub fn get_table_rows< 71 | C: Into, 72 | S: Into, 73 | T: Into, 74 | >( 75 | code: C, 76 | scope: S, 77 | table: T, 78 | ) -> GetTableRowsParams { 79 | GetTableRowsParams { 80 | code: code.into(), 81 | scope: scope.into(), 82 | table: table.into(), 83 | json: true, 84 | lower_bound: None, 85 | upper_bound: None, 86 | limit: None, 87 | } 88 | } 89 | 90 | #[derive(Serialize, Deserialize, Debug, Clone, Default)] 91 | pub struct GetTableRows { 92 | pub rows: Vec, 93 | pub more: bool, 94 | } 95 | -------------------------------------------------------------------------------- /crates/eosio_cdt/src/table.rs: -------------------------------------------------------------------------------- 1 | use alloc::vec::Vec; 2 | use core::borrow::Borrow; 3 | use eosio::{AccountName, DataStream, ReadError, ScopeName, Table, WriteError}; 4 | 5 | pub enum Payer { 6 | Same, 7 | New(AccountName), 8 | } 9 | 10 | /// Table Cursor 11 | pub trait TableCursor: IntoIterator 12 | where 13 | T: Table, 14 | { 15 | fn bytes(&self) -> Vec; 16 | 17 | #[inline] 18 | fn stream(&self) -> DataStream { 19 | self.bytes().into() 20 | } 21 | 22 | /// Read and deserialize the current table row 23 | /// 24 | /// # Errors 25 | /// 26 | /// Will return `Err` if there was an issue reading the stored value. 27 | #[inline] 28 | fn get(&self) -> Result { 29 | self.stream().read() 30 | } 31 | 32 | /// Erase the current row 33 | /// 34 | /// # Errors 35 | /// 36 | /// Will return `Err` if there was an issue reading the stored value. Stored 37 | /// values must be read in order to erase secondary indexes. 38 | fn erase(&self) -> Result; 39 | 40 | /// Modify the current row 41 | /// 42 | /// # Errors 43 | /// 44 | /// Will return `Err` if there was an issue serializing the value. 45 | fn modify>( 46 | &self, 47 | payer: Payer, 48 | item: I, 49 | ) -> Result; 50 | } 51 | 52 | /// Table index 53 | pub trait TableIndex<'a, K, T> 54 | where 55 | T: Table + 'a, 56 | { 57 | /// The kind of cursor this table index uses 58 | type Cursor: TableCursor + 'a; 59 | /// Returns the account name of the smart contract 60 | fn code(&'a self) -> AccountName; 61 | /// Returns the table scope 62 | fn scope(&'a self) -> ScopeName; 63 | /// Returns a cursor pointing to the first row that matches a key 64 | fn lower_bound>(&'a self, key: N) -> Option; 65 | /// Returns a cursor pointing to the last row that matches a key 66 | fn upper_bound>(&'a self, key: N) -> Option; 67 | 68 | /// Inserts a new row into the table 69 | /// 70 | /// # Errors 71 | /// 72 | /// Will return `Err` if there was an issue serializing the value. 73 | fn emplace>( 74 | &'a self, 75 | payer: AccountName, 76 | item: I, 77 | ) -> Result<(), WriteError>; 78 | 79 | fn find>(&'a self, key: N) -> Option; 80 | 81 | /// Returns true if the table contains a row with the specified primary key 82 | #[inline] 83 | fn exists>(&'a self, key: N) -> bool { 84 | self.find(key).is_some() 85 | } 86 | } 87 | 88 | /// Table iterator 89 | pub trait TableIterator: DoubleEndedIterator {} 90 | -------------------------------------------------------------------------------- /crates/eosio/src/name/name_type.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! name_type { 3 | ($ident:ident) => { 4 | #[derive( 5 | Debug, 6 | PartialEq, 7 | Eq, 8 | Clone, 9 | Copy, 10 | Default, 11 | Hash, 12 | PartialOrd, 13 | Ord, 14 | crate::bytes::Read, 15 | crate::bytes::Write, 16 | crate::bytes::NumBytes, 17 | )] 18 | #[eosio(crate_path = "crate::bytes")] 19 | pub struct $ident($crate::name::Name); 20 | 21 | impl $ident { 22 | #[must_use] 23 | pub const fn new(value: u64) -> Self { 24 | Self($crate::name::Name::new(value)) 25 | } 26 | 27 | #[must_use] 28 | pub const fn as_u64(&self) -> u64 { 29 | self.0.as_u64() 30 | } 31 | 32 | #[must_use] 33 | pub const fn as_name(&self) -> $crate::name::Name { 34 | self.0 35 | } 36 | } 37 | 38 | impl core::ops::Deref for $ident { 39 | type Target = $crate::name::Name; 40 | 41 | #[must_use] 42 | fn deref(&self) -> &Self::Target { 43 | &self.0 44 | } 45 | } 46 | 47 | impl core::convert::AsRef<$crate::name::Name> for $ident { 48 | #[must_use] 49 | fn as_ref(&self) -> &$crate::name::Name { 50 | &self.0 51 | } 52 | } 53 | 54 | impl core::convert::AsRef<$ident> for $ident { 55 | #[must_use] 56 | fn as_ref(&self) -> &Self { 57 | self 58 | } 59 | } 60 | 61 | impl From for $ident { 62 | #[must_use] 63 | fn from(value: u64) -> Self { 64 | Self::new(value) 65 | } 66 | } 67 | 68 | impl From<$ident> for u64 { 69 | #[must_use] 70 | fn from(value: $ident) -> Self { 71 | value.as_u64() 72 | } 73 | } 74 | 75 | impl From<$crate::name::Name> for $ident { 76 | #[must_use] 77 | fn from(value: $crate::name::Name) -> Self { 78 | Self(value) 79 | } 80 | } 81 | 82 | impl From<$ident> for $crate::name::Name { 83 | #[must_use] 84 | fn from(value: $ident) -> Self { 85 | value.as_name() 86 | } 87 | } 88 | 89 | impl core::str::FromStr for $ident { 90 | type Err = $crate::name::ParseNameError; 91 | 92 | #[inline] 93 | fn from_str(s: &str) -> Result { 94 | let name = $crate::name::Name::from_str(s)?; 95 | Ok(Self(name)) 96 | } 97 | } 98 | }; 99 | } 100 | -------------------------------------------------------------------------------- /crates/eosio/src/producer_schedule.rs: -------------------------------------------------------------------------------- 1 | //! 2 | use crate::{AccountName, NumBytes, PublicKey, Read, Write}; 3 | use alloc::{vec, vec::Vec}; 4 | 5 | /// Maps producer with its signing key, used for producer schedule 6 | /// 7 | #[derive(Read, Write, NumBytes, Clone, Default, Debug)] 8 | #[eosio(crate_path = "crate::bytes")] 9 | pub struct ProducerKey { 10 | /// Name of the producer 11 | pub producer_name: AccountName, 12 | /// Block signing key used by this producer 13 | pub block_signing_key: PublicKey, 14 | } 15 | 16 | /// Defines both the order, account name, and signing keys of the active set 17 | /// of producers. 18 | #[derive(Read, Write, NumBytes, Clone, Default, Debug)] 19 | #[eosio(crate_path = "crate::bytes")] 20 | pub struct ProducerSchedule { 21 | /// Version number of the schedule. It is sequentially incrementing 22 | /// version number. 23 | pub version: u32, 24 | /// List of producers for this schedule, including its signing key 25 | pub producers: Vec, 26 | } 27 | 28 | /// pairs a public key with an integer weight 29 | #[derive(Read, Write, NumBytes, Clone, Default, Debug)] 30 | #[eosio(crate_path = "crate::bytes")] 31 | pub struct KeyWeight { 32 | /// public key used in a weighted threshold multi-sig authority 33 | pub key: PublicKey, 34 | /// weight associated with a signature from the private key associated with 35 | /// the accompanying public key 36 | pub weight: u64, 37 | } 38 | 39 | impl From for KeyWeight { 40 | fn from(key: PublicKey) -> Self { 41 | Self { key, weight: 1 } 42 | } 43 | } 44 | 45 | /// block signing authority version 0 46 | /// this authority allows for a weighted threshold multi-sig per-producer 47 | #[derive(Read, Write, NumBytes, Clone, Default, Debug)] 48 | #[eosio(crate_path = "crate::bytes")] 49 | pub struct BlockSigningAuthority { 50 | /// minimum threshold of accumulated weights from component keys that 51 | /// satisfies this authority 52 | pub threshold: u32, 53 | /// component keys and their associated weights 54 | pub keys: Vec, 55 | } 56 | 57 | impl From for BlockSigningAuthority { 58 | #[inline] 59 | fn from(key: PublicKey) -> Self { 60 | Self { 61 | threshold: 1, 62 | keys: vec![key.into()], 63 | } 64 | } 65 | } 66 | 67 | /// Maps producer with its signing key, used for producer schedule 68 | #[derive(Read, Write, NumBytes, Clone, Default, Debug)] 69 | #[eosio(crate_path = "crate::bytes")] 70 | pub struct ProducerAuthority { 71 | /// Name of the producer 72 | pub producer_name: AccountName, 73 | /// The block signing authority used by this producer 74 | pub authority: BlockSigningAuthority, 75 | } 76 | -------------------------------------------------------------------------------- /crates/eosio/src/symbol/extended_symbol.rs: -------------------------------------------------------------------------------- 1 | use super::Symbol; 2 | use crate::{ 3 | account::AccountName, 4 | bytes::{NumBytes, Read, Write}, 5 | }; 6 | use core::{fmt, ops::Deref}; 7 | pub use eosio_numstr::ParseSymbolError; 8 | 9 | /// Extended asset which stores the information of the owner of the symbol 10 | /// 11 | #[derive(Debug, PartialEq, Clone, Copy, Default, Read, Write, NumBytes)] 12 | #[eosio(crate_path = "crate::bytes")] 13 | pub struct ExtendedSymbol { 14 | /// The symbol 15 | pub symbol: Symbol, 16 | /// The token contract hosting the symbol 17 | pub contract: AccountName, 18 | } 19 | 20 | impl fmt::Display for ExtendedSymbol { 21 | #[inline] 22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 23 | write!(f, "{}@{}", self.symbol, self.contract.deref()) 24 | } 25 | } 26 | 27 | #[cfg(test)] 28 | mod tests { 29 | use super::{AccountName, ExtendedSymbol, Symbol}; 30 | use crate::SymbolCode; 31 | use alloc::string::ToString; 32 | use core::str::FromStr; 33 | use proptest::prelude::*; 34 | 35 | proptest! { 36 | #[test] 37 | fn from_str_to_string( 38 | precision in 0_u8.., 39 | code in "[A-Z]{2,7}", 40 | contract in "[[1-5][a-z]]{1,12}" 41 | ) { 42 | let expected = format!("{},{}@{}", precision, code, contract); 43 | let code = SymbolCode::from_str(&code).unwrap(); 44 | let symbol = Symbol::new_with_code(precision, code); 45 | let contract = AccountName::from_str(&contract).unwrap(); 46 | let extended_symbol = ExtendedSymbol { symbol, contract }; 47 | let result = extended_symbol.to_string(); 48 | prop_assert_eq!(result, expected); 49 | } 50 | } 51 | } 52 | 53 | // #[cfg(test)] 54 | // mod extended_symbol_tests { 55 | // use super::*; 56 | // use alloc::string::ToString; 57 | // use eosio_macros::{n, s}; 58 | 59 | // macro_rules! test_to_string { 60 | // ($($name:ident, $symbol:expr, $contract:expr, $expected:expr)*) => 61 | // ($( #[test] 62 | // fn $name() { 63 | // let extended = ExtendedSymbol { 64 | // symbol: $symbol.into(), 65 | // contract: $contract.into(), 66 | // }; 67 | // assert_eq!(extended.to_string(), $expected); 68 | // } 69 | // )*) 70 | // } 71 | 72 | // test_to_string! { 73 | // to_string, 74 | // s!(4, "EOS"), 75 | // n!("eosio.token"), 76 | // "4,EOS@eosio.token" 77 | 78 | // to_string_zero_precision, 79 | // s!(0, "TST"), 80 | // n!("test"), 81 | // "0,TST@test" 82 | 83 | // to_string_one_precision, 84 | // s!(1, "TGFT"), 85 | // n!("greatfiltert"), 86 | // "1,TGFT@greatfiltert" 87 | // } 88 | // } 89 | -------------------------------------------------------------------------------- /crates/eosio_macros_internal/src/abi.rs: -------------------------------------------------------------------------------- 1 | use crate::proc_macro::TokenStream; 2 | use quote::quote; 3 | use syn::{ 4 | parse::{Parse, ParseStream, Result as ParseResult}, 5 | parse_macro_input, 6 | punctuated::Punctuated, 7 | Expr, Path, Token, 8 | }; 9 | 10 | struct AbiPair { 11 | code: Option, 12 | action: Path, 13 | } 14 | 15 | impl Parse for AbiPair { 16 | fn parse(input: ParseStream) -> ParseResult { 17 | let action: Path = input.parse()?; 18 | match input.parse::() { 19 | Ok(_) => { 20 | let code: Expr = input.parse()?; 21 | Ok(AbiPair { 22 | code: Some(code), 23 | action, 24 | }) 25 | } 26 | Err(_) => Ok(AbiPair { code: None, action }), 27 | } 28 | } 29 | } 30 | 31 | struct AbiPairs(Vec); 32 | 33 | impl Parse for AbiPairs { 34 | fn parse(input: ParseStream) -> ParseResult { 35 | let parsed = 36 | Punctuated::::parse_separated_nonempty(input)?; 37 | let pairs: Vec = parsed.into_iter().collect(); 38 | Ok(AbiPairs(pairs)) 39 | } 40 | } 41 | 42 | pub fn expand(input: TokenStream) -> TokenStream { 43 | let pairs = parse_macro_input!(input as AbiPairs); 44 | let actions = pairs.0.into_iter().map(|pair| { 45 | let code = pair 46 | .code 47 | .map(|code| quote!(eosio::n!(#code))) 48 | .unwrap_or_else(|| quote!(receiver)); 49 | let action = pair.action; 50 | quote! { 51 | else if code == #code && action == <#action as eosio::ActionFn>::NAME.as_u64() { 52 | let data = eosio_cdt::read_action_data::<#action>().expect("failed to read action data"); 53 | <#action as eosio::ActionFn>::call(data) 54 | } 55 | } 56 | }); 57 | let expanded = quote! { 58 | #[cfg(target_arch = "wasm32")] 59 | #[no_mangle] 60 | pub extern "C" fn apply(receiver: u64, code: u64, action: u64) { 61 | std::panic::set_hook(Box::new(|panic_info| { 62 | let payload = panic_info.payload(); 63 | let message = payload 64 | .downcast_ref::<&str>() 65 | .map(ToString::to_string) 66 | .or_else(|| payload.downcast_ref::().map(ToString::to_string)) 67 | .unwrap_or_else(|| panic_info.to_string()); 68 | eosio_cdt::check(false, &message); 69 | })); 70 | if action == eosio::n!("onerror") { 71 | assert!( 72 | code == eosio::n!("eosio"), 73 | "onerror action's are only valid from the \"eosio\" system account" 74 | ); 75 | } 76 | #(#actions)* 77 | else if code == receiver { 78 | panic!("unknown action '{}'", eosio::Name::new(action)); 79 | } 80 | } 81 | }; 82 | expanded.into() 83 | } 84 | -------------------------------------------------------------------------------- /crates/eosio/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! TODO docs 2 | #![no_std] 3 | #![deny( 4 | clippy::correctness, 5 | clippy::indexing_slicing, 6 | clippy::option_unwrap_used, 7 | clippy::result_unwrap_used, 8 | clippy::unimplemented, 9 | clippy::wrong_pub_self_convention, 10 | clippy::wrong_self_convention 11 | )] 12 | #![warn( 13 | clippy::complexity, 14 | clippy::pedantic, 15 | clippy::nursery, 16 | clippy::style, 17 | clippy::perf, 18 | // clippy::cargo, 19 | clippy::dbg_macro, 20 | clippy::else_if_without_else, 21 | clippy::float_cmp_const, 22 | clippy::mem_forget, 23 | clippy::use_debug 24 | )] 25 | #![allow( 26 | clippy::missing_docs_in_private_items, 27 | clippy::module_name_repetitions, 28 | clippy::module_inception, 29 | clippy::trivially_copy_pass_by_ref 30 | )] 31 | #![cfg_attr( 32 | test, 33 | allow(clippy::option_unwrap_used, clippy::result_unwrap_used) 34 | )] 35 | 36 | extern crate alloc; 37 | 38 | #[cfg(test)] 39 | #[macro_use] 40 | extern crate std; 41 | 42 | pub use eosio_macros::{abi, action, n, s, table}; 43 | 44 | mod abi; 45 | pub use self::abi::*; 46 | 47 | mod account; 48 | pub use self::account::AccountName; 49 | 50 | mod action; 51 | pub use self::action::{ 52 | Action, ActionFn, ActionName, PermissionLevel, PermissionName, 53 | }; 54 | 55 | mod asset; 56 | pub use self::asset::{Asset, ExtendedAsset}; 57 | 58 | mod binary_extension; 59 | pub use self::binary_extension::BinaryExtension; 60 | 61 | mod block; 62 | pub use self::block::*; 63 | 64 | mod blockchain_parameters; 65 | pub use self::blockchain_parameters::*; 66 | 67 | mod bytes; 68 | pub use self::bytes::{ 69 | DataStream, NumBytes, Read, ReadError, Write, WriteError, 70 | }; 71 | 72 | mod crypto; 73 | pub use self::crypto::{ 74 | Checksum160, Checksum256, Checksum512, PrivateKey, PublicKey, Signature, 75 | }; 76 | 77 | #[macro_use] 78 | mod name; 79 | pub use self::name::Name; 80 | pub use eosio_numstr::{ParseNameError, NAME_CHARS, NAME_MAX_LEN}; 81 | 82 | mod ops; 83 | pub use self::ops::{ 84 | CheckedAdd, CheckedDiv, CheckedMul, CheckedRem, CheckedSub, 85 | }; 86 | 87 | mod producer_schedule; 88 | pub use self::producer_schedule::*; 89 | 90 | mod resources; 91 | pub use self::resources::{CpuWeight, NetWeight, RamBytes}; 92 | 93 | mod symbol; 94 | pub use self::symbol::{ExtendedSymbol, Symbol, SymbolCode}; 95 | pub use eosio_numstr::{ 96 | ParseSymbolCodeError, ParseSymbolError, SYMBOL_CODE_CHARS, 97 | SYMBOL_CODE_MAX_LEN, 98 | }; 99 | 100 | mod table; 101 | pub use self::table::{ 102 | PrimaryTableIndex, ScopeName, SecondaryKey, SecondaryKeys, 103 | SecondaryTableIndex, SecondaryTableName, Table, TableName, 104 | }; 105 | 106 | mod time; 107 | pub use self::time::{BlockTimestamp, TimePoint, TimePointSec}; 108 | 109 | mod transaction; 110 | pub use self::transaction::{ 111 | Transaction, TransactionExtension, TransactionHeader, TransactionId, 112 | }; 113 | 114 | mod varint; 115 | pub use self::varint::{SignedInt, UnsignedInt}; 116 | -------------------------------------------------------------------------------- /examples/tictactoe/tictactoe.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "____comment": "This file was generated by eosio-abigen. DO NOT EDIT - 2018-07-06T13:38:01", 3 | "version": "eosio::abi/1.0", 4 | "types": [], 5 | "structs": [ 6 | { 7 | "name": "game", 8 | "base": "", 9 | "fields": [ 10 | { 11 | "name": "host", 12 | "type": "name" 13 | }, 14 | { 15 | "name": "challenger", 16 | "type": "name" 17 | }, 18 | { 19 | "name": "turn", 20 | "type": "uint8" 21 | }, 22 | { 23 | "name": "winner", 24 | "type": "uint8" 25 | }, 26 | { 27 | "name": "board", 28 | "type": "uint8[]" 29 | } 30 | ] 31 | }, 32 | { 33 | "name": "create", 34 | "base": "", 35 | "fields": [ 36 | { 37 | "name": "host", 38 | "type": "name" 39 | }, 40 | { 41 | "name": "challenger", 42 | "type": "name" 43 | } 44 | ] 45 | }, 46 | { 47 | "name": "restart", 48 | "base": "", 49 | "fields": [ 50 | { 51 | "name": "host", 52 | "type": "name" 53 | }, 54 | { 55 | "name": "challenger", 56 | "type": "name" 57 | }, 58 | { 59 | "name": "by", 60 | "type": "uint8" 61 | } 62 | ] 63 | }, 64 | { 65 | "name": "close", 66 | "base": "", 67 | "fields": [ 68 | { 69 | "name": "host", 70 | "type": "name" 71 | }, 72 | { 73 | "name": "challenger", 74 | "type": "name" 75 | } 76 | ] 77 | }, 78 | { 79 | "name": "makemove", 80 | "base": "", 81 | "fields": [ 82 | { 83 | "name": "host", 84 | "type": "name" 85 | }, 86 | { 87 | "name": "challenger", 88 | "type": "name" 89 | }, 90 | { 91 | "name": "by", 92 | "type": "uint8" 93 | }, 94 | { 95 | "name": "row", 96 | "type": "uint16" 97 | }, 98 | { 99 | "name": "column", 100 | "type": "uint16" 101 | } 102 | ] 103 | } 104 | ], 105 | "actions": [ 106 | { 107 | "name": "create", 108 | "type": "create", 109 | "ricardian_contract": "" 110 | }, 111 | { 112 | "name": "restart", 113 | "type": "restart", 114 | "ricardian_contract": "" 115 | }, 116 | { 117 | "name": "close", 118 | "type": "close", 119 | "ricardian_contract": "" 120 | }, 121 | { 122 | "name": "makemove", 123 | "type": "makemove", 124 | "ricardian_contract": "" 125 | } 126 | ], 127 | "tables": [ 128 | { 129 | "name": "games", 130 | "index_type": "i64", 131 | "key_names": ["challenger"], 132 | "key_types": ["name"], 133 | "type": "game" 134 | } 135 | ], 136 | "ricardian_clauses": [], 137 | "error_messages": [], 138 | "abi_extensions": [] 139 | } 140 | -------------------------------------------------------------------------------- /crates/eosio/src/blockchain_parameters.rs: -------------------------------------------------------------------------------- 1 | //! 2 | use crate::bytes::{NumBytes, Read, Write}; 3 | use alloc::string::String; 4 | 5 | /// Tunable blockchain configuration that can be changed via consensus 6 | #[derive( 7 | Read, Write, NumBytes, Clone, Default, Debug, PartialEq, PartialOrd, 8 | )] 9 | #[eosio(crate_path = "crate::bytes")] 10 | pub struct ChainId(String); 11 | 12 | /// Tunable blockchain configuration that can be changed via consensus 13 | #[derive( 14 | Read, Write, NumBytes, Clone, Default, Debug, PartialEq, PartialOrd, 15 | )] 16 | #[eosio(crate_path = "crate::bytes")] 17 | pub struct BlockchainParameters { 18 | /// The maximum net usage in instructions for a block 19 | pub max_block_net_usage: u64, 20 | /// The target percent (1% == 100, 100% == 10,000) of maximum net usage; 21 | /// exceeding this triggers congestion handling 22 | pub target_block_net_usage_pct: u32, 23 | /// The maximum objectively measured net usage that the chain will 24 | /// allow regardless of account limits 25 | pub max_transaction_net_usage: u32, 26 | /// The base amount of net usage billed for a transaction to cover 27 | /// incidentals 28 | pub base_per_transaction_net_usage: u32, 29 | /// The amount of net usage leeway available whilst executing a 30 | /// transaction (still checks against new limits wihout leeway at the end 31 | /// of the transaction) 32 | pub net_usage_leeway: u32, 33 | /// The numerator for the discount on net usage of context-free data 34 | pub context_free_discount_net_usage_num: u32, 35 | /// The denominator for the discount on net usage of context-free data 36 | pub context_free_discount_net_usage_den: u32, 37 | /// The maximum billable cpu usage (in microseconds) for a block 38 | pub max_block_cpu_usage: u32, 39 | /// The target percent (1% == 100, 100% == 10,000) of maximum cpu usage; 40 | /// exceeding this triggers congestion handling 41 | pub target_block_cpu_usage_pct: u32, 42 | /// The maximum billable cpu usage (in microseconds) that the chain will 43 | /// allow regardless of account limits 44 | pub max_transaction_cpu_usage: u32, 45 | /// The minimum billable cpu usage (in microseconds) that the chain 46 | /// requires 47 | pub min_transaction_cpu_usage: u32, 48 | /// Maximum lifetime of a transaction 49 | pub max_transaction_lifetime: u32, 50 | /// The number of seconds after the time a deferred transaction can first 51 | /// execute until it expires 52 | pub deferred_trx_expiration_window: u32, 53 | /// The maximum number of seconds that can be imposed as a delay 54 | /// requirement by authorization checks 55 | pub max_transaction_delay: u32, 56 | /// Maximum size of inline action 57 | pub max_inline_action_size: u32, 58 | /// Maximum depth of inline action 59 | pub max_inline_action_depth: u16, 60 | /// Maximum authority depth 61 | pub max_authority_depth: u16, 62 | } 63 | 64 | impl AsRef for BlockchainParameters { 65 | fn as_ref(&self) -> &Self { 66 | self 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /contracts/eosio_forum/src/lib.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use eosio_cdt::*; 3 | 4 | #[eosio::action] 5 | pub fn propose( 6 | proposer: AccountName, 7 | proposal_name: Name, 8 | title: String, 9 | proposal_json: String, 10 | expires_at: TimePointSec, 11 | ) { 12 | } 13 | 14 | #[eosio::action] 15 | pub fn expire(proposal_name: Name) {} 16 | 17 | #[eosio::action] 18 | pub fn vote( 19 | voter: AccountName, 20 | proposal_name: Name, 21 | vote: u8, 22 | vote_json: String, 23 | ) { 24 | } 25 | 26 | #[eosio::action] 27 | pub fn unvote(voter: AccountName, proposal_name: Name) {} 28 | 29 | #[eosio::action] 30 | pub fn clnproposal(proposal_name: Name, max_count: u64) {} 31 | 32 | #[eosio::action] 33 | pub fn post( 34 | poster: AccountName, 35 | post_uuid: String, 36 | content: String, 37 | reply_to_poster: AccountName, 38 | reply_to_poster_uuid: String, 39 | certify: bool, 40 | json_metadata: String, 41 | ) { 42 | } 43 | 44 | #[eosio::action] 45 | pub fn unpost(poster: AccountName, post_uuid: String) {} 46 | 47 | #[eosio::action] 48 | pub fn status(account: AccountName, content: String) {} 49 | 50 | const FREEZE_PERIOD_IN_SECONDS: u32 = 3 * 24 * 60 * 60; 51 | const SIX_MONTHS_IN_SECONDS: u32 = 52 | (6.0 * (365.25 / 12.0) * 24.0 * 60.0 * 60.0) as u32; 53 | 54 | fn compute_by_proposal_key(proposal_name: Name, voter: AccountName) -> u128 { 55 | u128::from(proposal_name.as_u64()) << 64 | u128::from(voter.as_u64()) 56 | } 57 | 58 | fn compute_by_voter_key(proposal_name: Name, voter: AccountName) -> u128 { 59 | u128::from(voter.as_u64()) << 64 | u128::from(voter.as_u64()) 60 | } 61 | 62 | #[eosio::table("proposal")] 63 | pub struct ProposalRow { 64 | #[eosio(primary_key)] 65 | proposal_name: Name, 66 | #[eosio(secondary_key)] 67 | proposer: AccountName, 68 | title: String, 69 | proposal_json: String, 70 | created_at: TimePointSec, 71 | expires_at: TimePointSec, 72 | } 73 | 74 | impl ProposalRow { 75 | fn is_expired(&self) -> bool { 76 | current_time_point_sec() >= self.expires_at 77 | } 78 | 79 | fn can_be_cleaned_up(&self) -> bool { 80 | current_time_point_sec() > self.expires_at + FREEZE_PERIOD_IN_SECONDS 81 | } 82 | } 83 | 84 | #[derive(Read, Write, NumBytes)] 85 | pub struct VoteRow { 86 | id: u64, 87 | proposal_name: Name, 88 | voter: AccountName, 89 | vote: u8, 90 | vote_json: String, 91 | updated_at: TimePointSec, 92 | } 93 | 94 | impl Table for VoteRow { 95 | type Row = Self; 96 | 97 | const NAME: TableName = TableName::new(n!("vote")); 98 | 99 | fn primary_key(row: &Self::Row) -> u64 { 100 | row.id 101 | } 102 | 103 | fn secondary_keys(row: &Self::Row) -> SecondaryKeys { 104 | ( 105 | compute_by_proposal_key(row.proposal_name, row.voter), 106 | compute_by_voter_key(row.proposal_name, row.voter), 107 | ) 108 | .into() 109 | } 110 | } 111 | 112 | #[eosio::table("status")] 113 | pub struct StatusRow { 114 | #[eosio(primary_key)] 115 | account: AccountName, 116 | content: String, 117 | updated_at: TimePointSec, 118 | } 119 | -------------------------------------------------------------------------------- /crates/eosio_cdt_sys/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | command_exists () { 4 | type "$1" &> /dev/null ; 5 | } 6 | 7 | if ! command_exists bindgen; then 8 | cargo install bindgen 9 | fi 10 | 11 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 12 | pushd ${DIR} 13 | bindgen \ 14 | --use-core \ 15 | --distrust-clang-mangling \ 16 | --no-layout-tests \ 17 | --output src/bindings.rs \ 18 | --ctypes-prefix crate \ 19 | --with-derive-default \ 20 | --with-derive-eq \ 21 | --with-derive-hash \ 22 | --with-derive-ord \ 23 | --with-derive-partialeq \ 24 | --with-derive-partialord \ 25 | --impl-debug \ 26 | --impl-partialeq \ 27 | --whitelist-function action_data_size \ 28 | --whitelist-function current_receiver \ 29 | --whitelist-function has_auth \ 30 | --whitelist-function is_account \ 31 | --whitelist-function publication_time \ 32 | --whitelist-function read_action_data \ 33 | --whitelist-function require_auth \ 34 | --whitelist-function require_auth2 \ 35 | --whitelist-function require_recipient \ 36 | --whitelist-function send_context_free_inline \ 37 | --whitelist-function send_inline \ 38 | --whitelist-function get_active_producers \ 39 | --whitelist-function assert_recover_key \ 40 | --whitelist-function assert_ripemd160 \ 41 | --whitelist-function assert_sha1 \ 42 | --whitelist-function assert_sha256 \ 43 | --whitelist-function assert_sha512 \ 44 | --whitelist-function recover_key \ 45 | --whitelist-function ripemd160 \ 46 | --whitelist-function sha1 \ 47 | --whitelist-function sha256 \ 48 | --whitelist-function sha512 \ 49 | --whitelist-function db_.+ \ 50 | --whitelist-function check_permission_authorization \ 51 | --whitelist-function check_transaction_authorization \ 52 | --whitelist-function get_account_creation_time \ 53 | --whitelist-function get_permission_last_used \ 54 | --whitelist-function print.* \ 55 | --whitelist-function get_blockchain_parameters_packed \ 56 | --whitelist-function get_resource_limits \ 57 | --whitelist-function is_privileged \ 58 | --whitelist-function set_blockchain_parameters_packed \ 59 | --whitelist-function set_privileged \ 60 | --whitelist-function set_proposed_producers \ 61 | --whitelist-function set_resource_limits \ 62 | --whitelist-function current_time \ 63 | --whitelist-function eosio_.+ \ 64 | --whitelist-function cancel_deferred \ 65 | --whitelist-function expiration \ 66 | --whitelist-function get_action \ 67 | --whitelist-function get_context_free_data \ 68 | --whitelist-function read_transaction \ 69 | --whitelist-function send_deferred \ 70 | --whitelist-function tapos_.+ \ 71 | --whitelist-function transaction_size \ 72 | --whitelist-function get_sender \ 73 | --whitelist-function preactivate_feature \ 74 | --whitelist-function is_feature_activated \ 75 | --whitelist-type capi_name \ 76 | --whitelist-type capi_public_key \ 77 | --whitelist-type capi_signature \ 78 | --whitelist-type capi_checksum256 \ 79 | --whitelist-type capi_checksum160 \ 80 | --whitelist-type capi_checksum512 \ 81 | wrapper.hpp \ 82 | -- \ 83 | -I ./eosio.cdt/libraries \ 84 | --std=c++14 85 | popd 86 | -------------------------------------------------------------------------------- /examples/addressbook/src/lib.rs: -------------------------------------------------------------------------------- 1 | use eosio::*; 2 | use eosio_cdt::*; 3 | 4 | eosio::abi!(add, update, erase, like, likezip); 5 | 6 | #[eosio::table("address")] 7 | struct Address { 8 | #[eosio(primary_key)] 9 | account: AccountName, 10 | first_name: String, 11 | last_name: String, 12 | street: String, 13 | city: String, 14 | state: String, 15 | #[eosio(secondary_key)] 16 | zip: u32, 17 | liked: u64, 18 | } 19 | 20 | #[eosio::action] 21 | fn add( 22 | account: AccountName, 23 | first_name: String, 24 | last_name: String, 25 | street: String, 26 | city: String, 27 | state: String, 28 | zip: u32, 29 | ) { 30 | require_auth(account); 31 | 32 | let code = current_receiver(); 33 | let table = Address::table(code, code); 34 | 35 | let address = table.find(account); 36 | assert!(address.is_none(), "Address for account already exists"); 37 | 38 | let address = Address { 39 | account, 40 | first_name, 41 | last_name, 42 | street, 43 | city, 44 | state, 45 | zip, 46 | liked: 0, 47 | }; 48 | table.emplace(account, address).expect("write"); 49 | } 50 | 51 | #[eosio::action] 52 | fn update( 53 | account: AccountName, 54 | first_name: String, 55 | last_name: String, 56 | street: String, 57 | city: String, 58 | state: String, 59 | zip: u32, 60 | ) { 61 | require_auth(account); 62 | 63 | let code = current_receiver(); 64 | let table = Address::table(code, code); 65 | let cursor = table.find(account).expect("Address for account not found"); 66 | 67 | let mut address = cursor.get().expect("read"); 68 | address.first_name = first_name; 69 | address.last_name = last_name; 70 | address.street = street; 71 | address.city = city; 72 | address.state = state; 73 | address.zip = zip; 74 | 75 | cursor.modify(Payer::Same, address).expect("write"); 76 | } 77 | 78 | #[eosio::action] 79 | fn erase(account: AccountName) { 80 | require_auth(account); 81 | 82 | let code = current_receiver(); 83 | let addresses = Address::table(code, code); 84 | let cursor = addresses 85 | .find(account) 86 | .expect("Address for account not found"); 87 | 88 | cursor.erase().expect("read"); 89 | } 90 | 91 | #[eosio::action] 92 | fn like(account: AccountName) { 93 | let code = current_receiver(); 94 | let addresses = Address::table(code, code); 95 | let cursor = addresses 96 | .find(account) 97 | .expect("Address for account not found"); 98 | 99 | let mut address = cursor.get().expect("read"); 100 | address.liked += 1; 101 | cursor 102 | .modify(Payer::New(address.account), address) 103 | .expect("write"); 104 | } 105 | 106 | #[eosio::action] 107 | fn likezip(zip: u32) { 108 | let code = current_receiver(); 109 | let table = Address::by_zip(code, code); 110 | for cursor in table.lower_bound(zip).into_iter() { 111 | let mut addr = cursor.get().expect("read"); 112 | if addr.zip != zip { 113 | break; 114 | } 115 | addr.liked += 1; 116 | cursor.modify(Payer::Same, addr).expect("write"); 117 | } 118 | } 119 | --------------------------------------------------------------------------------