Esempio n. 1
0
        public string SerializeTransaction(bool signed = true)
        {
            var tx     = this;
            var result = new StringBuilder();

            result.Append(num2hexstring(tx.type));
            result.Append(num2hexstring(tx.version));

            // excluusive data
            if (tx.type == 0xd1)
            {
                result.Append(num2VarInt(tx.script.Length));
                result.Append(Neo.Emulator.Helper.ToHexString(tx.script));
                if (tx.version >= 1)
                {
                    result.Append(LuxUtils.num2fixed8(tx.gas));
                }
            }

            // Don't need any attributes
            result.Append("00");

            result.Append(num2VarInt(tx.inputs.Length));
            foreach (var input in tx.inputs)
            {
                result.Append(SerializeTransactionInput(input));
            }

            result.Append(num2VarInt(tx.outputs.Length));
            foreach (var output in tx.outputs)
            {
                result.Append(SerializeTransactionOutput(output));
            }


            if (signed && tx.witnesses != null && tx.witnesses.Length > 0)
            {
                result.Append(num2VarInt(tx.witnesses.Length));
                foreach (var script in tx.witnesses)
                {
                    result.Append(SerializeWitness(script));
                }
            }

            return(result.ToString().ToLowerInvariant());
        }
Esempio n. 2
0
        public bool SendAsset(KeyPair fromKey, string toAddress, Dictionary <string, decimal> amounts)
        {
            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            var scriptHash = LuxUtils.reverseHex(Neo.Emulator.Helper.ToHexString(toAddress.GetScriptHashFromAddress()));

            GenerateInputsOutputs(fromKey, scriptHash, amounts, out inputs, out outputs);

            Transaction tx = new Transaction()
            {
                type    = 128,
                version = 0,
                script  = null,
                gas     = -1,
                inputs  = inputs.ToArray(),
                outputs = outputs.ToArray()
            };

            tx = tx.Sign(fromKey);

            var hexTx = tx.SerializeTransaction(true);

            return(SendRawTransaction(hexTx));

            /*
             * var account = getAccountFromWIFKey(fromWif);
             * var toScriptHash = getScriptHashFromAddress(toAddress);
             * var balances = getBalance(net, account.address);
             * // TODO: maybe have transactions handle this construction?
             * var intents = _.map(assetAmounts, (v, k) =>
             * {
             *  return { assetId: tx.ASSETS[k], value: v, scriptHash: toScriptHash }
             * });
             * var unsignedTx = tx.create.contract(account.publicKeyEncoded, balances, intents);
             * var signedTx = tx.signTransaction(unsignedTx, account.privateKey);
             * var hexTx = tx.serializeTransaction(signedTx);
             * return queryRPC(net, "sendrawtransaction", new object[] { hexTx }, 4);*/
        }
Esempio n. 3
0
        private static string SerializeTransactionOutput(Output output)
        {
            var value = LuxUtils.num2fixed8(output.value);

            return(LuxUtils.reverseHex(output.assetID) + value + LuxUtils.reverseHex(output.scriptHash));
        }
Esempio n. 4
0
 private static string SerializeTransactionInput(Input input)
 {
     return(LuxUtils.reverseHex(input.prevHash) + LuxUtils.reverseHex(num2hexstring(input.prevIndex, 4)));
 }
Esempio n. 5
0
        private void GenerateInputsOutputs(KeyPair key, string outputHash, Dictionary <string, decimal> ammounts, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs)
        {
            if (ammounts == null || ammounts.Count == 0)
            {
                throw new NeoException("Invalid amount list");
            }

            //var outputHash = toAddress.GetScriptHashFromAddress().ToHexString();

            var unspent = GetUnspent(key.address);

            inputs  = new List <Transaction.Input>();
            outputs = new List <Transaction.Output>();

            foreach (var entry in ammounts)
            {
                var symbol = entry.Key;

                if (!unspent.ContainsKey(symbol))
                {
                    throw new NeoException($"Not enough {symbol} in address {key.address}");
                }
            }

            foreach (var entry in ammounts)
            {
                var symbol = entry.Key;
                var cost   = entry.Value;

                string assetID;

                var info = GetAssetsInfo();
                if (info.ContainsKey(symbol))
                {
                    assetID = info[symbol];
                }
                else
                {
                    throw new NeoException($"{symbol} is not a valid blockchain asset.");
                }

                var sources = unspent[symbol];

                decimal selected = 0;
                foreach (var src in sources)
                {
                    selected += src.value;

                    var input = new Transaction.Input()
                    {
                        prevHash  = src.txid,
                        prevIndex = src.index,
                    };

                    inputs.Add(input);

                    if (selected >= cost)
                    {
                        break;
                    }
                }

                if (selected < cost)
                {
                    throw new NeoException($"Not enough {symbol}");
                }

                if (cost > 0)
                {
                    var output = new Transaction.Output()
                    {
                        assetID    = assetID,
                        scriptHash = outputHash,
                        value      = cost
                    };
                    outputs.Add(output);
                }

                if (selected > cost)
                {
                    var left = selected - cost;

                    var change = new Transaction.Output()
                    {
                        assetID    = assetID,
                        scriptHash = LuxUtils.reverseHex(key.signatureHash.ToArray().ByteToHex()),
                        value      = left
                    };
                    outputs.Add(change);
                }
            }
        }