forked from iotaledger/iota.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_max_dust.rs
124 lines (106 loc) · 4.24 KB
/
create_max_dust.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
//! cargo run --example create_max_dust --release
use iota_client::{
bee_message::prelude::{Essence, Output, Payload, UtxoInput},
Client, Result, Seed,
};
extern crate dotenv;
use dotenv::dotenv;
use std::env;
/// In this example we will create 100 dust outputs on the first address of the second seed
/// For this example you need to have >100 Mi on the first address before you run it
/// because we send transactions in parallel
#[tokio::main]
async fn main() -> Result<()> {
// Create a client instance
let iota = Client::builder()
.with_node("https://api.lb-0.testnet.chrysalis2.com")?
.finish()
.await?;
// 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())?);
let seed_2 = Seed::from_bytes(&hex::decode(env::var("NONSECURE_USE_OF_DEVELOPMENT_SEED_2").unwrap())?);
let new_address = iota.get_addresses(&seed_2).with_range(0..1).finish().await?;
let dust_allowance_message = iota
.message()
.with_seed(&seed)
.with_dust_allowance_output(&new_address[0], 10_000_000)?
.finish()
.await?;
let _ = iota
.retry_until_included(&dust_allowance_message.id().0, None, None)
.await?;
// Split funds to own addresses
let addresses = iota
.get_addresses(&seed)
// We start from index 1 so we can send remaining balance to the address with index 0
.with_range(1..101)
.finish()
.await?;
let mut message_builder = iota.message().with_seed(&seed);
for address in addresses {
message_builder = message_builder.with_output(&address, 1_000_001)?;
}
let message = message_builder.finish().await?;
println!(
"First transaction sent: https://explorer.iota.org/testnet/message/{}",
message.id().0
);
let _ = iota.retry_until_included(&message.id().0, None, None).await?;
// At this point we have 100 Mi on 100 addresses and we will just send it to the final address
// We use the outputs directly so we don't double spend them
let mut initial_outputs = Vec::new();
if let Some(Payload::Transaction(tx)) = message.payload() {
let Essence::Regular(essence) = tx.essence();
for (index, output) in essence.outputs().iter().enumerate() {
// Only include 1 Mi outputs, otherwise it fails for the remainder address
if let Output::SignatureLockedSingle(output) = output {
if output.amount() == 1_000_001 {
initial_outputs.push(UtxoInput::new(tx.id(), index as u16)?);
}
}
}
}
let first_address_old_seed = iota.get_addresses(&seed).with_range(0..1).finish().await?;
let mut sent_messages = Vec::new();
for (index, output) in initial_outputs.into_iter().enumerate() {
let message_id = iota
.message()
.with_seed(&seed)
.with_input(output)
.with_input_range(1..101)
.with_output(&new_address[0], 1)?
// send remaining iotas back
.with_output(&first_address_old_seed[0], 1_000_000)?
.finish()
.await?
.id()
.0;
println!(
"Transaction {} sent: https://explorer.iota.org/testnet/message/{}",
index, message_id
);
sent_messages.push(message_id);
}
// only check last message, if this gets confirmed all other messages should also be confirmed
let _ = iota
.retry_until_included(&sent_messages.pop().unwrap(), None, None)
.await?;
// Send all funds back to first address
let total_balance = iota.get_balance(&seed).finish().await?;
println!("Total balance: {}", total_balance);
let message = iota
.message()
.with_seed(&seed)
.with_output(&first_address_old_seed[0], total_balance)?
.finish()
.await?;
println!(
"Final tx sent: https://explorer.iota.org/testnet/message/{}",
message.id().0
);
let _ = iota.retry_until_included(&message.id().0, None, None).await.unwrap();
Ok(())
}