Nevertheless try for flaw:
In verify() of Transaction we just set public key of account to public key that was contained in transaction. But we do not check if signature belongs to the public key. (This is done only at the end of the method, after we already set accounts public key).
If someone creates (invalid) transactions with public key of accounts that never made a transaction before, this accounts will never be able to make valid transactions.
Sounds to easy for the flaw, but I think this should get fixed by first checking the signature and then set the accounts public key.
Code:
boolean verify() throws Exception {
Account account = accounts.get(Account.getId(senderPublicKey));
if (account == null) {
return false;
} else if (account.publicKey == null) {
account.publicKey = senderPublicKey;
} else if (!Arrays.equals(senderPublicKey, account.publicKey)) {
return false;
}
byte[] data = getBytes();
for (int i = 64; i < 128; i++) {
data[i] = 0;
}
return Crypto.verify(signature, data, senderPublicKey);
}