Completed
Pull Request — master (#446)
by thomas
27:20 queued 18:57
created

TransactionSerializer::parse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BitWasp\Bitcoin\Serializer\Transaction;
4
5
use BitWasp\Bitcoin\Serializer\Script\ScriptWitnessSerializer;
6
use BitWasp\Bitcoin\Serializer\Types;
7
use BitWasp\Bitcoin\Transaction\Transaction;
8
use BitWasp\Bitcoin\Transaction\TransactionInterface;
9
use BitWasp\Buffertools\BufferInterface;
10
use BitWasp\Buffertools\Parser;
11
12
class TransactionSerializer implements TransactionSerializerInterface
13
{
14
    const NO_WITNESS = 1;
15
16
    /**
17
     * @var \BitWasp\Buffertools\Types\Int32
18
     */
19
    private $int32le;
20
21
    /**
22
     * @var \BitWasp\Buffertools\Types\Uint32
23
     */
24
    private $uint32le;
25
26
    /**
27
     * @var \BitWasp\Buffertools\Types\VarInt
28
     */
29
    private $varint;
30
31
    /**
32
     * @var TransactionInputSerializer
33
     */
34
    private $inputSerializer;
35
36
    /**
37
     * @var TransactionOutputSerializer
38
     */
39
    private $outputSerializer;
40
41
    /**
42
     * @var ScriptWitnessSerializer
43
     */
44
    private $witnessSerializer;
45
46 1332
    public function __construct(TransactionInputSerializer $inputSerializer = null, TransactionOutputSerializer $outputSerializer = null, ScriptWitnessSerializer $witnessSerializer = null)
47
    {
48 1332
        $this->int32le = Types::int32le();
49 1332
        $this->uint32le = Types::uint32le();
50 1332
        $this->varint = Types::varint();
51
52 1332
        $this->inputSerializer = $inputSerializer ?: new TransactionInputSerializer(new OutPointSerializer());
53 1332
        $this->outputSerializer = $outputSerializer ?: new TransactionOutputSerializer;
54 1332
        $this->witnessSerializer = $witnessSerializer ?: new ScriptWitnessSerializer();
55 1332
    }
56
57
    /**
58
     * @param Parser $parser
59
     * @return TransactionInterface
60
     */
61 62
    public function fromParser(Parser $parser)
62
    {
63 62
        $version = $this->int32le->read($parser);
64
65 62
        $vin = [];
66 62
        $vinCount = $this->varint->read($parser);
67 62
        for ($i = 0; $i < $vinCount; $i++) {
68 62
            $vin[] = $this->inputSerializer->fromParser($parser);
69
        }
70
71 62
        $vout = [];
72 62
        $flags = 0;
73 62
        if (count($vin) === 0) {
74
            $flags = (int) $this->varint->read($parser);
75
            if ($flags !== 0) {
76
                $vinCount = $this->varint->read($parser);
77
                for ($i = 0; $i < $vinCount; $i++) {
78
                    $vin[] = $this->inputSerializer->fromParser($parser);
79
                }
80
81
                $voutCount = $this->varint->read($parser);
82
                for ($i = 0; $i < $voutCount; $i++) {
83
                    $vout[] = $this->outputSerializer->fromParser($parser);
84
                }
85
            }
86
        } else {
87 62
            $voutCount = $this->varint->read($parser);
88 62
            for ($i = 0; $i < $voutCount; $i++) {
89 62
                $vout[] = $this->outputSerializer->fromParser($parser);
90
            }
91
        }
92
93 62
        $vwit = [];
94 62
        if (($flags & 1)) {
95
            $flags ^= 1;
96
            $witCount = count($vin);
97
            for ($i = 0; $i < $witCount; $i++) {
98
                $vectorCount = $this->varint->read($parser);
99
                $vwit[] = $this->witnessSerializer->fromParser($parser, $vectorCount);
100
            }
101
        }
102
103 62
        if ($flags) {
104
            throw new \RuntimeException('Flags byte was 0');
105
        }
106
107 62
        $lockTime = $this->uint32le->read($parser);
108
109 62
        return new Transaction($version, $vin, $vout, $vwit, $lockTime);
110
    }
111
112
    /**
113
     * @param string|BufferInterface $data
114
     * @return TransactionInterface
115
     */
116 40
    public function parse($data)
117
    {
118 40
        return $this->fromParser(new Parser($data));
119
    }
120
121
    /**
122
     * @param TransactionInterface $transaction
123
     * @param int $opt
124
     * @return BufferInterface
125
     */
126 1306
    public function serialize(TransactionInterface $transaction, $opt = 0)
127
    {
128 1306
        $parser = new Parser();
129 1306
        $parser->appendBinary($this->int32le->write($transaction->getVersion()));
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
130
131 1306
        $flags = 0;
132 1306
        $allowWitness = !($opt & self::NO_WITNESS);
133 1306
        if ($allowWitness && $transaction->hasWitness()) {
134 22
            $flags |= 1;
135
        }
136
137 1306
        if ($flags) {
138 22
            $parser->appendBinary(pack("CC", 0, $flags));
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
        }
140
141 1306
        $parser->appendBinary($this->varint->write(count($transaction->getInputs())), true);
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142 1306
        foreach ($transaction->getInputs() as $input) {
143 1304
            $parser->appendBuffer($this->inputSerializer->serialize($input));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
        }
145
146 1306
        $parser->appendBinary($this->varint->write(count($transaction->getOutputs())), true);
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
147 1306
        foreach ($transaction->getOutputs() as $output) {
148 1302
            $parser->appendBuffer($this->outputSerializer->serialize($output));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149
        }
150
151 1306
        if ($flags & 1) {
152 22
            foreach ($transaction->getWitnesses() as $witness) {
153 22
                $parser->appendBuffer($this->witnessSerializer->serialize($witness));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
154
            }
155
        }
156
157 1306
        $parser->writeRawBinary(4, $this->uint32le->write($transaction->getLockTime()));
0 ignored issues
show
Bug introduced by
The method writeRawBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
159 1306
        return $parser->getBuffer();
160
    }
161
}
162