Completed
Pull Request — master (#220)
by thomas
73:29 queued 68:53
created

TxBuilder::lockToBlockHeight()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

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