@@ -42,11 +42,32 @@ type txJSON struct {
4242 V * hexutil.Big `json:"v"`
4343 R * hexutil.Big `json:"r"`
4444 S * hexutil.Big `json:"s"`
45+ YParity * hexutil.Uint64 `json:"yParity,omitempty"`
4546
4647 // Only used for encoding:
4748 Hash common.Hash `json:"hash"`
4849}
4950
51+ // yParityValue returns the YParity value from JSON. For backwards-compatibility reasons,
52+ // this can be given in the 'v' field or the 'yParity' field. If both exist, they must match.
53+ func (tx * txJSON ) yParityValue () (* big.Int , error ) {
54+ if tx .YParity != nil {
55+ val := uint64 (* tx .YParity )
56+ if val != 0 && val != 1 {
57+ return nil , errInvalidYParity
58+ }
59+ bigval := new (big.Int ).SetUint64 (val )
60+ if tx .V != nil && tx .V .ToInt ().Cmp (bigval ) != 0 {
61+ return nil , errVYParityMismatch
62+ }
63+ return bigval , nil
64+ }
65+ if tx .V != nil {
66+ return tx .V .ToInt (), nil
67+ }
68+ return nil , errVYParityMissing
69+ }
70+
5071// MarshalJSON marshals as JSON with a hash.
5172func (tx * Transaction ) MarshalJSON () ([]byte , error ) {
5273 var enc txJSON
@@ -79,6 +100,8 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
79100 enc .V = (* hexutil .Big )(itx .V )
80101 enc .R = (* hexutil .Big )(itx .R )
81102 enc .S = (* hexutil .Big )(itx .S )
103+ yparity := itx .V .Uint64 ()
104+ enc .YParity = (* hexutil .Uint64 )(& yparity )
82105
83106 case * DynamicFeeTx :
84107 enc .ChainID = (* hexutil .Big )(itx .ChainID )
@@ -93,14 +116,17 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
93116 enc .V = (* hexutil .Big )(itx .V )
94117 enc .R = (* hexutil .Big )(itx .R )
95118 enc .S = (* hexutil .Big )(itx .S )
119+ yparity := itx .V .Uint64 ()
120+ enc .YParity = (* hexutil .Uint64 )(& yparity )
96121 }
97122 return json .Marshal (& enc )
98123}
99124
100125// UnmarshalJSON unmarshals from JSON.
101126func (tx * Transaction ) UnmarshalJSON (input []byte ) error {
102127 var dec txJSON
103- if err := json .Unmarshal (input , & dec ); err != nil {
128+ err := json .Unmarshal (input , & dec )
129+ if err != nil {
104130 return err
105131 }
106132
@@ -134,20 +160,22 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
134160 }
135161 itx .Data = * dec .Input
136162
137- if dec .V == nil {
138- return errors .New ("missing required field 'v' in transaction" )
139- }
140- itx .V = (* big .Int )(dec .V )
163+ // signature R
141164 if dec .R == nil {
142165 return errors .New ("missing required field 'r' in transaction" )
143166 }
144167 itx .R = (* big .Int )(dec .R )
168+ // signature S
145169 if dec .S == nil {
146170 return errors .New ("missing required field 's' in transaction" )
147171 }
148172 itx .S = (* big .Int )(dec .S )
149- withSignature := itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0
150- if withSignature {
173+ // signature V
174+ if dec .V == nil {
175+ return errors .New ("missing required field 'v' in transaction" )
176+ }
177+ itx .V = (* big .Int )(dec .V )
178+ if itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0 {
151179 if err := sanityCheckSignature (itx .V , itx .R , itx .S , true ); err != nil {
152180 return err
153181 }
@@ -187,20 +215,22 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
187215 itx .AccessList = * dec .AccessList
188216 }
189217
190- if dec .V == nil {
191- return errors .New ("missing required field 'v' in transaction" )
192- }
193- itx .V = (* big .Int )(dec .V )
218+ // signature R
194219 if dec .R == nil {
195220 return errors .New ("missing required field 'r' in transaction" )
196221 }
197222 itx .R = (* big .Int )(dec .R )
223+ // signature S
198224 if dec .S == nil {
199225 return errors .New ("missing required field 's' in transaction" )
200226 }
201227 itx .S = (* big .Int )(dec .S )
202- withSignature := itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0
203- if withSignature {
228+ // signature V
229+ itx .V , err = dec .yParityValue ()
230+ if err != nil {
231+ return err
232+ }
233+ if itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0 {
204234 if err := sanityCheckSignature (itx .V , itx .R , itx .S , false ); err != nil {
205235 return err
206236 }
@@ -244,20 +274,22 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
244274 itx .AccessList = * dec .AccessList
245275 }
246276
247- if dec .V == nil {
248- return errors .New ("missing required field 'v' in transaction" )
249- }
250- itx .V = (* big .Int )(dec .V )
277+ // signature R
251278 if dec .R == nil {
252279 return errors .New ("missing required field 'r' in transaction" )
253280 }
254281 itx .R = (* big .Int )(dec .R )
282+ // signature S
255283 if dec .S == nil {
256284 return errors .New ("missing required field 's' in transaction" )
257285 }
258286 itx .S = (* big .Int )(dec .S )
259- withSignature := itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0
260- if withSignature {
287+ // signature V
288+ itx .V , err = dec .yParityValue ()
289+ if err != nil {
290+ return err
291+ }
292+ if itx .V .Sign () != 0 || itx .R .Sign () != 0 || itx .S .Sign () != 0 {
261293 if err := sanityCheckSignature (itx .V , itx .R , itx .S , false ); err != nil {
262294 return err
263295 }
0 commit comments