private void txtTx_TextChanged(object sender, EventArgs e) { if (disableUpdate) { return; } try { Transaction tx = new Transaction(HexString.ToByteArray(txtTx.Text)); // Disable *_Changed events disableUpdate = true; // Clear everything UTXO.Clear(); updateUTXOList(); selectedUTXO.Clear(); dgvOutputs.Rows.Clear(); outputs.Clear(); foreach (TxIn txin in tx.inputs) { TxOutId txi; TxOut txo; // Try local bitcoind first if (rpc != null) { try { string sPrevTx = rpc.doRequest <string>("getrawtransaction", new object[] { HexString.FromByteArrayReversed(txin.prevOut) }); Transaction prevTx = new Transaction(HexString.ToByteArray(sPrevTx)); txi = new TxOutId(txin.prevOut, txin.prevOutIndex); txo = prevTx.outputs[txin.prevOutIndex]; UTXO.Add(txi, txo); selectedUTXO.Add(txi, txo); continue; } catch (Exception) { } } // Get from blockchain if bitcoind fails try { string json; using (WebClient wc = new WebClient()) { json = wc.DownloadString("https://blockchain.info/rawtx/" + HexString.FromByteArrayReversed(txin.prevOut)); } JavaScriptSerializer jss = new JavaScriptSerializer(); Dictionary <string, object> jso = jss.Deserialize <Dictionary <string, object> >(json); Dictionary <string, object>[] outs = jss.ConvertToType <Dictionary <string, object>[]>(jso["out"]); Address addr = new Address((string)outs[txin.prevOutIndex]["addr"]); byte[] scriptPubKey = scriptPubKey = ScriptTemplate.PayToAddress(addr).ToBytes(); txi = new TxOutId(txin.prevOut, txin.prevOutIndex); txo = new TxOut(jss.ConvertToType <UInt64>(outs[txin.prevOutIndex]["value"]), scriptPubKey); UTXO.Add(txi, txo); selectedUTXO.Add(txi, txo); } catch (Exception) { MessageBox.Show("Could not get input data."); return; } } updateUTXOList(); foreach (DataGridViewRow row in dgvInputs.Rows) { row.Cells["inSelected"].Value = true; } foreach (TxOut txout in tx.outputs) { string addr; try { addr = Address.FromScript(txout.scriptPubKey).ToString(); } catch (Exception) { addr = "Could not decode address"; } dgvOutputs.Rows.Add(addr, (decimal)txout.value / 100000000m); outputs.Add(txout); } updateTx(false); txtTx.ForeColor = SystemColors.WindowText; } // Transaction invalid catch (Exception) { txtTx.ForeColor = Color.Red; return; } finally { disableUpdate = false; } }
private void dgvOutputs_Changed(object sender, EventArgs e) { if (disableUpdate) { return; } disableUpdate = true; outputs.Clear(); for (int i = 0; i < dgvOutputs.Rows.Count; i++) { if (i != dgvOutputs.Rows.Count - 1) { if (!string.IsNullOrWhiteSpace((string)dgvOutputs["outAddress", i].Value)) { try { Address addr = new Address((string)dgvOutputs["outAddress", i].Value); TxOut txo = new TxOut((UInt64)((decimal)dgvOutputs["outAmount", i].Value * 100000000m), ScriptTemplate.PayToAddress(addr).ToBytes()); outputs.Add(txo); dgvOutputs.Rows[i].ErrorText = ""; } catch (Exception) { dgvOutputs.Rows[i].ErrorText = "Invalid"; } } else { dgvOutputs.Rows[i].ErrorText = "Invalid"; } } } updateTx(); disableUpdate = false; }