Skip to content

Commit

Permalink
#100: add address version params (method overloading, mostly), fix do…
Browse files Browse the repository at this point in the history
…cs, and a bit of code org.
  • Loading branch information
gsmachado committed Jan 28, 2020
1 parent d8397fd commit 06b8b2c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 33 deletions.
46 changes: 24 additions & 22 deletions crypto/src/main/java/io/neow3j/crypto/ECKeyPair.java
Expand Up @@ -40,13 +40,13 @@
*/
public class ECKeyPair {

private final BigInteger privateKey;
private final ECPublicKey publicKey;

static {
addBouncyCastle();
}

private final BigInteger privateKey;
private final ECPublicKey publicKey;

// TODO: Remove as soon as private key is also its own type (ECPrivateKey).
public ECKeyPair(BigInteger privateKey, BigInteger publicKey) {
this.privateKey = privateKey;
Expand All @@ -59,7 +59,6 @@ public ECKeyPair(BigInteger privateKey, ECPublicKey publicKey) {
this.publicKey = publicKey;
}


public BigInteger getPrivateKey() {
return privateKey;
}
Expand All @@ -75,14 +74,26 @@ public ECPublicKey getPublicKey2() {
}

/**
* Constructs the NEO address from this key pairs public key.
* The address is constructed ad hoc each time this method is called.
* Constructs the NEO address from this key pairs public key, specifying the address version
* prefix and the address version. The address is constructed ad hoc each time this method is
* called.
*
* @return the NEO address of the public key.
*/
public String getAddress() {
public String getAddress(byte addressVersion) {
byte[] script = ScriptBuilder.buildVerificationScript(this.publicKey.getEncoded(true));
return ScriptHash.fromScript(script).toAddress();
return ScriptHash.fromScript(script).toAddress(addressVersion);
}

/**
* Constructs the NEO address from this key pairs public key. The address is constructed ad hoc
* each time this method is called. It uses the default address version {@link
* NeoConstants#DEFAULT_ADDRESS_VERSION}.
*
* @return the NEO address of the public key.
*/
public String getAddress() {
return getAddress(NeoConstants.DEFAULT_ADDRESS_VERSION);
}

/**
Expand Down Expand Up @@ -195,17 +206,6 @@ public byte[] serialize() {
return result;
}

public static ECKeyPair deserialize(byte[] input) {
if (input.length != PRIVATE_KEY_SIZE + PUBLIC_KEY_SIZE) {
throw new RuntimeException("Invalid input key size");
}

BigInteger privateKey = Numeric.toBigInt(input, 0, PRIVATE_KEY_SIZE);
BigInteger publicKey = Numeric.toBigInt(input, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE);

return new ECKeyPair(privateKey, publicKey);
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down Expand Up @@ -260,8 +260,9 @@ public ECPublicKey() {
}

/**
* Creates a new
* @param ecPoint
* Creates a new {@link ECPublicKey} based on a EC point ({@link ECPoint}).
*
* @param ecPoint The EC point (x,y) to construct the public key.
*/
public ECPublicKey(ECPoint ecPoint) {
if (!ecPoint.getCurve().equals(NeoConstants.CURVE_PARAMS.getCurve())) {
Expand Down Expand Up @@ -300,7 +301,8 @@ public ECPublicKey(BigInteger publicKey) {
* Gets this public key's elliptic curve point encoded as defined in section 2.3.3 of
* <a href="http://www.secg.org/sec1-v2.pdf">SEC1</a>.
*
* @param compressed If the EC point should be encoded in compressed or uncompressed format.
* @param compressed If the EC point should be encoded in compressed or uncompressed
* format.
* @return the encoded public key.
*/
public byte[] getEncoded(boolean compressed) {
Expand Down
4 changes: 3 additions & 1 deletion utils/src/main/java/io/neow3j/constants/NeoConstants.java
Expand Up @@ -33,7 +33,9 @@ public class NeoConstants {

//region Accounts, Addresses, Keys

public static final byte ADDRESS_VERSION = 0x17;
public static final byte DEFAULT_ADDRESS_VERSION = 0x17;

public static final byte PRIVATENET_ADDRESS_VERSION = 0x37;

/**
* The maximum number of public keys that can take part in a multi-signature address.
Expand Down
16 changes: 13 additions & 3 deletions utils/src/main/java/io/neow3j/contract/ScriptHash.java
Expand Up @@ -98,12 +98,22 @@ public String toString() {
}

/**
* Derives the address corresponding to this script hash.
* Derives the address corresponding to this script hash, specifying the address version.
*
* @return the address.
*/
public String toAddress(byte addressVersion) {
return AddressUtils.scriptHashToAddress(this.scriptHash, addressVersion);
}

/**
* Derives the address corresponding to this script hash. It uses the default address version
* {@link NeoConstants#DEFAULT_ADDRESS_VERSION}
*
* @return the address.
*/
public String toAddress() {
return AddressUtils.scriptHashToAddress(this.scriptHash);
return toAddress(NeoConstants.DEFAULT_ADDRESS_VERSION);
}

@Override
Expand Down Expand Up @@ -161,7 +171,7 @@ public static ScriptHash fromScript(String script) {
private void checkAndThrowHashLength(byte[] scriptHash) {
if (scriptHash.length != NeoConstants.SCRIPTHASH_LENGHT_BYTES) {
throw new IllegalArgumentException("Script hash must be " +
NeoConstants.SCRIPTHASH_LENGHT_BYTES + " bytes long but was "+ scriptHash.length +
NeoConstants.SCRIPTHASH_LENGHT_BYTES + " bytes long but was " + scriptHash.length +
" bytes.");
}
}
Expand Down
39 changes: 36 additions & 3 deletions utils/src/main/java/io/neow3j/utils/AddressUtils.java
Expand Up @@ -7,7 +7,26 @@

public class AddressUtils {

/**
* Checks whether the give address is valid or not. It uses the default address version {@link
* NeoConstants#DEFAULT_ADDRESS_VERSION}.
*
* @param address The address to be checked.
* @return whether the address is valid or not
*/
public static boolean isValidAddress(String address) {
return isValidAddress(address, NeoConstants.DEFAULT_ADDRESS_VERSION);
}

/**
* Checks whether the give address is valid or not. It uses the default address version {@link
* NeoConstants#DEFAULT_ADDRESS_VERSION}.
*
* @param address The address to be checked.
* @param addressVersion The address version.
* @return whether the address is valid or not
*/
public static boolean isValidAddress(String address, byte addressVersion) {
byte[] data;
try {
data = Base58.decode(address);
Expand All @@ -17,7 +36,7 @@ public static boolean isValidAddress(String address) {
if (data.length != 25) {
return false;
}
if (data[0] != NeoConstants.ADDRESS_VERSION) {
if (data[0] != addressVersion) {
return false;
}
byte[] checksum = Hash.sha256(Hash.sha256(data, 0, 21));
Expand Down Expand Up @@ -46,15 +65,29 @@ public static byte[] addressToScriptHash(String address) {
}

/**
* Derives the Neo address from the given script hash.
* Derives the Neo address from the given script hash. It uses the default address version
* {@link NeoConstants#DEFAULT_ADDRESS_VERSION}.
* <p>
* The script hash needs to be in little-endian order.
*
* @param scriptHash The script hash to get the address for.
* @return the address
*/
public static String scriptHashToAddress(byte[] scriptHash) {
byte[] script = ArrayUtils.concatenate(NeoConstants.ADDRESS_VERSION, scriptHash);
return scriptHashToAddress(scriptHash, NeoConstants.DEFAULT_ADDRESS_VERSION);
}

/**
* Derives the Neo address from the given script hash, also specifying the address version. Use
* {@link #scriptHashToAddress} if the default address version should be used.
* <p>
* The script hash needs to be in little-endian order.
*
* @param scriptHash The script hash to get the address for.
* @return the address
*/
public static String scriptHashToAddress(byte[] scriptHash, byte addressVersion) {
byte[] script = ArrayUtils.concatenate(addressVersion, scriptHash);
byte[] checksum = ArrayUtils.getFirstNBytes(Hash.sha256(Hash.sha256(script)), 4);
return Base58.encode(ArrayUtils.concatenate(script, checksum));
}
Expand Down
32 changes: 28 additions & 4 deletions utils/src/test/java/io/neow3j/utils/AddressUtilsTest.java
Expand Up @@ -7,6 +7,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import io.neow3j.constants.NeoConstants;
import io.neow3j.crypto.Hash;
import org.junit.Test;

Expand All @@ -15,18 +16,30 @@ public class AddressUtilsTest {
@Test
public void scriptHashToAddress() {
String script =
"2102208aea0068c429a03316e37be0e3e8e21e6cda5442df4c5914a19b3a9b6de37568747476aa";
"2102208aea0068c429a03316e37be0e3e8e21e6cda5442df4c5914a19b3a9b6de37568747476aa";
byte[] scriptHash = Hash.sha256AndThenRipemd160(Numeric.hexStringToByteArray(script));
String address = AddressUtils.scriptHashToAddress(scriptHash);
String expectedAddress = "Aa63RMYRWHPRcrZNzUnq5SNrPqoV866Spu";
assertThat(address, is(expectedAddress));
}

@Test
public void scriptHashToAddressWithAddressVersion() {
String script =
"21030529d1296dc2af1f77d8344138a77748599b69599af7ae6be57812a4ec3fa33968747476aa";
byte[] scriptHash = Hash.sha256AndThenRipemd160(Numeric.hexStringToByteArray(script));
System.out.println(Numeric.toHexString(scriptHash));
String address =
AddressUtils.scriptHashToAddress(scriptHash, NeoConstants.PRIVATENET_ADDRESS_VERSION);
String expectedAddress = "PRivaTenetyWuqK7Gj7Vd747d77ssYeDhL";
assertThat(address, is(expectedAddress));
}

@Test
public void addressToScriptHash() {
byte[] scriptHash = AddressUtils.addressToScriptHash("Aa63RMYRWHPRcrZNzUnq5SNrPqoV866Spu");
String script =
"2102208aea0068c429a03316e37be0e3e8e21e6cda5442df4c5914a19b3a9b6de37568747476aa";
"2102208aea0068c429a03316e37be0e3e8e21e6cda5442df4c5914a19b3a9b6de37568747476aa";
byte[] expected = Hash.sha256AndThenRipemd160(Numeric.hexStringToByteArray(script));
assertArrayEquals(scriptHash, expected);
}
Expand All @@ -38,10 +51,16 @@ public void testToScriptHashLargerThan25Chars() {

@Test
public void testScriptHashToAddress() {
byte[] script = Numeric.hexStringToByteArray("d336d7eb9975a29b2404fdb28185e277a4b299bc");
byte[] scriptHash = Numeric.hexStringToByteArray("d336d7eb9975a29b2404fdb28185e277a4b299bc");
String address = "Ab2fvZdmnM4HwDgVbdBrbTLz1wK5TcEyhU";
assertThat(AddressUtils.scriptHashToAddress(scriptHash), is(address));
}

assertThat(AddressUtils.scriptHashToAddress(script), is(address));
@Test
public void testScriptHashToAddressWithVersion() {
byte[] scriptHash = Numeric.hexStringToByteArray("bbf14c0d508108e56402116aede9942a064f7dc6");
String address = "PRivaTenetyWuqK7Gj7Vd747d77ssYeDhL";
assertThat(AddressUtils.scriptHashToAddress(scriptHash, NeoConstants.PRIVATENET_ADDRESS_VERSION), is(address));
}

@Test
Expand All @@ -63,4 +82,9 @@ public void testIsValidAddress() {
}
fail();
}

@Test
public void test() {

}
}

0 comments on commit 06b8b2c

Please sign in to comment.