TARAXA
encoding_solidity.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <libdevcore/Common.h>
4 #include <libdevcore/SHA3.h>
5 
6 #include <limits>
7 
8 #include "common/types.hpp"
9 
10 namespace taraxa::util {
12  public:
13  static constexpr uint8_t kStartPrefix = 32;
14  static constexpr uint8_t kStartPrefixSize = 1;
16  template <typename... Params>
17  static bytes packFunctionCall(const std::string& function, const Params&... args) {
18  auto output = getFunction(function);
19  auto args_data = pack(args...);
20  output.insert(output.end(), std::make_move_iterator(args_data.begin()), std::make_move_iterator(args_data.end()));
21  return output;
22  }
23 
24  template <typename... Params>
25  static bytes pack(const Params&... args) {
26  bytes output;
27  bytes offset_data;
28  // initial offset is after last arg
29  auto current_offset = kWordSize * sizeof...(args);
30 
31  auto process = [&](auto elem) {
32  auto data = packElemement(elem);
33  const auto data_size = data.size();
34  // Dynamic encoding needs to be appended to the end of the whole structure
35  if (data_size > kWordSize) {
36  offset_data.reserve(offset_data.size() + data_size);
37  offset_data.insert(offset_data.end(), std::make_move_iterator(data.begin()),
38  std::make_move_iterator(data.end()));
39  // Save position where data will be stored
40  data = packElemement(current_offset);
41  current_offset += data_size;
42  }
43  output.insert(output.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end()));
44  };
45 
46  (process(args), ...);
47 
48  output.insert(output.end(), std::make_move_iterator(offset_data.begin()),
49  std::make_move_iterator(offset_data.end()));
50  return output;
51  }
52 
53  template <unsigned N, std::enable_if_t<(N <= 32)>* = nullptr>
54  static bytes packElemement(dev::FixedHash<N> hash) {
55  bytes data;
56  data.insert(data.end(), 32 - N, 0);
57  data.insert(data.end(), hash.begin(), hash.end());
58  return data;
59  }
60 
61  template <typename T, std::enable_if_t<std::numeric_limits<T>::is_integer>* = nullptr>
62  static bytes packElemement(T num) {
63  return dev::toBigEndian(u256(num));
64  }
65 
66  static bytes packElemement(bool flag) { return dev::toBigEndian(u256(flag)); }
67 
68  static bytes packElemement(const bytes& value) {
69  bytes data;
70  // encode length of msg
71  if (value.size()) {
72  data = pack(value.size());
73  }
74  // encode msg
75  data.insert(data.end(), value.begin(), value.end());
76  // trailing zeros
77  data.insert(data.end(), kWordSize - (value.size() % kWordSize), 0);
78  return data;
79  }
81 
83  template <typename... Params>
84  static void staticUnpack(const bytes& input, Params&... args) {
85  uint16_t i = 0;
86  auto process = [&](auto& elem) {
87  const auto begin = input.begin() + i * kWordSize;
88  const auto end = input.begin() + (i + 1) * kWordSize;
89  unpackElement(bytes(begin, end), elem);
90  i++;
91  };
92 
93  (process(args), ...);
94  }
95 
96  static void unpackElement(const bytes& input, u256& out) { out = u256(input); }
97 
99  static void unpackElement(const bytes& input, T& out) {
100  out = dev::fromBigEndian<T>(input);
101  }
102 
103  template <unsigned N, std::enable_if_t<(N <= 32)>* = nullptr>
104  static void unpackElement(const bytes& input, dev::FixedHash<N>& hash) {
105  bytes stripped(input.begin() + 32 - N, input.end());
106  hash = dev::FixedHash<N>(stripped);
107  }
108 
110 
111  static bytes getFunction(const std::string& function) {
112  return dev::sha3(function.c_str()).ref().cropped(0, 4).toBytes();
113  }
114 
115  const static size_t kWordSize = 32;
116 };
117 
118 } // namespace taraxa::util
Definition: encoding_solidity.hpp:11
static constexpr uint8_t kStartPrefix
Definition: encoding_solidity.hpp:13
static bytes packFunctionCall(const std::string &function, const Params &... args)
PACKING ///.
Definition: encoding_solidity.hpp:17
static void staticUnpack(const bytes &input, Params &... args)
PACKING ///.
Definition: encoding_solidity.hpp:84
static constexpr uint8_t kStartPrefixSize
Definition: encoding_solidity.hpp:14
static bytes packElemement(const bytes &value)
Definition: encoding_solidity.hpp:68
static const size_t kWordSize
Definition: encoding_solidity.hpp:115
static void unpackElement(const bytes &input, u256 &out)
Definition: encoding_solidity.hpp:96
static bytes pack(const Params &... args)
Definition: encoding_solidity.hpp:25
static bytes packElemement(dev::FixedHash< N > hash)
Definition: encoding_solidity.hpp:54
static bytes packElemement(bool flag)
Definition: encoding_solidity.hpp:66
static bytes packElemement(T num)
Definition: encoding_solidity.hpp:62
static bytes getFunction(const std::string &function)
UNPACKING ///.
Definition: encoding_solidity.hpp:111
static void unpackElement(const bytes &input, T &out)
Definition: encoding_solidity.hpp:99
static constexpr std::enable_if_t<!std::is_enum_v< N >, bool > is_integer(Signedness sig)
Definition: CommonData.h:333
std::vector<::byte > bytes
Definition: Common.h:46
void toBigEndian(T _val, Out &o_out)
Definition: CommonData.h:105
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:98
Definition: default_construct_copyable_movable.hpp:10
std::vector< byte > bytes
Definition: types.hpp:53