@ -44,6 +44,8 @@ static CCriticalSection cs_nWalletUnlockTime;
extern Value dumpprivkey ( const Array & params , bool fHelp ) ;
extern Value importprivkey ( const Array & params , bool fHelp ) ;
const Object emptyobj ;
Object JSONRPCError ( int code , const string & message )
{
Object error ;
@ -111,6 +113,33 @@ HexBits(unsigned int nBits)
return HexStr ( BEGIN ( uBits . cBits ) , END ( uBits . cBits ) ) ;
}
enum DecomposeMode {
DM_NONE = 0 ,
DM_HASH ,
DM_HEX ,
DM_ASM ,
DM_OBJ ,
} ;
enum DecomposeMode
FindDecompose ( const Object & decompositions , const char * pcType , const char * pcDefault )
{
Value val = find_value ( decompositions , pcType ) ;
std : : string strDecompose = ( val . type ( ) = = null_type ) ? pcDefault : val . get_str ( ) ;
if ( strDecompose = = " no " )
return DM_NONE ;
if ( strDecompose = = " hash " )
return DM_HASH ;
if ( strDecompose = = " hex " )
return DM_HEX ;
if ( strDecompose = = " asm " )
return DM_ASM ;
if ( strDecompose = = " obj " )
return DM_OBJ ;
throw JSONRPCError ( - 18 , " Invalid decomposition " ) ;
}
void WalletTxToJSON ( const CWalletTx & wtx , Object & entry )
{
int confirms = wtx . GetDepthInMainChain ( ) ;
@ -126,11 +155,14 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
entry . push_back ( Pair ( item . first , item . second ) ) ;
}
void TxToJSON ( const CTransaction & tx , Object & entry )
void TxToJSON ( const CTransaction & tx , Object & entry , const Object & decompositions )
{
entry . push_back ( Pair ( " version " , tx . nVersion ) ) ;
entry . push_back ( Pair ( " locktime " , ( boost : : int64_t ) tx . nLockTime ) ) ;
entry . push_back ( Pair ( " size " , ( boost : : int64_t ) : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ) ) ;
enum DecomposeMode decomposeScript = FindDecompose ( decompositions , " script " , " asm " ) ;
Array vin ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
@ -143,7 +175,18 @@ void TxToJSON(const CTransaction &tx, Object& entry)
prevout . push_back ( Pair ( " hash " , txin . prevout . hash . GetHex ( ) ) ) ;
prevout . push_back ( Pair ( " n " , ( boost : : int64_t ) txin . prevout . n ) ) ;
in . push_back ( Pair ( " prevout " , prevout ) ) ;
in . push_back ( Pair ( " scriptSig " , txin . scriptSig . ToString ( ) ) ) ;
switch ( decomposeScript ) {
case DM_NONE :
break ;
case DM_HEX :
in . push_back ( Pair ( " scriptSig " , HexStr ( txin . scriptSig . begin ( ) , txin . scriptSig . end ( ) ) ) ) ;
break ;
case DM_ASM :
in . push_back ( Pair ( " scriptSig " , txin . scriptSig . ToString ( ) ) ) ;
break ;
default :
throw JSONRPCError ( - 18 , " Invalid script decomposition " ) ;
}
}
in . push_back ( Pair ( " sequence " , ( boost : : int64_t ) txin . nSequence ) ) ;
vin . push_back ( in ) ;
@ -154,12 +197,25 @@ void TxToJSON(const CTransaction &tx, Object& entry)
{
Object out ;
out . push_back ( Pair ( " value " , ValueFromAmount ( txout . nValue ) ) ) ;
out . push_back ( Pair ( " scriptPubKey " , txout . scriptPubKey . ToString ( ) ) ) ;
switch ( decomposeScript ) {
case DM_NONE :
break ;
case DM_HEX :
out . push_back ( Pair ( " scriptPubKey " , HexStr ( txout . scriptPubKey . begin ( ) , txout . scriptPubKey . end ( ) ) ) ) ;
break ;
case DM_ASM :
out . push_back ( Pair ( " scriptPubKey " , txout . scriptPubKey . ToString ( ) ) ) ;
break ;
default :
throw JSONRPCError ( - 18 , " Invalid script decomposition " ) ;
}
vout . push_back ( out ) ;
}
entry . push_back ( Pair ( " vout " , vout ) ) ;
}
void AnyTxToJSON ( const uint256 hash , const CTransaction * ptx , Object & entry , const Object & decompositions ) ;
string AccountFromValue ( const Value & value )
{
string strAccount = value . get_str ( ) ;
@ -168,7 +224,7 @@ string AccountFromValue(const Value& value)
return strAccount ;
}
Object blockToJSON ( const CBlock & block , const CBlockIndex * blockindex )
Object blockToJSON ( const CBlock & block , const CBlockIndex * blockindex , const Object & decompositions )
{
Object result ;
result . push_back ( Pair ( " hash " , block . GetHash ( ) . GetHex ( ) ) ) ;
@ -183,10 +239,38 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
result . push_back ( Pair ( " nonce " , ( boost : : uint64_t ) block . nNonce ) ) ;
result . push_back ( Pair ( " bits " , HexBits ( block . nBits ) ) ) ;
result . push_back ( Pair ( " difficulty " , GetDifficulty ( blockindex ) ) ) ;
Array txhashes ;
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
txhashes . push_back ( tx . GetHash ( ) . GetHex ( ) ) ;
result . push_back ( Pair ( " tx " , txhashes ) ) ;
enum DecomposeMode decomposeTxn = FindDecompose ( decompositions , " tx " , " hash " ) ;
if ( decomposeTxn )
{
Array txs ;
switch ( decomposeTxn ) {
case DM_OBJ :
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
{
Object entry ;
AnyTxToJSON ( tx . GetHash ( ) , & tx , entry , decompositions ) ;
txs . push_back ( entry ) ;
}
break ;
case DM_HEX :
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
{
CDataStream ssTx ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssTx < < tx ;
txs . push_back ( HexStr ( ssTx . begin ( ) , ssTx . end ( ) ) ) ;
}
break ;
case DM_HASH :
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
txs . push_back ( tx . GetHash ( ) . GetHex ( ) ) ;
break ;
default :
throw JSONRPCError ( - 18 , " Invalid transaction decomposition " ) ;
}
result . push_back ( Pair ( " tx " , txs ) ) ;
}
if ( blockindex - > pprev )
result . push_back ( Pair ( " previousblockhash " , blockindex - > pprev - > GetBlockHash ( ) . GetHex ( ) ) ) ;
@ -197,6 +281,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
///
/// Note: This interface may still be subject to change.
///
@ -1501,23 +1586,14 @@ Value listsinceblock(const Array& params, bool fHelp)
return ret ;
}
Value gettransaction ( const Array & params , bool fHelp )
void
AnyTxToJSON ( const uint256 hash , const CTransaction * ptx , Object & entry , const Object & decompositions )
{
if ( fHelp | | params . size ( ) ! = 1 )
throw runtime_error (
" gettransaction <txid> \n "
" Get detailed information about <txid> " ) ;
uint256 hash ;
hash . SetHex ( params [ 0 ] . get_str ( ) ) ;
Object entry ;
if ( pwalletMain - > mapWallet . count ( hash ) )
{
const CWalletTx & wtx = pwalletMain - > mapWallet [ hash ] ;
TxToJSON ( wtx , entry );
TxToJSON ( wtx , entry , decompositions ) ;
int64 nCredit = wtx . GetCredit ( ) ;
int64 nDebit = wtx . GetDebit ( ) ;
@ -1538,10 +1614,12 @@ Value gettransaction(const Array& params, bool fHelp)
{
CTransaction tx ;
uint256 hashBlock = 0 ;
if ( GetTransaction ( hash , tx , hashBlock ) )
if ( ( ! ptx ) & & GetTransaction ( hash , tx , hashBlock ) )
ptx = & tx ;
if ( ptx )
{
entry . push_back ( Pair ( " txid " , hash . GetHex ( ) ) ) ;
TxToJSON ( tx, entry ) ;
TxToJSON ( * p tx, entry , decompositions ) ;
if ( hashBlock = = 0 )
entry . push_back ( Pair ( " confirmations " , 0 ) ) ;
else
@ -1564,6 +1642,22 @@ Value gettransaction(const Array& params, bool fHelp)
else
throw JSONRPCError ( - 5 , " No information available about transaction " ) ;
}
}
Value gettransaction ( const Array & params , bool fHelp )
{
if ( fHelp | | params . size ( ) < 1 | | params . size ( ) > 2 )
throw runtime_error (
" gettransaction <txid> [decompositions] \n "
" Get detailed information about <txid> " ) ;
uint256 hash ;
hash . SetHex ( params [ 0 ] . get_str ( ) ) ;
Object entry ;
AnyTxToJSON ( hash , NULL , entry ,
( params . size ( ) > 1 ) ? params [ 1 ] . get_obj ( ) : emptyobj ) ;
return entry ;
}
@ -2045,9 +2139,9 @@ Value getblockhash(const Array& params, bool fHelp)
Value getblock ( const Array & params , bool fHelp )
{
if ( fHelp | | params . size ( ) != 1 )
if ( fHelp | | params . size ( ) < 1 | | params . size ( ) > 2 )
throw runtime_error (
" getblock <hash> \n "
" getblock <hash> [decompositions] \n "
" Returns details of a block with given block-hash. " ) ;
std : : string strHash = params [ 0 ] . get_str ( ) ;
@ -2060,7 +2154,8 @@ Value getblock(const Array& params, bool fHelp)
CBlockIndex * pblockindex = mapBlockIndex [ hash ] ;
block . ReadFromDisk ( pblockindex , true ) ;
return blockToJSON ( block , pblockindex ) ;
return blockToJSON ( block , pblockindex ,
( params . size ( ) > 1 ) ? params [ 1 ] . get_obj ( ) : emptyobj ) ;
}
@ -2718,7 +2813,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if ( strMethod = = " listreceivedbyaccount " & & n > 0 ) ConvertTo < boost : : int64_t > ( params [ 0 ] ) ;
if ( strMethod = = " listreceivedbyaccount " & & n > 1 ) ConvertTo < bool > ( params [ 1 ] ) ;
if ( strMethod = = " getbalance " & & n > 1 ) ConvertTo < boost : : int64_t > ( params [ 1 ] ) ;
if ( strMethod = = " getblock " & & n > 1 ) ConvertTo < Object > ( params [ 1 ] ) ;
if ( strMethod = = " getblockhash " & & n > 0 ) ConvertTo < boost : : int64_t > ( params [ 0 ] ) ;
if ( strMethod = = " gettransaction " & & n > 1 ) ConvertTo < Object > ( params [ 1 ] ) ;
if ( strMethod = = " move " & & n > 2 ) ConvertTo < double > ( params [ 2 ] ) ;
if ( strMethod = = " move " & & n > 3 ) ConvertTo < boost : : int64_t > ( params [ 3 ] ) ;
if ( strMethod = = " sendfrom " & & n > 2 ) ConvertTo < double > ( params [ 2 ] ) ;