Completed
Pull Request — master (#387)
by thomas
247:48 queued 175:25
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 34
cts 34
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 260
     * @return BufferInterface
26
     * @throws \Exception
27 260
     */
28 260
    public function calculate(ScriptInterface $txOutScript, $inputToSign, $sighashType = SigHashInterface::ALL)
29
    {
30
        $math = Bitcoin::getMath();
31
        $tx = new TxMutator($this->tx);
32
        $inputs = $tx->inputsMutator();
33
        $outputs = $tx->outputsMutator();
34
35
        // Default SIGHASH_ALL procedure: null all input scripts
36
        foreach ($inputs as $input) {
37
            $input->script(new Script);
38
        }
39
40
        $inputs[$inputToSign]->script($txOutScript);
41
42 254
        if (($sighashType & 31) === SigHashInterface::NONE) {
43
            // Set outputs to empty vector, and set sequence number of inputs to 0.
44 254
            $outputs->null();
45 254
46 254
            // Let the others update at will. Set sequence of inputs we're not signing to 0.
47 254
            foreach ($inputs as $i => $input) {
48
                if ($i !== $inputToSign) {
49
                    $input->sequence(0);
50 254
                }
51 254
            }
52 114
        } elseif (($sighashType & 31) === SigHashInterface::SINGLE) {
53
            // Resize output array to $inputToSign + 1, set remaining scripts to null,
54 254
            // and set sequence's to zero.
55
            $nOutput = $inputToSign;
56 248
            if ($nOutput >= count($this->tx->getOutputs())) {
57
                return Buffer::hex('0100000000000000000000000000000000000000000000000000000000000000', 32, $math);
58 6
            }
59
60
            // Resize, set to null
61 6
            $outputs->slice(0, $nOutput + 1);
62 6
            for ($i = 0; $i < $nOutput; $i++) {
63 6
                $outputs[$i]->null();
64 2
            }
65 2
66 248
            // Let the others update at will. Set sequence of inputs we're not signing to 0
67
            foreach ($inputs as $i => $input) {
68
                if ($i !== $inputToSign) {
69 12
                    $input->sequence(0);
70 12
                }
71 6
            }
72
        }
73
74
        // This can happen regardless of whether it's ALL, NONE, or SINGLE
75 12
        if (($sighashType & SigHashInterface::ANYONECANPAY) > 0) {
76 12
            $input = $inputs[$inputToSign]->done();
77 6
            $inputs->null()->add($input);
78 2
        }
79
80
        return Hash::sha256d(
81 12
            Buffertools::concat(
82 12
                $tx
83 10
                    ->done()
84 2
                    ->getBuffer(),
85 4
                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 4
            )
87
        );
88
    }
89
}
90