internal/ethapi: add personal_sign and fix eth_sign to hash message (#2940)
This commit includes several API changes: - The behavior of eth_sign is changed. It now accepts an arbitrary message, prepends the well-known string \x19Ethereum Signed Message:\n<length of message> hashes the result using keccak256 and calculates the signature of the hash. This breaks backwards compatability! - personal_sign(hash, address [, password]) is added. It has the same semantics as eth_sign but also accepts a password. The private key used to sign the hash is temporarily unlocked in the scope of the request. - personal_recover(message, signature) is added and returns the address for the account that created a signature.
This commit is contained in:
@ -136,8 +136,11 @@ func (am *Manager) DeleteAccount(a Account, passphrase string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sign signs hash with an unlocked private key matching the given address.
|
||||
func (am *Manager) Sign(addr common.Address, hash []byte) (signature []byte, err error) {
|
||||
// Sign calculates a ECDSA signature for the given hash.
|
||||
// Note, Ethereum signatures have a particular format as described in the
|
||||
// yellow paper. Use the SignEthereum function to calculate a signature
|
||||
// in Ethereum format.
|
||||
func (am *Manager) Sign(addr common.Address, hash []byte) ([]byte, error) {
|
||||
am.mu.RLock()
|
||||
defer am.mu.RUnlock()
|
||||
unlockedKey, found := am.unlocked[addr]
|
||||
@ -147,8 +150,20 @@ func (am *Manager) Sign(addr common.Address, hash []byte) (signature []byte, err
|
||||
return crypto.Sign(hash, unlockedKey.PrivateKey)
|
||||
}
|
||||
|
||||
// SignWithPassphrase signs hash if the private key matching the given address can be
|
||||
// decrypted with the given passphrase.
|
||||
// SignEthereum calculates a ECDSA signature for the given hash.
|
||||
// The signature has the format as described in the Ethereum yellow paper.
|
||||
func (am *Manager) SignEthereum(addr common.Address, hash []byte) ([]byte, error) {
|
||||
am.mu.RLock()
|
||||
defer am.mu.RUnlock()
|
||||
unlockedKey, found := am.unlocked[addr]
|
||||
if !found {
|
||||
return nil, ErrLocked
|
||||
}
|
||||
return crypto.SignEthereum(hash, unlockedKey.PrivateKey)
|
||||
}
|
||||
|
||||
// SignWithPassphrase signs hash if the private key matching the given
|
||||
// address can be decrypted with the given passphrase.
|
||||
func (am *Manager) SignWithPassphrase(addr common.Address, passphrase string, hash []byte) (signature []byte, err error) {
|
||||
_, key, err := am.getDecryptedKey(Account{Address: addr}, passphrase)
|
||||
if err != nil {
|
||||
@ -156,7 +171,7 @@ func (am *Manager) SignWithPassphrase(addr common.Address, passphrase string, ha
|
||||
}
|
||||
|
||||
defer zeroKey(key.PrivateKey)
|
||||
return crypto.Sign(hash, key.PrivateKey)
|
||||
return crypto.SignEthereum(hash, key.PrivateKey)
|
||||
}
|
||||
|
||||
// Unlock unlocks the given account indefinitely.
|
||||
|
Reference in New Issue
Block a user