Skip to content

Commit dcfcb40

Browse files
committed
block refactor
1 parent f28ef6c commit dcfcb40

File tree

3 files changed

+112
-59
lines changed

3 files changed

+112
-59
lines changed

src/Block.php

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,9 @@
1414
class Block
1515
{
1616
/**
17-
* @var int
18-
*/
19-
public $version;
20-
21-
/**
22-
* @var string
23-
*/
24-
public $prevBlockHash;
25-
26-
/**
27-
* @var string
17+
* @var Header
2818
*/
29-
public $merkleRootHash;
30-
31-
/**
32-
* @var int
33-
*/
34-
public $time;
35-
36-
/**
37-
* @var int
38-
*/
39-
public $bits;
40-
41-
/**
42-
* @var int
43-
*/
44-
public $nonce;
19+
public $header;
4520

4621
/**
4722
* @var int
@@ -60,12 +35,7 @@ class Block
6035
static public function parse(Reader $stream): self
6136
{
6237
$block = new self;
63-
$block->version = $stream->readUInt32();
64-
$block->prevBlockHash = bin2hex(strrev($stream->read(32)));
65-
$block->merkleRootHash = bin2hex(strrev($stream->read(32)));
66-
$block->time = $stream->readUInt32();
67-
$block->bits = $stream->readUInt32();
68-
$block->nonce = $stream->readUInt32();
38+
$block->header = Header::parse($stream);
6939
$block->transactionsCount = $stream->readVarInt();
7040

7141
for ($i = 0; $i < $block->transactionsCount; $i++) {
@@ -81,25 +51,13 @@ static public function parse(Reader $stream): self
8151
*/
8252
public function serialize(Writer $stream): self
8353
{
84-
$stream->writeUInt32($this->version);
85-
$stream->write(strrev(hex2bin($this->prevBlockHash)));
86-
$stream->write(strrev(hex2bin($this->merkleRootHash)));
87-
$stream->writeUInt32($this->time);
88-
$stream->writeUInt32($this->bits);
89-
$stream->writeUInt32($this->nonce);
90-
return $this;
91-
}
54+
$this->header->serialize($stream);
55+
$stream->writeVarInt(count($this->transactions));
9256

93-
/**
94-
* @return string
95-
*/
96-
public function getHash(): string
97-
{
98-
$stream = new Writer();
99-
$this->serialize($stream);
100-
$hash = Utils::hash($stream->getBuffer(), true);
101-
$hash = strrev($hash);
102-
$hash = bin2hex($hash);
103-
return $hash;
57+
foreach ($this->transactions as $transaction) {
58+
$transaction->serialize($stream);
59+
}
60+
61+
return $this;
10462
}
10563
}

src/Header.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AndKom\PhpBitcoinBlockchain;
6+
7+
use AndKom\BCDataStream\Reader;
8+
use AndKom\BCDataStream\Writer;
9+
10+
/**
11+
* Class Header
12+
* @package AndKom\PhpBitcoinBlockchain
13+
*/
14+
class Header
15+
{
16+
/**
17+
* @var int
18+
*/
19+
public $version;
20+
21+
/**
22+
* @var string
23+
*/
24+
public $prevBlockHash;
25+
26+
/**
27+
* @var string
28+
*/
29+
public $merkleRootHash;
30+
31+
/**
32+
* @var int
33+
*/
34+
public $time;
35+
36+
/**
37+
* @var int
38+
*/
39+
public $bits;
40+
41+
/**
42+
* @var int
43+
*/
44+
public $nonce;
45+
46+
/**
47+
* @param Reader $stream
48+
* @return Header
49+
*/
50+
static public function parse(Reader $stream): self
51+
{
52+
$header = new self;
53+
$header->version = $stream->readUInt32();
54+
$header->prevBlockHash = bin2hex(strrev($stream->read(32)));
55+
$header->merkleRootHash = bin2hex(strrev($stream->read(32)));
56+
$header->time = $stream->readUInt32();
57+
$header->bits = $stream->readUInt32();
58+
$header->nonce = $stream->readUInt32();
59+
return $header;
60+
}
61+
62+
/**
63+
* @param Writer $stream
64+
* @return Header
65+
*/
66+
public function serialize(Writer $stream): self
67+
{
68+
$stream->writeUInt32($this->version);
69+
$stream->write(strrev(hex2bin($this->prevBlockHash)));
70+
$stream->write(strrev(hex2bin($this->merkleRootHash)));
71+
$stream->writeUInt32($this->time);
72+
$stream->writeUInt32($this->bits);
73+
$stream->writeUInt32($this->nonce);
74+
return $this;
75+
}
76+
77+
/**
78+
* @return string
79+
*/
80+
public function getHash(): string
81+
{
82+
$stream = new Writer();
83+
$this->serialize($stream);
84+
$hash = Utils::hash($stream->getBuffer(), true);
85+
$hash = strrev($hash);
86+
$hash = bin2hex($hash);
87+
return $hash;
88+
}
89+
}

tests/BlockTest.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace AndKom\PhpBitcoinBlockchain\Tests;
66

77
use AndKom\BCDataStream\Reader;
8+
use AndKom\BCDataStream\Writer;
89
use AndKom\PhpBitcoinBlockchain\Block;
910
use PHPUnit\Framework\TestCase;
1011

@@ -32,13 +33,13 @@ public function testParse()
3233
$genesis .= "00000000"; // lock time
3334

3435
$block = Block::parse(new Reader(hex2bin($genesis)));
35-
$this->assertEquals($block->getHash(), '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
36-
$this->assertEquals($block->version, 1);
37-
$this->assertEquals($block->prevBlockHash, '0000000000000000000000000000000000000000000000000000000000000000');
38-
$this->assertEquals($block->merkleRootHash, '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b');
39-
$this->assertEquals($block->time, 1231006505);
40-
$this->assertEquals($block->bits, 486604799);
41-
$this->assertEquals($block->nonce, 2083236893);
36+
$this->assertEquals($block->header->getHash(), '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
37+
$this->assertEquals($block->header->version, 1);
38+
$this->assertEquals($block->header->prevBlockHash, '0000000000000000000000000000000000000000000000000000000000000000');
39+
$this->assertEquals($block->header->merkleRootHash, '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b');
40+
$this->assertEquals($block->header->time, 1231006505);
41+
$this->assertEquals($block->header->bits, 486604799);
42+
$this->assertEquals($block->header->nonce, 2083236893);
4243
$this->assertEquals($block->transactions[0]->getHash(), '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b');
4344
$this->assertEquals($block->transactions[0]->version, 1);
4445
$this->assertEquals($block->transactions[0]->inCount, 1);
@@ -50,5 +51,10 @@ public function testParse()
5051
$this->assertEquals($block->transactions[0]->outputs[0]->scriptPubKey->getData(), hex2bin('4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac'));
5152
$this->assertEquals($block->transactions[0]->lockTime, 0);
5253
$this->assertTrue($block->transactions[0]->isCoinbase());
54+
55+
$stream = new Writer();
56+
$block->serialize($stream);
57+
58+
$this->assertEquals($stream->getBuffer(), hex2bin($genesis));
5359
}
5460
}

0 commit comments

Comments
 (0)