-
Notifications
You must be signed in to change notification settings - Fork 47
/
main.rs
executable file
·147 lines (121 loc) · 4.98 KB
/
main.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
Copyright 2019 Supercomputing Systems AG
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate hex_literal;
extern crate log;
extern crate my_node_runtime;
extern crate parity_codec;
extern crate primitives;
extern crate runtime_primitives;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate sgx_crypto_helper;
extern crate sgx_types;
extern crate substrate_api_client;
use blake2_rfc::blake2s::blake2s;
use clap::App;
use parity_codec::Encode;
use primitive_types::U256;
use primitives::Pair;
use sgx_types::*;
use substrate_api_client::Api;
use substratee_client::*;
use substratee_node_calls::{get_worker_amount, get_worker_info};
use substratee_worker_api::Api as WorkerApi;
const WASM_FILE: &str = "worker_enclave.compact.wasm";
fn main() {
// message structure
#[derive(Debug, Serialize, Deserialize)]
struct Message {
account: String,
amount: u32,
sha256: sgx_sha256_hash_t
}
env_logger::init();
let yml = load_yaml!("cli.yml");
let matches = App::from_yaml(yml).get_matches();
let port = matches.value_of("node-port").unwrap_or("9944");
let server = matches.value_of("node-server").unwrap_or("127.0.0.1");
let mut api: substrate_api_client::Api = Api::new(format!("ws://{}:{}", server, port));
api.init();
println!("*** Getting the amount of the registered workers");
let worker = match get_worker_amount(&api) {
0 => {
println!("No worker in registry, returning...");
return;
}
x => {
println!("[<] Found {} workers\n", x);
println!("[>] Getting the first worker's from the substraTEE-node");
get_worker_info(&api, 0)
}
};
println!("[<] Got first worker's coordinates:");
println!(" W1's public key : {:?}", worker.pubkey.to_string());
println!(" W1's url: {:?}\n", worker.url);
let worker_api = WorkerApi::new(worker.url.clone());
if let Some(_matches) = matches.subcommand_matches("getcounter") {
let user = pair_from_suri("//Alice", Some(""));
println!("*** Getting the counter value of //Alice = {:?} from the substraTEE-worker", user.public().to_string());
let sign = user.sign(user.public().as_slice());
let value = worker_api.get_counter(user.public(), sign).unwrap();
println!("[<] Received MSG: {}", value);
return;
}
let wasm_path = matches.value_of("wasm-path").unwrap_or(WASM_FILE);
let hash_hex = get_wasm_hash(wasm_path);
println!("[>] Calculating WASM hash of {:?}", wasm_path);
println!("[<] WASM Hash: {:?}\n", hash_hex[0]);
let hash = hex::decode(hash_hex[0].clone()).unwrap();
let sha256: sgx_sha256_hash_t = slice_to_hash(&hash);
// get Alice's free balance
get_free_balance(&api, "//Alice");
// get Alice's account nonce
let mut nonce = get_account_nonce(&api, "//Alice");
// fund the account of Alice
fund_account(&api, "//Alice", 1_000_000, nonce, api.genesis_hash.unwrap());
// transfer from Alice to TEE
nonce = get_account_nonce(&api, "//Alice");
transfer_amount(&api, "//Alice", worker.pubkey.clone(), U256::from(1000), nonce, api.genesis_hash.unwrap());
// compose extrinsic with encrypted payload
println!("[>] Get the encryption key from W1 (={})", worker.pubkey.to_string());
let rsa_pubkey = worker_api.get_rsa_pubkey().unwrap();
println!("[<] Got worker shielding key {:?}\n", rsa_pubkey);
let account = user_to_pubkey("//Alice").to_string();
println!("[+] //Alice's Pubkey: {}\n", account);
let amount = value_t!(matches.value_of("amount"), u32).unwrap_or(42);
let message = Message { account, amount, sha256 };
let plaintext = serde_json::to_vec(&message).unwrap();
let mut payload_encrypted: Vec<u8> = Vec::new();
rsa_pubkey.encrypt_buffer(&plaintext, &mut payload_encrypted).unwrap();
println!("[>] Sending message '{:?}' to substraTEE-worker.\n", message);
nonce = get_account_nonce(&api, "//Alice");
let xt = compose_extrinsic_substratee_call_worker("//Alice", payload_encrypted, nonce, api.genesis_hash.unwrap());
let mut _xthex = hex::encode(xt.encode());
_xthex.insert_str(0, "0x");
// send and watch extrinsic until finalized
let tx_hash = api.send_extrinsic(_xthex).unwrap();
println!("[+] Transaction got finalized. Hash: {:?}", tx_hash);
println!("[<] Message sent successfully");
println!();
// subsribe to callConfirmed event
println!("[>] Subscribe to callConfirmed event");
let act_hash = subscribe_to_call_confirmed(api);
println!("[<] callConfirmed event received");
println!("[+] Expected Hash: {:?}", blake2s(32, &[0; 32], &plaintext).as_bytes());
println!("[+] Actual Hash: {:?}", act_hash);
}