Ejemplo n.º 1
0
        /// <summary>
        /// Gets a cold staking account.
        /// </summary>
        /// <remarks>
        /// <para>In order to keep track of cold staking addresses and balances we are using <see cref="HdAccount"/>'s
        /// with indexes starting from the value defined in <see cref="Wallet.Wallet.SpecialPurposeAccountIndexesStart"/>.
        /// </para><para>
        /// We are using two such accounts, one when the wallet is in the role of cold wallet, and another one when
        /// the wallet is in the role of hot wallet. For this reason we specify the required account when calling this
        /// method.
        /// </para></remarks>
        /// <param name="wallet">The wallet where we wish to create the account.</param>
        /// <param name="isColdWalletAccount">Indicates whether we need the cold wallet account (versus the hot wallet account).</param>
        /// <returns>The cold staking account or <c>null</c> if the account does not exist.</returns>
        internal HdAccount GetColdStakingAccount(Wallet.Wallet wallet, bool isColdWalletAccount)
        {
            this.logger.LogTrace("({0}:'{1}',{2}:{3})", nameof(wallet), wallet.Name, nameof(isColdWalletAccount), isColdWalletAccount);

            var       coinType = (CoinType)wallet.Network.Consensus.CoinType;
            HdAccount account  = wallet.GetAccountByCoinType(isColdWalletAccount ? ColdWalletAccountName : HotWalletAccountName, coinType);

            if (account == null)
            {
                this.logger.LogTrace("(-)[ACCOUNT_DOES_NOT_EXIST]:null");
                return(null);
            }

            this.logger.LogTrace("(-):'{0}'", account.Name);
            return(account);
        }
        private BuildCallContractTransactionResponse BuildCallTx(BuildCallContractTransactionRequest request)
        {
            this.logger.LogTrace(request.ToString());

            AddressBalance addressBalance = this.walletManager.GetAddressBalance(request.Sender);

            if (addressBalance.AmountConfirmed == 0)
            {
                return(BuildCallContractTransactionResponse.Failed($"The 'Sender' address you're trying to spend from doesn't have a confirmed balance. Current unconfirmed balance: {addressBalance.AmountUnconfirmed}. Please check the 'Sender' address."));
            }

            var selectedInputs = new List <OutPoint>();

            selectedInputs = this.walletManager.GetSpendableTransactionsInWallet(request.WalletName, MinConfirmationsAllChecks).Where(x => x.Address.Address == request.Sender).Select(x => x.ToOutPoint()).ToList();

            ulong   gasPrice       = ulong.Parse(request.GasPrice);
            ulong   gasLimit       = ulong.Parse(request.GasLimit);
            uint160 addressNumeric = new Address(request.ContractAddress).ToUint160(this.network);

            SmartContractCarrier carrier;

            if (request.Parameters != null && request.Parameters.Any())
            {
                carrier = SmartContractCarrier.CallContract(ReflectionVirtualMachine.VmVersion, addressNumeric, request.MethodName, gasPrice, new Gas(gasLimit), request.Parameters);
            }
            else
            {
                carrier = SmartContractCarrier.CallContract(ReflectionVirtualMachine.VmVersion, addressNumeric, request.MethodName, gasPrice, new Gas(gasLimit));
            }

            HdAddress senderAddress = null;

            if (!string.IsNullOrWhiteSpace(request.Sender))
            {
                Wallet.Wallet wallet  = this.walletManager.GetWallet(request.WalletName);
                HdAccount     account = wallet.GetAccountByCoinType(request.AccountName, this.coinType);
                senderAddress = account.GetCombinedAddresses().FirstOrDefault(x => x.Address == request.Sender);
            }

            ulong totalFee = (gasPrice * gasLimit) + Money.Parse(request.FeeAmount);
            var   context  = new TransactionBuildContext(
                new WalletAccountReference(request.WalletName, request.AccountName),
                new[] { new Recipient {
                            Amount = request.Amount, ScriptPubKey = new Script(carrier.Serialize())
                        } }.ToList(),
                request.Password)
            {
                TransactionFee   = totalFee,
                ChangeAddress    = senderAddress,
                SelectedInputs   = selectedInputs,
                MinConfirmations = MinConfirmationsAllChecks,
                UseAllInputs     = false,
                DustPrevention   = false
            };

            try
            {
                Transaction transaction = this.walletTransactionHandler.BuildTransaction(context);
                return(BuildCallContractTransactionResponse.Succeeded(request.MethodName, transaction, context.TransactionFee));
            }
            catch (Exception exception)
            {
                return(BuildCallContractTransactionResponse.Failed(exception.Message));
            }
        }