private static void CheckCoinbaseSignatureScript(Transaction.Input coinbaseInput) { var scriptLength = coinbaseInput.SignatureScript.Length; if (scriptLength < BlockChain.MinCoinbaseScriptLength || scriptLength > BlockChain.MaxCoinbaseScriptLength) { throw new TransactionRuleException($"Coinbase transaction input signature script length {scriptLength} is outside valid range"); } }
private async Task RecalculatePendingTransaction() { if (PendingOutputs.Count == 0 || PendingOutputs.Any(x => !x.IsValid)) { UnsetPendingTransaction(); return; } var walletClient = App.Current.Synchronizer?.WalletRpcClient; var outputs = PendingOutputs.Select(po => { var amount = po.OutputAmount; var script = po.BuildOutputScript().Script; return new Transaction.Output(amount, Transaction.Output.LatestPkScriptVersion, script); }).ToArray(); TransactionAuthor.InputSource inputSource = async targetAmount => { var inputs = new Transaction.Input[0]; // TODO: don't hardcode confs var funding = await walletClient.FundTransactionAsync(SelectedAccount.Account, targetAmount, 1); if (funding.Item2 >= targetAmount) { inputs = funding.Item1.Select(o => Transaction.Input.CreateFromPrefix(new Transaction.OutPoint(o.TransactionHash, o.OutputIndex, o.Tree), TransactionRules.MaxInputSequence)).ToArray(); } return Tuple.Create(funding.Item2, inputs); }; TransactionAuthor.ChangeSource changeSource = async () => { // Use cached change script if one has already been generated for this account. var selectedAccount = SelectedAccount.Account; OutputScript cachedScript; if (_unusedChangeScripts.TryGetValue(selectedAccount, out cachedScript)) return cachedScript; var changeAddress = await walletClient.NextInternalAddressAsync(SelectedAccount.Account); var changeScript = Address.Decode(changeAddress).BuildScript(); _unusedChangeScripts[selectedAccount] = changeScript; return changeScript; }; try { var r = await TransactionAuthor.BuildUnsignedTransaction(outputs, TransactionFees.DefaultFeePerKb, inputSource, changeSource); SetPendingTransaction(r.Item1, r.Item2, outputs.Sum(o => o.Amount)); } catch (Exception ex) { UnsetPendingTransaction(); // Insufficient funds will need a nicer error displayed somehow. For now, hide it // while disabling the UI to create the transaction. All other errors are unexpected. if (!(ex is InsufficientFundsException)) throw; } }