1 // Copyright (c) 2017 The Zcash developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://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"
21 // Ensure that the two different protocol messages, payment disclosure blobs and transactions,
22 // which are signed with the same key, joinSplitPrivKey, have disjoint encodings such that an
23 // encoding from one context will be rejected in the other. We know that the set of valid
24 // transaction versions is currently ({1..INT32_MAX}) so we will use a negative value for
25 // payment disclosure of -10328976 which in hex is 0xFF626470. Serialization is in little endian
26 // format, so a payment disclosure hex string begins 706462FF, which in ISO-8859-1 is "pdbÿ".
27 #define PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES -10328976
29 #define PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL 0
31 #define PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX "zpd:"
33 typedef JSOutPoint PaymentDisclosureKey;
35 struct PaymentDisclosureInfo {
36 uint8_t version; // 0 = experimental, 1 = first production version, etc.
37 uint256 esk; // zcash/NoteEncryption.cpp
38 uint256 joinSplitPrivKey; // primitives/transaction.h
39 // ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
41 libzcash::SproutPaymentAddress zaddr;
43 PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
46 PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
48 ADD_SERIALIZE_METHODS;
50 template <typename Stream, typename Operation>
51 inline void SerializationOp(Stream& s, Operation ser_action) {
54 READWRITE(joinSplitPrivKey);
58 std::string ToString() const;
60 friend bool operator==(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
61 return (a.version == b.version && a.esk == b.esk && a.joinSplitPrivKey == b.joinSplitPrivKey && a.zaddr == b.zaddr);
64 friend bool operator!=(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
71 struct PaymentDisclosurePayload {
72 int32_t marker = PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES; // to be disjoint from transaction encoding
73 uint8_t version; // 0 = experimental, 1 = first production version, etc.
74 uint256 esk; // zcash/NoteEncryption.cpp
75 uint256 txid; // primitives/transaction.h
76 uint64_t js; // Index into CTransaction.vjoinsplit
77 uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
78 libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp
79 std::string message; // parameter to RPC call
81 ADD_SERIALIZE_METHODS;
83 template <typename Stream, typename Operation>
84 inline void SerializationOp(Stream& s, Operation ser_action) {
95 std::string ToString() const;
97 friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
99 a.version == b.version &&
104 a.zaddr == b.zaddr &&
105 a.message == b.message
109 friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
114 struct PaymentDisclosure {
115 PaymentDisclosurePayload payload;
116 boost::array<unsigned char, 64> payloadSig;
117 // We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64];
119 PaymentDisclosure() {};
120 PaymentDisclosure(const PaymentDisclosurePayload payload, const boost::array<unsigned char, 64> sig) : payload(payload), payloadSig(sig) {};
121 PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message);
123 ADD_SERIALIZE_METHODS;
125 template <typename Stream, typename Operation>
126 inline void SerializationOp(Stream& s, Operation ser_action) {
128 READWRITE(payloadSig);
131 std::string ToString() const;
133 friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) {
134 return (a.payload == b.payload && a.payloadSig == b.payloadSig);
137 friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) {
144 typedef std::pair<PaymentDisclosureKey, PaymentDisclosureInfo> PaymentDisclosureKeyInfo;
147 #endif // ZCASH_PAYMENTDISCLOSURE_H