// ppcoin: coinstake must meet hash target according to the protocol:
// at least one input must meet the formula
-// hash(nBits + txPrev.block.nTime + txPrev.nTime + nTime) < bnTarget * nCoinDay
+// hash(nBits + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDay
// this ensures that the chance of getting a coinstake is proportional to the
// amount of coin age one owns.
// The reason this hash is chosen is the following:
-// nBits: encodes all past block timestamps, prevents computing hash in advance
-// txPrev.block.nTime: prevent nodes from guessing a good timestamp to generate
-// transaction for future advantage
-// txPrev.nTime: prevent nodes from meeting target simultaneously
-// block/tx hash should not be used here as they can be generated in vast quatities
-// so as to generate blocks faster, degrading the system back into a proof-of-work
-// situation.
+// nBits: encodes all past block timestamps, making computing hash in advance
+// more difficult
+// txPrev.block.nTime: prevent nodes from guessing a good timestamp to
+// generate transaction for future advantage
+// txPrev.offset: offset of txPrev inside block, to reduce the chance of
+// nodes generating coinstake at the same time
+// txPrev.nTime: reduce the chance of nodes generating coinstake at the same
+// time
+// txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
+// generating coinstake at the same time
+// block/tx hash should not be used here as they can be generated in vast
+// quantities so as to generate blocks faster, degrading the system back into
+// a proof-of-work situation.
//
bool CTransaction::CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const
{
CBigNum bnCoinDay = CBigNum(nValueIn) * (nTime-txPrev.nTime) / COIN / (24 * 60 * 60);
// Calculate hash
CDataStream ss(SER_GETHASH, VERSION);
- ss << nBits << block.nTime << txPrev.nTime << nTime;
+ ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << txPrev.nTime << txin.prevout.n << nTime;
if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
return true;
}
CBigNum bnCoinDay = CBigNum(nValueIn) * (txNew.nTime-pcoin.first->nTime) / COIN / (24 * 60 * 60);
// Calculate hash
CDataStream ss(SER_GETHASH, VERSION);
- ss << nBits << block.nTime << pcoin.first->nTime << txNew.nTime;
+ ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << pcoin.first->nTime << pcoin.second << txNew.nTime;
if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
{
txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));