/** * Constructs a new hierarchy rooted at the given key. Note that this does not have to be the top of the tree. * You can construct a DeterministicHierarchy for a subtree of a larger tree that you may not own. */ public DeterministicHierarchy(DeterministicKey rootKey) { putKey(rootKey); rootPath = rootKey.getPath(); }
/** * Returns the path of this key as a human readable string starting with M to indicate the master key. */ public String getPathAsString() { return HDUtils.formatPath(getPath()); }
/** * Constructs a new hierarchy rooted at the given key. Note that this does not have to be the top of the tree. * You can construct a DeterministicHierarchy for a subtree of a larger tree that you may not own. */ public DeterministicHierarchy(DeterministicKey rootKey) { putKey(rootKey); rootPath = rootKey.getPath(); }
/** * Returns the path of this key as a human readable string starting with M to indicate the master key. */ public String getPathAsString() { return HDUtils.formatPath(getPath()); }
/** * Returns the path of this key as a human readable string starting with M to indicate the master key. */ public String getPathAsString() { return HDUtils.formatPath(getPath()); }
/** * Constructs a new hierarchy rooted at the given key. Note that this does not have to be the top of the tree. * You can construct a DeterministicHierarchy for a subtree of a larger tree that you may not own. */ public DeterministicHierarchy(DeterministicKey rootKey) { putKey(rootKey); rootPath = rootKey.getPath(); }
/** * Returns the path of this key as a human readable string starting with M to indicate the master key. */ public String getPathAsString() { return HDUtils.formatPath(getPath()); }
/** * Constructs a new hierarchy rooted at the given key. Note that this does not have to be the top of the tree. * You can construct a DeterministicHierarchy for a subtree of a larger tree that you may not own. */ public DeterministicHierarchy(DeterministicKey rootKey) { putKey(rootKey); rootPath = rootKey.getPath(); }
/** * Inserts a key into the heirarchy. Used during deserialization: you normally don't need this. Keys must be * inserted in order. */ public final void putKey(DeterministicKey key) { ImmutableList<ChildNumber> path = key.getPath(); // Update our tracking of what the next child in each branch of the tree should be. Just assume that keys are // inserted in order here. final DeterministicKey parent = key.getParent(); if (parent != null) lastChildNumbers.put(parent.getPath(), key.getChildNumber()); keys.put(path, key); }
/** * Inserts a key into the heirarchy. Used during deserialization: you normally don't need this. Keys must be * inserted in order. */ public final void putKey(DeterministicKey key) { ImmutableList<ChildNumber> path = key.getPath(); // Update our tracking of what the next child in each branch of the tree should be. Just assume that keys are // inserted in order here. final DeterministicKey parent = key.getParent(); if (parent != null) lastChildNumbers.put(parent.getPath(), key.getChildNumber()); keys.put(path, key); }
private List<ECKey> getMarriedKeysWithFollowed(DeterministicKey followedKey) { ImmutableList.Builder<ECKey> keys = ImmutableList.builder(); for (DeterministicKeyChain keyChain : followingKeyChains) { keyChain.maybeLookAhead(); keys.add(keyChain.getKeyByPath(followedKey.getPath())); } keys.add(followedKey); return keys.build(); }
private List<ECKey> getMarriedKeysWithFollowed(DeterministicKey followedKey) { ImmutableList.Builder<ECKey> keys = ImmutableList.builder(); for (DeterministicKeyChain keyChain : followingKeyChains) { keyChain.maybeLookAhead(); keys.add(keyChain.getKeyByPath(followedKey.getPath())); } keys.add(followedKey); return keys.build(); }
private List<ECKey> getMarriedKeysWithFollowed(DeterministicKey followedKey) { ImmutableList.Builder<ECKey> keys = ImmutableList.builder(); for (DeterministicKeyChain keyChain : followingKeyChains) { keyChain.maybeLookAhead(); keys.add(keyChain.getKeyByPath(followedKey.getPath())); } keys.add(followedKey); return keys.build(); }
private List<ECKey> getMarriedKeysWithFollowed(DeterministicKey followedKey) { ImmutableList.Builder<ECKey> keys = ImmutableList.builder(); for (DeterministicKeyChain keyChain : followingKeyChains) { keyChain.maybeLookAhead(); keys.add(keyChain.getKeyByPath(followedKey.getPath())); } keys.add(followedKey); return keys.build(); }
/** * <p>Returns the same key with the parent pointer removed (it still knows its own path and the parent fingerprint).</p> * * <p>If this key doesn't have private key bytes stored/cached itself, but could rederive them from the parent, then * the new key returned by this method won't be able to do that. Thus, using dropPrivateBytes().dropParent() on a * regular DeterministicKey will yield a new DeterministicKey that cannot sign or do other things involving the * private key at all.</p> */ public DeterministicKey dropParent() { DeterministicKey key = new DeterministicKey(getPath(), getChainCode(), pub, priv, null); key.parentFingerprint = parentFingerprint; return key; }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
private static Protos.Key getMasterKeyProto(Wallet wallet) { DeterministicKey key = wallet.getMasterKey(); Protos.Key.Builder proto = KeyUtils.serializeKey(key); proto.setType(Protos.Key.Type.DETERMINISTIC_KEY); final Protos.DeterministicKey.Builder detKey = proto.getDeterministicKeyBuilder(); detKey.setChainCode(ByteString.copyFrom(key.getChainCode())); for (ChildNumber num : key.getPath()) { detKey.addPath(num.i()); } return proto.build(); }
private static Protos.Key getMasterKeyProto(Wallet wallet) { DeterministicKey key = wallet.getMasterKey(); Protos.Key.Builder proto = KeyUtils.serializeKey(key); proto.setType(Protos.Key.Type.DETERMINISTIC_KEY); final Protos.DeterministicKey.Builder detKey = proto.getDeterministicKeyBuilder(); detKey.setChainCode(ByteString.copyFrom(key.getChainCode())); for (ChildNumber num : key.getPath()) { detKey.addPath(num.i()); } return proto.build(); }
@Test public void parentlessDeserialization() { NetworkParameters params = UnitTestParams.get(); DeterministicKey key1 = HDKeyDerivation.createMasterPrivateKey("satoshi lives!".getBytes()); DeterministicKey key2 = HDKeyDerivation.deriveChildKey(key1, ChildNumber.ZERO_HARDENED); DeterministicKey key3 = HDKeyDerivation.deriveChildKey(key2, ChildNumber.ZERO_HARDENED); DeterministicKey key4 = HDKeyDerivation.deriveChildKey(key3, ChildNumber.ZERO_HARDENED); assertEquals(key4.getPath().size(), 3); assertEquals(DeterministicKey.deserialize(params, key4.serializePrivate(params), key3).getPath().size(), 3); assertEquals(DeterministicKey.deserialize(params, key4.serializePrivate(params), null).getPath().size(), 1); assertEquals(DeterministicKey.deserialize(params, key4.serializePrivate(params)).getPath().size(), 1); }