public async Task Erc20ServiceUnitTest_SignAndCommitTransaction()
        {
            string           from           = TestConstants.PW_ADDRESS;
            Erc20Transaction ethTransaction = new Erc20Transaction()
            {
                FromAddress  = from,
                GasAmount    = 21000,
                GasPrice     = 30000000000,
                ToAddress    = _contractAddress,
                TokenAddress = _contractAddress,
                TokenAmount  = 30000000000
            };

            string transactionHex = await _erc20Service.GetTransferTransactionRaw(ethTransaction);

            string signedTransaction = SignRawTransaction(transactionHex, _privateKey);
            string transactionHash   = await _erc20Service.SubmitSignedTransaction(from, signedTransaction);

            Nethereum.Signer.Transaction transaction = new Nethereum.Signer.Transaction(signedTransaction.HexToByteArray());

            _client.Verify(x => x.SendRequestAsync <string>(It.IsAny <Nethereum.JsonRpc.Client.RpcRequest>(), null), Times.Once);
            Assert.AreEqual(from, transaction.Key.GetPublicAddress());
            Assert.AreEqual(_nonceCalc._nonceStorage[from].Value, new HexBigInteger(transaction.Nonce.ToHex()));
            Assert.AreEqual(ethTransaction.GasAmount, new HexBigInteger(transaction.GasLimit.ToHex()));
            Assert.AreEqual(new HexBigInteger(0).Value, new HexBigInteger(transaction.Value.ToHex()));
            Assert.AreEqual(ethTransaction.GasPrice, new HexBigInteger(transaction.GasPrice.ToHex()));
            Assert.AreEqual(ethTransaction.ToAddress.ToLower(), transaction.ReceiveAddress.ToHex().EnsureHexPrefix());
        }
예제 #2
0
        public async Task <string> SignAndSendRawTransaction(Nethereum.Signer.Transaction transaction)
        {
            transaction.Sign(new EthECKey(_sender_private_key.HexToByteArray(), isPrivate: true));
            string signed_transaction_data = transaction.GetRLPEncoded().ToHex();
            string tx_hash = await _web3geth.Eth.Transactions.SendRawTransaction.SendRequestAsync(signed_transaction_data);

            return(tx_hash);
        }
        private string SignRawTransaction(string trHex, string privateKey)
        {
            var transaction = new Nethereum.Signer.Transaction(trHex.HexToByteArray());
            var secret      = new EthECKey(privateKey);

            transaction.Sign(secret);

            string signedHex = transaction.GetRLPEncoded().ToHex();

            return(signedHex);
        }
예제 #4
0
        private Nethereum.Signer.Transaction ConvertToTx(RelayResponse response)
        {
            var tx = new Nethereum.Signer.Transaction(
                response.To,
                response.Value.Value,
                response.Nonce.Value,
                response.GasPrice.Value,
                response.Gas.Value,
                response.Input);

            tx.SetSignature(new EthECDSASignature(
                                new Org.BouncyCastle.Math.BigInteger(response.R.RemoveHexPrefix(), 16),
                                new Org.BouncyCastle.Math.BigInteger(response.S.RemoveHexPrefix(), 16),
                                response.V.HexToByteArray()));

            return(tx);
        }
예제 #5
0
        public async Task <string> SendTransactionAsync <T>(T transaction) where T : TransactionInput
        {
            var ethSendTransaction = new EthSendRawTransaction(Client);

            var nonce = await GetNonceAsync(transaction);

            var value    = transaction.Value?.Value ?? 0;
            var gasPrice = await EstimateGasPrice();

            var gasValue = transaction.Gas?.Value ?? Transaction.DEFAULT_GAS_LIMIT;

            var tr       = new Transaction(transaction.To, value, nonce, gasPrice, gasValue, transaction.Data);
            var hex      = tr.GetRLPEncoded().ToHex();
            var response = await _signatureApi.SignTransaction(new SignRequest { From = transaction.From, Transaction = hex });

            return(await ethSendTransaction.SendRequestAsync(response.SignedTransaction.EnsureHexPrefix()).ConfigureAwait(false));
        }
        public Task <bool> IsValidTransactionHex(string transactionHex)
        {
            if (string.IsNullOrEmpty(transactionHex))
            {
                return(Task.FromResult(false));
            }

            try
            {
                var transaction = new Nethereum.Signer.Transaction(transactionHex.HexToByteArray());
            }
            catch (Exception e)
            {
                return(Task.FromResult(false));
            }

            return(Task.FromResult(true));
        }
        public async Task <string> BuildTransactionAsync(
            string from,
            string to,
            BigInteger amount,
            BigInteger gasAmount,
            BigInteger gasPrice)
        {
            var transaction = new NethereumTransaction
                              (
                to: to,
                amount: amount,
                nonce: await GetNextNonceAsync(from),
                gasPrice: gasPrice,
                gasLimit: gasAmount,
                data: null
                              );

            return(transaction
                   .GetRLPEncoded()
                   .ToHex(prefix: true));
        }
예제 #8
0
        public string SignTransaction(
            string transactionContext,
            string privateKey)
        {
            using (var eventHolder = _telemetryClient.StartEvent("TransactionSigned"))
            {
                try
                {
                    var transactionBytes = transactionContext.HexToByteArray();
                    var transactionDto   = MessagePackSerializer.Deserialize <UnsignedTransaction>(transactionBytes);

                    var transaction = new NethereumTransaction
                                      (
                        to: transactionDto.To,
                        amount: transactionDto.Amount,
                        nonce: transactionDto.Nonce,
                        gasPrice: transactionDto.GasPrice,
                        gasLimit: transactionDto.GasAmount,
                        data: null
                                      );

                    transaction.Sign
                    (
                        key: new EthECKey(privateKey)
                    );

                    return(transaction
                           .GetRLPEncoded()
                           .ToHex(prefix: true));
                }
                catch (Exception)
                {
                    eventHolder.TrackFailure("TransactionSigningFailed");

                    throw;
                }
            }
        }
        public async Task Erc20ServiceUnitTest_TestGetTransaction()
        {
            string           from           = TestConstants.PW_ADDRESS;
            Erc20Transaction ethTransaction = new Erc20Transaction()
            {
                FromAddress  = from,
                GasAmount    = 21000,
                GasPrice     = 30000000000,
                ToAddress    = _contractAddress,
                TokenAddress = _contractAddress,
                TokenAmount  = 30000000000
            };

            string transactionHex = await _erc20Service.GetTransferTransactionRaw(ethTransaction);

            Nethereum.Signer.Transaction transaction = new Nethereum.Signer.Transaction(transactionHex.HexToByteArray());

            Assert.AreEqual(_nonceCalc._nonceStorage[from].Value, new HexBigInteger(transaction.Nonce.ToHex()));
            Assert.AreEqual(ethTransaction.GasAmount, new HexBigInteger(transaction.GasLimit.ToHex()));
            Assert.AreEqual(new HexBigInteger(0).Value, new HexBigInteger(transaction.Value.ToHex()));
            Assert.AreEqual(ethTransaction.GasPrice, new HexBigInteger(transaction.GasPrice.ToHex()));
            Assert.AreEqual(ethTransaction.ToAddress.ToLower(), transaction.ReceiveAddress.ToHex().EnsureHexPrefix());
            Assert.IsNotNull(transaction.Data.ToHex().EnsureHexPrefix());
        }
예제 #10
0
    /// <summary>
    /// Gets the signed transaction data from the Trezor wallet.
    /// </summary>
    /// <param name="transaction"> The transaction to sign. </param>
    /// <param name="path"> The path of the address to sign the transaction with. </param>
    /// <param name="onSignatureRequestSent"> Action to call once the signature request has been sent. </param>
    /// <returns> Task returning the SignedTransactionDataHolder instance. </returns>
    protected override async Task <SignedTransactionDataHolder> GetSignedTransactionData(Transaction transaction, string path, Action onSignatureRequestSent)
    {
        var trezorManager = TrezorConnector.GetWindowsConnectedTrezor(GetSignedTransactionDataEnterPin);

        if (trezorManager == null)
        {
            return(null);
        }

        var signedTransactionResponse = (EthereumTxRequest)null;
        var signedTransactionRequest  = new EthereumSignTx
        {
            Nonce            = transaction.Nonce,
            AddressNs        = KeyPath.Parse(path).Indexes,
            GasPrice         = transaction.GasPrice,
            GasLimit         = transaction.GasLimit,
            To               = transaction.ReceiveAddress,
            Value            = transaction.Value,
            DataInitialChunk = transaction.Data,
            DataLength       = (uint)transaction.Data.Length,
            ChainId          = (uint)ethereumNetworkSettings.networkType
        };

        while (true)
        {
            try
            {
                signedTransactionResponse = await trezorManager.SendMessageAsync <EthereumTxRequest, EthereumSignTx>(signedTransactionRequest, onSignatureRequestSent)
                                            .ConfigureAwait(false);

                break;
            }
            catch (FailureException <Failure> )
            {
                if (forceCancel)
                {
                    forceCancel = false;
                    break;
                }

                if (trezorManager.PinRequest.HasValue && trezorManager.PinRequest == false)
                {
                    break;
                }
            }
        }

        if (signedTransactionResponse == null)
        {
            return(new SignedTransactionDataHolder());
        }

        return(new SignedTransactionDataHolder
        {
            signed = true,
            v = signedTransactionResponse.SignatureV,
            r = signedTransactionResponse.SignatureR,
            s = signedTransactionResponse.SignatureS
        });
    }
        public async Task <string> CreateAsync(
            string task_uuid,
            string flight_id, string pid, string ufid,
            string flight_code, string fs_flight_code,
            string departure_utc_offset_hours, string arrival_utc_offset_hours,
            string departure_airport, string arrival_airport,
            string scheduled_departure_date,
            string scheduled_departure_date_time, string scheduled_departure_date_time_local,
            string scheduled_arrival_date_time, string scheduled_arrival_date_time_local,
            BigInteger?nonce = null)
        {
            _logger.LogDebug("FDBC_Nethereum.SmartContracts.Flight.CreateAsync({task_uuid})", task_uuid);

            string sender_address    = _settings.default_sender_address;
            string contract_abi      = _settings.flight_contract_abi;
            string contract_bytecode = _settings.flight_contract_bytecode;

            //====================================
            // deploy contract
            var from     = sender_address;
            var gasLimit = new HexBigInteger(_settings.flight_contract_deploy_gas);
            var wei      = new HexBigInteger(0);

            object[] values = new object[] {
                task_uuid,
                flight_id,
                pid,
                ufid,
                flight_code,
                fs_flight_code,
                departure_utc_offset_hours,
                arrival_utc_offset_hours,
                departure_airport,
                arrival_airport,
                scheduled_departure_date,
                scheduled_departure_date_time,
                scheduled_departure_date_time_local,
                scheduled_arrival_date_time,
                scheduled_arrival_date_time_local
            };


            string tx_hash = "";

            if (nonce != null)
            {
                string data = web3geth.Eth.DeployContract.GetData(contract_bytecode, contract_abi, values);
                Nethereum.Signer.Transaction signable_transcation = new Nethereum.Signer.Transaction(
                    to: null, amount: wei, nonce: (BigInteger)nonce,
                    gasPrice: Nethereum.Signer.Transaction.DEFAULT_GAS_PRICE,
                    gasLimit: gasLimit.Value,
                    data: data
                    );

                tx_hash = await _blockchain_manager.SignAndSendRawTransaction(signable_transcation);

                //_logger.LogDebug("SignAndSendRawTransaction(PrivateKey = {sender_private_key}, Signature = {@Signature}) => tx=hash = {tx_hash}", _blockchain_manager.sender_private_key, signable_transcation.Signature, tx_hash);
            }
            else
            {
                tx_hash = await web3geth.Eth.DeployContract.SendRequestAsync(
                    abi : contract_abi,
                    contractByteCode : contract_bytecode,
                    from : from,
                    gas : gasLimit,
                    value : wei,
                    values : values);
            }

            return(tx_hash);
        }
        public async Task <string> SetFlightAllAttributes(
            string contract_address,
            string task_uuid,
            string status,
            string actual_departure_date_time,
            string actual_departure_date_time_local,
            string actual_arrival_date_time,
            string actual_arrival_date_time_local,
            string cancel_date_time,
            string cancel_date_time_local,
            string deleted,
            string flight_status_source,
            string flight_status_fed,
            string delay_notification_date_time,
            BigInteger?nonce = null
            )
        {
            // SmartContract function doesn't take null as input for string
            status = status ?? "";
            actual_departure_date_time       = actual_departure_date_time ?? "";
            actual_departure_date_time_local = actual_departure_date_time_local ?? "";
            actual_arrival_date_time         = actual_arrival_date_time ?? "";
            actual_arrival_date_time_local   = actual_arrival_date_time_local ?? "";
            cancel_date_time       = cancel_date_time ?? "";
            cancel_date_time_local = cancel_date_time_local ?? "";
            deleted = deleted ?? "";
            flight_status_source         = flight_status_source ?? "";
            flight_status_fed            = flight_status_fed ?? "";
            delay_notification_date_time = delay_notification_date_time ?? "";

            // Web3
            string sender_address = _settings.default_sender_address;
            string contract_abi   = _settings.flight_contract_abi;

            Contract contract = web3geth.Eth.GetContract(contract_abi, contract_address);

            string task_uuid_sha3 = $"0x{_web3geth.Sha3(task_uuid)}";

            byte[] task_uuid_sha3_bytes32 = task_uuid_sha3.HexToByteArray();

            Function set_function = contract.GetFunction("set_all");

            var from     = sender_address;
            var gasLimit = new HexBigInteger(_settings.flight_contract_set_all_gas);
            var wei      = new HexBigInteger(0);

            object[] values = new object[] {
                task_uuid,
                status,
                actual_departure_date_time,
                actual_departure_date_time_local,
                actual_arrival_date_time,
                actual_arrival_date_time_local,
                cancel_date_time,
                cancel_date_time_local,
                deleted,
                flight_status_source,
                flight_status_fed,
                delay_notification_date_time
            };

            string tx_hash = "";

            if (nonce != null)
            {
                string data = set_function.GetData(values);

                Nethereum.Signer.Transaction signable_transcation = new Nethereum.Signer.Transaction(
                    to: contract_address, amount: wei, nonce: (BigInteger)nonce,
                    gasPrice: Nethereum.Signer.Transaction.DEFAULT_GAS_PRICE,
                    gasLimit: gasLimit.Value,
                    data: data
                    );

                tx_hash = await _blockchain_manager.SignAndSendRawTransaction(signable_transcation);
            }
            else
            {
                tx_hash = await set_function.SendTransactionAsync(
                    from : from, gas : gasLimit, value : wei,
                    functionInput : values
                    );
            }

            return(tx_hash);
        }
예제 #13
0
    /// <summary>
    /// Signs a transaction using this IWallet.
    /// </summary>
    /// <typeparam name="T"> The type of the popup to display the transaction confirmation for. </typeparam>
    /// <param name="onTransactionSigned"> The action to call if the transaction is confirmed and signed. </param>
    /// <param name="gasLimit"> The gas limit to use with the transaction. </param>
    /// <param name="gasPrice"> The gas price to use with the transaction. </param>
    /// <param name="value"> The amount of ether in wei being sent along with the transaction. </param>
    /// <param name="addressFrom"> The address of the wallet signing the transaction. </param>
    /// <param name="addressTo"> The address the transaction is being sent to. </param>
    /// <param name="data"> The data sent along with the transaction. </param>
    /// <param name="path"> The path of the wallet to sign the transaction with. </param>
    /// <param name="displayInput"> The display input that goes along with the transaction request. </param>
    public void SignTransaction <T>(
        Action <TransactionSignedUnityRequest> onTransactionSigned,
        BigInteger gasLimit,
        BigInteger gasPrice,
        BigInteger value,
        string addressFrom,
        string addressTo,
        string data,
        string path,
        params object[] displayInput) where T : ConfirmTransactionPopupBase <T>
    {
        if (signingTransaction)
        {
            return;
        }

        signingTransaction = true;

        TransactionUtils.GetAddressTransactionCount(addressFrom).OnSuccess(async txCount =>
        {
            var currentPopupType = popupManager.ActivePopupType;

            var transaction = new Transaction(
                txCount.ToBytesForRLPEncoding(),
                gasPrice.ToBytesForRLPEncoding(),
                gasLimit.ToBytesForRLPEncoding(),
                addressTo.HexToByteArray(),
                value.ToBytesForRLPEncoding(),
                data.HexToByteArray(),
                new byte[] { 0 },
                new byte[] { 0 },
                (byte)ethereumNetworkSettings.networkType);

            var signedTransactionData = await GetSignedTransactionData(
                transaction,
                path,
                () => MainThreadExecutor.QueueAction(() => popupManager.GetPopup <T>(true)?.SetConfirmationValues(null, gasLimit, gasPrice, displayInput))).ConfigureAwait(false);

            signingTransaction = false;

            if (signedTransactionData == null)
            {
                return;
            }
            else if (!signedTransactionData.signed)
            {
                if (currentPopupType != popupManager.ActivePopupType)
                {
                    MainThreadExecutor.QueueAction(() => popupManager.CloseActivePopup());
                }

                return;
            }

            var transactionChainId = new TransactionChainId(
                transaction.Nonce,
                transaction.GasPrice,
                transaction.GasLimit,
                transaction.ReceiveAddress,
                transaction.Value,
                transaction.Data,
                new byte[] { (byte)ethereumNetworkSettings.networkType },
                signedTransactionData.r,
                signedTransactionData.s,
                new byte[] { (byte)signedTransactionData.v });

            MainThreadExecutor.QueueAction(() =>
            {
                onTransactionSigned?.Invoke(new TransactionSignedUnityRequest(transactionChainId.GetRLPEncoded().ToHex(), ethereumNetworkManager.CurrentNetwork.NetworkUrl));
                popupManager.CloseAllPopups();
            });
        });
    }
예제 #14
0
 /// <summary>
 /// Abstract method used for getting the signed transaction data from the hardware wallet.
 /// </summary>
 /// <param name="transaction"> The Transaction object containing all the data to sign. </param>
 /// <param name="path"> The path of the address signing the transaction. </param>
 /// <param name="onSignatureRequestSent"> Action to call once the request for a transaction signature has been sent. </param>
 /// <returns> Task returning the SignedTransactionDataHolder instance. </returns>
 protected abstract Task <SignedTransactionDataHolder> GetSignedTransactionData(Transaction transaction, string path, Action onSignatureRequestSent);
예제 #15
0
    /// <summary>
    /// Gets the signed transaction data from the Ledger wallet.
    /// </summary>
    /// <param name="transaction"> The transaction to sign. </param>
    /// <param name="path"> The path of the address to sign the transaction with. </param>
    /// <param name="onSignatureRequestSent"> Action to call once the signature request has been sent. </param>
    /// <returns> Task returning the SignedTransactionDataHolder instance. </returns>
    protected override async Task <SignedTransactionDataHolder> GetSignedTransactionData(Transaction transaction, string path, Action onSignatureRequestSent)
    {
        var ledgerManager = LedgerConnector.GetWindowsConnectedLedger();
        var address       = ledgerManager == null
            ? null
            : (await ledgerManager.GetPublicKeyResponse(Wallet.ELECTRUM_LEDGER_PATH.Replace("x", "0"), false, false).ConfigureAwait(false))?.Address;

        // Don't sign transaction if app is not Ethereum, or if the first address doesn't match the first address of the opened Ledger wallet.
        if (string.IsNullOrEmpty(address) || !address.EqualsIgnoreCase(addresses[1][0]))
        {
            return(null);
        }

        var addressIndex   = path.Count(c => c == '/') - 1;
        var derivationData = Helpers.GetDerivationPathData(path);

        var request = new EthereumAppSignTransactionRequest(derivationData.Concat(transaction.GetRLPEncoded()).ToArray());

        onSignatureRequestSent?.Invoke();

        var response = await ledgerManager.SendRequestAsync <EthereumAppSignTransactionResponse, EthereumAppSignTransactionRequest>(request).ConfigureAwait(false);

        if (!response.IsSuccess)
        {
            return(new SignedTransactionDataHolder());
        }

        return(new SignedTransactionDataHolder {
            signed = true, v = response.SignatureV, r = response.SignatureR, s = response.SignatureS
        });
    }