signer/core: add canonical TypedData hashing methods (#25283)
This commit is contained in:
parent
1764f8f559
commit
ba3919cac6
@ -251,6 +251,25 @@ type TypedDataDomain struct {
|
|||||||
Salt string `json:"salt"`
|
Salt string `json:"salt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TypedDataAndHash is a helper function that calculates a hash for typed data conforming to EIP-712.
|
||||||
|
// This hash can then be safely used to calculate a signature.
|
||||||
|
//
|
||||||
|
// See https://eips.ethereum.org/EIPS/eip-712 for the full specification.
|
||||||
|
//
|
||||||
|
// This gives context to the signed typed data and prevents signing of transactions.
|
||||||
|
func TypedDataAndHash(typedData TypedData) ([]byte, string, error) {
|
||||||
|
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
rawData := fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))
|
||||||
|
return crypto.Keccak256([]byte(rawData)), rawData, nil
|
||||||
|
}
|
||||||
|
|
||||||
// HashStruct generates a keccak256 hash of the encoding of the provided data
|
// HashStruct generates a keccak256 hash of the encoding of the provided data
|
||||||
func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage) (hexutil.Bytes, error) {
|
func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage) (hexutil.Bytes, error) {
|
||||||
encodedData, err := typedData.EncodeData(primaryType, data, 1)
|
encodedData, err := typedData.EncodeData(primaryType, data, 1)
|
||||||
|
@ -233,23 +233,17 @@ func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAd
|
|||||||
// - the signature preimage (hash)
|
// - the signature preimage (hash)
|
||||||
func (api *SignerAPI) signTypedData(ctx context.Context, addr common.MixedcaseAddress,
|
func (api *SignerAPI) signTypedData(ctx context.Context, addr common.MixedcaseAddress,
|
||||||
typedData apitypes.TypedData, validationMessages *apitypes.ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
|
typedData apitypes.TypedData, validationMessages *apitypes.ValidationMessages) (hexutil.Bytes, hexutil.Bytes, error) {
|
||||||
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
|
sighash, rawData, err := apitypes.TypedDataAndHash(typedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash)))
|
|
||||||
sighash := crypto.Keccak256(rawData)
|
|
||||||
messages, err := typedData.Format()
|
messages, err := typedData.Format()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
req := &SignDataRequest{
|
req := &SignDataRequest{
|
||||||
ContentType: apitypes.DataTyped.Mime,
|
ContentType: apitypes.DataTyped.Mime,
|
||||||
Rawdata: rawData,
|
Rawdata: []byte(rawData),
|
||||||
Messages: messages,
|
Messages: messages,
|
||||||
Hash: sighash,
|
Hash: sighash,
|
||||||
Address: addr}
|
Address: addr}
|
||||||
|
Loading…
Reference in New Issue
Block a user