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 "Transaction.h"
8
#include "BinaryCoding.h"
9
#include "../Base58.h"
10
#include "../BinaryCoding.h"
11
#include "../HexCoding.h"
12

13
using namespace TW;
14
using namespace TW::Waves;
15

16
using json = nlohmann::json;
17

18 1
const std::string Transaction::WAVES = "WAVES";
19

20 1
Data serializeTransfer(int64_t amount, std::string asset, int64_t fee, std::string fee_asset, Address to, const Data& attachment, int64_t timestamp, const Data& pub_key) {
21 1
    auto data = Data();
22 1
    if (asset.empty()) {
23 1
      asset = Transaction::WAVES;
24
    }
25 1
    if (fee_asset.empty()) {
26 0
        fee_asset = Transaction::WAVES;
27
    }
28 1
    data.resize(2);
29 1
    data[0] = static_cast<byte>(TransactionType::transfer);
30 1
    data[1] = static_cast<byte>(TransactionVersion::V2);
31 1
    append(data, pub_key);
32 1
    if (asset == Transaction::WAVES) {
33 1
        data.push_back(static_cast<uint8_t>(0));
34 1
    } else {
35 1
        data.push_back(static_cast<uint8_t>(1));
36 1
        append(data, Base58::bitcoin.decode(asset));
37
    }
38 1
    if (fee_asset == Transaction::WAVES) {
39 1
        data.push_back(static_cast<uint8_t>(0));
40 1
    } else {
41 1
        data.push_back(static_cast<uint8_t>(1));
42 1
        append(data, Base58::bitcoin.decode(fee_asset));
43
    }
44 1
    encode64BE(timestamp, data);
45 1
    encode64BE(amount, data);
46 1
    encode64BE(fee, data);
47 1
    append(data, Data(std::begin(to.bytes), std::end(to.bytes)));
48 1
    encodeDynamicLengthBytes(attachment, data);
49
    
50 1
    return data;
51
}
52

53 1
Data serializeLease(int64_t amount, int64_t fee, Address to, int64_t timestamp, const Data& pub_key) {
54 1
    auto data = Data();
55 1
    data.resize(2);
56 1
    data[0] = static_cast<byte>(TransactionType::lease);
57 1
    data[1] = static_cast<byte>(TransactionVersion::V2);
58 1
    data.push_back(static_cast<uint8_t>(0));
59 1
    append(data, pub_key);
60 1
    append(data, Data(std::begin(to.bytes), std::end(to.bytes)));
61 1
    encode64BE(amount, data);
62 1
    encode64BE(fee, data);
63 1
    encode64BE(timestamp, data);
64
    
65 1
    return data;
66
}
67

68 1
Data serializeCancelLease(const Data& leaseId, int64_t fee, int64_t timestamp, const Data& pub_key) {
69 1
    auto data = Data();
70 1
    data.resize(2);
71 1
    data[0] = static_cast<byte>(TransactionType::cancelLease);
72 1
    data[1] = static_cast<byte>(TransactionVersion::V2);
73 1
    data.push_back(static_cast<uint8_t>(87));
74 1
    append(data, pub_key);
75 1
    encode64BE(fee, data);
76 1
    encode64BE(timestamp, data);
77 1
    append(data, leaseId);
78
    
79 1
    return data;
80
}
81

82 1
json jsonTransfer(const Data& signature, int64_t amount, const std::string& asset, int64_t fee, const std::string& fee_asset, Address to, const Data& attachment, int64_t timestamp, const Data& pub_key) {
83 1
    json jsonTx;
84
    
85 1
    jsonTx["type"] = TransactionType::transfer;
86 1
    jsonTx["version"] = TransactionVersion::V2;
87 1
    jsonTx["fee"] = fee;
88 1
    jsonTx["senderPublicKey"] = Base58::bitcoin.encode(pub_key);
89 1
    jsonTx["timestamp"] = timestamp;
90 1
    jsonTx["proofs"] = json::array({Base58::bitcoin.encode(signature)});
91 1
    jsonTx["recipient"] = Address(to).string();
92 1
    if (asset != Transaction::WAVES) {
93 1
        jsonTx["assetId"] = asset;
94
    }
95 1
    if (fee_asset != Transaction::WAVES) {
96 1
        jsonTx["feeAssetId"] = fee_asset;
97
    }
98 1
    jsonTx["amount"] = amount;
99 1
    jsonTx["attachment"] = Base58::bitcoin.encode(attachment);
100
    
101 1
    return jsonTx;
102
}
103

104 1
json jsonLease(const Data& signature, int64_t amount, int64_t fee, Address to, int64_t timestamp, const Data& pub_key) {
105 1
    json jsonTx;
106
    
107 1
    jsonTx["type"] = TransactionType::lease;
108 1
    jsonTx["version"] = TransactionVersion::V2;
109 1
    jsonTx["fee"] = fee;
110 1
    jsonTx["senderPublicKey"] = Base58::bitcoin.encode(pub_key);
111 1
    jsonTx["timestamp"] = timestamp;
112 1
    jsonTx["proofs"] = json::array({Base58::bitcoin.encode(signature)});
113 1
    jsonTx["recipient"] = Address(to).string();
114 1
    jsonTx["amount"] = amount;
115
    
116 1
    return jsonTx;
117
}
118

119 1
json jsonCancelLease(const Data& signature, const Data& leaseId, int64_t fee, int64_t timestamp, const Data& pub_key) {
120 1
    json jsonTx;
121
    
122 1
    jsonTx["type"] = TransactionType::cancelLease;
123 1
    jsonTx["version"] = TransactionVersion::V2;
124 1
    jsonTx["fee"] = fee;
125 1
    jsonTx["senderPublicKey"] = Base58::bitcoin.encode(pub_key);
126 1
    jsonTx["leaseId"] = Base58::bitcoin.encode(leaseId);
127 1
    jsonTx["chainId"] = 87; // mainnet
128 1
    jsonTx["timestamp"] = timestamp;
129 1
    jsonTx["proofs"] = json::array({Base58::bitcoin.encode(signature)});
130
    
131 1
    return jsonTx;
132
}
133

134 1
Data Transaction::serializeToSign() const {
135 1
    if (pub_key.empty()) {
136 1
        throw std::invalid_argument("Public key can't be empty");
137
    }
138 1
    if (input.has_transfer_message()) {
139 1
        auto message = input.transfer_message();
140
        auto attachment =
141 1
            Data(message.attachment().begin(), message.attachment().end());
142 1
        if (attachment.size() > 140) {
143 1
            throw std::invalid_argument("Maximum attachment size is 140 bytes");
144
        }
145 1
        return serializeTransfer(message.amount(), message.asset(),
146 1
                                 message.fee(), message.fee_asset(),
147 1
                                 Address(message.to()), attachment,
148 1
                                 input.timestamp(), pub_key);
149 1
    } else if (input.has_lease_message()) {
150 1
        auto message = input.lease_message();
151 1
        return serializeLease(message.amount(), message.fee(), Address(message.to()), input.timestamp(), pub_key);
152 1
    } else if (input.has_cancel_lease_message()) {
153 1
        auto message = input.cancel_lease_message();
154 1
        auto leaseId = Base58::bitcoin.decode(message.lease_id());
155 1
        return serializeCancelLease(leaseId, message.fee(), input.timestamp(), pub_key);
156
    }
157
    
158 0
    return Data();
159
}
160

161

162

163

164

165 1
json Transaction::buildJson(const Data& signature) const {
166 1
    if (input.has_transfer_message()) {
167 1
        auto message = input.transfer_message();
168 1
        auto attachment = Data(message.attachment().begin(), message.attachment().end());
169 1
        return jsonTransfer(
170 1
                            signature,
171 1
                            message.amount(),
172 1
                            message.asset(),
173 1
                            message.fee(),
174 1
                            message.fee_asset(),
175 1
                            Address(message.to()),
176
                            attachment,
177 1
                            input.timestamp(),
178 1
                            pub_key);
179 1
    } else if (input.has_lease_message()) {
180 1
        auto message = input.lease_message();
181 1
        return jsonLease(
182 1
                            signature,
183 1
                            message.amount(),
184 1
                            message.fee(),
185 1
                            Address(message.to()),
186 1
                            input.timestamp(),
187 1
                            pub_key);
188 1
    } else if (input.has_cancel_lease_message()) {
189 1
        auto message = input.cancel_lease_message();
190 1
        auto leaseId = Base58::bitcoin.decode(message.lease_id());
191 1
        return jsonCancelLease(
192 1
                            signature,
193
                            leaseId,
194 1
                            message.fee(),
195 1
                            input.timestamp(),
196 1
                            pub_key);
197
    }
198 0
    return nullptr;
199
}
200

201

202

Read our documentation on viewing source code .

Loading