public async Task CreateContract_CallswithCorrectParams_Test()
        {
            var body = new SmartContractSchema
            {
                TransactionType      = "name",
                Image                = "ubuntu:latest",
                ExecutionOrder       = SmartContractExecutionOrder.Serial,
                EnvironmentVariables = new { Banana = "banana", Apple = "banana" },
                Cmd       = "banana",
                Arguments = new string[] { "-m cool" }
            };
            await _dragonchainClient.CreateSmartContract(body.TransactionType, body.Image, body.Cmd, body.Arguments, (SmartContractExecutionOrder)body.ExecutionOrder, body.EnvironmentVariables);

            _httpService.Verify(service => service.PostAsync <DragonchainContractResponse>("/contract", It.IsAny <SmartContractSchema>(), ""), Times.Once);
        }
        /// <summary>
        /// Create a new Smart Contract on your Dragonchain.
        /// </summary>
        /// <param name="transactionType">Transaction type to assign to this new smart contract. Must not already exist as a transaction type on the chain</param>
        /// <param name="image">Docker image to use with the smart contract. Should be in the form registry/image:tag (or just image:tag if it's a docker hub image)</param>
        /// <param name="cmd">The command to run in your docker container for your application</param>
        /// <param name="args">The list of arguments to use in conjunction with cmd</param>
        /// <param name="executionOrder">The execution of the smart contract, can be `serial` or `parallel`. Will default to `parallel`
        /// If running in serial, the contract will be queued and executed in order, only one at a time
        /// If running in parallel, the contract will be executed as soon as possible after invocation, potentially out of order, and many at a time
        /// </param>
        /// <param name="environmentVariables">JSON object key-value pairs of strings for environments variables provided to the smart contract on execution</param>
        /// <param name="secrets">JSON object key-value pairs of strings for secrets provided to the smart contract on execution
        /// These are more securely stored than environment variables, and can be accessed during execution the smart contract by using the `getSmartContractSecret` method of the sdk
        /// </param>
        /// <param name="scheduleIntervalInSeconds">Schedule a smart contract to be automatically executed every `x` seconds
        /// For example: if `10` is supplied, then this contract will be automatically invoked and create a transaction once every 10 seconds
        /// Note: This is a mutually exclusive parameter with cronExpression
        /// </param>
        /// <param name="cronExpression">Schedule a smart contract to be automatically executed on a cadence via a cron expression
        /// Note: This is a mutually exclusive parameter with scheduleIntervalInSeconds
        /// </param>
        /// <param name="registryCredentials">The basic-auth credentials necessary to pull the docker container.
        /// This should be a base64-encoded string of `username:password` for the docker registry
        /// </param>
        /// <returns></returns>
        public async Task <ApiResponse <DragonchainContractResponse> > CreateSmartContract(string transactionType,
                                                                                           string image,
                                                                                           string cmd,
                                                                                           IEnumerable <string> args,
                                                                                           SmartContractExecutionOrder executionOrder = SmartContractExecutionOrder.Parallel,
                                                                                           object environmentVariables = null,
                                                                                           object secrets = null,
                                                                                           int?scheduleIntervalInSeconds = null,
                                                                                           string cronExpression         = null,
                                                                                           string registryCredentials    = null)
        {
            if (string.IsNullOrWhiteSpace(transactionType))
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameter `transactionType` is required");
            }
            if (string.IsNullOrWhiteSpace(image))
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameter `image` is required");
            }
            if (string.IsNullOrWhiteSpace(cmd))
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameter `cmd` is required");
            }
            if (scheduleIntervalInSeconds != null && cronExpression != null)
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameters `scheduleIntervalInSeconds` and `cronExpression` are mutually exclusive");
            }
            var body = new SmartContractSchema {
                Version              = "3",
                TransactionType      = transactionType,
                Image                = image,
                ExecutionOrder       = executionOrder, // default execution order
                Cmd                  = cmd,
                Arguments            = args,
                EnvironmentVariables = environmentVariables,
                Secrets              = secrets,
                Seconds              = scheduleIntervalInSeconds,
                Cron                 = cronExpression,
                Auth                 = registryCredentials
            };

            return(await _httpService.PostAsync <DragonchainContractResponse>("/contract", body));
        }
        /// <summary>
        /// Update an existing Smart Contract on your Dragonchain
        /// Note that all parameters (aside from contract id) are optional, and only supplied parameters will be updated
        /// </summary>
        /// <param name="smartContractId">Smart contract id of which to update. Should be a guid</param>
        /// <param name="image">Docker image to use with the smart contract. Should be in the form registry/image:tag (or just image:tag if it's a docker hub image)</param>
        /// <param name="cmd">The command to run in your docker container for your application</param>
        /// <param name="args">The list of arguments to use in conjunction with cmd</param>
        /// <param name="executionOrder">The execution of the smart contract, can be `serial` or `parallel`. Will default to `parallel`
        /// If running in serial, the contract will be queued and executed in order, only one at a time
        /// If running in parallel, the contract will be executed as soon as possible after invocation, potentially out of order, and many at a time
        /// </param>
        /// <param name="enabled">Boolean whether or not the contract should be enabled, and able to be invoked</param>
        /// <param name="environmentVariables">object key-value pairs of strings for environments variables provided to the smart contract on execution</param>
        /// <param name="secrets">object key-value pairs of strings for secrets provided to the smart contract on execution</param>
        /// <param name="scheduleIntervalInSeconds">Schedule a smart contract to be automatically executed every `x` seconds
        /// For example, if `10` is supplied, then this contract will be automatically invoked and create a transaction once every 10 seconds
        /// Note: This is a mutually exclusive parameter with cronExpression
        /// </param>
        /// <param name="cronExpression">Schedule a smart contract to be automatically executed on a cadence via a cron expression
        /// Note: This is a mutually exclusive parameter with scheduleIntervalInSeconds
        /// </param>
        /// <param name="registryCredentials">The basic-auth credentials necessary to pull the docker container.
        /// This should be a base64-encoded string of `username:password` for the docker registry
        /// </param>
        /// <returns></returns>
        public async Task <ApiResponse <DragonchainContractResponse> > UpdateSmartContract(string smartContractId,
                                                                                           string image  = null,
                                                                                           string cmd    = null,
                                                                                           string[] args = null,
                                                                                           SmartContractExecutionOrder?executionOrder = null,
                                                                                           bool?enabled = null,
                                                                                           object environmentVariables = null,
                                                                                           object secrets = null,
                                                                                           int?scheduleIntervalInSeconds = null,
                                                                                           string cronExpression         = null,
                                                                                           string registryCredentials    = null)
        {
            if (string.IsNullOrWhiteSpace(smartContractId))
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameter `smartContractId` is required");
            }
            if (scheduleIntervalInSeconds != null && cronExpression != null)
            {
                throw new FailureByDesignException(FailureCode.PARAM_ERROR, "Parameters `scheduleIntervalInSeconds` and `cronExpression` are mutually exclusive");
            }
            var body = new SmartContractSchema
            {
                Version              = "3",
                Image                = image,
                Cmd                  = cmd,
                ExecutionOrder       = executionOrder,
                DesiredState         = enabled.HasValue ? (enabled == true ? SmartContractDesiredState.Active : SmartContractDesiredState.Inactive) : default(SmartContractDesiredState?),
                Arguments            = args != null && args.Length > 0 ? args : null,
                EnvironmentVariables = environmentVariables != null ? environmentVariables : null,
                Secrets              = secrets != null ? secrets : null,
                Seconds              = scheduleIntervalInSeconds != null ? scheduleIntervalInSeconds : null,
                Cron                 = !string.IsNullOrWhiteSpace(cronExpression) ? cronExpression : null,
                Auth                 = !string.IsNullOrWhiteSpace(registryCredentials) ? registryCredentials : null
            };

            return(await _httpService.PutAsync <DragonchainContractResponse>($"/contract/{smartContractId}", body));
        }