// 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)); }
public static string SymbolFromAssetID(byte[] assetID) { var str = assetID.ByteToHex(); var result = SymbolFromAssetID(str); if (result == null) { result = SymbolFromAssetID(NeoUtils.ReverseHex(str)); } return(result); }
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); }
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); }
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); }
// 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)); }
public IEnumerator GetTransaction(string hash, Action <Transaction> callback) { var val = new UInt256(NeoUtils.ReverseHex(hash).HexToBytes()); return(GetTransaction(val, callback)); }
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 }); } } }
public static string GetStringFromScriptHash(byte[] hash) { return(NeoUtils.ReverseHex(hash.ToHexString())); }