diff --git a/libraries/chain/pts_address.cpp b/libraries/chain/pts_address.cpp new file mode 100644 index 00000000..3d0ff115 --- /dev/null +++ b/libraries/chain/pts_address.cpp @@ -0,0 +1,77 @@ +#include +#include + +#include +#include +#include +#include + +namespace graphene { namespace chain { + + pts_address::pts_address() + { + memset( addr.data, 0, sizeof(addr.data) ); + } + + pts_address::pts_address( const std::string& base58str ) + { + std::vector v = fc::from_base58( fc::string(base58str) ); + if( v.size() ) + memcpy( addr.data, v.data(), std::min( v.size(), sizeof(addr) ) ); + + if( !is_valid() ) + { + FC_THROW_EXCEPTION( invalid_pts_address, "invalid pts_address ${a}", ("a", base58str) ); + } + } + + pts_address::pts_address( const fc::ecc::public_key& pub, bool compressed, uint8_t version ) + { + fc::sha256 sha2; + if( compressed ) + { + auto dat = pub.serialize(); + sha2 = fc::sha256::hash(dat.data, sizeof(dat) ); + } + else + { + auto dat = pub.serialize_ecc_point(); + sha2 = fc::sha256::hash(dat.data, sizeof(dat) ); + } + auto rep = fc::ripemd160::hash((char*)&sha2,sizeof(sha2)); + addr.data[0] = version; + memcpy( addr.data+1, (char*)&rep, sizeof(rep) ); + auto check = fc::sha256::hash( addr.data, sizeof(rep)+1 ); + check = fc::sha256::hash(check); + memcpy( addr.data+1+sizeof(rep), (char*)&check, 4 ); + } + + /** + * Checks the address to verify it has a + * valid checksum + */ + bool pts_address::is_valid()const + { + auto check = fc::sha256::hash( addr.data, sizeof(fc::ripemd160)+1 ); + check = fc::sha256::hash(check); + return memcmp( addr.data+1+sizeof(fc::ripemd160), (char*)&check, 4 ) == 0; + } + + pts_address::operator std::string()const + { + return fc::to_base58( addr.data, sizeof(addr) ); + } + +} } // namespace graphene + +namespace fc +{ + void to_variant( const graphene::chain::pts_address& var, variant& vo ) + { + vo = std::string(var); + } + void from_variant( const variant& var, graphene::chain::pts_address& vo ) + { + vo = graphene::chain::pts_address( var.as_string() ); + } +}