Completed
Pull Request — master (#380)
by thomas
143:23 queued 73:21
created

InputSigner::calculateSigHash()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 10
ccs 6
cts 6
cp 1
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\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 ScriptInterface $scriptCode
257
     * @param int $sigVersion
258
     * @return BufferInterface
259
     */
260
    public function calculateSigHash(ScriptInterface $scriptCode, $sigVersion)
261 84
    {
262
        if ($sigVersion === 1) {
263 84
            $hasher = new V1Hasher($this->tx, $this->txOut->getValue());
264 30
        } else {
265 10
            $hasher = new Hasher($this->tx);
266 54
        }
267
268
        return $hasher->calculate($scriptCode, $this->nInput, $this->sigHashType);
269 84
    }
270
271 84
    /**
272 84
     * @param PrivateKeyInterface $key
273 84
     * @param ScriptInterface $scriptCode
274 28
     * @param int $sigVersion
275 28
     * @return TransactionSignature
276 84
     */
277 84
    public function calculateSignature(PrivateKeyInterface $key, ScriptInterface $scriptCode, $sigVersion)
278 28
    {
279 28
        $hash = $this->calculateSigHash($scriptCode, $sigVersion);
280 56
        return new TransactionSignature(
281 28
            $this->ecAdapter,
282 28
            $this->ecAdapter->sign(
283 84
                $hash,
284 28
                $key,
285
                new Rfc6979(
286
                    $this->ecAdapter,
287
                    $key,
288
                    $hash,
289
                    'sha256'
290 78
                )
291
            ),
292 78
            $this->sigHashType
293
        );
294
    }
295
296
    /**
297
     * @return bool
298
     */
299
    public function isFullySigned()
300
    {
301
        return $this->requiredSigs !== 0 && $this->requiredSigs === count($this->signatures);
302
    }
303
304
    /**
305 84
     * The function only returns true when $scriptPubKey could be classified
306
     *
307 84
     * @param PrivateKeyInterface $key
308 84
     * @param ScriptInterface $scriptPubKey
309 84
     * @param string $outputType
310
     * @param BufferInterface[] $results
311
     * @param int $sigVersion
312
     * @return bool
313 84
     */
314
    private function doSignature(PrivateKeyInterface $key, ScriptInterface $scriptPubKey, &$outputType, array &$results, $sigVersion = 0)
315 12
    {
316 12
        $return = [];
317 12
        $outputType = $this->classifier->classify($scriptPubKey, $return);
318 12
        if ($outputType === OutputClassifier::UNKNOWN) {
319 4
            throw new \RuntimeException('Cannot sign unknown script type');
320
        }
321 12
322
        if ($outputType === OutputClassifier::PAYTOPUBKEY) {
323
            /** @var BufferInterface $return */
324 72
            $results[] = $return;
325
            $this->requiredSigs = 1;
326 42
            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...
327 42
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
328 42
            }
329 36
330 36
            return true;
331 12
        }
332
333 42
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH) {
334
            /** @var BufferInterface $return */
335
            $results[] = $return;
336 48
            $this->requiredSigs = 1;
337 30
            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...
338 30
                $this->signatures[0] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
339 30
                $this->publicKeys[0] = $key->getPublicKey();
340
            }
341 30
342 30
            return true;
343 30
        }
344 30
345 30
        if ($outputType === OutputClassifier::MULTISIG) {
346 10
            $info = new Multisig($scriptPubKey);
347 10
            $this->publicKeys = $info->getKeys();
348
            $this->requiredSigs = $info->getKeyCount();
349 30
350
            $myKey = $key->getPublicKey()->getBuffer();
351
            foreach ($info->getKeys() as $keyIdx => $publicKey) {
352 42
                $results[] = $publicKey->getBuffer();
353
                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...
354 24
                    $this->signatures[$keyIdx] = $this->calculateSignature($key, $scriptPubKey, $sigVersion);
355 24
                }
356 24
            }
357
358
            return true;
359 30
        }
360
361 12
        if ($outputType === OutputClassifier::PAYTOSCRIPTHASH) {
362 12
            /** @var BufferInterface $scriptHash */
363 12
            $scriptHash = $return;
364
            $results[] = $scriptHash;
365 12
            return true;
366 12
        }
367 12
368 12
        if ($outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
369 4
            /** @var BufferInterface $pubKeyHash */
370
            $pubKeyHash = $return;
371 12
            $results[] = $pubKeyHash;
372
            $this->requiredSigs = 1;
373
374 18
            if ($pubKeyHash->getBinary() === $key->getPublicKey()->getPubKeyHash()->getBinary()) {
375
                $script = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
376 18
                $this->signatures[0] = $this->calculateSignature($key, $script, 1);
377 18
                $this->publicKeys[0] = $key->getPublicKey();
378
            }
379 18
380
            return true;
381
        }
382
383
        if ($outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
384
            /** @var BufferInterface $scriptHash */
385
            $scriptHash = $return;
386
            $results[] = $scriptHash;
387
388
            return true;
389
        }
390
391 84
        return false;
392
    }
393
394 84
    /**
395 84
     * @param PrivateKeyInterface $key
396 84
     * @param ScriptInterface|null $redeemScript
397
     * @param ScriptInterface|null $witnessScript
398 84
     * @return bool
399 24
     */
400
    public function sign(PrivateKeyInterface $key, ScriptInterface $redeemScript = null, ScriptInterface $witnessScript = null)
401 24
    {
402
        /** @var BufferInterface[] $return */
403
        $type = null;
404
        $return = [];
405 24
        $solved = $this->doSignature($key, $this->txOut->getScript(), $type, $return, 0);
406
407
        if ($solved && $type === OutputClassifier::PAYTOSCRIPTHASH) {
408
            $redeemScriptBuffer = $return[0];
409 24
410 24
            if (!$redeemScript instanceof ScriptInterface) {
411 24
                throw new \InvalidArgumentException('Must provide redeem script for P2SH');
412 24
            }
413 8
414 8
            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...
415
                throw new \InvalidArgumentException("Incorrect redeem script - hash doesn't match");
416 84
            }
417 12
418 12
            $results = []; // ???
419 12
            $solved = $solved && $this->doSignature($key, $redeemScript, $type, $results, 0) && $type !== OutputClassifier::PAYTOSCRIPTHASH;
420 12
            if ($solved) {
421 12
                $this->redeemScript = $redeemScript;
422 76
            }
423 18
        }
424
425 18
        if ($solved && $type === OutputClassifier::WITNESS_V0_KEYHASH) {
426
            $pubKeyHash = $return[0];
427
            $witnessScript = ScriptFactory::sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $pubKeyHash, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG]);
428
            $subType = null;
429 18
            $subResults = [];
430
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1);
431
        } else if ($solved && $type === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
432
            $scriptHash = $return[0];
433 18
434 18
            if (!$witnessScript instanceof ScriptInterface) {
435
                throw new \InvalidArgumentException('Must provide witness script for witness v0 scripthash');
436 18
            }
437 18
438 18
            if (!Hash::sha256($witnessScript->getBuffer())->getBinary() === $scriptHash->getBinary()) {
439 18
                throw new \InvalidArgumentException("Incorrect witness script - hash doesn't match");
440
            }
441 18
442 18
            $subType = null;
443 6
            $subResults = [];
444 6
445
            $solved = $solved && $this->doSignature($key, $witnessScript, $subType, $subResults, 1)
446 84
                && $subType !== OutputClassifier::PAYTOSCRIPTHASH
447
                && $subType !== OutputClassifier::WITNESS_V0_SCRIPTHASH
448
                && $subType !== OutputClassifier::WITNESS_V0_KEYHASH;
449
450
            if ($solved) {
451
                $this->witnessScript = $witnessScript;
452
            }
453
        }
454 84
455
        return $solved;
456 84
    }
457
458
    /**
459
     * @param string $outputType
460 84
     * @param $answer
461 12
     * @return bool
462 12
     */
463
    private function serializeSimpleSig($outputType, &$answer)
464
    {
465 72
        if ($outputType === OutputClassifier::UNKNOWN) {
466 30
            throw new \RuntimeException('Cannot sign unknown script type');
467 30
        }
468
469
        if ($outputType === OutputClassifier::PAYTOPUBKEY && $this->isFullySigned()) {
470 48
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer()]), new ScriptWitness([]));
471 30
            return true;
472 30
        }
473 30
474 30
        if ($outputType === OutputClassifier::PAYTOPUBKEYHASH && $this->isFullySigned()) {
475 30
            $answer = new SigValues(ScriptFactory::sequence([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]), new ScriptWitness([]));
476 10
            return true;
477 10
        }
478
479 30
        if ($outputType === OutputClassifier::MULTISIG) {
480 30
            $sequence = [Opcodes::OP_0];
481
            $nPubKeys = count($this->publicKeys);
482
            for ($i = 0; $i < $nPubKeys; $i++) {
483 42
                if (isset($this->signatures[$i])) {
484
                    $sequence[] = $this->signatures[$i]->getBuffer();
485
                }
486
            }
487
488
            $answer = new SigValues(ScriptFactory::sequence($sequence), new ScriptWitness([]));
489 84
            return true;
490
        }
491 84
492 84
        return false;
493 84
    }
494 6
495 6
    /**
496 2
     * @return SigValues
497
     */
498
    public function serializeSignatures()
499 84
    {
500
        static $emptyScript = null;
501
        static $emptyWitness = null;
502 84
        if (is_null($emptyScript) || is_null($emptyWitness)) {
503 84
            $emptyScript = new Script();
504
            $emptyWitness = new ScriptWitness([]);
505 84
        }
506 84
507 24
        /** @var BufferInterface[] $return */
508 24
        $outputType = $this->classifier->classify($this->txOut->getScript());
509 24
510 8
        /** @var SigValues $answer */
511
        $answer = new SigValues($emptyScript, $emptyWitness);
512 84
        $serialized = $this->serializeSimpleSig($outputType, $answer);
513 12
514 76
        $p2sh = false;
515 18
        if (!$serialized && $outputType === OutputClassifier::PAYTOSCRIPTHASH) {
516 18
            $p2sh = true;
517
            $outputType = $this->classifier->classify($this->redeemScript);
518 18
            $serialized = $this->serializeSimpleSig($outputType, $answer);
519 18
        }
520 18
521 18
        if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_KEYHASH) {
522 6
            $answer = new SigValues($emptyScript, new ScriptWitness([$this->signatures[0]->getBuffer(), $this->publicKeys[0]->getBuffer()]));
523
        } else if (!$serialized && $outputType === OutputClassifier::WITNESS_V0_SCRIPTHASH) {
524 18
            $outputType = $this->classifier->classify($this->witnessScript);
525 18
            $serialized = $this->serializeSimpleSig($outputType, $answer);
526 6
527 6
            if ($serialized) {
528
                $data = [];
529 84
                foreach ($answer->getScriptSig()->getScriptParser()->decode() as $o) {
530 24
                    $data[] = $o->getData();
531 24
                }
532 24
533 8
                $data[] = $this->witnessScript->getBuffer();
534 8
                $answer = new SigValues($emptyScript, new ScriptWitness($data));
535
            }
536 84
        }
537
538
        if ($p2sh) {
539
            $answer = new SigValues(
540
                ScriptFactory::create($answer->getScriptSig()->getBuffer())->push($this->redeemScript->getBuffer())->getScript(),
541
                $answer->getScriptWitness()
542
            );
543
        }
544
545
        return $answer;
546
    }
547
}
548