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")); }
private static string SerializeTransactionOutput(Transaction.Output output) { var value = num2fixed8(output.value); return(reverseHex(output.assetID) + value + reverseHex(output.scriptHash)); }
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); } } }