Exemple #1
0
        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);
        }
Exemple #2
0
 public static void SerializeTransactionInput(BinaryWriter writer, SignedTransaction.Input input)
 {
     writer.Write(input.PrevHash);
     writer.Write((ushort)input.PrevIndex);
 }