|
|
@ -51,6 +51,32 @@ double GetDifficulty(const CBlockIndex* blockindex) |
|
|
|
return dDiff; |
|
|
|
return dDiff; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UniValue blockheaderToJSON(const CBlockIndex* blockindex) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|
|
|
|
|
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); |
|
|
|
|
|
|
|
int confirmations = -1; |
|
|
|
|
|
|
|
// Only report confirmations if the block is on the main chain
|
|
|
|
|
|
|
|
if (chainActive.Contains(blockindex)) |
|
|
|
|
|
|
|
confirmations = chainActive.Height() - blockindex->nHeight + 1; |
|
|
|
|
|
|
|
result.push_back(Pair("confirmations", confirmations)); |
|
|
|
|
|
|
|
result.push_back(Pair("height", blockindex->nHeight)); |
|
|
|
|
|
|
|
result.push_back(Pair("version", blockindex->nVersion)); |
|
|
|
|
|
|
|
result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); |
|
|
|
|
|
|
|
result.push_back(Pair("time", (int64_t)blockindex->nTime)); |
|
|
|
|
|
|
|
result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); |
|
|
|
|
|
|
|
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); |
|
|
|
|
|
|
|
result.push_back(Pair("difficulty", GetDifficulty(blockindex))); |
|
|
|
|
|
|
|
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (blockindex->pprev) |
|
|
|
|
|
|
|
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); |
|
|
|
|
|
|
|
CBlockIndex *pnext = chainActive.Next(blockindex); |
|
|
|
|
|
|
|
if (pnext) |
|
|
|
|
|
|
|
result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); |
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) |
|
|
|
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -255,6 +281,62 @@ UniValue getblockhash(const UniValue& params, bool fHelp) |
|
|
|
return pblockindex->GetBlockHash().GetHex(); |
|
|
|
return pblockindex->GetBlockHash().GetHex(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UniValue getblockheader(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (fHelp || params.size() < 1 || params.size() > 2) |
|
|
|
|
|
|
|
throw runtime_error( |
|
|
|
|
|
|
|
"getblockheader \"hash\" ( verbose )\n" |
|
|
|
|
|
|
|
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" |
|
|
|
|
|
|
|
"If verbose is true, returns an Object with information about blockheader <hash>.\n" |
|
|
|
|
|
|
|
"\nArguments:\n" |
|
|
|
|
|
|
|
"1. \"hash\" (string, required) The block hash\n" |
|
|
|
|
|
|
|
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" |
|
|
|
|
|
|
|
"\nResult (for verbose = true):\n" |
|
|
|
|
|
|
|
"{\n" |
|
|
|
|
|
|
|
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n" |
|
|
|
|
|
|
|
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" |
|
|
|
|
|
|
|
" \"height\" : n, (numeric) The block height or index\n" |
|
|
|
|
|
|
|
" \"version\" : n, (numeric) The block version\n" |
|
|
|
|
|
|
|
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n" |
|
|
|
|
|
|
|
" \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" |
|
|
|
|
|
|
|
" \"nonce\" : n, (numeric) The nonce\n" |
|
|
|
|
|
|
|
" \"bits\" : \"1d00ffff\", (string) The bits\n" |
|
|
|
|
|
|
|
" \"difficulty\" : x.xxx, (numeric) The difficulty\n" |
|
|
|
|
|
|
|
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" |
|
|
|
|
|
|
|
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" |
|
|
|
|
|
|
|
"}\n" |
|
|
|
|
|
|
|
"\nResult (for verbose=false):\n" |
|
|
|
|
|
|
|
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" |
|
|
|
|
|
|
|
"\nExamples:\n" |
|
|
|
|
|
|
|
+ HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") |
|
|
|
|
|
|
|
+ HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string strHash = params[0].get_str(); |
|
|
|
|
|
|
|
uint256 hash(uint256S(strHash)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool fVerbose = true; |
|
|
|
|
|
|
|
if (params.size() > 1) |
|
|
|
|
|
|
|
fVerbose = params[1].get_bool(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mapBlockIndex.count(hash) == 0) |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBlockIndex* pblockindex = mapBlockIndex[hash]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!fVerbose) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); |
|
|
|
|
|
|
|
ssBlock << pblockindex->GetBlockHeader(); |
|
|
|
|
|
|
|
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); |
|
|
|
|
|
|
|
return strHex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return blockheaderToJSON(pblockindex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
UniValue getblock(const UniValue& params, bool fHelp) |
|
|
|
UniValue getblock(const UniValue& params, bool fHelp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (fHelp || params.size() < 1 || params.size() > 2) |
|
|
|
if (fHelp || params.size() < 1 || params.size() > 2) |
|
|
|