UNPKG

zcash-block

Version:

A Zcash block interface and decoder for JavaScript

131 lines (115 loc) 5.49 kB
const { decodeProperties } = require('./class-utils') const SAPLING_TX_VERSION = 4 /** * A class representation of a Zcash Transaction's joinsplit, which may or may not be present for a given transaction. * * This class isn't explicitly exported, access it for direct use with `require('zcash-block/classes/JoinSplitDescription')`. * * @property {BigInt} vpubOld - a representation of an amount / value * @property {BigInt} vpubNew - a representation of an amount / value * @property {Uint8Array|Buffer} anchor - a 256-bit hash anchoring the joinsplit's position in the commitment tree * @property {Array.<Uint8Array>|Array.<Buffer>} nullifiers - two 256-bit blocks derived from secrets in the note * @property {Array.<Uint8Array>|Array.<Buffer>} commitments - two 256-bit blocks representing the spend commitments * @property {Uint8Array|Buffer} ephemeralKey - a 256-bit hash * @property {Uint8Array|Buffer} randomSeed - - a 256-bit block * @property {Array.<Uint8Array>|Array.<Buffer>} macs - two 256-bit hashes required to verify this joinsplit * @property {Uint8Array|Buffer|PHGRProof} sproutProof - either a GrothProof encoded directly as 192 bytes of binary data or a decoded {@link PHGRProof}, depending on the block version. * @property {Uint8Array|Buffer} ciphertexts - two ciphertexts of 601 bytes each which encode trapdoors, values and other information that the recipient needs, including a memo field. * @class */ class ZcashJoinSplitDescription { /** * Instantiate a new `ZcashJoinSplitDescription`. * * See the class properties for expanded information on these parameters. * * @param {BigInt} vpubOld * @param {BigInt} vpubNew * @param {Uint8Array|Buffer} anchor * @param {Array.<Uint8Array>|Array.<Buffer>} nullifiers * @param {Array.<Uint8Array>|Array.<Buffer>} commitments * @param {Uint8Array|Buffer} ephemeralKey * @param {Uint8Array|Buffer} randomSeed * @param {Array.<Uint8Array>|Array.<Buffer>} macs * @param {Uint8Array|Buffer|PHGRProof} sproutProof * @param {Uint8Array|Buffer} ciphertexts * @constructs ZcashJoinSplitDescription */ constructor (vpubOld, vpubNew, anchor, nullifiers, commitments, ephemeralKey, randomSeed, macs, sproutProof, ciphertexts) { this.vpubOld = vpubOld this.vpubNew = vpubNew this.anchor = anchor this.nullifiers = nullifiers this.commitments = commitments this.ephemeralKey = ephemeralKey this.randomSeed = randomSeed this.macs = macs this.sproutProof = sproutProof this.ciphertexts = ciphertexts } /** * Convert to a serializable form that has nice stringified hashes and other simplified forms. May be * useful for simplified inspection. */ toJSON () { return Object.assign({}, this, { vpubOld: Number(this.vpubOld), vpubNew: Number(this.vpubNew) }) } } // ------------------------------------------------------------------------------------------------------- // Custom decoder descriptors and functions below here, used by ../decoder.js ZcashJoinSplitDescription._nativeName = 'JSDescription' // https://github.com/zcash/zcash/blob/6da42887f10f9228da4c8c1182174d70b2633284/src/primitives/transaction.h#L179 ZcashJoinSplitDescription._propertiesDescriptor = decodeProperties(` CAmount vpub_old; CAmount vpub_new; // JoinSplits are always anchored to a root in the note // commitment tree at some point in the blockchain // history or in the history of the current // transaction. uint256 anchor; // Nullifiers are used to prevent double-spends. They // are derived from the secrets placed in the note // and the secret spend-authority key known by the // spender. std::array<uint256, 2> nullifiers; // Note commitments are introduced into the commitment // tree, blinding the public about the values and // destinations involved in the JoinSplit. The presence of // a commitment in the note commitment tree is required // to spend it. std::array<uint256, 2> commitments; // Ephemeral key uint256 ephemeralKey; // Random seed uint256 randomSeed; // MACs // The verification of the JoinSplit requires these MACs // to be provided as an input. std::array<uint256, 2> macs; // JoinSplit proof // This is a zk-SNARK which ensures that this JoinSplit is valid. //libzcash::SproutProof proof; _customDecodeSproutProof // Ciphertexts // These contain trapdoors, values and other information // that the recipient needs, including a memo field. It // is encrypted using the scheme implemented in crypto/NoteEncryption.cpp std::array<ZCNoteEncryption::Ciphertext, 2> ciphertexts `) // libzcash::SproutProof is a boost::variant<PHGRProof, GrothProof> (boost::varint is a union container) // custom serialization occurs @ https://github.com/zcash/zcash/blob/6da42887f10f9228da4c8c1182174d70b2633284/src/primitives/transaction.h#L276-L286 // and https://github.com/zcash/zcash/blob/6da42887f10f9228da4c8c1182174d70b2633284/src/primitives/transaction.h#L166-L177 // typedef std::array<unsigned char, GROTH_PROOF_SIZE> GrothProof; ZcashJoinSplitDescription._customDecodeSproutProof = function (decoder, properties, state) { const useGroth = state.fOverwintered && state.nVersion >= SAPLING_TX_VERSION // if useGroth, unserialize as libzcash::GrothProof, otherwise as libzcash::PHGRProof if (useGroth) { properties.push(decoder.readType('libzcash::GrothProof')) } else { properties.push(decoder.readType('PHGRProof')) } } module.exports = ZcashJoinSplitDescription