Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move transcode example to doc test, add helper method #705

Merged
merged 14 commits into from
Aug 24, 2022
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ test-registry-publish-install:
- echo -e '[registries]\nestuary = { index = "http://0.0.0.0:7878/git/index" }' > .cargo/config.toml
- echo 0000 | cargo login --registry estuary
- rusty-cachier snapshot create
- cd transcode && cargo publish --registry estuary && cd ..
- cargo publish --registry estuary
- cargo install cargo-contract --index http://0.0.0.0:7878/git/index

Expand Down
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ toml = "0.5.9"
rustc_version = "0.4.0"
blake2 = "0.10.4"
contract-metadata = { version = "1", path = "./metadata" }
transcode = { package = "contract-transcode", version = "0.1.0", path = "./transcode" }
transcode = { package = "contract-transcode", version = "0.2.0", path = "./transcode" }
semver = { version = "1.0.13", features = ["serde"] }
serde = { version = "1.0.144", default-features = false, features = ["derive"] }
serde_json = "1.0.85"
Expand All @@ -47,7 +47,6 @@ regex = "1.6.0"

# dependencies for extrinsics (deploying and calling a contract)
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
ink_metadata = { version = "3.3", features = ["derive"] }
sp-core = "6.0.0"
pallet-contracts-primitives = "6.0.0"
subxt = "0.23.0"
Expand Down
10 changes: 4 additions & 6 deletions src/cmd/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use crate::{
cmd::extrinsics::{
load_metadata,
ContractMessageTranscoder,
},
crate_metadata::CrateMetadata,
util::decode_hex,
DEFAULT_KEY_COL_WIDTH,
};
Expand All @@ -27,6 +24,7 @@ use anyhow::{
Result,
};
use colored::Colorize as _;
use transcode::ContractMessageTranscoder;

#[derive(Debug, Clone, clap::Args)]
#[clap(
Expand All @@ -51,8 +49,8 @@ enum DataType {

impl DecodeCommand {
pub fn run(&self) -> Result<()> {
let (_, contract_metadata) = load_metadata(None)?;
let transcoder = ContractMessageTranscoder::new(&contract_metadata);
let crate_metadata = CrateMetadata::from_manifest_path(None)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;

const ERR_MSG: &str = "Failed to decode specified data as a hex value";
let decoded_data = match self.r#type {
Expand Down
11 changes: 6 additions & 5 deletions src/cmd/extrinsics/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ use super::{
display_contract_exec_result,
display_events,
error_details,
load_metadata,
parse_balance,
prompt_confirm_tx,
state_call,
submit_extrinsic,
Balance,
Client,
ContractMessageTranscoder,
CrateMetadata,
DefaultConfig,
ExtrinsicOpts,
PairSigner,
Expand Down Expand Up @@ -74,9 +74,10 @@ pub struct CallCommand {

impl CallCommand {
pub fn run(&self) -> Result<()> {
let (_, contract_metadata) =
load_metadata(self.extrinsic_opts.manifest_path.as_ref())?;
let transcoder = ContractMessageTranscoder::new(&contract_metadata);
let crate_metadata = CrateMetadata::from_manifest_path(
self.extrinsic_opts.manifest_path.as_ref(),
)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;
let call_data = transcoder.encode(&self.message, &self.args)?;
tracing::debug!("Message data: {:?}", hex::encode(&call_data));

Expand Down Expand Up @@ -146,7 +147,7 @@ impl CallCommand {
client: &Client,
data: Vec<u8>,
signer: &PairSigner,
transcoder: &ContractMessageTranscoder<'_>,
transcoder: &ContractMessageTranscoder,
) -> Result<()> {
tracing::debug!("calling contract {:?}", self.contract);

Expand Down
6 changes: 5 additions & 1 deletion src/cmd/extrinsics/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ pub fn display_events(
name
});

let decoded_field = events_transcoder.decode(*field_ty, event_data)?;
let decoded_field = events_transcoder.decode(
&runtime_metadata.types,
*field_ty,
event_data,
)?;
maybe_println!(
verbosity,
"{:width$}{}",
Expand Down
14 changes: 8 additions & 6 deletions src/cmd/extrinsics/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use super::{
CodeHash,
ContractAccount,
ContractMessageTranscoder,
CrateMetadata,
DefaultConfig,
ExtrinsicOpts,
PairSigner,
Expand Down Expand Up @@ -121,9 +122,10 @@ impl InstantiateCommand {
/// Creates an extrinsic with the `Contracts::instantiate` Call, submits via RPC, then waits for
/// the `ContractsEvent::Instantiated` event.
pub fn run(&self) -> Result<()> {
let (crate_metadata, contract_metadata) =
super::load_metadata(self.extrinsic_opts.manifest_path.as_ref())?;
let transcoder = ContractMessageTranscoder::new(&contract_metadata);
let crate_metadata = CrateMetadata::from_manifest_path(
self.extrinsic_opts.manifest_path.as_ref(),
)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;
let data = transcoder.encode(&self.constructor, &self.args)?;
let signer = super::pair_signer(self.extrinsic_opts.signer()?);
let url = self.extrinsic_opts.url_to_string();
Expand Down Expand Up @@ -190,17 +192,17 @@ struct InstantiateArgs {
salt: Vec<u8>,
}

pub struct Exec<'a> {
pub struct Exec {
opts: ExtrinsicOpts,
args: InstantiateArgs,
verbosity: Verbosity,
url: String,
client: Client,
signer: PairSigner,
transcoder: ContractMessageTranscoder<'a>,
transcoder: ContractMessageTranscoder,
}

impl<'a> Exec<'a> {
impl Exec {
async fn exec(&self, code: Code, dry_run: bool) -> Result<()> {
tracing::debug!("instantiate data {:?}", self.args.data);
if dry_run {
Expand Down
37 changes: 0 additions & 37 deletions src/cmd/extrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ use jsonrpsee::{
ws_client::WsClientBuilder,
};
use std::{
fs::File,
io::{
self,
Write,
Expand All @@ -48,7 +47,6 @@ use self::events::display_events;
use crate::{
crate_metadata::CrateMetadata,
name_value_println,
workspace::ManifestPath,
Verbosity,
VerbosityFlags,
DEFAULT_KEY_COL_WIDTH,
Expand All @@ -58,7 +56,6 @@ use scale::{
Decode,
Encode,
};
use serde_json::Value;
use sp_core::{
crypto::Pair,
sr25519,
Expand Down Expand Up @@ -144,40 +141,6 @@ impl ExtrinsicOpts {
}
}

/// For a contract project with its `Cargo.toml` at the specified `manifest_path`, load the cargo
/// [`CrateMetadata`] along with the contract metadata [`ink_metadata::InkProject`].
pub fn load_metadata(
manifest_path: Option<&PathBuf>,
) -> Result<(CrateMetadata, ink_metadata::InkProject)> {
let manifest_path = ManifestPath::try_from(manifest_path)?;
let crate_metadata = CrateMetadata::collect(&manifest_path)?;
let path = crate_metadata.metadata_path();

if !path.exists() {
return Err(anyhow!(
"Metadata file not found. Try building with `cargo contract build`."
))
}

let file = File::open(&path)
.context(format!("Failed to open metadata file {}", path.display()))?;
let metadata: contract_metadata::ContractMetadata = serde_json::from_reader(file)
.context(format!(
"Failed to deserialize metadata file {}",
path.display()
))?;
let ink_metadata =
serde_json::from_value(Value::Object(metadata.abi)).context(format!(
"Failed to deserialize ink project metadata from file {}",
path.display()
))?;
if let ink_metadata::MetadataVersioned::V3(ink_project) = ink_metadata {
Ok((crate_metadata, ink_project))
} else {
Err(anyhow!("Unsupported ink metadata version. Expected V1"))
}
}

/// Parse Rust style integer balance literals which can contain underscores.
fn parse_balance(input: &str) -> Result<Balance> {
input
Expand Down
10 changes: 6 additions & 4 deletions src/cmd/extrinsics/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::{
Client,
CodeHash,
ContractMessageTranscoder,
CrateMetadata,
DefaultConfig,
ExtrinsicOpts,
PairSigner,
Expand Down Expand Up @@ -59,9 +60,10 @@ pub struct UploadCommand {

impl UploadCommand {
pub fn run(&self) -> Result<()> {
let (crate_metadata, contract_metadata) =
super::load_metadata(self.extrinsic_opts.manifest_path.as_ref())?;
let transcoder = ContractMessageTranscoder::new(&contract_metadata);
let crate_metadata = CrateMetadata::from_manifest_path(
self.extrinsic_opts.manifest_path.as_ref(),
)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;
let signer = super::pair_signer(self.extrinsic_opts.signer()?);

let wasm_path = match &self.wasm_path {
Expand Down Expand Up @@ -135,7 +137,7 @@ impl UploadCommand {
client: &Client,
code: Vec<u8>,
signer: &PairSigner,
transcoder: &ContractMessageTranscoder<'_>,
transcoder: &ContractMessageTranscoder,
) -> Result<Option<api::contracts::events::CodeStored>> {
let call = super::runtime_api::api::tx()
.contracts()
Expand Down
6 changes: 6 additions & 0 deletions src/crate_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ pub struct CrateMetadata {
}

impl CrateMetadata {
/// Attempt to construct [`CrateMetadata`] from the given manifest path.
pub fn from_manifest_path(manifest_path: Option<&PathBuf>) -> Result<Self> {
let manifest_path = ManifestPath::try_from(manifest_path)?;
Self::collect(&manifest_path)
}

/// Parses the contract manifest and returns relevant metadata.
pub fn collect(manifest_path: &ManifestPath) -> Result<Self> {
let (metadata, root_package) = get_cargo_metadata(manifest_path)?;
Expand Down
2 changes: 1 addition & 1 deletion transcode/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "contract-transcode"
version = "0.1.0"
version = "0.2.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"

Expand Down
35 changes: 1 addition & 34 deletions transcode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,4 @@ Contains utilities for encoding smart contract calls to SCALE.
Currently part of [`cargo-contract`](https://github.com/paritytech/cargo-contract), the build tool for smart
contracts written in [ink!](https://github.com/paritytech/ink).


# Example

```rust
use transcode::ContractMessageTranscoder;

fn main() {
let metadata_path = "/path/to/metadata.json";

let metadata = load_metadata(&metadata_path.into())?;
let transcoder = ContractMessageTranscoder::new(&metadata);

let constructor = "new";
let args = ["foo", "bar"];
let data = transcoder.encode(&constructor, &args).unwrap();

println!("Encoded constructor data {:?}", data);
}

fn load_metadata(path: &Path) -> anyhow::Result<ink_metadata::InkProject> {
let file = File::open(&path).expect("Failed to open metadata file");
let metadata: ContractMetadata =
serde_json::from_reader(file).expect("Failed to deserialize metadata file");
let ink_metadata = serde_json::from_value(serde_json::Value::Object(metadata.abi))
.expect("Failed to deserialize ink project metadata");

if let ink_metadata::MetadataVersioned::V3(ink_project) = ink_metadata {
Ok(ink_project)
} else {
Err(anyhow!("Unsupported ink metadata version. Expected V3"))
}
}

```
See [crate docs](https://docs.rs/contract-transcode/latest/contract_transcode/) for example usage.
Loading