package com.yoghurt.crypto.transactions.client.util.address; import java.util.ArrayList; import com.yoghurt.crypto.transactions.shared.domain.Address; import com.yoghurt.crypto.transactions.shared.domain.Address.TYPE; import com.yoghurt.crypto.transactions.shared.domain.Base58CheckContents; import com.yoghurt.crypto.transactions.shared.domain.Operation; import com.yoghurt.crypto.transactions.shared.domain.ScriptPart; import com.yoghurt.crypto.transactions.shared.domain.TransactionOutput; public class AddressParseUtil { private static final Operation[] P2PKH_TEMPLATE = new Operation[] { Operation.OP_DUP, Operation.OP_HASH160, Operation.OP_PUSHDATA, Operation.OP_EQUALVERIFY, Operation.OP_CHECKSIG }; private static final Operation[] P2SH_TEMPLATE = new Operation[] { Operation.OP_HASH160, Operation.OP_PUSHDATA, Operation.OP_EQUAL }; public static Base58CheckContents parseAddress(final String addressText) { return Base58CheckUtil.parseBase58Check(addressText); } public static byte[] getChecksum(final Address address) { return Base58CheckUtil.computeChecksum(address.getVersion(), address.getHash160()); } public static Address parseAddress(final Base58CheckContents contents) { final Address address = new Address(); switch(contents.getVersion() & 0xFF) { case 0x01: address.setType(TYPE.P2PKH); break; case 0x03: address.setType(TYPE.P2SH); break; } address.setVersion(contents.getVersion()); address.setHash160(contents.getPayload()); return address; } public static boolean isValid(final Base58CheckContents contents) { return Base58CheckUtil.isValid(contents); } public static Address tryParseAddress(final TransactionOutput output) { if(matchesTemplate(output.getInstructions(), P2PKH_TEMPLATE)) { final Address p2pkh = new Address(); p2pkh.setType(TYPE.P2PKH); p2pkh.setVersion((byte) 0); p2pkh.setHash160(output.getInstructions().get(2).getBytes()); return p2pkh; } else if (matchesTemplate(output.getInstructions(), P2SH_TEMPLATE)) { final Address p2sh = new Address(); p2sh.setType(TYPE.P2SH); p2sh.setVersion((byte) 5); p2sh.setHash160(output.getInstructions().get(1).getBytes()); return p2sh; } return null; } private static boolean matchesTemplate(final ArrayList<ScriptPart> instructions, final Operation[] template) { if(instructions.size() != template.length) { return false; } int counter = 0; for(final ScriptPart part : instructions) { if(part.getOperation() != template[counter]) { return false; } counter++; } return true; } }