@ -9,7 +9,15 @@
# include <pubkey.h>
# include <pubkey.h>
# include <script/standard.h>
# include <script/standard.h>
bool CScriptCompressor : : IsToKeyID ( CKeyID & hash ) const
/*
* These check for scripts for which a special case with a shorter encoding is defined .
* They are implemented separately from the CScript test , as these test for exact byte
* sequence correspondences , and are more strict . For example , IsToPubKey also verifies
* whether the public key is valid ( as invalid ones cannot be represented in compressed
* form ) .
*/
static bool IsToKeyID ( const CScript & script , CKeyID & hash )
{
{
if ( script . size ( ) = = 25 & & script [ 0 ] = = OP_DUP & & script [ 1 ] = = OP_HASH160
if ( script . size ( ) = = 25 & & script [ 0 ] = = OP_DUP & & script [ 1 ] = = OP_HASH160
& & script [ 2 ] = = 20 & & script [ 23 ] = = OP_EQUALVERIFY
& & script [ 2 ] = = 20 & & script [ 23 ] = = OP_EQUALVERIFY
@ -20,7 +28,7 @@ bool CScriptCompressor::IsToKeyID(CKeyID &hash) const
return false ;
return false ;
}
}
bool CScriptCompressor : : IsToScriptID ( CScriptID & hash ) const
static bool IsToScriptID ( const CScript & script , CScriptID & hash )
{
{
if ( script . size ( ) = = 23 & & script [ 0 ] = = OP_HASH160 & & script [ 1 ] = = 20
if ( script . size ( ) = = 23 & & script [ 0 ] = = OP_HASH160 & & script [ 1 ] = = 20
& & script [ 22 ] = = OP_EQUAL ) {
& & script [ 22 ] = = OP_EQUAL ) {
@ -30,7 +38,7 @@ bool CScriptCompressor::IsToScriptID(CScriptID &hash) const
return false ;
return false ;
}
}
bool CScriptCompressor : : IsToPubKey ( CPubKey & pubkey ) const
static bool IsToPubKey ( const CScript & script , CPubKey & pubkey )
{
{
if ( script . size ( ) = = 35 & & script [ 0 ] = = 33 & & script [ 34 ] = = OP_CHECKSIG
if ( script . size ( ) = = 35 & & script [ 0 ] = = 33 & & script [ 34 ] = = OP_CHECKSIG
& & ( script [ 1 ] = = 0x02 | | script [ 1 ] = = 0x03 ) ) {
& & ( script [ 1 ] = = 0x02 | | script [ 1 ] = = 0x03 ) ) {
@ -45,24 +53,24 @@ bool CScriptCompressor::IsToPubKey(CPubKey &pubkey) const
return false ;
return false ;
}
}
bool C ScriptCompressor: : Compress ( std : : vector < unsigned char > & out ) const
bool C ompressScript( const CScript & script , std : : vector < unsigned char > & out )
{
{
CKeyID keyID ;
CKeyID keyID ;
if ( IsToKeyID ( keyID) ) {
if ( IsToKeyID ( script, keyID) ) {
out . resize ( 21 ) ;
out . resize ( 21 ) ;
out [ 0 ] = 0x00 ;
out [ 0 ] = 0x00 ;
memcpy ( & out [ 1 ] , & keyID , 20 ) ;
memcpy ( & out [ 1 ] , & keyID , 20 ) ;
return true ;
return true ;
}
}
CScriptID scriptID ;
CScriptID scriptID ;
if ( IsToScriptID ( script ID) ) {
if ( IsToScriptID ( script , script ID) ) {
out . resize ( 21 ) ;
out . resize ( 21 ) ;
out [ 0 ] = 0x01 ;
out [ 0 ] = 0x01 ;
memcpy ( & out [ 1 ] , & scriptID , 20 ) ;
memcpy ( & out [ 1 ] , & scriptID , 20 ) ;
return true ;
return true ;
}
}
CPubKey pubkey ;
CPubKey pubkey ;
if ( IsToPubKey ( pubkey) ) {
if ( IsToPubKey ( script, pubkey) ) {
out . resize ( 33 ) ;
out . resize ( 33 ) ;
memcpy ( & out [ 1 ] , & pubkey [ 1 ] , 32 ) ;
memcpy ( & out [ 1 ] , & pubkey [ 1 ] , 32 ) ;
if ( pubkey [ 0 ] = = 0x02 | | pubkey [ 0 ] = = 0x03 ) {
if ( pubkey [ 0 ] = = 0x02 | | pubkey [ 0 ] = = 0x03 ) {
@ -76,7 +84,7 @@ bool CScriptCompressor::Compress(std::vector<unsigned char> &out) const
return false ;
return false ;
}
}
unsigned int CScriptCompressor: : GetSpecialSize( unsigned int nSize ) const
unsigned int GetSpecialScript Size( unsigned int nSize )
{
{
if ( nSize = = 0 | | nSize = = 1 )
if ( nSize = = 0 | | nSize = = 1 )
return 20 ;
return 20 ;
@ -85,7 +93,7 @@ unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const
return 0 ;
return 0 ;
}
}
bool CScriptCompressor: : Decompress ( unsigned int nSize , const std : : vector < unsigned char > & in )
bool DecompressScript( CScript & script , unsigned int nSize , const std : : vector < unsigned char > & in )
{
{
switch ( nSize ) {
switch ( nSize ) {
case 0x00 :
case 0x00 :
@ -139,7 +147,7 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])
// (this is decodable, as d is in [1-9] and e is in [0-9])
uint64_t C TxOutCompressor: : C ompressAmount( uint64_t n )
uint64_t C ompressAmount( uint64_t n )
{
{
if ( n = = 0 )
if ( n = = 0 )
return 0 ;
return 0 ;
@ -158,7 +166,7 @@ uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
}
}
}
}
uint64_t CTxOutCompressor: : DecompressAmount( uint64_t x )
uint64_t DecompressAmount( uint64_t x )
{
{
// x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
// x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
if ( x = = 0 )
if ( x = = 0 )