Permalink
Browse files

Early proof-of-concept experiments with unique Omni ‘o’ and ‘Q’ addre…

…sses
  • Loading branch information...
msgilligan committed Sep 15, 2016
1 parent a542601 commit 6809366926a980c34cbc4a849a79f2203937b66d
@@ -0,0 +1,20 @@
package foundation.omni.address;

import org.bitcoinj.core.Address;
import org.bitcoinj.params.MainNetParams;

/**
* EXPERIMENTAL 2-way Conversion between MAINNET Omni and BTC Addresses
*/
public class OmniAddressConverter {
static final OmniAddressMainNetParams omniParams = OmniAddressMainNetParams.get();
static final MainNetParams btcParams = MainNetParams.get();

static Address btcToOmni(Address btcAddress) {
return new Address(omniParams, btcAddress.getHash160());
}

static Address omniToBTC(Address omniAddress) {
return new Address(btcParams, omniAddress.getHash160());
}
}
@@ -0,0 +1,26 @@
package foundation.omni.address;

import org.bitcoinj.params.MainNetParams;

/**
* EXPERIMENTAL Subclass of MainNetParams for generating Omni Addresses
* This is an experiment for POC Omni-specific addresses
* If we go ahead with this approach we should merge `OmniAddressMainNetParams` with `OmniMainNetParams`
*/
public class OmniAddressMainNetParams extends MainNetParams {
public OmniAddressMainNetParams() {
super();
addressHeader = 115; // 'o'
p2shHeader = 58; // 'Q'
acceptableAddressCodes = new int[] { addressHeader, p2shHeader };
}


private static OmniAddressMainNetParams instance;
public static synchronized OmniAddressMainNetParams get() {
if (instance == null) {
instance = new OmniAddressMainNetParams();
}
return instance;
}
}
@@ -0,0 +1,93 @@
package foundation.omni.address

import org.bitcoinj.core.Address
import org.bitcoinj.core.ECKey
import org.bitcoinj.params.MainNetParams
import spock.lang.Specification
import spock.lang.Unroll

/**
* Proof-of-concept test of conversion between Omni and BTC addresses
*/
class OmniAddressConverterSpec extends Specification {
static final omniParams = OmniAddressMainNetParams.get()
static final btcParams = MainNetParams.get();

def "2 way conversion works for a random address"() {
given: "a random bitcoin address"
def key = new ECKey()
def btcAddress = key.toAddress(btcParams)

when: "we convert to Omni"
def omniAddress = OmniAddressConverter.btcToOmni(btcAddress)

then: "it's a valid Omni address"
omniAddress.parameters == omniParams
!omniAddress.isP2SHAddress()
omniAddress.toString().substring(0,1) == 'o'

when: "we convert back to Bitcoin"
def backAgainBTCAddress = OmniAddressConverter.omniToBTC(omniAddress)

then: "it's the same, valid BTC address"
backAgainBTCAddress == btcAddress
backAgainBTCAddress.parameters == btcParams
!backAgainBTCAddress.isP2SHAddress()
backAgainBTCAddress.toString().substring(0,1) == '1'
}

@Unroll
def "2 way conversion works for Bitcoin address #addressString"(String addressString) {
given: "a bitcoin address"
def btcAddress = new Address(btcParams, addressString)

when: "we convert to Omni"
def omniAddress = OmniAddressConverter.btcToOmni(btcAddress)
println "btc address -> omni address: ${btcAddress} -> ${omniAddress}"

then: "it's a valid Omni address"
omniAddress.parameters == omniParams
!omniAddress.isP2SHAddress()
omniAddress.toString().substring(0,1) == 'o'

when: "we convert back to Bitcoin"
def backAgainBTCAddress = OmniAddressConverter.omniToBTC(omniAddress)

then: "it's the same, valid BTC address"
backAgainBTCAddress == btcAddress
backAgainBTCAddress.parameters == btcParams
!backAgainBTCAddress.isP2SHAddress()
backAgainBTCAddress.toString().substring(0,1) == '1'

where:
addressString << ["1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P", "1Po1oWkD2LmodfkBYiAktwh76vkF93LKnh", "19w61aha78sXnqvVZqRYZPzK5R6WE8rUmT"]
}

@Unroll
def "2 way conversion works for Omni address #addressString"(String addressString) {
given: "an Omni address"
def omniAddress = new Address(omniParams, addressString)

when: "we convert to BTC"
def btcAddress = OmniAddressConverter.omniToBTC(omniAddress)
println "omni address -> btc address: ${btcAddress} -> ${omniAddress}"

then: "it's a valid BTC address"
btcAddress.parameters == btcParams
!btcAddress.isP2SHAddress()
btcAddress.toString().substring(0,1) == '1'

when: "we convert back to Omni"
def backAgainOmniAddress = OmniAddressConverter.btcToOmni(btcAddress)

then: "it's the same, valid Omni address"
backAgainOmniAddress == omniAddress
backAgainOmniAddress.parameters == omniParams
!backAgainOmniAddress.isP2SHAddress()
backAgainOmniAddress.toString().substring(0,1) == 'o'

where:
addressString << ["oWQATQ9rvhDYnQWw91GCptai37kTq2rRQr", "offP312Lg64ZgWn9MxUQfMzaUwNitETkBp", "oRoTF4yhktAHqgxTP5jCKpHnTRiz2134jk"]
}

}
@@ -0,0 +1,38 @@
package foundation.omni.address

import org.bitcoinj.core.Address
import org.bitcoinj.core.ECKey
import org.bitcoinj.core.Utils
import org.bitcoinj.params.MainNetParams
import spock.lang.Specification

/**
* Proof-of-concept test of ability to generate Omni-specific addresses
* via OmniAddressMainNetParams
*/
class OmniAddressMainNetParamsSpec extends Specification {
static final omniParams = OmniAddressMainNetParams.get()
static final btcParams = MainNetParams.get();

def "can create an omni address"() {
given: "A randomly generated ECKey"
def key = new ECKey()

when: "We generate an Omni address from it"
def omniAddress = key.toAddress(omniParams)

then: "It begins with an 'o'"
omniAddress.toString().substring(0,1) == 'o'
}

def "can create an omni P2SH address"() {
given: "An arbitrary hash value"
byte[] hash160 = Utils.sha256hash160([0] as byte[])

when: "We generate an Omni address from it"
def omniAddress = Address.fromP2SHHash(omniParams, hash160)

then: "It begins with an 'Q'"
omniAddress.toString().substring(0,1) == 'Q'
}
}

0 comments on commit 6809366

Please sign in to comment.