Skip to content

Commit 497cb88

Browse files
smiasojedlean-appleascjonescmichi
authored
Add --binary flag for info command (#1311)
* add info structure * add info import * change function call * wip - fix some issues * fix client error * fix: fix info_contract_call getter * remove from extrenstics condition * Decode bytes into type. * add first accountid handling * refactor contract info getter and decoder by using fetch * first draft for print in a good way contract ways * add integration test for info * remove extrenstics and add url flag for info command * remove the useless check for accountId * add doc * fix fmt * update changelog * refactor: move out extrinstics info command * remove ignore comments for integration tests * change output format for info command * remove tracing debug in integration tests * fix fmt * change trie id format * fix fmt and format in a better way comments and output * remove output_json * fix fmt * fix fmt output for trie_id * change comments, docs and removing debug for inetgration tests * complete doc * docs: change minor term * first draft to add output_json flag * fix serde_json data to print * remove useless comments for tests and doc * Derive `Default` instances, make clippy happy 🦖 * fix output-json result * remove useless return + fmt * update changelog + doc * first draft to print pristine_code * fix fmt and clippy * wip - second draft for binary flag * wip - format ouput depending on the flag * optimize the display * fix fmt * fix master merge and restore changes * add docs + first draft of test * complete tests * fix error merge * fix error merge * change to display only pristine code * fix temporary test * fix fmt * reimport items in binary outpuson * Update crates/cargo-contract/src/cmd/info.rs Co-authored-by: Michael Müller <mich@elmueller.net> * Update crates/cargo-contract/src/cmd/info.rs Co-authored-by: Michael Müller <mich@elmueller.net> * Implemented combination of --binary and --output-json including code cleanup * Removed BoundedVec from API --------- Co-authored-by: lean-apple <lea@parity.io> Co-authored-by: Andrew Jones <ascjones@gmail.com> Co-authored-by: Léa Narzis <78718413+lean-apple@users.noreply.github.com> Co-authored-by: Michael Müller <mich@elmueller.net>
1 parent 0627b1e commit 497cb88

File tree

5 files changed

+95
-8
lines changed

5 files changed

+95
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- Adds workflow for publishing docker images for the verifiable builds - [#1267](https://github.com/paritytech/cargo-contract/pull/1267)
1111
- Detect `INK_STATIC_BUFFER_SIZE` env var - [#1310](https://github.com/paritytech/cargo-contract/pull/1310)
1212
- Add `verify` command - [#1306](https://github.com/paritytech/cargo-contract/pull/1306)
13+
- Add `--binary` flag for `info` command - [#1311](https://github.com/paritytech/cargo-contract/pull/1311/)
1314

1415
## [4.0.0-alpha]
1516

crates/cargo-contract/src/cmd/info.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ use anyhow::{
2424
};
2525
use contract_extrinsics::{
2626
fetch_contract_info,
27+
fetch_wasm_code,
2728
ErrorVariant,
2829
};
29-
use std::fmt::Debug;
30+
use std::{
31+
fmt::Debug,
32+
io::Write,
33+
};
3034
use subxt::{
3135
Config,
3236
OnlineClient,
@@ -50,6 +54,9 @@ pub struct InfoCommand {
5054
/// Export the instantiate output in JSON format.
5155
#[clap(name = "output-json", long)]
5256
output_json: bool,
57+
/// Display the contract's Wasm bytecode.
58+
#[clap(name = "binary", long)]
59+
binary: bool,
5360
}
5461

5562
impl InfoCommand {
@@ -67,10 +74,46 @@ impl InfoCommand {
6774

6875
match info_result {
6976
Some(info_to_json) => {
70-
if self.output_json {
71-
println!("{}", info_to_json.to_json()?);
72-
} else {
73-
basic_display_format_contract_info(&info_to_json);
77+
match (self.output_json, self.binary) {
78+
(true, false) => println!("{}", info_to_json.to_json()?),
79+
(false, false) => {
80+
basic_display_format_contract_info(&info_to_json)
81+
}
82+
// Binary flag applied
83+
(_, true) => {
84+
let wasm_code =
85+
fetch_wasm_code(*info_to_json.code_hash(), &client)
86+
.await?;
87+
match (wasm_code, self.output_json) {
88+
(Some(code), false) => {
89+
std::io::stdout()
90+
.write_all(&code)
91+
.expect("Writing to stdout failed")
92+
}
93+
(Some(code), true) => {
94+
let wasm = serde_json::json!({
95+
"wasm": format!("0x{}", hex::encode(code))
96+
});
97+
println!(
98+
"{}",
99+
serde_json::to_string_pretty(&wasm).map_err(
100+
|err| {
101+
anyhow!(
102+
"JSON serialization failed: {}",
103+
err
104+
)
105+
}
106+
)?
107+
);
108+
}
109+
(None, _) => {
110+
return Err(anyhow!(
111+
"Contract wasm code was not found"
112+
)
113+
.into())
114+
}
115+
}
116+
}
74117
}
75118
Ok(())
76119
}

crates/extrinsics/src/integration_tests.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::{
2222
UploadCommandBuilder,
2323
};
2424
use anyhow::Result;
25+
use contract_build::code_hash;
2526
use predicates::prelude::*;
2627
use std::{
2728
ffi::OsStr,
@@ -358,15 +359,15 @@ async fn build_upload_instantiate_info() {
358359
let contract_account = extract_contract_address(stdout);
359360
assert_eq!(48, contract_account.len(), "{stdout:?}");
360361

361-
cargo_contract(project_path.as_path())
362+
let output = cargo_contract(project_path.as_path())
362363
.arg("info")
363364
.args(["--contract", contract_account])
364365
.output()
365366
.expect("failed to execute process");
366367
let stderr = str::from_utf8(&output.stderr).unwrap();
367368
assert!(output.status.success(), "getting info failed: {stderr}");
368369

369-
cargo_contract(project_path.as_path())
370+
let output = cargo_contract(project_path.as_path())
370371
.arg("info")
371372
.args(["--contract", contract_account])
372373
.arg("--output-json")
@@ -378,6 +379,32 @@ async fn build_upload_instantiate_info() {
378379
"getting info as JSON format failed: {stderr}"
379380
);
380381

382+
let output = cargo_contract(project_path.as_path())
383+
.arg("info")
384+
.args(["--contract", contract_account])
385+
.arg("--binary")
386+
.output()
387+
.expect("failed to execute process");
388+
let stderr = str::from_utf8(&output.stderr).unwrap();
389+
assert!(
390+
output.status.success(),
391+
"getting Wasm code failed: {stderr}"
392+
);
393+
394+
// construct the contract file path
395+
let contract_wasm = project_path.join("target/ink/flipper.wasm");
396+
397+
let code = std::fs::read(contract_wasm).expect("contract Wasm file not found");
398+
assert_eq!(code_hash(&code), code_hash(&output.stdout));
399+
400+
cargo_contract(project_path.as_path())
401+
.arg("info")
402+
.args(["--contract", contract_account])
403+
.arg("--output-json")
404+
.arg("--binary")
405+
.assert()
406+
.stdout(predicate::str::contains(r#""wasm": "0x"#));
407+
381408
// prevent the node_process from being dropped and killed
382409
let _ = node_process;
383410
}

crates/extrinsics/src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use jsonrpsee::{
4343
};
4444
use std::path::PathBuf;
4545

46-
use crate::runtime_api::api::{self,};
46+
use crate::runtime_api::api;
4747
use contract_build::{
4848
CrateMetadata,
4949
DEFAULT_KEY_COL_WIDTH,
@@ -363,6 +363,21 @@ impl ContractInfo {
363363
}
364364
}
365365

366+
/// Fetch the contract wasm code from the storage using the provided client and code hash.
367+
pub async fn fetch_wasm_code(hash: CodeHash, client: &Client) -> Result<Option<Vec<u8>>> {
368+
let pristine_code_address = api::storage().contracts().pristine_code(hash);
369+
370+
let pristine_bytes = client
371+
.storage()
372+
.at_latest()
373+
.await?
374+
.fetch(&pristine_code_address)
375+
.await?
376+
.map(|v| v.0);
377+
378+
Ok(pristine_bytes)
379+
}
380+
366381
/// Copy of `pallet_contracts_primitives::StorageDeposit` which implements `Serialize`,
367382
/// required for json output.
368383
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, serde::Serialize)]

docs/info.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ cargo contract info \
1818
*Optional*
1919
- `--url` the url of the rpc endpoint you want to specify - by default `ws://localhost:9944`.
2020
- `--output-json` to export the output as JSON.
21+
- `--binary` outputs Wasm code as a binary blob. If used in combination with `--output-json`, outputs Wasm code as JSON object with hex string.

0 commit comments

Comments
 (0)