示例#1
0
        /// Generates an HD public key derived from an extended public key.
        /// </summary>
        /// <param name="accountExtPubKey">The extended public key used to generate child keys.</param>
        /// <param name="index">The index of the child key to generate.</param>
        /// <param name="isChange">A value indicating whether the public key to generate corresponds to a change address.</param>
        /// <returns>
        /// An HD public key derived from an extended public key.
        /// </returns>

        public Script GeneratePublicKey(int hdPathIndex, Network network, bool isChange = false)
        {
            List <PubKey> derivedPubKeys = new List <PubKey>();

            foreach (var xpub in this.MultisigScheme.XPubs)
            {
                derivedPubKeys.Add(HdOperations.GeneratePublicKey(xpub, hdPathIndex, isChange, network));
            }
            var sortedkeys = LexographicalSort(derivedPubKeys);

            Script redeemScript = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(this.MultisigScheme.Threashold, sortedkeys.ToArray());

            return(redeemScript);
        }
示例#2
0
        /// <summary>
        /// Creates a number of additional addresses in the current account.
        /// </summary>
        /// <remarks>
        /// The name given to the account is of the form "account (i)" by default, where (i) is an incremental index starting at 0.
        /// According to BIP44, an account at index (i) can only be created when the account at index (i - 1) contains at least one transaction.
        /// </remarks>
        /// <param name="network">The network these addresses will be for.</param>
        /// <param name="addressesQuantity">The number of addresses to create.</param>
        /// <param name="isChange">Whether the addresses added are change (internal) addresses or receiving (external) addresses.</param>
        /// <returns>The created addresses.</returns>
        public IEnumerable <HdAddress> CreateAddresses(Network network, int addressesQuantity, bool isChange = false)
        {
            ICollection <HdAddress> addresses = isChange ? this.InternalAddresses : this.ExternalAddresses;

            // Get the index of the last address.
            int firstNewAddressIndex = 0;

            if (addresses.Any())
            {
                firstNewAddressIndex = addresses.Max(add => add.Index) + 1;
            }

            var addressesCreated = new List <HdAddress>();

            for (int i = firstNewAddressIndex; i < firstNewAddressIndex + addressesQuantity; i++)
            {
                // Retrieve the pubkey associated with the private key of this address index.
                PubKey pubkey = HdOperations.GeneratePublicKey(this.ExtendedPubKey, i, isChange);

                // Generate the P2PKH address corresponding to the pubkey.
                BitcoinPubKeyAddress    address    = pubkey.GetAddress(network);
                BitcoinWitPubKeyAddress witAddress = pubkey.GetSegwitAddress(network);

                // Add the new address details to the list of addresses.
                var newAddress = new HdAddress
                {
                    Index         = i,
                    HdPath        = HdOperations.CreateHdPath((int)this.GetCoinType(), this.Index, isChange, i),
                    ScriptPubKey  = address.ScriptPubKey,
                    Pubkey        = pubkey.ScriptPubKey,
                    Bech32Address = witAddress.ToString(),
                    Address       = address.ToString(),
                };

                addresses.Add(newAddress);
                addressesCreated.Add(newAddress);
            }

            if (isChange)
            {
                this.InternalAddresses = addresses;
            }
            else
            {
                this.ExternalAddresses = addresses;
            }

            return(addressesCreated);
        }
示例#3
0
        public void pubKeysDerivedFromExtendedPrivateAndPublicKeysMatch()
        {
            string password   = "******";
            string passphrase = password;

            string mnemonic = "chalk call anger chase endless level slow sleep coast left sand enter save bind curious puzzle stadium volume mixture shuffle hurry gas borrow believe";

            ExtKey extendedKey = HdOperations.GetExtendedKey(mnemonic, passphrase);

            string encryptedSeed = extendedKey.PrivateKey.GetEncryptedBitcoinSecret(password, this.Network).ToWif();
            Key    privateKey    = HdOperations.DecryptSeed(encryptedSeed, password, this.Network);

            string accountHdPath = HdOperations.GetAccountHdPath(COINTYPE, 0);
            string path          = HdOperations.CreateHdPath(COINTYPE, 0, false, 0);

            ExtPubKey accountExtPubKey = HdOperations.GetExtendedPublicKey(privateKey, extendedKey.ChainCode, accountHdPath);
            var       subjectPubKey    = HdOperations.GeneratePublicKey(accountExtPubKey.ToString(this.Network), 0, false, this.Network);

            var subjectPrivKey = HdOperations.GetExtendedPrivateKey(privateKey, extendedKey.ChainCode, path, this.Network);

            Assert.Equal(subjectPubKey.ScriptPubKey, subjectPrivKey.PrivateKey.PubKey.ScriptPubKey);
        }