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);
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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.");
                }
            }
        }
Exemplo n.º 5
0
        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;
            }
        }