From 9966d7d2f65f492dfe366d34c9d3564c91e45912 Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 15 Mar 2018 09:42:16 -0700 Subject: [PATCH 01/12] Python 3.x Compatibility Updates This PR contains commits for ultimately full Python 3.x compatibility. Some changes (such as formatting) may seem a little pedantic, but thats just who I am as a developer. The main thing in this isn't necessarily changing any API, mostly just to move towards Python 3.x in any library changes closer to that version. If you have any questions, comments, and concerns, please do let me know. --- rpc_server.py | 65 ++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/rpc_server.py b/rpc_server.py index bf69355..3a0debd 100644 --- a/rpc_server.py +++ b/rpc_server.py @@ -3,56 +3,55 @@ # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +from __future__ import print_function -import socket, signal -from SimpleXMLRPCServer import * import argparse -import ConfigParser import json +import signal +import socket +import xmlrpclib + import ConfigParser from rpc_commands import * - +from SimpleXMLRPCServer import * if sys.maxsize <= 2**32: - print "Warning: it looks like you are using a 32bit system. You may experience crashes caused by mmap" - + print("Warning: it looks like you are using a 32bit system. You may experience crashes caused by mmap") if os.getuid() == 0: - print "Do not run this program as root!" - print "Run the install script to create a non-privileged user." - sys.exit() - - + print("Do not run this program as root!") + print("Run the install script to create a non-privileged user.") + sys.exit(0) def run_rpc_command(params, electrum_rpc_port): cmd = params[0] - import xmlrpclib - server = xmlrpclib.ServerProxy('http://localhost:%d' % 4878) + server = xmlrpclib.ServerProxy('http://localhost:4878') func = getattr(server, cmd) r = func(*params[1:]) - print json.dumps(r, indent=4, sort_keys=True) + print(json.dumps(r, indent=4, sort_keys=True)) -class AltXMLRPCServer(SimpleXMLRPCServer): - finished=False +class AltXMLRPCServer(SimpleXMLRPCServer): + finished = False def register_signal(self, signum): signal.signal(signum, self.signal_handler) def signal_handler(self, signum, frame): - print "Caught signal", signum + print("Caught signal", signum) self.shutdown() def shutdown(self): - self.finished=True - return 1 + self.finished = True + return self def serve_forever(self): - while not self.finished: server.handle_request() + while not self.finished: + server.handle_request() @@ -62,8 +61,7 @@ def serve_forever(self): if __name__ == '__main__': config = ConfigParser.ConfigParser() - config.read(expanduser("~") + "/" + ".silme/silme.conf") - + config.read('{}/.silme/silme.conf'.format(exanduser('~'))) rpc_host = config.get('server', 'host') rpc_port = 4878 @@ -75,10 +73,10 @@ def serve_forever(self): if len(args.command) >= 1: try: run_rpc_command(args.command, rpc_port) + sys.exit(0) except socket.error: print "server not running" sys.exit(1) - sys.exit(0) try: run_rpc_command(['getpid'], rpc_port) @@ -87,34 +85,37 @@ def serve_forever(self): is_running = False if is_running: - print "server already running" + print("Server already running!") sys.exit(1) server = AltXMLRPCServer((rpc_host, rpc_port)) - print "Serving on %s:%d" %(rpc_host, rpc_port) + print("Serving on {}:{}".format(rpc_host, rpc_port)) + + # server control server.register_function(pow) server.register_function(server.shutdown, 'stop') server.register_function(lambda: os.getpid(), 'getpid') + server.register_function(Version, 'version') server.register_introspection_functions() - #blockchain + + # blockchain server.register_function(GetBestHeight, 'getbestheight') server.register_function(GetBestHash, 'getbesthash') server.register_function(GetDifficulty, 'getdifficulty') server.register_function(NetHashRate, 'nethashrate') - #wallet + + # wallet server.register_function(GetMyAddresses, 'getmyaddresses') server.register_function(GetNewAddress, 'getnewaddress') server.register_function(GetBalance, 'getbalance') - #mining - server.register_function(MemCount, 'mempoolcount') - # - server.register_function(Version, 'version') + # mining + server.register_function(MemCount, 'mempoolcount') # signals server.register_signal(signal.SIGHUP) server.register_signal(signal.SIGINT) server.serve_forever() - print "Closed" + print("Server closed") From c3d490538f1902586a467b2b6d6012c24ff8493f Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 15 Mar 2018 09:43:39 -0700 Subject: [PATCH 02/12] Fix missing dependency --- rpc_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rpc_server.py b/rpc_server.py index 3a0debd..7d7bb9b 100644 --- a/rpc_server.py +++ b/rpc_server.py @@ -7,6 +7,7 @@ import argparse import json +from os.path import expanduser import signal import socket import xmlrpclib From a3331894d30920d07a0a19bab39f5c7188f42e7b Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 15 Mar 2018 10:56:06 -0700 Subject: [PATCH 03/12] Update main.py --- main.py | 335 +++++++++++++++----------------------------------------- 1 file changed, 90 insertions(+), 245 deletions(-) diff --git a/main.py b/main.py index e901b64..0e3646b 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,11 @@ import string import struct - +# python 3.x compatibility +try: + xrange +except NameError: + xrange = range # One silme can be split into 100000000 satoshi COIN = 100000000 @@ -28,52 +32,41 @@ nSubsibyHalvingInterval = 210000 # MaxBlockSize nMaxSize = 1000000 # 1MB - +# logging +logging.basicConfig(level=logging.INFO, filename="debug.log", format='%(asctime)s %(message)s') # include timestamp def GetAppDir(): # currently suppports linux - if not platform == "linux": - if not platform == "linux2": - sys.exit(logg("Error: Unsupported platform")) - return expanduser("~") + "/" + ".silme" - - -logging.basicConfig(level=logging.INFO, filename="debug.log", format='%(asctime)s %(message)s') # include timestamp - - -def logg(msg): logging.info(msg) - + if not platform in ["linux", "linux2"]: + sys.exit(logging.info("Error: Unsupported platform")) + return "{}/.silme".format(expanduser("~")) if not os.path.exists(GetAppDir()): # db isn't initalized, initialize it try: os.mkdir(GetAppDir()) - except Exception, e: - raise - else: - logg("Initializing empty blockchain database at " + GetAppDir() + "/blockchain.db") - blockchain_conn = sqlite3.connect(GetAppDir() + "/blockchain.db") + logging.info("Initializing empty blockchain database at {}/blockchain.db".format(GetAppDir())) + blockchain_conn = sqlite3.connect("{}/blockchain.db".format(GetAppDir())) blockchain_cursor = blockchain_conn.cursor() blockchain_cursor.execute("CREATE TABLE blocks (height INTEGER, hash, raw, nonce)") blockchain_cursor.execute("CREATE TABLE transactions (block, version, prev, time, value, hash, input_script, output_script, signature)") blockchain_conn.commit() - logg("Initializing empty wallet database at " + GetAppDir() + "/wallet.db") - wallet_conn = sqlite3.connect(GetAppDir() + "/wallet.db") + logging.info("Initializing empty wallet database at {}/wallet.db".format(GetAppDir())) + wallet_conn = sqlite3.connect("{}/wallet.db".format(GetAppDir())) wallet_cursor = wallet_conn.cursor() wallet_cursor.execute("CREATE TABLE keys (private, pubkey)") wallet_cursor.execute("CREATE TABLE transactions (tx_hash)") wallet_conn.commit() - logg("Initializing empty peers database at " + GetAppDir() + "/peers.db") - peers_conn = sqlite3.connect(GetAppDir() + "/peers.db") + logging.info("Initializing empty peers database at {}/peers.db".format(GetAppDir())) + peers_conn = sqlite3.connect("{}/peers.db".format(GetAppDir())) peers_cursor = peers_conn.cursor() peers_cursor.execute("CREATE TABLE nodes (ip, port, status)") peers_conn.commit() - # hardcode nodes peers_cursor.execute("INSERT INTO nodes VALUES (?,?,?)", ("127.0.0.1", 7777, "ok")) peers_cursor.execute("INSERT INTO nodes VALUES (?,?,?)", ("127.0.0.2", 7777, "ok")) @@ -81,21 +74,19 @@ def logg(msg): logging.info(msg) peers_cursor.execute("INSERT INTO nodes VALUES (?,?,?)", ("127.0.0.4", 7777, "ok")) peers_conn.commit() - - - # add genesis to database blockchain_cursor.execute("INSERT INTO blocks VALUES (?,?,?,?)", (1, "000009cb25c348b85b01819c52402adea224580263fbe9b915be8502c5220f82", "0100000000000000000000000000000000000000000000000000000000000000000000007a98ffba469fe652771c5bb7b236248b4d78e4127ef369f1b07e1071da069e2fba756b5affff0f1ef7830e00", 0)) # Insert a row of data blockchain_conn.commit() - mempool_conn = sqlite3.connect(GetAppDir() + "/mempool.db") + mempool_conn = sqlite3.connect("{}/mempool.db".format(GetAppDir())) mempool_cursor = mempool_conn.cursor() mempool_cursor.execute("CREATE TABLE transactions (version, prev, time, value, hash, input_script, output_script, signature)") mempool_conn.commit() + except Exception, e: + raise def internetConnection(host="8.8.8.8", port=53, timeout=3): - try: socket.setdefaulttimeout(timeout) socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port)) @@ -104,12 +95,10 @@ def internetConnection(host="8.8.8.8", port=53, timeout=3): return False - def haveReachableNode(): - have = 0 - peers_conn = sqlite3.connect(GetAppDir() + "/peers.db") + peers_conn = sqlite3.connect("{}/peers.db".format(GetAppDir())) peers_cursor = peers_conn.cursor() peers = peers_cursor.execute("SELECT * FROM nodes").fetchall() @@ -122,20 +111,16 @@ def haveReachableNode(): try: s.connect(peerip, port) + have += 1 except: s.close() - else: - have +=1 + if have > 0: return True return False - - - class CKey(object): - # CKey class use https://github.com/vbuterin/pybitcointools # from bitcoin import * @@ -148,35 +133,28 @@ def GetPubKey(self, priv): return privtopub(priv) - def GetAddress(self, pub): return pubtoaddr(pub) - - class Sig(object): - def SSign(self, tx, priv): sig = ecdsa_sign(str(tx),priv) return sig def VVerify(self, tx, signature): - return ecdsa_verify(str(tx),signature,tx["output_script"].encode("hex_codec")[2:132]) + return ecdsa_verify(str(tx), signature,tx["output_script"].encode("hex_codec")[2:132]) def VVVerify(self, msg, sig, pub): return ecdsa_verify(msg, sig, pub) - class CBlockchain(object): - - def GetTransactions(self): # get all blockchain transactions - conn = sqlite3.connect(GetAppDir() + "/blockchain.db") + conn = sqlite3.connect("{}/blockchain.db".format(GetAppDir())) conn.text_factory = str cur = conn.cursor() cur.execute("SELECT * FROM transactions") @@ -184,7 +162,6 @@ def GetTransactions(self): def isVaildTx(self, tx): - amount = tx["value"] inHash = tx["prev_out"] itime = tx["time"] @@ -193,38 +170,26 @@ def isVaildTx(self, tx): # remove signature from tx del tx['signature'] - - - conn = sqlite3.connect(GetAppDir() + "/blockchain.db") + conn = sqlite3.connect("{}/blockchain.db".format(GetAppDir())) conn.text_factory = str cur = conn.cursor() res = cur.execute("SELECT value FROM transactions where hash = ?", (inHash,)).fetchone()[0] ous = cur.execute("SELECT output_script FROM transactions where hash = ?", (inHash,)).fetchone()[0].encode("hex_codec")[2:132] - if not res: - return False - - if res < amount: - return False - - if itime > int(time.time()): + if not res or res < amount or itime > int(time.time()): return False return ecdsa_verify(str(tx),signature,ous) - class CWalletDB(object): - - def __init__(self): - self.conn = sqlite3.connect(GetAppDir() + "/wallet.db") + self.conn = sqlite3.connect("{}/wallet.db".format(GetAppDir())) self.conn.text_factory = str self.cur = self.conn.cursor() - def WriteKey(self, key, pubkey): try: self.cur.execute("INSERT INTO keys VALUES (?,?)", (key, pubkey)) @@ -240,13 +205,11 @@ def IsMineKey(self, pubkey): return pubkey in str(results) - def GetMyAddresses(self): self.cur.execute("SELECT private from keys") results = self.cur.fetchall() - addresses = [] - + addresses = [] for priv in results: addresses.append(CKey().GetAddress(str(priv))) @@ -254,7 +217,6 @@ def GetMyAddresses(self): def GetBalance(self): - balance = 0 # calculate balance @@ -273,22 +235,22 @@ def GetBalance(self): def FindHash(self, amount): - ntxs = [] for transaction in CBlockchain().GetTransactions(): pubkey = transaction[7].encode("hex_codec")[2:132] if self.IsMineKey(pubkey): thisHash = transaction[5] + if transaction[4] >= amount: for ttx in CBlockchain().GetTransactions(): - if type(ttx[2] == int): + if isinstance(ttx[2], int): return thisHash def FindAddrFromHash(self, txhash): # get all blockchain transactions - conn = sqlite3.connect(GetAppDir() + "/blockchain.db") + conn = sqlite3.connect("{}/blockchain.db".format(GetAppDir())) conn.text_factory = str cur = conn.cursor() res = cur.execute("SELECT output_script FROM transactions where hash = ?", (txhash,)).fetchone()[0] @@ -297,20 +259,17 @@ def FindAddrFromHash(self, txhash): return thisPriv - - def GenerateTransaction(self, amount, recipten): mybalance = self.GetBalance() - if mybalance < amount: # not enought balance to create this transaction - logg("GenerateTransaction() Failed not enought balance to create this transaction") + logging.info("GenerateTransaction() Failed not enought balance to create this transaction") return False if len(recipten) != 130: # not vaild recipten key - logg("GenerateTransaction() Failed not vaild recipten key") + logging.info("GenerateTransaction() Failed not vaild recipten key") return False # collect hash @@ -326,26 +285,18 @@ def GenerateTransaction(self, amount, recipten): txNew.input_script("SilmeTransaction") txNew.output_script(recipten) txNew.add("signature", Sig().SSign(str(txNew), priv)) + if Mempool().addtx(txNew): return True return False - - - - - class Mempool(object): - - def __init__(self): # initilize empty mempool - self.mem_conn = sqlite3.connect(GetAppDir() + "/mempool.db") + self.mem_conn = sqlite3.connect("{}/mempool.db".format(GetAppDir())) self.mem_conn.text_factory = str self.mem_cur = self.mem_conn.cursor() - - def HaveHash(self, tx): @@ -356,16 +307,22 @@ def HaveHash(self, tx): return thisHash in mempool_txs - def addtx(self, tx): # add tx to mem pool - if not self.HaveHash(tx): - self.mem_cur.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?, ?)", (tx["version"], tx["prev_out"], tx["time"], tx["value"], hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(), tx["input_script"], tx["output_script"], tx["signature"])) # Insert a row of data + self.mem_cur.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?, ?)", + (tx["version"], + tx["prev_out"], + tx["time"], + tx["value"], + hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(), + tx["input_script"], + tx["output_script"], + tx["signature"])) # Insert a row of data self.mem_conn.commit() - logg("Mempool() : Transaction %s added to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) + logging("Mempool() : Transaction %s added to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) return True - logg("Mempool() : Transaction %s already to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) + logging.info("Mempool() : Transaction %s already to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) return False, "Already have" @@ -375,14 +332,12 @@ def CountTxs(self): return len(mempool_txs) - def GetTransactions(self): # get all mempool transactions self.mem_cur.execute("SELECT * FROM transactions") return self.mem_cur.fetchall() - def GetSize(self): fsize = 0 mempool_txs = self.mem_cur.execute("SELECT * FROM transactions").fetchall() @@ -390,33 +345,24 @@ def GetSize(self): ff += sys.getsizeof(tx) return fsize + def gettx(self, n): return self.mem_cur.execute("SELECT * FROM transactions").fetchall()[n] def RemoveTx(self, tx): - - query = 'delete from transactions where hash=?' - self.mem_cur.execute(query, (tx.strip(),)) + self.mem_cur.execute('DELETE FROM transactions WHERE hash=?', (tx.strip(),)) self.mem_conn.commit() - - - - def decode_uint32(self): - return struct.unpack(" 76: psz_prefix = '4c' - script_prefix = '04ffff001d0104' + psz_prefix + chr(len(message)).encode('hex') + if len(message) > 76: + psz_prefix = '4c' + + script_prefix = '04ffff001d0104{}{}'.format(psz_prefix, hr(len(message)).encode('hex')) + input_script_f = (script_prefix + message.encode('hex')).decode('hex') self.add("input_script", input_script_f) + def output_script(self, pubkey): script_len = '41' OP_CHECKSIG = 'ac' @@ -553,28 +496,19 @@ def add(self, key, value): self[key] = value - - def clear(self): # clear the dict self.clear() - def getHash(self): # transaction hash return hashlib.sha256(hashlib.sha256(str(self)).digest()).digest() - - - - class CBlockchainDB(object): - - def __init__(self): - self.conn = sqlite3.connect((GetAppDir() + "/blockchain.db")) + self.conn = sqlite3.connect(("{}/blockchain.db")) self.conn.text_factory = str self.cur = self.conn.cursor() @@ -585,15 +519,12 @@ def getBestHeight(self): return len(results) - - def GetBestHash(self): self.cur.execute('SELECT hash FROM blocks') results = self.cur.fetchall() return results[len(results) -1][0] - def haveHash(self, hash): self.cur.execute("SELECT hash FROM blocks WHERE hash = ?", (hash,)) result = self.cur.fetchone() @@ -615,34 +546,25 @@ def insertTxs(self, height, pblock): cursor.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?,?)", (height, pblock.vtx[x]["version"],pblock.vtx[x]["prev_out"],pblock.vtx[x]["time"], pblock.vtx[x]["value"], txhash, pblock.vtx[x]["input_script"], pblock.vtx[x]["output_script"], pblock.vtx[x]["signature"])) # Insert a row of data conn.commit() except Exception, e: - logg(e) + logging.info(e) return False def insertBlock(self, pblock, block, nonce): - b_height = self.getBestHeight() + 1 - b_hash = hashlib.sha256(hashlib.sha256(block).digest()).digest()[::-1].encode('hex_codec') - try: self.cur.execute("INSERT INTO blocks VALUES (?,?,?,?)", (b_height, b_hash, block, nonce)) self.conn.commit() self.insertTxs(b_height, pblock) + return True except Exception, e: - logg(e) + logging.info(e) return False - else: - return True - - - - class CBlock(object): - # block header nVersion = None # version hashPrevBlock = None # previous block hash @@ -659,7 +581,6 @@ def CBlock(self): SetNull() - def SetNull(self): self.nVersion = 1 self.hashPrevBlock = 0 @@ -675,14 +596,10 @@ def IsNull(self): return self.nBits == 0 - - def Nullvtx(self): del self.vtx[:] - - def hash2(self, a, b): # Reverse inputs before and after hashing # due to big-endian / little-endian nonsense @@ -692,8 +609,6 @@ def hash2(self, a, b): return h[::-1].encode('hex') - - def BuildMerkleTree(self): del self.vMerkleTree[:] @@ -709,16 +624,14 @@ def BuildMerkleTree(self): return BuildMerkleTree(newtxHashes) - def pprint(self): - print("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s)\n") %("missinghash", self.hashPrevBlock,self.nVersion, self.hashMerkleRoot) - - - + print("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s)\n") %("missinghash", + self.hashPrevBlock, + self.nVersion, + self.hashMerkleRoot) class tmp(): - nVersion = None hashPrevBlock = None hashMerkleRoot = None @@ -748,45 +661,36 @@ def build(self): return block_header.build(Cblock) - - - - class Proccess(object): - - def thisBlock(self, block, pblock, nonce): - logg("Proccessing new block\n") + logging.info("Proccessing new block") # calculate hash block_hash = hashlib.sha256(hashlib.sha256(block).digest()).digest()[::-1].encode('hex_codec') - - - # Check for duplicate if CBlockchainDB().haveHash(block_hash): - logg("ProcessBlock() : already have block %s %s" %(CBlockIndex(block_hash).Height(), block_hash,)) + logging.info("ProcessBlock() : already have block %s %s" %(CBlockIndex(block_hash).Height(), block_hash,)) return False # Check prev block if CBlockchainDB().GetBestHash() != block[8:72]: - logg("CheckBlock() : prev block not found") + logging.info("CheckBlock() : prev block not found") return False # Check timestamp against prev if CBlockIndex(CBlockchainDB().GetBestHash()).Time() >= decode_uint32(a2b_hex(block[136:144])): - logg("CheckBlock() : block's timestamp is too early") + logging.info("CheckBlock() : block's timestamp is too early") return False # Check Proof Of Work if decode_uint32(a2b_hex(block[144:152])) != GetNextWorkRequired(): - logg("CheckBlock() : incorrect proof of work") + logging.info("CheckBlock() : incorrect proof of work") return False # Check size if sys.getsizeof(pblock.vtx) > nMaxSize: - logg("CheckBlock() : Block size failed") + logging.info("CheckBlock() : Block size failed") return False @@ -796,49 +700,38 @@ def thisBlock(self, block, pblock, nonce): def CheckBlock(self, block, pblock, nonce): - # be sure that first tx is coinbase if not pblock.vtx[0]["prev_out"] == 0: - logg("CheckBlock() : first tx is not coinbase") + logging.info("CheckBlock() : first tx is not coinbase") return False # be sure that only 1 coinbase tx included for x in xrange(1,len(pblock.vtx)): if pblock.vtx[x]["prev_out"] == 0: - logg("CheckBlock() : more than one coinbase") + logging.info("CheckBlock() : more than one coinbase") return False # check transactions, not include coinbase tx for x in xrange(1,len(pblock.vtx)): if not self.thisTxIsVaild(pblock.vtx[x]): - logg("CheckBlock() : Invaild tx found") + logging.info("CheckBlock() : Invaild tx found") return False - # verify input sig for x in xrange(1,len(pblock.vtx)): if not CBlockchain().isVaildTx(pblock.vtx[x]): - logg("CheckBlock() : Failed to verify input sig") + logging.info("CheckBlock() : Failed to verify input sig") return False - return True - - - def thisTxIsPayingMe(self, tx): # get this tx out pubkey tx_pubkey = tx["output_script"].encode("hex_codec")[2:132] return CWalletDB().IsMineKey(tx_pubkey) - - - def thisTxIsVaild(self, tx): - # check transaction verification - # store signature in memory signature = tx["signature"] # remove signature from tx @@ -849,42 +742,33 @@ def thisTxIsVaild(self, tx): tx['signature'] = signature except Exception, e: tx['signature'] = signature - logg("Transaction %s verification error" %hashlib.sha256(hashlib.sha256(str(tx)).digest()).digest().encode("hex_codec")) - logg(e) + logging.info("Transaction %s verification error" %hashlib.sha256(hashlib.sha256(str(tx)).digest()).digest().encode("hex_codec")) + logging.info(e) return False - - # check for empty scripts if len(tx["input_script"]) < 10 or len(tx["output_script"]) < 10: - logg("Proccess::thisTxIsVaild() : vin or vout empty") + logging.info("Proccess::thisTxIsVaild() : vin or vout empty") return False # check for negative tx value if tx["value"] == 0: - logg("Proccess::thisTxIsVaild() : txout.nValue negative") + logging.info("Proccess::thisTxIsVaild() : txout.nValue negative") return False # check for missing prevout if tx["prev_out"] == 0: - logg("Proccess::thisTxIsVaild() : prevout is null") + logging.info("Proccess::thisTxIsVaild() : prevout is null") return False - - - return True class thisBlock(object): - # Proccess new block received by peer, and add it to database if is vaild # Return True if vaild False if Not # Only proccess blocks with coinbase transaction, wil be fixed later - - - def __init__(self, peer, raw, coinbase, transactions, nonce): self.ThisPeer = peer self.thisRaw = raw @@ -893,7 +777,6 @@ def __init__(self, peer, raw, coinbase, transactions, nonce): self.thisNonce = nonce - def isVaild(self): blk, pblock, = self.Build() blk = blk[0:len(blk) - 4] + struct.pack('>= (height / nSubsibyHalvingInterval) return subsidy + fees - def GetBalance(pub): # get balance of specifiec key - # balance balance = 0 @@ -972,19 +847,13 @@ def GetBalance(pub): return balance - ######## Keys - - def AddKey(pkey): key = CKey() pubkey = key.GetPubKey(pkey) return CWalletDB().WriteKey(pkey, pubkey) - - - def GenerateNewKey(): key = CKey() pkey = key.MakeNewKey() @@ -994,10 +863,7 @@ def GenerateNewKey(): return key.GetPubKey(pkey) - - def GetNextWorkRequired(): - # latest block hash pindexLast = CBlockchainDB().GetBestHash() @@ -1007,29 +873,27 @@ def GetNextWorkRequired(): nTargetSpacing = 100 # That give us a interval 6 blocks nInterval = nTargetTimespan / nTargetSpacing - - + # if the last block height == 1 return the minimun diif if CBlockIndex(pindexLast).Height() == 1: return 0x1e0fffff - # Only change once per interval if ((CBlockIndex(pindexLast).Height()+1) % nInterval != 0): # Return the last block bits (difficulty) return CBlockIndex(pindexLast).Bits() - # Go back by what we want to be 10 minuntes worth of blocks # nActualTimespan is the avg time of the last 6 blocks, example if each of the last 6 blocks took 30 seconds nActualTimespan will be 180 nActualTimespan = CBlockIndex(pindexLast).Time() - CBlockIndex(CBlockIndex(pindexLast).Height() - nInterval + 2).Time() # so if the nActualTimespan is bigger the nTargetTimespan means that blocks are mined slowly, difficulty will be reduced, # if the nActualTimespan is lower than nTargetTimespan means that blocks are mined quick, difficulty will be increased - logg("nActualTimespan = %d before bounds\n" %nActualTimespan) + logging.info("nActualTimespan = %d before bounds\n" %nActualTimespan) if nActualTimespan < nTargetTimespan/4: nActualTimespan = nTargetTimespan/4 + if nActualTimespan > nTargetTimespan*4: nActualTimespan = nTargetTimespan*4 @@ -1040,19 +904,15 @@ def GetNextWorkRequired(): if bnNew > bnProofOfWorkLimit: bnNew = bnProofOfWorkLimit - - - logg("\n\n\nGetNextWorkRequired RETARGET *****\n") - logg("nTargetTimespan = %d nActualTimespan = %d\n" %(nTargetTimespan, nActualTimespan,)) - logg("Last %d blocks time average was %d\n" %(nInterval, nActualTimespan,)) - logg("Before: %08x %s\n" %(CBlockIndex(pindexLast).Bits(), nActualTimespan,)) - logg("After: %08x %s\n" %(GetCompact(int(bnNew)), nActualTimespan,)) + logging.info("\n\n\nGetNextWorkRequired RETARGET *****\n") + logging.info("nTargetTimespan = %d nActualTimespan = %d\n" %(nTargetTimespan, nActualTimespan,)) + logging.info("Last %d blocks time average was %d\n" %(nInterval, nActualTimespan,)) + logging.info("Before: %08x %s\n" %(CBlockIndex(pindexLast).Bits(), nActualTimespan,)) + logging.info("After: %08x %s\n" %(GetCompact(int(bnNew)), nActualTimespan,)) return target2bits(bnNew) - - def target2bits(target): MM = 256*256*256 c = ("%064X"%int(target))[2:] @@ -1086,7 +946,6 @@ def num2mpi(n): return struct.pack(">I", datasize) + r - def GetCompact(n): """convert number to bc compact uint""" mpi = num2mpi(n) @@ -1102,12 +961,6 @@ def GetCompact(n): return nCompact - - - - - - def bits2target(bits): """ Convert bits to target """ exponent = ((bits >> 24) & 0xff) @@ -1117,8 +970,6 @@ def bits2target(bits): return (mantissa * (256**(exponent-3))) - - def CalculateDiff(): """ Calculate current difficulty """ # diff is minimun difficulty target / current_target @@ -1132,25 +983,19 @@ def NetworkHashrate(): difficulty = CalculateDiff() return difficulty * 2**32 / 100 / 1000000000 - def HashesTowin(): """ Calculate required hashes to find a block """ return CalculateDiff() * 2**256 / (0xffff * 2**208) - - - def generate_hashes_from_block(data_block): sha256_hash = hashlib.sha256(hashlib.sha256(data_block).digest()).digest()[::-1] return sha256_hash, sha256_hash - - def generate_hash(data_block, targetx): - nonce = 0 + nonce = 0 target = targetx last_updated = time.time() @@ -1159,6 +1004,6 @@ def generate_hash(data_block, targetx): if int(header_hash.encode('hex_codec'), 16) < target: return (sha256_hash, nonce, data_block) else: - nonce +=1 + nonce +=1 data_block = data_block[0:len(data_block) - 4] + struct.pack(' Date: Thu, 15 Mar 2018 10:57:11 -0700 Subject: [PATCH 04/12] Fix missing parens error --- rpc_server.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rpc_server.py b/rpc_server.py index 7d7bb9b..adcb819 100644 --- a/rpc_server.py +++ b/rpc_server.py @@ -55,10 +55,6 @@ def serve_forever(self): server.handle_request() - - - - if __name__ == '__main__': config = ConfigParser.ConfigParser() @@ -76,7 +72,7 @@ def serve_forever(self): run_rpc_command(args.command, rpc_port) sys.exit(0) except socket.error: - print "server not running" + print("Server not running") sys.exit(1) try: From 62eba9afa62c0cbce3a3046e2f08bc4746802b14 Mon Sep 17 00:00:00 2001 From: cvsae <33999023+cvsae@users.noreply.github.com> Date: Thu, 15 Mar 2018 18:11:44 +0000 Subject: [PATCH 05/12] Update main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 0e3646b..429bb73 100644 --- a/main.py +++ b/main.py @@ -508,7 +508,7 @@ def getHash(self): class CBlockchainDB(object): def __init__(self): - self.conn = sqlite3.connect(("{}/blockchain.db")) + self.conn = sqlite3.connect("{}/blockchain.db".format(GetAppDir())) self.conn.text_factory = str self.cur = self.conn.cursor() From f51136d3313c907e53e905cc094ede3cd1cd3085 Mon Sep 17 00:00:00 2001 From: cvsae <33999023+cvsae@users.noreply.github.com> Date: Thu, 15 Mar 2018 18:17:57 +0000 Subject: [PATCH 06/12] Update main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 429bb73..e2d1e7a 100644 --- a/main.py +++ b/main.py @@ -479,7 +479,7 @@ def input_script(self, message): if len(message) > 76: psz_prefix = '4c' - script_prefix = '04ffff001d0104{}{}'.format(psz_prefix, hr(len(message)).encode('hex')) + script_prefix = '04ffff001d0104{}{}'.format(psz_prefix, chr(len(message)).encode('hex')) input_script_f = (script_prefix + message.encode('hex')).decode('hex') self.add("input_script", input_script_f) From 9f7ac98c1368e93392ed00f5680f3c1c99f14c9d Mon Sep 17 00:00:00 2001 From: cvsae <33999023+cvsae@users.noreply.github.com> Date: Thu, 15 Mar 2018 18:23:48 +0000 Subject: [PATCH 07/12] Update main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index e2d1e7a..0174142 100644 --- a/main.py +++ b/main.py @@ -320,7 +320,7 @@ def addtx(self, tx): tx["output_script"], tx["signature"])) # Insert a row of data self.mem_conn.commit() - logging("Mempool() : Transaction %s added to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) + logging.info("Mempool() : Transaction %s added to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) return True logging.info("Mempool() : Transaction %s already to mempool" %(hashlib.sha256(hashlib.sha256(str(tx)).hexdigest()).hexdigest(),)) return False, "Already have" From 6d7b5d149d766b386415e897f90a0af01dd6cab3 Mon Sep 17 00:00:00 2001 From: cvsae <33999023+cvsae@users.noreply.github.com> Date: Thu, 15 Mar 2018 19:09:06 +0000 Subject: [PATCH 08/12] Update miner --- miner | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/miner b/miner index 53528e3..4a7f6df 100755 --- a/miner +++ b/miner @@ -9,7 +9,7 @@ import optparse def Miner(debug, blocks): - logg("SilmeMiner Started\n") + logging.info("SilmeMiner Started\n") while True: @@ -116,16 +116,16 @@ def Miner(debug, blocks): if debug: print("\n\nRunning SilmeMiner with %d transactions in block\n" %(len(pblock.vtx))) - logg("Running SilmeMiner with %d transactions in block" %len(pblock.vtx)) + logging.info("Running SilmeMiner with %d transactions in block" %len(pblock.vtx)) hash, nonce, data_block = generate_hash(blk, target) - logg("SilmeMiner:\n") + logging.info("SilmeMiner:\n") - logg("proof-of-work found \nhash: %s \ntarget: %s\n" %(hash.encode('hex_codec'), target)) + logging.info("proof-of-work found \nhash: %s \ntarget: %s\n" %(hash.encode('hex_codec'), target)) # save key if not AddKey(privatekey): @@ -134,13 +134,13 @@ def Miner(debug, blocks): # Process this block the same as if we had received it from another node if Proccess().thisBlock(data_block, pblock, nonce): - logg("Block accepted\n") + logging.info("Block accepted\n") if CBlockchainDB().insertBlock(pblock, data_block, nonce): - logg("Block successfull added to database") + logging.info("Block successfull added to database") for txhash in included_hashes: Mempool().RemoveTx(txhash) else: - logg("Block failed") + logging.info("Block failed") if __name__ == '__main__': From 9a8ec6a2eac04dbd5f5f56c77015659c3f5bc048 Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 3 May 2018 07:22:08 -0700 Subject: [PATCH 09/12] Install new version of pybitcointools, name changed from that to 'cryptos'. Add pbkdf2 depend --- main.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/main.py b/main.py index 0174142..c82e892 100644 --- a/main.py +++ b/main.py @@ -3,23 +3,25 @@ # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from binascii import hexlify, unhexlify -from binascii import b2a_hex, a2b_hex -from os.path import expanduser -from termcolor import colored -from sys import platform -from construct import * -from pybitcointools import * import logging -import sqlite3 +import os import socket +import sqlite3 import string import struct +import sys +from binascii import a2b_hex, b2a_hex, hexlify, unhexlify +from os.path import expanduser +from sys import platform + +from construct import * +from cryptos import * +from termcolor import colored # python 3.x compatibility try: xrange -except NameError: +except: xrange = range # One silme can be split into 100000000 satoshi @@ -38,8 +40,6 @@ def GetAppDir(): # currently suppports linux - if not platform in ["linux", "linux2"]: - sys.exit(logging.info("Error: Unsupported platform")) return "{}/.silme".format(expanduser("~")) @@ -82,7 +82,7 @@ def GetAppDir(): mempool_cursor = mempool_conn.cursor() mempool_cursor.execute("CREATE TABLE transactions (version, prev, time, value, hash, input_script, output_script, signature)") mempool_conn.commit() - except Exception, e: + except Exception as e: raise @@ -195,7 +195,7 @@ def WriteKey(self, key, pubkey): self.cur.execute("INSERT INTO keys VALUES (?,?)", (key, pubkey)) self.conn.commit() return True - except Exception, e: + except Exception as e: return False @@ -545,7 +545,7 @@ def insertTxs(self, height, pblock): txhash = hashlib.sha256(hashlib.sha256(str(pblock.vtx[x])).hexdigest()).hexdigest() cursor.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?,?)", (height, pblock.vtx[x]["version"],pblock.vtx[x]["prev_out"],pblock.vtx[x]["time"], pblock.vtx[x]["value"], txhash, pblock.vtx[x]["input_script"], pblock.vtx[x]["output_script"], pblock.vtx[x]["signature"])) # Insert a row of data conn.commit() - except Exception, e: + except Exception as e: logging.info(e) return False @@ -559,7 +559,7 @@ def insertBlock(self, pblock, block, nonce): self.conn.commit() self.insertTxs(b_height, pblock) return True - except Exception, e: + except Exception as e: logging.info(e) return False @@ -740,7 +740,7 @@ def thisTxIsVaild(self, tx): try: Sig().VVerify(tx,signature) tx['signature'] = signature - except Exception, e: + except Exception as e: tx['signature'] = signature logging.info("Transaction %s verification error" %hashlib.sha256(hashlib.sha256(str(tx)).digest()).digest().encode("hex_codec")) logging.info(e) @@ -1006,4 +1006,3 @@ def generate_hash(data_block, targetx): else: nonce +=1 data_block = data_block[0:len(data_block) - 4] + struct.pack(' Date: Thu, 3 May 2018 15:28:59 -0700 Subject: [PATCH 10/12] Fix dependencies --- silme_req.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/silme_req.txt b/silme_req.txt index 3cfb035..9a19983 100644 --- a/silme_req.txt +++ b/silme_req.txt @@ -1,4 +1,5 @@ -pybitcointools +git+git://github.com/primal100/pybitcointools bitcoin termcolor construct==2.5.2 +pbkdf2==1.3 From 84b16d8df81e28987912cbf8d7dfc6ab200b2611 Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 3 May 2018 15:34:09 -0700 Subject: [PATCH 11/12] Fix god awful naming --- configure => configure.sh | 0 miner => miner.py | 0 silme_req.txt => requirements.txt | 0 silme-sample.conf => silme.sample.conf | 0 silmed => silmed.sh | 0 silme-qt => wallet.py | 2 +- 6 files changed, 1 insertion(+), 1 deletion(-) rename configure => configure.sh (100%) mode change 100755 => 100644 rename miner => miner.py (100%) mode change 100755 => 100644 rename silme_req.txt => requirements.txt (100%) rename silme-sample.conf => silme.sample.conf (100%) rename silmed => silmed.sh (100%) mode change 100755 => 100644 rename silme-qt => wallet.py (99%) mode change 100755 => 100644 diff --git a/configure b/configure.sh old mode 100755 new mode 100644 similarity index 100% rename from configure rename to configure.sh diff --git a/miner b/miner.py old mode 100755 new mode 100644 similarity index 100% rename from miner rename to miner.py diff --git a/silme_req.txt b/requirements.txt similarity index 100% rename from silme_req.txt rename to requirements.txt diff --git a/silme-sample.conf b/silme.sample.conf similarity index 100% rename from silme-sample.conf rename to silme.sample.conf diff --git a/silmed b/silmed.sh old mode 100755 new mode 100644 similarity index 100% rename from silmed rename to silmed.sh diff --git a/silme-qt b/wallet.py old mode 100755 new mode 100644 similarity index 99% rename from silme-qt rename to wallet.py index 4bc458a..9b2ba52 --- a/silme-qt +++ b/wallet.py @@ -3,7 +3,7 @@ # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from Tkinter import * +from tkinter import * import thread import time import tkMessageBox From 1517568784005e6ed7d7ba98c48c7e883f94d0ee Mon Sep 17 00:00:00 2001 From: Aareon Sullivan Date: Thu, 3 May 2018 15:36:06 -0700 Subject: [PATCH 12/12] Fix README --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ce5ebe7..4ca5fda 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,17 @@ You can contribute to silme, simple open a pull request # INSTAL SILME ``` bash -git clone https://github.com/cvsae/silme +git clone https://github.com/Aareon/silme cd silme -sudo pip install -r silme_req.txt -./configure +sudo pip install -r requirements.txt +sh ./configure.sh ``` # RUN SILME ``` bash cd silme -./silme-qt +py ./wallet.py ``` # USAGE @@ -31,9 +31,9 @@ cd silme Silme supports rpc commands ``` bash -./silmed start - Start rpc server -./silmed stop - Stop rpc server -./silmed help - Get a list of the available commands +sh ./silmed.sh start - Start rpc server +sh ./silmed.sh stop - Stop rpc server +sh ./silmed.sh help - Get a list of the available commands ``` ## MINING