rpc: add support for eth_signedTypedData (#953)

* add signTypedData api

* fix typo

* fix lint issues

* add crypto recovery offset

* Apply suggestions from code review

* add changelog

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
crypto-facs 2022-02-25 08:42:33 -05:00 committed by GitHub
parent a2c26208ed
commit e41c713ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 2 deletions

View File

@ -1,3 +1,4 @@
<!-- <!--
Guiding Principles: Guiding Principles:
@ -39,7 +40,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements ### Improvements
- (log) [#948](https://github.com/tharsis/ethermint/pull/948) redirect go-ethereum's logs to cosmos-sdk logger. * (log) [#948](https://github.com/tharsis/ethermint/pull/948) redirect go-ethereum's logs to cosmos-sdk logger.
* (rpc) [tharsis#953](https://github.com/tharsis/ethermint/pull/953) Add `eth_signTypedData` api support.
## [v0.10.0-beta1] - 2022-02-15 ## [v0.10.0-beta1] - 2022-02-15

View File

@ -7,6 +7,8 @@ import (
"math" "math"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
@ -429,7 +431,41 @@ func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.By
return nil, err return nil, err
} }
signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
return signature, nil
}
// SignTypedData signs EIP-712 conformant typed data
func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) {
e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData)
from := sdk.AccAddress(address.Bytes())
_, err := e.clientCtx.Keyring.KeyByAddress(from)
if err != nil {
e.logger.Error("failed to find key in keyring", "address", address.String())
return nil, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.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 := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash)))
sigHash := crypto.Keccak256(rawData)
// Sign the requested hash with the wallet
signature, _, err := e.clientCtx.Keyring.SignByAddress(from, sigHash)
if err != nil {
e.logger.Error("keyring.SignByAddress failed", "address", address.Hex())
return nil, err
}
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
return signature, nil return signature, nil
} }