package org.ripple.power.txns.btc; import java.util.Arrays; import org.ripple.power.Helper; /** * An address is a 20-byte Hash160 of a public key. The displayable form * is Base-58 encoded with a 1-byte version and a 4-byte checksum. */ public class Address { /** Address label */ private String label; /** Address hash */ private byte[] hash; /** * Creates a new Address with a zero public key hash */ public Address() { this (new byte[20]); } /** * Creates a new Address using the 20-byte public key hash * * @param hash Public key hash */ public Address(byte[] hash) { this(hash, ""); } /** * Creates a new Address using the 20-byte public key hash and a label * * @param hash Public key hash * @param label Address label */ public Address(byte[] hash, String label) { this.hash = hash; this.label = label; } /** * Creates a new Address using a Base-58 encoded address * * @param address Encoded address * @throws AddressFormatException Address string is not a valid address */ public Address(String address) throws AddressFormatException { this(address, ""); } /** * Creates a new Address using a Base-58 encoded address and a label * * @param address Encoded address * @param label Address label * @throws AddressFormatException Address string is not valid */ public Address(String address, String label) throws AddressFormatException { // // Set the label // this.label = label; // // Decode the address // byte[] decoded = Base58.decodeChecked(address); int version = (int)decoded[0]&0xff; if (version != NetParams.ADDRESS_VERSION) throw new AddressFormatException(String.format("Address version %d is not correct", version)); // // The address must be 20 bytes // if (decoded.length != 20+1) throw new AddressFormatException("Address length is not 20 bytes"); // // Get the public key hash // hash = Arrays.copyOfRange(decoded, 1, decoded.length); } /** * Returns the address label * * @return Address label */ public String getLabel() { return label; } /** * Sets the address label * * @param label Address label */ public void setLabel(String label) { this.label = label; } /** * Returns the address hash * * @return 20-byte address hash */ public byte[] getHash() { return hash; } /** * Returns the address as a Base58-encoded string with a 1-byte version * and a 4-byte checksum * * @return Encoded string */ @Override public String toString() { byte[] addressBytes = new byte[1+hash.length+4]; addressBytes[0] = (byte)NetParams.ADDRESS_VERSION; System.arraycopy(hash, 0, addressBytes, 1, hash.length); byte[] digest = Helper.doubleDigest(addressBytes, 0, hash.length+1); System.arraycopy(digest, 0, addressBytes, hash.length+1, 4); return Base58.encode(addressBytes); } /** * Returns the hash code for this object * * @return Hash code */ @Override public int hashCode() { return Arrays.hashCode(hash); } /** * Checks if two objects are equal * * @param obj The object to check * @return TRUE if the objects are equal */ @Override public boolean equals(Object obj) { return (obj!=null && (obj instanceof Address) && Arrays.equals(hash, ((Address)obj).hash)); } }