PassportTransactionFormatter { public byte[] signRawTransaction(PublicKey pubkey, byte[][] parts, PassportConnection pcon) throws Exception { byte[] rawTransaction = Bytes.concat(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8], parts[9], parts[10], parts[11], parts[12]); byte[] step14 = Sha256Hash.hash(Sha256Hash.hash(rawTransaction)); byte[] multiSignature = new byte[320]; byte[] hashPart; for (int i = 0; i < 4; i++) { hashPart = Arrays.copyOfRange(step14, i * 8, i * 8 + 8); System.arraycopy(pcon.signData(hashPart), 0, multiSignature, i * 80, 80); } byte[] signatureLength = Util.hexStringToByteArray("fd97014d4101"); byte[] hashCodeType = Util.hexStringToByteArray("01"); byte[] publicKeyASN = pubkey.getEncoded(); byte[] publicKey = new byte[81]; System.arraycopy(publicKeyASN, publicKeyASN.length-81, publicKey, 0, 81); byte[] publickeyLength = Util.hexStringToByteArray("4c51"); byte[] step16 = Bytes.concat(signatureLength, multiSignature, hashCodeType, publickeyLength, publicKey); byte[] step19 = Bytes.concat(parts[0], parts[1], parts[2], parts[3], step16, parts[6], parts[7], parts[8], parts[9], parts[10], parts[11], parts[12]); return step19; } PassportTransactionFormatter(TransactionOutput utxo, Address destination); void setDestinationAddress(Address destination); void setUTXO(TransactionOutput utxo); byte[] buildAndSign(PublicKey pubKey, PassportConnection pcon); byte[][] buildRawTransaction(); byte[] signRawTransaction(PublicKey pubkey, byte[][] parts, PassportConnection pcon);  }
@Test public void testSignRawTransaction() { try { when(pCon.signData((byte[])notNull())).thenReturn( Util.hexStringToByteArray("0A5FADA8967CF77C8F00FAF3A8CF73D4615BC970E9BAA76883A2C4E8B9DA56C4ECC9F72E66F045D70A22918431F6263BDB6737A89393D2F5C3931007DF2532C86FDF9390A7163C98F72DE1590D21D34A"), Util.hexStringToByteArray("76732217AC784D75B1A89BAD2348271F5092B6D303F72E26D7374B8ED47F5D3A3324A41BBEE6781967DAF8706A83D6BE5D8990F1CA17FABF07E2FB003C21177EF9C270F64E22828A09E65FE4ECE14039"), Util.hexStringToByteArray("9585FCCCF6A430ECA5E3F9E2C52CDF7627F1E62D04042A69CB0478BFBA60AA2708F55E92FA6518578F9498B7B0A6CCBA14676D921BFB74081970E5E5B944C11BD46F123764F97988A6479D8358FFA6F3"), Util.hexStringToByteArray("606D9D27341FB36052F1F04914E34F3B5C25A6073A6A0565B7BABC2A45C4B964B5B41311FE539A06AB2640B3C68ABFF1A3C78FA946C2BDF01896442956B0A675531374B3E3AE02661D59F91BA0E34557")); when(pubKey.getEncoded()).thenReturn(Util.hexStringToByteArray("04b41f0dda6797b6afd9dcfab9b9cc99744644705e67b5872540860cc015044b86de5cc13da2b3f23564f4c4da996c9321d3c8ea25642bd8176761eecc8fbc3fcdbf846b5c927bd488f42afa9f193517e6")); byte[][] rawTransaction = ptf.buildRawTransaction(); byte[] transaction = ptf.signRawTransaction(pubKey, rawTransaction, pCon); byte[] correctTransaction = Util.hexStringToByteArray("01000000" + "01" + "ECCF7E3034189B851985D871F91384B8EE357CD47C3024736E5676EB2DEBB3F2" + "01000000" + "FD97014D4101" + "0A5FADA8967CF77C8F00FAF3A8CF73D4615BC970E9BAA76883A2C4E8B9DA56C4ECC9F72E66F045D70A22918431F6263BDB6737A89393D2F5C3931007DF2532C86FDF9390A7163C98F72DE1590D21D34A" + "76732217AC784D75B1A89BAD2348271F5092B6D303F72E26D7374B8ED47F5D3A3324A41BBEE6781967DAF8706A83D6BE5D8990F1CA17FABF07E2FB003C21177EF9C270F64E22828A09E65FE4ECE14039" + "9585FCCCF6A430ECA5E3F9E2C52CDF7627F1E62D04042A69CB0478BFBA60AA2708F55E92FA6518578F9498B7B0A6CCBA14676D921BFB74081970E5E5B944C11BD46F123764F97988A6479D8358FFA6F3" + "606D9D27341FB36052F1F04914E34F3B5C25A6073A6A0565B7BABC2A45C4B964B5B41311FE539A06AB2640B3C68ABFF1A3C78FA946C2BDF01896442956B0A675531374B3E3AE02661D59F91BA0E34557" + "014C" + "51" + "04B41F0DDA6797B6AFD9DCFAB9B9CC99744644705E67B5872540860CC015044B86DE5CC13DA2B3F23564F4C4DA996C9321D3C8EA25642BD8176761EECC8FBC3FCDBF846B5C927BD488F42AFA9F193517E6" + "FFFFFFFF" + "010000000" + "000000000" + "19" + "76A91476A914010966776006953D5567439E5E39F86A0D88AC" + "00000000" + "01000000"); assertEquals(correctTransaction.length, transaction.length); for(int i=0; i< correctTransaction.length; i++) { assertEquals("Error at byte " + i, correctTransaction[i], transaction[i]); } } catch(Exception e) { e.printStackTrace(); assertTrue(false); } }