Completed
Pull Request — master (#387)
by thomas
249:34 queued 246:57
created

Hasher   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 76
ccs 41
cts 41
cp 1
rs 10
c 0
b 0
f 0
wmc 11
lcom 1
cbo 11

1 Method

Rating   Name   Duplication   Size   Complexity  
C calculate() 0 61 11
1
<?php
2
3
namespace BitWasp\Bitcoin\Transaction\SignatureHash;
4
5
use BitWasp\Bitcoin\Bitcoin;
6
use BitWasp\Bitcoin\Crypto\Hash;
7
use BitWasp\Bitcoin\Transaction\Mutator\TxMutator;
8
use BitWasp\Buffertools\Buffer;
9
use BitWasp\Buffertools\BufferInterface;
10
use BitWasp\Buffertools\Buffertools;
11
use BitWasp\Bitcoin\Script\Script;
12
use BitWasp\Bitcoin\Script\ScriptInterface;
13
14
class Hasher extends SigHash
15
{
16
    /**
17
     * Calculate the hash of the current transaction, when you are looking to
18
     * spend $txOut, and are signing $inputToSign. The SigHashType defaults to
19
     * SIGHASH_ALL, though SIGHASH_SINGLE, SIGHASH_NONE, SIGHASH_ANYONECANPAY
20
     * can be used.
21
     *
22
     * @param ScriptInterface $txOutScript
23
     * @param int $inputToSign
24
     * @param int $sighashType
25
     * @return BufferInterface
26
     * @throws \Exception
27
     */
28 254
    public function calculate(ScriptInterface $txOutScript, $inputToSign, $sighashType = SigHashInterface::ALL)
29
    {
30 254
        $math = Bitcoin::getMath();
31 254
        $tx = new TxMutator($this->tx);
32 254
        $inputs = $tx->inputsMutator();
33 254
        $outputs = $tx->outputsMutator();
34
35
        // Default SIGHASH_ALL procedure: null all input scripts
36 254
        foreach ($inputs as $input) {
37 254
            $input->script(new Script);
38 114
        }
39
40 254
        $inputs[$inputToSign]->script($txOutScript);
41
42 248
        if (($sighashType & 31) === SigHashInterface::NONE) {
43
            // Set outputs to empty vector, and set sequence number of inputs to 0.
44 6
            $outputs->null();
45
46
            // Let the others update at will. Set sequence of inputs we're not signing to 0.
47 6
            foreach ($inputs as $i => $input) {
48 6
                if ($i !== $inputToSign) {
49 6
                    $input->sequence(0);
50 2
                }
51 2
            }
52 248
        } elseif (($sighashType & 31) === SigHashInterface::SINGLE) {
53
            // Resize output array to $inputToSign + 1, set remaining scripts to null,
54
            // and set sequence's to zero.
55 12
            $nOutput = $inputToSign;
56 12
            if ($nOutput >= count($this->tx->getOutputs())) {
57 6
                return Buffer::hex('0100000000000000000000000000000000000000000000000000000000000000', 32, $math);
58
            }
59
60
            // Resize, set to null
61 12
            $outputs->slice(0, $nOutput + 1);
62 12
            for ($i = 0; $i < $nOutput; $i++) {
63 6
                $outputs[$i]->null();
64 2
            }
65
66
            // Let the others update at will. Set sequence of inputs we're not signing to 0
67 12
            foreach ($inputs as $i => $input) {
68 12
                if ($i !== $inputToSign) {
69 10
                    $input->sequence(0);
70 2
                }
71 4
            }
72 4
        }
73
74
        // This can happen regardless of whether it's ALL, NONE, or SINGLE
75 248
        if (($sighashType & SigHashInterface::ANYONECANPAY) > 0) {
76 10
            $input = $inputs[$inputToSign]->done();
77 10
            $inputs->null()->add($input);
78 4
        }
79
80 248
        return Hash::sha256d(
81 248
            Buffertools::concat(
82
                $tx
83 248
                    ->done()
84 248
                    ->getBuffer(),
85 248
                Buffertools::flipBytes(Buffer::int($sighashType, 4, $math))
0 ignored issues
show
Bug introduced by
It seems like \BitWasp\Buffertools\Buf...sighashType, 4, $math)) targeting BitWasp\Buffertools\Buffertools::flipBytes() can also be of type string; however, BitWasp\Buffertools\Buffertools::concat() does only seem to accept object<BitWasp\Buffertools\BufferInterface>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
86 112
            )
87 112
        );
88
    }
89
}
90