internal/ethapi: add personal_sign method

This commit is contained in:
Bas van Kervel 2016-08-24 11:23:20 +02:00
parent 4ce83bf57b
commit 0f079e8e06
4 changed files with 61 additions and 4 deletions

View file

@ -126,6 +126,44 @@ func (b *bridge) UnlockAccount(call otto.FunctionCall) (response otto.Value) {
return val
}
// Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password
// prompt to aquire the passphrase and executes the original RPC method (saved in
// jeth.sign) with it to actually execute the RPC call.
func (b *bridge) Sign(call otto.FunctionCall) (response otto.Value) {
var (
hash = call.Argument(0)
account = call.Argument(1)
passwd = call.Argument(2)
)
if !hash.IsString() {
throwJSException("first argument must be the hash to sign")
}
if !account.IsString() {
throwJSException("second argument must be the account to sign with")
}
// if the password is not given or null ask the user, otherwise ensure it's a string
if passwd.IsUndefined() || passwd.IsNull() {
fmt.Fprintf(b.printer, "Give password for account %s\n", account)
if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil {
throwJSException(err.Error())
} else {
passwd, _ = otto.ToValue(input)
}
}
if !passwd.IsString() {
throwJSException("third argument must be the password to unlock the account")
}
// Send the request to the backend and return
val, err := call.Otto.Call("jeth.sign", nil, hash, account, passwd)
if err != nil {
throwJSException(err.Error())
}
return val
}
// Sleep will block the console for the specified number of seconds.
func (b *bridge) Sleep(call otto.FunctionCall) (response otto.Value) {
if call.Argument(0).IsNumber() {

View file

@ -156,10 +156,9 @@ func (c *Console) init(preload []string) error {
if err != nil {
return err
}
// Override the unlockAccount and newAccount methods since these require user interaction.
// Assign the jeth.unlockAccount and jeth.newAccount in the Console the original web3 callbacks.
// These will be called by the jeth.* methods after they got the password from the user and send
// the original web3 request to the backend.
// Override the unlockAccount, newAccount and sign methods since these require user interaction.
// Assign these method in the Console the original web3 callbacks. These will be called by the jeth.*
// methods after they got the password from the user and send the original web3 request to the backend.
if obj := personal.Object(); obj != nil { // make sure the personal api is enabled over the interface
if _, err = c.jsre.Run(`jeth.unlockAccount = personal.unlockAccount;`); err != nil {
return fmt.Errorf("personal.unlockAccount: %v", err)
@ -167,8 +166,12 @@ func (c *Console) init(preload []string) error {
if _, err = c.jsre.Run(`jeth.newAccount = personal.newAccount;`); err != nil {
return fmt.Errorf("personal.newAccount: %v", err)
}
if _, err = c.jsre.Run(`jeth.sign = personal.sign;`); err != nil {
return fmt.Errorf("personal.sign: %v", err)
}
obj.Set("unlockAccount", bridge.UnlockAccount)
obj.Set("newAccount", bridge.NewAccount)
obj.Set("sign", bridge.Sign)
}
}
// The admin.sleep and admin.sleepBlocks are offered by the console and not by the RPC layer.

View file

@ -298,6 +298,16 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
return submitTransaction(ctx, s.b, tx, signature)
}
// Sign decrypts the private key associated with the given address with the given password.
// If the key was successful decrypted the given hash is signed and the signature is returned.
func (s *PrivateAccountAPI) Sign(ctx context.Context, hash common.Hash, addr common.Address, passwd string) (string, error) {
signature, err := s.b.AccountManager().SignWithPassphrase(addr, passwd, hash.Bytes())
if err != nil {
return "0x", err
}
return "0x" + hex.EncodeToString(signature), nil
}
// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated
// and will be removed in the future. It primary goal is to give clients time to update.
func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {

View file

@ -428,6 +428,12 @@ web3._extend({
call: 'personal_sendTransaction',
params: 2,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
}),
new web3._extend.Method({
name: 'sign',
call: 'personal_sign',
params: 3,
inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null]
})
]
});