public void TestDecodeTxNoTail()
        {
            var noTailTransactionXdr =
                "AAAAAEntn0+aXWXUuLtq9RDTOQHw6FKCz4YULdFpx6KrFLM2AAABLACOUUAAAAAEAAAAAQAAAABbFYjQAAAAAH////8AAAABAAAAFEVDTFlQU0VTQ09JTiBQYXltZW50AAAAAwAAAAAAAAABAAAAANqNgkK/Piz99iwrbp+Lr2LjwDKul8tgETQO2igoZaaNAAAAAkVDTFlQU0VTQ09JTgAAAABwYz2lcMDGOi6MU/sYdRuBye2KWD5aolXM/Yxdr8X9+AAAAAAF9eEAAAAAAAAAAAYAAAACRUNMWVBTRVNDT0lOAAAAAHBjPaVwwMY6LoxT+xh1G4HJ7YpYPlqiVcz9jF2vxf34AAAAAAAAAAAAAAABAAAAAEntn0+aXWXUuLtq9RDTOQHw6FKCz4YULdFpx6KrFLM2AAAACAAAAACxJkMYYoztLLzXom8YBWAqFrREfEt3DvmQepBBLNCzbQAAAAAAAAABLNCzbQAAAEDjlco8Cz8GnuFItJVUUEMPYizwC5LLTxueNI9KEf1fgyPZ0hYC5IQP5Augl/p78z5WpnHfFZXYz3vXMf6buhgN";

            var bytes = noTailTransactionXdr.ToCharArray();
            var xdrDataInputStream = new XdrDataInputStream(Convert.FromBase64CharArray(bytes, 0, bytes.Length));

            var decodedTransaction = Transaction.Decode(xdrDataInputStream);
            var memo = decodedTransaction.Memo.Text;

            Assert.AreEqual("ECLYPSESCOIN Payment", memo);
        }
Пример #2
0
        /// <summary>
        ///     Generates Transaction XDR object.
        /// </summary>
        /// <returns></returns>
        public xdr.Transaction ToXdr()
        {
            // fee
            var fee = new Uint32 {
                InnerValue = Fee
            };

            // sequenceNumber
            var sequenceNumberUint = new Uint64 {
                InnerValue = SequenceNumber
            };
            var sequenceNumber = new SequenceNumber {
                InnerValue = sequenceNumberUint
            };

            // sourceAccount
            var sourceAccount = new AccountID {
                InnerValue = SourceAccount.XdrPublicKey
            };

            // operations
            var operations = new xdr.Operation[Operations.Length];

            for (var i = 0; i < Operations.Length; i++)
            {
                operations[i] = Operations[i].ToXdr();
            }

            // ext
            var ext = new xdr.Transaction.TransactionExt {
                Discriminant = 0
            };

            var transaction = new xdr.Transaction
            {
                Fee           = fee,
                SeqNum        = sequenceNumber,
                SourceAccount = sourceAccount,
                Operations    = operations,
                Memo          = Memo.ToXdr(),
                TimeBounds    = TimeBounds?.ToXdr(),
                Ext           = ext
            };

            return(transaction);
        }
Пример #3
0
        public void TestBuilderTimeBounds()
        {
            // GBPMKIRA2OQW2XZZQUCQILI5TMVZ6JNRKM423BSAISDM7ZFWQ6KWEBC4
            var source      = KeyPair.FromSecretSeed("SCH27VUZZ6UAKB67BDNF6FA42YMBMQCBKXWGMFD5TZ6S5ZZCZFLRXKHS");
            var destination = KeyPair.FromAccountId("GDW6AUTBXTOC7FIKUO5BOO3OGLK4SF7ZPOBLMQHMZDI45J2Z6VXRB5NR");

            var account     = new Account(source, 2908908335136768L);
            var transaction = new Transaction.Builder(account)
                              .AddOperation(new CreateAccountOperation.Builder(destination, "2000").Build())
                              .AddTimeBounds(new TimeBounds(42, 1337))
                              .Build();

            transaction.Sign(source);

            // Convert transaction to binary XDR and back again to make sure timebounds are correctly de/serialized.
            var bytes = transaction.ToEnvelopeXdrBase64().ToCharArray();
            var xdrDataInputStream = new XdrDataInputStream(Convert.FromBase64CharArray(bytes, 0, bytes.Length));

            var decodedTransaction = XdrTransaction.Decode(xdrDataInputStream);

            Assert.AreEqual(decodedTransaction.TimeBounds.MinTime.InnerValue, 42);
            Assert.AreEqual(decodedTransaction.TimeBounds.MaxTime.InnerValue, 1337);
        }
        public void TestBuilderFee()
        {
            // GBPMKIRA2OQW2XZZQUCQILI5TMVZ6JNRKM423BSAISDM7ZFWQ6KWEBC4
            var source      = KeyPair.FromSecretSeed("SCH27VUZZ6UAKB67BDNF6FA42YMBMQCBKXWGMFD5TZ6S5ZZCZFLRXKHS");
            var destination = KeyPair.FromAccountId("GDW6AUTBXTOC7FIKUO5BOO3OGLK4SF7ZPOBLMQHMZDI45J2Z6VXRB5NR");

            var account     = new Account(source.AccountId, 2908908335136768L);
            var transaction = new TransactionBuilder(account)
                              .AddOperation(new CreateAccountOperation.Builder(destination, "2000").Build())
                              .AddOperation(new CreateAccountOperation.Builder(destination, "2000").Build())
                              .SetFee(173)
                              .Build();

            // Convert transaction to binary XDR and back again to make sure fee is correctly de/serialized.
            var bytes = transaction.ToUnsignedEnvelopeXdrBase64().ToCharArray();
            var xdrDataInputStream = new XdrDataInputStream(Convert.FromBase64CharArray(bytes, 0, bytes.Length));

            var decodedTransaction = XdrTransaction.Decode(xdrDataInputStream);

            Assert.AreEqual(decodedTransaction.Fee.InnerValue, 173 * 2U);

            var transaction2 = Transaction.FromEnvelopeXdr(transaction.ToUnsignedEnvelopeXdr());

            Assert.AreEqual(transaction.SourceAccount.AccountId, transaction2.SourceAccount.AccountId);
            Assert.AreEqual(transaction.SequenceNumber, transaction2.SequenceNumber);
            Assert.AreEqual(transaction.Memo, transaction2.Memo);
            Assert.AreEqual(transaction.TimeBounds, transaction2.TimeBounds);
            Assert.AreEqual(transaction.Fee, transaction2.Fee);
            Assert.AreEqual(
                ((CreateAccountOperation)transaction.Operations[0]).StartingBalance,
                ((CreateAccountOperation)transaction2.Operations[0]).StartingBalance
                );
            Assert.AreEqual(
                ((CreateAccountOperation)transaction.Operations[1]).StartingBalance,
                ((CreateAccountOperation)transaction2.Operations[1]).StartingBalance
                );
        }
Пример #5
0
        public static Transaction FromEnvelopeXdr(TransactionEnvelope envelope)
        {
            xdr.Transaction transactionXdr = envelope.Tx;
            var             fee            = transactionXdr.Fee.InnerValue;
            KeyPair         sourceAccount  = KeyPair.FromXdrPublicKey(transactionXdr.SourceAccount.InnerValue);
            long            sequenceNumber = transactionXdr.SeqNum.InnerValue.InnerValue;
            Memo            memo           = Memo.FromXdr(transactionXdr.Memo);
            TimeBounds      timeBounds     = TimeBounds.FromXdr(transactionXdr.TimeBounds);

            Operation[] operations = new Operation[transactionXdr.Operations.Length];
            for (int i = 0; i < transactionXdr.Operations.Length; i++)
            {
                operations[i] = Operation.FromXdr(transactionXdr.Operations[i]);
            }

            Transaction transaction = new Transaction(sourceAccount, fee, sequenceNumber, operations, memo, timeBounds);

            foreach (var signature in envelope.Signatures)
            {
                transaction.Signatures.Add(signature);
            }

            return(transaction);
        }
Пример #6
0
        private async Task <bool> ProcessDwToHwTransaction(Guid operationId, stellar_dotnet_sdk.xdr.Transaction tx)
        {
            var fromKeyPair = KeyPair.FromPublicKey(tx.SourceAccount.Ed25519.InnerValue);

            if (!_balanceService.IsDepositBaseAddress(fromKeyPair.Address) || tx.Operations.Length != 1 ||
                tx.Operations[0].Body.PaymentOp == null || string.IsNullOrWhiteSpace(tx.Memo.Text))
            {
                return(false);
            }

            var toKeyPair = KeyPair.FromPublicKey(tx.Operations[0].Body.PaymentOp.Destination.Ed25519.InnerValue);

            if (!_balanceService.IsDepositBaseAddress(toKeyPair.Address))
            {
                return(false);
            }

            var fromAddress = $"{fromKeyPair.Address}{Constants.PublicAddressExtension.Separator}{tx.Memo.Text}";
            var amount      = tx.Operations[0].Body.PaymentOp.Amount.InnerValue;

            // Use our guid-ed OperationId as transaction hash, as it uniquely identifies the transaction,
            // just without dashes to look more hash-y.
            var hash = operationId.ToString("N");

            // While we have only single action within DW->HW transaction,
            // we can use any value to identify action within transaction.
            // Use hashed operation ID to add more diversity.
            var opId = operationId.ToString("N").CalculateHash64();

            var ledger = await _horizonService.GetLatestLedger();

            var updateLedger = (ledger.Sequence * 10) + 1;
            var broadcast    = new TxBroadcast
            {
                OperationId = operationId,
                Amount      = amount,
                Fee         = 0,
                Hash        = hash,
                // ReSharper disable once ArrangeRedundantParentheses
                Ledger    = updateLedger,
                CreatedAt = DateTime.UtcNow
            };

            var assetId = _blockchainAssetsService.GetNativeAsset().Id;
            var balance = await _balanceRepository.GetAsync(assetId, fromAddress);

            if (balance.Balance < amount)
            {
                broadcast.State     = TxBroadcastState.Failed;
                broadcast.Error     = "Not enough balance!";
                broadcast.ErrorCode = TxExecutionError.NotEnoughBalance;
            }
            else
            {
                await _balanceRepository.RecordOperationAsync(assetId, fromAddress, updateLedger, opId, hash, (-1) *amount);

                await _balanceRepository.RefreshBalance(assetId, fromAddress);

                broadcast.State = TxBroadcastState.Completed;
            }

            _chaos.Meow(nameof(ProcessDwToHwTransaction));

            // update state
            await _broadcastRepository.InsertOrReplaceAsync(broadcast);

            return(true);
        }