// Copyright 2018-2019 Parity Technologies (UK) Ltd. // This file is part of ink!. // // ink! is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ink! is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with ink!. If not, see . mod cmd; use structopt::{ clap::AppSettings, StructOpt, }; use url::Url; #[derive(Debug, StructOpt)] #[structopt(bin_name = "cargo")] pub(crate) enum Opts { #[structopt( name = "contract", raw( setting = "AppSettings::UnifiedHelpMessage", setting = "AppSettings::DeriveDisplayOrder", setting = "AppSettings::DontCollapseArgsInUsage" ) )] /// Utilities to develop Wasm smart contracts. Contract(ContractArgs), } #[derive(Debug, StructOpt)] pub(crate) struct ContractArgs { #[structopt(subcommand)] cmd: Command, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) enum AbstractionLayer { Core, Model, Lang, } use std::result::Result as StdResult; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) struct InvalidAbstractionLayer; impl std::fmt::Display for InvalidAbstractionLayer { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "expected `core`, `model` or `lang`") } } impl std::str::FromStr for AbstractionLayer { type Err = InvalidAbstractionLayer; fn from_str(input: &str) -> StdResult { match input { "core" => Ok(AbstractionLayer::Core), "model" => Ok(AbstractionLayer::Model), "lang" => Ok(AbstractionLayer::Lang), _ => Err(InvalidAbstractionLayer), } } } #[derive(Debug, StructOpt)] enum Command { /// Setup and create a new smart contract. #[structopt(name = "new")] New { /// The abstraction layer to use: `core`, `model` or `lang` #[structopt(short = "l", long = "layer", default_value = "lang")] layer: AbstractionLayer, /// The name of the newly created smart contract. name: String, }, /// Builds the smart contract. #[structopt(name = "build")] Build {}, /// Test the smart contract off-chain. #[structopt(name = "test")] Test {}, /// Deploy the smart contract on-chain. (Also for testing purposes.) #[structopt(name = "deploy")] Deploy { /// Websockets url of a substrate node #[structopt( name = "url", long, parse(try_from_str), default_value = "ws://localhost:9944" )] url: Url, /// Secret key URI for the account deploying the contract. #[structopt(name = "suri", long, short)] suri: String, /// Password for the secret key #[structopt(name = "password", long, short)] password: Option, #[structopt(name = "gas", long, default_value = "500000")] /// Maximum amount of gas to be used in this deployment gas: u64, /// Path to wasm contract code, defaults to ./target/-pruned.wasm #[structopt(parse(from_os_str))] wasm_path: Option, }, } fn main() { env_logger::init(); let Opts::Contract(args) = Opts::from_args(); match exec(args.cmd) { Ok(msg) => println!("\t{}", msg), Err(err) => eprintln!("error: {}", err), } } fn exec(cmd: Command) -> cmd::Result { use crate::cmd::CommandError; match &cmd { Command::New { layer, name } => cmd::execute_new(*layer, name), Command::Build {} => cmd::execute_build(), Command::Test {} => Err(CommandError::UnimplementedCommand), Command::Deploy { url, suri, password, gas, wasm_path, } => { cmd::execute_deploy( url.clone(), suri, password.as_ref().map(String::as_ref), *gas, wasm_path.as_ref(), ) } } }