Skip to content

Commit 5724b7d

Browse files
Merge pull request #1753 from multiversx/adder-keystore-signing-example
Modified the adder interactor example to work with keystore-signing
2 parents c1a459a + 3e46541 commit 5724b7d

File tree

6 files changed

+141
-44
lines changed

6 files changed

+141
-44
lines changed

contracts/examples/adder/interact/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Pem files are used for interactions, but shouldn't be committed
22
*.pem
3+
*.json
34
!adder-owner.pem
45

56
# Temporary storage of deployed contract address, so we can preserve the context between executions.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"version": 4,
3+
"kind": "secretKey",
4+
"id": "f2c5e236-9039-46cd-8df5-1efcd9466ead",
5+
"address": "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1",
6+
"bech32": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
7+
"crypto": {
8+
"ciphertext": "45de5198c6c477725abc17d26c6b5fc88b1ff22a67a8c4784b297d426d351cf5c891a4c92d63e04cf23f602f660b7b606ed1c5293c85ff40216d9e53c9a07c23",
9+
"cipherparams": {
10+
"iv": "d6442fb1d4c49106152baeb3c539ed2c"
11+
},
12+
"cipher": "aes-128-ctr",
13+
"kdf": "scrypt",
14+
"kdfparams": {
15+
"dklen": 32,
16+
"salt": "dd69d88742b9d27a0438a4554d4180b070d9af224ea8ff8225fdf74c8e272adb",
17+
"n": 4096,
18+
"r": 8,
19+
"p": 1
20+
},
21+
"mac": "b277984f71d0e9b4a6597911775c0ee6d598002645b29f22021e595c2725d204"
22+
}
23+
}

contracts/examples/adder/interact/src/basic_interact.rs

+89-36
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ async fn main() {
4141
basic_interact.print_sum().await;
4242
},
4343
Some(basic_interact_cli::InteractCliCommand::Upgrade(args)) => {
44-
basic_interact.upgrade(args.value).await
44+
let owner_address = basic_interact.adder_owner_address.clone();
45+
basic_interact
46+
.upgrade(args.value, &owner_address, None)
47+
.await
4548
},
4649
None => {},
4750
}
@@ -65,7 +68,15 @@ impl AdderInteract {
6568

6669
let adder_owner_address =
6770
interactor.register_wallet(Wallet::from_pem_file("adder-owner.pem").unwrap());
68-
let wallet_address = interactor.register_wallet(test_wallets::mike());
71+
// PASSWORD: "alice"
72+
// InsertPassword::Plaintext("alice".to_string()) || InsertPassword::StandardInput
73+
let wallet_address = interactor.register_wallet(
74+
Wallet::from_keystore_secret(
75+
"alice.json",
76+
InsertPassword::Plaintext("alice".to_string()),
77+
)
78+
.unwrap(),
79+
);
6980

7081
Self {
7182
interactor,
@@ -93,7 +104,7 @@ impl AdderInteract {
93104
.interactor
94105
.tx()
95106
.from(&self.adder_owner_address)
96-
.gas(3_000_000)
107+
.gas(6_000_000)
97108
.typed(adder_proxy::AdderProxy)
98109
.init(0u32)
99110
.code(ADDER_CODE_PATH)
@@ -123,7 +134,7 @@ impl AdderInteract {
123134
.typed(adder_proxy::AdderProxy)
124135
.init(0u32)
125136
.code(ADDER_CODE_PATH)
126-
.gas(3_000_000)
137+
.gas(6_000_000)
127138
.returns(ReturnsNewBech32Address)
128139
});
129140
}
@@ -151,7 +162,7 @@ impl AdderInteract {
151162
.to(self.state.current_adder_address())
152163
.typed(adder_proxy::AdderProxy)
153164
.add(value)
154-
.gas(3_000_000)
165+
.gas(6_000_000)
155166
});
156167
}
157168

@@ -176,7 +187,7 @@ impl AdderInteract {
176187
.tx()
177188
.from(&self.wallet_address)
178189
.to(self.state.current_adder_address())
179-
.gas(3_000_000)
190+
.gas(6_000_000)
180191
.typed(adder_proxy::AdderProxy)
181192
.add(value)
182193
.prepare_async()
@@ -201,45 +212,87 @@ impl AdderInteract {
201212
println!("sum: {sum}");
202213
}
203214

204-
async fn upgrade(&mut self, new_value: u32) {
205-
let response = self
206-
.interactor
207-
.tx()
208-
.from(&self.wallet_address)
209-
.to(self.state.current_adder_address())
210-
.gas(3_000_000)
211-
.typed(adder_proxy::AdderProxy)
212-
.upgrade(BigUint::from(new_value))
213-
.code_metadata(CodeMetadata::UPGRADEABLE)
214-
.code(ADDER_CODE_PATH)
215-
.returns(ReturnsResultUnmanaged)
216-
.prepare_async()
217-
.run()
218-
.await;
219-
220-
let sum = self
221-
.interactor
222-
.query()
223-
.to(self.state.current_adder_address())
224-
.typed(adder_proxy::AdderProxy)
225-
.sum()
226-
.returns(ReturnsResultUnmanaged)
227-
.prepare_async()
228-
.run()
229-
.await;
230-
assert_eq!(sum, RustBigUint::from(new_value));
215+
async fn upgrade(
216+
&mut self,
217+
new_value: u32,
218+
sender: &Bech32Address,
219+
expected_result: Option<(u64, &str)>,
220+
) {
221+
match expected_result {
222+
Some((code, msg)) => {
223+
let response = self
224+
.interactor
225+
.tx()
226+
.from(sender)
227+
.to(self.state.current_adder_address())
228+
.gas(6_000_000)
229+
.typed(adder_proxy::AdderProxy)
230+
.upgrade(new_value)
231+
.code_metadata(CodeMetadata::UPGRADEABLE)
232+
.code(ADDER_CODE_PATH)
233+
.returns(ExpectError(code, msg))
234+
.prepare_async()
235+
.run()
236+
.await;
237+
238+
println!("response: {response:?}");
239+
},
240+
None => {
241+
self.interactor
242+
.tx()
243+
.from(sender)
244+
.to(self.state.current_adder_address())
245+
.gas(6_000_000)
246+
.typed(adder_proxy::AdderProxy)
247+
.upgrade(new_value)
248+
.code_metadata(CodeMetadata::UPGRADEABLE)
249+
.code(ADDER_CODE_PATH)
250+
.prepare_async()
251+
.run()
252+
.await;
231253

232-
println!("response: {response:?}");
254+
let sum = self
255+
.interactor
256+
.query()
257+
.to(self.state.current_adder_address())
258+
.typed(adder_proxy::AdderProxy)
259+
.sum()
260+
.returns(ReturnsResultUnmanaged)
261+
.prepare_async()
262+
.run()
263+
.await;
264+
265+
assert_eq!(sum, RustBigUint::from(new_value));
266+
},
267+
}
233268
}
234269
}
235270

236271
#[tokio::test]
237272
#[ignore = "run on demand"]
238-
async fn test() {
273+
async fn upgrade_test() {
239274
let mut basic_interact = AdderInteract::init().await;
275+
let wallet_address = basic_interact.wallet_address.clone();
276+
let adder_owner_address = basic_interact.adder_owner_address.clone();
277+
let error_not_owner = (4, "upgrade is allowed only for owner");
240278

241279
basic_interact.deploy().await;
242280
basic_interact.add(1u32).await;
243281

244-
basic_interact.upgrade(7u32).await;
282+
// Sum will be 1
283+
basic_interact.print_sum().await;
284+
285+
basic_interact
286+
.upgrade(7u32, &adder_owner_address, None)
287+
.await;
288+
289+
// Sum will be the updated value of 7
290+
basic_interact.print_sum().await;
291+
292+
basic_interact
293+
.upgrade(10u32, &wallet_address, Some(error_not_owner))
294+
.await;
295+
296+
// Sum will remain 7
297+
basic_interact.print_sum().await;
245298
}

framework/snippets/src/imports.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ pub use crate::{
44
dns_address_for_name, test_wallets, Interactor, InteractorPrepareAsync, StepBuffer,
55
};
66

7-
pub use multiversx_sdk::wallet::Wallet;
7+
pub use multiversx_sdk::{
8+
wallet::Wallet,
9+
data::keystore::InsertPassword,
10+
};
811

912
pub use env_logger;
1013
pub use tokio;

sdk/core/src/data/keystore.rs

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ pub enum WalletError {
1212
InvalidKdf,
1313
InvalidCipher,
1414
}
15+
16+
#[derive(Debug)]
17+
pub enum InsertPassword {
18+
Plaintext(String),
19+
StandardInput,
20+
}
21+
1522
#[derive(Debug, Serialize, Deserialize)]
1623
pub struct CryptoParams {
1724
pub iv: String,

sdk/core/src/wallet.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,24 @@ impl Wallet {
156156
(private_key_str, public_key_str)
157157
}
158158

159-
pub fn from_keystore_secret(file_path: &str) -> Result<Self> {
160-
let decyption_params =
161-
Self::validate_keystore_password(file_path, Self::get_keystore_password())
162-
.unwrap_or_else(|e| {
163-
panic!("Error: {:?}", e);
164-
});
159+
pub fn from_keystore_secret(file_path: &str, insert_password: InsertPassword) -> Result<Self> {
160+
let decryption_params = match insert_password {
161+
InsertPassword::Plaintext(password) => {
162+
Self::validate_keystore_password(file_path, password.to_string()).unwrap_or_else(
163+
|e| {
164+
panic!("Error: {:?}", e);
165+
},
166+
)
167+
},
168+
InsertPassword::StandardInput => {
169+
Self::validate_keystore_password(file_path, Self::get_keystore_password())
170+
.unwrap_or_else(|e| {
171+
panic!("Error: {:?}", e);
172+
})
173+
},
174+
};
165175
let priv_key = PrivateKey::from_hex_str(
166-
hex::encode(Self::decrypt_secret_key(decyption_params)).as_str(),
176+
hex::encode(Self::decrypt_secret_key(decryption_params)).as_str(),
167177
)?;
168178
Ok(Self { priv_key })
169179
}

0 commit comments

Comments
 (0)