Skip to content

Commit ba3919c

Browse files
authored
signer/core: add canonical TypedData hashing methods (#25283)
1 parent 1764f8f commit ba3919c

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

signer/core/apitypes/types.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,25 @@ type TypedDataDomain struct {
251251
Salt string `json:"salt"`
252252
}
253253

254+
// TypedDataAndHash is a helper function that calculates a hash for typed data conforming to EIP-712.
255+
// This hash can then be safely used to calculate a signature.
256+
//
257+
// See https://eips.ethereum.org/EIPS/eip-712 for the full specification.
258+
//
259+
// This gives context to the signed typed data and prevents signing of transactions.
260+
func TypedDataAndHash(typedData TypedData) ([]byte, string, error) {
261+
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
262+
if err != nil {
263+
return nil, "", err
264+
}
265+
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
266+
if err != nil {
267+
return nil, "", err
268+
}
269+
rawData := fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))
270+
return crypto.Keccak256([]byte(rawData)), rawData, nil
271+
}
272+
254273
// HashStruct generates a keccak256 hash of the encoding of the provided data
255274
func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage) (hexutil.Bytes, error) {
256275
encodedData, err := typedData.EncodeData(primaryType, data, 1)

signer/core/signed_data.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,23 +233,17 @@ func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAd
233233
// - the signature preimage (hash)
234234
func (api *SignerAPI) signTypedData(ctx context.Context, addr common.MixedcaseAddress,
235235
typedData apitypes.TypedData, validationMessages *apitypes.ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
236-
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
236+
sighash, rawData, err := apitypes.TypedDataAndHash(typedData)
237237
if err != nil {
238238
return nil, nil, err
239239
}
240-
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
241-
if err != nil {
242-
return nil, nil, err
243-
}
244-
rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash)))
245-
sighash := crypto.Keccak256(rawData)
246240
messages, err := typedData.Format()
247241
if err != nil {
248242
return nil, nil, err
249243
}
250244
req := &SignDataRequest{
251245
ContentType: apitypes.DataTyped.Mime,
252-
Rawdata: rawData,
246+
Rawdata: []byte(rawData),
253247
Messages: messages,
254248
Hash: sighash,
255249
Address: addr}

0 commit comments

Comments
 (0)