80 lines
2.5 KiB
Java
80 lines
2.5 KiB
Java
package cy.agorise.graphenej;
|
|
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.primitives.Bytes;
|
|
import cy.agorise.graphenej.errors.MalformedAddressException;
|
|
import org.bitcoinj.core.Base58;
|
|
import org.bitcoinj.core.ECKey;
|
|
import org.spongycastle.crypto.digests.RIPEMD160Digest;
|
|
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* Class used to encapsulate address-related operations.
|
|
*/
|
|
public class Address {
|
|
|
|
public final static String BITSHARES_PREFIX = "BTS";
|
|
|
|
private PublicKey publicKey;
|
|
private String prefix;
|
|
|
|
public Address(ECKey key) {
|
|
this.publicKey = new PublicKey(key);
|
|
this.prefix = BITSHARES_PREFIX;
|
|
}
|
|
|
|
public Address(ECKey key, String prefix) {
|
|
this.publicKey = new PublicKey(key);
|
|
this.prefix = prefix;
|
|
}
|
|
|
|
public Address(String address) throws MalformedAddressException {
|
|
this.prefix = address.substring(0, 3);
|
|
byte[] decoded = Base58.decode(address.substring(3, address.length()));
|
|
byte[] pubKey = Arrays.copyOfRange(decoded, 0, decoded.length - 4);
|
|
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
|
|
publicKey = new PublicKey(ECKey.fromPublicOnly(pubKey));
|
|
byte[] calculatedChecksum = calculateChecksum(pubKey);
|
|
for(int i = 0; i < calculatedChecksum.length; i++){
|
|
if(checksum[i] != calculatedChecksum[i]){
|
|
throw new MalformedAddressException("Checksum error");
|
|
}
|
|
}
|
|
}
|
|
|
|
public PublicKey getPublicKey(){
|
|
return this.publicKey;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
byte[] pubKey = this.publicKey.toBytes();
|
|
byte[] checksum = calculateChecksum(pubKey);
|
|
byte[] pubKeyChecksummed = Bytes.concat(pubKey, checksum);
|
|
return this.prefix + Base58.encode(pubKeyChecksummed);
|
|
}
|
|
|
|
private byte[] calculateChecksum(byte[] data){
|
|
byte[] checksum = new byte[160 / 8];
|
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
|
ripemd160Digest.update(data, 0, data.length);
|
|
ripemd160Digest.doFinal(checksum, 0);
|
|
return Arrays.copyOfRange(checksum, 0, 4);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) return true;
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
Address address = (Address) o;
|
|
return Objects.equal(publicKey, address.publicKey) &&
|
|
Objects.equal(prefix, address.prefix);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hashCode(publicKey, prefix);
|
|
}
|
|
}
|