From 57f25d4c223e0459371c12e506dfa40c4efc4b84 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Thu, 15 Feb 2018 17:47:09 +0100 Subject: [PATCH] VersionedChecksummedBytes: Store network params rather than version, in preparation for native segwit addresses. --- .../main/java/org/bitcoinj/core/Address.java | 122 +++++++----------- .../org/bitcoinj/core/DumpedPrivateKey.java | 57 ++++---- .../core/VersionedChecksummedBytes.java | 89 +++++++------ .../org/bitcoinj/crypto/BIP38PrivateKey.java | 67 ++++------ .../java/org/bitcoinj/core/AddressTest.java | 8 +- .../core/VersionedChecksummedBytesTest.java | 19 ++- 6 files changed, 171 insertions(+), 191 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/Address.java b/core/src/main/java/org/bitcoinj/core/Address.java index 56bd3e93..6e6a8870 100644 --- a/core/src/main/java/org/bitcoinj/core/Address.java +++ b/core/src/main/java/org/bitcoinj/core/Address.java @@ -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; /** *

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()); - } } diff --git a/core/src/main/java/org/bitcoinj/core/DumpedPrivateKey.java b/core/src/main/java/org/bitcoinj/core/DumpedPrivateKey.java index e71a72b1..25a67260 100644 --- a/core/src/main/java/org/bitcoinj/core/DumpedPrivateKey.java +++ b/core/src/main/java/org/bitcoinj/core/DumpedPrivateKey.java @@ -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)); - } } diff --git a/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java b/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java index cbc325b9..39738273 100644 --- a/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java +++ b/core/src/main/java/org/bitcoinj/core/VersionedChecksummedBytes.java @@ -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; /** - *

In Bitcoin the following format is often used to represent some type of key:

- *

- *

[one version byte] [data bytes] [4 checksum bytes]
- *

- *

and the result is then Base58 encoded. This format is used for addresses, and private keys exported using the - * dumpprivkey command.

+ *

+ * The following format is often used to represent some type of data (e.g. key or hash of key): + *

+ * + *
+ * [prefix] [data bytes] [checksum]
+ * 
+ *

+ * 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. + *

*/ -public class VersionedChecksummedBytes implements Serializable, Cloneable, Comparable { - protected final int version; - protected byte[] bytes; +public abstract class VersionedChecksummedBytes implements Serializable, Cloneable, Comparable { + 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 VersionedChecksummedBytes * and allows subclasses to throw CloneNotSupportedException 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 bytes. */ @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); + } } } diff --git a/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java b/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java index 7cba10bb..b4dc55b3 100644 --- a/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java @@ -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())); - } } diff --git a/core/src/test/java/org/bitcoinj/core/AddressTest.java b/core/src/test/java/org/bitcoinj/core/AddressTest.java index f3652f7f..8bbe0b51 100644 --- a/core/src/test/java/org/bitcoinj/core/AddressTest.java +++ b/core/src/test/java/org/bitcoinj/core/AddressTest.java @@ -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 diff --git a/core/src/test/java/org/bitcoinj/core/VersionedChecksummedBytesTest.java b/core/src/test/java/org/bitcoinj/core/VersionedChecksummedBytesTest.java index d3b9fb9b..4159a038 100644 --- a/core/src/test/java/org/bitcoinj/core/VersionedChecksummedBytesTest.java +++ b/core/src/test/java/org/bitcoinj/core/VersionedChecksummedBytesTest.java @@ -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);