Add personal_newAccount handler for socket server
This commit is contained in:
parent
e71b5ef4ea
commit
acaff79ad2
@ -1,12 +1,44 @@
|
|||||||
import socket
|
import socket
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
from jsonrpc.exceptions import JSONRPCParseError
|
from jsonrpc.exceptions import *
|
||||||
|
|
||||||
|
from signer import ReferenceSigner
|
||||||
|
from keystore import ReferenceDatabase
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
db = None
|
||||||
|
signer = None
|
||||||
|
|
||||||
|
|
||||||
|
def personal_new_account(p):
|
||||||
|
if p.__class__.__name__ != 'list':
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e )
|
||||||
|
if len(p) != 1:
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e)
|
||||||
|
if p[0].__class__.__name__ != 'str':
|
||||||
|
e = JSONRPCInvalidParams()
|
||||||
|
e.data = 'parameter must be list containing one string'
|
||||||
|
raise ValueError(e)
|
||||||
|
|
||||||
|
r = db.new(p[0])
|
||||||
|
|
||||||
|
return [r]
|
||||||
|
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
'personal_newAccount': personal_new_account,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def jsonrpc_error(id, err):
|
def jsonrpc_error(id, err):
|
||||||
return {
|
return {
|
||||||
@ -22,23 +54,61 @@ def jsonrpc_ok(rpc_id, response):
|
|||||||
return {
|
return {
|
||||||
'json-rpc': '2.0',
|
'json-rpc': '2.0',
|
||||||
'id': rpc_id,
|
'id': rpc_id,
|
||||||
'response': response,
|
'result': response,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
def process_input(j):
|
||||||
s.bind('/tmp/foo.ipc')
|
|
||||||
s.listen(10)
|
|
||||||
while True:
|
|
||||||
(csock, caddr) = s.accept()
|
|
||||||
d = csock.recv(4096)
|
|
||||||
try:
|
|
||||||
logg.debug('{}'.format(d.decode('utf-8')))
|
|
||||||
json.loads(d)
|
|
||||||
csock.send(json.dumps(jsonrpc_ok(0, [])).encode('utf-8'))
|
|
||||||
except:
|
|
||||||
csock.send(json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8'))
|
|
||||||
csock.close()
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
os.unlink('/tmp/foo.ipc')
|
rpc_id = j['id']
|
||||||
|
|
||||||
|
m = j['method']
|
||||||
|
p = j['params']
|
||||||
|
return (rpc_id, methods[m](p))
|
||||||
|
|
||||||
|
|
||||||
|
def start_server():
|
||||||
|
os.unlink('/tmp/foo.ipc')
|
||||||
|
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
||||||
|
s.bind('/tmp/foo.ipc')
|
||||||
|
s.listen(10)
|
||||||
|
while True:
|
||||||
|
(csock, caddr) = s.accept()
|
||||||
|
d = csock.recv(4096)
|
||||||
|
try:
|
||||||
|
j = json.loads(b)
|
||||||
|
process_input(j)
|
||||||
|
logg.debug('{}'.format(d.decode('utf-8')))
|
||||||
|
csock.send(json.dumps(jsonrpc_ok(0, [])).encode('utf-8'))
|
||||||
|
except:
|
||||||
|
csock.send(json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8'))
|
||||||
|
csock.close()
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
os.unlink('/tmp/foo.ipc')
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global db, signer
|
||||||
|
secret_hex = os.environ.get('SIGNER_SECRET')
|
||||||
|
secret = bytes.fromhex(secret_hex)
|
||||||
|
kw = {
|
||||||
|
'symmetric_key': secret,
|
||||||
|
}
|
||||||
|
db = ReferenceDatabase('cic_signer', **kw)
|
||||||
|
signer = ReferenceSigner(db.get)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
init()
|
||||||
|
arg = None
|
||||||
|
try:
|
||||||
|
arg = json.loads(sys.argv[1])
|
||||||
|
except:
|
||||||
|
logg.info('no json rpc command detected, starting socket server')
|
||||||
|
start_server()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
(rpc_id, response) = process_input(arg)
|
||||||
|
r = jsonrpc_ok(rpc_id, response)
|
||||||
|
sys.stdout.write(json.dumps(r))
|
||||||
|
@ -9,6 +9,8 @@ from eth_keys import KeyAPI
|
|||||||
from eth_keys.backends import NativeECCBackend
|
from eth_keys.backends import NativeECCBackend
|
||||||
import sha3
|
import sha3
|
||||||
|
|
||||||
|
from common import strip_hex_prefix
|
||||||
|
|
||||||
keyapi = KeyAPI(NativeECCBackend)
|
keyapi = KeyAPI(NativeECCBackend)
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
@ -24,7 +26,7 @@ class ReferenceDatabase:
|
|||||||
|
|
||||||
|
|
||||||
def __init__(self, dbname, **kwargs):
|
def __init__(self, dbname, **kwargs):
|
||||||
self.conn = psycopg2.connect('dbname='+dbname)
|
self.conn = psycopg2.connect('dbname=' + dbname)
|
||||||
self.cur = self.conn.cursor()
|
self.cur = self.conn.cursor()
|
||||||
self.symmetric_key = kwargs.get('symmetric_key')
|
self.symmetric_key = kwargs.get('symmetric_key')
|
||||||
|
|
||||||
@ -36,12 +38,20 @@ class ReferenceDatabase:
|
|||||||
return self._decrypt(k, password)
|
return self._decrypt(k, password)
|
||||||
|
|
||||||
|
|
||||||
def new(self, address, password=None):
|
def new(self, password=None):
|
||||||
b = os.urandom(32)
|
b = os.urandom(32)
|
||||||
pk = keyapi.PrivateKey(b)
|
pk = keyapi.PrivateKey(b)
|
||||||
|
|
||||||
|
pubk = keyapi.private_key_to_public_key(pk)
|
||||||
|
address_hex = pubk.to_checksum_address()
|
||||||
|
address_hex_clean = strip_hex_prefix(address_hex)
|
||||||
|
|
||||||
|
logg.debug('address {}'.format(address_hex_clean))
|
||||||
c = self._encrypt(pk.to_bytes(), password)
|
c = self._encrypt(pk.to_bytes(), password)
|
||||||
s = sql.SQL('INSERT INTO ethereum (wallet_address_hex, key_ciphertext) VALUES (%s, %s)')
|
s = sql.SQL('INSERT INTO ethereum (wallet_address_hex, key_ciphertext) VALUES (%s, %s)')
|
||||||
self.cur.execute(s, [ address, c.decode('utf-8') ])
|
self.cur.execute(s, [ address_hex_clean, c.decode('utf-8') ])
|
||||||
|
self.conn.commit()
|
||||||
|
return address_hex
|
||||||
|
|
||||||
|
|
||||||
def _encrypt(self, private_key, password):
|
def _encrypt(self, private_key, password):
|
||||||
@ -64,7 +74,8 @@ class ReferenceDatabase:
|
|||||||
return f.decrypt(c.encode('utf-8'))
|
return f.decrypt(c.encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def __exit__(self):
|
def __del__(self):
|
||||||
self.conn
|
logg.debug('closing database')
|
||||||
|
self.conn.commit()
|
||||||
self.cur.close()
|
self.cur.close()
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
|
@ -27,12 +27,12 @@ class ReferenceSigner(Signer):
|
|||||||
super(ReferenceSigner, self).__init__(keyGetter)
|
super(ReferenceSigner, self).__init__(keyGetter)
|
||||||
|
|
||||||
|
|
||||||
def signTransaction(self, tx):
|
def signTransaction(self, tx, password=None):
|
||||||
s = tx.serialize()
|
s = tx.serialize()
|
||||||
h = sha3.keccak_256()
|
h = sha3.keccak_256()
|
||||||
h.update(s)
|
h.update(s)
|
||||||
g = h.digest()
|
g = h.digest()
|
||||||
k = keys.PrivateKey(self.keyGetter(tx.sender))
|
k = keys.PrivateKey(self.keyGetter(tx.sender, password))
|
||||||
z = keys.ecdsa_sign(message_hash=g, private_key=k)
|
z = keys.ecdsa_sign(message_hash=g, private_key=k)
|
||||||
tx.v = (tx.v * 2) + 35 + z[64]
|
tx.v = (tx.v * 2) + 35 + z[64]
|
||||||
tx.r = z[:32]
|
tx.r = z[:32]
|
||||||
|
Loading…
Reference in New Issue
Block a user