Skip to content

Commit

Permalink
[documentation]: #6 Move the Rust examples to this repository
Browse files Browse the repository at this point in the history
Signed-off-by: 6r1d <[email protected]>
  • Loading branch information
6r1d committed Sep 12, 2023
1 parent 4100a65 commit bb9c5d9
Show file tree
Hide file tree
Showing 12 changed files with 562 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "iroha_2_examples"
version = "0.1.0"
edition = "2021"

[dependencies]
iroha = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
iroha_crypto = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
iroha_client = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
iroha_config = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
iroha_data_model = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
iroha_genesis = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }
test_network = { "git" = "https://github.com/hyperledger/iroha.git", branch = "iroha2-dev" }

eyre = "0.6.8"

serde = { version = "1.0.151", default-features = false }
serde_json = { version = "1.0.91", default-features = false }

tokio = "1.23.0"
19 changes: 19 additions & 0 deletions Rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Rust examples for Iroha 2

This directory contains the examples from the [Rust tutorial](https://hyperledger.github.io/iroha-2-docs/guide/rust.html#_2-configuring-iroha-2).

## Running the examples

To run the examples, you need to install [`cargo-nextest`](https://nexte.st/) first.

```bash
cargo install cargo-nextest
```

After it is installed, type:

```bash
cargo nextest run
```

You'll Cargo install the packages that are needed for the tests and the test code will run.
21 changes: 21 additions & 0 deletions Rust/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"PUBLIC_KEY": "ed01207233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0",
"PRIVATE_KEY": {
"digest_function": "ed25519",
"payload": "9ac47abf59b356e0bd7dcbbbb4dec080e302156a48ca907e47cb6aea1d32719e7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"
},
"ACCOUNT_ID": "alice@wonderland",
"BASIC_AUTH": {
"web_login": "mad_hatter",
"password": "ilovetea"
},
"TORII_API_URL": "http://127.0.0.1:8080/",
"TORII_TELEMETRY_URL": "http://127.0.0.1:8180/",
"TRANSACTION_TIME_TO_LIVE_MS": 100000,
"TRANSACTION_STATUS_TIMEOUT_MS": 15000,
"TRANSACTION_LIMITS": {
"max_instruction_number": 4096,
"max_wasm_size_bytes": 4194304
},
"ADD_TRANSACTION_NONCE": false
}
28 changes: 28 additions & 0 deletions Rust/examples/client_account_definition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use eyre::{Error};

fn main() {
account_definition_test()
.expect("Account definition example is expected to work correctly");

println!("Account definition example works!");
}

fn account_definition_test() -> Result<(), Error> {
// #region account_definition_comparison
use iroha_data_model::prelude::AccountId;

// Create an `iroha_data_model::AccountId` instance
// with a DomainId instance and a Domain ID for an account
let longhand_account_id = AccountId::new("white_rabbit".parse()?, "looking_glass".parse()?);
let account_id: AccountId = "white_rabbit@looking_glass"
.parse()
.expect("Valid, because the string contains no whitespace, has a single '@' character and is not empty after");

// Check that two ways to define an account match
assert_eq!(account_id, longhand_account_id);

// #endregion account_definition_comparison

// Finish the test successfully
Ok(())
}
68 changes: 68 additions & 0 deletions Rust/examples/client_account_registration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::fs::File;
use eyre::{Error, WrapErr};
use iroha_config::client::Configuration;

fn main() {
// #region rust_config_load
let config_loc = "../configs/client/config.json";
let file = File::open(config_loc)
.wrap_err("Unable to load the configuration file at `.....`")
.expect("Config file is loading normally.");
let config: Configuration = serde_json::from_reader(file)
.wrap_err("Failed to parse `../configs/client/config.json`")
.expect("Verified in tests");
// #endregion rust_config_load

account_registration_test(&config)
.expect("Account registration example is expected to work correctly");

println!("Account registration example works!");
}

fn account_registration_test(config: &Configuration) -> Result<(), Error> {
// #region register_account_crates
use iroha_client::client::Client;
use iroha_crypto::KeyPair;
use iroha_data_model::{
metadata::UnlimitedMetadata,
prelude::{Account, AccountId, InstructionBox, RegisterBox},
};
// #endregion register_account_crates

// Create an Iroha client
let iroha_client: Client = Client::new(&config)?;

// #region register_account_create
// Create an AccountId instance by providing the account and domain name
let account_id: AccountId = "white_rabbit@looking_glass"
.parse()
.expect("Valid, because the string contains no whitespace, has a single '@' character and is not empty after");
// #endregion register_account_create

// TODO: consider getting a key from white_rabbit
// Generate a new public key for a new account
let (public_key, _) = KeyPair::generate()
.expect("Failed to generate KeyPair")
.into();

// #region register_account_generate
// Generate a new account
let create_account = RegisterBox::new(Account::new(account_id, [public_key]));
// #endregion register_account_generate

// #region register_account_prepare_tx
// Prepare a transaction using the
// Account's RegisterBox
let metadata = UnlimitedMetadata::new();
let instructions: Vec<InstructionBox> = vec![create_account.into()];
let tx = iroha_client.build_transaction(instructions, metadata)?;
// #endregion register_account_prepare_tx

// #region register_account_submit_tx
// Submit a prepared account registration transaction
iroha_client.submit_transaction(&tx)?;
// #endregion register_account_submit_tx

// Finish the test successfully
Ok(())
}
78 changes: 78 additions & 0 deletions Rust/examples/client_asset_burning.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::fs::File;
use eyre::{Error, WrapErr};
use iroha_config::client::Configuration;

fn main() {
// #region rust_config_load
let config_loc = "../configs/client/config.json";
let file = File::open(config_loc)
.wrap_err("Unable to load the configuration file at `.....`")
.expect("Config file is loading normally.");
let config: Configuration = serde_json::from_reader(file)
.wrap_err("Failed to parse `../configs/client/config.json`")
.expect("Verified in tests");
// #endregion rust_config_load

asset_burning_test(&config)
.expect("Asset burning example is expected to work correctly");

println!("Asset burning example works!");
}

fn asset_burning_test(config: &Configuration) -> Result<(), Error> {
// #region burn_asset_crates
use std::str::FromStr;

use iroha_client::client::Client;
use iroha_data_model::{
prelude::{AccountId, AssetDefinitionId, AssetId, BurnBox, ToValue},
IdBox,
};
// #endregion burn_asset_crates

// Create an Iroha client
let iroha_client: Client = Client::new(&config)?;

// #region burn_asset_define_asset_account
// Define the instances of an Asset and Account
let roses = AssetDefinitionId::from_str("rose#wonderland")
.expect("Valid, because the string contains no whitespace, has a single '#' character and is not empty after");
let alice: AccountId = "alice@wonderland".parse()
.expect("Valid, because the string contains no whitespace, has a single '@' character and is not empty after");
// #endregion burn_asset_define_asset_account

// #region burn_asset_burn
// Burn the Asset instance
let burn_roses = BurnBox::new(
10_u32.to_value(),
IdBox::AssetId(AssetId::new(roses, alice)),
);
// #endregion burn_asset_burn

// #region burn_asset_submit_tx
iroha_client
.submit(burn_roses)
.wrap_err("Failed to submit transaction")?;
// #endregion burn_asset_submit_tx

// #region burn_asset_burn_alt
// Burn the Asset instance (alternate syntax).
// The syntax is `asset_name#asset_domain#account_name@account_domain`,
// or `roses.to_string() + "#" + alice.to_string()`.
// The `##` is a short-hand for the rose `which belongs to the same domain as the account
// to which it belongs to.
let burn_roses_alt = BurnBox::new(
10_u32.to_value(),
IdBox::AssetId("rose##alice@wonderland".parse()?),
);
// #endregion burn_asset_burn_alt

// #region burn_asset_submit_tx_alt
iroha_client
.submit(burn_roses_alt)
.wrap_err("Failed to submit transaction")?;
// #endregion burn_asset_submit_tx_alt

// Finish the test successfully
Ok(())
}
78 changes: 78 additions & 0 deletions Rust/examples/client_asset_minting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::fs::File;
use eyre::{Error, WrapErr};
use iroha_config::client::Configuration;

fn main() {
// #region rust_config_load
let config_loc = "../configs/client/config.json";
let file = File::open(config_loc)
.wrap_err("Unable to load the configuration file at `.....`")
.expect("Config file is loading normally.");
let config: Configuration = serde_json::from_reader(file)
.wrap_err("Failed to parse `../configs/client/config.json`")
.expect("Verified in tests");
// #endregion rust_config_load

asset_minting_test(&config)
.expect("Asset minting example is expected to work correctly");

println!("Asset minting example works!");
}

fn asset_minting_test(config: &Configuration) -> Result<(), Error> {
// #region mint_asset_crates
use std::str::FromStr;

use iroha_client::client::Client;
use iroha_data_model::{
prelude::{AccountId, AssetDefinitionId, AssetId, MintBox, ToValue},
IdBox,
};
// #endregion mint_asset_crates

// Create an Iroha client
let iroha_client: Client = Client::new(&config)?;

// Define the instances of an Asset and Account
// #region mint_asset_define_asset_account
let roses = AssetDefinitionId::from_str("rose#wonderland")
.expect("Valid, because the string contains no whitespace, has a single '#' character and is not empty after");
let alice: AccountId = "alice@wonderland".parse()
.expect("Valid, because the string contains no whitespace, has a single '@' character and is not empty after");
// #endregion mint_asset_define_asset_account

// Mint the Asset instance
// #region mint_asset_mint
let mint_roses = MintBox::new(
42_u32.to_value(),
IdBox::AssetId(AssetId::new(roses, alice)),
);
// #endregion mint_asset_mint

// #region mint_asset_submit_tx
iroha_client
.submit(mint_roses)
.wrap_err("Failed to submit transaction")?;
// #endregion mint_asset_submit_tx

// #region mint_asset_mint_alt
// Mint the Asset instance (alternate syntax).
// The syntax is `asset_name#asset_domain#account_name@account_domain`,
// or `roses.to_string() + "#" + alice.to_string()`.
// The `##` is a short-hand for the rose `which belongs to the same domain as the account
// to which it belongs to.
let mint_roses_alt = MintBox::new(
10_u32.to_value(),
IdBox::AssetId("rose##alice@wonderland".parse()?),
);
// #endregion mint_asset_mint_alt

// #region mint_asset_submit_tx_alt
iroha_client
.submit(mint_roses_alt)
.wrap_err("Failed to submit transaction")?;
// #endregion mint_asset_submit_tx_alt

// Finish the test successfully
Ok(())
}
69 changes: 69 additions & 0 deletions Rust/examples/client_asset_registration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::fs::File;
use eyre::{Error, WrapErr};
use iroha_config::client::Configuration;
use iroha_data_model::TryToValue;

fn main() {
// #region rust_config_load
let config_loc = "../configs/client/config.json";
let file = File::open(config_loc)
.wrap_err("Unable to load the configuration file at `.....`")
.expect("Config file is loading normally.");
let config: Configuration = serde_json::from_reader(file)
.wrap_err("Failed to parse `../configs/client/config.json`")
.expect("Verified in tests");
// #endregion rust_config_load

asset_registration_test(&config)
.expect("Asset registration example is expected to work correctly");

println!("Asset registration example works!");
}

fn asset_registration_test(config: &Configuration) -> Result<(), Error> {
// #region register_asset_crates
use std::str::FromStr as _;

use iroha_client::client::Client;
use iroha_data_model::prelude::{
AccountId, AssetDefinition, AssetDefinitionId, AssetId, IdBox, MintBox, RegisterBox,
};
// #endregion register_asset_crates

// Create an Iroha client
let iroha_client: Client = Client::new(&config)?;

// #region register_asset_create_asset
// Create an asset
let asset_def_id = AssetDefinitionId::from_str("time#looking_glass")
.expect("Valid, because the string contains no whitespace, has a single '#' character and is not empty after");
// #endregion register_asset_create_asset

// #region register_asset_init_submit
// Initialise the registration time
let register_time =
RegisterBox::new(AssetDefinition::fixed(asset_def_id.clone()).mintable_once());

// Submit a registration time
iroha_client.submit(register_time)?;
// #endregion register_asset_init_submit

// Create an account using the previously defined asset
let account_id: AccountId = "white_rabbit@looking_glass"
.parse()
.expect("Valid, because the string contains no whitespace, has a single '@' character and is not empty after");

// #region register_asset_mint_submit
// Create a MintBox using a previous asset and account
let mint = MintBox::new(
12.34_f64.try_to_value()?,
IdBox::AssetId(AssetId::new(asset_def_id, account_id)),
);

// Submit a minting transaction
iroha_client.submit_all([mint])?;
// #endregion register_asset_mint_submit

// Finish the test successfully
Ok(())
}
Loading

0 comments on commit bb9c5d9

Please sign in to comment.