mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 18:25:51 +00:00
VersionedChecksummedBytes: Store network params rather than version, in preparation for native segwit addresses.
This commit is contained in:
parent
f25840309b
commit
57f25d4c22
@ -18,18 +18,17 @@
|
||||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bitcoinj.params.Networks;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* <p>A Bitcoin address looks like 1MsScoe2fTJoq4ZPdQgqyhgWeoNamYPevy and is derived from an elliptic curve public key
|
||||
@ -48,7 +47,8 @@ public class Address extends VersionedChecksummedBytes {
|
||||
*/
|
||||
public static final int LENGTH = 20;
|
||||
|
||||
private transient NetworkParameters params;
|
||||
/** True if P2SH, false if P2PKH. */
|
||||
public final boolean p2sh;
|
||||
|
||||
/**
|
||||
* Private constructor. Use {@link #fromBase58(NetworkParameters, String)},
|
||||
@ -62,13 +62,10 @@ public class Address extends VersionedChecksummedBytes {
|
||||
* @param hash160
|
||||
* 20-byte hash of pubkey or script
|
||||
*/
|
||||
private Address(NetworkParameters params, int version, byte[] hash160) throws WrongNetworkException {
|
||||
super(version, hash160);
|
||||
checkNotNull(params);
|
||||
private Address(NetworkParameters params, boolean p2sh, byte[] hash160) throws WrongNetworkException {
|
||||
super(params, hash160);
|
||||
checkArgument(hash160.length == 20, "Addresses are 160-bit hashes, so you must provide 20 bytes");
|
||||
if (!isAcceptableVersion(params, version))
|
||||
throw new WrongNetworkException(version);
|
||||
this.params = params;
|
||||
this.p2sh = p2sh;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +79,7 @@ public class Address extends VersionedChecksummedBytes {
|
||||
* @return constructed address
|
||||
*/
|
||||
public static Address fromPubKeyHash(NetworkParameters params, byte[] hash160) {
|
||||
return new Address(params, params.getAddressHeader(), hash160);
|
||||
return new Address(params, false, hash160);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +107,7 @@ public class Address extends VersionedChecksummedBytes {
|
||||
*/
|
||||
public static Address fromP2SHHash(NetworkParameters params, byte[] hash160) {
|
||||
try {
|
||||
return new Address(params, params.getP2SHHeader(), hash160);
|
||||
return new Address(params, true, hash160);
|
||||
} catch (WrongNetworkException e) {
|
||||
throw new RuntimeException(e); // Cannot happen.
|
||||
}
|
||||
@ -144,37 +141,35 @@ public class Address extends VersionedChecksummedBytes {
|
||||
* if the given address is valid but for a different chain (eg testnet vs mainnet)
|
||||
*/
|
||||
public static Address fromBase58(@Nullable NetworkParameters params, String base58) throws AddressFormatException {
|
||||
return new Address(params, base58);
|
||||
byte[] versionAndDataBytes = Base58.decodeChecked(base58);
|
||||
int version = versionAndDataBytes[0] & 0xFF;
|
||||
byte[] bytes = Arrays.copyOfRange(versionAndDataBytes, 1, versionAndDataBytes.length);
|
||||
if (params == null) {
|
||||
for (NetworkParameters p : Networks.get()) {
|
||||
if (version == p.getAddressHeader())
|
||||
return new Address(p, false, bytes);
|
||||
else if (version == p.getP2SHHeader())
|
||||
return new Address(p, true, bytes);
|
||||
}
|
||||
throw new AddressFormatException("No network found for " + base58);
|
||||
} else {
|
||||
if (version == params.getAddressHeader())
|
||||
return new Address(params, false, bytes);
|
||||
else if (version == params.getP2SHHeader())
|
||||
return new Address(params, true, bytes);
|
||||
throw new WrongNetworkException(version);
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #fromPubKeyHash(NetworkParameters, byte[])} */
|
||||
@Deprecated
|
||||
public Address(NetworkParameters params, byte[] hash160) {
|
||||
this(params, params.getAddressHeader(), hash160);
|
||||
this(params, false, hash160);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #fromBase58(NetworkParameters, String)} */
|
||||
@Deprecated
|
||||
public Address(@Nullable NetworkParameters params, String address) throws AddressFormatException {
|
||||
super(address);
|
||||
if (params != null) {
|
||||
if (!isAcceptableVersion(params, version)) {
|
||||
throw new WrongNetworkException(version);
|
||||
}
|
||||
this.params = params;
|
||||
} else {
|
||||
NetworkParameters paramsFound = null;
|
||||
for (NetworkParameters p : Networks.get()) {
|
||||
if (isAcceptableVersion(p, version)) {
|
||||
paramsFound = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paramsFound == null)
|
||||
throw new AddressFormatException("No network found for " + address);
|
||||
|
||||
this.params = paramsFound;
|
||||
}
|
||||
@Override
|
||||
protected int getVersion() {
|
||||
return p2sh ? params.getP2SHHeader() : params.getAddressHeader();
|
||||
}
|
||||
|
||||
/** The (big endian) 20 byte hash that is the core of a Bitcoin address. */
|
||||
@ -187,20 +182,7 @@ public class Address extends VersionedChecksummedBytes {
|
||||
* See also https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki: Address Format for pay-to-script-hash
|
||||
*/
|
||||
public boolean isP2SHAddress() {
|
||||
final NetworkParameters parameters = getParameters();
|
||||
return parameters != null && this.version == parameters.p2shHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines the version byte of the address and attempts to find a matching NetworkParameters. If you aren't sure
|
||||
* which network the address is intended for (eg, it was provided by a user), you can use this to decide if it is
|
||||
* compatible with the current wallet. You should be able to handle a null response from this method. Note that the
|
||||
* parameters returned is not necessarily the same as the one the Address was created with.
|
||||
*
|
||||
* @return network the address is valid for
|
||||
*/
|
||||
public NetworkParameters getParameters() {
|
||||
return params;
|
||||
return p2sh;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,31 +201,23 @@ public class Address extends VersionedChecksummedBytes {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given address version is valid given the NetworkParameters.
|
||||
*/
|
||||
private static boolean isAcceptableVersion(NetworkParameters params, int version) {
|
||||
if (version == params.getAddressHeader())
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (version == params.getP2SHHeader())
|
||||
return true;
|
||||
return false;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Address other = (Address) o;
|
||||
return super.equals(other) && this.p2sh == other.p2sh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(), p2sh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address clone() throws CloneNotSupportedException {
|
||||
return (Address) super.clone();
|
||||
}
|
||||
|
||||
// Java serialization
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeUTF(params.id);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
params = NetworkParameters.fromID(in.readUTF());
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bitcoinj.params.Networks;
|
||||
|
||||
/**
|
||||
* Parses and generates private keys in the form used by the Bitcoin "dumpprivkey" command. This is the private key
|
||||
* bytes with a header byte and 4 checksum bytes at the end. If there are 33 private key bytes instead of 32, then
|
||||
@ -42,13 +43,37 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
|
||||
* @throws WrongNetworkException
|
||||
* if the given private key is valid but for a different chain (eg testnet vs mainnet)
|
||||
*/
|
||||
public static DumpedPrivateKey fromBase58(@Nullable NetworkParameters params,String base58) throws AddressFormatException {
|
||||
return new DumpedPrivateKey(params, base58);
|
||||
public static DumpedPrivateKey fromBase58(@Nullable NetworkParameters params, String base58)
|
||||
throws AddressFormatException {
|
||||
byte[] versionAndDataBytes = Base58.decodeChecked(base58);
|
||||
int version = versionAndDataBytes[0] & 0xFF;
|
||||
byte[] bytes = Arrays.copyOfRange(versionAndDataBytes, 1, versionAndDataBytes.length);
|
||||
if (params == null) {
|
||||
for (NetworkParameters p : Networks.get())
|
||||
if (version == p.getDumpedPrivateKeyHeader())
|
||||
return new DumpedPrivateKey(p, bytes);
|
||||
throw new AddressFormatException("No network found for " + base58);
|
||||
} else {
|
||||
if (version == params.getDumpedPrivateKeyHeader())
|
||||
return new DumpedPrivateKey(params, bytes);
|
||||
throw new WrongNetworkException(version);
|
||||
}
|
||||
}
|
||||
|
||||
private DumpedPrivateKey(NetworkParameters params, byte[] bytes) {
|
||||
super(params, bytes);
|
||||
if (bytes.length != 32 && bytes.length != 33)
|
||||
throw new AddressFormatException("Wrong number of bytes for a private key, not 32 or 33");
|
||||
}
|
||||
|
||||
// Used by ECKey.getPrivateKeyEncoded()
|
||||
DumpedPrivateKey(NetworkParameters params, byte[] keyBytes, boolean compressed) {
|
||||
super(params.getDumpedPrivateKeyHeader(), encode(keyBytes, compressed));
|
||||
this(params, encode(keyBytes, compressed));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVersion() {
|
||||
return params.getDumpedPrivateKeyHeader();
|
||||
}
|
||||
|
||||
private static byte[] encode(byte[] keyBytes, boolean compressed) {
|
||||
@ -64,17 +89,6 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #fromBase58(NetworkParameters, String)} */
|
||||
@Deprecated
|
||||
public DumpedPrivateKey(@Nullable NetworkParameters params, String encoded) throws AddressFormatException {
|
||||
super(encoded);
|
||||
if (params != null && version != params.getDumpedPrivateKeyHeader())
|
||||
throw new WrongNetworkException(version);
|
||||
if (bytes.length != 32 && bytes.length != 33) {
|
||||
throw new AddressFormatException("Wrong number of bytes for a private key, not 32 or 33");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ECKey created from this encoded private key.
|
||||
*/
|
||||
@ -88,17 +102,4 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
|
||||
public boolean isPubKeyCompressed() {
|
||||
return bytes.length == 33 && bytes[32] == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DumpedPrivateKey other = (DumpedPrivateKey) o;
|
||||
return version == other.version && Arrays.equals(bytes, other.bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(version, Arrays.hashCode(bytes));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
* Copyright 2018 Andreas Schildbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,39 +17,44 @@
|
||||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* <p>In Bitcoin the following format is often used to represent some type of key:</p>
|
||||
* <p/>
|
||||
* <pre>[one version byte] [data bytes] [4 checksum bytes]</pre>
|
||||
* <p/>
|
||||
* <p>and the result is then Base58 encoded. This format is used for addresses, and private keys exported using the
|
||||
* dumpprivkey command.</p>
|
||||
* <p>
|
||||
* The following format is often used to represent some type of data (e.g. key or hash of key):
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* [prefix] [data bytes] [checksum]
|
||||
* </pre>
|
||||
* <p>
|
||||
* and the result is then encoded with some variant of base. This format is most commonly used for addresses and private
|
||||
* keys exported using Bitcoin Core's dumpprivkey command.
|
||||
* </p>
|
||||
*/
|
||||
public class VersionedChecksummedBytes implements Serializable, Cloneable, Comparable<VersionedChecksummedBytes> {
|
||||
protected final int version;
|
||||
protected byte[] bytes;
|
||||
public abstract class VersionedChecksummedBytes implements Serializable, Cloneable, Comparable<VersionedChecksummedBytes> {
|
||||
protected final transient NetworkParameters params;
|
||||
protected final byte[] bytes;
|
||||
|
||||
protected VersionedChecksummedBytes(String encoded) throws AddressFormatException {
|
||||
byte[] versionAndDataBytes = Base58.decodeChecked(encoded);
|
||||
byte versionByte = versionAndDataBytes[0];
|
||||
version = versionByte & 0xFF;
|
||||
bytes = new byte[versionAndDataBytes.length - 1];
|
||||
System.arraycopy(versionAndDataBytes, 1, bytes, 0, versionAndDataBytes.length - 1);
|
||||
protected VersionedChecksummedBytes(NetworkParameters params, byte[] bytes) {
|
||||
this.params = checkNotNull(params);
|
||||
this.bytes = checkNotNull(bytes);
|
||||
}
|
||||
|
||||
protected VersionedChecksummedBytes(int version, byte[] bytes) {
|
||||
checkArgument(version >= 0 && version < 256);
|
||||
this.version = version;
|
||||
this.bytes = bytes;
|
||||
/**
|
||||
* @return network this data is valid for
|
||||
*/
|
||||
public final NetworkParameters getParameters() {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,9 +62,11 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
|
||||
* object, including version and checksum bytes.
|
||||
*/
|
||||
public final String toBase58() {
|
||||
return Base58.encodeChecked(version, bytes);
|
||||
return Base58.encodeChecked(getVersion(), bytes);
|
||||
}
|
||||
|
||||
protected abstract int getVersion();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toBase58();
|
||||
@ -66,7 +74,7 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(version, Arrays.hashCode(bytes));
|
||||
return Objects.hashCode(params, Arrays.hashCode(bytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,12 +82,10 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
VersionedChecksummedBytes other = (VersionedChecksummedBytes) o;
|
||||
return this.version == other.version && Arrays.equals(this.bytes, other.bytes);
|
||||
return this.params.equals(other.params) && Arrays.equals(this.bytes, other.bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* This implementation narrows the return type to <code>VersionedChecksummedBytes</code>
|
||||
* and allows subclasses to throw <code>CloneNotSupportedException</code> even though it
|
||||
* is never thrown by this implementation.
|
||||
@ -90,23 +96,30 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* This implementation uses an optimized Google Guava method to compare <code>bytes</code>.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(VersionedChecksummedBytes o) {
|
||||
int result = Ints.compare(this.version, o.version);
|
||||
int result = this.params.getId().compareTo(o.params.getId());
|
||||
return result != 0 ? result : UnsignedBytes.lexicographicalComparator().compare(this.bytes, o.bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "version" or "header" byte: the first byte of the data. This is used to disambiguate what the
|
||||
* contents apply to, for example, which network the key or address is valid on.
|
||||
*
|
||||
* @return A positive number between 0 and 255.
|
||||
*/
|
||||
public int getVersion() {
|
||||
return version;
|
||||
// Java serialization
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeUTF(params.getId());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
try {
|
||||
Field paramsField = VersionedChecksummedBytes.class.getDeclaredField("params");
|
||||
paramsField.setAccessible(true);
|
||||
paramsField.set(this, checkNotNull(NetworkParameters.fromID(in.readUTF())));
|
||||
paramsField.setAccessible(false);
|
||||
} catch (NoSuchFieldException | IllegalAccessException x) {
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,22 +18,17 @@ package org.bitcoinj.crypto;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.lambdaworks.crypto.SCrypt;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.text.Normalizer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
/**
|
||||
@ -41,8 +36,6 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
* passphrase-protected private keys. Currently, only decryption is supported.
|
||||
*/
|
||||
public class BIP38PrivateKey extends VersionedChecksummedBytes {
|
||||
|
||||
public transient NetworkParameters params;
|
||||
public final boolean ecMultiply;
|
||||
public final boolean compressed;
|
||||
public final boolean hasLotAndSequence;
|
||||
@ -62,20 +55,16 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
|
||||
* if the given base58 doesn't parse or the checksum is invalid
|
||||
*/
|
||||
public static BIP38PrivateKey fromBase58(NetworkParameters params, String base58) throws AddressFormatException {
|
||||
return new BIP38PrivateKey(params, base58);
|
||||
}
|
||||
byte[] versionAndDataBytes = Base58.decodeChecked(base58);
|
||||
int version = versionAndDataBytes[0] & 0xFF;
|
||||
byte[] bytes = Arrays.copyOfRange(versionAndDataBytes, 1, versionAndDataBytes.length);
|
||||
|
||||
/** @deprecated Use {@link #fromBase58(NetworkParameters, String)} */
|
||||
@Deprecated
|
||||
public BIP38PrivateKey(NetworkParameters params, String encoded) throws AddressFormatException {
|
||||
super(encoded);
|
||||
this.params = checkNotNull(params);
|
||||
if (version != 0x01)
|
||||
throw new AddressFormatException("Mismatched version number: " + version);
|
||||
if (bytes.length != 38)
|
||||
throw new AddressFormatException("Wrong number of bytes, excluding version byte: " + bytes.length);
|
||||
hasLotAndSequence = (bytes[1] & 0x04) != 0; // bit 2
|
||||
compressed = (bytes[1] & 0x20) != 0; // bit 5
|
||||
boolean hasLotAndSequence = (bytes[1] & 0x04) != 0; // bit 2
|
||||
boolean compressed = (bytes[1] & 0x20) != 0; // bit 5
|
||||
if ((bytes[1] & 0x01) != 0) // bit 0
|
||||
throw new AddressFormatException("Bit 0x01 reserved for future use.");
|
||||
if ((bytes[1] & 0x02) != 0) // bit 1
|
||||
@ -85,6 +74,7 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
|
||||
if ((bytes[1] & 0x10) != 0) // bit 4
|
||||
throw new AddressFormatException("Bit 0x10 reserved for future use.");
|
||||
final int byte0 = bytes[0] & 0xff;
|
||||
final boolean ecMultiply;
|
||||
if (byte0 == 0x42) {
|
||||
// Non-EC-multiplied key
|
||||
if ((bytes[1] & 0xc0) != 0xc0) // bits 6+7
|
||||
@ -100,8 +90,24 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
|
||||
} else {
|
||||
throw new AddressFormatException("Second byte must by 0x42 or 0x43.");
|
||||
}
|
||||
addressHash = Arrays.copyOfRange(bytes, 2, 6);
|
||||
content = Arrays.copyOfRange(bytes, 6, 38);
|
||||
byte[] addressHash = Arrays.copyOfRange(bytes, 2, 6);
|
||||
byte[] content = Arrays.copyOfRange(bytes, 6, 38);
|
||||
return new BIP38PrivateKey(params, bytes, ecMultiply, compressed, hasLotAndSequence, addressHash, content);
|
||||
}
|
||||
|
||||
private BIP38PrivateKey(NetworkParameters params, byte[] bytes, boolean ecMultiply, boolean compressed,
|
||||
boolean hasLotAndSequence, byte[] addressHash, byte[] content) throws AddressFormatException {
|
||||
super(params, bytes);
|
||||
this.ecMultiply = ecMultiply;
|
||||
this.compressed = compressed;
|
||||
this.hasLotAndSequence = hasLotAndSequence;
|
||||
this.addressHash = addressHash;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVersion() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public ECKey decrypt(String passphrase) throws BadPassphraseException {
|
||||
@ -180,29 +186,4 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BIP38PrivateKey other = (BIP38PrivateKey) o;
|
||||
return super.equals(other) && Objects.equal(this.params, other.params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(), params);
|
||||
}
|
||||
|
||||
// Java serialization
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeUTF(params.getId());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
params = checkNotNull(NetworkParameters.fromID(in.readUTF()));
|
||||
}
|
||||
}
|
||||
|
@ -149,11 +149,11 @@ public class AddressTest {
|
||||
@Test
|
||||
public void p2shAddress() throws Exception {
|
||||
// Test that we can construct P2SH addresses
|
||||
Address mainNetP2SHAddress = Address.fromBase58(MAINNET, "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
|
||||
assertEquals(mainNetP2SHAddress.version, MAINNET.p2shHeader);
|
||||
Address mainNetP2SHAddress = Address.fromBase58(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
|
||||
assertEquals(mainNetP2SHAddress.getVersion(), MAINNET.p2shHeader);
|
||||
assertTrue(mainNetP2SHAddress.isP2SHAddress());
|
||||
Address testNetP2SHAddress = Address.fromBase58(TESTNET, "2MuVSxtfivPKJe93EC1Tb9UhJtGhsoWEHCe");
|
||||
assertEquals(testNetP2SHAddress.version, TESTNET.p2shHeader);
|
||||
Address testNetP2SHAddress = Address.fromBase58(TestNet3Params.get(), "2MuVSxtfivPKJe93EC1Tb9UhJtGhsoWEHCe");
|
||||
assertEquals(testNetP2SHAddress.getVersion(), TESTNET.p2shHeader);
|
||||
assertTrue(testNetP2SHAddress.isP2SHAddress());
|
||||
|
||||
// Test that we can determine what network a P2SH address belongs to
|
||||
|
@ -29,19 +29,30 @@ public class VersionedChecksummedBytesTest {
|
||||
private static final NetworkParameters TESTNET = TestNet3Params.get();
|
||||
private static final NetworkParameters MAINNET = MainNetParams.get();
|
||||
|
||||
private static class VersionedChecksummedBytesToTest extends VersionedChecksummedBytes {
|
||||
public VersionedChecksummedBytesToTest(NetworkParameters params, byte[] bytes) {
|
||||
super(params, bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVersion() {
|
||||
return params.getAddressHeader();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringification() throws Exception {
|
||||
// Test a testnet address.
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytes(TESTNET.getAddressHeader(), HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytesToTest(TESTNET, HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
assertEquals("n4eA2nbYqErp7H6jebchxAN59DmNpksexv", a.toString());
|
||||
|
||||
VersionedChecksummedBytes b = new VersionedChecksummedBytes(MAINNET.getAddressHeader(), HEX.decode("4a22c3c4cbb31e4d03b15550636762bda0baf85a"));
|
||||
VersionedChecksummedBytes b = new VersionedChecksummedBytesToTest(MAINNET, HEX.decode("4a22c3c4cbb31e4d03b15550636762bda0baf85a"));
|
||||
assertEquals("17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL", b.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloning() throws Exception {
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytes(TESTNET.getAddressHeader(), HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytesToTest(TESTNET, HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
VersionedChecksummedBytes b = a.clone();
|
||||
|
||||
assertEquals(a, b);
|
||||
@ -50,7 +61,7 @@ public class VersionedChecksummedBytesTest {
|
||||
|
||||
@Test
|
||||
public void comparisonCloneEqualTo() throws Exception {
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytes(TESTNET.getAddressHeader(), HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
VersionedChecksummedBytes a = new VersionedChecksummedBytesToTest(TESTNET, HEX.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
VersionedChecksummedBytes b = a.clone();
|
||||
|
||||
assertTrue(a.compareTo(b) == 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user