mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-02 13:37:24 +00:00
Support for discovering the network parameters from an address. Different exception type for wrong network parameters so chain-crossing can be handled differently.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
/**
|
||||
* A BitCoin address is fundamentally derived from an elliptic curve public key and a set of network parameters.
|
||||
* A Bitcoin address is derived from an elliptic curve public key and a set of network parameters.
|
||||
* It has several possible representations:<p>
|
||||
*
|
||||
* <ol>
|
||||
@@ -26,6 +26,9 @@ package com.google.bitcoin.core;
|
||||
* <li>A base58 encoded "human form" that includes a version and check code, to guard against typos.
|
||||
* </ol><p>
|
||||
*
|
||||
* The most common written form is the latter, and there may be several different types of address with the meaning
|
||||
* determined by the version code.<p>
|
||||
*
|
||||
* One may question whether the base58 form is really an improvement over the hash160 form, given
|
||||
* they are both very unfriendly for typists. More useful representations might include qrcodes
|
||||
* and identicons.<p>
|
||||
@@ -47,17 +50,78 @@ public class Address extends VersionedChecksummedBytes {
|
||||
/**
|
||||
* Construct an address from parameters and the standard "human readable" form. Example:<p>
|
||||
*
|
||||
* <pre>new Address(NetworkParameters.prodNet(), "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");</pre>
|
||||
* <pre>new Address(NetworkParameters.prodNet(), "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 prodnet)
|
||||
*/
|
||||
public Address(NetworkParameters params, String address) throws AddressFormatException {
|
||||
public Address(NetworkParameters params, String address) throws AddressFormatException, WrongNetworkException {
|
||||
super(address);
|
||||
if (version != params.addressHeader)
|
||||
throw new AddressFormatException("Mismatched version number, trying to cross networks? " + version +
|
||||
" vs " + params.addressHeader);
|
||||
if (params != null) {
|
||||
boolean found = false;
|
||||
for (int v : params.acceptableAddressCodes) {
|
||||
if (version == v) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new WrongNetworkException(version, params.acceptableAddressCodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The (big endian) 20 byte hash that is the core of a BitCoin address. */
|
||||
public byte[] getHash160() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 a NetworkParameters representing the network the address is intended for, or null if unknown.
|
||||
*/
|
||||
public NetworkParameters getParameters() {
|
||||
// TODO: There should be a more generic way to get all supported networks.
|
||||
NetworkParameters[] networks =
|
||||
new NetworkParameters[] { NetworkParameters.testNet(), NetworkParameters.prodNet() };
|
||||
|
||||
for (NetworkParameters params : networks) {
|
||||
if (params.acceptableAddressCodes == null) {
|
||||
// Old Java-serialized wallet. This code can eventually be deleted.
|
||||
if (params.getId().equals(NetworkParameters.ID_PRODNET))
|
||||
params = NetworkParameters.prodNet();
|
||||
else if (params.getId().equals(NetworkParameters.ID_TESTNET))
|
||||
params = NetworkParameters.testNet();
|
||||
}
|
||||
for (int code : params.acceptableAddressCodes) {
|
||||
if (code == version) {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an address, examines the version byte 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.
|
||||
*
|
||||
* @param address
|
||||
* @return a NetworkParameters representing the network the address is intended for, or null if unknown.
|
||||
*/
|
||||
public static NetworkParameters getParametersFromAddress(String address) throws AddressFormatException {
|
||||
try {
|
||||
return new Address(null, address).getParameters();
|
||||
} catch (WrongNetworkException e) {
|
||||
// Cannot happen.
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ public class Base58 {
|
||||
}
|
||||
|
||||
public static byte[] decode(String input) throws AddressFormatException {
|
||||
if (input.length() == 0) {
|
||||
throw new AddressFormatException("Attempt to parse an empty address.");
|
||||
}
|
||||
byte[] bytes = decodeToBigInteger(input).toByteArray();
|
||||
// We may have got one more byte than we wanted, if the high bit of the next-to-last byte was not zero. This
|
||||
// is because BigIntegers are represented with twos-compliment notation, thus if the high bit of the last
|
||||
|
||||
@@ -73,7 +73,11 @@ public class NetworkParameters implements Serializable {
|
||||
public int port;
|
||||
/** The header bytes that identify the start of a packet on this network. */
|
||||
public long packetMagic;
|
||||
/** First byte of a base58 encoded address. See {@link Address}*/
|
||||
/**
|
||||
* First byte of a base58 encoded address. See {@link Address}. This is the same as acceptableAddressCodes[0] and
|
||||
* is the one used for "normal" addresses. Other types of address may be encountered with version codes found in
|
||||
* the acceptableAddressCodes array.
|
||||
*/
|
||||
public int addressHeader;
|
||||
/** First byte of a base58 encoded dumped private key. See {@link DumpedPrivateKey}. */
|
||||
public int dumpedPrivateKeyHeader;
|
||||
@@ -96,7 +100,14 @@ public class NetworkParameters implements Serializable {
|
||||
* by looking at the port number.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
|
||||
/**
|
||||
* The version codes that prefix addresses which are acceptable on this network. Although Satoshi intended these to
|
||||
* be used for "versioning", in fact they are today used to discriminate what kind of data is contained in the
|
||||
* address and to prevent accidentally sending coins across chains which would destroy them.
|
||||
*/
|
||||
public int[] acceptableAddressCodes;
|
||||
|
||||
private static Block createGenesis(NetworkParameters n) {
|
||||
Block genesisBlock = new Block(n);
|
||||
Transaction t = new Transaction(n);
|
||||
@@ -132,6 +143,7 @@ public class NetworkParameters implements Serializable {
|
||||
n.packetMagic = 0xfabfb5daL;
|
||||
n.port = 18333;
|
||||
n.addressHeader = 111;
|
||||
n.acceptableAddressCodes = new int[] { 111 };
|
||||
n.dumpedPrivateKeyHeader = 239;
|
||||
n.interval = INTERVAL;
|
||||
n.targetTimespan = TARGET_TIMESPAN;
|
||||
@@ -160,6 +172,7 @@ public class NetworkParameters implements Serializable {
|
||||
n.port = 8333;
|
||||
n.packetMagic = 0xf9beb4d9L;
|
||||
n.addressHeader = 0;
|
||||
n.acceptableAddressCodes = new int[] { 0 };
|
||||
n.dumpedPrivateKeyHeader = 128;
|
||||
n.interval = INTERVAL;
|
||||
n.targetTimespan = TARGET_TIMESPAN;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This exception is thrown by the Address class when you try and decode an address with a version code that isn't
|
||||
* used by that network. You shouldn't allow the user to proceed in this case as they are trying to send money across
|
||||
* different chains, an operation that is guaranteed to destroy the money.
|
||||
*/
|
||||
public class WrongNetworkException extends AddressFormatException {
|
||||
/** The version code that was provided in the address. */
|
||||
public int verCode;
|
||||
/** The list of acceptable versions that were expected given the addresses network parameters. */
|
||||
public int[] acceptableVersions;
|
||||
|
||||
public WrongNetworkException(int verCode, int[] acceptableVersions) {
|
||||
super("Version code of address did not match acceptable versions for network: " + verCode + " not in " +
|
||||
Arrays.toString(acceptableVersions));
|
||||
this.verCode = verCode;
|
||||
this.acceptableVersions = acceptableVersions;
|
||||
}
|
||||
}
|
||||
@@ -34,27 +34,26 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Provides a standard implementation of a Bitcoin URI with support for the
|
||||
* following:
|
||||
* </p>
|
||||
* <p>Provides a standard implementation of a Bitcoin URI with support for the
|
||||
* following:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>URLEncoded URIs (as passed in by IE on the command line)</li>
|
||||
* <li>BIP21 names (including the "req-" prefix handling requirements)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Accepted formats</h2>
|
||||
* <p>
|
||||
* The following input forms are accepted
|
||||
* </p>
|
||||
*
|
||||
* <p>The following input forms are accepted:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code bitcoin:<address>}</li>
|
||||
* <li>{@code bitcoin:<address>?<name1>=<value1>&<name2>=<value2>} with multiple
|
||||
* additional name/value pairs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The name/value pairs are processed as follows:
|
||||
* </p>
|
||||
* <ul>
|
||||
*
|
||||
* <p>The name/value pairs are processed as follows.</p>
|
||||
* <ol>
|
||||
* <li>URL encoding is stripped and treated as UTF-8</li>
|
||||
* <li>names prefixed with {@code req-} are treated as required and if unknown
|
||||
* or conflicting cause a parse exception</li>
|
||||
@@ -62,10 +61,9 @@ import java.util.Map;
|
||||
* by parameter name</li>
|
||||
* <li>Known names not prefixed with {@code req-} are processed unless they are
|
||||
* malformed</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The following names are known and have the following formats
|
||||
* </p>
|
||||
* </ol>
|
||||
*
|
||||
* <p>The following names are known and have the following formats</p>
|
||||
* <ul>
|
||||
* <li>{@code amount} decimal value to 8 dp (e.g. 0.12345678) <b>Note that the
|
||||
* exponent notation is not supported any more</b></li>
|
||||
@@ -85,10 +83,10 @@ public class BitcoinURI {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitcoinURI.class);
|
||||
|
||||
// Not worth turning into an enum
|
||||
private static final String FIELD_MESSAGE = "message";
|
||||
private static final String FIELD_LABEL = "label";
|
||||
private static final String FIELD_AMOUNT = "amount";
|
||||
private static final String FIELD_ADDRESS = "address";
|
||||
public static final String FIELD_MESSAGE = "message";
|
||||
public static final String FIELD_LABEL = "label";
|
||||
public static final String FIELD_AMOUNT = "amount";
|
||||
public static final String FIELD_ADDRESS = "address";
|
||||
|
||||
public static final String BITCOIN_SCHEME = "bitcoin";
|
||||
private static final String ENCODED_SPACE_CHARACTER = "%20";
|
||||
@@ -102,7 +100,7 @@ public class BitcoinURI {
|
||||
private final Map<String, Object> parameterMap = new LinkedHashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* @param networkParameters
|
||||
* @param params
|
||||
* The BitCoinJ network parameters that determine which network
|
||||
* the URI is from
|
||||
* @param input
|
||||
@@ -111,16 +109,16 @@ public class BitcoinURI {
|
||||
* @throws BitcoinURIParseException
|
||||
* If the input fails Bitcoin URI syntax and semantic checks
|
||||
*/
|
||||
public BitcoinURI(NetworkParameters networkParameters, String input) {
|
||||
public BitcoinURI(NetworkParameters params, String input) {
|
||||
// Basic validation
|
||||
if (networkParameters == null) {
|
||||
if (params == null) {
|
||||
throw new IllegalArgumentException("NetworkParameters cannot be null");
|
||||
}
|
||||
if (input == null) {
|
||||
throw new IllegalArgumentException("Input cannot be null");
|
||||
}
|
||||
|
||||
log.debug("Attempting to parse '{}' for {}", input, networkParameters.port == 8333 ? "prodNet" : "testNet");
|
||||
log.debug("Attempting to parse '{}' for {}", input, params.getId());
|
||||
|
||||
// URI validation
|
||||
if (!input.startsWith(BITCOIN_SCHEME)) {
|
||||
@@ -137,16 +135,17 @@ public class BitcoinURI {
|
||||
|
||||
// URI is formed as bitcoin:<address>?<query parameters>
|
||||
|
||||
// Remove the bitcoin scheme
|
||||
// Remove the bitcoin scheme.
|
||||
// (Note: getSchemeSpecificPart() is not used as it unescapes the label and parse then fails.
|
||||
// For instance with : bitcoin:129mVqKUmJ9uwPxKJBnNdABbuaaNfho4Ha?amount=0.06&label=Tom%20%26%20Jerry
|
||||
// the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed as 'Tom ' instead of 'Tom & Jerry')
|
||||
// the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed
|
||||
// as 'Tom ' instead of 'Tom & Jerry')
|
||||
String schemeSpecificPart = "";
|
||||
if (uri.toString().startsWith(BITCOIN_SCHEME + COLON_SEPARATOR)) {
|
||||
schemeSpecificPart = uri.toString().substring(BITCOIN_SCHEME.length() + 1);
|
||||
}
|
||||
|
||||
// Split off the address from the rest of the query parameters
|
||||
// Split off the address from the rest of the query parameters.
|
||||
String[] addressSplitTokens = schemeSpecificPart.split("\\?");
|
||||
if (addressSplitTokens.length == 0 || "".equals(addressSplitTokens[0])) {
|
||||
throw new BitcoinURIParseException("Missing address");
|
||||
@@ -155,51 +154,51 @@ public class BitcoinURI {
|
||||
|
||||
String[] nameValuePairTokens;
|
||||
if (addressSplitTokens.length == 1) {
|
||||
// only an address is specified - use an empty '<name>=<value>' token array
|
||||
// Only an address is specified - use an empty '<name>=<value>' token array.
|
||||
nameValuePairTokens = new String[] {};
|
||||
} else {
|
||||
if (addressSplitTokens.length == 2) {
|
||||
// split into '<name>=<value>' tokens
|
||||
// Split into '<name>=<value>' tokens.
|
||||
nameValuePairTokens = addressSplitTokens[1].split("&");
|
||||
} else {
|
||||
throw new BitcoinURIParseException("Too many question marks in URI '" + input + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to parse the rest of the URI parameters
|
||||
parseParameters(networkParameters, addressToken, nameValuePairTokens);
|
||||
// Attempt to parse the rest of the URI parameters.
|
||||
parseParameters(params, addressToken, nameValuePairTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param networkParameters
|
||||
* @param params
|
||||
* The network parameters
|
||||
* @param nameValuePairTokens
|
||||
* The tokens representing the name value pairs (assumed to be
|
||||
* separated by '=' e.g. 'amount=0.2')
|
||||
*/
|
||||
private void parseParameters(NetworkParameters networkParameters, String addressToken, String[] nameValuePairTokens) {
|
||||
private void parseParameters(NetworkParameters params, String addressToken, String[] nameValuePairTokens) {
|
||||
// Attempt to parse the addressToken as a Bitcoin address for this network
|
||||
try {
|
||||
Address address = new Address(networkParameters, addressToken);
|
||||
Address address = new Address(params, addressToken);
|
||||
putWithValidation(FIELD_ADDRESS, address);
|
||||
} catch (final AddressFormatException e) {
|
||||
throw new BitcoinURIParseException("Bad address", e);
|
||||
}
|
||||
|
||||
// Attempt to decode the rest of the tokens into a parameter map
|
||||
// Attempt to decode the rest of the tokens into a parameter map.
|
||||
for (int i = 0; i < nameValuePairTokens.length; i++) {
|
||||
|
||||
String[] tokens = nameValuePairTokens[i].split("=");
|
||||
if (tokens.length != 2 || "".equals(tokens[0])) {
|
||||
throw new BitcoinURIParseException("Malformed Bitcoin URI - cannot parse name value pair '" + nameValuePairTokens[i] + "'");
|
||||
throw new BitcoinURIParseException("Malformed Bitcoin URI - cannot parse name value pair '" +
|
||||
nameValuePairTokens[i] + "'");
|
||||
}
|
||||
|
||||
String nameToken = tokens[0].toLowerCase();
|
||||
String valueToken = tokens[1];
|
||||
|
||||
// Parse the amount
|
||||
// Parse the amount.
|
||||
if (FIELD_AMOUNT.equals(nameToken)) {
|
||||
// Decode the amount (contains an optional decimal component to 8dp)
|
||||
// Decode the amount (contains an optional decimal component to 8dp).
|
||||
try {
|
||||
BigInteger amount = Utils.toNanoCoins(valueToken);
|
||||
putWithValidation(FIELD_AMOUNT, amount);
|
||||
@@ -208,33 +207,29 @@ public class BitcoinURI {
|
||||
}
|
||||
} else {
|
||||
if (nameToken.startsWith("req-")) {
|
||||
// A required parameter that we do not know about
|
||||
// A required parameter that we do not know about.
|
||||
throw new RequiredFieldValidationException("'" + nameToken + "' is required but not known, this URI is not valid");
|
||||
} else {
|
||||
// Known fields and unknown parameters that are optional
|
||||
// Known fields and unknown parameters that are optional.
|
||||
try {
|
||||
putWithValidation(nameToken, URLDecoder.decode(valueToken, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// should not happen as UTF-8 is valid encoding
|
||||
// Unreachable.
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note to the future : when you want to implement 'req-expires' have a look at commit 410a53791841 which had it in
|
||||
// Note to the future: when you want to implement 'req-expires' have a look at commit 410a53791841
|
||||
// which had it in.
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Put the value against the key in the map checking for duplication.
|
||||
* This avoids address field overwrite etc.
|
||||
* </p>
|
||||
* Put the value against the key in the map checking for duplication. This avoids address field overwrite etc.
|
||||
*
|
||||
* @param key
|
||||
* The key for the map
|
||||
* @param value
|
||||
* The value to store
|
||||
* @param key The key for the map
|
||||
* @param value The value to store
|
||||
*/
|
||||
private void putWithValidation(String key, Object value) {
|
||||
if (parameterMap.containsKey(key)) {
|
||||
@@ -298,18 +293,12 @@ public class BitcoinURI {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Simple Bitcoin URI builder using known good fields
|
||||
* </p>
|
||||
* Simple Bitcoin URI builder using known good fields.
|
||||
*
|
||||
* @param address
|
||||
* The Bitcoin address
|
||||
* @param amount
|
||||
* The amount in nanocoins (decimal)
|
||||
* @param label
|
||||
* A label
|
||||
* @param message
|
||||
* A message
|
||||
* @param address The Bitcoin address
|
||||
* @param amount The amount in nanocoins (decimal)
|
||||
* @param label A label
|
||||
* @param message A message
|
||||
* @return A String containing the Bitcoin URI
|
||||
*/
|
||||
public static String convertToBitcoinURI(Address address, BigInteger amount, String label, String message) {
|
||||
@@ -356,12 +345,9 @@ public class BitcoinURI {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Encode a string using URL encoding
|
||||
* </p>
|
||||
*
|
||||
* @param stringToEncode
|
||||
* The string to URL encode
|
||||
* @param stringToEncode The string to URL encode
|
||||
*/
|
||||
static String encodeURLString(String stringToEncode) {
|
||||
try {
|
||||
|
||||
@@ -9,11 +9,9 @@ package com.google.bitcoin.uri;
|
||||
* that reported in the exception message). Since this is in English, it may not be worth reporting directly
|
||||
* to the user other than as part of a "general failure to parse" response.</p>
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public class BitcoinURIParseException extends RuntimeException {
|
||||
|
||||
public BitcoinURIParseException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
@@ -19,14 +19,16 @@ package com.google.bitcoin.core;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class AddressTest {
|
||||
static final NetworkParameters testParams = NetworkParameters.testNet();
|
||||
static final NetworkParameters prodParams = NetworkParameters.prodNet();
|
||||
|
||||
@Test
|
||||
public void testStringification() throws Exception {
|
||||
public void stringification() throws Exception {
|
||||
// Test a testnet address.
|
||||
Address a = new Address(testParams, Hex.decode("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc"));
|
||||
assertEquals("n4eA2nbYqErp7H6jebchxAN59DmNpksexv", a.toString());
|
||||
@@ -36,11 +38,54 @@ public class AddressTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecoding() throws Exception {
|
||||
public void decoding() throws Exception {
|
||||
Address a = new Address(testParams, "n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
|
||||
assertEquals("fda79a24e50ff70ff42f7d89585da5bd19d9e5cc", Utils.bytesToHexString(a.getHash160()));
|
||||
|
||||
Address b = new Address(prodParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
|
||||
assertEquals("4a22c3c4cbb31e4d03b15550636762bda0baf85a", Utils.bytesToHexString(b.getHash160()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorPaths() {
|
||||
// Check what happens if we try and decode garbage.
|
||||
try {
|
||||
new Address(testParams, "this is not a valid address!");
|
||||
fail();
|
||||
} catch (WrongNetworkException e) {
|
||||
fail();
|
||||
} catch (AddressFormatException e) {
|
||||
// Success.
|
||||
}
|
||||
|
||||
// Check the empty case.
|
||||
try {
|
||||
new Address(testParams, "");
|
||||
fail();
|
||||
} catch (WrongNetworkException e) {
|
||||
fail();
|
||||
} catch (AddressFormatException e) {
|
||||
// Success.
|
||||
}
|
||||
|
||||
// Check the case of a mismatched network.
|
||||
try {
|
||||
new Address(testParams, "17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
|
||||
fail();
|
||||
} catch (WrongNetworkException e) {
|
||||
// Success.
|
||||
assertEquals(e.verCode, NetworkParameters.prodNet().addressHeader);
|
||||
assertTrue(Arrays.equals(e.acceptableVersions, NetworkParameters.testNet().acceptableAddressCodes));
|
||||
} catch (AddressFormatException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNetwork() throws Exception {
|
||||
NetworkParameters params = Address.getParametersFromAddress("17kzeh4N8g49GFvdDzSf8PjaPfyoD1MndL");
|
||||
assertEquals(NetworkParameters.prodNet().getId(), params.getId());
|
||||
params = Address.getParametersFromAddress("n4eA2nbYqErp7H6jebchxAN59DmNpksexv");
|
||||
assertEquals(NetworkParameters.testNet().getId(), params.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class BitcoinURITest {
|
||||
* @throws AddressFormatException
|
||||
*/
|
||||
@Test
|
||||
public void testConvertToBitcoinURI() throws BitcoinURIParseException, AddressFormatException {
|
||||
public void testConvertToBitcoinURI() throws Exception {
|
||||
Address goodAddress = new Address(NetworkParameters.prodNet(), PRODNET_GOOD_ADDRESS);
|
||||
|
||||
// simple example
|
||||
|
||||
Reference in New Issue
Block a user