-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcounter_contract_increment.rs
More file actions
137 lines (116 loc) · 4.6 KB
/
counter_contract_increment.rs
File metadata and controls
137 lines (116 loc) · 4.6 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
use std::{fs, path::Path, sync::Arc};
use miden_assembly::{
ast::{Module, ModuleKind},
LibraryPath,
};
use miden_client::{
account::Address,
builder::ClientBuilder,
keystore::FilesystemKeyStore,
rpc::{Endpoint, TonicRpcClient},
transaction::{TransactionKernel, TransactionRequestBuilder},
ClientError, ScriptBuilder,
};
use miden_objects::{assembly::Assembler, assembly::DefaultSourceManager};
fn create_library(
assembler: Assembler,
library_path: &str,
source_code: &str,
) -> Result<miden_assembly::Library, Box<dyn std::error::Error>> {
let source_manager = Arc::new(DefaultSourceManager::default());
let module = Module::parser(ModuleKind::Library).parse_str(
LibraryPath::new(library_path)?,
source_code,
&source_manager,
)?;
let library = assembler.clone().assemble_library([module])?;
Ok(library)
}
#[tokio::main]
async fn main() -> Result<(), ClientError> {
// Initialize client
let endpoint = Endpoint::testnet();
let timeout_ms = 10_000;
let rpc_api = Arc::new(TonicRpcClient::new(&endpoint, timeout_ms));
let keystore = FilesystemKeyStore::new("./keystore".into()).unwrap().into();
let mut client = ClientBuilder::new()
.rpc(rpc_api)
.authenticator(keystore)
.in_debug_mode(true.into())
.build()
.await?;
let sync_summary = client.sync_state().await.unwrap();
println!("Latest block: {}", sync_summary.block_num);
// -------------------------------------------------------------------------
// STEP 1: Read the Public State of the Counter Contract
// -------------------------------------------------------------------------
println!("\n[STEP 1] Reading data from public state");
// Define the Counter Contract account id from counter contract deploy
let (_network_id, address) =
Address::from_bech32("mtst1qrhk9zc2au2vxqzaynaz5ddhs4cqqghmajy").unwrap();
let counter_contract_id = match address {
Address::AccountId(account_id_address) => account_id_address.id(),
_ => panic!("Expected AccountId address"),
};
client
.import_account_by_id(counter_contract_id)
.await
.unwrap();
let counter_contract_details = client.get_account(counter_contract_id).await.unwrap();
let counter_contract = if let Some(account_record) = counter_contract_details {
// Clone the account to get an owned instance
let account = account_record.account().clone();
println!(
"Account details: {:?}",
account.storage().slots().first().unwrap()
);
account // Now returns an owned account
} else {
panic!("Counter contract not found!");
};
// -------------------------------------------------------------------------
// STEP 2: Call the Counter Contract with a script
// -------------------------------------------------------------------------
// Load the MASM script referencing the increment procedure
let script_path = Path::new("../masm/scripts/counter_script.masm");
let script_code = fs::read_to_string(script_path).unwrap();
let counter_path = Path::new("../masm/accounts/counter.masm");
let counter_code = fs::read_to_string(counter_path).unwrap();
let assembler: Assembler = TransactionKernel::assembler().with_debug_mode(true);
let account_component_lib = create_library(
assembler.clone(),
"external_contract::counter_contract",
&counter_code,
)
.unwrap();
let tx_script = ScriptBuilder::new(true)
.with_dynamically_linked_library(&account_component_lib)
.unwrap()
.compile_tx_script(script_code)
.unwrap();
// Build a transaction request with the custom script
let tx_increment_request = TransactionRequestBuilder::new()
.custom_script(tx_script)
.build()
.unwrap();
// Execute the transaction locally
let tx_result = client
.new_transaction(counter_contract.id(), tx_increment_request)
.await
.unwrap();
let tx_id = tx_result.executed_transaction().id();
println!(
"View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}",
tx_id
);
// Submit transaction to the network
let _ = client.submit_transaction(tx_result).await;
client.sync_state().await.unwrap();
// Retrieve updated contract data to see the incremented counter
let account = client.get_account(counter_contract.id()).await.unwrap();
println!(
"counter contract storage: {:?}",
account.unwrap().account().storage().get_item(0)
);
Ok(())
}