1
// Copyright © 2017-2020 Trust Wallet.
2
//
3
// This file is part of Trust. The full Trust copyright notice, including
4
// terms governing use, modification, and redistribution, is contained in the
5
// file LICENSE at the root of the source code distribution tree.
6

7
#pragma once
8

9
#include "Transaction.h"
10
#include "../Data.h"
11
#include "../uint256.h"
12

13
#include <cstdint>
14
#include <string>
15
#include <vector>
16

17
namespace TW::Ethereum {
18

19
/// Implementation of Ethereum's RLP encoding.
20
///
21
/// - SeeAlso: https://github.com/ethereum/wiki/wiki/RLP
22
struct RLP {
23
    /// Encodes a string;
24 1
    static Data encode(const std::string& string) noexcept {
25 1
        return encode(Data(string.begin(), string.end()));
26
    }
27

28 1
    static Data encode(uint8_t number) noexcept { return encode(uint256_t(number)); }
29

30 1
    static Data encode(uint16_t number) noexcept { return encode(uint256_t(number)); }
31

32 1
    static Data encode(int32_t number) noexcept {
33 1
        if (number < 0) {
34 1
            return {}; // RLP cannot encode negative numbers
35
        }
36 1
        return encode(static_cast<uint32_t>(number));
37
    }
38

39 1
    static Data encode(uint32_t number) noexcept { return encode(uint256_t(number)); }
40

41
    static Data encode(int64_t number) noexcept {
42
        if (number < 0) {
43
            return {}; // RLP cannot encode negative numbers
44
        }
45
        return encode(static_cast<uint64_t>(number));
46
    }
47

48 1
    static Data encode(uint64_t number) noexcept { return encode(uint256_t(number)); }
49

50
    static Data encode(const uint256_t& number) noexcept;
51

52
    /// Encodes a transaction.
53
    static Data encode(const Transaction& transaction) noexcept;
54

55
    /// Wraps encoded data as a list.
56
    static Data encodeList(const Data& encoded) noexcept;
57

58
    /// Encodes a block of data.
59
    static Data encode(const Data& data) noexcept;
60

61
    /// Encodes a static array.
62
    template <std::size_t N>
63 1
    static Data encode(const std::array<uint8_t, N>& data) noexcept {
64
        if (N == 1 && data[0] <= 0x7f) {
65
            // Fits in single byte, no header
66
            return Data(data.begin(), data.end());
67
        }
68

69 1
        auto encoded = encodeHeader(data.size(), 0x80, 0xb7);
70 1
        encoded.insert(encoded.end(), data.begin(), data.end());
71 1
        return encoded;
72
    }
73

74
    /// Encodes a list of elements.
75
    template <typename T>
76 1
    static Data encodeList(T elements) noexcept {
77 1
        auto encodedData = Data();
78 1
        for (const auto& el : elements) {
79 1
            auto encoded = encode(el);
80 1
            if (encoded.empty()) {
81 1
                return {};
82
            }
83 1
            encodedData.insert(encodedData.end(), encoded.begin(), encoded.end());
84
        }
85

86 1
        auto encoded = encodeHeader(encodedData.size(), 0xc0, 0xf7);
87 1
        encoded.insert(encoded.end(), encodedData.begin(), encodedData.end());
88 1
        return encoded;
89
    }
90

91
    /// Encodes a list header.
92
    static Data encodeHeader(uint64_t size, uint8_t smallTag, uint8_t largeTag) noexcept;
93

94
    /// Returns the representation of an integer using the least number of bytes
95
    /// needed.
96
    static Data putint(uint64_t i) noexcept;
97

98 1
    struct DecodedItem {
99
        std::vector<Data> decoded;
100
        Data remainder;
101
    };
102

103
    /// Decodes raw transaction to json data
104
    static Data decodeRawTransaction(const Data& data);
105

106
    /// Decodes data, remainder from RLP encoded data
107
    static DecodedItem decode(const Data& data);
108
};
109

110
} // namespace TW::Ethereum

Read our documentation on viewing source code .

Loading