}
long sumInput = 0;
for ( TransactionOutput o : sources )
{
TransactionInput i = new TransactionInput ();
i.setSourceHash (o.getTxHash ());
i.setIx (o.getIx ());
sumInput += o.getValue ();
transaction.getInputs ().add (i);
}
if ( sumInput != (sumOut + fee) )
{
throw new ValidationException ("Sum of sinks (+fee) does not match sum of sources");
}
int j = 0;
for ( TransactionOutput s : sources )
{
TransactionInput i = transaction.getInputs ().get (j);
ScriptFormat.Writer sw = new ScriptFormat.Writer ();
if ( ScriptFormat.isPayToAddress (s.getScript ()) )
{
Address address = s.getOutputAddress ();
Key key = getKeyForAddress (address);
if ( key == null )
{
throw new ValidationException ("Have no key to spend this output");
}
byte[] sig = key.sign (hashTransaction (transaction, j, ScriptFormat.SIGHASH_ALL, s.getScript ()));
byte[] sigPlusType = new byte[sig.length + 1];
System.arraycopy (sig, 0, sigPlusType, 0, sig.length);
sigPlusType[sigPlusType.length - 1] = (byte) (ScriptFormat.SIGHASH_ALL & 0xff);
sw.writeData (sigPlusType);
sw.writeData (key.getPublic ());
}
else
{
spendNonAddressOutput (j, s, sw, transaction);
}
i.setScript (sw.toByteArray ());
++j;
}
transaction.computeHash ();
return transaction;