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
use crate::{
api::Api,
metadata::Metadata,
result::{Error, Result},
};
use std::{fs, path::PathBuf};
use structopt::StructOpt;
use subxt::sp_core::H256;
#[derive(Clone, Debug, StructOpt)]
pub enum Action {
State {
metadata: PathBuf,
#[structopt(short, long, default_value = "0x")]
msg: String,
#[structopt(short, long)]
timestamp: Option<u64>,
#[structopt(short, long)]
height: Option<u64>,
},
}
#[derive(Debug, StructOpt)]
pub struct Program {
pid: String,
#[structopt(subcommand)]
action: Action,
}
impl Program {
pub async fn exec(&self, api: Api) -> Result<()> {
let pid_bytes = hex::decode(&self.pid.trim_start_matches("0x"))?;
let mut pid = [0; 32];
pid.copy_from_slice(&pid_bytes);
match self.action {
Action::State { .. } => self.state(api, pid.into()).await?,
}
Ok(())
}
pub async fn state(&self, api: Api, pid: H256) -> Result<()> {
let Action::State {
metadata,
msg,
timestamp,
height,
} = self.action.clone();
let program = api.gprog(pid).await?;
let code_id = program.code_hash;
let code = api
.code_storage(code_id.0)
.await?
.ok_or_else(|| Error::CodeNotFound(self.pid.clone()))?;
let pages = api.gpages(pid, program).await?;
let state = Metadata::read(
&fs::read(&metadata)?,
code.static_pages.0 as u64,
pages,
hex::decode(msg.trim_start_matches("0x"))?,
timestamp.unwrap_or(0),
height.unwrap_or(0),
)?;
println!("state: 0x{}", hex::encode(state));
Ok(())
}
}