Beispiel #1
0
        // Note: This current implementation requires NeoScan running at port 4000
        public IEnumerator GetClaimable(string address, Action <List <UnspentEntry>, decimal> callback)
        {
            var url = this.neoscanUrl + "/api/main_net/v1/get_claimable/" + address;

            return(ExecuteRequestWeb(
                       (response) =>
            {
                var result = new List <UnspentEntry>();

                var amount = response.GetDecimal("unclaimed");

                response = response["claimable"];

                foreach (var child in response.Children)
                {
                    var txid = child.GetString("txid");
                    var index = child.GetUInt32("n");
                    var value = child.GetDecimal("unclaimed");

                    result.Add(new UnspentEntry()
                    {
                        hash = new UInt256(NeoUtils.ReverseHex(txid).HexToBytes()), index = index, value = value
                    });
                }

                callback(result, amount);
            }
                       , ErrorHandler, url));
        }
Beispiel #2
0
        public static string SymbolFromAssetID(byte[] assetID)
        {
            var str    = assetID.ByteToHex();
            var result = SymbolFromAssetID(str);

            if (result == null)
            {
                result = SymbolFromAssetID(NeoUtils.ReverseHex(str));
            }

            return(result);
        }
Beispiel #3
0
        public static byte[] GetAssetID(string symbol)
        {
            var info = GetAssetsInfo();

            foreach (var entry in info)
            {
                if (entry.Key == symbol)
                {
                    return(NeoUtils.ReverseHex(entry.Value).HexToBytes());
                }
            }

            return(null);
        }
Beispiel #4
0
        public void GenerateInputsOutputs(UnspentEntries unspent, UInt160 key, string symbol, IEnumerable <Transaction.Output> targets, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs, decimal system_fee = 0, bool allowSameSourceAndDest = false)
        {
            var info          = GetAssetsInfo();
            var targetAssetID = NeoUtils.ReverseHex(info[symbol]).HexToBytes();

            if (targets != null)
            {
                foreach (var t in targets)
                {
                    if (t.assetID == null)
                    {
                        t.assetID = targetAssetID;
                    }
                }
            }
            // else  Console.WriteLine("ASSETID target already existed: " + symbol);
            GenerateInputsOutputs(unspent, key, targets, out inputs, out outputs, system_fee, allowSameSourceAndDest);
        }
Beispiel #5
0
        public void GenerateInputsOutputs(UnspentEntries unspent, NeoKeys key, string symbol, IEnumerable <Transaction.Output> targets, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs, decimal system_fee = 0)
        {
            var from_script_hash = new UInt160(key.signatureHash.ToArray());
            var info             = GetAssetsInfo();
            var targetAssetID    = NeoUtils.ReverseHex(info[symbol]).HexToBytes();

            if (targets != null)
            {
                foreach (var t in targets)
                {
                    if (t.assetID == null)
                    {
                        t.assetID = targetAssetID;
                    }
                }
            }
            //else Console.WriteLine("ASSETID target already existed: " + symbol);
            GenerateInputsOutputs(unspent, from_script_hash, targets, out inputs, out outputs, system_fee);
        }
Beispiel #6
0
        // Note: This current implementation requires NeoScan running at port 4000
        public IEnumerator GetUnspent(UInt160 hash, Action <UnspentEntries> callback)
        {
            var url = this.neoscanUrl + "/api/main_net/v1/get_balance/" + hash.ToAddress();

            return(ExecuteRequestWeb(
                       (response) =>
            {
                var unspents = new Dictionary <string, List <UnspentEntry> >();

                response = response["balance"];

                foreach (var child in response.Children)
                {
                    var symbol = child.GetString("asset");

                    List <UnspentEntry> list = new List <UnspentEntry>();
                    unspents[symbol] = list;

                    var unspentNode = child.GetNode("unspent");
                    foreach (var entry in unspentNode.Children)
                    {
                        var txid = entry.GetString("txid");
                        var val = entry.GetDecimal("value");
                        var temp = new UnspentEntry()
                        {
                            hash = new UInt256(NeoUtils.ReverseHex(txid).HexToBytes()), value = val, index = entry.GetUInt32("n")
                        };
                        list.Add(temp);
                    }
                }

                var result = new UnspentEntries()
                {
                    entries = unspents
                };
                callback(result);
            },
                       ErrorHandler,
                       url));
        }
Beispiel #7
0
        public IEnumerator GetTransaction(string hash, Action <Transaction> callback)
        {
            var val = new UInt256(NeoUtils.ReverseHex(hash).HexToBytes());

            return(GetTransaction(val, callback));
        }
Beispiel #8
0
        public void GenerateInputsOutputs(UnspentEntries unspent, UInt160 from_script_hash, IEnumerable <Transaction.Output> targets, out List <Transaction.Input> inputs, out List <Transaction.Output> outputs, decimal system_fee = 0, bool allowSameSourceAndDest = false)
        {
            // filter any asset lists with zero unspent inputs
            var entries = unspent.entries.Where(pair => pair.Value.Count > 0).ToDictionary(pair => pair.Key, pair => pair.Value);

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

            var from_address = from_script_hash.ToAddress();
            var info         = GetAssetsInfo();

            // dummy tx to self
            if (targets == null)
            {
                // We get here from CallContract() method.
                string assetName     = "GAS";
                string assetID       = info[assetName];
                var    targetAssetID = NeoUtils.ReverseHex(assetID).HexToBytes();
                if (!entries.ContainsKey(assetName))
                {
                    throw new NeoException($"Not enough {assetName} in address {from_address}");
                }

                decimal selected = 0;
                if (system_fee == 0)
                {
                    // Taking any GAS unspent entry if no fee is set.
                    var src = entries[assetName][0];
                    selected = src.value;

                    inputs.Add(new Transaction.Input()
                    {
                        prevHash  = src.hash,
                        prevIndex = src.index,
                    });
                }
                else
                {
                    // Taking ALL GAS unspent entries if fee is set and merging them.
                    foreach (var gasEntry in entries[assetName])
                    {
                        selected += gasEntry.value;
                        inputs.Add(new Transaction.Input()
                        {
                            prevHash  = gasEntry.hash,
                            prevIndex = gasEntry.index,
                        });
                    }

                    if (selected < system_fee)
                    {
                        throw new NeoException($"Not enough {assetName} in address {from_address}");
                    }
                }
                // Console.WriteLine("SENDING " + selected + " GAS to source");

                outputs.Add(new Transaction.Output()
                {
                    assetID    = targetAssetID,
                    scriptHash = from_script_hash,
                    value      = selected - system_fee
                });
                return;
            }

            if (!allowSameSourceAndDest)
            {
                foreach (var target in targets)
                {
                    if (target.scriptHash.Equals(from_script_hash))
                    {
                        throw new NeoException("Target can't be same as input");
                    }
                }
            }

            bool done_fee = false;

            foreach (var asset in info)
            {
                string assetName = asset.Key;
                string assetID   = asset.Value;

                if (!entries.ContainsKey(assetName))
                {
                    continue;
                }

                var targetAssetID = NeoUtils.ReverseHex(assetID).HexToBytes();

                var thistargets = targets.Where(o => o.assetID.SequenceEqual(targetAssetID));

                decimal cost = -1;
                foreach (var target in thistargets)
                {
                    if (target.assetID.SequenceEqual(targetAssetID))
                    {
                        if (cost < 0)
                        {
                            cost = 0;
                        }
                        cost += target.value;
                    }
                }

                // incorporate fee in GAS utxo, if sending GAS
                if (system_fee > 0 && assetName == "GAS")
                {
                    done_fee = true;
                    if (cost < 0)
                    {
                        cost = 0;
                    }
                    cost += system_fee;
                }

                if (cost == -1)
                {
                    continue;
                }

                var     sources  = entries[assetName].OrderBy(src => src.value);
                decimal selected = 0;

                // >= cost ou > cost??
                foreach (var src in sources)
                {
                    if (selected >= cost && inputs.Count > 0)
                    {
                        break;
                    }

                    selected += src.value;
                    inputs.Add(new Transaction.Input()
                    {
                        prevHash  = src.hash,
                        prevIndex = src.index,
                    });
                    // Console.WriteLine("ADD inp " + src.ToString());
                }

                if (selected < cost)
                {
                    throw new NeoException($"Not enough {assetName} in address {from_address}");
                }

                if (cost > 0)
                {
                    foreach (var target in thistargets)
                    {
                        outputs.Add(target);
                    }
                }

                if (selected > cost)
                {
                    outputs.Add(new Transaction.Output()
                    {
                        assetID    = targetAssetID,
                        scriptHash = from_script_hash,
                        value      = selected - cost
                    });
                }
            }
        }
Beispiel #9
0
 public static string GetStringFromScriptHash(byte[] hash)
 {
     return(NeoUtils.ReverseHex(hash.ToHexString()));
 }