public void CanChooseInputsForCall()
        {
            const int utxoIndex       = 0;
            uint256   utxoId          = uint256.Zero;
            uint256   utxoIdUnused    = uint256.One;
            string    senderAddress   = uint160.Zero.ToBase58Address(this.network);
            string    contractAddress = uint160.One.ToBase58Address(this.network);

            var request = new BuildCallContractTransactionRequest
            {
                Amount          = "0",
                AccountName     = "account 0",
                ContractAddress = contractAddress,
                FeeAmount       = "0.01",
                GasLimit        = 100_000,
                GasPrice        = 100,
                MethodName      = "TestMethod",
                WalletName      = "wallet",
                Password        = "******",
                Sender          = senderAddress,
                Outpoints       = new List <OutpointRequest>
                {
                    new OutpointRequest
                    {
                        Index         = utxoIndex,
                        TransactionId = utxoId.ToString()
                    },
                }
            };

            this.walletManager.Setup(x => x.GetAddressBalance(request.Sender))
            .Returns(new AddressBalance
            {
                Address         = senderAddress,
                AmountConfirmed = new Money(100, MoneyUnit.BTC)
            });

            this.walletManager.Setup(x => x.GetSpendableTransactionsInWallet(It.IsAny <string>(), 0))
            .Returns(new List <UnspentOutputReference>
            {
                new UnspentOutputReference
                {
                    Address = new HdAddress
                    {
                        Address = senderAddress
                    },
                    Transaction = new TransactionData
                    {
                        Id    = utxoId,
                        Index = utxoIndex,
                    }
                }, new UnspentOutputReference
                {
                    Address = new HdAddress
                    {
                        Address = senderAddress
                    },
                    Transaction = new TransactionData
                    {
                        Id    = utxoIdUnused,
                        Index = utxoIndex,
                    }
                }
            });

            var wallet = new Features.Wallet.Wallet();

            wallet.AccountsRoot.Add(new AccountRoot(wallet));
            var account0 = new HdAccount(wallet.AccountsRoot.First().Accounts)
            {
                Name = request.AccountName
            };

            account0.ExternalAddresses.Add(new HdAddress()
            {
                Address = senderAddress
            });

            this.walletManager.Setup(x => x.GetWallet(request.WalletName))
            .Returns(wallet);

            var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock <ISignals>().Object);

            var service = new SmartContractTransactionService(
                this.network,
                this.walletManager.Object,
                this.walletTransactionHandler.Object,
                this.stringSerializer.Object,
                this.callDataSerializer.Object,
                this.addressGenerator.Object,
                this.stateRepository.Object,
                reserveUtxoService);

            BuildCallContractTransactionResponse result = service.BuildCallTx(request);

            this.walletTransactionHandler.Verify(x => x.BuildTransaction(It.Is <TransactionBuildContext>(y => y.SelectedInputs.Count == 1)));
        }
        public void ChoosingInvalidInputFails()
        {
            const int utxoIndex       = 0;
            uint256   utxoId          = uint256.Zero;
            uint256   utxoIdUnused    = uint256.One;
            string    senderAddress   = uint160.Zero.ToBase58Address(this.network);
            string    contractAddress = uint160.One.ToBase58Address(this.network);

            var request = new BuildCallContractTransactionRequest
            {
                Amount          = "0",
                AccountName     = "account 0",
                ContractAddress = contractAddress,
                FeeAmount       = "0.01",
                GasLimit        = 100_000,
                GasPrice        = 100,
                MethodName      = "TestMethod",
                WalletName      = "wallet",
                Password        = "******",
                Sender          = senderAddress,
                Outpoints       = new List <OutpointRequest>
                {
                    new OutpointRequest
                    {
                        Index         = utxoIndex,
                        TransactionId = new uint256(64).ToString() // A tx we don't have.
                    },
                }
            };

            this.walletManager.Setup(x => x.GetAddressBalance(request.Sender))
            .Returns(new AddressBalance
            {
                Address         = senderAddress,
                AmountConfirmed = new Money(100, MoneyUnit.BTC)
            });

            this.walletManager.Setup(x => x.GetSpendableTransactionsInWallet(It.IsAny <string>(), 0))
            .Returns(new List <UnspentOutputReference>
            {
                new UnspentOutputReference
                {
                    Address = new HdAddress
                    {
                        Address = senderAddress
                    },
                    Transaction = new TransactionData
                    {
                        Id    = utxoId,
                        Index = utxoIndex,
                    }
                }, new UnspentOutputReference
                {
                    Address = new HdAddress
                    {
                        Address = senderAddress
                    },
                    Transaction = new TransactionData
                    {
                        Id    = utxoIdUnused,
                        Index = utxoIndex,
                    }
                }
            });

            var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock <ISignals>().Object);

            var service = new SmartContractTransactionService(
                this.network,
                this.walletManager.Object,
                this.walletTransactionHandler.Object,
                this.stringSerializer.Object,
                this.callDataSerializer.Object,
                this.addressGenerator.Object,
                this.stateRepository.Object,
                reserveUtxoService);

            BuildCallContractTransactionResponse result = service.BuildCallTx(request);

            Assert.False(result.Success);
            Assert.StartsWith("An invalid list of request outpoints", result.Message);
        }