Completed
Push — master ( 46e6d3...cfc147 )
by thomas
208:06 queued 195:14
created

InputSigner::sign()   C

Complexity

Conditions 20
Paths 107

Size

Total Lines 57
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 20.432

Importance

Changes 0
Metric Value
cc 20
eloc 35
c 0
b 0
f 0
nc 107
nop 3
dl 0
loc 57
ccs 35
cts 39
cp 0.8974
crap 20.432
rs 6.2125

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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...
318 12
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
319 4
            }
320
321 12
            return true;
322
        }
323
324 72
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH) {
325
            /** @var BufferInterface $return */
326 42
            $results[] = $return;
327 42
            $this->requiredSigs = 1;
328 42
            if ($key->getPublicKey()->getPubKeyHash()->equals($return)) {
0 ignored issues
show
Documentation introduced by
$return is of type object<BitWasp\Buffertools\BufferInterface>, but the function expects a object<self>.

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...
329 36
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
330 36
                $this->publicKeys[0] = $key->getPublicKey();
331 12
            }
332
333 42
            return true;
334
        }
335
336 48
        if ($outputType === OutputClassifier::MULTISIG) {
337 30
            $info = new Multisig($scriptPubKey);
338 30
            $this->publicKeys = $info->getKeys();
339 30
            $this->requiredSigs = $info->getKeyCount();
340
341 30
            $myKey = $key->getPublicKey()->getBuffer();
342 30
            foreach ($info->getKeys() as $keyIdx => $publicKey) {
343 30
                $results[] = $publicKey->getBuffer();
344 30
                if ($publicKey->getBuffer()->equals($myKey)) {
0 ignored issues
show
Documentation introduced by
$myKey is of type object<BitWasp\Buffertools\BufferInterface>, but the function expects a object<self>.

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...
345 30
                    $this->signatures[$keyIdx] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
346 10
                }
347 10
            }
348
349 30
            return true;
350
        }
351
352 42
        if ($outputType === OutputClassifier::PAYTOSCRIPTHASH) {
353
            /** @var BufferInterface $scriptHash */
354 24
            $scriptHash = $return;
355 24
            $results[] = $scriptHash;
356 24
            return true;
357
        }
358
359 30
        if ($outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
360
            /** @var BufferInterface $pubKeyHash */
361 12
            $pubKeyHash = $return;
362 12
            $results[] = $pubKeyHash;
363 12
            $this->requiredSigs = 1;
364
365 12
            if ($pubKeyHash->getBinary() === $key->getPublicKey()->getPubKeyHash()->getBinary()) {
366 12
                $script = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
367 12
                $this->signatures[0] = $this->calculateSignature($key, $script, 1);
368 12
                $this->publicKeys[0] = $key->getPublicKey();
369 4
            }
370
371 12
            return true;
372
        }
373
374 18
        if ($outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
375
            /** @var BufferInterface $scriptHash */
376 18
            $scriptHash = $return;
377 18
            $results[] = $scriptHash;
378
379 18
            return true;
380
        }
381
382
        return false;
383
    }
384
385
    /**
386
     * @param PrivateKeyInterface $key
387
     * @param ScriptInterface|null $redeemScript
388
     * @param ScriptInterface|null $witnessScript
389
     * @return bool
390
     */
391 84
    public function sign(PrivateKeyInterface $key, ScriptInterface $redeemScript = null, ScriptInterface $witnessScript = null)
392
    {
393
        /** @var BufferInterface[] $return */
394 84
        $type = null;
395 84
        $return = [];
396 84
        $solved = $this->doSignature($key, $this->txOut->getScript(), $type, $return, 0);
397
398 84
        if ($solved && $type === OutputClassifier::PAYTOSCRIPTHASH) {
399 24
            $redeemScriptBuffer = $return[0];
400
401 24
            if (!$redeemScript instanceof ScriptInterface) {
402
                throw new \InvalidArgumentException('Must provide redeem script for P2SH');
403
            }
404
405 24
            if (!$redeemScript->getScriptHash()->equals($redeemScriptBuffer)) {
0 ignored issues
show
Documentation introduced by
$redeemScriptBuffer is of type object<BitWasp\Buffertools\BufferInterface>, but the function expects a object<self>.

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...
406
                throw new \InvalidArgumentException("Incorrect redeem script - hash doesn't match");
407
            }
408
409 24
            $results = []; // ???
410 24
            $solved = $solved && $this->doSignature($key, $redeemScript, $type, $results, 0) && $type !== OutputClassifier::PAYTOSCRIPTHASH;
411 24
            if ($solved) {
412 24
                $this->redeemScript = $redeemScript;
413 8
            }
414 8
        }
415
416 84
        if ($solved && $type === OutputClassifier::WITNESS_V0_KEYHASH) {
417 12
            $pubKeyHash = $return[0];
418 12
            $witnessScript = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
419 12
            $subType = null;
420 12
            $subResults = [];
421 12
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1);
422 76
        } else if ($solved && $type === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
423 18
            $scriptHash = $return[0];
424
425 18
            if (!$witnessScript instanceof ScriptInterface) {
426
                throw new \InvalidArgumentException('Must provide witness script for witness v0 scripthash');
427
            }
428
429 18
            if (!Hash::sha256($witnessScript->getBuffer())->getBinary() === $scriptHash->getBinary()) {
430
                throw new \InvalidArgumentException("Incorrect witness script - hash doesn't match");
431
            }
432
433 18
            $subType = null;
434 18
            $subResults = [];
435
436 18
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1)
437 18
                && $subType !== OutputClassifier::PAYTOSCRIPTHASH
438 18
                && $subType !== OutputClassifier::WITNESS_V0_SCRIPTHASH
439 18
                && $subType !== OutputClassifier::WITNESS_V0_KEYHASH;
440
441 18
            if ($solved) {
442 18
                $this->witnessScript = $witnessScript;
443 6
            }
444 6
        }
445
446 84
        return $solved;
447
    }
448
449
    /**
450
     * @param string $outputType
451
     * @param $answer
452
     * @return bool
453
     */
454 84
    private function serializeSimpleSig($outputType, &$answer)
455
    {
456 84
        if ($outputType === OutputClassifier::UNKNOWN) {
457
            throw new \RuntimeException('Cannot sign unknown script type');
458
        }
459
460 84
        if ($outputType === OutputClassifier::PAYTOPUBKEY && $this->isFullySigned()) {
461 12
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer()]), new ScriptWitness([]));
462 12
            return true;
463
        }
464
465 72
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH && $this->isFullySigned()) {
466 30
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]), new ScriptWitness([]));
467 30
            return true;
468
        }
469
470 48
        if ($outputType === OutputClassifier::MULTISIG) {
471 30
            $sequence = [Opcodes::OP_0];
472 30
            $nPubKeys = count($this->publicKeys);
473 30
            for ($i = 0; $i < $nPubKeys; $i++) {
474 30
                if (isset($this->signatures[$i])) {
475 30
                    $sequence[] = $this->signatures[$i]->getBuffer();
476 10
                }
477 10
            }
478
479 30
            $answer = new SigValues(ScriptFactory::sequence($sequence), new ScriptWitness([]));
480 30
            return true;
481
        }
482
483 42
        return false;
484
    }
485
486
    /**
487
     * @return SigValues
488
     */
489 84
    public function serializeSignatures()
490
    {
491 84
        static $emptyScript = null;
492 84
        static $emptyWitness = null;
493 84
        if (is_null($emptyScript) || is_null($emptyWitness)) {
494 6
            $emptyScript = new Script();
495 6
            $emptyWitness = new ScriptWitness([]);
496 2
        }
497
498
        /** @var BufferInterface[] $return */
499 84
        $outputType = $this->classifier->classify($this->txOut->getScript());
500
501
        /** @var SigValues $answer */
502 84
        $answer = new SigValues($emptyScript, $emptyWitness);
503 84
        $serialized = $this->serializeSimpleSig($outputType, $answer);
504
505 84
        $p2sh = false;
506 84
        if (!$serialized && $outputType === OutputClassifier::PAYTOSCRIPTHASH) {
507 24
            $p2sh = true;
508 24
            $outputType = $this->classifier->classify($this->redeemScript);
509 24
            $serialized = $this->serializeSimpleSig($outputType, $answer);
510 8
        }
511
512 84
        if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
513 12
            $answer = new SigValues($emptyScript, new ScriptWitness([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]));
514 76
        } else if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
515 18
            $outputType = $this->classifier->classify($this->witnessScript);
516 18
            $serialized = $this->serializeSimpleSig($outputType, $answer);
517
518 18
            if ($serialized) {
519 18
                $data = [];
520 18
                foreach ($answer->getScriptSig()->getScriptParser()->decode() as $o) {
521 18
                    $data[] = $o->getData();
522 6
                }
523
524 18
                $data[] = $this->witnessScript->getBuffer();
525 18
                $answer = new SigValues($emptyScript, new ScriptWitness($data));
526 6
            }
527 6
        }
528
529 84
        if ($p2sh) {
530 24
            $answer = new SigValues(
531 24
                ScriptFactory::create($answer->getScriptSig()->getBuffer())->push($this->redeemScript->getBuffer())->getScript(),
532 24
                $answer->getScriptWitness()
533 8
            );
534 8
        }
535
536 84
        return $answer;
537
    }
538
}
539