Esempio n. 1
0
        public static bool CallContract(Net net, KeyPair key, string scriptHash, byte[] bytes)
        {
            /*var invoke = TestInvokeScript(net, bytes);
             * if (invoke.state == null)
             * {
             *  throw new Exception("Invalid script invoke");
             * }
             *
             * decimal gasCost = invoke.gasSpent;*/

            var unspent = GetUnspent(net, key.address);

            if (!unspent.ContainsKey("GAS"))
            {
                throw new Exception("Not GAS available");
            }

            var sources = unspent["GAS"];


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

            /*var output = new Transaction.Output()
             * {
             *  assetID = gasId,
             *  scriptHash = outputHash,
             *  value = gasCost
             * };
             * outputs.Add(output);*/

            var gasCost = 0;

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

            decimal selectedGas = 0;

            foreach (var src in sources)
            {
                selectedGas += src.value;

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

                inputs.Add(input);

                if (selectedGas >= gasCost)
                {
                    break;
                }
            }

            if (selectedGas < gasCost)
            {
                throw new Exception("Not enough GAS");
            }

            if (selectedGas > gasCost)
            {
                var left = selectedGas - gasCost;

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

            Transaction tx = new Transaction()
            {
                type    = 0xd1,
                version = 0,
                script  = bytes,
                gas     = gasCost,
                inputs  = inputs.ToArray(),
                outputs = outputs.ToArray()
            };

            //File.WriteAllBytes("output2.avm", bytes);


            tx = tx.Sign(key);

            var hexTx = SerializeTransaction(tx, true);

            var response = QueryRPC(net, "sendrawtransaction", new object[] { hexTx });

            return(response.GetBool("result"));
        }
Esempio n. 2
0
        private static string SerializeTransactionOutput(Transaction.Output output)
        {
            var value = num2fixed8(output.value);

            return(reverseHex(output.assetID) + value + reverseHex(output.scriptHash));
        }
Esempio n. 3
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);
                }
            }
        }