Commit 0441b385 authored by Andreas Schildbach's avatar Andreas Schildbach

Provide a consistent fromBase58/toBase58 API for the VersionChecksummedBytes hierarchy.

Deprecates the old constructors and migrates bitcoinj itself to use the new API. Also makes DumpedPrivateKey use WrongNetworkException when appropriate. Adds missing testcases and corrects/adds a bit of JavaDoc.
parent 4112ed80
......@@ -78,6 +78,21 @@ public class Address extends VersionedChecksummedBytes {
return fromP2SHHash(params, scriptPubKey.getPubKeyHash());
}
/**
* Construct an address from its Base58 representation.
* @param params
* The expected NetworkParameters or null if you don't want validation.
* @param base58
* The textual form of the address, such as "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL".
* @throws AddressFormatException
* if the given base58 doesn't parse or the checksum is invalid
* @throws WrongNetworkException
* 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);
}
/**
* Construct an address from parameters and the hash160 form. Example:<p>
*
......@@ -89,16 +104,8 @@ public class Address extends VersionedChecksummedBytes {
this.params = params;
}
/**
* Construct an address from parameters and the standard "human readable" form. Example:<p>
*
* <pre>new Address(MainNetParams.get(), "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");</pre><p>
*
* @param params The expected NetworkParameters or null if you don't want validation.
* @param address The textual form of the address, such as "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL"
* @throws AddressFormatException if the given address doesn't parse or the checksum is invalid
* @throws WrongNetworkException if the given address is valid but for a different chain (eg testnet vs mainnet)
*/
/** @deprecated Use {@link #fromBase58(NetworkParameters, String)} */
@Deprecated
public Address(@Nullable NetworkParameters params, String address) throws AddressFormatException {
super(address);
if (params != null) {
......@@ -156,7 +163,7 @@ public class Address extends VersionedChecksummedBytes {
*/
public static NetworkParameters getParametersFromAddress(String address) throws AddressFormatException {
try {
return new Address(null, address).getParameters();
return Address.fromBase58(null, address).getParameters();
} catch (WrongNetworkException e) {
throw new RuntimeException(e); // Cannot happen.
}
......
/**
* Copyright 2011 Google Inc.
* Copyright 2015 Andreas Schildbach
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -21,6 +22,8 @@ import com.google.common.base.Preconditions;
import java.util.Arrays;
import javax.annotation.Nullable;
/**
* 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
......@@ -29,6 +32,21 @@ import java.util.Arrays;
public class DumpedPrivateKey extends VersionedChecksummedBytes {
private boolean compressed;
/**
* Construct a private key from its Base58 representation.
* @param params
* The expected NetworkParameters or null if you don't want validation.
* @param base58
* The textual form of the private key.
* @throws AddressFormatException
* if the given base58 doesn't parse or the checksum is invalid
* @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);
}
// Used by ECKey.getPrivateKeyEncoded()
DumpedPrivateKey(NetworkParameters params, byte[] keyBytes, boolean compressed) {
super(params.getDumpedPrivateKeyHeader(), encode(keyBytes, compressed));
......@@ -48,18 +66,12 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
}
}
/**
* Parses the given private key as created by the "dumpprivkey" Bitcoin C++ RPC.
*
* @param params The expected network parameters of the key. If you don't care, provide null.
* @param encoded The base58 encoded string.
* @throws AddressFormatException If the string is invalid or the header byte doesn't match the network params.
*/
public DumpedPrivateKey(NetworkParameters params, String encoded) throws AddressFormatException {
/** @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 AddressFormatException("Mismatched version number, trying to cross networks? " + version +
" vs " + params.getDumpedPrivateKeyHeader());
throw new WrongNetworkException(version, new int[]{ params.getDumpedPrivateKeyHeader() });
if (bytes.length == 33 && bytes[32] == 1) {
compressed = true;
bytes = Arrays.copyOf(bytes, 32); // Chop off the additional marker byte.
......
......@@ -55,8 +55,7 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
* Returns the base-58 encoded String representation of this
* object, including version and checksum bytes.
*/
@Override
public String toString() {
public final String toBase58() {
// A stringified buffer is:
// 1 byte version + data bytes + 4 bytes check code (a truncated hash)
byte[] addressBytes = new byte[1 + bytes.length + 4];
......@@ -67,6 +66,11 @@ public class VersionedChecksummedBytes implements Serializable, Cloneable, Compa
return Base58.encode(addressBytes);
}
@Override
public String toString() {
return toBase58();
}
@Override
public int hashCode() {
return Objects.hashCode(version, Arrays.hashCode(bytes));
......
......@@ -51,6 +51,21 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
public static final class BadPassphraseException extends Exception {
}
/**
* Construct a password-protected private key from its Base58 representation.
* @param params
* The network parameters of the chain that the key is for.
* @param base58
* The textual form of the password-protected private key.
* @throws AddressFormatException
* 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);
}
/** @deprecated Use {@link #fromBase58(NetworkParameters, String)} */
@Deprecated
public BIP38PrivateKey(NetworkParameters params, String encoded) throws AddressFormatException {
super(encoded);
this.params = params;
......
......@@ -184,7 +184,7 @@ public class BitcoinURI {
if (!addressToken.isEmpty()) {
// Attempt to parse the addressToken as a Bitcoin address for this network
try {
Address address = new Address(params, addressToken);
Address address = Address.fromBase58(params, addressToken);
putWithValidation(FIELD_ADDRESS, address);
} catch (final AddressFormatException e) {
throw new BitcoinURIParseException("Bad address", e);
......
......@@ -40,14 +40,14 @@ public class AddressTest {
@Test
public void testJavaSerialization() throws Exception {
Address testAddress = new Address(testParams, "n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
Address testAddress = Address.fromBase58(testParams, "n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
ByteArrayOutputStream os = new ByteArrayOutputStream();
new ObjectOutputStream(os).writeObject(testAddress);
VersionedChecksummedBytes testAddressCopy = (VersionedChecksummedBytes) new ObjectInputStream(
new ByteArrayInputStream(os.toByteArray())).readObject();
assertEquals(testAddress, testAddressCopy);
Address mainAddress = new Address(mainParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
Address mainAddress = Address.fromBase58(mainParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
os = new ByteArrayOutputStream();
new ObjectOutputStream(os).writeObject(mainAddress);
VersionedChecksummedBytes mainAddressCopy = (VersionedChecksummedBytes) new ObjectInputStream(
......@@ -69,10 +69,10 @@ public class AddressTest {
@Test
public void decoding() throws Exception {
Address a = new Address(testParams, "n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
Address a = Address.fromBase58(testParams, "n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
assertEquals("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc", Utils.HEX.encode(a.getHash160()));
Address b = new Address(mainParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
Address b = Address.fromBase58(mainParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
assertEquals("4a22c3c4cbb31e4d03b15550636762bda0baf85a", Utils.HEX.encode(b.getHash160()));
}
......@@ -80,7 +80,7 @@ public class AddressTest {
public void errorPaths() {
// Check what happens if we try and decode garbage.
try {
new Address(testParams, "this is not a valid address!");
Address.fromBase58(testParams, "this is not a valid address!");
fail();
} catch (WrongNetworkException e) {
fail();
......@@ -90,7 +90,7 @@ public class AddressTest {
// Check the empty case.
try {
new Address(testParams, "");
Address.fromBase58(testParams, "");
fail();
} catch (WrongNetworkException e) {
fail();
......@@ -100,7 +100,7 @@ public class AddressTest {
// Check the case of a mismatched network.
try {
new Address(testParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
Address.fromBase58(testParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
fail();
} catch (WrongNetworkException e) {
// Success.
......@@ -151,10 +151,10 @@ public class AddressTest {
@Test
public void p2shAddress() throws Exception {
// Test that we can construct P2SH addresses
Address mainNetP2SHAddress = new Address(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
Address mainNetP2SHAddress = Address.fromBase58(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
assertEquals(mainNetP2SHAddress.version, MainNetParams.get().p2shHeader);
assertTrue(mainNetP2SHAddress.isP2SHAddress());
Address testNetP2SHAddress = new Address(TestNet3Params.get(), "2MuVSxtfivPKJe93EC1Tb9UhJtGhsoWEHCe");
Address testNetP2SHAddress = Address.fromBase58(TestNet3Params.get(), "2MuVSxtfivPKJe93EC1Tb9UhJtGhsoWEHCe");
assertEquals(testNetP2SHAddress.version, TestNet3Params.get().p2shHeader);
assertTrue(testNetP2SHAddress.isP2SHAddress());
......@@ -177,11 +177,11 @@ public class AddressTest {
@Test
public void p2shAddressCreationFromKeys() throws Exception {
// import some keys from this example: https://gist.github.com/gavinandresen/3966071
ECKey key1 = new DumpedPrivateKey(mainParams, "5JaTXbAUmfPYZFRwrYaALK48fN6sFJp4rHqq2QSXs8ucfpE4yQU").getKey();
ECKey key1 = DumpedPrivateKey.fromBase58(mainParams, "5JaTXbAUmfPYZFRwrYaALK48fN6sFJp4rHqq2QSXs8ucfpE4yQU").getKey();
key1 = ECKey.fromPrivate(key1.getPrivKeyBytes());
ECKey key2 = new DumpedPrivateKey(mainParams, "5Jb7fCeh1Wtm4yBBg3q3XbT6B525i17kVhy3vMC9AqfR6FH2qGk").getKey();
ECKey key2 = DumpedPrivateKey.fromBase58(mainParams, "5Jb7fCeh1Wtm4yBBg3q3XbT6B525i17kVhy3vMC9AqfR6FH2qGk").getKey();
key2 = ECKey.fromPrivate(key2.getPrivKeyBytes());
ECKey key3 = new DumpedPrivateKey(mainParams, "5JFjmGo5Fww9p8gvx48qBYDJNAzR9pmH5S389axMtDyPT8ddqmw").getKey();
ECKey key3 = DumpedPrivateKey.fromBase58(mainParams, "5JFjmGo5Fww9p8gvx48qBYDJNAzR9pmH5S389axMtDyPT8ddqmw").getKey();
key3 = ECKey.fromPrivate(key3.getPrivKeyBytes());
List<ECKey> keys = Arrays.asList(key1, key2, key3);
......@@ -199,9 +199,15 @@ public class AddressTest {
assertNotSame(a, b);
}
@Test
public void roundtripBase58() throws Exception {
String base58 = "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL";
assertEquals(base58, Address.fromBase58(null, base58).toBase58());
}
@Test
public void comparisonCloneEqualTo() throws Exception {
Address a = new Address(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address a = Address.fromBase58(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = a.clone();
int result = a.compareTo(b);
......@@ -210,7 +216,7 @@ public class AddressTest {
@Test
public void comparisonEqualTo() throws Exception {
Address a = new Address(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address a = Address.fromBase58(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = a.clone();
int result = a.compareTo(b);
......@@ -219,8 +225,8 @@ public class AddressTest {
@Test
public void comparisonLessThan() throws Exception {
Address a = new Address(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = new Address(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
Address a = Address.fromBase58(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = Address.fromBase58(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
int result = a.compareTo(b);
assertTrue(result < 0);
......@@ -228,8 +234,8 @@ public class AddressTest {
@Test
public void comparisonGreaterThan() throws Exception {
Address a = new Address(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
Address b = new Address(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address a = Address.fromBase58(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
Address b = Address.fromBase58(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
int result = a.compareTo(b);
assertTrue(result > 0);
......@@ -238,8 +244,8 @@ public class AddressTest {
@Test
public void comparisonBytesVsString() throws Exception {
// TODO: To properly test this we need a much larger data set
Address a = new Address(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = new Address(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
Address a = Address.fromBase58(mainParams, "1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX");
Address b = Address.fromBase58(mainParams, "1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P");
int resultBytes = a.compareTo(b);
int resultsString = a.toString().compareTo(b.toString());
......
......@@ -70,7 +70,7 @@ public class BloomFilterTest {
NetworkParameters params = MainNetParams.get();
Context context = new Context(params);
DumpedPrivateKey privKey = new DumpedPrivateKey(params, "5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
DumpedPrivateKey privKey = DumpedPrivateKey.fromBase58(params, "5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
Address addr = privKey.getKey().toAddress(params);
assertTrue(addr.toString().equals("17Wx1GQfyPTNWpQMHrTwRSMTCAonSiZx9e"));
......
......@@ -69,7 +69,7 @@ public class CoinbaseBlockTest {
StoredBlock storedBlock = new StoredBlock(block, BigInteger.ONE, BLOCK_OF_INTEREST); // Nonsense work - not used in test.
// Create a wallet contain the miner's key that receives a spend from a coinbase.
ECKey miningKey = (new DumpedPrivateKey(params, MINING_PRIVATE_KEY)).getKey();
ECKey miningKey = DumpedPrivateKey.fromBase58(params, MINING_PRIVATE_KEY).getKey();
assertNotNull(miningKey);
Context context = new Context(params);
Wallet wallet = new Wallet(context);
......
......@@ -25,14 +25,28 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
public class DumpedPrivateKeyTest {
private static final MainNetParams MAINNET = MainNetParams.get();
private static final TestNet3Params TESTNET = TestNet3Params.get();
@Test
public void checkNetwork() throws Exception {
DumpedPrivateKey.fromBase58(MAINNET, "5HtUCLMFWNueqN9unpgX2DzjMg6SDNZyKRb8s3LJgpFg5ubuMrk");
}
@Test(expected = WrongNetworkException.class)
public void checkNetworkWrong() throws Exception {
DumpedPrivateKey.fromBase58(TESTNET, "5HtUCLMFWNueqN9unpgX2DzjMg6SDNZyKRb8s3LJgpFg5ubuMrk");
}
@Test
public void testJavaSerialization() throws Exception {
DumpedPrivateKey key = new DumpedPrivateKey(MainNetParams.get(), new ECKey().getPrivKeyBytes(), true);
DumpedPrivateKey key = new DumpedPrivateKey(MAINNET, new ECKey().getPrivKeyBytes(), true);
ByteArrayOutputStream os = new ByteArrayOutputStream();
new ObjectOutputStream(os).writeObject(key);
DumpedPrivateKey keyCopy = (DumpedPrivateKey) new ObjectInputStream(new ByteArrayInputStream(os.toByteArray()))
......@@ -42,7 +56,7 @@ public class DumpedPrivateKeyTest {
@Test
public void cloning() throws Exception {
DumpedPrivateKey a = new DumpedPrivateKey(MainNetParams.get(), new ECKey().getPrivKeyBytes(), true);
DumpedPrivateKey a = new DumpedPrivateKey(MAINNET, new ECKey().getPrivKeyBytes(), true);
// TODO: Consider overriding clone() in DumpedPrivateKey to narrow the type
DumpedPrivateKey b = (DumpedPrivateKey) a.clone();
......@@ -50,4 +64,9 @@ public class DumpedPrivateKeyTest {
assertNotSame(a, b);
}
@Test
public void roundtripBase58() throws Exception {
String base58 = "5HtUCLMFWNueqN9unpgX2DzjMg6SDNZyKRb8s3LJgpFg5ubuMrk";
assertEquals(base58, DumpedPrivateKey.fromBase58(null, base58).toBase58());
}
}
......@@ -189,7 +189,7 @@ public class ECKeyTest {
public void base58Encoding() throws Exception {
String addr = "mqAJmaxMcG5pPHHc3H3NtyXzY7kGbJLuMF";
String privkey = "92shANodC6Y4evT5kFzjNFQAdjqTtHAnDTLzqBBq4BbKUPyx6CD";
ECKey key = new DumpedPrivateKey(TestNet3Params.get(), privkey).getKey();
ECKey key = DumpedPrivateKey.fromBase58(TestNet3Params.get(), privkey).getKey();
assertEquals(privkey, key.getPrivateKeyEncoded(TestNet3Params.get()).toString());
assertEquals(addr, key.toAddress(TestNet3Params.get()).toString());
}
......@@ -197,7 +197,7 @@ public class ECKeyTest {
@Test
public void base58Encoding_leadingZero() throws Exception {
String privkey = "91axuYLa8xK796DnBXXsMbjuc8pDYxYgJyQMvFzrZ6UfXaGYuqL";
ECKey key = new DumpedPrivateKey(TestNet3Params.get(), privkey).getKey();
ECKey key = DumpedPrivateKey.fromBase58(TestNet3Params.get(), privkey).getKey();
assertEquals(privkey, key.getPrivateKeyEncoded(TestNet3Params.get()).toString());
assertEquals(0, key.getPrivKeyBytes()[0]);
}
......@@ -207,7 +207,7 @@ public class ECKeyTest {
// Replace the loop bound with 1000 to get some keys with leading zero byte
for (int i = 0 ; i < 20 ; i++) {
ECKey key = new ECKey();
ECKey key1 = new DumpedPrivateKey(TestNet3Params.get(),
ECKey key1 = DumpedPrivateKey.fromBase58(TestNet3Params.get(),
key.getPrivateKeyEncoded(TestNet3Params.get()).toString()).getKey();
assertEquals(Utils.HEX.encode(key.getPrivKeyBytes()),
Utils.HEX.encode(key1.getPrivKeyBytes()));
......@@ -235,7 +235,7 @@ public class ECKeyTest {
// Test vector generated by Bitcoin-Qt.
String message = "hello";
String sigBase64 = "HxNZdo6ggZ41hd3mM3gfJRqOQPZYcO8z8qdX2BwmpbF11CaOQV+QiZGGQxaYOncKoNW61oRuSMMF8udfK54XqI8=";
Address expectedAddress = new Address(MainNetParams.get(), "14YPSNPi6NSXnUxtPAsyJSuw3pv7AU3Cag");
Address expectedAddress = Address.fromBase58(MainNetParams.get(), "14YPSNPi6NSXnUxtPAsyJSuw3pv7AU3Cag");
ECKey key = ECKey.signedMessageToKey(message, sigBase64);
Address gotAddress = key.toAddress(MainNetParams.get());
assertEquals(expectedAddress, gotAddress);
......@@ -365,7 +365,7 @@ public class ECKeyTest {
assertTrue(key.isCompressed());
NetworkParameters params = UnitTestParams.get();
String base58 = key.getPrivateKeyEncoded(params).toString();
ECKey key2 = new DumpedPrivateKey(params, base58).getKey();
ECKey key2 = DumpedPrivateKey.fromBase58(params, base58).getKey();
assertTrue(key2.isCompressed());
assertTrue(Arrays.equals(key.getPrivKeyBytes(), key2.getPrivKeyBytes()));
assertTrue(Arrays.equals(key.getPubKey(), key2.getPubKey()));
......
......@@ -93,7 +93,7 @@ public class FilteredBlockAndPartialMerkleTreeTests extends TestWithPeerGroup {
ECKey key2 = new ECKey();
Transaction tx1 = FakeTxBuilder.createFakeTx(params, Coin.COIN, key1);
Transaction tx2 = FakeTxBuilder.createFakeTx(params, Coin.FIFTY_COINS, key2.toAddress(params));
Block block = FakeTxBuilder.makeSolvedTestBlock(params.getGenesisBlock(), new Address(params, "msg2t2V2sWNd85LccoddtWysBTR8oPnkzW"), tx1, tx2);
Block block = FakeTxBuilder.makeSolvedTestBlock(params.getGenesisBlock(), Address.fromBase58(params, "msg2t2V2sWNd85LccoddtWysBTR8oPnkzW"), tx1, tx2);
BloomFilter filter = new BloomFilter(4, 0.1, 1);
filter.insert(key1);
filter.insert(key2);
......
......@@ -51,7 +51,7 @@ public class TransactionOutputTest extends TestWithWallet {
@Test
public void testP2SHOutputScript() throws Exception {
String P2SHAddressString = "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU";
Address P2SHAddress = new Address(MainNetParams.get(), P2SHAddressString);
Address P2SHAddress = Address.fromBase58(MainNetParams.get(), P2SHAddressString);
Script script = ScriptBuilder.createOutputScript(P2SHAddress);
Transaction tx = new Transaction(MainNetParams.get());
tx.addOutput(Coin.COIN, script);
......
......@@ -37,7 +37,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_noCompression_noEcMultiply_test1() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MAINNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg");
ECKey key = encryptedKey.decrypt("TestingOneTwoThree");
assertEquals("5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR", key.getPrivateKeyEncoded(MAINNET)
......@@ -46,7 +46,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_noCompression_noEcMultiply_test2() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MAINNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq");
ECKey key = encryptedKey.decrypt("Satoshi");
assertEquals("5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5", key.getPrivateKeyEncoded(MAINNET)
......@@ -55,7 +55,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_noCompression_noEcMultiply_test3() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MAINNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PRW5o9FLp4gJDDVqJQKJFTpMvdsSGJxMYHtHaQBF3ooa8mwD69bapcDQn");
StringBuilder passphrase = new StringBuilder();
passphrase.appendCodePoint(0x03d2); // GREEK UPSILON WITH HOOK
......@@ -70,7 +70,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_compression_noEcMultiply_test1() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo");
ECKey key = encryptedKey.decrypt("TestingOneTwoThree");
assertEquals("L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP", key.getPrivateKeyEncoded(MAINNET)
......@@ -79,7 +79,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_compression_noEcMultiply_test2() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7");
ECKey key = encryptedKey.decrypt("Satoshi");
assertEquals("KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7", key.getPrivateKeyEncoded(MAINNET)
......@@ -88,7 +88,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_ecMultiply_noCompression_noLotAndSequence_test1() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX");
ECKey key = encryptedKey.decrypt("TestingOneTwoThree");
assertEquals("5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2", key.getPrivateKeyEncoded(MAINNET)
......@@ -97,7 +97,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_ecMultiply_noCompression_noLotAndSequence_test2() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd");
ECKey key = encryptedKey.decrypt("Satoshi");
assertEquals("5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH", key.getPrivateKeyEncoded(MAINNET)
......@@ -106,7 +106,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_ecMultiply_noCompression_lotAndSequence_test1() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j");
ECKey key = encryptedKey.decrypt("MOLON LABE");
assertEquals("5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8", key.getPrivateKeyEncoded(MAINNET)
......@@ -115,7 +115,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bip38testvector_ecMultiply_noCompression_lotAndSequence_test2() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MainNetParams.get(),
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MainNetParams.get(),
"6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH");
ECKey key = encryptedKey.decrypt("ΜΟΛΩΝ ΛΑΒΕ");
assertEquals("5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D", key.getPrivateKeyEncoded(MAINNET)
......@@ -125,7 +125,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bitcoinpaperwallet_testnet() throws Exception {
// values taken from bitcoinpaperwallet.com
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(TESTNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(TESTNET,
"6PRPhQhmtw6dQu6jD8E1KS4VphwJxBS9Eh9C8FQELcrwN3vPvskv9NKvuL");
ECKey key = encryptedKey.decrypt("password");
assertEquals("93MLfjbY6ugAsLeQfFY6zodDa8izgm1XAwA9cpMbUTwLkDitopg", key.getPrivateKeyEncoded(TESTNET)
......@@ -135,7 +135,7 @@ public class BIP38PrivateKeyTest {
@Test
public void bitaddress_testnet() throws Exception {
// values taken from bitaddress.org
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(TESTNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(TESTNET,
"6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb");
ECKey key = encryptedKey.decrypt("password");
assertEquals("91tCpdaGr4Khv7UAuUxa6aMqeN5GcPVJxzLtNsnZHTCndxkRcz2", key.getPrivateKeyEncoded(TESTNET)
......@@ -144,14 +144,14 @@ public class BIP38PrivateKeyTest {
@Test(expected = BadPassphraseException.class)
public void badPassphrase() throws Exception {
BIP38PrivateKey encryptedKey = new BIP38PrivateKey(MAINNET,
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg");
encryptedKey.decrypt("BAD");
}
@Test
public void testJavaSerialization() throws Exception {
BIP38PrivateKey testKey = new BIP38PrivateKey(TESTNET,
BIP38PrivateKey testKey = BIP38PrivateKey.fromBase58(TESTNET,
"6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb");
ByteArrayOutputStream os = new ByteArrayOutputStream();
new ObjectOutputStream(os).writeObject(testKey);
......@@ -159,7 +159,7 @@ public class BIP38PrivateKeyTest {
new ByteArrayInputStream(os.toByteArray())).readObject();
assertEquals(testKey, testKeyCopy);
BIP38PrivateKey mainKey = new BIP38PrivateKey(MAINNET,
BIP38PrivateKey mainKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb");
os = new ByteArrayOutputStream();
new ObjectOutputStream(os).writeObject(mainKey);
......@@ -170,11 +170,17 @@ public class BIP38PrivateKeyTest {
@Test
public void cloning() throws Exception {
BIP38PrivateKey a = new BIP38PrivateKey(TESTNET, "6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb");
BIP38PrivateKey a = BIP38PrivateKey.fromBase58(TESTNET, "6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb");
// TODO: Consider overriding clone() in BIP38PrivateKey to narrow the type
BIP38PrivateKey b = (BIP38PrivateKey) a.clone();
assertEquals(a, b);
assertNotSame(a, b);
}
@Test
public void roundtripBase58() throws Exception {
String base58 = "6PfMmVHn153N3x83Yiy4Nf76dHUkXufe2Adr9Fw5bewrunGNeaw2QCpifb";
assertEquals(base58, BIP38PrivateKey.fromBase58(MAINNET, base58).toBase58());
}
}
......@@ -106,7 +106,7 @@ public class ScriptTest {
@Test
public void testP2SHOutputScript() throws Exception {
Address p2shAddress = new Address(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
Address p2shAddress = Address.fromBase58(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
assertTrue(ScriptBuilder.createOutputScript(p2shAddress).isPayToScriptHash());
}
......@@ -120,15 +120,15 @@ public class ScriptTest {
@Test
public void testCreateMultiSigInputScript() throws AddressFormatException {
// Setup transaction and signatures
ECKey key1 = new DumpedPrivateKey(params, "cVLwRLTvz3BxDAWkvS3yzT9pUcTCup7kQnfT2smRjvmmm1wAP6QT").getKey();
ECKey key2 = new DumpedPrivateKey(params, "cTine92s8GLpVqvebi8rYce3FrUYq78ZGQffBYCS1HmDPJdSTxUo").getKey();
ECKey key3 = new DumpedPrivateKey(params, "cVHwXSPRZmL9adctwBwmn4oTZdZMbaCsR5XF6VznqMgcvt1FDDxg").getKey();
ECKey key1 = DumpedPrivateKey.fromBase58(params, "cVLwRLTvz3BxDAWkvS3yzT9pUcTCup7kQnfT2smRjvmmm1wAP6QT").getKey();
ECKey key2 = DumpedPrivateKey.fromBase58(params, "cTine92s8GLpVqvebi8rYce3FrUYq78ZGQffBYCS1HmDPJdSTxUo").getKey();
ECKey key3 = DumpedPrivateKey.fromBase58(params, "cVHwXSPRZmL9adctwBwmn4oTZdZMbaCsR5XF6VznqMgcvt1FDDxg").getKey();
Script multisigScript = ScriptBuilder.createMultiSigOutputScript(2, Arrays.asList(key1, key2, key3));
byte[] bytes = HEX.decode("01000000013df681ff83b43b6585fa32dd0e12b0b502e6481e04ee52ff0fdaf55a16a4ef61000000006b483045022100a84acca7906c13c5895a1314c165d33621cdcf8696145080895cbf301119b7cf0220730ff511106aa0e0a8570ff00ee57d7a6f24e30f592a10cae1deffac9e13b990012102b8d567bcd6328fd48a429f9cf4b315b859a58fd28c5088ef3cb1d98125fc4e8dffffffff02364f1c00000000001976a91439a02793b418de8ec748dd75382656453dc99bcb88ac40420f000000000017a9145780b80be32e117f675d6e0ada13ba799bf248e98700000000");
Transaction transaction = new Transaction(params, bytes);
TransactionOutput output = transaction.getOutput(1);
Transaction spendTx = new Transaction(params);
Address address = new Address(params, "n3CFiCmBXVt5d3HXKQ15EFZyhPz4yj5F3H");
Address address = Address.fromBase58(params, "n3CFiCmBXVt5d3HXKQ15EFZyhPz4yj5F3H");
Script outputScript = ScriptBuilder.createOutputScript(address);
spendTx.addOutput(output.getValue(), outputScript);
spendTx.addInput(output);
......
......@@ -25,7 +25,7 @@ public class LevelDBBlockStoreTest {
assertEquals(0, genesis.getHeight());
// Build a new block.
Address to = new Address(params, "mrj2K6txjo2QBcSmuAzHj4nD1oXSEJE1Qo");
Address to = Address.fromBase58(params, "mrj2K6txjo2QBcSmuAzHj4nD1oXSEJE1Qo");
StoredBlock b1 = genesis.build(genesis.getHeader().createNextBlock(to).cloneAsHeader());
store.put(b1);
store.setChainHead(b1);
......
......@@ -33,7 +33,7 @@ public class BitcoinURITest {
@Test
public void testConvertToBitcoinURI() throws Exception {
Address goodAddress = new Address(MainNetParams.get(), MAINNET_GOOD_ADDRESS);
Address goodAddress = Address.fromBase58(MainNetParams.get(), MAINNET_GOOD_ADDRESS);
// simple example
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello&message=AMessage", BitcoinURI.convertToBitcoinURI(goodAddress, parseCoin("12.34"), "Hello", "AMessage"));
......
......@@ -59,7 +59,7 @@ public class DeterministicKeyChainTest {
ECKey key2 = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
assertFalse(key2.isPubKeyOnly());
final Address address = new Address(UnitTestParams.get(), "n1bQNoEx8uhmCzzA5JPG6sFdtsUQhwiQJV");
final Address address = Address.fromBase58(UnitTestParams.get(), "n1bQNoEx8uhmCzzA5JPG6sFdtsUQhwiQJV");
assertEquals(address, key1.toAddress(UnitTestParams.get()));
assertEquals("mnHUcqUVvrfi5kAaXJDQzBb9HsWs78b42R", key2.toAddress(UnitTestParams.get()).toString());
assertEquals(key1, chain.findKeyFromPubHash(address.getHash160()));
......@@ -90,7 +90,7 @@ public class DeterministicKeyChainTest {
ECKey key1 = chain1.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
ECKey key2 = chain1.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
final Address address = new Address(UnitTestParams.get(), "n2nHHRHs7TiZScTuVhZUkzZfTfVgGYwy6X");
final Address address = Address.fromBase58(UnitTestParams.get(), "n2nHHRHs7TiZScTuVhZUkzZfTfVgGYwy6X");
assertEquals(address, key1.toAddress(UnitTestParams.get()));
assertEquals("mnp2j9za5zMuz44vNxrJCXXhZsCdh89QXn", key2.toAddress(UnitTestParams.get()).toString());
assertEquals(key1, chain1.findKeyFromPubHash(address.getHash160()));
......@@ -124,7 +124,7 @@ public class DeterministicKeyChainTest {
DeterministicKeyChain chain1 = new AccountOneChain(ENTROPY, "", secs);
ECKey key1 = chain1.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
final Address address = new Address(UnitTestParams.get(), "n2nHHRHs7TiZScTuVhZUkzZfTfVgGYwy6X");
final Address address = Address.fromBase58(UnitTestParams.get(), "n2nHHRHs7TiZScTuVhZUkzZfTfVgGYwy6X");
assertEquals(address, key1.toAddress(UnitTestParams.get()));
DeterministicKey watching = chain1.getWatchingKey();
......
......@@ -28,8 +28,8 @@ public class DoubleSpend {
System.out.println(kit.wallet());
kit.wallet().getBalanceFuture(COIN, Wallet.BalanceType.AVAILABLE).get();
Transaction tx1 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT);
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT.add(SATOSHI.multiply(10)));
Transaction tx1 = kit.wallet().createSend(Address.fromBase58(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT);
Transaction tx2 = kit.wallet().createSend(Address.fromBase58(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT.add(SATOSHI.multiply(10)));
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
peer.addEventListener(new AbstractPeerEventListener() {
@Override
......
......@@ -62,7 +62,7 @@ public class ForwardingService {
filePrefix = "forwarding-service";
}
// Parse the address given as the first parameter.