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
#include "ValueEncoder.h"
8

9
#include <Ethereum/Address.h>
10

11
#include <Data.h>
12
#include <Hash.h>
13

14
#include <cassert>
15

16
namespace TW::Ethereum::ABI {
17

18
using namespace TW;
19

20 1
void ValueEncoder::encodeBool(bool value, Data& inout) {
21 1
    append(inout, Data(encodedIntSize));
22 1
    inout[inout.size() - 1] = value ? 1 : 0;
23
}
24

25 1
void ValueEncoder::encodeInt32(int32_t value, Data& inout) {
26
    // cast up
27 1
    encodeInt256(static_cast<int256_t>(value), inout);
28
}
29

30 1
void ValueEncoder::encodeUInt32(uint32_t value, Data& inout) {
31
    // cast up
32 1
    encodeUInt256(static_cast<uint256_t>(value), inout);
33
}
34

35 1
void ValueEncoder::encodeInt256(const int256_t& value, Data& inout) {
36 1
    encodeUInt256(uint256FromInt256(value), inout);
37
}
38

39 1
inline Data paddedOnLeft(const Data& inout) {
40 1
    int paddingSize = (int)(ValueEncoder::encodedIntSize - inout.size());
41 1
    if (paddingSize <= 0) { return inout; }
42 1
    assert(inout.size() < ValueEncoder::encodedIntSize);
43 1
    Data res(paddingSize); // padding on left
44 1
    append(res, inout);
45 1
    return res;
46
}
47

48 1
void ValueEncoder::encodeUInt256(const uint256_t& value, Data& inout) {
49 1
    append(inout, paddedOnLeft(store(value)));
50
}
51

52
/// Encoding primitive: encode a number of bytes by taking hash
53 1
inline void encodeBytesWithHash(const byte* data, size_t length, Data& inout) {
54 1
    Data res = Hash::keccak256(data, length);
55 1
    assert(res.size() == ValueEncoder::encodedIntSize);
56 1
    append(inout, res);
57
}
58

59 1
void ValueEncoder::encodeAddress(const Data& value, Data& inout) {
60 1
    const Address address(value);
61 1
    append(inout, paddedOnLeft(data(address.bytes.data(), address.bytes.size())));
62
}
63

64 1
void ValueEncoder::encodeString(const std::string& value, Data& inout) {
65 1
    Data valueData = data(value);
66 1
    encodeBytesWithHash(valueData.data(), valueData.size(), inout);
67
}
68

69 1
void ValueEncoder::encodeBytes(const Data& value, Data& inout) {
70 1
    auto len = value.size();
71 1
    if (len > encodedIntSize) {
72
        // too long, truncating
73 1
        len = encodedIntSize;
74
    }
75 1
    assert(len <= encodedIntSize);
76 1
    append(inout, Data(encodedIntSize));
77 1
    std::copy(value.begin(), value.begin() + len, inout.end() - encodedIntSize);
78
    // note: padded on right
79
}
80

81 1
void ValueEncoder::encodeBytesDyn(const Data& value, Data& inout) {
82 1
    encodeBytesWithHash(value.data(), value.size(), inout);
83
}
84

85 1
int256_t ValueEncoder::int256FromUint256(uint256_t x) {
86
    static const uint256_t maxNeg = uint256_t(1) << 255;
87 1
    if (x <= maxNeg) { return static_cast<int256_t>(x); }
88 1
    return -(static_cast<int256_t>(~x)) - 1;
89
}
90

91 1
uint256_t ValueEncoder::uint256FromInt256(int256_t x) {
92 1
    if (x >= 0) { return static_cast<uint256_t>(x); }
93 1
    return ~static_cast<uint256_t>(-(x + 1));
94
}
95

96
} // namespace TW::Ethereum::ABI

Read our documentation on viewing source code .

Loading