ThinNeo.Transaction signAndBroadcast() { ThinNeo.Transaction trans = GenTran(); if (trans == null) { return(null); } var msg = trans.GetMessage(); trans.witnesses = new ThinNeo.Witness[this.listWitness.Items.Count]; //检查签名 for (var i = 0; i < listWitness.Items.Count; i++) { var item = listWitness.Items[i] as ThinNeo.Witness; var witness = new ThinNeo.Witness(); witness.VerificationScript = item.VerificationScript; witness.InvocationScript = item.InvocationScript; //autoresign { var pubkey = ThinNeo.Helper.GetPublicKeyFromPrivateKey(this.privatekey); var addr = ThinNeo.Helper.GetAddressFromPublicKey(pubkey); if (item.Address == addr) { var signdata = ThinNeo.Helper.Sign(msg, this.privatekey); var sb = new ThinNeo.ScriptBuilder(); sb.EmitPushBytes(signdata); witness.InvocationScript = sb.ToArray(); } } trans.witnesses[i] = witness; } var rawdata = trans.GetRawData(); bool b = rpc_SendRaw(rawdata); if (b) { var str = Tools.CoinTool.RecordTran(trans); this.UpdateTranData(); Tools.CoinTool.SaveRecord(); MessageBox.Show("txid=" + str); ClearTran(); return(trans); } else { MessageBox.Show("transaction error"); ClearTran(); return(null); } }
public static byte[] ShowDialog(Window owner, ThinNeo.Witness witness) { var d = new Dialog_Witness_Edit(); d.Owner = owner; d.vscript = witness.VerificationScript; d.iscript = witness.InvocationScript; d.update(); if (d.ShowDialog() == true) { return(d.iscript); } return(null); }
void signAndBroadcast() { if (this.listInput.Items.Count == 0) { MessageBox.Show("no input"); return; } if (this.listOutput.Items.Count == 0) { MessageBox.Show("no output"); return; } if (this.listWitness.Items.Count == 0) { MessageBox.Show("no witness"); return; } ThinNeo.Transaction trans = new ThinNeo.Transaction(); trans.attributes = new ThinNeo.Attribute[0]; if (tabCType.SelectedIndex == 0) { trans.type = ThinNeo.TransactionType.ContractTransaction; } else if (tabCType.SelectedIndex == 1) { if (lastScript == null) { throw new Exception("need script"); } if (lastFee.HasValue == false) { throw new Exception("need test script"); } trans.type = ThinNeo.TransactionType.InvocationTransaction; trans.extdata = new ThinNeo.InvokeTransData(); (trans.extdata as ThinNeo.InvokeTransData).script = lastScript; (trans.extdata as ThinNeo.InvokeTransData).gas = lastFee.Value; } trans.inputs = new ThinNeo.TransactionInput[this.listInput.Items.Count]; trans.outputs = new ThinNeo.TransactionOutput[this.listOutput.Items.Count]; trans.witnesses = new ThinNeo.Witness[this.listWitness.Items.Count]; for (var i = 0; i < listInput.Items.Count; i++) { var item = listInput.Items[i] as Tools.Input; var input = new ThinNeo.TransactionInput(); input.index = (ushort)item.Coin.fromN; input.hash = ThinNeo.Helper.HexString2Bytes(item.Coin.fromID).Reverse().ToArray();//反转 trans.inputs[i] = input; } for (var i = 0; i < listOutput.Items.Count; i++) { var item = listOutput.Items[i] as Tools.Output; var output = new ThinNeo.TransactionOutput(); output.assetId = ThinNeo.Helper.HexString2Bytes(item.assetID).Reverse().ToArray();//反转 output.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(item.Target); output.value = item.Fix8; trans.outputs[i] = output; } for (var i = 0; i < listWitness.Items.Count; i++) { var item = listWitness.Items[i] as Tools.Witnees; var witness = new ThinNeo.Witness(); if (item.IsSmartContract) { if (item.iscript == null) { throw new Exception("a smartContract witness not set InvocationScript."); } var s = ThinNeo.Helper.GetPublicKeyHashFromAddress(item.address); witness.VerificationScript = rpc_getScript(s); witness.InvocationScript = item.iscript; return; } else //个人鉴证人 { var pubkey = ThinNeo.Helper.GetPublicKeyFromPrivateKey(this.privatekey); var addr = ThinNeo.Helper.GetAddressFromPublicKey(pubkey); if (item.address != addr) { MessageBox.Show("the key is no match with your witness."); } witness.VerificationScript = ThinNeo.Helper.GetScriptFromPublicKey(pubkey); var signdata = ThinNeo.Helper.Sign(trans.GetMessage(), this.privatekey); var sb = new ThinNeo.ScriptBuilder(); sb.EmitPushBytes(signdata); witness.InvocationScript = sb.ToArray(); } trans.witnesses[i] = witness; } var rawdata = trans.GetRawData(); bool b = rpc_SendRaw(rawdata); if (b) { var hash = trans.GetHash(); var str = ThinNeo.Helper.Bytes2HexString(hash.Reverse().ToArray()); MessageBox.Show("txid=" + str); } else { MessageBox.Show("transaction error"); } }
void _updateOutput() { Dictionary <string, Dictionary <string, decimal> > incoins = new Dictionary <string, Dictionary <string, decimal> >(); List <string> needWitness = new List <string>(); //智能合約輸入,記錄 Dictionary <string, byte[]> hadscript = new Dictionary <string, byte[]>(); foreach (Tools.Input input in listInput.Items) { if (incoins.ContainsKey(input.Address) == false) { incoins[input.Address] = new Dictionary <string, decimal>(); } var incoin = incoins[input.Address]; if (incoin.ContainsKey(input.Coin.assetID) == false) { incoin[input.Coin.assetID] = input.Coin.value; } else { incoin[input.Coin.assetID] += input.Coin.value; } if (needWitness.Contains(input.Address) == false) { needWitness.Add(input.Address); } if (input.Script != null) { hadscript[input.Address] = input.Script; } } var pubkey = this.privatekey != null?ThinNeo.Helper.GetPublicKeyFromPrivateKey(this.privatekey) : null; var address = pubkey != null?ThinNeo.Helper.GetAddressFromPublicKey(pubkey) : null; {//处理见证人 List <string> witness = new List <string>(); foreach (ThinNeo.Witness w in listWitness.Items) { witness.Add(w.Address); } foreach (var f in needWitness) { if (witness.Contains(f) == false) { ThinNeo.Witness wit = new ThinNeo.Witness(); if (f == address) { wit.VerificationScript = ThinNeo.Helper.GetScriptFromPublicKey(pubkey); } else if (hadscript.ContainsKey(f))//自帶脚本 { wit.VerificationScript = hadscript[f]; } else { byte[] script = rpc_getScript(ThinNeo.Helper.GetPublicKeyHashFromAddress(f)); if (script != null)//并不知道试试是不是公開的智能合約 { wit.VerificationScript = script; } } listWitness.Items.Add(wit); } } } //去除无法完成的输出 List <Tools.Output> needdel = new List <Tools.Output>(); foreach (Tools.Output output in listOutput.Items) { bool bCon = false; foreach (var incoin in incoins) { if (incoin.Value.ContainsKey(output.assetID)) { bCon = true; break; } } if (bCon == false) { needdel.Add(output); } } foreach (var del in needdel) { listOutput.Items.Remove(del); } //交换合约(utxo来自多个人),不自动找零 if (incoins.Count > 1) { return; } //清除找零 needdel.Clear(); foreach (Tools.Output output in listOutput.Items) { if (output.isTheChange) { needdel.Add(output); } } foreach (var del in needdel) { listOutput.Items.Remove(del); } var moneys = incoins.First().Value; foreach (var money in moneys) { decimal value = 0; foreach (Tools.Output output in listOutput.Items) { if (output.assetID == money.Key) { value += (decimal)output.Fix8; } } decimal last = money.Value - value; if (last > 0) { Tools.Output vout = new Tools.Output(); vout.assetID = money.Key; vout.isTheChange = true; vout.Target = incoins.First().Key; vout.Fix8 = last; listOutput.Items.Add(vout); } else if (last < 0) { throw new Exception("too mush output money."); } } }
private void dapp_sendrawtransaction(DApp_Func func, bool onlyMakeTran = false) { try { dapp_result.Text = ""; dapp_result_raw.Text = ""; //fill script if (string.IsNullOrEmpty(func.call.scriptcall)) { this.lastScript = null; this.tabCType.SelectedIndex = 0; this.updateScript(); lastFee = 0; labelFee.Text = "Fee:" + lastFee; } else { var hash = dapp_getCallParam(func.call.scriptcall); var scrb = new ThinNeo.ScriptBuilder(); var jsonps = func.call.scriptparam; for (var i = jsonps.Length - 1; i >= 0; i--) { dapp_EmitParam(scrb, jsonps[i]); } scrb.EmitAppCall(hash); this.lastScript = scrb.ToArray(); this.tabCType.SelectedIndex = 1; this.updateScript(); lastFee = (decimal)func.call.scriptfee; labelFee.Text = "Fee:" + lastFee; } //fill input this.listInput.Items.Clear(); foreach (var coin in func.call.coins) { var hash = dapp_getCallParam(coin.scripthash); var value = coin.value; tx_fillInputs(hash, coin.asset, value); } //fill output this.updateOutput(); //生成交易,拼签名 var tran = this.GenTran(); if (tran == null) { return; } this.lastTranMessage = tran.GetMessage(); //处理鉴证 foreach (var coin in func.call.witnesses) { byte[] vscript = dapp_getCallParam(coin.vscript); var hash = ThinNeo.Helper.GetScriptHashFromScript(vscript); var addr = ThinNeo.Helper.GetAddressFromScriptHash(hash); ThinNeo.Witness wit = null; foreach (ThinNeo.Witness w in listWitness.Items) { if (w.Address == addr) { wit = w; break; } } if (wit == null) { wit = new ThinNeo.Witness(); wit.VerificationScript = vscript; listWitness.Items.Add(wit); } ThinNeo.ScriptBuilder sb = new ThinNeo.ScriptBuilder(); for (var i = coin.iscript.Length - 1; i >= 0; i--) { dapp_EmitParam(sb, coin.iscript[i]); } wit.InvocationScript = sb.ToArray(); } if (onlyMakeTran) { return; } var ttran = this.signAndBroadcast(); if (tran != null) { this.dapp_result_raw.Text = "sendtran:" + ThinNeo.Helper.Bytes2HexString(ttran.GetHash()); } } catch (Exception err) { this.dapp_result_raw.Text = "error=" + err.Message + "\r\n" + err.StackTrace; } }