Add --output-json for call, instantiate & upload commands#722
Add --output-json for call, instantiate & upload commands#722
--output-json for call, instantiate & upload commands#722Conversation
|
Currently, JSON is only displayed when if the operation has been successful. Should JSON response be introduced for errors? |
That would be ideal, then third-party tooling can make better use of For context: The PR has conflicts with |
UpdateError are now partially json-rendered. Only ExampleP.S.After short conversation with @ascjones It was agreed that RPC error does not have to and can not be serialised properly |
UpdateModule and Generic errors are now serialised generically
|
* Convert subxt error to custom ErrorVariant * Refactor displaying of extrinsic result events
crates/cargo-contract/src/main.rs
Outdated
| "ERROR:".bright_red().bold(), | ||
| format!("{:?}", err).bright_red() | ||
| ); | ||
| if !suppress_err { |
There was a problem hiding this comment.
I think we actually want to report the error as json rather than supressing it. At the moment for some errors we will get the pretty printed json at the call site, and all others will not be displayed at all.
There was a problem hiding this comment.
If don't do this, then the output result can be like this:
{
"module_error": {
"pallet": "Contracts",
"error": "DuplicateContract",
"docs": [
"A contract with the same AccountId already exists."
]
}
}
{
"error": "Pre-submission dry-run failed. Use --skip-dry-run to skip this step."
}There was a problem hiding this comment.
Then we will need to rethink the approach. How about instead of printing the json error directly, we bubble it back up as an error?.
So instead of eprintnln!("{}", json_error); Ok(()) you could do (Err(anyhow!("{}", json_err)). Then this would be printed correctly at the top level
There was a problem hiding this comment.
I made the error propagate to the top level, all the way back to the main(), then I check if an error is an json format and print out, otherwise I wrap the message into a serializable object.
crates/cargo-contract/src/main.rs
Outdated
| // error message can be either plain text or json string | ||
| // we need to check whether the error message is json object | ||
| let json_result = | ||
| serde_json::from_str::<serde_json::Value>(&err.to_string()); |
There was a problem hiding this comment.
It's not great to serialize to json at the error site and then deserialize again at the top level. I think we can do better with a strongly typed approach see #736
--output-json for call and instantiate commands--output-json for call, instantiate & upload commands
Summary
As requested this PR closes #682, this PR adds support for printing out response from calling
cargo contract instantiate .... andcargo contract call ...outputs in JSON format by introducing--output-jsonflag.Previous human-readable format has been preserved.
Examples
Calling a contract with arg
cargo contract call --contract 5HLJobbpgd9EpJFySGDEanHkgh4nMaG6h1pFq9D2A5aTqibt --message inc --args 5 --suri //Alice --skip-confirm --output-json { "verbosity": "Default", "estimated_gas": 74999922688, "events": [ { "pallet": "Balances", "name": "Withdraw", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "amount", "value": { "UInt": 86298156 } } ] }, { "pallet": "TransactionPayment", "name": "TransactionFeePaid", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "actual_fee", "value": { "UInt": 86298156 } }, { "name": "tip", "value": { "UInt": 0 } } ] }, { "pallet": "System", "name": "ExtrinsicSuccess", "fields": [ { "name": "dispatch_info", "value": { "Map": { "weight": { "UInt": 7841193043 }, "class": { "Tuple": { "ident": "Normal", "values": [] } }, "pays_fee": { "Tuple": { "ident": "Yes", "values": [] } } } } } ] } ] }Calling a contract with
--dry-runflagcargo contract call --contract 5HLJobbpgd9EpJFySGDEanHkgh4nMaG6h1pFq9D2A5aTqibt --message inc --args 5 --suri //Alice --skip-confirm --dry-run --output-json { "result": "Success!", "reverted": false, "data": "Unit", "gas_consumed": 7391961043, "gas_required": 74999922688, "storage_deposit": { "charge": "0x0" } }Instantiating contract
{ "contract": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9", "code_hash": "0xd73514bcae8754202a7cf32b2d4057ba9c95e7e82a3cb8f00b5ce1c64995ab70", "verbosity": "Default", "estimated_gas": 27371571412, "events": [ { "pallet": "Balances", "name": "Withdraw", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "amount", "value": { "UInt": 31189830465 } } ] }, { "pallet": "System", "name": "NewAccount", "fields": [ { "name": "account", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } } ] }, { "pallet": "Balances", "name": "Endowed", "fields": [ { "name": "account", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } }, { "name": "free_balance", "value": { "UInt": 100405000000 } } ] }, { "pallet": "Balances", "name": "Transfer", "fields": [ { "name": "from", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "to", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } }, { "name": "amount", "value": { "UInt": 100405000000 } } ] }, { "pallet": "Balances", "name": "Reserved", "fields": [ { "name": "who", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } }, { "name": "amount", "value": { "UInt": 100405000000 } } ] }, { "pallet": "Balances", "name": "Reserved", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "amount", "value": { "UInt": 536140000000 } } ] }, { "pallet": "Contracts", "name": "CodeStored", "fields": [ { "name": "code_hash", "value": { "Hex": { "s": "d73514bcae8754202a7cf32b2d4057ba9c95e7e82a3cb8f00b5ce1c64995ab70", "bytes": [ 215, 53, 20, 188, 174, 135, 84, 32, 42, 124, 243, 43, 45, 64, 87, 186, 156, 149, 231, 232, 42, 60, 184, 240, 11, 92, 225, 198, 73, 149, 171, 112 ] } } } ] }, { "pallet": "Contracts", "name": "Instantiated", "fields": [ { "name": "deployer", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "contract", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } } ] }, { "pallet": "Balances", "name": "Transfer", "fields": [ { "name": "from", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "to", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } }, { "name": "amount", "value": { "UInt": 100020000000 } } ] }, { "pallet": "Balances", "name": "Reserved", "fields": [ { "name": "who", "value": { "Literal": "5FUdyfmrdbk1H5F1E4HnweiQjENqwAWnPxH2Mkty6LeK5at9" } }, { "name": "amount", "value": { "UInt": 100020000000 } } ] }, { "pallet": "Balances", "name": "Deposit", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "amount", "value": { "UInt": 27233000969 } } ] }, { "pallet": "TransactionPayment", "name": "TransactionFeePaid", "fields": [ { "name": "who", "value": { "Literal": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" } }, { "name": "actual_fee", "value": { "UInt": 3956829496 } }, { "name": "tip", "value": { "UInt": 0 } } ] }, { "pallet": "System", "name": "ExtrinsicSuccess", "fields": [ { "name": "dispatch_info", "value": { "Map": { "weight": { "UInt": 3870509443 }, "class": { "Tuple": { "ident": "Normal", "values": [] } }, "pays_fee": { "Tuple": { "ident": "Yes", "values": [] } } } } } ] } ] }Instantiating a contract with dry-run
cargo contract instantiate --suri //Alice target/ink/incrementer.wasm --skip-dry-run --gas 27371571412 --args 0 --skip-confirm --dry-run --output-json { "result": "Success!", "contract": "5EMUDqdfmSsyE7v3uksHtGRuEeQrgk7QteoJ8tXhqGANDCfG", "reverted": false, "data": "0x", "gas_consumed": 7360357127, "gas_required": 74999922688, "storage_deposit": { "charge": "0x2eaa42cc40" } }Updates
StorageDepositchanges