#include #include #include #include namespace graphene { namespace peerplays_sidechain { namespace ethereum { //! base_encoder std::string base_encoder::encode_uint256(boost::multiprecision::uint256_t value) { return (boost::format("%x") % boost::io::group(std::setw(64), std::setfill('0'), value)).str(); } std::string base_encoder::encode_address(const std::string& value) { return (boost::format("%x") % boost::io::group(std::setw(64), std::setfill('0'), value)).str(); } std::string base_encoder::encode_string(const std::string& value) { std::string data = (boost::format("%x") % boost::io::group(std::setw(64), std::setfill('0'), value.size())).str(); data += boost::algorithm::hex(value) + std::string( (64 - value.size() * 2 % 64), '0' ); return data; } //! update_owners_encoder std::string update_owners_encoder::encode(const std::vector>& owners_weights, const std::string& object_id) const { std::string data = "0x" + function_signature; data += base_encoder::encode_uint256(64); data += base_encoder::encode_uint256((owners_weights.size() * 2 + 3) * 32); data += base_encoder::encode_uint256(owners_weights.size()); for(const auto& owner : owners_weights) { data += base_encoder::encode_address(owner.first); data += base_encoder::encode_uint256(owner.second); } data += base_encoder::encode_string(object_id); return data; } //! withdrawal_encoder std::string withdrawal_encoder::encode(const std::string& to, boost::multiprecision::uint256_t amount, const std::string& object_id) const { std::string data = "0x" + function_signature; data += base_encoder::encode_address(to); data += base_encoder::encode_uint256(amount); data += base_encoder::encode_uint256(32*3); data += base_encoder::encode_string(object_id); return data; } //! rlp_encoder std::string rlp_encoder::encode(const std::string& s) { return encode_rlp(hex2bytes(s)); } std::string rlp_encoder::encode_length(int len, int offset) { if(len<56) { std::string temp; temp=(char)(len+offset); return temp; } else { const std::string hexLength = int2Hex(len); const int lLength = hexLength.size()/2; const std::string fByte = int2Hex(offset+55+lLength); return hex2bytes(fByte+hexLength); } } std::string rlp_encoder::hex2bytes(const std::string& s) { std::string dest; dest.resize(s.size()/2); hex2bin(s.c_str(), &dest[0]); return dest; } std::string rlp_encoder::encode_rlp(const std::string& s) { if(s.size()==1 && (unsigned char)s[0]<128) return s; else return encode_length(s.size(), 128) + s; } std::string rlp_encoder::int2Hex(int n) { std::stringstream stream; stream << std::hex << n; std::string result( stream.str() ); if(result.size() % 2) result = "0"+result; return result; } int rlp_encoder::char2int(char input) { if(input >= '0' && input <= '9') return input - '0'; if(input >= 'A' && input <= 'F') return input - 'A' + 10; if(input >= 'a' && input <= 'f') return input - 'a' + 10; return -1; } void rlp_encoder::hex2bin(const char* src, char* target) { while(*src && src[1]) { *(target++) = char2int(*src)*16 + char2int(src[1]); src += 2; } } }}} // namespace graphene::peerplays_sidechain::ethereum