Exemplo n.º 1
0
    void PPChanged(object sender, TextChangedEventArgs e)
    {
        m_textBoxPP.Background = Brushes.White;
        m_paragraphAddress.Inlines.Clear();

        // empty
        if (m_textBoxPP.Text == "")
        {
            m_paragraphAddress.Inlines.Add(
                "Select any charset from menu to generate random password with " + m_passwordStrengthBit + "-bit strength.\n"
                + "ETH and ETC addresses are derived from the password.\n\n"
                + "Procedures:\n"
                + "random password -> EC private key -> EC public key -> ETH and ETC addresses\n");
            return;
        }

        // private key
        BigInteger privateKey;

        if (EllipticCurve.HexToPrivateKey(m_textBoxPP.Text, out privateKey))
        {
            m_textBoxPP.Background = Brushes.LightSkyBlue;
            Output(privateKey);
            return;
        }

        // password
        BigInteger keySpace    = Password.GetKeySpace(m_textBoxPP.Text);
        BigInteger keySpaceMin = BigInteger.Pow(2, m_passwordStrengthBit);

        if (keySpace < 0)
        {
            m_paragraphAddress.Inlines.Add("Password contains invalid character.\n");
        }
        else if (keySpace < keySpaceMin)
        {
            m_paragraphAddress.Inlines.Add("Current password charset: " + string.Join(" ", Password.GetCharsetNames(m_textBoxPP.Text)) + "\n");
            m_paragraphAddress.Inlines.Add("Current Password length: " + m_textBoxPP.Text.Length + "\n");
            m_paragraphAddress.Inlines.Add("Current Password strength: " + keySpace + "\n");
            m_paragraphAddress.Inlines.Add("Minimum password strength: " + keySpaceMin + "\n");
        }
        else
        {
            m_paragraphAddress.Inlines.Add("Password (confidential): " + m_textBoxPP.Text + "\n");
            Output(Password.PasswordToPrivateKey(m_textBoxPP.Text));
        }
    }
    void UpdateTransaction(bool loadNonce)
    {
        m_paragraphTransaction.Inlines.Clear();

        // Password / Private key
        BigInteger privateKey;

        if (EllipticCurve.HexToPrivateKey(m_passwordBoxPP.Password, out privateKey))
        {
            m_passwordBoxPP.Background = Brushes.LightSkyBlue;
        }
        else
        {
            m_passwordBoxPP.Background = Brushes.White;

            if (Password.GetKeySpace(m_passwordBoxPP.Password) < BigInteger.Pow(2, m_passwordStrengthBit))
            {
                return;
            }

            privateKey = Password.PasswordToPrivateKey(m_passwordBoxPP.Password);
        }

        BigInteger publicKeyX;
        BigInteger publicKeyY;

        BouncyCastle.ECPrivateKeyToPublicKey(privateKey, out publicKeyX, out publicKeyY);

        byte[] publicKey = EllipticCurve.PublicKeyToBytes(publicKeyX, publicKeyY);
        byte[] address   = ETHAddress.PublicKeyToETHAddress(publicKey);

        PrintAddressAndBlockExplorer("From", address);

        // Nonce
        if (loadNonce)
        {
            string text = "";
            if (m_dAddressNonce.ContainsKey(Encode.BytesToHex(address)))
            {
                text = m_dAddressNonce[Encode.BytesToHex(address)];
            }

            Dispatcher.BeginInvoke(new Action(() => m_comboBoxNonce.Text = text));
        }

        if (!BigInteger.TryParse(m_comboBoxNonce.Text, out m_tx.m_nonce))
        {
            m_paragraphTransaction.Inlines.Add("Nonce: <Invalid>\n"); return;
        }
        if (m_tx.m_nonce < 0)
        {
            m_paragraphTransaction.Inlines.Add("Nonce: <Invalid>\n"); return;
        }

        m_paragraphTransaction.Inlines.Add("Nonce: " + m_tx.m_nonce + "\n");

        // To
        string to    = m_comboBoxTo.Text.Trim();
        int    index = to.IndexOf(" ");

        if (index != -1)
        {
            to = to.Substring(0, index);
        }
        m_tx.m_to = Encode.HexToBytes(to);

        if (m_tx.m_to == null)
        {
            m_paragraphTransaction.Inlines.Add("To: <Invalid>\n");       return;
        }
        else if (m_tx.m_to.Length == 0)
        {
            m_paragraphTransaction.Inlines.Add("To: Empty\n");
        }
        else if (m_tx.m_to.Length == 20)
        {
            PrintAddressAndBlockExplorer("To", m_tx.m_to);
        }
        else
        {
            m_paragraphTransaction.Inlines.Add("To: <Invalid>\n");       return;
        }

        // Value
        if (Encode.DecimalToBigInteger(m_comboBoxValue.Text, 18, out m_tx.m_value))
        {
            m_paragraphTransaction.Inlines.Add("Value: " + Encode.BigIntegerToDecimal(m_tx.m_value, 18) + " " + GetCurrency() + "\n");
        }
        else
        {
            m_paragraphTransaction.Inlines.Add("Value: <Invalid>\n");
            return;
        }

        // Init / Data
        if (m_tx.m_initOrData.Length > 0)
        {
            m_paragraphTransaction.Inlines.Add("Init / Data: " + m_tx.m_initOrData.Length + " bytes\n");
        }

        // Gas price
        if (!Encode.DecimalToBigInteger(m_comboBoxGasPrice.Text, 18, out m_tx.m_gasPrice))
        {
            m_paragraphTransaction.Inlines.Add("Gas price: <Invalid>\n");
            return;
        }

//		m_paragraphTransaction.Inlines.Add("Gas price: " + Encode.BigIntegerToDecimal(m_tx.m_gasPrice, 18) + " " + GetCurrency() + "\n");

        // Gas limit
        if (!BigInteger.TryParse(m_comboBoxGasLimit.Text, out m_tx.m_gasLimit))
        {
            m_paragraphTransaction.Inlines.Add("Gas limit: <Invalid>\n");   return;
        }
        if (m_tx.m_gasLimit < 0)
        {
            m_paragraphTransaction.Inlines.Add("Gas limit: <Invalid>\n");   return;
        }

//		m_paragraphTransaction.Inlines.Add("Gas limit: " + m_tx.m_gasLimit + "\n");

        BigInteger gasLimitMin = m_tx.GetGasLimitMin();

        if (m_tx.m_gasLimit < gasLimitMin)
        {
            m_paragraphTransaction.Inlines.Add(new Run("Minimal gas limit is " + gasLimitMin + ".\n")
            {
                Foreground = Brushes.Red
            });
        }

        // calculation
        m_paragraphTransaction.Inlines.Add(new Run("Fee: " + Encode.BigIntegerToDecimal(m_tx.m_gasPrice * m_tx.m_gasLimit, 18) + " " + GetCurrency() + "\n")
        {
            ToolTip = "Fee = Gas price * Gas limit"
        });
        m_paragraphTransaction.Inlines.Add(new Run("Value + Fee: " + Encode.BigIntegerToDecimal(m_tx.m_value + m_tx.m_gasPrice * m_tx.m_gasLimit, 18) + " " + GetCurrency() + "\n")
        {
            ToolTip = "Fee = Gas price * Gas limit"
        });

        // additional check
        if (m_tx.m_to.Length == 0 && m_tx.m_initOrData.Length == 0)
        {
            return;
        }

        // tx
        m_tx.ECDsaSign(GetCurrency(), privateKey);
        byte[] tx   = m_tx.EncodeRLP();
        byte[] hash = BouncyCastle.Keccak(tx);

        // button
        foreach (string node in m_lNode)
        {
            Button buttonSend = new Button()
            {
                Margin = new Thickness(2), Content = "Send to " + node, ToolTip = "Send raw transaction to " + node
            };
            buttonSend.Click += (sender, e) =>
            {
                // save
                string file = GetCurrency() + "_tx_" + DateTime.Now.ToString("yyMMdd_HHmmss") + "_0x" + Encode.BytesToHex(hash);
                File.WriteAllBytes(file, tx);

                // nonce read
                m_dAddressNonce.Clear();

                foreach (var entry in ConfigFile.ReadAddressInfo(GetCurrency() + "_nonce"))
                {
                    m_dAddressNonce[entry.Item1] = entry.Item2;
                }

                // nonce update
                m_dAddressNonce[Encode.BytesToHex(address)] = m_tx.m_nonce.ToString();

                // nonce write
                List <string> lLine = new List <string>();
                foreach (var entry in m_dAddressNonce)
                {
                    lLine.Add("0x" + entry.Key + " " + entry.Value);
                }
                File.WriteAllLines(GetCurrency() + "_nonce", lLine);

                // send
                System.Diagnostics.Process.Start("send_transaction.exe", file + " " + node + " -pause");
            };
            m_paragraphTransaction.Inlines.Add(buttonSend);
        }

        Button buttonCopy = new Button()
        {
            Margin = new Thickness(2), Content = "Copy", ToolTip = "Copy raw transaction to clipboard"
        };
        Button buttonSave = new Button()
        {
            Margin = new Thickness(2), Content = "Save", ToolTip = "Save raw transaction to file"
        };

        buttonCopy.Click += (sender, e) => Clipboard.SetText(Encode.BytesToHex(tx));
        buttonSave.Click += (sender, e) =>
        {
            var dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = GetCurrency() + "_tx_0x" + Encode.BytesToHex(hash);
            if (dlg.ShowDialog() == true)
            {
                File.WriteAllBytes(dlg.FileName, tx);
            }
        };

        m_paragraphTransaction.Inlines.Add(buttonCopy);
        m_paragraphTransaction.Inlines.Add(buttonSave);
    }