Completed
Pull Request — master (#386)
by thomas
112:49 queued 42:55
created

Signer::signer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 3
dl 0
loc 8
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\Bitcoin;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface;
8
use BitWasp\Bitcoin\Script\ScriptInterface;
9
use BitWasp\Bitcoin\Transaction\SignatureHash\SigHashInterface;
10
use BitWasp\Bitcoin\Transaction\TransactionFactory;
11
use BitWasp\Bitcoin\Transaction\TransactionInterface;
12
use BitWasp\Bitcoin\Transaction\TransactionOutputInterface;
13
14
class Signer
15
{
16
    /**
17
     * @var EcAdapterInterface
18
     */
19
    private $ecAdapter;
20
21
    /**
22
     * @var TransactionInterface
23
     */
24
    private $tx;
25
26
    /**
27
     * @var InputSigner[]
28
     */
29
    private $signatureCreator = [];
30
31
    /**
32
     * TxWitnessSigner constructor.
33
     * @param TransactionInterface $tx
34
     * @param EcAdapterInterface $ecAdapter
35
     */
36 84
    public function __construct(TransactionInterface $tx, EcAdapterInterface $ecAdapter = null)
37
    {
38 84
        $this->tx = $tx;
39 84
        $this->ecAdapter = $ecAdapter ?: Bitcoin::getEcAdapter();
40 84
    }
41
42
    /**
43
     * @param int $nIn
44
     * @param PrivateKeyInterface $key
45
     * @param TransactionOutputInterface $txOut
46
     * @param ScriptInterface|null $redeemScript
47
     * @param ScriptInterface|null $witnessScript
48
     * @param int $sigHashType
49
     * @return $this
50
     */
51 84
    public function sign($nIn, PrivateKeyInterface $key, TransactionOutputInterface $txOut, ScriptInterface $redeemScript = null, ScriptInterface $witnessScript = null, $sigHashType = SigHashInterface::ALL)
52
    {
53 84
        $signData = new SignData();
54 84
        if ($redeemScript) {
55 28
            $signData->p2sh($redeemScript);
56
        }
57 84
        if ($witnessScript) {
58
            $signData->p2wsh($witnessScript);
59
        }
60
61 84
        if (!$this->signer($nIn, $txOut, $signData)->sign($key, $sigHashType)) {
62
            throw new \RuntimeException('Unsignable script');
63
        }
64
65
        return $this;
66
    }
67 84
68
    /**
69 84
     * @param int $nIn
70 84
     * @param TransactionOutputInterface $txOut
71 84
     * @param SignData $signData
72 84
     * @return InputSigner
73 84
     */
74 84
    public function signer($nIn, TransactionOutputInterface $txOut, SignData $signData)
0 ignored issues
show
Best Practice introduced by
Using PHP4-style constructors that are named like the class is not recommend; better use the more explicit __construct method.
Loading history...
75 28
    {
76
        if (!isset($this->signatureCreator[$nIn])) {
77 84
            $this->signatureCreator[$nIn] = new InputSigner($this->ecAdapter, $this->tx, $nIn, $txOut, $signData);
78 84
        }
79 28
80
        return $this->signatureCreator[$nIn];
81 84
    }
82 84
83
    /**
84
     * @return TransactionInterface
85
     */
86
    public function get()
87
    {
88
        $mutable = TransactionFactory::mutate($this->tx);
89
        $witnesses = [];
90
        foreach ($mutable->inputsMutator() as $idx => $input) {
91
            $sig = $this->signatureCreator[$idx]->serializeSignatures();
92
            $input->script($sig->getScriptSig());
93
            $witnesses[$idx] = $sig->getScriptWitness();
94
        }
95
96
        if (count($witnesses) > 0) {
97
            $mutable->witness($witnesses);
98
        }
99
100
        $new = $mutable->done();
101
        return $new;
102
    }
103
}
104