mirror of https://github.com/zcash/zips.git
479 lines
70 KiB
HTML
479 lines
70 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ZIP 143: Transaction Signature Validation for Overwinter</title>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="css/style.css"></head>
|
|
<body>
|
|
<section>
|
|
<pre>ZIP: 143
|
|
Title: Transaction Signature Validation for Overwinter
|
|
Owners: Jack Grigg <str4d@electriccoin.co>
|
|
Daira Hopwood <daira@electriccoin.co>
|
|
Credits: Johnson Lau
|
|
Pieter Wuille
|
|
Bitcoin-ABC
|
|
Status: Final
|
|
Category: Consensus
|
|
Created: 2017-12-27
|
|
License: MIT</pre>
|
|
<section id="terminology"><h2><span class="section-heading">Terminology</span><span class="section-anchor"> <a rel="bookmark" href="#terminology"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>The key words "MUST" and "MUST NOT" in this document are to be interpreted as described in RFC 2119. <a id="id1" class="footnote_reference" href="#rfc2119">1</a></p>
|
|
<p>The terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. <a id="id2" class="footnote_reference" href="#zip-0200">10</a></p>
|
|
<p>The term "Overwinter" in this document is to be interpreted as described in ZIP 201. <a id="id3" class="footnote_reference" href="#zip-0201">11</a></p>
|
|
</section>
|
|
<section id="abstract"><h2><span class="section-heading">Abstract</span><span class="section-anchor"> <a rel="bookmark" href="#abstract"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>This proposal defines a new transaction digest algorithm for signature validation from the Overwinter network upgrade, in order to minimize redundant data hashing in validation, and to cover the input value by the signature.</p>
|
|
</section>
|
|
<section id="motivation"><h2><span class="section-heading">Motivation</span><span class="section-anchor"> <a rel="bookmark" href="#motivation"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>There are 4 ECDSA signature validation operations in the original Zcash script system: <code>CHECKSIG</code>, <code>CHECKSIGVERIFY</code>, <code>CHECKMULTISIG</code>, <code>CHECKMULTISIGVERIFY</code> ("sigops"). According to the sighash type (<code>ALL</code>, <code>NONE</code>, or <code>SINGLE</code>, possibly modified by <code>ANYONECANPAY</code>), a transaction digest is generated with a double SHA256 of a serialized subset of the transaction, and the signature is validated against this digest with a given public key. The detailed procedure is described in a Bitcoin Wiki article. <a id="id4" class="footnote_reference" href="#wiki-checksig">3</a> The transaction digest is additionally used for the JoinSplit signature (solely with sighash type <code>ALL</code>). <a id="id5" class="footnote_reference" href="#protocol-sproutsend">2</a></p>
|
|
<p>Unfortunately, there are at least 2 weaknesses in the original SignatureHash transaction digest algorithm:</p>
|
|
<ul>
|
|
<li>For the validation of each signature, the amount of data hashing is proportional to the size of the transaction. Therefore, data hashing grows in O(n<sup>2</sup>) as the number of sigops in a transaction increases. While a 1 MB block would normally take 2 seconds to validate with an average computer in 2015, a 1MB transaction with 5569 sigops may take 25 seconds to validate. This could be fixed by optimizing the digest algorithm by introducing some reusable "midstate", so the time complexity becomes O(n). <a id="id6" class="footnote_reference" href="#quadratic">4</a></li>
|
|
<li>The algorithm does not involve the value being spent by the input. This is usually not a problem for online network nodes as they could request for the specified transaction to acquire the output value. For an offline transaction signing device ("cold wallet"), however, the lack of knowledge of input amount makes it impossible to calculate the exact amount being spent and the transaction fee. To cope with this problem a cold wallet must also acquire the full transaction being spent, which could be a big obstacle in the implementation of a lightweight, air-gapped wallet. By including the input value of part of the transaction digest, a cold wallet may safely sign a transaction by learning the value from an untrusted source. In the case that a wrong value is provided and signed, the signature would be invalid and no funds would be lost. <a id="id7" class="footnote_reference" href="#offline-wallets">5</a></li>
|
|
</ul>
|
|
<p>Deploying the aforementioned fixes in the original script system is not a simple task.</p>
|
|
</section>
|
|
<section id="specification"><h2><span class="section-heading">Specification</span><span class="section-anchor"> <a rel="bookmark" href="#specification"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>A new transaction digest algorithm is defined:</p>
|
|
<pre>BLAKE2b-256 hash of the serialization of:
|
|
1. header of the transaction (4-byte little endian)
|
|
2. nVersionGroupId of the transaction (4-byte little endian)
|
|
3. hashPrevouts (32-byte hash)
|
|
4. hashSequence (32-byte hash)
|
|
5. hashOutputs (32-byte hash)
|
|
6. hashJoinSplits (32-byte hash)
|
|
7. nLockTime of the transaction (4-byte little endian)
|
|
8. nExpiryHeight of the transaction (4-byte little endian)
|
|
9. sighash type of the signature (4-byte little endian)
|
|
10. If we are serializing an input (i.e. this is not a JoinSplit signature hash):
|
|
a. outpoint (32-byte hash + 4-byte little endian)
|
|
b. scriptCode of the input (serialized as scripts inside CTxOuts)
|
|
c. value of the output spent by this input (8-byte little endian)
|
|
d. nSequence of the input (4-byte little endian)</pre>
|
|
<p>The new algorithm is based on the Bitcoin transaction digest algorithm defined in BIP 143, <a id="id8" class="footnote_reference" href="#bip-0143">6</a> with replay protection inspired by BUIP-HF v1.2. <a id="id9" class="footnote_reference" href="#buip-hf">7</a></p>
|
|
<p>The new algorithm MUST be used for signatures created over the Overwinter transaction format. <a id="id10" class="footnote_reference" href="#zip-0202">12</a> Combined with the new consensus rule that v1 and v2 transaction formats will be invalid from the Overwinter upgrade, <a id="id11" class="footnote_reference" href="#zip-0202">12</a> this effectively means that all transaction signatures from the Overwinter activation height will use the new algorithm. <a id="id12" class="footnote_reference" href="#zip-0201">11</a></p>
|
|
<p>The BLAKE2b-256 personalization field <a id="id13" class="footnote_reference" href="#blake2-personalization">8</a> is set to:</p>
|
|
<pre>"ZcashSigHash" || CONSENSUS_BRANCH_ID</pre>
|
|
<p><code>CONSENSUS_BRANCH_ID</code> is the 4-byte little-endian encoding of the consensus branch ID for the epoch of the block containing the transaction. <a id="id14" class="footnote_reference" href="#zip-0200">10</a> Domain separation of the signature hash across parallel consensus branches provides replay protection: transactions targeted for one consensus branch will have invalid signatures on other consensus branches.</p>
|
|
<p>Transaction creators MUST specify the epoch they want their transaction to be mined in. Across a network upgrade, this means that if a transaction is not mined before the activation height, it will never be mined.</p>
|
|
<p>Semantics of the original sighash types remain unchanged, except the following:</p>
|
|
<ol type="1">
|
|
<li>The serialization format is changed;</li>
|
|
<li>All sighash types commit to the amount being spent by the signed input;</li>
|
|
<li><code>SINGLE</code> does not commit to the input index. When <code>ANYONECANPAY</code> is not set, the semantics are unchanged since <code>hashPrevouts</code> and <code>outpoint</code> together implictly commit to the input index. When <code>SINGLE</code> is used with <code>ANYONECANPAY</code>, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index.</li>
|
|
</ol>
|
|
<section id="field-definitions"><h3><span class="section-heading">Field definitions</span><span class="section-anchor"> <a rel="bookmark" href="#field-definitions"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
|
|
<p>The items 7, 9, 10a, 10d have the same meaning as the original algorithm from Bitcoin. <a id="id15" class="footnote_reference" href="#wiki-checksig">3</a></p>
|
|
<section id="header"><h4><span class="section-heading">1: <code>header</code></span><span class="section-anchor"> <a rel="bookmark" href="#header"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<p>Deserialized into two transaction properties: <code>fOverwintered</code> and <code>nVersion</code>. For transactions that use this transaction digest algorithm, <code>fOverwintered</code> is always set. <a id="id16" class="footnote_reference" href="#zip-0202">12</a></p>
|
|
</section>
|
|
<section id="nversiongroupid"><h4><span class="section-heading">2: <code>nVersionGroupId</code></span><span class="section-anchor"> <a rel="bookmark" href="#nversiongroupid"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<p>Provides domain separation of <code>nVersion</code>. It is only defined if <code>fOverwintered</code> is set, which means that it is always defined for transactions that use this algorithm. <a id="id17" class="footnote_reference" href="#zip-0202">12</a></p>
|
|
</section>
|
|
<section id="hashprevouts"><h4><span class="section-heading">3: <code>hashPrevouts</code></span><span class="section-anchor"> <a rel="bookmark" href="#hashprevouts"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<ul>
|
|
<li>If the <code>ANYONECANPAY</code> flag is not set, <code>hashPrevouts</code> is the BLAKE2b-256 hash of the serialization of all input outpoints;
|
|
<ul>
|
|
<li>The BLAKE2b-256 personalization field is set to <code>ZcashPrevoutHash</code>.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Otherwise, <code>hashPrevouts</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
|
|
</ul>
|
|
</section>
|
|
<section id="hashsequence"><h4><span class="section-heading">4: <code>hashSequence</code></span><span class="section-anchor"> <a rel="bookmark" href="#hashsequence"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<ul>
|
|
<li>If none of the <code>ANYONECANPAY</code>, <code>SINGLE</code>, <code>NONE</code> sighash type is set, <code>hashSequence</code> is the BLAKE2b-256 hash of the serialization of <code>nSequence</code> of all inputs;
|
|
<ul>
|
|
<li>The BLAKE2b-256 personalization field is set to <code>ZcashSequencHash</code>.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Otherwise, <code>hashSequence</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
|
|
</ul>
|
|
<p>Note: the encoding of the sighash type is masked with <code>0x1F</code> when checking whether or not the <code>SINGLE</code> and <code>NONE</code> flags are set.</p>
|
|
</section>
|
|
<section id="hashoutputs"><h4><span class="section-heading">5: <code>hashOutputs</code></span><span class="section-anchor"> <a rel="bookmark" href="#hashoutputs"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<ul>
|
|
<li>If the sighash type is neither <code>SINGLE</code> nor <code>NONE</code>, <code>hashOutputs</code> is the BLAKE2b-256 hash of the serialization of all output amount (8-byte little endian) with <code>scriptPubKey</code> (serialized as scripts inside CTxOuts);</li>
|
|
<li>If sighash type is <code>SINGLE</code> and the input index is smaller than the number of outputs, <code>hashOutputs</code> is the BLAKE2b-256 hash of the output (serialized as above) with the same index as the input;
|
|
<ul>
|
|
<li>The BLAKE2b-256 personalization field is set to <code>ZcashOutputsHash</code> in both cases above.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Otherwise, <code>hashOutputs</code> is a <code>uint256</code> of <code>0x0000......0000</code>. <a id="id18" class="footnote_reference" href="#change">9</a></li>
|
|
</ul>
|
|
<p>Note: the encoding of the sighash type is masked with <code>0x1F</code> when checking whether or not the <cite>SINGLE`</cite> and <code>NONE</code> flags are set.</p>
|
|
</section>
|
|
<section id="hashjoinsplits"><h4><span class="section-heading">6: <code>hashJoinSplits</code></span><span class="section-anchor"> <a rel="bookmark" href="#hashjoinsplits"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<ul>
|
|
<li>If <code>vjoinsplits</code> is non-empty, <code>hashJoinSplits</code> is the BLAKE2b-256 hash of the serialization of all JoinSplits (in their canonical transaction serialization format) concatenated with the joinSplitPubKey;
|
|
<ul>
|
|
<li>The BLAKE2b-256 personalization field is set to <code>ZcashJSplitsHash</code>.</li>
|
|
<li>Note that while signatures are omitted, the JoinSplit proofs are included in the signature hash, as with v1 and v2 transactions.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Otherwise, <code>hashJoinSplits</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
|
|
</ul>
|
|
</section>
|
|
<section id="nexpiryheight"><h4><span class="section-heading">8: <code>nExpiryHeight</code></span><span class="section-anchor"> <a rel="bookmark" href="#nexpiryheight"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<p>The block height after which the transaction becomes unilaterally invalid, and can never be mined. <a id="id19" class="footnote_reference" href="#zip-0203">13</a></p>
|
|
</section>
|
|
<section id="b-scriptcode"><h4><span class="section-heading">10b: <code>scriptCode</code></span><span class="section-anchor"> <a rel="bookmark" href="#b-scriptcode"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<p>The script being currently executed: <code>redeemScript</code> for P2SH, or <code>scriptPubKey</code> in the general case. This is the same script as serialized in the Sprout transaction digest algorithm.</p>
|
|
</section>
|
|
<section id="c-value"><h4><span class="section-heading">10c: value</span><span class="section-anchor"> <a rel="bookmark" href="#c-value"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h4>
|
|
<p>An 8-byte little-endian value of the amount, in zatoshi, spent in this input.</p>
|
|
</section>
|
|
</section>
|
|
<section id="notes"><h3><span class="section-heading">Notes</span><span class="section-anchor"> <a rel="bookmark" href="#notes"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
|
|
<p>The <code>hashPrevouts</code>, <code>hashSequence</code>, <code>hashOutputs</code>, and <code>hashJoinSplits</code> calculated in an earlier validation can be reused in other inputs of the same transaction, so that the time complexity of the whole hashing process reduces from O(n<sup>2</sup>) to O(n).</p>
|
|
<p>Refer to the reference implementation, reproduced below, for the precise algorithm:</p>
|
|
<pre data-language="cpp"><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">ZCASH_PREVOUTS_HASH_PERSONALIZATION</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span>
|
|
<span class="p">{</span><span class="sc">'Z'</span><span class="p">,</span><span class="sc">'c'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">,</span><span class="sc">'P'</span><span class="p">,</span><span class="sc">'r'</span><span class="p">,</span><span class="sc">'e'</span><span class="p">,</span><span class="sc">'v'</span><span class="p">,</span><span class="sc">'o'</span><span class="p">,</span><span class="sc">'u'</span><span class="p">,</span><span class="sc">'t'</span><span class="p">,</span><span class="sc">'H'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">};</span>
|
|
<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">ZCASH_SEQUENCE_HASH_PERSONALIZATION</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span>
|
|
<span class="p">{</span><span class="sc">'Z'</span><span class="p">,</span><span class="sc">'c'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">,</span><span class="sc">'S'</span><span class="p">,</span><span class="sc">'e'</span><span class="p">,</span><span class="sc">'q'</span><span class="p">,</span><span class="sc">'u'</span><span class="p">,</span><span class="sc">'e'</span><span class="p">,</span><span class="sc">'n'</span><span class="p">,</span><span class="sc">'c'</span><span class="p">,</span><span class="sc">'H'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">};</span>
|
|
<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">ZCASH_OUTPUTS_HASH_PERSONALIZATION</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span>
|
|
<span class="p">{</span><span class="sc">'Z'</span><span class="p">,</span><span class="sc">'c'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">,</span><span class="sc">'O'</span><span class="p">,</span><span class="sc">'u'</span><span class="p">,</span><span class="sc">'t'</span><span class="p">,</span><span class="sc">'p'</span><span class="p">,</span><span class="sc">'u'</span><span class="p">,</span><span class="sc">'t'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'H'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">};</span>
|
|
<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">ZCASH_JOINSPLITS_HASH_PERSONALIZATION</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span>
|
|
<span class="p">{</span><span class="sc">'Z'</span><span class="p">,</span><span class="sc">'c'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">,</span><span class="sc">'J'</span><span class="p">,</span><span class="sc">'S'</span><span class="p">,</span><span class="sc">'p'</span><span class="p">,</span><span class="sc">'l'</span><span class="p">,</span><span class="sc">'i'</span><span class="p">,</span><span class="sc">'t'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'H'</span><span class="p">,</span><span class="sc">'a'</span><span class="p">,</span><span class="sc">'s'</span><span class="p">,</span><span class="sc">'h'</span><span class="p">};</span>
|
|
|
|
<span class="c1">// The default values are zeroes</span>
|
|
<span class="n">uint256</span> <span class="n">hashPrevouts</span><span class="p">;</span>
|
|
<span class="n">uint256</span> <span class="n">hashSequence</span><span class="p">;</span>
|
|
<span class="n">uint256</span> <span class="n">hashOutputs</span><span class="p">;</span>
|
|
<span class="n">uint256</span> <span class="n">hashJoinSplits</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">nHashType</span> <span class="o">&</span> <span class="n">SIGHASH_ANYONECANPAY</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="n">CBLAKE2bWriter</span> <span class="n">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ZCASH_PREVOUTS_HASH_PERSONALIZATION</span><span class="p">);</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">n</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">[</span><span class="n">n</span><span class="p">].</span><span class="n">prevout</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="n">hashPrevouts</span> <span class="o">=</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">nHashType</span> <span class="o">&</span> <span class="n">SIGHASH_ANYONECANPAY</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">nHashType</span> <span class="o">&</span> <span class="mh">0x1f</span><span class="p">)</span> <span class="o">!=</span> <span class="n">SIGHASH_SINGLE</span> <span class="o">&&</span> <span class="p">(</span><span class="n">nHashType</span> <span class="o">&</span> <span class="mh">0x1f</span><span class="p">)</span> <span class="o">!=</span> <span class="n">SIGHASH_NONE</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">CBLAKE2bWriter</span> <span class="n">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ZCASH_SEQUENCE_HASH_PERSONALIZATION</span><span class="p">);</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">n</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">[</span><span class="n">n</span><span class="p">].</span><span class="n">nSequence</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="n">hashSequence</span> <span class="o">=</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="p">((</span><span class="n">nHashType</span> <span class="o">&</span> <span class="mh">0x1f</span><span class="p">)</span> <span class="o">!=</span> <span class="n">SIGHASH_SINGLE</span> <span class="o">&&</span> <span class="p">(</span><span class="n">nHashType</span> <span class="o">&</span> <span class="mh">0x1f</span><span class="p">)</span> <span class="o">!=</span> <span class="n">SIGHASH_NONE</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">CBLAKE2bWriter</span> <span class="n">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ZCASH_OUTPUTS_HASH_PERSONALIZATION</span><span class="p">);</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vout</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">n</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vout</span><span class="p">[</span><span class="n">n</span><span class="p">];</span>
|
|
<span class="p">}</span>
|
|
<span class="n">hashOutputs</span> <span class="o">=</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">nHashType</span> <span class="o">&</span> <span class="mh">0x1f</span><span class="p">)</span> <span class="o">==</span> <span class="n">SIGHASH_SINGLE</span> <span class="o">&&</span> <span class="n">nIn</span> <span class="o"><</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vout</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="p">{</span>
|
|
<span class="n">CBLAKE2bWriter</span> <span class="n">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ZCASH_OUTPUTS_HASH_PERSONALIZATION</span><span class="p">);</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vout</span><span class="p">[</span><span class="n">nIn</span><span class="p">];</span>
|
|
<span class="n">hashOutputs</span> <span class="o">=</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">txTo</span><span class="p">.</span><span class="n">vjoinsplit</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
|
|
<span class="n">CBLAKE2bWriter</span> <span class="n">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ZCASH_JOINSPLITS_HASH_PERSONALIZATION</span><span class="p">);</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vjoinsplit</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">n</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vjoinsplit</span><span class="p">[</span><span class="n">n</span><span class="p">];</span>
|
|
<span class="p">}</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">joinSplitPubKey</span><span class="p">;</span>
|
|
<span class="n">hashJoinSplits</span> <span class="o">=</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kt">uint32_t</span> <span class="n">leConsensusBranchId</span> <span class="o">=</span> <span class="n">htole32</span><span class="p">(</span><span class="n">consensusBranchId</span><span class="p">);</span>
|
|
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">personalization</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{};</span>
|
|
<span class="n">memcpy</span><span class="p">(</span><span class="n">personalization</span><span class="p">,</span> <span class="s">"ZcashSigHash"</span><span class="p">,</span> <span class="mi">12</span><span class="p">);</span>
|
|
<span class="n">memcpy</span><span class="p">(</span><span class="n">personalization</span><span class="o">+</span><span class="mi">12</span><span class="p">,</span> <span class="o">&</span><span class="n">leConsensusBranchId</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
|
|
|
|
<span class="n">CBLAKE2bWriter</span> <span class="nf">ss</span><span class="p">(</span><span class="n">SER_GETHASH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">personalization</span><span class="p">);</span>
|
|
<span class="c1">// fOverwintered and nVersion</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">GetHeader</span><span class="p">();</span>
|
|
<span class="c1">// Version group ID</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">nVersionGroupId</span><span class="p">;</span>
|
|
<span class="c1">// Input prevouts/nSequence (none/all, depending on flags)</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">hashPrevouts</span><span class="p">;</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">hashSequence</span><span class="p">;</span>
|
|
<span class="c1">// Outputs (none/one/all, depending on flags)</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">hashOutputs</span><span class="p">;</span>
|
|
<span class="c1">// JoinSplits</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">hashJoinSplits</span><span class="p">;</span>
|
|
<span class="c1">// Locktime</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">nLockTime</span><span class="p">;</span>
|
|
<span class="c1">// Expiry height</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">nExpiryHeight</span><span class="p">;</span>
|
|
<span class="c1">// Sighash type</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">nHashType</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">nIn</span> <span class="o">!=</span> <span class="n">NOT_AN_INPUT</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="c1">// The input being signed (replacing the scriptSig with scriptCode + amount)</span>
|
|
<span class="c1">// The prevout may already be contained in hashPrevout, and the nSequence</span>
|
|
<span class="c1">// may already be contained in hashSequence.</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">[</span><span class="n">nIn</span><span class="p">].</span><span class="n">prevout</span><span class="p">;</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="k">static_cast</span><span class="o"><</span><span class="k">const</span> <span class="n">CScriptBase</span><span class="o">&></span><span class="p">(</span><span class="n">scriptCode</span><span class="p">);</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">amount</span><span class="p">;</span>
|
|
<span class="n">ss</span> <span class="o"><<</span> <span class="n">txTo</span><span class="p">.</span><span class="n">vin</span><span class="p">[</span><span class="n">nIn</span><span class="p">].</span><span class="n">nSequence</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">return</span> <span class="n">ss</span><span class="p">.</span><span class="n">GetHash</span><span class="p">();</span></pre>
|
|
</section>
|
|
</section>
|
|
<section id="example"><h2><span class="section-heading">Example</span><span class="section-anchor"> <a rel="bookmark" href="#example"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>To ensure consistency in consensus-critical behaviour, developers should test their implementations against the ZIP 143 test vectors <a id="id20" class="footnote_reference" href="#test-vectors">14</a>. The first two test vectors are broken out below for clarity. Note that 32-byte values below are exactly as the hash function returns, and are not reversed. Further examples can be found in the SignatureHash test data <a id="id21" class="footnote_reference" href="#sighash-tests">15</a>.</p>
|
|
<p>The test vectors below should be verified with the Overwinter consensus branch ID (0x5ba81b19) <a id="id22" class="footnote_reference" href="#zip-0201">11</a>.</p>
|
|
<section id="test-vector-1"><h3><span class="section-heading">Test vector 1</span><span class="section-anchor"> <a rel="bookmark" href="#test-vector-1"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
|
|
<p>Raw transaction:</p>
|
|
<pre>030000807082c4030002e7719811893e0000095200ac6551ac636565b2835a0805750200025151481cdd86b3cc431800
|
|
|
|
header: 03000080
|
|
nVersionGroupId: 7082c403
|
|
vin: 00
|
|
vout: 02 e7719811893e0000 095200ac6551ac636565
|
|
b2835a0805750200 025151
|
|
nLockTime: 481cdd86
|
|
nExpiryHeight: b3cc4318
|
|
vJoinSplits: 00</pre>
|
|
<p>Transaction digest with <code>nIn = NOT_AN_INPUT</code> and <code>nHashType = 1</code> (<code>SIGHASH_ALL</code>):</p>
|
|
<pre>hashPrevouts:
|
|
BLAKE2b-256('ZcashPrevoutHash', b'')
|
|
= d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
|
|
|
|
hashSequence:
|
|
BLAKE2b-256('ZcashSequencHash', b'')
|
|
= a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
|
|
|
|
hashOutputs:
|
|
BLAKE2b-256('ZcashOutputsHash', e7719811893e0000095200ac6551ac636565b2835a0805750200025151)
|
|
= ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
|
|
|
|
Preimage:
|
|
030000807082c403d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a0000000000000000000000000000000000000000000000000000000000000000481cdd86b3cc431801000000
|
|
|
|
header: 03000080
|
|
nVersionGroupId: 7082c403
|
|
hashPrevouts: d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
|
|
hashSequence: a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
|
|
hashOutputs: ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
|
|
hashJoinSplits: 0000000000000000000000000000000000000000000000000000000000000000
|
|
nLockTime: 481cdd86
|
|
nExpiryHeight: b3cc4318
|
|
nHashType: 01000000
|
|
|
|
sighash: a1f1a4e5cd9bd522322d661edd2af1bf2a7019cfab94ece18f4ba935b0a19073</pre>
|
|
</section>
|
|
<section id="test-vector-2"><h3><span class="section-heading">Test vector 2</span><span class="section-anchor"> <a rel="bookmark" href="#test-vector-2"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
|
|
<p>Raw transaction:</p>
|
|
<pre>030000807082c403024201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a703ac6a0098421c69378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7056363635353e8c7203d02d2da86387ae60100080063656a63ac5200a7622997f4ff0400075151005353656597b0e4e4c705fc05020000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a70339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952
|
|
|
|
header: 03000080
|
|
nVersionGroupId: 7082c403
|
|
vin: 02 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e2 9d4e30a7 03ac6a00 98421c69
|
|
378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7 056363635353 e8c7203d
|
|
vout: 02 d2da86387ae60100 080063656a63ac5200
|
|
a7622997f4ff0400 0751510053536565
|
|
nLockTime: 97b0e4e4
|
|
nExpiryHeight: c705fc05
|
|
vJoinSplit: 02
|
|
vpub_old: 0000000000000000
|
|
vpub_new: 0000000000000000
|
|
anchor: 76495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d
|
|
nullifiers: 3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a98 51a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dad
|
|
commitments: d64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e1 91e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8
|
|
ephemeralKey: fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c
|
|
randomSeed: 94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a0
|
|
macs: 08e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b21035965 55ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c
|
|
proof: 03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf
|
|
ciphertexts:
|
|
73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bf
|
|
b3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e
|
|
|
|
vpub_old: 0000000000000000
|
|
vpub_new: 0000000000000000
|
|
anchor: ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6
|
|
nullifiers: e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba 27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082
|
|
commitments: ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd 78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490
|
|
ephemeralKey: adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e9786
|
|
randomSeed: 2dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8
|
|
macs: da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d4 56851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a7
|
|
proof: 0339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262
|
|
ciphertexts:
|
|
275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2
|
|
f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d31
|
|
|
|
joinSplitPubKey: 5e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a
|
|
joinSplitSig: 5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952
|
|
(joinSplitPubKey is a potentially-invalid public key; joinSplitSig is invalid random data)</pre>
|
|
<p>Transaction digest with <code>nIn = 1</code> and <code>nHashType = 3</code> (<code>SIGHASH_SINGLE</code>):</p>
|
|
<pre>hashPrevouts:
|
|
BLAKE2b-256('ZcashPrevoutHash', 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a7378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7)
|
|
= 92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
|
|
|
|
hashOutputs:
|
|
BLAKE2b-256('ZcashOutputsHash', 23752997f4ff04000751510053536565)
|
|
= e03b74bc5187184406285bb9f03b4be510f5700c5859738434cf7b8f5bdb6772
|
|
|
|
hashJoinSplits:
|
|
BLAKE2b-256('ZcashJSplitsHash', 0000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a70339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a)
|
|
= f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
|
|
|
|
Preimage:
|
|
030000807082c40392b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f0000000000000000000000000000000000000000000000000000000000000000edc32cce530f836f7c31c53656f859f514c3ff8dcae642d3e17700fdc6e829a4f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d51497b0e4e4c705fc0503000000378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d701532f6e04963b4c0100e8c7203d
|
|
|
|
header: 03000080
|
|
nVersionGroupId: 7082c403
|
|
hashPrevouts: 92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
|
|
hashSequence: 0000000000000000000000000000000000000000000000000000000000000000
|
|
hashOutputs: edc32cce530f836f7c31c53656f859f514c3ff8dcae642d3e17700fdc6e829a4
|
|
hashJoinSplits: f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
|
|
nLockTime: 97b0e4e4
|
|
nExpiryHeight: c705fc05
|
|
nHashType: 03000000
|
|
|
|
Input:
|
|
prevout: 378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7
|
|
scriptCode: 0153
|
|
amount: 2f6e04963b4c0100
|
|
nSequence: e8c7203d
|
|
|
|
sighash: 23652e76cb13b85a0e3363bb5fca061fa791c40c533eccee899364e6e60bb4f7</pre>
|
|
</section>
|
|
</section>
|
|
<section id="deployment"><h2><span class="section-heading">Deployment</span><span class="section-anchor"> <a rel="bookmark" href="#deployment"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>This proposal is deployed with the Overwinter network upgrade. <a id="id23" class="footnote_reference" href="#zip-0201">11</a></p>
|
|
</section>
|
|
<section id="backward-compatibility"><h2><span class="section-heading">Backward compatibility</span><span class="section-anchor"> <a rel="bookmark" href="#backward-compatibility"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p>This proposal is backwards-compatible with old UTXOs. It is <strong>not</strong> backwards-compatible with older software. All transactions will be required to use this transaction digest algorithm for signatures, and so transactions created by older software will be rejected by the network.</p>
|
|
</section>
|
|
<section id="reference-implementation"><h2><span class="section-heading">Reference Implementation</span><span class="section-anchor"> <a rel="bookmark" href="#reference-implementation"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<p><a href="https://github.com/zcash/zcash/pull/2903">https://github.com/zcash/zcash/pull/2903</a></p>
|
|
</section>
|
|
<section id="references"><h2><span class="section-heading">References</span><span class="section-anchor"> <a rel="bookmark" href="#references"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
|
<table id="rfc2119" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>1</th>
|
|
<td><a href="https://www.rfc-editor.org/rfc/rfc2119.html">RFC 2119: Key words for use in RFCs to Indicate Requirement Levels</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="protocol-sproutsend" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>2</th>
|
|
<td><a href="protocol/protocol.pdf#sproutsend">Zcash Protocol Specification, Version 2020.1.15. Section 4.6: Sending Notes (Sprout)</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="wiki-checksig" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>3</th>
|
|
<td><a href="https://en.bitcoin.it/wiki/OP_CHECKSIG">OP_CHECKSIG. Bitcoin Wiki</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="quadratic" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>4</th>
|
|
<td>
|
|
<ul>
|
|
<li><a href="https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-2292">CVE-2013-2292</a></li>
|
|
<li><a href="https://bitcointalk.org/?topic=140078">New Bitcoin vulnerability: A transaction that takes at least 3 minutes to verify</a></li>
|
|
<li><a href="http://rusty.ozlabs.org/?p=522">The Megatransaction: Why Does It Take 25 Seconds?</a></li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="offline-wallets" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>5</th>
|
|
<td><a href="https://bitcointalk.org/index.php?topic=181734.0">SIGHASH_WITHINPUTVALUE: Super-lightweight HW wallets and offline data</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="bip-0143" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>6</th>
|
|
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki">BIP 143: Transaction Signature Verification for Version 0 Witness Program</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="buip-hf" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>7</th>
|
|
<td><a href="https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/abc/replay-protected-sighash.md">BUIP-HF Digest for replay protected signature verification across hard forks, version 1.2</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="blake2-personalization" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>8</th>
|
|
<td><a href="https://blake2.net/blake2.pdf">"BLAKE2: simpler, smaller, fast as MD5", Section 2.8</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="change" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>9</th>
|
|
<td>In the original algorithm, a <code>uint256</code> of <code>0x0000......0001</code> is committed if the input index for a <code>SINGLE</code> signature is greater than or equal to the number of outputs. In this ZIP a <code>0x0000......0000</code> is commited, without changing the semantics.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="zip-0200" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>10</th>
|
|
<td><a href="zip-0200">ZIP 200: Network Upgrade Mechanism</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="zip-0201" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>11</th>
|
|
<td><a href="zip-0201">ZIP 201: Network Peer Management for Overwinter</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="zip-0202" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>12</th>
|
|
<td><a href="zip-0202">ZIP 202: Version 3 Transaction Format for Overwinter</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="zip-0203" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>13</th>
|
|
<td><a href="zip-0203">ZIP 203: Transaction Expiry</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="test-vectors" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>14</th>
|
|
<td><a href="https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0143.py">ZIP 143 Test Vectors</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table id="sighash-tests" class="footnote">
|
|
<tbody>
|
|
<tr>
|
|
<th>15</th>
|
|
<td><a href="https://github.com/zcash/zcash/blob/master/src/test/data/sighash.json">SignatureHash Test Vectors</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
</section>
|
|
</body>
|
|
</html> |