Completed
Pull Request — master (#286)
by thomas
23:49
created

OutputScriptFactory::multisig()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 31
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 31
ccs 17
cts 20
cp 0.85
rs 8.439
cc 6
eloc 18
nc 8
nop 3
crap 6.1215
1
<?php
2
3
namespace BitWasp\Bitcoin\Script\Factory;
4
5
use BitWasp\Bitcoin\Address\AddressInterface;
6
use BitWasp\Bitcoin\Address\ScriptHashAddress;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface;
8
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
9
use BitWasp\Bitcoin\Script\Opcodes;
10
use BitWasp\Bitcoin\Script\Script;
11
use BitWasp\Bitcoin\Script\ScriptFactory;
12
use BitWasp\Bitcoin\Script\ScriptInterface;
13
use BitWasp\Buffertools\Buffer;
14
use BitWasp\Buffertools\Buffertools;
15
16
class OutputScriptFactory
17
{
18
    /**
19
     * @return OutputClassifier
20
     */
21
    public function classify()
22
    {
23
        return new OutputClassifier();
24
    }
25
26
    /**
27
     * @param AddressInterface $address
28
     * @return ScriptInterface
29
     */
30 108
    public function payToAddress(AddressInterface $address)
31
    {
32
        $script = ($address instanceof ScriptHashAddress
33 108
            ? ScriptFactory::create()
34 12
                ->op('OP_HASH160')
35 12
                ->push(Buffer::hex($address->getHash(), 20))
36 12
                ->op('OP_EQUAL')
37 108
            : ScriptFactory::create()
38 102
                ->op('OP_DUP')
39 102
                ->op('OP_HASH160')
40 102
                ->push(Buffer::hex($address->getHash(), 20))
41 102
                ->op('OP_EQUALVERIFY')
42 108
                ->op('OP_CHECKSIG'));
43
44 108
        return $script->getScript();
45
    }
46
47
    /**
48
     * Create a Pay to pubkey output
49
     *
50
     * @param PublicKeyInterface  $public_key
51
     * @return ScriptInterface
52
     */
53 36
    public function payToPubKey(PublicKeyInterface $public_key)
54
    {
55 36
        return ScriptFactory::create()
56 36
            ->push($public_key->getBuffer())
57 36
            ->op('OP_CHECKSIG')
58 36
            ->getScript();
59
    }
60
61
    /**
62
     * Create a P2PKH output script
63
     *
64
     * @param PublicKeyInterface $public_key
65
     * @return ScriptInterface
66
     */
67 18
    public function payToPubKeyHash(PublicKeyInterface $public_key)
68
    {
69 18
        return ScriptFactory::create()
70 18
            ->op('OP_DUP')
71 18
            ->op('OP_HASH160')
72 18
            ->push($public_key->getPubKeyHash())
73 18
            ->op('OP_EQUALVERIFY')
74 18
            ->op('OP_CHECKSIG')
75 18
            ->getScript();
76
    }
77
78
    /**
79
     * Create a P2SH output script
80
     *
81
     * @param ScriptInterface $p2shScript
82
     * @return ScriptInterface
83
     */
84 96
    public function payToScriptHash(ScriptInterface $p2shScript)
85
    {
86 96
        return ScriptFactory::create()
87 96
            ->op('OP_HASH160')
88 96
            ->push($p2shScript->getScriptHash())
89 96
            ->op('OP_EQUAL')
90 96
            ->getScript();
91
    }
92
93
    /**
94
     * @param int $m
95
     * @param PublicKeyInterface[] $keys
96
     * @param bool|true $sort
97
     * @return ScriptCreator|Script
98
     */
99 78
    public function multisig($m, array $keys = [], $sort = true)
100
    {
101 78
        $n = count($keys);
102 78
        if ($m > $n) {
103
            throw new \LogicException('Required number of sigs exceeds number of public keys');
104
        }
105
106 78
        if ($n > 16) {
107
            throw new \LogicException('Number of public keys is greater than 16');
108
        }
109
110 78
        if ($sort) {
111 78
            $keys = Buffertools::sort($keys);
112 78
        }
113
114 78
        $opM = \BitWasp\Bitcoin\Script\encodeOpN($m);
115 78
        $opN = \BitWasp\Bitcoin\Script\encodeOpN($n);
116
117 78
        $script = ScriptFactory::create();
118 78
        foreach ($keys as $key) {
119 78
            if (!$key instanceof PublicKeyInterface) {
120
                throw new \LogicException('Values in $keys[] must be a PublicKey');
121
            }
122
123 78
            $script->push($key->getBuffer());
124 78
        }
125 78
        $keyBuf = $script->getScript()->getBuffer();
126
127 78
        $script = new Script(new Buffer(chr($opM) . $keyBuf->getBinary() . chr($opN) . chr(Opcodes::OP_CHECKMULTISIG)));
128 78
        return $script;
129
    }
130
}
131