Пример #1
0
        public void TestAddInputsWithSecurityLevelHigherThanOneShouldAddMultipleTransactionsToHoldSignature()
        {
            var bundle = new Bundle();

            bundle.AddTransaction(
                new Address("TESTVALUE9DONTUSEINPRODUCTION99999VELDTFQHDFTHIHFE9II9WFFDFHEATEI99GEDC9BAUH9EBGZ")
            {
                Balance = 84
            },
                new TryteString(),
                Tag.Empty,
                999999999L);

            bundle.AddInput(
                new List <Address>
            {
                new Address("NVGLHFZWLEQAWBDJXCWJBMVBVNXEG9DALNBTAYMKEMMJ9BCDVVHJJLSTQW9JEJXUUX9JNFGALBNASRDUD")
                {
                    Balance       = 42,
                    KeyIndex      = 4,
                    SecurityLevel = 2
                },
                new Address("XXYRPQ9BDZGKZZQLYNSBDD9HZLI9OFRK9TZCTU9PFAJYXZIZGO9BWLOCNGVMTLFQFMGJWYRMLXSCW9UTQ")
                {
                    Balance       = 42,
                    KeyIndex      = 5,
                    SecurityLevel = 3
                }
            });

            bundle.Finalize();

            Assert.AreEqual(6, bundle.Transactions.Count);
        }
        /// <inheritdoc />
        public async Task <Bundle> PrepareTransferAsync(Seed seed, Bundle bundle, int securityLevel, Address remainderAddress = null, List <Address> inputAddresses = null)
        {
            // user wants to spend IOTA, so we need to find input addresses (if not provided) with valid balances
            if (bundle.Balance > 0)
            {
                inputAddresses = inputAddresses == null
                           ? (await this.GetInputsAsync(seed, bundle.Balance, securityLevel, 0)).Addresses
                           : (await this.GetBalancesAsync(inputAddresses)).Addresses;

                var availableAmount = inputAddresses.Sum(a => a.Balance);

                if (availableAmount < bundle.Balance)
                {
                    throw new IotaApiException($"Insufficient balance! Found {availableAmount}. Need {bundle.Balance}");
                }

                bundle.AddInput(inputAddresses);
            }

            // the bundle balance currently spends less iota tokens than available. that means we have to send remaining funds to a remainder address in order to prevent key reuse
            if (bundle.Balance < 0)
            {
                if (remainderAddress == null)
                {
                    remainderAddress = (await this.GetNewAddressesAsync(seed, 0, 1, securityLevel))[0];
                }

                bundle.AddRemainder(remainderAddress);
            }

            bundle.Finalize();
            bundle.Sign();

            return(bundle);
        }
Пример #3
0
        public void TestBundleHasInsufficientInputsShouldNotBeFinalizable()
        {
            var transfer = new Transfer
            {
                Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB")
                {
                    Balance = 42
                },
                Message = new TryteString(),
                Tag     = Tag.Empty
            };

            var bundle = new Bundle();

            bundle.AddTransaction(transfer.Address, transfer.Message, transfer.Tag, 999999999L);

            bundle.AddInput(
                new List <Address>
            {
                new Address("NVGLHFZWLEQAWBDJXCWJBMVBVNXEG9DALNBTAYMKEMMJ9BCDVVHJJLSTQW9JEJXUUX9JNFGALBNASRDUD")
                {
                    Balance       = 40,
                    KeyIndex      = 0,
                    SecurityLevel = 1
                }
            });

            Assert.AreEqual(2, bundle.Balance);

            bundle.Finalize();
        }
Пример #4
0
        public void TestBundleIsFinalizedShouldThrowExceptionOnAddInput()
        {
            var bundle = new Bundle();

            bundle.AddTransaction(
                new Address("TESTVALUE9DONTUSEINPRODUCTION99999VELDTFQHDFTHIHFE9II9WFFDFHEATEI99GEDC9BAUH9EBGZ")
            {
                Balance = 84
            },
                new TryteString(),
                Tag.Empty,
                999999999L);

            bundle.Finalize();

            bundle.AddInput(
                new List <Address>
            {
                new Address("NVGLHFZWLEQAWBDJXCWJBMVBVNXEG9DALNBTAYMKEMMJ9BCDVVHJJLSTQW9JEJXUUX9JNFGALBNASRDUD")
                {
                    Balance       = 42,
                    KeyIndex      = 4,
                    SecurityLevel = 2
                }
            });
        }
Пример #5
0
        public void TestAddInputsCoversTheExactAmountSpentShouldCreateCorrectTransactionCount()
        {
            var bundle = new Bundle();

            bundle.AddTransaction(
                new Address("TESTVALUE9DONTUSEINPRODUCTION99999VELDTFQHDFTHIHFE9II9WFFDFHEATEI99GEDC9BAUH9EBGZ")
            {
                Balance = 29
            },
                new TryteString(),
                Tag.Empty,
                999999999L);
            bundle.AddTransaction(
                new Address("TESTVALUE9DONTUSEINPRODUCTION99999OGVEEFBCYAM9ZEAADBGBHH9BPBOHFEGCFAM9DESCCHODZ9Y")
            {
                Balance = 13
            },
                new TryteString(),
                Tag.Empty,
                999999999L);

            bundle.AddInput(
                new List <Address>
            {
                new Address("KHWHSTISMVVSDCOMHVFIFCTINWZT9EHJUATYSMCXDSMZXPL9KXREBBYHJGRBCYVGPJQEHEDPXLBDJNQNX")
                {
                    Balance       = 40,
                    KeyIndex      = 1,
                    SecurityLevel = 1
                },
                new Address("GOAAMRU9EALPO9GKBOWUVZVQEJMB9CSGIZJATHRBTRRJPNTSQRZTASRBTQCRFAIDOGTWSHIDGOUUULQIG")
                {
                    Balance       = 2,
                    KeyIndex      = 2,
                    SecurityLevel = 1
                }
            });

            // since balance and spent tokens are even, this should be ignored
            bundle.AddRemainder(new Address("TESTVALUE9DONTUSEINPRODUCTION99999KAFGVCIBLHS9JBZCEFDELEGFDCZGIEGCPFEIQEYGA9UFPAE"));

            bundle.Finalize();

            Assert.AreEqual(4, bundle.Transactions.Count);
        }
Пример #6
0
        public void TestBundleIsFinalizedShouldApplySigningFragmentAndWithExtraTransactionsForSecurityLevelAboveOne()
        {
            var bundle = new Bundle();

            bundle.AddTransaction(
                new Address("TESTVALUE9DONTUSEINPRODUCTION99999VELDTFQHDFTHIHFE9II9WFFDFHEATEI99GEDC9BAUH9EBGZ")
            {
                Balance = 42
            },
                new TryteString("ASDF"),
                Tag.Empty,
                999999999L);

            bundle.AddInput(
                new List <Address>
            {
                new Address("KHWHSTISMVVSDCOMHVFIFCTINWZT9EHJUATYSMCXDSMZXPL9KXREBBYHJGRBCYVGPJQEHEDPXLBDJNQNX")
                {
                    Balance       = 40,
                    KeyIndex      = 1,
                    SecurityLevel = 2
                },
                new Address("GOAAMRU9EALPO9GKBOWUVZVQEJMB9CSGIZJATHRBTRRJPNTSQRZTASRBTQCRFAIDOGTWSHIDGOUUULQIG")
                {
                    Balance       = 2,
                    KeyIndex      = 2,
                    SecurityLevel = 3
                }
            });

            bundle.Finalize();
            bundle.Sign(new KeyGeneratorStub());

            Assert.AreEqual(6, bundle.Transactions.Count);

            Assert.IsTrue(string.IsNullOrEmpty(bundle.Transactions[0].SignatureFragment));

            for (var i = 1; i < bundle.Transactions.Count; i++)
            {
                Assert.IsTrue(!string.IsNullOrEmpty(bundle.Transactions[i].SignatureFragment));
            }
        }
Пример #7
0
        public void TestBundleHasUnspentInputsButRemainderIsGivenShouldBeFinalizable()
        {
            var transfer = new Transfer
            {
                Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB")
                {
                    Balance = 42
                },
                Message = new TryteString(),
                Tag     = Tag.Empty
            };

            var bundle = new Bundle();

            bundle.AddTransaction(transfer.Address, transfer.Message, transfer.Tag, 999999999L);

            bundle.AddInput(
                new List <Address>
            {
                new Address("NVGLHFZWLEQAWBDJXCWJBMVBVNXEG9DALNBTAYMKEMMJ9BCDVVHJJLSTQW9JEJXUUX9JNFGALBNASRDUD")
                {
                    Balance       = 42,
                    KeyIndex      = 0,
                    SecurityLevel = 1
                },
                new Address("XXYRPQ9BDZGKZZQLYNSBDD9HZLI9OFRK9TZCTU9PFAJYXZIZGO9BWLOCNGVMTLFQFMGJWYRMLXSCW9UTQ")
                {
                    Balance       = 2,
                    KeyIndex      = 2,
                    SecurityLevel = 1
                }
            });


            bundle.AddRemainder(new Address("NVGLHFZWLEQAWBDJXCWJBMVBVNXEG9DALNBTAYMKEMMJ9BCDVVHJJLSTQW9JEJXUUX9JNFGALBNASRDUD"));

            bundle.Finalize();

            Assert.AreEqual(0, bundle.Balance);
            Assert.AreEqual(4, bundle.Transactions.Count);
        }