Skip to content

Commit

Permalink
Added support for testnet contract addresses (txch). (#213)
Browse files Browse the repository at this point in the history
- Added tests to support it.
  • Loading branch information
haorldbchi authored Sep 22, 2022
1 parent 747112d commit fbdc5e7
Show file tree
Hide file tree
Showing 8 changed files with 1,561 additions and 471 deletions.
22 changes: 17 additions & 5 deletions src/util/KeyTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,25 @@ void KeyTools::PrintSK( const bls::PrivateKey& key )
/// PuzzleHash
///
//-----------------------------------------------------------
bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] )
bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_MAX_LENGTH+1] )
{
ASSERT( address );
if( !address )
return false;

if( strlen( address ) != CHIA_ADDRESS_LENGTH )
const size_t addrLen = strlen( address );
if( addrLen != CHIA_ADDRESS_LENGTH && addrLen != CHIA_TESTNET_ADDRESS_LENGTH )
return false;

char hrp [CHIA_ADDRESS_LENGTH-5] = { 0 };
byte data[CHIA_ADDRESS_LENGTH-8];
char hrp [CHIA_ADDRESS_MAX_LENGTH-5] = {};
byte data[CHIA_ADDRESS_MAX_LENGTH-8];

size_t dataLen = 0;
if( bech32_decode( hrp, data, &dataLen, address ) != BECH32_ENCODING_BECH32M )
return false;

if( memcmp( "xch", hrp, sizeof( "xch" ) ) != 0 )
if( memcmp( "xch", hrp, sizeof( "xch" ) ) != 0 &&
memcmp( "txch", hrp, sizeof( "txch" ) ) != 0 )
return false;

byte decoded[40];
Expand All @@ -105,3 +107,13 @@ bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_
return true;
}

//-----------------------------------------------------------
bool PuzzleHash::FromHex( const char hex[CHIA_PUZZLE_HASH_SIZE*2+1], PuzzleHash& outHash )
{
const size_t hexLen = strlen( hex );
if( hexLen != CHIA_PUZZLE_HASH_SIZE*2 )
return false;

return HexStrToBytesSafe( hex, hexLen, outHash.data, CHIA_PUZZLE_HASH_SIZE );
}

15 changes: 11 additions & 4 deletions src/util/KeyTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,28 @@ extern "C" {
#pragma warning( pop )


#define CHIA_PUZZLE_HASH_SIZE 32
#define CHIA_ADDRESS_LENGTH 62 // 3 (hrp) + 1 (divisor) + 52 (data) + 6 (checksum)
#define CHIA_PUZZLE_HASH_SIZE 32
#define CHIA_ADDRESS_MAX_LENGTH 63 // 4 (hrp) + 1 (divisor) + 52 (data) + 6 (checksum)
// hrp is either xch or txch

#define CHIA_ADDRESS_LENGTH 62
#define CHIA_TESTNET_ADDRESS_LENGTH 63

struct XchAddress : NBytes<CHIA_ADDRESS_LENGTH+1>
{};

struct PuzzleHash : NBytes<CHIA_PUZZLE_HASH_SIZE>
{
static bool FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] );
static bool FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_MAX_LENGTH+1] );

void ToAddress( char address[CHIA_ADDRESS_LENGTH+1] );
void ToAddress( char address[CHIA_ADDRESS_MAX_LENGTH+1] );
std::string ToAddressString();

void ToHex( char hex[CHIA_PUZZLE_HASH_SIZE+1] ) const;
std::string ToHex() const;

static bool FromHex( const char hex[CHIA_PUZZLE_HASH_SIZE*2+1], PuzzleHash& outHash );

};

class KeyTools
Expand Down
34 changes: 34 additions & 0 deletions src/util/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,40 @@ inline void HexStrToBytes( const char* str, const size_t strSize,
}
}

//-----------------------------------------------------------
inline bool HexStrToBytesSafe( const char* str, const size_t strSize,
byte* dst, size_t dstSize )
{
if( !str || !strSize || !dst || !dstSize )
return false;

const size_t maxSize = (strSize / 2) * 2;
const char* end = str + maxSize;

if( dstSize < maxSize / 2 )
return false;

int i = 0;
while( str < end )
{
const int char0 = (int)str[0];
const int char1 = (int)str[1];

if( (char0 - (int)'0' > 9 && char0 - (int)'A' > 5 && char0 - (int)'a' > 5) ||
(char1 - (int)'0' > 9 && char1 - (int)'A' > 5 && char1 - (int)'a' > 5) )
return false;

byte msb = (byte)HEX_TO_BIN[char0];
byte lsb = (byte)HEX_TO_BIN[char1];

byte v = lsb + msb * 16u;
dst[i++] = v;
str += 2;
}

return true;
}

//-----------------------------------------------------------
// Encode bytes into hex format
// Return:
Expand Down
15 changes: 0 additions & 15 deletions test/checker.py

This file was deleted.

42 changes: 42 additions & 0 deletions tests/TestAddressesAndKeys.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "TestUtil.h"
#include "util/KeyTools.h"
#include "TestXchAddressData.h"
#include "util/Util.h"

//-----------------------------------------------------------
TEST_CASE( "mainnet-contract-address-decode", "[unit-core][contract-address]" )
{
const uint64 numAddresses = (uint64)( sizeof( TestMainnetAddress) / sizeof( AddrHashTestPair ) );
PuzzleHash generatedHash;

for( uint64 i = 0; i < numAddresses; i++ )
{
const AddrHashTestPair& pair = TestMainnetAddress[i];

ENSURE( PuzzleHash::FromAddress( generatedHash, pair.address ) );

PuzzleHash expectedHash;
ENSURE( PuzzleHash::FromHex( pair.hash, expectedHash ) );

ENSURE( memcmp( generatedHash.data, expectedHash.data, CHIA_PUZZLE_HASH_SIZE ) == 0 );
}
}

//-----------------------------------------------------------
TEST_CASE( "testnet-contract-address-decode", "[unit-core][contract-address]" )
{
const uint64 numAddresses = (uint64)( sizeof( TestTestnetAddress) / sizeof( AddrHashTestPair ) );
PuzzleHash generatedHash;

for( uint64 i = 0; i < numAddresses; i++ )
{
const AddrHashTestPair& pair = TestTestnetAddress[i];

ENSURE( PuzzleHash::FromAddress( generatedHash, pair.address ) );

PuzzleHash expectedHash;
ENSURE( PuzzleHash::FromHex( pair.hash, expectedHash ) );

ENSURE( memcmp( generatedHash.data, expectedHash.data, CHIA_PUZZLE_HASH_SIZE ) == 0 );
}
}
Loading

0 comments on commit fbdc5e7

Please sign in to comment.