commit acaff79ad21803f26a85edc50dd53efbc92b5b71
parent e71b5ef4ea22c01108644eed815d7feff54a186b
Author: nolash <dev@holbrook.no>
Date: Wed, 5 Aug 2020 21:30:08 +0200
Add personal_newAccount handler for socket server
Diffstat:
3 files changed, 104 insertions(+), 23 deletions(-)
diff --git a/scripts/server.py b/scripts/server.py
@@ -1,12 +1,44 @@
import socket
import json
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)
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):
return {
@@ -22,23 +54,61 @@ def jsonrpc_ok(rpc_id, response):
return {
'json-rpc': '2.0',
'id': rpc_id,
- 'response': response,
+ 'result': response,
+ }
+
+
+def process_input(j):
+
+ 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)
-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)
+if __name__ == '__main__':
+ init()
+ arg = None
try:
- logg.debug('{}'.format(d.decode('utf-8')))
- json.loads(d)
- csock.send(json.dumps(jsonrpc_ok(0, [])).encode('utf-8'))
+ arg = json.loads(sys.argv[1])
except:
- csock.send(json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8'))
- csock.close()
-s.close()
-
-os.unlink('/tmp/foo.ipc')
+ 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))
diff --git a/src/keystore/postgres.py b/src/keystore/postgres.py
@@ -9,6 +9,8 @@ from eth_keys import KeyAPI
from eth_keys.backends import NativeECCBackend
import sha3
+from common import strip_hex_prefix
+
keyapi = KeyAPI(NativeECCBackend)
logging.basicConfig(level=logging.DEBUG)
@@ -24,7 +26,7 @@ class ReferenceDatabase:
def __init__(self, dbname, **kwargs):
- self.conn = psycopg2.connect('dbname='+dbname)
+ self.conn = psycopg2.connect('dbname=' + dbname)
self.cur = self.conn.cursor()
self.symmetric_key = kwargs.get('symmetric_key')
@@ -36,12 +38,20 @@ class ReferenceDatabase:
return self._decrypt(k, password)
- def new(self, address, password=None):
+ def new(self, password=None):
b = os.urandom(32)
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)
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):
@@ -64,7 +74,8 @@ class ReferenceDatabase:
return f.decrypt(c.encode('utf-8'))
- def __exit__(self):
- self.conn
+ def __del__(self):
+ logg.debug('closing database')
+ self.conn.commit()
self.cur.close()
self.conn.close()
diff --git a/src/signer/defaultsigner.py b/src/signer/defaultsigner.py
@@ -27,12 +27,12 @@ class ReferenceSigner(Signer):
super(ReferenceSigner, self).__init__(keyGetter)
- def signTransaction(self, tx):
+ def signTransaction(self, tx, password=None):
s = tx.serialize()
h = sha3.keccak_256()
h.update(s)
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)
tx.v = (tx.v * 2) + 35 + z[64]
tx.r = z[:32]