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::PaymentAddress zaddr;
43 PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
46 PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::PaymentAddress 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, int nType, int nVersion) {
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
79 size_t js; // Index into CTransaction.vjoinsplit
81 uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
82 libzcash::PaymentAddress zaddr; // zcash/Address.hpp
83 std::string message; // parameter to RPC call
85 ADD_SERIALIZE_METHODS;
87 template <typename Stream, typename Operation>
88 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
99 std::string ToString() const;
101 friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
103 a.version == b.version &&
108 a.zaddr == b.zaddr &&
109 a.message == b.message
113 friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
118 struct PaymentDisclosure {
119 PaymentDisclosurePayload payload;
120 boost::array<unsigned char, 64> payloadSig;
121 // We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64];
123 PaymentDisclosure() {};
124 PaymentDisclosure(const PaymentDisclosurePayload payload, const boost::array<unsigned char, 64> sig) : payload(payload), payloadSig(sig) {};
125 PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message);
127 ADD_SERIALIZE_METHODS;
129 template <typename Stream, typename Operation>
130 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
132 READWRITE(payloadSig);
135 std::string ToString() const;
137 friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) {
138 return (a.payload == b.payload && a.payloadSig == b.payloadSig);
141 friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) {
148 typedef std::pair<PaymentDisclosureKey, PaymentDisclosureInfo> PaymentDisclosureKeyInfo;
151 #endif // ZCASH_PAYMENTDISCLOSURE_H