#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() ); } }