//Atomic Transaction Method
        public static void AtomicTransaction()
        {
            //Performing Atomic Transactions

            //PureStake Configuration with AlgodApi
            AlgodApi algodApiInstance = new AlgodApi("https://testnet-algorand.api.purestake.io/ps2", "B3SU4KcVKi94Jap2VXkK83xx38bsv95K5UZm2lab");
            //First Account Address - acc1
            var acc1 = "QQNTMX62E2UZF3264V3OB3O3F6CURWBBHR3MQZPRM26CFVMXUYWOXIKG6E";
            //Second Account Address - acc2
            var acc2 = "RP2HQNAY4F4FWJ6OGOBSLCB73PXHVAQ36R6RAQTYPUEIPR4C7M2YJS4SSE";
            //Key of the Main account that will fund other Accounts
            var key = "hood industry indicate catch erode return wage gas wrong museum lesson renew acid erupt victory swallow distance spy orchard tomorrow organ traffic hen ability drift";
            //Account that will fund other accounts
            var     accountAddress = "DZLN2QPBURBXHGHYY2Z5B3BOBZQS4BXIHJMOVXXDBDF66ZFWLFOXZG4OWE";
            Account src            = new Account(key);

            //Creating a transactionParams on the V2
            Algorand.V2.Model.TransactionParametersResponse transParams;
            try
            {
                transParams = algodApiInstance.TransactionParams();
            }
            catch (ApiException e)
            {
                throw new Exception("Could not get params", e);
            }

            // let's create a transaction group

            //amount to fund other accounts
            var amount = Utils.AlgosToMicroalgos(1);
            //First Transaction
            var tx = Utils.GetPaymentTransaction(new Address(accountAddress), new Address(acc1), amount, "pay message", transParams);
            //Second Transaction
            var tx2 = Utils.GetPaymentTransaction(new Address(accountAddress), new Address(acc2), amount, "pay message", transParams);
            //Grouping the Transactions (Atomic Transactions)
            Digest gid = TxGroup.ComputeGroupID(new Transaction[] { tx, tx2 });

            tx.AssignGroupID(gid);
            tx2.AssignGroupID(gid);
            // already updated the groupid, sign
            var signedTx  = src.SignTransaction(tx);
            var signedTx2 = src.SignTransaction(tx2);

            try
            {
                //contact the signed msgpack
                List <byte> byteList = new List <byte>(Algorand.Encoder.EncodeToMsgPack(signedTx));
                byteList.AddRange(Algorand.Encoder.EncodeToMsgPack(signedTx2));
                var id = algodApiInstance.RawTransaction(byteList.ToArray());
                Console.WriteLine($"Successfully sent tx group with first tx id: {id}");
                Console.WriteLine(Utils.WaitTransactionToComplete(algodApiInstance, id.TxId));
            }
            catch (ApiException e)
            {
                // This is generally expected, but should give us an informative error message.
                Console.WriteLine("Exception when calling algod#rawTransaction: " + e.Message);
            }
            Console.WriteLine("You have successefully arrived the end of this test, please press and key to exit.");
        }
示例#2
0
        public static void Main(params string[] args)
        {
            string ALGOD_API_ADDR = args[0];

            if (ALGOD_API_ADDR.IndexOf("//") == -1)
            {
                ALGOD_API_ADDR = "http://" + ALGOD_API_ADDR;
            }

            string  ALGOD_API_TOKEN  = args[1];
            string  SRC_ACCOUNT      = "typical permit hurdle hat song detail cattle merge oxygen crowd arctic cargo smooth fly rice vacuum lounge yard frown predict west wife latin absent cup";
            string  DEST_ADDR        = "KV2XGKMXGYJ6PWYQA5374BYIQBL3ONRMSIARPCFCJEAMAHQEVYPB7PL3KU";
            string  DEST_ADDR2       = "OAMCXDCH7LIVYUF2HSNQLPENI2ZXCWBSOLUAOITT47E4FAMFGAMI4NFLYU";
            Account src              = new Account(SRC_ACCOUNT);
            var     algodApiInstance = new AlgodApi(ALGOD_API_ADDR, ALGOD_API_TOKEN);

            Algorand.V2.Model.TransactionParametersResponse transParams;
            try
            {
                transParams = algodApiInstance.TransactionParams();
            }
            catch (ApiException e)
            {
                throw new Exception("Could not get params", e);
            }
            // let's create a transaction group
            var amount = Utils.AlgosToMicroalgos(1);
            var tx     = Utils.GetPaymentTransaction(src.Address, new Address(DEST_ADDR), amount, "pay message", transParams);
            var tx2    = Utils.GetPaymentTransaction(src.Address, new Address(DEST_ADDR2), amount, "pay message", transParams);
            //SignedTransaction signedTx2 = src.SignTransactionWithFeePerByte(tx2, feePerByte);
            Digest gid = TxGroup.ComputeGroupID(new Transaction[] { tx, tx2 });

            tx.AssignGroupID(gid);
            tx2.AssignGroupID(gid);
            // already updated the groupid, sign
            var signedTx  = src.SignTransaction(tx);
            var signedTx2 = src.SignTransaction(tx2);

            try
            {
                //contact the signed msgpack
                List <byte> byteList = new List <byte>(Algorand.Encoder.EncodeToMsgPack(signedTx));
                byteList.AddRange(Algorand.Encoder.EncodeToMsgPack(signedTx2));
                var id = algodApiInstance.RawTransaction(byteList.ToArray());
                Console.WriteLine("Successfully sent tx group with first tx id: " + id);
                Console.WriteLine("Confirmed Round is: " +
                                  Utils.WaitTransactionToComplete(algodApiInstance, id.TxId).ConfirmedRound);
            }
            catch (ApiException e)
            {
                // This is generally expected, but should give us an informative error message.
                Console.WriteLine("Exception when calling algod#rawTransaction: " + e.Message);
            }
            Console.WriteLine("You have successefully arrived the end of this test, please press and key to exist.");
            Console.ReadKey();
        }
示例#3
0
        public void testTransactionGroupLimit()
        {
            Transaction[] txs = new Transaction[TxGroup.MAX_TX_GROUP_SIZE + 1];

            bool   gotExpectedException = false;
            Digest gid = null;

            try
            {
                gid = TxGroup.ComputeGroupID(txs);
            }
            catch (ArgumentException e)
            {
                gotExpectedException = true;
                Assert.AreEqual(e.Message, "max group size is " + TxGroup.MAX_TX_GROUP_SIZE);
            }
            Assert.IsTrue(gotExpectedException);
            Assert.IsNull(gid);
        }
示例#4
0
        async void AtomicTransfer_Clicked(System.Object sender, System.EventArgs e)
        {
            //var transParams = algodApiInstance.TransactionParams();
            AtomicTransfer.Opacity         = .2;
            StackAtomicTransfers.IsEnabled = false;
            Algorand.V2.Model.TransactionParametersResponse transParams = null;
            AtomicTransfer.IsEnabled = false;

            try
            {
                transParams = algodApiInstance.TransactionParams();
            }
            catch (ApiException err)
            {
                throw new Exception("Could not get params", err);
            }
            // let's create a transaction group
            var amount = Utils.AlgosToMicroalgos(1);
            var tx     = Utils.GetPaymentTransaction(account1.Address, account2.Address, amount, "pay message", transParams);
            var tx2    = Utils.GetPaymentTransaction(account1.Address, account3.Address, amount, "pay message", transParams);
            //SignedTransaction signedTx2 = src.SignTransactionWithFeePerByte(tx2, feePerByte);
            Digest gid = TxGroup.ComputeGroupID(new Algorand.Transaction[] { tx, tx2 });

            tx.AssignGroupID(gid);
            tx2.AssignGroupID(gid);
            // already updated the groupid, sign
            var signedTx  = account1.SignTransaction(tx);
            var signedTx2 = account1.SignTransaction(tx2);

            try
            {
                //contact the signed msgpack
                List <byte> byteList = new List <byte>(Algorand.Encoder.EncodeToMsgPack(signedTx));
                byteList.AddRange(Algorand.Encoder.EncodeToMsgPack(signedTx2));
                var act = await algodApiInstance.AccountInformationAsync(account1.Address.ToString());

                var before = "Account 1 balance before: " + act.Amount.ToString();
                var id     = algodApiInstance.RawTransaction(byteList.ToArray());
                var wait   = Utils.WaitTransactionToComplete(algodApiInstance, id.TxId);
                Console.WriteLine(wait);

                // Console.WriteLine("Successfully sent tx group with first tx id: " + id);

                act = await algodApiInstance.AccountInformationAsync(account1.Address.ToString());

                await SecureStorage.SetAsync(helper.StorageAtomicTransaction, wait.ToString());

                var htmlSource = new HtmlWebViewSource();
                htmlSource.Html = @"<html><body><h3>" + before + " </h3>" +
                                  "<h3>" + wait + "</h3>" + "<h3> Account 1 balance after: " + act.Amount.ToString() + "</h3></body></html>";

                myWebView.Source         = htmlSource;
                AtomicTransfer.IsEnabled = true;
            }
            catch (ApiException err)
            {
                // This is generally expected, but should give us an informative error message.
                Console.WriteLine("Exception when calling algod#rawTransaction: " + err.Message);
                AtomicTransfer.IsEnabled = true;
            }
            AtomicTransfer.Opacity         = 1;
            StackAtomicTransfers.IsEnabled = true;
            AtomicTransferInfo.IsEnabled   = true;
            buttonstate();
        }
示例#5
0
        public void testTransactionGroupNull()
        {
            var ex = Assert.Throws <ArgumentException>(() => { TxGroup.ComputeGroupID(); });

            Assert.AreEqual(ex.Message, "empty transaction list");
        }
示例#6
0
        public void testTransactionGroup()
        {
            Address from        = new Address("UPYAFLHSIPMJOHVXU2MPLQ46GXJKSDCEMZ6RLCQ7GWB5PRDKJUWKKXECXI");
            Address to          = new Address("UPYAFLHSIPMJOHVXU2MPLQ46GXJKSDCEMZ6RLCQ7GWB5PRDKJUWKKXECXI");
            ulong   fee         = 1000;
            ulong   amount      = 2000;
            string  genesisID   = "devnet-v1.0";
            Digest  genesisHash = new Digest("sC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0E=");
            ulong   firstRound1 = 710399;

            byte[] note1 = Convert.FromBase64String("wRKw5cJ0CMo=");


            var tx1 = new Transaction(from, fee, firstRound1, firstRound1 + 1000,
                                      note1, amount, to, genesisID, genesisHash);

            ulong firstRound2 = 710515;

            byte[] note2 = Convert.FromBase64String("dBlHI6BdrIg=");


            var tx2 = new Transaction(from, fee, firstRound2, firstRound2 + 1000,
                                      note2, amount, to, genesisID, genesisHash);

            // check serialization/deserialization without group field
            Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx1)), tx1);
            Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx2)), tx2);

            string goldenTx1 = "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK2uekbm90ZcQIwRKw5cJ0CMqjcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5";
            string goldenTx2 = "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArXc6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK21ukbm90ZcQIdBlHI6BdrIijcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5";

            // goal clerk send dumps unsigned transaction as signed with empty signature in order to save tx type
            SignedTransaction stx1 = new SignedTransaction(tx1, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx1.TxID());
            SignedTransaction stx2 = new SignedTransaction(tx2, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx2.TxID());

            Assert.AreEqual(Convert.ToBase64String(Encoder.EncodeToMsgPack(stx1)), goldenTx1);
            Assert.AreEqual(Convert.ToBase64String(Encoder.EncodeToMsgPack(stx2)), goldenTx2);
            TestUtil.SerializeDeserializeCheck(stx1);
            TestUtil.SerializeDeserializeCheck(stx2);


            Digest gid = TxGroup.ComputeGroupID(tx1, tx2);

            tx1.AssignGroupID(gid);
            tx2.AssignGroupID(gid);

            // check serialization/deserialization with group field set
            Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx1)), tx1);
            Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx2)), tx2);

            // goal clerk group sets Group to every transaction and concatenate them in output file
            // simulating that behavior here
            string goldenTxg = "gaN0eG6Lo2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bo2dycMQgLiQ9OBup9H/bZLSfQUH2S6iHUM6FQ3PLuv9FNKyt09SibHbOAAra56Rub3RlxAjBErDlwnQIyqNyY3bEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0so3NuZMQgo/ACrPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSykdHlwZaNwYXmBo3R4boujYW10zQfQo2ZlZc0D6KJmds4ACtdzo2dlbqtkZXZuZXQtdjEuMKJnaMQgsC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0GjZ3JwxCAuJD04G6n0f9tktJ9BQfZLqIdQzoVDc8u6/0U0rK3T1KJsds4ACttbpG5vdGXECHQZRyOgXayIo3JjdsQgo/ACrPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSyjc25kxCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKR0eXBlo3BheQ==";

            stx1 = new SignedTransaction(tx1, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx1.TxID());
            stx2 = new SignedTransaction(tx2, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx2.TxID());
            byte[] stx1Enc = Encoder.EncodeToMsgPack(stx1);
            byte[] stx2Enc = Encoder.EncodeToMsgPack(stx2);
            var    concat  = stx1Enc.ToList();

            concat.AddRange(stx2Enc);

            Assert.AreEqual(Convert.ToBase64String(concat.ToArray()), goldenTxg);

            // check assignGroupID
            Transaction[] result = TxGroup.AssignGroupID(tx1, tx2);
            Assert.AreEqual(result.Length, 2);

            result = TxGroup.AssignGroupID(from, tx1, tx2);
            Assert.AreEqual(result.Length, 2);

            result = TxGroup.AssignGroupID(to, tx1, tx2);
            Assert.AreEqual(result.Length, 0);
        }
        public IActionResult GroupedTransactions()
        {
            AlgodApi          algodApiInstance = new AlgodApi("https://testnet-algorand.api.purestake.io/ps1", "B3SU4KcVKi94Jap2VXkK83xx38bsv95K5UZm2lab");
            TransactionParams transparams      = null;

            try
            {
                transparams = algodApiInstance.TransactionParams();
            }
            catch (ApiException err)
            {
                throw new Exception("Could not get params", err);
            }
            //4CLRLFJQK3WKEIHKOYTFJ5TT7W2KKQJQUXVJM4GZYLOHG5FC3C3PNF5XMQ
            var acc1 = "5LDA2DCL4BPUBWMJXLQC47XKGPLYDY2OVBNEKBXUV6GY3NIXBSDSMTIAKA";
            var acc2 = "RSVGYZ5653Z3X6GLFNBNM7NSR2OVQC6WRPPSOQLURI2H5R5DU35OYOQQ5A";
            //AE47UNNWHF2XCVFF4DAB7WPHKKNL5MFEW2YQ6DTK3HYNGO4GCG32WQAA5I
            var     Key     = "brain under subject brown letter select auto artwork inject display reflect clerk index prosper trick host true stable fork tone drum please loud abstract reject";
            Account account = new Account(Key);
            //Console.WriteLine(account.Address.ToString());
            //Console.WriteLine($"{account.Address.ToString()} and {account.ToMnemonic()}");
            //brain under subject brown letter select auto artwork inject display reflect clerk index prosper trick host true stable fork tone drum please loud abstract reject
            //LLMTMNBRXUF5ARJZLYYJEJPVOGDJ2SBYOHQDWXHOPIODS6ANXBL4S6BECE
            var accountAddress = "LLMTMNBRXUF5ARJZLYYJEJPVOGDJ2SBYOHQDWXHOPIODS6ANXBL4S6BECE";

            var accountInfo = algodApiInstance.AccountInformation("LLMTMNBRXUF5ARJZLYYJEJPVOGDJ2SBYOHQDWXHOPIODS6ANXBL4S6BECE");

            Console.WriteLine($"The address {accountAddress} has a Balance of: {accountInfo.Amount} microAlgos");
            //Let's create a grouped transaction
            var amount = Utils.AlgosToMicroalgos(1);

            var tx1 = Utils.GetPaymentTransaction(new Address(accountAddress), new Address(acc1), amount, "Perfoming First Grouped Transactions", transparams);

            var tx2 = Utils.GetPaymentTransaction(new Address(accountAddress), new Address(acc2), amount, "Perfoming Second Grouped Transactions", transparams);

            Digest gid = TxGroup.ComputeGroupID(new Algorand.Transaction[] { tx1, tx2 });

            tx1.AssignGroupID(gid);
            tx2.AssignGroupID(gid);
            var signedTx1 = account.SignTransaction(tx1);

            var signedTx2 = account.SignTransaction(tx2);

            try
            {
                List <byte> byteList = new List <byte>(Algorand.Encoder.EncodeToMsgPack(signedTx1));

                byteList.AddRange(Algorand.Encoder.EncodeToMsgPack(signedTx2));
                var acc = algodApiInstance.AccountInformation(accountAddress);

                var before = $"Account 1 Balance before: {acc.Amount.ToString()}";

                var id = algodApiInstance.RawTransaction(byteList.ToArray());

                var wait = Utils.WaitTransactionToComplete(algodApiInstance, id.TxId);

                //Console.WriteLine(wait);
                //Console.WriteLine($"Transfer sent to Tx group with id: {id}");
                acc = algodApiInstance.AccountInformation(accountAddress.ToString());
            }
            catch (ApiException err)
            {
                //Console.WriteLine($"Exception when calling algodrawtransactions: {err.Message}");
            }
            return(RedirectToAction(nameof(Index)));
        }