Completed
Push — master ( 26caf6...2acf03 )
by thomas
8s
created

InputSigner   F

Complexity

Total Complexity 90

Size/Duplication

Total Lines 513
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 28

Test Coverage

Coverage 95.07%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 90
c 6
b 0
f 0
lcom 1
cbo 28
dl 0
loc 513
ccs 270
cts 284
cp 0.9507
rs 1.3043

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
B sortMultiSigs() 0 24 5
D extractFromValues() 0 39 10
C extractSignatures() 0 66 15
B calculateSignature() 0 25 2
A isFullySigned() 0 4 2
D doSignature() 0 85 14
C sign() 0 57 20
D serializeSimpleSig() 0 31 9
C serializeSignatures() 0 50 12

How to fix   Complexity   

Complex Class

Complex classes like InputSigner often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use InputSigner, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace BitWasp\Bitcoin\Transaction\Factory;
4
5
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface;
8
use BitWasp\Bitcoin\Crypto\Hash;
9
use BitWasp\Bitcoin\Crypto\Random\Rfc6979;
10
use BitWasp\Bitcoin\Key\PublicKeyFactory;
11
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
12
use BitWasp\Bitcoin\Script\Opcodes;
13
use BitWasp\Bitcoin\Script\Script;
14
use BitWasp\Bitcoin\Script\ScriptFactory;
15
use BitWasp\Bitcoin\Script\ScriptInfo\Multisig;
16
use BitWasp\Bitcoin\Script\ScriptInterface;
17
use BitWasp\Bitcoin\Script\ScriptWitness;
18
use BitWasp\Bitcoin\Signature\SignatureSort;
19
use BitWasp\Bitcoin\Signature\TransactionSignature;
20
use BitWasp\Bitcoin\Signature\TransactionSignatureFactory;
21
use BitWasp\Bitcoin\Signature\TransactionSignatureInterface;
22
use BitWasp\Bitcoin\Transaction\SignatureHash\Hasher;
23
use BitWasp\Bitcoin\Transaction\SignatureHash\SigHashInterface;
24
use BitWasp\Bitcoin\Transaction\SignatureHash\V1Hasher;
25
use BitWasp\Bitcoin\Transaction\TransactionInterface;
26
use BitWasp\Bitcoin\Transaction\TransactionOutputInterface;
27
use BitWasp\Buffertools\BufferInterface;
28
29
class InputSigner
30
{
31
    /**
32
     * @var EcAdapterInterface
33
     */
34
    private $ecAdapter;
35
36
    /**
37
     * @var ScriptInterface $redeemScript
38
     */
39
    private $redeemScript;
40
41
    /**
42
     * @var ScriptInterface $witnessScript
43
     */
44
    private $witnessScript;
45
46
    /**
47
     * @var TransactionInterface
48
     */
49
    private $tx;
50
51
    /**
52
     * @var int
53
     */
54
    private $nInput;
55
56
    /**
57
     * @var TransactionOutputInterface
58
     */
59
    private $txOut;
60
61
    /**
62
     * @var PublicKeyInterface[]
63
     */
64
    private $publicKeys = [];
65
66
    /**
67
     * @var int
68
     */
69
    private $sigHashType;
70
71
    /**
72
     * @var TransactionSignatureInterface[]
73
     */
74
    private $signatures = [];
75
76
    /**
77
     * @var int
78
     */
79
    private $requiredSigs = 0;
80
81
    /**
82
     * TxInputSigning constructor.
83
     * @param EcAdapterInterface $ecAdapter
84
     * @param TransactionInterface $tx
85
     * @param int $nInput
86
     * @param TransactionOutputInterface $txOut
87
     * @param int $sigHashType
88
     */
89 84
    public function __construct(EcAdapterInterface $ecAdapter, TransactionInterface $tx, $nInput, TransactionOutputInterface $txOut, $sigHashType = SigHashInterface::ALL)
90
    {
91 84
        $this->ecAdapter = $ecAdapter;
92 84
        $this->tx = $tx;
93 84
        $this->nInput = $nInput;
94 84
        $this->txOut = $txOut;
95 84
        $this->classifier = new OutputClassifier();
0 ignored issues
show
Bug introduced by
The property classifier does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
96 84
        $this->sigHashType = $sigHashType;
97 84
        $this->publicKeys = [];
98 84
        $this->signatures = [];
99
100 84
        $this->extractSignatures();
101 84
    }
102
103
    /**
104
     * @param int $sigVersion
105
     * @param $stack
106
     * @param ScriptInterface $scriptCode
107
     * @return \SplObjectStorage
108
     */
109 24
    private function sortMultiSigs($sigVersion, $stack, ScriptInterface $scriptCode)
110
    {
111 24
        if ($sigVersion === 1) {
112 12
            $hasher = new V1Hasher($this->tx, $this->txOut->getValue());
113 12
        } else {
114 12
            $hasher = new Hasher($this->tx);
115
        }
116
117 24
        $sigSort = new SignatureSort($this->ecAdapter);
118 24
        $sigs = new \SplObjectStorage;
119
120 24
        foreach ($stack as $txSig) {
121
            $hash = $hasher->calculate($scriptCode, $this->nInput, $txSig->getHashType());
122
            $linked = $sigSort->link([$txSig->getSignature()], $this->publicKeys, $hash);
123
124
            foreach ($this->publicKeys as $key) {
125 6
                if ($linked->contains($key)) {
126
                    $sigs[$key] = $txSig;
127
                }
128
            }
129 24
        }
130
131 24
        return $sigs;
132
    }
133
134
    /**
135
     * @param string $type
136
     * @param ScriptInterface $scriptCode
137
     * @param BufferInterface[] $stack
138
     * @param int $sigVersion
139
     * @return string
140
     */
141 84
    public function extractFromValues($type, ScriptInterface $scriptCode, array $stack, $sigVersion)
142
    {
143 84
        $size = count($stack);
144 72
        if ($type === OutputClassifier::PAYTOPUBKEYHASH) {
145 30
            $this->requiredSigs = 1;
146 30
            if ($size === 2) {
147 12
                $this->signatures = [TransactionSignatureFactory::fromHex($stack[0], $this->ecAdapter)];
148 12
                $this->publicKeys = [PublicKeyFactory::fromHex($stack[1], $this->ecAdapter)];
149 12
            }
150 30
        }
151
152 72
        if ($type === OutputClassifier::PAYTOPUBKEY) {
153 12
            $this->requiredSigs = 1;
154 12
            if ($size === 1) {
155 6
                $this->signatures = [TransactionSignatureFactory::fromHex($stack[0], $this->ecAdapter)];
156 6
            }
157 12
        }
158
159 72
        if ($type === OutputClassifier::MULTISIG) {
160 24
            $info = new Multisig($scriptCode);
161 24
            $this->requiredSigs = $info->getRequiredSigCount();
162 24
            $this->publicKeys = $info->getKeys();
163
164 24
            if ($size > 1) {
165 24
                $vars = [];
166 24
                foreach (array_slice($stack, 1, -1) as $sig) {
167
                    $vars[] = TransactionSignatureFactory::fromHex($sig, $this->ecAdapter);
168 24
                }
169
170 24
                $sigs = $this->sortMultiSigs($sigVersion, $vars, $scriptCode);
171
172 24
                foreach ($this->publicKeys as $idx => $key) {
173 24
                    $this->signatures[$idx] = isset($sigs[$key]) ? $sigs[$key]->getBuffer() : null;
174 24
                }
175 24
            }
176 24
        }
177
178 72
        return $type;
179
    }
180
181
    /**
182
     * @return $this
183
     */
184 84
    public function extractSignatures()
185
    {
186 84
        $scriptPubKey = $this->txOut->getScript();
187 84
        $scriptSig = $this->tx->getInput($this->nInput)->getScript();
188 84
        $type = $this->classifier->classify($scriptPubKey);
189
190 84
        if ($type === OutputClassifier::PAYTOPUBKEYHASH || $type === OutputClassifier::PAYTOPUBKEY || $type === OutputClassifier::MULTISIG) {
191 42
            $values = [];
192 42
            foreach ($scriptSig->getScriptParser()->decode() as $o) {
193 18
                $values[] = $o->getData();
194 78
            }
195
196 42
            $this->extractFromValues($type, $scriptPubKey, $values, 0);
197 42
        }
198
199 84
        if ($type === OutputClassifier::PAYTOSCRIPTHASH) {
200 24
            $decodeSig = $scriptSig->getScriptParser()->decode();
201 24
            if (count($decodeSig) > 0) {
202 18
                $redeemScript = new Script(end($decodeSig)->getData());
203 18
                $p2shType = $this->classifier->classify($redeemScript);
204
205 18
                if (count($decodeSig) > 1) {
206 6
                    $decodeSig = array_slice($decodeSig, 0, -1);
207 6
                }
208
209 18
                $internalSig = [];
210 18
                foreach ($decodeSig as $operation) {
211 18
                    $internalSig[] = $operation->getData();
212 18
                }
213
214 18
                $this->redeemScript = $redeemScript;
215 18
                $this->extractFromValues($p2shType, $redeemScript, $internalSig, 0);
216
217 18
                $type = $p2shType;
218 18
            }
219 24
        }
220
221 84
        $witnesses = $this->tx->getWitnesses();
222 84
        if ($type === OutputClassifier::WITNESS_V0_KEYHASH) {
223 12
            $this->requiredSigs = 1;
224 12
            if (isset($witnesses[$this->nInput])) {
225 12
                $witness = $witnesses[$this->nInput];
226 12
                $this->signatures = [TransactionSignatureFactory::fromHex($witness[0], $this->ecAdapter)];
227 12
                $this->publicKeys = [PublicKeyFactory::fromHex($witness[1], $this->ecAdapter)];
228 12
            }
229
230 84
        } else if ($type === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
231 18
            if (isset($witnesses[$this->nInput])) {
232 18
                $witness = $witnesses[$this->nInput];
233 18
                $witCount = count($witnesses[$this->nInput]);
234 18
                if ($witCount > 0) {
235 18
                    $witnessScript = new Script($witness[$witCount - 1]);
236 18
                    $vWitness = $witness->all();
237 18
                    if (count($vWitness) > 1) {
238 18
                        $vWitness = array_slice($witness->all(), 0, -1);
239 18
                    }
240
241 18
                    $witnessType = $this->classifier->classify($witnessScript);
242 18
                    $this->extractFromValues($witnessType, $witnessScript, $vWitness, 1);
243 18
                    $this->witnessScript = $witnessScript;
244 18
                }
245 18
            }
246 18
        }
247
248 84
        return $this;
249
    }
250
251
    /**
252
     * @param PrivateKeyInterface $key
253
     * @param ScriptInterface $scriptCode
254
     * @param int $sigVersion
255
     * @return TransactionSignature
256
     */
257 84
    public function calculateSignature(PrivateKeyInterface $key, ScriptInterface $scriptCode, $sigVersion)
258
    {
259 84
        if ($sigVersion == 1) {
260 30
            $hasher = new V1Hasher($this->tx, $this->txOut->getValue());
261 30
        } else {
262 54
            $hasher = new Hasher($this->tx);
263
        }
264
265 84
        $hash = $hasher->calculate($scriptCode, $this->nInput, $this->sigHashType);
266
267 84
        return new TransactionSignature(
268 84
            $this->ecAdapter,
269 84
            $this->ecAdapter->sign(
270 84
                $hash,
271 84
                $key,
272 84
                new Rfc6979(
273 84
                    $this->ecAdapter,
274 84
                    $key,
275 84
                    $hash,
276
                    'sha256'
277 84
                )
278 84
            ),
279 84
            $this->sigHashType
280 84
        );
281
    }
282
283
    /**
284
     * @return bool
285
     */
286 78
    public function isFullySigned()
287
    {
288 78
        return $this->requiredSigs !== 0 && $this->requiredSigs === count($this->signatures);
289
    }
290
291
    /**
292
     * The function only returns true when $scriptPubKey could be classified
293
     *
294
     * @param PrivateKeyInterface $key
295
     * @param ScriptInterface $scriptPubKey
296
     * @param string $outputType
297
     * @param BufferInterface[] $results
298
     * @param int $sigVersion
299
     * @return bool
300
     */
301 84
    private function doSignature(PrivateKeyInterface $key, ScriptInterface $scriptPubKey, &$outputType, array &$results, $sigVersion = 0)
302
    {
303 84
        $return = [];
304 84
        $outputType = $this->classifier->classify($scriptPubKey, $return);
305 84
        if ($outputType === OutputClassifier::UNKNOWN) {
306
            throw new \RuntimeException('Cannot sign unknown script type');
307
        }
308
309 84
        if ($outputType === OutputClassifier::PAYTOPUBKEY) {
310 12
            $publicKeyBuffer = $return;
311 12
            $results[] = $publicKeyBuffer;
312 12
            $this->requiredSigs = 1;
313 12
            $publicKey = PublicKeyFactory::fromHex($publicKeyBuffer);
0 ignored issues
show
Documentation introduced by
$publicKeyBuffer is of type array, but the function expects a object<BitWasp\Buffertoo...BufferInterface>|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
314
315 12
            if ($publicKey->getBinary() === $key->getPublicKey()->getBinary()) {
316 12
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
317 12
            }
318
319 12
            return true;
320
        }
321
322 72
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH) {
323
            /** @var BufferInterface $pubKeyHash */
324 42
            $pubKeyHash = $return;
325 42
            $results[] = $pubKeyHash;
326 42
            $this->requiredSigs = 1;
327 42
            if ($pubKeyHash->getBinary() === $key->getPublicKey()->getPubKeyHash()->getBinary()) {
328 36
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
329 36
                $this->publicKeys[0] = $key->getPublicKey();
330 36
            }
331
332 42
            return true;
333
        }
334
335 48
        if ($outputType === OutputClassifier::MULTISIG) {
336 30
            $info = new Multisig($scriptPubKey);
337
338 30
            foreach ($info->getKeys() as $publicKey) {
339 30
                $results[] = $publicKey->getBuffer();
340 30
            }
341
342 30
            $this->publicKeys = $info->getKeys();
343 30
            $this->requiredSigs = $info->getKeyCount();
344
345 30
            foreach ($this->publicKeys as $keyIdx => $publicKey) {
346 30
                if ($publicKey->getBinary() == $key->getPublicKey()->getBinary()) {
347 30
                    $this->signatures[$keyIdx] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
348 30
                }
349 30
            }
350
351 30
            return true;
352
        }
353
354 42
        if ($outputType === OutputClassifier::PAYTOSCRIPTHASH) {
355
            /** @var BufferInterface $scriptHash */
356 24
            $scriptHash = $return;
357 24
            $results[] = $scriptHash;
358 24
            return true;
359
        }
360
361 30
        if ($outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
362
            /** @var BufferInterface $pubKeyHash */
363 12
            $pubKeyHash = $return;
364 12
            $results[] = $pubKeyHash;
365 12
            $this->requiredSigs = 1;
366
367 12
            if ($pubKeyHash->getBinary() === $key->getPublicKey()->getPubKeyHash()->getBinary()) {
368 12
                $script = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
369 12
                $this->signatures[0] = $this->calculateSignature($key, $script, 1);
370 12
                $this->publicKeys[0] = $key->getPublicKey();
371 12
            }
372
373 12
            return true;
374
        }
375
376 18
        if ($outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
377
            /** @var BufferInterface $scriptHash */
378 18
            $scriptHash = $return;
379 18
            $results[] = $scriptHash;
380
381 18
            return true;
382
        }
383
384
        return false;
385
    }
386
387
    /**
388
     * @param PrivateKeyInterface $key
389
     * @param ScriptInterface|null $redeemScript
390
     * @param ScriptInterface|null $witnessScript
391
     * @return bool
392
     */
393 84
    public function sign(PrivateKeyInterface $key, ScriptInterface $redeemScript = null, ScriptInterface $witnessScript = null)
394
    {
395
        /** @var BufferInterface[] $return */
396 84
        $type = null;
397 84
        $return = [];
398 84
        $solved = $this->doSignature($key, $this->txOut->getScript(), $type, $return, 0);
399
400 84
        if ($solved && $type === OutputClassifier::PAYTOSCRIPTHASH) {
401 24
            $redeemScriptBuffer = $return[0];
402
403 24
            if (!$redeemScript instanceof ScriptInterface) {
404
                throw new \InvalidArgumentException('Must provide redeem script for P2SH');
405
            }
406
407 24
            if (!$redeemScript->getScriptHash()->getBinary() === $redeemScriptBuffer->getBinary()) {
408
                throw new \InvalidArgumentException("Incorrect redeem script - hash doesn't match");
409
            }
410
411 24
            $results = []; // ???
412 24
            $solved = $solved && $this->doSignature($key, $redeemScript, $type, $results, 0) && $type !== OutputClassifier::PAYTOSCRIPTHASH;
413 24
            if ($solved) {
414 24
                $this->redeemScript = $redeemScript;
415 24
            }
416 24
        }
417
418 84
        if ($solved && $type === OutputClassifier::WITNESS_V0_KEYHASH) {
419 12
            $pubKeyHash = $return[0];
420 12
            $witnessScript = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
421 12
            $subType = null;
422 12
            $subResults = [];
423 12
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1);
424 84
        } else if ($solved && $type === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
425 18
            $scriptHash = $return[0];
426
427 18
            if (!$witnessScript instanceof ScriptInterface) {
428
                throw new \InvalidArgumentException('Must provide witness script for witness v0 scripthash');
429
            }
430
431 18
            if (!Hash::sha256($witnessScript->getBuffer())->getBinary() === $scriptHash->getBinary()) {
432
                throw new \InvalidArgumentException("Incorrect witness script - hash doesn't match");
433
            }
434
435 18
            $subType = null;
436 18
            $subResults = [];
437
438 18
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1)
439 18
                && $subType !== OutputClassifier::PAYTOSCRIPTHASH
440 18
                && $subType !== OutputClassifier::WITNESS_V0_SCRIPTHASH
441 18
                && $subType !== OutputClassifier::WITNESS_V0_KEYHASH;
442
443 18
            if ($solved) {
444 18
                $this->witnessScript = $witnessScript;
445 18
            }
446 18
        }
447
448 84
        return $solved;
449
    }
450
451
    /**
452
     * @param string $outputType
453
     * @param $answer
454
     * @return bool
455
     */
456 84
    private function serializeSimpleSig($outputType, &$answer)
457
    {
458 84
        if ($outputType === OutputClassifier::UNKNOWN) {
459
            throw new \RuntimeException('Cannot sign unknown script type');
460
        }
461
462 84
        if ($outputType === OutputClassifier::PAYTOPUBKEY && $this->isFullySigned()) {
463 12
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer()]), new ScriptWitness([]));
464 12
            return true;
465
        }
466
467 72
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH && $this->isFullySigned()) {
468 30
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]), new ScriptWitness([]));
469 30
            return true;
470
        }
471
472 48
        if ($outputType === OutputClassifier::MULTISIG) {
473 30
            $sequence = [Opcodes::OP_0];
474 30
            $nPubKeys = count($this->publicKeys);
475 30
            for ($i = 0; $i < $nPubKeys; $i++) {
476 30
                if (isset($this->signatures[$i])) {
477 30
                    $sequence[] = $this->signatures[$i]->getBuffer();
478 30
                }
479 30
            }
480
481 30
            $answer = new SigValues(ScriptFactory::sequence($sequence), new ScriptWitness([]));
482 30
            return true;
483
        }
484
485 42
        return false;
486
    }
487
488
    /**
489
     * @return SigValues
490
     */
491 84
    public function serializeSignatures()
492
    {
493 84
        static $emptyScript = null;
494 84
        static $emptyWitness = null;
495 84
        if (is_null($emptyScript) || is_null($emptyWitness)) {
496 6
            $emptyScript = new Script();
497 6
            $emptyWitness = new ScriptWitness([]);
498 6
        }
499
500
        /** @var BufferInterface[] $return */
501 84
        $outputType = $this->classifier->classify($this->txOut->getScript());
502
503
        /** @var SigValues $answer */
504 84
        $answer = new SigValues($emptyScript, $emptyWitness);
505 84
        $serialized = $this->serializeSimpleSig($outputType, $answer);
506
507 84
        $p2sh = false;
508 84
        if (!$serialized && $outputType === OutputClassifier::PAYTOSCRIPTHASH) {
509 24
            $p2sh = true;
510 24
            $outputType = $this->classifier->classify($this->redeemScript);
511 24
            $serialized = $this->serializeSimpleSig($outputType, $answer);
512 24
        }
513
514 84
        if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
515 12
            $answer = new SigValues($emptyScript, new ScriptWitness([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]));
516
517 84
        } else if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
518 18
            $outputType = $this->classifier->classify($this->witnessScript);
519 18
            $serialized = $this->serializeSimpleSig($outputType, $answer);
520
521 18
            if ($serialized) {
522 18
                $data = [];
523 18
                foreach ($answer->getScriptSig()->getScriptParser()->decode() as $o) {
524 18
                    $data[] = $o->getData();
525 18
                }
526
527 18
                $data[] = $this->witnessScript->getBuffer();
528 18
                $answer = new SigValues($emptyScript, new ScriptWitness($data));
529 18
            }
530 18
        }
531
532 84
        if ($p2sh) {
533 24
            $answer = new SigValues(
534 24
                ScriptFactory::create($answer->getScriptSig()->getBuffer())->push($this->redeemScript->getBuffer())->getScript(),
535 24
                $answer->getScriptWitness()
536 24
            );
537 24
        }
538
539 84
        return $answer;
540
    }
541
}
542