GenerateInputsOutputs(KeyPair key, string symbol, IEnumerable <TransactionOutput> targets) { if (targets == null) { throw new WalletException("Invalid amount list"); } var address = Helper.CreateSignatureRedeemScript(key.PublicKey); var unspent = await GetUnspent(Wallet.ToAddress(address.ToScriptHash())); // filter any asset lists with zero unspent inputs unspent = unspent.Where(pair => pair.Value.Count > 0).ToDictionary(pair => pair.Key, pair => pair.Value); var inputs = new List <SignedTransaction.Input>(); var outputs = new List <SignedTransaction.Output>(); string assetId; var info = GetAssetsInfo(); if (info.ContainsKey(symbol)) { assetId = info[symbol]; } else { throw new WalletException($"{symbol} is not a valid blockchain asset."); } if (!unspent.ContainsKey(symbol)) { throw new WalletException($"Not enough {symbol} in address {address}"); } decimal cost = 0; var fromHash = key.PublicKeyHash.ToArray(); var transactionOutputs = targets.ToList(); foreach (var target in transactionOutputs) { if (target.AddressHash.SequenceEqual(fromHash)) { throw new WalletException("Target can't be same as input"); } cost += target.Amount; } var sources = unspent[symbol]; decimal selected = 0; foreach (var src in sources) { selected += (decimal)src.Value; var input = new SignedTransaction.Input { PrevHash = src.TxId.HexToBytes().Reverse().ToArray(), PrevIndex = src.N }; inputs.Add(input); if (selected >= cost) { break; } } if (selected < cost) { throw new WalletException($"Not enough {symbol}"); } if (cost > 0) { foreach (var target in transactionOutputs) { var output = new SignedTransaction.Output { AssetId = assetId.HexToBytes().Reverse().ToArray(), ScriptHash = target.AddressHash.ToArray(), Value = target.Amount }; outputs.Add(output); } } if (selected > cost || cost == 0) { var left = selected - cost; var signatureScript = Helper.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); var change = new SignedTransaction.Output { AssetId = assetId.HexToBytes().Reverse().ToArray(), ScriptHash = signatureScript.ToArray(), Value = left }; outputs.Add(change); } return(inputs, outputs); }
public static void SerializeTransactionInput(BinaryWriter writer, SignedTransaction.Input input) { writer.Write(input.PrevHash); writer.Write((ushort)input.PrevIndex); }