Exemplo n.º 1
0
        public async static Task <EthereumTransactionInfo> GetEthTransactionDetails(ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] apdu = { 0x80, 0xE0, 0x00, 0x00 };
            byte[] response;

            try
            {
                response = await SendWrappedAPDU(apdu, 29, connectionState, token, tls);
            }
            catch (Non9000SwException)
            {
                throw new TransactionNotActiveException();
            }

            EthereumTransactionInfo transactionInfo = new EthereumTransactionInfo();

            transactionInfo.type = Helper.MakeUint16(response, 0);

            if (response[2] != 0x00)
            {
                transactionInfo.transactionTooBigToDisplay = true;
            }
            else
            {
                transactionInfo.transactionTooBigToDisplay = false;
            }

            transactionInfo.currentOffset = Helper.MakeUint16(response, 3);
            transactionInfo.address       = new byte[20];
            Array.Copy(response, 5, transactionInfo.address, 0, 20);
            transactionInfo.remainingTime = Helper.MakeUint32(response, 25);
            return(transactionInfo);
        }
Exemplo n.º 2
0
        public static string ParseEthereumTransaction(EthereumTransactionInfo info, byte[] input)
        {
            string htmlOutput = "";
            string details    = "";

            Dictionary <int, string> chainIDDict = new Dictionary <int, string>()
            {
                { 1, "Ethereum mainnet" },
                { 2, "Morden(disused), Expanse mainnet" },
                { 3, "Ropsten" },
                { 4, "Rinkeby" },
                { 30, "Rootstock mainnet" },
                { 31, "Rootstock testnet" },
                { 42, "Kovan" },
                { 61, "Ethereum Classic mainnet" },
                { 62, "Ethereum Classic testnet" },
                { 1337, "Geth private chains (default)" },
            };

            if (info.transactionTooBigToDisplay == true)
            {
                throw new EthParserException("Transaction too big to display.");
            }

            if (info.type == 0x6666)
            {
                throw new EthParserException("A message is being signed. Cannot display.");
            }
            else
            {
                RLPCollection collection = RLP.Decode(input);

                if (collection.Count != 1)
                {
                    throw new EthParserException("Invalid transaction.");
                }

                collection = (RLPCollection)collection[0];

                if (collection.Count != 9)
                {
                    throw new EthParserException("Invalid transaction.");
                }

                string fromAddress = "0x" + string.Join(string.Empty, Array.ConvertAll(info.address, b => b.ToString("x2")));

                string nonce = new BigInteger(collection[0].RLPData).ToString(10);

                string gasPrice                = "";
                var    gasPriceInGwei          = new BigInteger(collection[1].RLPData).DivideAndRemainder(new BigInteger("1000000000"));
                var    gasPriceInGweiRemainder = gasPriceInGwei[1].ToString(10).PadLeft(9, '0').TrimEnd('0');

                if (gasPriceInGweiRemainder == "")
                {
                    gasPrice = gasPriceInGwei[0].ToString(10) + " GWEI";
                }
                else
                {
                    gasPrice = gasPriceInGwei[0].ToString(10) + "." + gasPriceInGweiRemainder + " GWEI";
                }

                string gasLimit  = new BigInteger(collection[2].RLPData).ToString(10);
                string toAddress = "0x" + string.Join(string.Empty, Array.ConvertAll(collection[3].RLPData, b => b.ToString("x2")));

                string value               = "";
                var    valueInEth          = new BigInteger(collection[4].RLPData).DivideAndRemainder(new BigInteger("1000000000000000000"));
                var    valueInEthRemainder = valueInEth[1].ToString(10).PadLeft(18, '0').TrimEnd('0');

                if (valueInEthRemainder == "")
                {
                    value = valueInEth[0].ToString(10) + " ETH";
                }
                else
                {
                    value = valueInEth[0].ToString(10) + "." + valueInEthRemainder + " ETH";
                }



                string data = "None";
                if (collection[5].RLPData != null)
                {
                    data = "0x" + string.Join(string.Empty, Array.ConvertAll(collection[5].RLPData, b => b.ToString("x2")));
                }

                int v = collection[6].RLPData.ToIntFromRLPDecoded();

                string chainID = "";

                if (chainIDDict.ContainsKey(v))
                {
                    chainID = chainIDDict[v];
                }
                else
                {
                    chainID = v.ToString();
                }

                if ((collection[7].RLPData != null) || (collection[8].RLPData != null))
                {
                    throw new EthParserException("Invalid transaction.");
                }

                details += "<b>Send to: </b>" + toAddress + "<br>";
                details += "<b>Send from: </b>" + fromAddress + "<br>";
                details += "<b>Value: </b>" + value + "<br>";
                details += "<b>ChainID: </b>" + chainID + "<br>";
                details += "<b>Gas limit: </b>" + gasLimit + "<br>";
                details += "<b>Gas price: </b>" + gasPrice + "<br>";
                details += "<b>Nonce: </b>" + nonce + "<br>";
                details += "<b>Data: </b>" + data + "<br><br>";
            }

            htmlOutput += details;

            htmlOutput += "Time remaining to confirm: <b>" + (info.remainingTime / 1000).ToString() + "</b> seconds. <br><br>";

            return(htmlOutput);
        }