Completed
Pull Request — master (#204)
by thomas
25:00
created

Multisig::__construct()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6.1215

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 30
ccs 17
cts 20
cp 0.85
rs 8.439
cc 6
eloc 18
nc 6
nop 1
crap 6.1215
1
<?php
2
3
namespace BitWasp\Bitcoin\Script\ScriptInfo;
4
5
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface;
6
use BitWasp\Bitcoin\Key\PublicKeyFactory;
7
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
8
use BitWasp\Bitcoin\Script\Opcodes;
9
use BitWasp\Bitcoin\Script\Script;
10
use BitWasp\Bitcoin\Script\ScriptFactory;
11
use BitWasp\Bitcoin\Script\ScriptInterface;
12
13
class Multisig implements ScriptInfoInterface
14
{
15
    /**
16
     * @var int
17
     */
18
    private $m;
19
20
    /**
21
     * @var int
22
     */
23
    private $n;
24
25
    /**
26
     * @var ScriptInterface
27
     */
28
    private $script;
29
30
    /**
31
     * @var PublicKeyInterface[]
32
     */
33
    private $keys = [];
34
35
    /**
36
     * @param ScriptInterface $script
37
     */
38 42
    public function __construct(ScriptInterface $script)
39
    {
40 42
        $publicKeys = [];
41 42
        $parse = $script->getScriptParser()->decode();
42 42
        if (count($parse) < 4) {
43
            throw new \InvalidArgumentException('Malformed multisig script');
44
        }
45
46 42
        $mCode = $parse[0]->getOp();
47 42
        $nCode = $parse[count($parse) - 2]->getOp();
48
49 42
        $this->m = $mCode - Opcodes::OP_1 + 1 ;
0 ignored issues
show
Documentation Bug introduced by
The property $m was declared of type integer, but $mCode - \BitWasp\Bitcoin\Script\Opcodes::OP_1 + 1 is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
50 42
        foreach (array_slice($parse, 1, -2) as $key) {
51
            /** @var \BitWasp\Bitcoin\Script\Parser\Operation $key */
52 42
            if (!$key->isPush()) {
53
                throw new \RuntimeException('Malformed multisig script');
54
            }
55
56 42
            $publicKeys[] = PublicKeyFactory::fromHex($key->getData());
57 42
        }
58
59 42
        $n = $nCode - Opcodes::OP_1 + 1 ;
60 42
        $this->n = count($publicKeys);
61 42
        if ($this->n === 0 || $this->n !== $n) {
62
            throw new \LogicException('No public keys found in script');
63
        }
64
65 42
        $this->script = $script;
66 42
        $this->keys = $publicKeys;
67 42
    }
68
69
    /**
70
     * @return int
71
     */
72 12
    public function getRequiredSigCount()
73
    {
74 12
        return $this->m;
75
    }
76
77
    /**
78
     * @return int
79
     */
80 6
    public function getKeyCount()
81
    {
82 6
        return $this->n;
83
    }
84
85
    /**
86
     * @return string
87
     */
88 36
    public function classification()
89
    {
90 36
        return OutputClassifier::MULTISIG;
91
    }
92
93
    /**
94
     * @param PublicKeyInterface $publicKey
95
     * @return bool
96
     */
97
    public function checkInvolvesKey(PublicKeyInterface $publicKey)
98
    {
99
        $binary = $publicKey->getBinary();
100
        foreach ($this->keys as $key) {
101
            if ($key->getBinary() === $binary) {
102
                return true;
103
            }
104
        }
105
106
        return false;
107
    }
108
109
    /**
110
     * @return \BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface[]
111
     */
112 42
    public function getKeys()
113
    {
114 42
        return $this->keys;
115
    }
116
117
    /**
118
     * @param array $signatures
119
     * @param array $publicKeys
120
     * @return Script|ScriptInterface
121
     */
122 18
    public function makeScriptSig(array $signatures = [], array $publicKeys = [])
123
    {
124 18
        $newScript = new Script();
125 18
        if (count($signatures) > 0) {
126 18
            $newScript = ScriptFactory::scriptSig()->multisig($signatures);
127 18
        }
128
129 18
        return $newScript;
130
    }
131
}
132