@@ -21,7 +21,7 @@ class Transaction
2121 /**
2222 * @var int
2323 */
24- public $ flag ;
24+ public $ isSegwit = false ;
2525
2626 /**
2727 * @var int
@@ -43,11 +43,6 @@ class Transaction
4343 */
4444 public $ outputs = [];
4545
46- /**
47- * @var array
48- */
49- public $ witnesses = [];
50-
5146 /**
5247 * @var int
5348 */
@@ -61,6 +56,13 @@ static public function parse(Reader $stream): self
6156 {
6257 $ tx = new self ;
6358 $ tx ->version = $ stream ->readUInt32 ();
59+
60+ $ tx ->isSegwit = $ stream ->read (2 ) == "\x00\x01" ;
61+
62+ if (!$ tx ->isSegwit ) {
63+ $ stream ->setPosition ($ stream ->getPosition () - 2 );
64+ }
65+
6466 $ tx ->inCount = $ stream ->readVarInt ();
6567
6668 for ($ i = 0 ; $ i < $ tx ->inCount ; $ i ++) {
@@ -73,18 +75,33 @@ static public function parse(Reader $stream): self
7375 $ tx ->outputs [] = Output::parse ($ stream );
7476 }
7577
78+ if ($ tx ->isSegwit ) {
79+ foreach ($ tx ->inputs as $ input ) {
80+ $ count = $ stream ->readVarInt ();
81+ for ($ i = 0 ; $ i < $ count ; $ i ++) {
82+ $ input ->witnesses [] = $ stream ->readString ();
83+ }
84+ }
85+ }
86+
7687 $ tx ->lockTime = $ stream ->readInt32 ();
7788
7889 return $ tx ;
7990 }
8091
8192 /**
8293 * @param Writer $stream
94+ * @param bool $segWit
8395 * @return Transaction
8496 */
85- public function serialize (Writer $ stream ): self
97+ public function serialize (Writer $ stream, bool $ segWit = true ): self
8698 {
8799 $ stream ->writeUInt32 ($ this ->version );
100+
101+ if ($ this ->isSegwit && $ segWit ) {
102+ $ stream ->write ("\x00\x01" );
103+ }
104+
88105 $ stream ->writeVarInt ($ this ->inCount );
89106
90107 foreach ($ this ->inputs as $ in ) {
@@ -97,18 +114,29 @@ public function serialize(Writer $stream): self
97114 $ out ->serialize ($ stream );
98115 }
99116
117+ if ($ this ->isSegwit && $ segWit ) {
118+ foreach ($ this ->inputs as $ input ) {
119+ $ stream ->writeVarInt (count ($ input ->witnesses ));
120+
121+ foreach ($ input ->witnesses as $ witness ) {
122+ $ stream ->writeString ($ witness );
123+ }
124+ }
125+ }
126+
100127 $ stream ->writeInt32 ($ this ->lockTime );
101128
102129 return $ this ;
103130 }
104131
105132 /**
133+ * @param bool $segWit
106134 * @return string
107135 */
108- public function getHash (): string
136+ public function getHash (bool $ segWit = false ): string
109137 {
110138 $ stream = new Writer ();
111- $ this ->serialize ($ stream );
139+ $ this ->serialize ($ stream, $ segWit );
112140 $ hash = Utils::hash ($ stream ->getBuffer (), true );
113141 $ hash = strrev ($ hash );
114142 $ hash = bin2hex ($ hash );
0 commit comments