コード例 #1
0
        public void TrySign(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath, SigHash sigHash = SigHash.All)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (accountHDScriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(accountHDScriptPubKey));
            }
            var cache = accountKey.AsHDKeyCache();

            accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
            foreach (var hdk in this.HDKeysFor(accountHDScriptPubKey, cache, accountKeyPath))
            {
                if (((HDKeyCache)cache.Derive(hdk.AddressKeyPath)).Inner is ISecret k)
                {
                    Sign(k.PrivateKey, sigHash);
                }
                else
                {
                    throw new ArgumentException(paramName: nameof(accountKey), message: "This should be a private key");
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Rebase the keypaths.
        /// If a PSBT updater only know the child HD public key but not the root one, another updater knowing the parent master key it is based on
        /// can rebase the paths.
        /// </summary>
        /// <param name="accountKey">The current account key</param>
        /// <param name="newRoot">The KeyPath with the fingerprint of the new root key</param>
        /// <returns>This PSBT</returns>
        public PSBT RebaseKeyPaths(IHDKey accountKey, RootedKeyPath newRoot)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (newRoot == null)
            {
                throw new ArgumentNullException(nameof(newRoot));
            }
            accountKey = accountKey.AsHDKeyCache();
            var accountKeyFP = accountKey.GetPublicKey().GetHDFingerPrint();

            foreach (var o in HDKeysFor(accountKey).GroupBy(c => c.Coin))
            {
                foreach (var keyPath in o)
                {
                    o.Key.HDKeyPaths.Remove(keyPath.PubKey);
                    o.Key.HDKeyPaths.Add(keyPath.PubKey, newRoot.Derive(keyPath.RootedKeyPath.KeyPath));
                }
            }
            foreach (var xpub in GlobalXPubs.ToList())
            {
                if (xpub.Key.ExtPubKey.PubKey == accountKey.GetPublicKey())
                {
                    GlobalXPubs.Remove(xpub.Key);
                    GlobalXPubs.Add(xpub.Key, newRoot.Derive(xpub.Value.KeyPath));
                }
            }
            return(this);
        }
コード例 #3
0
ファイル: Utils.cs プロジェクト: tohidkazemi/NBitcoin
        /// <summary>
        /// Derive keyPaths as fast as possible using caching and parallelism
        /// </summary>
        /// <param name="hdkey">The hdKey to derive</param>
        /// <param name="keyPaths">keyPaths to derive</param>
        /// <returns>An array of keyPaths.Length size with the derived keys</returns>
        public static IHDKey[] Derive(this IHDKey hdkey, KeyPath[] keyPaths)
        {
            if (hdkey == null)
            {
                throw new ArgumentNullException(nameof(hdkey));
            }
            if (keyPaths == null)
            {
                throw new ArgumentNullException(nameof(keyPaths));
            }
            var result = new IHDKey[keyPaths.Length];
            var cache  = (HDKeyCache)hdkey.AsHDKeyCache();

#if !NOPARALLEL
            Parallel.For(0, keyPaths.Length, i =>
            {
                result[i] = hdkey.Derive(keyPaths[i]);
            });
#else
            for (int i = 0; i < keyPaths.Length; i++)
            {
                result[i] = hdkey.Derive(keyPaths[i]);
            }
#endif
            return(result);
        }
コード例 #4
0
 /// <summary>
 /// Filter the keys which contains the <paramref name="accountKey"/> and <paramref name="accountKeyPath"/>.
 /// </summary>
 /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
 /// <param name="accountKeyPath">The account key path</param>
 /// <returns>HD Keys matching master root key</returns>
 public IEnumerable <PSBTHDKeyMatch> HDKeysFor(IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     if (accountKey == null)
     {
         throw new ArgumentNullException(nameof(accountKey));
     }
     accountKey = accountKey.AsHDKeyCache();
     return(Inputs.HDKeysFor(accountKey, accountKeyPath).OfType <PSBTHDKeyMatch>().Concat(Outputs.HDKeysFor(accountKey, accountKeyPath)));
 }
コード例 #5
0
 /// <summary>
 /// Filter the coins which contains the <paramref name="accountKey"/> and <paramref name="accountKeyPath"/> in the HDKeys and derive
 /// the same scriptPubKeys as <paramref name="accountHDScriptPubKey"/>.
 /// </summary>
 /// <param name="accountHDScriptPubKey">The hdScriptPubKey used to generate addresses</param>
 /// <param name="accountKey">The account key that will be used to sign (ie. 49'/0'/0')</param>
 /// <param name="accountKeyPath">The account key path</param>
 /// <returns>Inputs with HD keys matching masterFingerprint and account key</returns>
 public IEnumerable <PSBTCoin> CoinsFor(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
 {
     if (accountKey == null)
     {
         throw new ArgumentNullException(nameof(accountKey));
     }
     if (accountHDScriptPubKey == null)
     {
         throw new ArgumentNullException(nameof(accountHDScriptPubKey));
     }
     accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
     accountKey            = accountKey.AsHDKeyCache();
     return(Inputs.CoinsFor(accountHDScriptPubKey, accountKey, accountKeyPath).OfType <PSBTCoin>().Concat(Outputs.CoinsFor(accountHDScriptPubKey, accountKey, accountKeyPath).OfType <PSBTCoin>()));
 }
コード例 #6
0
        internal IEnumerable <PSBTHDKeyMatch <T> > GetHDKeys(HDFingerprint?masterFingerprint, IHDKey accountKey)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            accountKey = accountKey.AsHDKeyCache();
            var accountFingerprint = accountKey.GetPublicKey().GetHDFingerPrint();

            foreach (var c in this)
            {
                foreach (var match in c.HDKeysFor(masterFingerprint, accountKey, accountFingerprint))
                {
                    yield return((PSBTHDKeyMatch <T>)match);
                }
            }
        }
コード例 #7
0
        internal IEnumerable <PSBTHDKeyMatch <T> > GetHDKeys(IHDScriptPubKey hdScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath = null)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            accountKey     = accountKey.AsHDKeyCache();
            hdScriptPubKey = hdScriptPubKey?.AsHDKeyCache();
            var accountFingerprint = accountKey.GetPublicKey().GetHDFingerPrint();

            foreach (var c in this)
            {
                foreach (var match in c.HDKeysFor(hdScriptPubKey, accountKey, accountKeyPath, accountFingerprint))
                {
                    yield return((PSBTHDKeyMatch <T>)match);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Add keypath information to this PSBT for each input or output involving it
        /// </summary>
        /// <param name="masterKey">The master key of the keypaths</param>
        /// <param name="paths">The path of the public keys with their expected scriptPubKey</param>
        /// <returns>This PSBT</returns>
        public PSBT AddKeyPath(IHDKey masterKey, params Tuple <KeyPath, Script>[] paths)
        {
            if (masterKey == null)
            {
                throw new ArgumentNullException(nameof(masterKey));
            }
            if (paths == null)
            {
                throw new ArgumentNullException(nameof(paths));
            }

            masterKey = masterKey.AsHDKeyCache();
            foreach (var path in paths)
            {
                var key = masterKey.Derive(path.Item1);
                AddKeyPath(masterKey.GetPublicKey().GetHDFingerPrint(), key.GetPublicKey(), path.Item1, path.Item2);
            }
            return(this);
        }
コード例 #9
0
        /// <summary>
        /// Sign all inputs which derive addresses from <paramref name="accountHDScriptPubKey"/> and that need to be signed by <paramref name="accountKey"/>.
        /// </summary>
        /// <param name="accountHDScriptPubKey">The address generator</param>
        /// <param name="accountKey">The account key with which to sign</param>
        /// <param name="accountKeyPath">The account key path (eg. [masterFP]/49'/0'/0')</param>
        /// <param name="sigHash">The SigHash</param>
        /// <returns>This PSBT</returns>
        public PSBT SignAll(IHDScriptPubKey accountHDScriptPubKey, IHDKey accountKey, RootedKeyPath accountKeyPath, SigHash sigHash = SigHash.All)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (accountHDScriptPubKey == null)
            {
                throw new ArgumentNullException(nameof(accountHDScriptPubKey));
            }
            accountHDScriptPubKey = accountHDScriptPubKey.AsHDKeyCache();
            accountKey            = accountKey.AsHDKeyCache();
            Money total = Money.Zero;

            foreach (var o in Inputs.CoinsFor(accountHDScriptPubKey, accountKey, accountKeyPath))
            {
                o.TrySign(accountHDScriptPubKey, accountKey, accountKeyPath, sigHash);
            }
            return(this);
        }
コード例 #10
0
        public void TrySign(IHDKey masterKey, SigHash sigHash = SigHash.All)
        {
            if (masterKey == null)
            {
                throw new ArgumentNullException(nameof(masterKey));
            }
            var cache = masterKey.AsHDKeyCache();

            foreach (var hdk in this.HDKeysFor(masterKey))
            {
                if (((HDKeyCache)cache.Derive(hdk.KeyPath)).Inner is ExtKey k)
                {
                    Sign(k.PrivateKey, sigHash);
                }
                else
                {
                    throw new ArgumentException(paramName: nameof(masterKey), message: "This should be a private key");
                }
            }
        }
コード例 #11
0
        public PSBT SignAll(IHDKey masterKey, SigHash sigHash = SigHash.All)
        {
            if (masterKey == null)
            {
                throw new ArgumentNullException(nameof(masterKey));
            }
            var cache = masterKey.AsHDKeyCache();

            foreach (var o in Inputs.HDKeysFor(masterKey))
            {
                if (((HDKeyCache)cache.Derive(o.KeyPath)).Inner is ExtKey k)
                {
                    o.Coin.Sign(k.PrivateKey, sigHash);
                }
                else
                {
                    throw new ArgumentException(paramName: nameof(masterKey), message: "This should be a private key");
                }
            }
            return(this);
        }
コード例 #12
0
        /// <summary>
        /// Rebase the keypaths.
        /// If a PSBT updater only know the child HD public key but not the root one, another updater knowing the parent master key it is based on
        /// can rebase the paths.
        /// </summary>
        /// <param name="accountKey">The current account key</param>
        /// <param name="accountKeyPath">The path from the master key to the accountKey</param>
        /// <param name="masterFingerprint">The master key fingerprint</param>
        /// <returns></returns>
        public PSBT RebaseKeyPaths(IHDKey accountKey, KeyPath accountKeyPath, HDFingerprint masterFingerprint)
        {
            if (accountKey == null)
            {
                throw new ArgumentNullException(nameof(accountKey));
            }
            if (accountKeyPath == null)
            {
                throw new ArgumentNullException(nameof(accountKeyPath));
            }
            accountKey = accountKey.AsHDKeyCache();
            var accountKeyFP = accountKey.GetPublicKey().GetHDFingerPrint();

            foreach (var o in HDKeysFor(null, accountKey).GroupBy(c => c.Coin))
            {
                foreach (var keyPath in o)
                {
                    o.Key.HDKeyPaths.Remove(keyPath.PubKey);
                    o.Key.HDKeyPaths.Add(keyPath.PubKey, Tuple.Create(masterFingerprint, accountKeyPath.Derive(keyPath.KeyPath)));
                }
            }
            return(this);
        }