public void TestAddressGenerationFromStateWithSecondAddress()
        {
            var path = Bip44AddressGenerator.GenerateAddress(new InMemoryBip44GeneratorState {
                IsInternal = true
            }, false);

            Assert.AreEqual("m/44'/4218'/0'/0'/1'", path.ToString());
        }
예제 #2
0
        public void TestSubseedGenerationFromPath()
        {
            var seed = Ed25519Seed.FromMnemonic("witch collapse practice feed shame open despair creek road again ice least");
            var path = Bip44AddressGenerator.GenerateAddress(1, 1, false);

            var subseed = seed.GenerateSeedFromPath(path);

            var expectedSeed = "56b7b7c582f3ebdfbe904ead6b3455a2a4595029a39126e6c2ebbadd98702ecd";

            Assert.AreEqual(expectedSeed, subseed.SecretKey.ToHex());
        }
예제 #3
0
        public async Task <GetUnspentAddressesResponse> GetUnspentAddressesAsync(GetUnspentAddressesRequest request)
        {
            var nodeInfo = await this.Client.GetNodeInfoAsync();

            var state = new InMemoryBip44GeneratorState
            {
                AccountIndex = request.AccountIndex,
                AddressIndex = request.AddressOptions.StartIndex,
                IsInternal   = false
            };

            var unspentAddresses = new List <Bech32Address>();
            var isFirst          = true;
            var zeroCount        = 0;

            var foundAll = false;

            do
            {
                var bip32Path = Bip44AddressGenerator.GenerateAddress(state, isFirst);
                isFirst = false;

                var addressSeed = request.Seed.GenerateSeedFromPath(bip32Path);
                var address     = Ed25519Address.FromPublicKey(addressSeed.KeyPair.PublicKey);

                var addressWithBalance = await this.Client.GetAddressFromEd25519Async(address.Address);

                if (addressWithBalance.Balance == 0)
                {
                    zeroCount++;
                    if (zeroCount >= request.AddressOptions.ZeroCount)
                    {
                        foundAll = true;
                    }
                }
                else
                {
                    unspentAddresses.Add(Bech32Address.FromEd25519Address(addressWithBalance, bip32Path, nodeInfo.Bech32Hrp));

                    if (unspentAddresses.Count == request.AddressOptions.RequiredCount)
                    {
                        foundAll = true;
                    }
                }
            } while (!foundAll);

            return(new GetUnspentAddressesResponse(unspentAddresses));
        }
        public void TestAddressCreationFromEd25519AddressAndBip31Path()
        {
            var expectedAddressBech32Address = "iota1qq97h4hsl6l67v45cal2ue64k8vrg7xueyv9cv7rrr2tpgjt54xks8esknu";

            var address = new Ed25519Address
            {
                Address = "0bebd6f0febfaf32b4c77eae6755b1d83478dcc9185c33c318d4b0a24ba54d68", Balance = 100, DustAllowed = true
            };

            var path   = Bip44AddressGenerator.GenerateAddress(1, 1, false);
            var actual = Bech32Address.FromEd25519Address(address, path, "iota");

            Assert.AreEqual(expectedAddressBech32Address, actual.Address);
            Assert.AreEqual(path.ToString(), actual.Path.ToString());
            Assert.AreEqual(address.Balance, actual.Balance);
        }
        public void TestAddressGeneration()
        {
            var path = Bip44AddressGenerator.GenerateAddress(1, 1, false);

            Assert.AreEqual("m/44'/4218'/1'/0'/1'", path.ToString());
        }
예제 #6
0
        private async Task <Dictionary <UTXOInput, Ed25519Seed> > CalculateInputsAsync(Ed25519Seed seed, List <TransferOutput> outputs, int zeroCount, int accountIndex, int startIndex)
        {
            var state = new InMemoryBip44GeneratorState
            {
                AccountIndex = accountIndex,
                AddressIndex = startIndex,
                IsInternal   = false
            };

            var inputs           = new Dictionary <UTXOInput, Ed25519Seed>();
            var consumedBalance  = 0L;
            var isFirst          = true;
            var zeroBalanceCount = 0;
            var requiredBalance  = outputs.Sum(o => o.Amount);

            var foundAll = false;

            do
            {
                var bip32Path = Bip44AddressGenerator.GenerateAddress(state, isFirst);
                isFirst = false;

                var addressSeed = seed.GenerateSeedFromPath(bip32Path);
                var address     = Ed25519Address.FromPublicKey(addressSeed.KeyPair.PublicKey);

                var addressOutputs = await this.Client.GetOutputsFromEd25519Async(address.Address);

                if (addressOutputs.Count == 0)
                {
                    zeroBalanceCount++;
                    if (zeroBalanceCount >= zeroCount)
                    {
                        foundAll = true;
                    }
                }
                else
                {
                    foreach (var outputId in addressOutputs.OutputIds)
                    {
                        var addressOutput = await this.Client.FindOutputByIdAsync(outputId);

                        if (!addressOutput.IsSpent &&
                            consumedBalance < requiredBalance)
                        {
                            if (addressOutput.Output.Amount == 0)
                            {
                                zeroBalanceCount++;
                                if (zeroBalanceCount >= zeroCount)
                                {
                                    foundAll = true;
                                }
                            }
                            else
                            {
                                consumedBalance += addressOutput.Output.Amount;

                                inputs.Add(
                                    new UTXOInput
                                {
                                    TransactionId = addressOutput.TransactionId, TransactionOutputIndex = addressOutput.OutputIndex
                                },
                                    addressSeed);

                                if (consumedBalance < requiredBalance)
                                {
                                    continue;
                                }

                                if (consumedBalance - requiredBalance > 0)
                                {
                                    outputs.Add(new TransferOutput(addressOutput.Output.Address, consumedBalance - requiredBalance));
                                }

                                foundAll = true;
                            }
                        }
                    }
                }
            } while (!foundAll);

            return(inputs);
        }