static void parseBlock( const Block *block ) { startBlock(block); auto p = block->chunk->getData(); auto header = p; SKIP(uint32_t, version, p); SKIP(uint256_t, prevBlkHash, p); SKIP(uint256_t, blkMerkleRoot, p); SKIP(uint32_t, blkTime, p); SKIP(uint32_t, blkBits, p); SKIP(uint32_t, blkNonce, p); #if defined PROTOSHARES SKIP(uint32_t, nBirthdayA, p); SKIP(uint32_t, nBirthdayB, p); #endif startTXs(p); LOAD_VARINT(nbTX, p); for(uint64_t txIndex=0; likely(txIndex<nbTX); ++txIndex) { parseTX<false>(block, p); } endTXs(p); #if defined(PEERCOIN) || defined(CLAM) || defined(JUMBUCKS) LOAD_VARINT(vchBlockSigSize, p); p += vchBlockSigSize; #endif block->chunk->releaseData(); endBlock(block); }
static void parseOutputs( const uint8_t *&p, const uint8_t *txHash, uint64_t stopAtIndex = -1, const uint8_t *downTXHash = 0, uint64_t downInputIndex = 0, const uint8_t *downInputScript = 0, uint64_t downInputScriptSize = 0 ) { if(!skip && !fullContext) startOutputs(p); LOAD_VARINT(nbOutputs, p); for(uint64_t outputIndex=0; outputIndex<nbOutputs; ++outputIndex) { bool found = fullContext && !skip && (stopAtIndex==outputIndex); parseOutput<skip, fullContext>( p, txHash, outputIndex, downTXHash, downInputIndex, downInputScript, downInputScriptSize, found ); if(found) break; } if(!skip && !fullContext) endOutputs(p); }
virtual void startInput( const uint8_t *p ) { if(dump) { printf( " input[%" PRIu64 "] = {\n\n", nbInputs++ ); static uint256_t gNullHash; LOAD(uint256_t, upTXHash, p); LOAD(uint32_t, upOutputIndex, p); LOAD_VARINT(inputScriptSize, p); isGenTX = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash))); if(isGenTX) { //uint64_t reward = getBaseReward(currBlock); printf(" generation transaction\n"); //printf(" proof of work block reward:, reward = %.8f\n", 1e-6*reward); printf(" hex dump of coinbase follows:\n\n"); canonicalHexDump(p, inputScriptSize, " "); //valueIn += reward; } } }
virtual void startInput( const uint8_t *p ) { if(dump) { printf( " input[%" PRIu64 "] = {\n\n", nbInputs++ ); static uint256_t gNullHash; LOAD(uint256_t, upTXHash, p); LOAD(uint32_t, upOutputIndex, p); LOAD_VARINT(inputScriptSize, p); showScript(p, inputScriptSize, 0, " "); isGenTX = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash))); if(isGenTX) { uint64_t reward = getBaseReward(currBlock); printf(" generation transaction\n"); printf(" based on block height, reward = %.8f\n", satoshisToNormaForm(reward)); printf(" hex dump of coinbase follows:\n\n"); canonicalHexDump(p, inputScriptSize, " "); valueIn += reward; } } }
static void parseInputs( const uint8_t *&p, const uint8_t *txHash ) { if(!skip) startInputs(p); LOAD_VARINT(nbInputs, p); for(uint64_t inputIndex=0; inputIndex<nbInputs; ++inputIndex) parseInput<skip>(p, txHash, inputIndex); if(!skip) endInputs(p); }
static void parseInput( const Block *block, const uint8_t *&p, const uint8_t *txHash, uint64_t inputIndex ) { if(!skip) { startInput(p); } auto upTXHash = p; const Chunk *upTX = 0; if(gNeedTXHash && !skip) { auto isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash))); if(likely(false==isGenTX)) { auto i = gTXOMap.find(upTXHash); if(unlikely(gTXOMap.end()==i)) { errFatal("failed to locate upstream transaction"); } upTX = i->second; } } SKIP(uint256_t, dummyUpTXhash, p); LOAD(uint32_t, upOutputIndex, p); LOAD_VARINT(inputScriptSize, p); if(!skip && 0!=upTX) { auto inputScript = p; auto upTXOutputs = upTX->getData(); parseOutputs<false, true>( upTXOutputs, upTXHash, upOutputIndex, txHash, inputIndex, inputScript, inputScriptSize ); upTX->releaseData(); } p += inputScriptSize; SKIP(uint32_t, sequence, p); if(!skip) { endInput(p); } }
virtual void endOutputs( const uint8_t *p ) { #if defined(CLAM) if(1<txVersion) { LOAD_VARINT(strCLAMSpeechLen, p); printf(" comment = '\n"); canonicalHexDump( p, strCLAMSpeechLen, " " ); printf("'\n"); } #endif }
// Called when a TX input is encountered virtual void startInput( const uint8_t *p ) { printf( "%sinput%d = {\n", spaces, (int)inputId ); push(); static uint256_t gNullHash; LOAD(uint256_t, upTXHash, p); LOAD(uint32_t, upOutputIndex, p); LOAD_VARINT(inputScriptSize, p); printf("%sscript = '\n", spaces); pop(); showScript(p, inputScriptSize, 0, (const char *)spaces); push(); printf("%s'\n", spaces); p += inputScriptSize; LOAD(uint32_t, sequence, p); printf("%snsequence = %" PRIu32 "\n",spaces, sequence); isCoinBase = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash))); if(isCoinBase) { uint64_t value = getBaseReward(currBlock); printf("%sisCoinBase = true\n", spaces); printf( "%svalue = %" PRIu64 " # %.08f\n", spaces, value, satoshisToNormaForm(value) ); printf("%scoinBase = '\n", spaces); push(); canonicalHexDump( p, inputScriptSize, (const char *)spaces ); pop(); printf("%s'\n", spaces); } }
static void parseOutput( const uint8_t *&p, const uint8_t *txHash, uint64_t outputIndex, const uint8_t *downTXHash, uint64_t downInputIndex, const uint8_t *downInputScript, uint64_t downInputScriptSize, bool found = false ) { if(!skip && !fullContext) { startOutput(p); } LOAD(uint64_t, value, p); LOAD_VARINT(outputScriptSize, p); auto outputScript = p; p += outputScriptSize; if(!skip && fullContext && found) { edge( value, txHash, outputIndex, outputScript, outputScriptSize, downTXHash, downInputIndex, downInputScript, downInputScriptSize ); } if(!skip && !fullContext) { endOutput( p, value, txHash, outputIndex, outputScript, outputScriptSize ); } }
static void parseInputs( const Block *block, const uint8_t *&p, const uint8_t *txHash ) { if(!skip) { startInputs(p); } LOAD_VARINT(nbInputs, p); for(uint64_t inputIndex=0; inputIndex<nbInputs; ++inputIndex) { parseInput<skip>(block, p, txHash, inputIndex); } if(!skip) { endInputs(p); } }
static void parseInput( const uint8_t *&p, const uint8_t *txHash, uint64_t inputIndex ) { if(!skip) startInput(p); const uint8_t *upTXHash = p; const uint8_t *upTXOutputs = 0; if(gNeedTXHash && !skip) { bool isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash))); if(likely(false==isGenTX)) { auto i = gTXMap.find(upTXHash); if(unlikely(gTXMap.end()==i)) errFatal("failed to locate upstream TX"); upTXOutputs = i->second; } } SKIP(uint256_t, dummyUpTXhash, p); LOAD(uint32_t, upOutputIndex, p); LOAD_VARINT(inputScriptSize, p); if(!skip && 0!=upTXOutputs) { const uint8_t *inputScript = p; parseOutputs<false, true>( upTXOutputs, upTXHash, upOutputIndex, txHash, inputIndex, inputScript, inputScriptSize ); } p += inputScriptSize; SKIP(uint32_t, sequence, p); if(!skip) endInput(p); }
static void parseBlock( const Block *block ) { startBlock(block); const uint8_t *p = block->data; const uint8_t *header = p; SKIP(uint32_t, version, p); SKIP(uint256_t, prevBlkHash, p); SKIP(uint256_t, blkMerkleRoot, p); SKIP(uint32_t, blkTime, p); SKIP(uint32_t, blkBits, p); SKIP(uint32_t, blkNonce, p); LOAD_VARINT(nbTX, p); for(uint64_t txIndex=0; likely(txIndex<nbTX); ++txIndex) parseTX<false>(p); endBlock(block); }
// Called when the end of a TX's output array is encountered virtual void endOutputs( const uint8_t *p ) { #if defined(CLAM) if(1<txVersion) { LOAD_VARINT(strCLAMSpeechLen, p); printf("%stxComment = '\n", spaces); push(); canonicalHexDump( p, strCLAMSpeechLen, (const char *)spaces ); pop(); printf("%s'\n", spaces); } #endif pop(); printf("%s}\n", spaces); }
static void parseTX( const Block *block, const uint8_t *&p ) { auto txStart = p; uint8_t *txHash = 0; if(gNeedTXHash && !skip) { auto txEnd = p; txHash = allocHash256(); parseTX<true>(block, txEnd); sha256Twice(txHash, txStart, txEnd - txStart); } if(!skip) { startTX(p, txHash); } #if defined(CLAM) LOAD(uint32_t, nVersion, p); #else SKIP(uint32_t, nVersion, p); #endif #if defined(PEERCOIN) || defined(CLAM) || defined(JUMBUCKS) SKIP(uint32_t, nTime, p); #endif parseInputs<skip>(block, p, txHash); Chunk *txo = 0; size_t txoOffset = -1; const uint8_t *outputsStart = p; if(gNeedTXHash && !skip) { txo = Chunk::alloc(); txoOffset = block->chunk->getOffset() + (p - block->chunk->getData()); gTXOMap[txHash] = txo; } parseOutputs<skip, false>(p, txHash); if(txo) { size_t txoSize = p - outputsStart; txo->init( block->chunk->getMap(), txoSize, txoOffset ); } SKIP(uint32_t, lockTime, p); #if defined(CLAM) if(1<nVersion) { LOAD_VARINT(strCLAMSpeechLen, p); p += strCLAMSpeechLen; } #endif if(!skip) { endTX(p); } }