Skip to content

Commit

Permalink
Merge branch 'dev' into maturin_build
Browse files Browse the repository at this point in the history
  • Loading branch information
bingyanglin authored Feb 26, 2021
2 parents 9268f6f + 12fcb20 commit 8c824d4
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 104 deletions.
2 changes: 1 addition & 1 deletion bindings/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -912,4 +912,4 @@ metrics_dto = {
'sent_heartbeats': int,
'dropped_packets': int,
}
```
```
2 changes: 1 addition & 1 deletion bindings/python/examples/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def main():

print('get_addresses')
address_changed_list = client.get_addresses(
seed=SEED, account_index=0, begin=0, end=10, get_all=True)
seed=SEED, account_index=0, input_range_begin=0, input_range_end=10, get_all=True)
print(f'address_changed list: {address_changed_list}')

# Get the (address, changed ) for the first found address
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/native/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct Client {
pub client: RustClient,
}

/// An instance of the client using IRI URI.
/// An instance of the client using IOTA node URI.
#[pymethods]
impl Client {
#[new]
Expand Down
8 changes: 8 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,11 @@ path = "peers.rs"
[[example]]
name = "message_time"
path = "message_time.rs"

[[example]]
name = "send_all"
path = "send_all.rs"

[[example]]
name = "split_all"
path = "split_all.rs"
57 changes: 57 additions & 0 deletions examples/send_all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example send_all --release
use iota::{client::Result, Client, MessageId, Seed};
use std::time::Duration;
use tokio::time::sleep;
extern crate dotenv;
use dotenv::dotenv;
use std::env;

/// In this example, we get the balance of the first account of the seed and send everything
// Todo: automatically detect amount of inputs and if > 127 create multiple transactions

#[tokio::main]
async fn main() -> Result<()> {
let iota = Client::builder() // Crate a client instance builder
.with_node("http://api.lb-0.testnet.chrysalis2.com")?
.finish()
.await?;

// Insert your seed in the .env. Since the output amount cannot be zero. The seed must contain non-zero balance.
println!("This example uses dotenv, which is not safe for use in production.");
dotenv().ok();
let seed_1 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap())?)?;

let total_balance = iota.get_balance(&seed_1).with_initial_address_index(0).finish().await?;
println!("total_balance {}", total_balance);
let message = iota
.message()
.with_seed(&seed_1)
.with_output(
&"atoi1qzt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupx3y7x0r".into(),
total_balance,
)?
.with_initial_address_index(0)
.finish()
.await?;
println!(
"Transaction sent: https://explorer.iota.org/chrysalis/message/{}",
message.id().0
);
reattach_promote_until_confirmed(message.id().0, &iota).await;
Ok(())
}

async fn reattach_promote_until_confirmed(message_id: MessageId, iota: &Client) {
while let Ok(metadata) = iota.get_message().metadata(&message_id).await {
if let Some(state) = metadata.ledger_inclusion_state {
println!("Leder inclusion state: {:?}", state);
break;
} else if let Ok(msg_id) = iota.reattach(&message_id).await {
println!("Reattached or promoted {}", msg_id.0);
}
sleep(Duration::from_secs(5)).await;
}
}
70 changes: 70 additions & 0 deletions examples/split_all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example split_all --release
use iota::{client::Result, Client, MessageId, Seed};
use std::time::Duration;
use tokio::time::sleep;
extern crate dotenv;
use dotenv::dotenv;
use std::env;

/// In this example, we get the balance of the first account of the seed and send everything splitted to the second seed
#[tokio::main]
async fn main() -> Result<()> {
let iota = Client::builder() // Crate a client instance builder
.with_node("http://api.lb-0.testnet.chrysalis2.com")?
.finish()
.await?;

// Insert your seed in the .env. Since the output amount cannot be zero. The seed must contain non-zero balance.
println!("This example uses dotenv, which is not safe for use in production.");
dotenv().ok();
let seed_1 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap())?)?;
let seed_2 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap())?)?;

let total_balance = iota.get_balance(&seed_1).finish().await?;
let mut available = total_balance;
println!("total_balance {}", total_balance);
let addresses_from_seed_2 = iota
.get_addresses(&seed_2)
.with_range(0..available as usize / 1_000_000)
.finish()
.await?;
let mut message_builder = iota.message().with_seed(&seed_1);
for i in 0..total_balance / 1_000_000 {
let mut amount = 1_000_000;
// Don't add more than we have or is allowed; 1 less here for remaining iotas
if available == 0 || i > 125 {
break;
}
available -= amount;
// Add last amount so we don't create dust
if available < amount {
amount += available;
available = 0;
}
message_builder = message_builder.with_output(&addresses_from_seed_2[i as usize], amount)?;
}

let message = message_builder.finish().await?;
println!(
"Transaction sent: https://explorer.iota.org/chrysalis/message/{}",
message.id().0
);
reattach_promote_until_confirmed(message.id().0, &iota).await;
Ok(())
}

async fn reattach_promote_until_confirmed(message_id: MessageId, iota: &Client) {
while let Ok(metadata) = iota.get_message().metadata(&message_id).await {
if let Some(state) = metadata.ledger_inclusion_state {
println!("Leder inclusion state: {:?}", state);
break;
} else if let Ok(msg_id) = iota.reattach(&message_id).await {
println!("Reattached or promoted {}", msg_id.0);
}
sleep(Duration::from_secs(5)).await;
}
}
95 changes: 34 additions & 61 deletions examples/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

//! cargo run --example transaction --release
use iota::{Client, MessageId, Seed};
use iota::{client::Result, Client, MessageId, Seed};
use std::time::Duration;
use tokio::time::sleep;
extern crate dotenv;
Expand All @@ -21,115 +21,88 @@ use std::env;
///
///
/// Then we send 6_000_000 tokens from the second seed to the first one
/// to addresses "atoi1qpnrumvaex24dy0duulp4q07lpa00w20ze6jfd0xly422kdcjxzakzsz5kf" and
/// "atoi1qzu7dnlfld2p0rhld20nr6axdnl0katmwu59fprwcnahglmnvgpwjsc20jg", and check the ledger
/// inclusion state, which should be "included".
/// to addresses "atoi1qpnrumvaex24dy0duulp4q07lpa00w20ze6jfd0xly422kdcjxzakzsz5kf" (index 1) and
/// "atoi1qz4sfmp605vnj6fxt0sf0cwclffw5hpxjqkf6fthyd74r9nmmu337m3lwl2" (index 2), and check the ledger
/// inclusion state, which should be "Some(Included)".
#[tokio::main]
async fn main() {
async fn main() -> Result<()> {
let explorer_url = "https://explorer.iota.org/chrysalis/message/";
let iota = Client::builder() // Crate a client instance builder
.with_node("http://localhost:14265") // Insert the node here
.unwrap()
.with_node("http://api.lb-0.testnet.chrysalis2.com")? // Insert the node here
.with_node_sync_disabled()
.finish()
.await
.unwrap();
.await?;

// Insert your seed in the .env. Since the output amount cannot be zero. The seed must contain non-zero balance.
// First address from the seed in the .env is iot1qxt0nhsf38nh6rs4p6zs5knqp6psgha9wsv74uajqgjmwc75ugupxgecea4
println!("This example uses dotenv, which is not safe for use in production.");
dotenv().ok();
let seed =
Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap()).unwrap()).unwrap();
let seed_1 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_1").unwrap())?)?;
let seed_2 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap())?)?;

let message = iota
.message()
.with_seed(&seed)
.with_seed(&seed_1)
// Insert the output address and amount to spent. The amount cannot be zero.
.with_output(
&"atoi1qzj8s3kpacr6kmh05sxul4zp0xqulzn2vy9rznqj6rrc4nwd304pk6w523x".into(),
&iota.get_addresses(&seed_2).with_range(0..1).finish().await?[0],
3_000_000,
)
.unwrap()
)?
.finish()
.await
.unwrap();
.await?;

println!(
"First transaction sent: http://127.0.0.1:14265/api/v1/messages/{}",
message.id().0
);
println!("First transaction sent: {}{}", explorer_url, message.id().0);
reattach_promote_until_confirmed(message.id().0, &iota).await;

let message = iota
.message()
.with_seed(&seed)
// Insert the output address and amount to spent. The amount cannot be zero.
.with_seed(&seed_1)
.with_output(
&"atoi1qzu7dnlfld2p0rhld20nr6axdnl0katmwu59fprwcnahglmnvgpwjsc20jg".into(),
&iota.get_addresses(&seed_2).with_range(1..2).finish().await?[0],
3_000_000,
)
.unwrap()
)?
.finish()
.await
.unwrap();
.await?;

println!(
"Second transaction sent: http://127.0.0.1:14265/api/v1/messages/{}",
message.id().0
);
println!("Second transaction sent: {}{}", explorer_url, message.id().0);
reattach_promote_until_confirmed(message.id().0, &iota).await;

let message = iota
.message()
.with_seed(&seed)
// Insert the output address and amount to spent. The amount cannot be zero.
.with_seed(&seed_1)
.with_output(
&"atoi1qz0vue67w2e2wjk9jh07s7wfgxmsxgy9ssctn3nntyf9uqd6qs3zsp0k73u".into(),
&iota.get_addresses(&seed_2).with_range(2..3).finish().await?[0],
3_000_000,
)
.unwrap()
)?
.finish()
.await
.unwrap();
println!(
"Third transaction sent: http://127.0.0.1:14265/api/v1/messages/{}",
message.id().0
);
.await?;
println!("Third transaction sent: {}{}", explorer_url, message.id().0);
reattach_promote_until_confirmed(message.id().0, &iota).await;

let seed =
Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap()).unwrap()).unwrap();

let message = iota
.message()
.with_seed(&seed)
// Insert the output address and amount to spent. The amount cannot be zero.
.with_seed(&seed_2)
// Note that we can transfer to multiple outputs by using the `SendTransactionBuilder`
.with_output(
&"atoi1qzj8s3kpacr6kmh05sxul4zp0xqulzn2vy9rznqj6rrc4nwd304pk6w523x".into(),
&iota.get_addresses(&seed_1).with_range(1..2).finish().await?[0],
3_000_000,
)
.unwrap()
)?
.with_output(
&"atoi1qzu7dnlfld2p0rhld20nr6axdnl0katmwu59fprwcnahglmnvgpwjsc20jg".into(),
&iota.get_addresses(&seed_1).with_range(2..3).finish().await?[0],
3_000_000,
)
.unwrap()
)?
.finish()
.await
.unwrap();
.await?;

println!(
"Last transaction sent: http://127.0.0.1:14265/api/v1/messages/{}",
message.id().0
);
println!("Last transaction sent: {}{}", explorer_url, message.id().0);
reattach_promote_until_confirmed(message.id().0, &iota).await;
let message_metadata = iota.get_message().metadata(&message.id().0).await;
println!(
"The ledgerInclusionState: {:?}",
message_metadata.unwrap().ledger_inclusion_state
message_metadata?.ledger_inclusion_state
);
Ok(())
}

async fn reattach_promote_until_confirmed(message_id: MessageId, iota: &Client) {
Expand Down
10 changes: 5 additions & 5 deletions iota-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ name = "iota_client"
# bee-pow = { git = "https://github.com/iotaledger/bee.git", branch = "chrysalis-pt-2" }
# bee-common-derive = { git = "https://github.com/iotaledger/bee.git", branch = "dev" }
# bee-crypto = { git = "https://github.com/iotaledger/bee.git", branch = "dev" }
bee-rest-api = { git = "https://github.com/iotaledger/bee.git", rev = "8ee15fbc064b2aa1a506fa7ac5d88b5073e5d0f7" }
bee-message = { git = "https://github.com/iotaledger/bee.git", rev = "8ee15fbc064b2aa1a506fa7ac5d88b5073e5d0f7" }
bee-pow = { git = "https://github.com/iotaledger/bee.git", rev = "8ee15fbc064b2aa1a506fa7ac5d88b5073e5d0f7" }
bee-rest-api = { git = "https://github.com/iotaledger/bee.git", rev = "ce3bd4e1b1ba423c8268e435dcc98c90c397379e" }
bee-message = { git = "https://github.com/iotaledger/bee.git", rev = "ce3bd4e1b1ba423c8268e435dcc98c90c397379e" }
bee-pow = { git = "https://github.com/iotaledger/bee.git", rev = "ce3bd4e1b1ba423c8268e435dcc98c90c397379e" }
bee-common = { git = "https://github.com/iotaledger/bee.git", branch = "dev" }
bee-common-derive = { git = "https://github.com/iotaledger/bee.git", rev = "c42171ff33c80cc2efb183e244dc79b7f58d9ac4" }
bee-crypto = { git = "https://github.com/iotaledger/bee.git", rev = "c42171ff33c80cc2efb183e244dc79b7f58d9ac4" }
iota-crypto = { git = "https://github.com/iotaledger/crypto.rs.git", rev = "6e67b652dd55df05877f575b9a09ccb5a7006694", features = ["ed25519", "random"]}
iota-crypto = { git = "https://github.com/iotaledger/crypto.rs", rev = "09ff1a94d6a87838589ccf1b874cfa3283a00f26", features = ["blake2b", "ed25519", "random"] }
slip10 = "0.4"
reqwest = { version = "0.11", features = ["json", "rustls-tls", "blocking"], default-features = false }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.58"
chrono = { version = "0.4", features = ["serde"] }
hex = "0.4.2"
blake2 = "0.9"
tokio = { version = "1.1", features = ["macros", "sync", "rt-multi-thread"] }
thiserror = "1.0"
num_cpus = "1.13"
Expand Down
14 changes: 3 additions & 11 deletions iota-client/src/api/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
use crate::{Client, Error, Result, Seed};

use bee_message::prelude::{Address, Bech32Address, Ed25519Address};
use blake2::{
digest::{Update, VariableOutput},
VarBlake2b,
};
use core::convert::TryInto;
use crypto::hashes::{blake2b::Blake2b256, Digest};
use slip10::BIP32Path;
use std::ops::Range;

Expand Down Expand Up @@ -110,17 +107,12 @@ fn generate_address(seed: &Seed, path: &mut BIP32Path, index: usize, internal: b

let public_key = seed.generate_private_key(path)?.public_key().to_compressed_bytes();
// Hash the public key to get the address
let mut hasher = VarBlake2b::new(32).unwrap();
hasher.update(public_key);
let mut result: [u8; 32] = [0; 32];
hasher.finalize_variable(|res| {
result = res.try_into().expect("Invalid Length of Public Key");
});
let result = Blake2b256::digest(&public_key);

path.pop();
path.pop();

Ok(Address::Ed25519(Ed25519Address::new(result)))
Ok(Address::Ed25519(Ed25519Address::new(result.try_into().unwrap())))
}

/// Function to find the index and public or internal type of an Bech32 encoded address
Expand Down
Loading

0 comments on commit 8c824d4

Please sign in to comment.