Skip to content

Commit

Permalink
Finish support for tuple encoding
Browse files Browse the repository at this point in the history
This includes encoding std::vector<std::tuple<Args...> and std::tuple<std::tuple<>> nested support.
  • Loading branch information
itamarcps committed Dec 12, 2023
1 parent ab46e1c commit 63c6236
Show file tree
Hide file tree
Showing 3 changed files with 584 additions and 6 deletions.
4 changes: 0 additions & 4 deletions src/contract/abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ See the LICENSE.txt file in the project root for more information.

#include "abi.h"

void ABI::Encoder::append(Bytes &dest, const Bytes &src) {
dest.insert(dest.end(), src.begin(), src.end());
}

Functor ABI::Encoder::encodeFunction(const std::string_view func) {
auto view = Utils::create_view_span(func);
auto hash = Utils::sha3(view);
Expand Down
11 changes: 9 additions & 2 deletions src/contract/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,10 @@ namespace ABI {
* @param dest The Bytes piece to append to.
* @param src The Bytes piece to be appended.
*/
void append(Bytes& dest, const Bytes& src);
template <typename T>
void append(Bytes &dest, const T &src) {
dest.insert(dest.end(), src.cbegin(), src.cend());
}

/**
* Encode a function header (functor).
Expand Down Expand Up @@ -661,6 +664,7 @@ namespace ABI {

/// Forward declaration.
template<typename T, typename... Ts> Bytes encode(const T& first, const Ts&... rest);
template<typename... Ts> Bytes encode(const std::vector<std::tuple<Ts...>>& v);

/// Specialization for encoding a tuple. Expand and call back encode<T,Ts...>
template<typename... Ts> Bytes encode(const std::tuple<Ts...>& t) {
Expand Down Expand Up @@ -690,18 +694,21 @@ namespace ABI {
/// Specialization for encoding a vector of tuples.
template<typename... Ts> Bytes encode(const std::vector<std::tuple<Ts...>>& v) {
Bytes result;
uint64_t nextOffset = 32; // The first 32 bytes are for the length of the dynamic array
uint64_t nextOffset = 32 * v.size(); // The first 32 bytes are for the length of the dynamic array
Bytes dynamicBytes;
Bytes tupleData;
Bytes tupleOffSets;

// Encode each tuple
for (const auto& t : v) {
append(tupleOffSets, Utils::uint256ToBytes(nextOffset));
Bytes tupleBytes = encode(t); // We're calling the encode function specialized for tuples
nextOffset += tupleBytes.size();
tupleData.insert(tupleData.end(), tupleBytes.begin(), tupleBytes.end());
}

append(result, Utils::padLeftBytes(Utils::uintToBytes(v.size()), 32)); // Add the array length to the result
append(result, tupleOffSets); // Add the tuple offsets
result.insert(result.end(), tupleData.begin(), tupleData.end()); // Add the tuple data
return result;
}
Expand Down
Loading

0 comments on commit 63c6236

Please sign in to comment.