Completed
Push — master ( eabe8c...61f277 )
by thomas
25:26
created

ScriptFactory::getBitcoinConsensus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Script;
6
7
use BitWasp\Bitcoin\Bitcoin;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
9
use BitWasp\Bitcoin\Math\Math;
10
use BitWasp\Bitcoin\Script\Consensus\BitcoinConsensus;
11
use BitWasp\Bitcoin\Script\Consensus\ConsensusInterface;
12
use BitWasp\Bitcoin\Script\Consensus\NativeConsensus;
13
use BitWasp\Bitcoin\Script\Factory\OutputScriptFactory;
14
use BitWasp\Bitcoin\Script\Factory\ScriptCreator;
15
use BitWasp\Bitcoin\Script\Parser\Operation;
16
use BitWasp\Buffertools\Buffer;
17
use BitWasp\Buffertools\BufferInterface;
18
19
class ScriptFactory
20
{
21
    /**
22
     * @var OutputScriptFactory
23
     */
24
    private static $outputScriptFactory = null;
25
26
    /**
27
     * @param string $string
28
     * @return ScriptInterface
29
     * @throws \Exception
30
     */
31 21
    public static function fromHex(string $string): ScriptInterface
32
    {
33 21
        return self::fromBuffer(Buffer::hex($string));
34
    }
35
36
    /**
37
     * @param BufferInterface $buffer
38
     * @param Opcodes|null $opcodes
39
     * @param Math|null $math
40
     * @return ScriptInterface
41
     */
42 21
    public static function fromBuffer(BufferInterface $buffer, Opcodes $opcodes = null, Math $math = null): ScriptInterface
43
    {
44 21
        return self::create($buffer, $opcodes, $math)->getScript();
45
    }
46
47
    /**
48
     * @param BufferInterface|null $buffer
49
     * @param Opcodes|null $opcodes
50
     * @param Math|null $math
51
     * @return ScriptCreator
52
     */
53 5384
    public static function create(BufferInterface $buffer = null, Opcodes $opcodes = null, Math $math = null): ScriptCreator
54
    {
55 5384
        return new ScriptCreator($math ?: Bitcoin::getMath(), $opcodes ?: new Opcodes(), $buffer);
56
    }
57
58
    /**
59
     * Create a script consisting only of push-data operations.
60
     * Suitable for a scriptSig.
61
     *
62
     * @param BufferInterface[] $buffers
63
     * @return ScriptInterface
64
     */
65
    public static function pushAll(array $buffers): ScriptInterface
66
    {
67 95
        return self::sequence(array_map(function ($buffer) {
68 78
            if (!($buffer instanceof BufferInterface)) {
69
                throw new \RuntimeException('Script contained a non-push opcode');
70
            }
71
72 78
            $size = $buffer->getSize();
73 78
            if ($size === 0) {
74 24
                return Opcodes::OP_0;
75
            }
76
77 78
            $first = ord($buffer->getBinary()[0]);
78 78
            if ($size === 1 && $first >= 1 && $first <= 16) {
79 4
                return \BitWasp\Bitcoin\Script\encodeOpN($first);
80
            } else {
81 78
                return $buffer;
82
            }
83 95
        }, $buffers));
84
    }
85
86
    /**
87
     * @param int[]|\BitWasp\Bitcoin\Script\Interpreter\Number[]|BufferInterface[] $sequence
88
     * @return ScriptInterface
89
     */
90 5346
    public static function sequence(array $sequence): ScriptInterface
91
    {
92 5346
        return self::create()->sequence($sequence)->getScript();
93
    }
94
95
    /**
96
     * @param Operation[] $operations
97
     * @return ScriptInterface
98
     */
99 20
    public static function fromOperations(array $operations): ScriptInterface
100
    {
101 20
        $sequence = [];
102 20
        foreach ($operations as $operation) {
103 19
            if (!($operation instanceof Operation)) {
104
                throw new \RuntimeException("Invalid input to fromOperations");
105
            }
106
107 19
            $sequence[] = $operation->encode();
108
        }
109
110 20
        return self::sequence($sequence);
111
    }
112
113
    /**
114
     * @return OutputScriptFactory
115
     */
116 211
    public static function scriptPubKey(): OutputScriptFactory
117
    {
118 211
        if (self::$outputScriptFactory === null) {
119
            self::$outputScriptFactory = new OutputScriptFactory();
120
        }
121
122 211
        return self::$outputScriptFactory;
123
    }
124
125
    /**
126
     * @param EcAdapterInterface|null $ecAdapter
127
     * @return NativeConsensus
128
     */
129 1
    public static function getNativeConsensus(EcAdapterInterface $ecAdapter = null): NativeConsensus
130
    {
131 1
        return new NativeConsensus($ecAdapter ?: Bitcoin::getEcAdapter());
132
    }
133
134
    /**
135
     * @return BitcoinConsensus
136
     */
137 81
    public static function getBitcoinConsensus(): BitcoinConsensus
138
    {
139 81
        return new BitcoinConsensus();
140
    }
141
142
    /**
143
     * @param EcAdapterInterface|null $ecAdapter
144
     * @return ConsensusInterface
145
     */
146 80
    public static function consensus(EcAdapterInterface $ecAdapter = null): ConsensusInterface
147
    {
148 80
        if (extension_loaded('bitcoinconsensus')) {
149 80
            return self::getBitcoinConsensus();
150
        } else {
151
            return self::getNativeConsensus($ecAdapter);
152
        }
153
    }
154
}
155