peerplays_migrated/libraries/plugins/peerplays_sidechain/ethereum/encoders.cpp
2022-08-19 17:34:57 +03:00

128 lines
3.4 KiB
C++

#include <graphene/peerplays_sidechain/ethereum/encoders.hpp>
#include <stdlib.h>
#include <boost/algorithm/hex.hpp>
#include <boost/format.hpp>
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<std::pair<std::string, uint16_t>>& 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