I did decompile and analyze Qora already some weeks ago.
I think "qora\c\a.class" is the block Class which is very important for the understanding of the forging algo.
Here are three methods of that decompiled class:
public final JSONObject bO()
{
JSONObject jsonobject;
(jsonobject = new JSONObject()).put("version", Integer.valueOf(version));
jsonobject.put("reference", qora.crypto.a.encode(ef));
jsonobject.put("timestamp", Long.valueOf(timestamp));
jsonobject.put("generatingBalance", Long.valueOf(ep));
jsonobject.put("generator", eq.getAddress());
jsonobject.put("fee", bJ().toPlainString());
jsonobject.put("transactionsSignature", qora.crypto.a.encode(ev));
jsonobject.put("generatorSignature", qora.crypto.a.encode(er));
jsonobject.put("signature", qora.crypto.a.encode(getSignature()));
JSONArray jsonarray = new JSONArray();
m m1;
for(Iterator iterator = bL().iterator(); iterator.hasNext(); jsonarray.add(m1.bO()))
m1 = (m)iterator.next();
jsonobject.put("transactions", jsonarray);
return jsonobject;
}
public boolean bP()
{
byte abyte0[] = new byte[0];
byte abyte1[] = Arrays.copyOfRange(ef, 0, 64); // ef = reference (?Hash of last block i think)
abyte0 = Bytes.concat(new byte[][] {
abyte0, abyte1
});
abyte1 = Longs.toByteArray(ep); // generatingBalance
abyte0 = Bytes.concat(new byte[][] {
abyte0, abyte1
});
abyte1 = Bytes.ensureCapacity(eq.bp(), 32, 0); // eq.bp = public key of block creator
abyte0 = Bytes.concat(new byte[][] {
abyte0, abyte1
});
b.bS();
if(!b.a(eq.bp(), er, abyte0))
return false;
abyte0 = er;
for(Iterator iterator = bL().iterator(); iterator.hasNext();)
{
m m1;
if(!(m1 = (m)iterator.next()).bP())
return false;
abyte0 = Bytes.concat(new byte[][] {
abyte0, m1.getSignature()
});
}
b.bS();
return b.a(eq.bp(), ev, abyte0);
}
public boolean n(j j1)
{
if(ef == null || l(j1) == null)
return false;
if(timestamp - 500L > c.a.getTime() || timestamp < l(j1).timestamp)
return false;
if(timestamp % 1000L != l(j1).timestamp % 1000L)
return false;
if(ep != qora.d.b(j1, l(j1)))
return false;
byte abyte0[];
Arrays.fill(abyte0 = new byte[32], (byte)127);
BigInteger biginteger = new BigInteger(1, abyte0);
Object obj = BigInteger.valueOf(qora.d.e(ep));
biginteger = (biginteger = biginteger.divide(((BigInteger) (obj)))).multiply(eq.c(j1).toBigInteger());
long l1 = (timestamp - ((a) (obj = l(j1))).timestamp) / 1000L;
obj = biginteger.multiply(BigInteger.valueOf(l1 - 1L));
biginteger = biginteger.multiply(BigInteger.valueOf(l1));
b.bS();
byte abyte1[] = b.digest(er);
BigInteger biginteger1;
if((biginteger1 = new BigInteger(1, abyte1)).compareTo(biginteger) >= 0)
return false;
if(biginteger1.compareTo(((BigInteger) (obj))) < 0)
return false;
j1 = j1.X();
m m1;
for(Iterator iterator = bL().iterator(); iterator.hasNext(); m1.k(j1))
{
if((m1 = (m)iterator.next()) instanceof qora.f.g)
return false;
if(m1.p(j1) != 1)
return false;
if(m1.getTimestamp() > timestamp || m1.getDeadline() <= timestamp)
return false;
}
return true;
}
I have added the bO() method which creates an JSON Object from that Object because it helps to understand what which variable is.
b.a (Not shown here) is the Crypto-verify method.
"bP()" obviously checks if the transactionsSignature (ev) and the generatorSignature (er) are valid Crypto signatures.
generatorSignature = signature of (ef + ep + eq.bp())
Where
ef = reference (?Hash of last block i think)
ep=generatingBalance
eq.bp = public key of block creator
transactionsSignature = signature of ( generatorSignature + all transactions) in that block
"n(j j1)" Checks if the Block is valid in terms of whether the creator was allowed to build on top of the last block at that given time.
Therefore the generatorSignature is beeing hashed and the result is somehow beeing compared to the time since the last block multiplied with the generatingBalance.