Completed
Pull Request — master (#248)
by thomas
58:32 queued 33:01
created

TxBuilder::payToAddress()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

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