1 // Copyright (c) 2017 The Zcash developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
5 #ifndef ZCASH_PAYMENTDISCLOSURE_H
6 #define ZCASH_PAYMENTDISCLOSURE_H
9 #include "clientversion.h"
10 #include "serialize.h"
15 #include "wallet/wallet.h"
22 // Ensure that the two different protocol messages, payment disclosure blobs and transactions,
23 // which are signed with the same key, joinSplitPrivKey, have disjoint encodings such that an
24 // encoding from one context will be rejected in the other. We know that the set of valid
25 // transaction versions is currently ({1..INT32_MAX}) so we will use a negative value for
26 // payment disclosure of -10328976 which in hex is 0xFF626470. Serialization is in little endian
27 // format, so a payment disclosure hex string begins 706462FF, which in ISO-8859-1 is "pdbÿ".
28 #define PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES -10328976
30 #define PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL 0
32 #define PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX "zpd:"
34 typedef JSOutPoint PaymentDisclosureKey;
36 struct PaymentDisclosureInfo {
37 uint8_t version; // 0 = experimental, 1 = first production version, etc.
38 uint256 esk; // zcash/NoteEncryption.cpp
39 uint256 joinSplitPrivKey; // primitives/transaction.h
40 // ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
42 libzcash::SproutPaymentAddress zaddr;
44 PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
47 PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
49 ADD_SERIALIZE_METHODS;
51 template <typename Stream, typename Operation>
52 inline void SerializationOp(Stream& s, Operation ser_action) {
55 READWRITE(joinSplitPrivKey);
59 std::string ToString() const;
61 friend bool operator==(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
62 return (a.version == b.version && a.esk == b.esk && a.joinSplitPrivKey == b.joinSplitPrivKey && a.zaddr == b.zaddr);
65 friend bool operator!=(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
72 struct PaymentDisclosurePayload {
73 int32_t marker = PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES; // to be disjoint from transaction encoding
74 uint8_t version; // 0 = experimental, 1 = first production version, etc.
75 uint256 esk; // zcash/NoteEncryption.cpp
76 uint256 txid; // primitives/transaction.h
77 uint64_t js; // Index into CTransaction.vJoinSplit
78 uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
79 libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp
80 std::string message; // parameter to RPC call
82 ADD_SERIALIZE_METHODS;
84 template <typename Stream, typename Operation>
85 inline void SerializationOp(Stream& s, Operation ser_action) {
96 std::string ToString() const;
98 friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
100 a.version == b.version &&
105 a.zaddr == b.zaddr &&
106 a.message == b.message
110 friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
115 struct PaymentDisclosure {
116 PaymentDisclosurePayload payload;
117 std::array<unsigned char, 64> payloadSig;
118 // We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64];
120 PaymentDisclosure() {};
121 PaymentDisclosure(const PaymentDisclosurePayload payload, const std::array<unsigned char, 64> sig) : payload(payload), payloadSig(sig) {};
122 PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message);
124 ADD_SERIALIZE_METHODS;
126 template <typename Stream, typename Operation>
127 inline void SerializationOp(Stream& s, Operation ser_action) {
129 READWRITE(payloadSig);
132 std::string ToString() const;
134 friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) {
135 return (a.payload == b.payload && a.payloadSig == b.payloadSig);
138 friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) {
145 typedef std::pair<PaymentDisclosureKey, PaymentDisclosureInfo> PaymentDisclosureKeyInfo;
148 #endif // ZCASH_PAYMENTDISCLOSURE_H