Example #1
0
        public JObject VerifyRawTransaction(string rawTx, string externalTxHash, bool useNewChainId)
        {
            var ethTx = new TransactionChainId(rawTx.HexToBytes());

            var r = ethTx.Signature.R;

            while (r.Length < 32)
            {
                r = "00".HexToBytes().Concat(r).ToArray();
            }

            var s = ethTx.Signature.S;

            while (s.Length < 32)
            {
                s = "00".HexToBytes().Concat(s).ToArray();
            }

            var v        = ethTx.Signature.V;
            var decodedV = DecodeV(v);

            var signature = r.Concat(s).Concat(v).ToArray().ToSignature(useNewChainId);

            try
            {
                var transaction = MakeTransaction(ethTx);
                var txHash      = transaction.FullHash(signature, useNewChainId);
                if (!txHash.ToBytes().SequenceEqual(externalTxHash.HexToBytes()))
                {
                    return(FormatResult($"tx hash mismatch, calculated hash: {txHash.ToHex()}", UInt256Utils.Zero, 0));
                }
                var receipt = new TransactionReceipt
                {
                    Hash        = txHash,
                    Signature   = signature,
                    Status      = TransactionStatus.Pool,
                    Transaction = transaction
                };
                var publicKey = receipt.RecoverPublicKey(useNewChainId);
                var address   = publicKey.GetAddress();
                if (!address.Equals(receipt.Transaction.From))
                {
                    return(FormatResult($"Address mismatch, got address: {address.ToHex()}", UInt256Utils.Zero, null));
                }
                var result = _transactionManager.Verify(receipt, useNewChainId);

                if (result != OperatingError.Ok)
                {
                    return(FormatResult($"Transaction is invalid: {result}", UInt256Utils.Zero, 0));
                }
                return(FormatResult("transaction verified", txHash, decodedV));
            }
            catch (Exception e)
            {
                Logger.LogWarning($"Exception in handling fe_verifyRawTransaction: {e}");
                throw;
            }
        }
Example #2
0
        public bool VerifyTransactionImmediately(TransactionReceipt receipt, bool useNewChainId, bool cacheEnabled)
        {
            if (receipt is null)
            {
                throw new ArgumentNullException(nameof(receipt));
            }

            /* validate transaction hash */
            if (!receipt.Hash.Equals(receipt.FullHash(useNewChainId)))
            {
                return(false);
            }

            try
            {
                /* try to verify signature using public key cache to avoid EC recover */
                if (cacheEnabled && _publicKeyCache.TryGetValue(receipt.Transaction.From, out var publicKey))
                {
                    return(VerifyTransactionImmediately(receipt, publicKey, useNewChainId));
                }

                /* recover EC to get public key from signature to compute address */
                publicKey = receipt.RecoverPublicKey(useNewChainId);
                var address = publicKey.GetAddress();

                /* check if recovered address from public key is valid */
                if (!address.Equals(receipt.Transaction.From))
                {
                    return(false);
                }

                /* try to remember public key for this address */
                if (cacheEnabled)
                {
                    _publicKeyCache.Add(receipt.Transaction.From, publicKey);
                }
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"Failed to verify transaction: {ex}");
                return(false);
            }

            return(true);
        }