@@ -49,6 +49,36 @@ public void Validate_Secp256k1SignsCanonicalHashWithExplicitSigner_ReturnsTrue()
4949 Assert . That ( error , Is . Null ) ;
5050 }
5151
52+ [ Test ]
53+ public void Validate_Secp256k1BlobCarryingTx_ReturnsTrueAndResolvesSigner ( )
54+ {
55+ // A blob-carrying frame tx: the blob fields are in the sig-hash preimage (EIP-8141 /
56+ // EELS #3047), so a signature computed over that hash validates and resolves the signer.
57+ Transaction tx = CreateFrameTx ( ) ;
58+ tx . MaxFeePerBlobGas = 3 ;
59+ tx . BlobVersionedHashes = [ BlobVersionedHash ( 0x01 ) , BlobVersionedHash ( 0x02 ) ] ;
60+ tx . FrameSignatures = [ Secp256k1Entry ( tx , TestItem . PrivateKeyB , signer : TestItem . PrivateKeyB . Address ) ] ;
61+
62+ Assert . That ( Validate ( tx , out string ? error ) , Is . True ) ;
63+ Assert . That ( error , Is . Null ) ;
64+ }
65+
66+ [ Test ]
67+ public void Validate_BlobFieldTamperedAfterSigning_ReturnsFalse ( )
68+ {
69+ // The signature commits to the blob fields; mutating one after signing must invalidate it,
70+ // proving the sig-hash preimage covers max_fee_per_blob_gas and blob_versioned_hashes.
71+ Transaction tx = CreateFrameTx ( ) ;
72+ tx . MaxFeePerBlobGas = 3 ;
73+ tx . BlobVersionedHashes = [ BlobVersionedHash ( 0x01 ) ] ;
74+ tx . FrameSignatures = [ Secp256k1Entry ( tx , TestItem . PrivateKeyB , signer : TestItem . PrivateKeyB . Address ) ] ;
75+
76+ tx . BlobVersionedHashes = [ BlobVersionedHash ( 0x02 ) ] ;
77+
78+ Assert . That ( Validate ( tx , out string ? error ) , Is . False ) ;
79+ Assert . That ( error , Is . EqualTo ( FrameTxSignatureValidator . InvalidSignature ) ) ;
80+ }
81+
5282 [ Test ]
5383 public void Validate_Secp256k1WithAbsentSigner_ResolvesToTxSender ( )
5484 {
@@ -327,6 +357,13 @@ private static byte[] ToVrs(Signature signature)
327357 return bytes ;
328358 }
329359
360+ private static byte [ ] BlobVersionedHash ( byte fill )
361+ {
362+ byte [ ] hash = new byte [ Hash256 . Size ] ;
363+ hash . AsSpan ( ) . Fill ( fill ) ;
364+ return hash ;
365+ }
366+
330367 private static byte [ ] Pad32 ( byte [ ] value )
331368 {
332369 if ( value . Length == 32 ) return value ;
0 commit comments