Completed
Push — master ( 2a5c77...6a30c1 )
by thomas
52:06 queued 14:02
created

TxBuilder::witnesses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 8
ccs 0
cts 4
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace BitWasp\Bitcoin\Transaction\Factory;
4
5
use BitWasp\Bitcoin\Address\AddressInterface;
6
use BitWasp\Bitcoin\Locktime;
7
use BitWasp\Bitcoin\Script\Script;
8
use BitWasp\Bitcoin\Script\ScriptFactory;
9
use BitWasp\Bitcoin\Script\ScriptInterface;
10
use BitWasp\Bitcoin\Script\ScriptWitnessInterface;
11
use BitWasp\Bitcoin\Transaction\Bip69\Bip69;
12
use BitWasp\Bitcoin\Transaction\OutPoint;
13
use BitWasp\Bitcoin\Transaction\OutPointInterface;
14
use BitWasp\Bitcoin\Transaction\Transaction;
15
use BitWasp\Bitcoin\Transaction\TransactionInput;
16
use BitWasp\Bitcoin\Transaction\TransactionInputInterface;
17
use BitWasp\Bitcoin\Transaction\TransactionInterface;
18
use BitWasp\Bitcoin\Transaction\TransactionOutput;
19
use BitWasp\Bitcoin\Transaction\TransactionOutputInterface;
20
use BitWasp\Buffertools\Buffer;
21
use BitWasp\Buffertools\BufferInterface;
22
23
class TxBuilder
24
{
25
    /**
26
     * @var int
27
     */
28
    private $nVersion;
29
30
    /**
31
     * @var array
32
     */
33
    private $inputs;
34
35
    /**
36
     * @var array
37
     */
38
    private $outputs;
39
40
    /**
41
     * @var array
42
     */
43
    private $witness;
44
45
    /**
46
     * @var int
47
     */
48
    private $nLockTime;
49
50 114
    public function __construct()
51
    {
52 114
        $this->reset();
53 114
    }
54
55
    /**
56
     * @return $this
57
     */
58 114
    public function reset()
59
    {
60 114
        $this->nVersion = 1;
61 114
        $this->inputs = [];
62 114
        $this->outputs = [];
63 114
        $this->witness = [];
64 114
        $this->nLockTime = 0;
65 114
        return $this;
66
    }
67
68
    /**
69
     * @return TransactionInterface
70
     */
71 258
    private function makeTransaction()
72
    {
73 258
        return new Transaction($this->nVersion, $this->inputs, $this->outputs, $this->witness, $this->nLockTime);
74
    }
75
76
    /**
77
     * @return TransactionInterface
78
     */
79 252
    public function get()
80
    {
81 252
        return $this->makeTransaction();
82
    }
83
84
    /**
85
     * @return TransactionInterface
86
     */
87 30
    public function getAndReset()
88
    {
89 30
        $transaction = $this->makeTransaction();
90 30
        $this->reset();
91 30
        return $transaction;
92
    }
93
94
    /**
95
     * @param int $nVersion
96
     * @return $this
97
     */
98 18
    public function version($nVersion)
99
    {
100 18
        $this->nVersion = $nVersion;
101 18
        return $this;
102
    }
103
104
    /**
105
     * @param BufferInterface|string $hashPrevOut - hex or BufferInterface
106
     * @param int $nPrevOut
107
     * @param Script|null $script
108
     * @param int $nSequence
109
     * @return $this
110
     */
111 78
    public function input($hashPrevOut, $nPrevOut, Script $script = null, $nSequence = TransactionInputInterface::SEQUENCE_FINAL)
112
    {
113 78
        $this->inputs[] = new TransactionInput(
114 78
            new OutPoint(
115 78
                $hashPrevOut instanceof BufferInterface ? $hashPrevOut : Buffer::hex($hashPrevOut, 32),
116
                $nPrevOut
117 39
            ),
118 78
            $script ?: new Script(),
119
            $nSequence
120 39
        );
121
122 78
        return $this;
123
    }
124
125
    /**
126
     * @param TransactionInputInterface[] $inputs
127
     * @return $this
128
     */
129
    public function inputs(array $inputs)
130
    {
131
        array_walk($inputs, function (TransactionInputInterface $input) {
132
            $this->inputs[] = $input;
133
        });
134
135
        return $this;
136
    }
137
138
    /**
139
     * @param integer $value
140
     * @param ScriptInterface $script
141
     * @return $this
142
     */
143 90
    public function output($value, ScriptInterface $script)
144
    {
145 90
        $this->outputs[] = new TransactionOutput($value, $script);
146 90
        return $this;
147
    }
148
149
    /**
150
     * @param TransactionOutputInterface[] $outputs
151
     * @return $this
152
     */
153
    public function outputs(array $outputs)
154
    {
155
        array_walk($outputs, function (TransactionOutputInterface $output) {
156
            $this->outputs[] = $output;
157
        });
158
159
        return $this;
160
    }
161
162
    /**
163
     * @param ScriptWitnessInterface[] $witness
164
     * @return $this
165
     */
166
    public function witnesses(array $witness)
167
    {
168
        array_walk($witness, function (ScriptWitnessInterface $witness) {
169
            $this->witness[] = $witness;
170
        });
171
172
        return $this;
173
    }
174
175
    /**
176
     * @param int $locktime
177
     * @return $this
178
     */
179 24
    public function locktime($locktime)
180
    {
181 24
        $this->nLockTime = $locktime;
182 24
        return $this;
183
    }
184
185
    /**
186
     * @param Locktime $lockTime
187
     * @param int $nTimestamp
188
     * @return $this
189
     * @throws \Exception
190
     */
191 6
    public function lockToTimestamp(Locktime $lockTime, $nTimestamp)
192
    {
193 6
        $this->locktime($lockTime->fromTimestamp($nTimestamp));
194 6
        return $this;
195
    }
196
197
    /**
198
     * @param Locktime $lockTime
199
     * @param int $blockHeight
200
     * @return $this
201
     * @throws \Exception
202
     */
203 6
    public function lockToBlockHeight(Locktime $lockTime, $blockHeight)
204
    {
205 6
        $this->locktime($lockTime->fromBlockHeight($blockHeight));
206 6
        return $this;
207
    }
208
209
    /**
210
     * @param OutPointInterface $outpoint
211
     * @param ScriptInterface|null $script
212
     * @param int $nSequence
213
     * @return $this
214
     */
215
    public function spendOutPoint(OutPointInterface $outpoint, ScriptInterface $script = null, $nSequence = TransactionInputInterface::SEQUENCE_FINAL)
216
    {
217
        $this->inputs[] = new TransactionInput(
218
            $outpoint,
219
            $script ?: new Script(),
220
            $nSequence
221
        );
222
223
        return $this;
224
    }
225
226
    /**
227
     * @param TransactionInterface $transaction
228
     * @param int $outputToSpend
229
     * @param ScriptInterface|null $script
230
     * @param int $nSequence
231
     * @return $this
232
     */
233 24
    public function spendOutputFrom(TransactionInterface $transaction, $outputToSpend, ScriptInterface $script = null, $nSequence = TransactionInputInterface::SEQUENCE_FINAL)
234
    {
235
        // Check TransactionOutput exists in $tx
236 24
        $transaction->getOutput($outputToSpend);
237 24
        $this->input(
238 24
            $transaction->getTxId(),
239 12
            $outputToSpend,
240 12
            $script,
0 ignored issues
show
Bug introduced by
It seems like $script defined by parameter $script on line 233 can also be of type object<BitWasp\Bitcoin\Script\ScriptInterface>; however, BitWasp\Bitcoin\Transact...tory\TxBuilder::input() does only seem to accept null|object<BitWasp\Bitcoin\Script\Script>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and 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...
241
            $nSequence
242 12
        );
243
244 24
        return $this;
245
    }
246
247
    /**
248
     * Create an output paying $value to an Address.
249
     *
250
     * @param int $value
251
     * @param AddressInterface $address
252
     * @return $this
253
     */
254 18
    public function payToAddress($value, AddressInterface $address)
255
    {
256
        // Create Script from address, then create an output.
257 18
        $this->output(
258 9
            $value,
259 18
            ScriptFactory::scriptPubKey()->payToAddress($address)
260 9
        );
261
262 18
        return $this;
263
    }
264
265
    /**
266
     * Sorts the transaction inputs and outputs lexicographically,
267
     * according to BIP69
268
     *
269
     * @param Bip69 $bip69
270
     * @return $this
271
     */
272
    public function bip69(Bip69 $bip69)
273
    {
274
        list ($inputs, $witness) = $bip69->sortInputsAndWitness($this->inputs, $this->witness);
275
276
        $this->inputs = $inputs;
277
        $this->outputs = $bip69->sortOutputs($this->outputs);
278
        $this->witness = $witness;
279
280
        return $this;
281
    }
282
}
283