BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
address.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
26 #include <fc/crypto/base58.hpp>
27 #include <algorithm>
28 
29 #include <fc/io/raw.hpp>
30 
31 namespace graphene { namespace protocol {
32 
33  address::address( const std::string& base58str )
34  {
35  std::string prefix( GRAPHENE_ADDRESS_PREFIX );
36  FC_ASSERT( is_valid( base58str, prefix ), "${str}", ("str",base58str) );
37 
38  std::vector<char> v = fc::from_base58( base58str.substr( prefix.size() ) );
39  memcpy( (char*)addr._hash, v.data(), std::min<size_t>( v.size()-4, sizeof( addr ) ) );
40  }
41 
42  bool address::is_valid( const std::string& base58str, const std::string& prefix )
43  {
44  const size_t prefix_len = prefix.size();
45  if( base58str.size() <= prefix_len )
46  return false;
47  if( base58str.substr( 0, prefix_len ) != prefix )
48  return false;
49  std::vector<char> v;
50  try
51  {
52  v = fc::from_base58( base58str.substr( prefix_len ) );
53  }
54  catch( const fc::parse_error_exception& e )
55  {
56  return false;
57  }
58 
59  if( v.size() != sizeof( fc::ripemd160 ) + 4 )
60  return false;
61 
62  const fc::ripemd160 checksum = fc::ripemd160::hash( v.data(), v.size() - 4 );
63  if( memcmp( v.data() + 20, (char*)checksum._hash, 4 ) != 0 )
64  return false;
65 
66  return true;
67  }
68 
70  {
71  auto dat = pub.serialize();
72  addr = fc::ripemd160::hash( fc::sha512::hash( (char*) dat.data(), dat.size() ) );
73  }
74 
75  address::address( const pts_address& ptsaddr )
76  {
77  addr = fc::ripemd160::hash( (char*)&ptsaddr, sizeof( ptsaddr ) );
78  }
79 
81  {
82  addr = fc::ripemd160::hash( fc::sha512::hash( (char*) pub.data(), pub.size() ) );
83  }
84 
86  {
87  addr = fc::ripemd160::hash( fc::sha512::hash( (char*) pub.key_data.data(), pub.key_data.size() ) );
88  }
89 
90  address::operator std::string()const
91  {
92  char bin_addr[24];
93  static_assert( sizeof(bin_addr) >= sizeof(addr) + 4, "address size mismatch" );
94  memcpy( bin_addr, addr.data(), sizeof(addr) );
95  auto checksum = fc::ripemd160::hash( addr.data(), sizeof(addr) );
96  memcpy( bin_addr + sizeof(addr), (char*)&checksum._hash[0], 4 );
97  return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( bin_addr, sizeof(bin_addr) );
98  }
99 
100 } } // namespace graphene::protocol
101 
102 namespace fc
103 {
104  void to_variant( const graphene::protocol::address& var, variant& vo, uint32_t max_depth )
105  {
106  vo = std::string(var);
107  }
108  void from_variant( const variant& var, graphene::protocol::address& vo, uint32_t max_depth )
109  {
111  }
112 }
113 
boost::endian::little_uint32_buf_t _hash[5]
Definition: ripemd160.hpp:71
public_key_data serialize() const
std::string to_base58(const char *d, size_t s)
Definition: base58.cpp:612
Definition: api.cpp:56
static ripemd160 hash(const fc::sha512 &h)
Definition: ripemd160.cpp:43
#define GRAPHENE_ADDRESS_PREFIX
Definition: config.hpp:27
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
static bool is_valid(const std::string &base58str, const std::string &prefix=GRAPHENE_ADDRESS_PREFIX)
Definition: address.cpp:42
void from_variant(const variant &var, graphene::protocol::address &vo, uint32_t max_depth)
Definition: address.cpp:108
char * data() const
Definition: ripemd160.cpp:26
fc::ecc::public_key_data key_data
Definition: types.hpp:256
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type)
Definition: types.hpp:74
std::vector< char > from_base58(const std::string &base58_str)
Definition: base58.cpp:622
Definition: api.hpp:15
a 160 bit hash of a public key
Definition: address.hpp:44
void to_variant(const graphene::protocol::address &var, variant &vo, uint32_t max_depth)
Definition: address.cpp:104
address()
constructs empty / null address
Definition: address.hpp:47
std::string as_string() const
Definition: variant.cpp:469