def main(c=0): if type(c)==int: p={'command':sys.argv[1:]} else: p={'command':c} if len(p['command'])==0: p['command'].append(' ') c=p['command'] if c[0]=='make_PM': tx=build_pm() return run_command({'command':['pushtx', tools.package(tx).encode('base64')]}) elif c[0]=='buy_shares': tx=build_buy_shares() return run_command({'command':['pushtx', tools.package(tx).encode('base64')]}) elif c[0]=='start': r=connect({'command':'blockcount'}) if is_off(r): p=raw_input('what is your password?\n') daemonize(lambda: threads.main(p)) else: print('blockchain is already running') elif c[0]=='new_address': if len(c)<2: print('what is your brain wallet? not enough inputs.') else: privkey=tools.det_hash(c[1]) pubkey=tools.privtopub(privkey) address=tools.make_address([pubkey], 1) return({'brain':str(c[1]), 'privkey':str(privkey), 'pubkey':str(pubkey), 'address':str(address)}) else: return run_command(p)
def build_pm(): tx={'type':'prediction_market', 'fees':0} pubkey=str(raw_input('What is the address or pubkey of the owner of the PM?\n>')) if len(pubkey)>40: tx['owner']=tools.make_address([pubkey], 1) else: tx['owner']=pubkey tx['PM_id']=str(raw_input('What is the unique name for this new prediction market?\n>')) tx['B']=int(raw_input('how big should B be? Initial investment is B*ln(n) where n is the number of states\n>')) num_decisions=int(raw_input('how many decisions is this prediction market to be based upon?\n>')) tx['decisions']=[] for i in range(num_decisions): tx['decisions'].append(str(raw_input('What is the unique name of the '+str(i)+' decision?\n>'))) num_states=int(raw_input('how many states can this PM result in?\n>')) if num_states>2**num_decisions: print('too many states') return False tx['states_combinatory']=[] tx['states']=[] for i in range(num_states): tx['states'].append(str(raw_input('what is the text title of the '+str(i)+' state?\n>'))) if i!=num_states-1: next_comb=(str(raw_input('how does the '+str(i)+' state depend upon the outcome of the decisions? For example: if there are 2 decisions, and this market only comes true when the first is "yes" and the second is "no", then you would put: "1 0" here.\n>'))) tx['states_combinatory'].append(map(int, next_comb.split(' '))) print('tx for copy/pasting into pushtx: '+tools.package(tx).encode('base64')) return tx
def insert_block(pubkey, rewarded_pubkey): length = tools.db_get('length') if length == -1: # this is the first ever block candidate_block = genesis(pubkey) else: # get the last block prev_block = tools.db_get(length) candidate_block = make_block(prev_block, tools.db_get('txs'), pubkey) txs = copy.deepcopy(candidate_block['txs']) flag = True for tx in txs: if tx['type'] == 'mint': # no need to add reward flag = False if flag: txs = txs + [make_mint(rewarded_pubkey)] candidate_block['txs'] = txs if tools.db_existence('privkey'): privkey = tools.db_get('privkey') else: return 'no private key is known, so the tx cannot be signed. Here is the tx: \n' + str( tools.package(txs).encode('base64').replace('\n', '')) candidate_block['auth_sign'] = tools.sign(tools.det_hash(candidate_block), privkey) candidate_block['auth_pubkey'] = pubkey if candidate_block is None: return else: custom.queues['suggested_blocks'].put(candidate_block)
def genesis(pubkey): out = {'version': custom.version, 'length': 0, 'time': time.time(), 'txs': [make_mint(pubkey)]} out = tools.unpackage(tools.package(out)) return out
def genesis(pubkey, DB): out={'version':custom.version, 'length':0, 'time':time.time(), 'target':blockchain.target(DB), 'txs':[make_mint(pubkey, DB)]} out=tools.unpackage(tools.package(out)) return out
def common_buy_shares(tx, num_states, brainwallet): privkey = tools.det_hash(brainwallet) pubkey = tools.privtopub(privkey) address = tools.make_address([pubkey], 1) tx['pubkeys'] = [pubkey] tx['count'] = tools.count(address, {}) cost = txs_tools.cost_to_buy_shares(tx) tx['price_limit'] = int(cost * 1.01) + 1 print( 'now for a little proof of work. This may take several minutes. The purpose of this pow is to make it more difficult for a front runner to steal your trade.' ) tx = tools.unpackage(tools.package(tx)) tx = tools.POW(tx) tx['signatures'] = [tools.sign(tools.det_hash(tx), privkey)] print('tx for copy/pasting into pushtx: ' + tools.package(tx).encode('base64')) return tx
def __init__(self, *parts): parts = package(parts) assert "agent" in parts.keys() assert "call" in parts.keys() super(Brick, self).__init__() for key in parts: setattr(self, key, parts[key]) self.agent.bricks[id] = self return self
def genesis(pubkey): out = { 'version': custom.version, 'length': 0, 'time': time.time(), 'txs': [make_mint(pubkey)] } out = tools.unpackage(tools.package(out)) return out
def genesis(pubkey, DB): target_ = target.target() out = {'version': custom.version, 'length': 0, 'time': time.time(), 'target': target_, 'diffLength': blockchain.hexInvert(target_), 'txs': [make_mint(pubkey, DB)]} out = tools.unpackage(tools.package(out)) return out
def rangeRequest(dic, DB): ran = dic['range'] out = [] counter = 0 while len(tools.package(out)) < 50000 and ran[0] + counter <= ran[1]: block = blockchain.db_get(ran[0] + counter, DB) if 'length' in block: out.append(block) counter += 1 return out
def make_block(prev_block, txs, pubkey): leng = int(prev_block['length']) + 1 out = {'version': custom.version, 'txs': txs, # dont forget to add coinbase transaction ;) 'length': leng, 'time': time.time(), 'prevHash': tools.det_hash(prev_block)} out = tools.unpackage(tools.package(out)) return out
def make_block(prev_block, txs, pubkey, DB): leng=int(prev_block['length'])+1 out={'version':custom.version, 'txs':txs+[make_mint(pubkey, DB)], 'length':leng, 'time':time.time(), 'target':blockchain.target(DB, leng), 'prevHash':tools.det_hash(prev_block)} out=tools.unpackage(tools.package(out)) return out
def send_msg(data, sock): data=tools.package(data) data=tools.buffer_(str(len(data)), 5)+data while data: time.sleep(0.0001) try: sent = sock.send(data) except: return 'peer died' data = data[sent:] return 0
def rangeRequest(dic, DB): ran = dic['range'] out = [] counter = 0 while (len(tools.package(out)) < custom.max_download and ran[0] + counter <= ran[1]): block = tools.db_get(ran[0] + counter, DB) if 'length' in block: out.append(block) counter += 1 return out
def build_buy_shares(): tx={'type':'buy_shares', 'PM_id':str(raw_input('What is the unique name for this prediction market?\n>'))} num_states=int(raw_input('how many states does this pm have?\n>')) tx['buy']=[] for i in range(num_states): tx['buy'].append(int(raw_input('how many shares do you want to buy of state '+str(i)+'? To sell states, use negative numbers.\n>'))) brainwallet=str(raw_input('What is your brainwallet\n>')) privkey=tools.det_hash(brainwallet) pubkey=tools.privtopub(privkey) address=tools.make_address([pubkey], 1) tx['pubkeys']=[pubkey] tx['count'] = tools.count(address, {}) cost=txs_tools.cost_to_buy_shares(tx) tx['price_limit']=int(cost*1.01) print('now for a little proof of work. This may take several minutes. The purpose of this pow is to make it more difficult for a front runner to steal your trade.') tx=tools.unpackage(tools.package(tx)) tx=tools.POW(tx) tx['signatures']=[tools.sign(tools.det_hash(tx), privkey)] print('tx for copy/pasting into pushtx: '+tools.package(tx).encode('base64')) return tx
def genesis(pubkey, DB): target = blockchain.target(DB) out = {'version': custom.version, 'length': 0, 'time': time.time(), 'target': target, 'diffLength': blockchain.hexInvert(target), 'txs': [make_mint(pubkey, DB)]} print('out: ' + str(out)) out = tools.unpackage(tools.package(out)) return out
def send_msg(data, sock): data = tools.package(data) data = tools.buffer_(str(len(data)), 5) + data while data: time.sleep(0.0001) try: sent = sock.send(data) except: return 'peer died' data = data[sent:] return 0
def rangeRequest(dic): ran = dic['range'] out = [] counter = 0 while (len(tools.package(out)) < custom.max_download and ran[0] + counter <= ran[1]): block = tools.db_get(ran[0] + counter, custom.queues) if 'length' in block: out.append(block) counter += 1 return out
def serve_forever(message_handler_func, PORT, queue): server = socket.socket() server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(('127.0.0.1', PORT)) server.listen(100) while True: client, addr = server.accept() (ip, port) = addr data = client.recv(MAX_MESSAGE_SIZE) #we could insert security checks here data = tools.unpackage(data) client.sendall(tools.package(message_handler_func(data, queue)))
def serve_forever(message_handler_func, PORT, queue): server = socket.socket() server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(("127.0.0.1", PORT)) server.listen(100) while True: client, addr = server.accept() (ip, port) = addr data = client.recv(MAX_MESSAGE_SIZE) # we could insert security checks here data = tools.unpackage(data) client.send(tools.package(message_handler_func(data, queue)))
def make_block(prev_block, txs, pubkey): leng = int(prev_block['length']) + 1 out = { 'version': custom.version, 'txs': txs, # dont forget to add coinbase transaction ;) 'length': leng, 'time': time.time(), 'prevHash': tools.det_hash(prev_block) } out = tools.unpackage(tools.package(out)) return out
def make_block(prev_block, txs, pubkey, DB): leng=int(prev_block['length'])+1 target=blockchain.target(DB, leng) diffLength=blockchain.hexSum(prev_block['diffLength'], blockchain.hexInvert(target)) out={'version':custom.version, 'txs':txs+[make_mint(pubkey, DB)], 'length':leng, 'time':time.time(), 'diffLength':diffLength, 'target':target, 'prevHash':tools.det_hash(prev_block)} out=tools.unpackage(tools.package(out)) return out
def main(): info=sys.argv p={'command':sys.argv[1:]} if len(p['command'])==0: p['command'].append(' ') c=p['command'] if c[0]=='make_PM': tx=build_pm() run_command({'command':['pushtx', tools.package(tx).encode('base64')]}) elif c[0]=='buy_shares': tx=build_buy_shares() run_command({'command':['pushtx', tools.package(tx).encode('base64')]}) elif c[0]=='start': r=connect({'command':'blockcount'}) if is_truthcoin_off(r): p=raw_input('what is your password?\n') if sys.platform == 'win32': pypath = list(os.path.split(sys.executable)) pypath[-1] = 'pythonw.exe' os.system('start '+os.path.join(*pypath)+' threads.py '+p) sys.exit(0) else: daemonize(lambda: threads.main(p)) else: print('truthcoin is already running') elif c[0]=='new_address': if len(c)<2: print('what is your brain wallet? not enough inputs.') else: privkey=tools.det_hash(c[1]) pubkey=tools.privtopub(privkey) address=tools.make_address([pubkey], 1) print('brain: ' +str(c[1])) print('privkey: ' +str(privkey)) print('pubkey: ' +str(pubkey)) print('address: ' +str(address)) else: run_command(p)
def make_block(prev_block, txs, pubkey, DB): leng = int(prev_block['length']) + 1 target = blockchain.target(DB, leng) diffLength = blockchain.hexSum(prev_block['diffLength'], blockchain.hexInvert(target)) out = {'version': custom.version, 'txs': txs + [make_mint(pubkey, DB)], 'length': leng, 'time': time.time(), 'diffLength': diffLength, 'target': target, 'prevHash': tools.det_hash(prev_block)} out = tools.unpackage(tools.package(out)) return out
def create_sign_tx(): on_block=tools.local_get('length')+1 if on_block==0: time.sleep(1) return{'error':'not ready'} r=tools.det_random(on_block) jackpots=[] address=tools.local_get('address') l=max(-1, on_block-1-(custom.long_time*2-custom.medium_time)) election_block=tools.db_get(l+1) proof=tools.local_get('balance_proofs'+str(l)) if 'root_hash' not in election_block: return({'error':'database changed'}) a=tools.db_verify(election_block['root_hash'], address, proof) if a==False: #tools.log('election block: ' +str(election_block)) #tools.log('proof: ' +str(proof)) return({'error':'not valid proof'}) old_balance=a['amount'] M=custom.all_money for j in range(custom.jackpot_nonces): if tools.winner(old_balance, M, r, address, j): jackpots.append(j) if len(jackpots)>0: tx={'on_block':on_block, 'jackpots':jackpots, 'type':'sign', 'amount':M/3000/3} tx['B']=old_balance tx['proof']=proof if proof=='empty': time.sleep(1) return {'error':'not ready'} secrets=tools.local_get('secrets') if str(on_block) in secrets: secret=secrets[str(on_block)] else: secret=tools.unpackage(tools.package({'salt':str(random.random())+str(random.random()), 'entropy':random.randint(0,1)})) secrets[str(on_block)]=secret tools.local_put('secrets', secrets) tx['secret_hash']=tools.det_hash(secret) if on_block>0: block=tools.db_get(on_block-1) if 'amount' in block and block['amount']==0: return({'error':'database changed'}) #tools.log('on_block: ' +str(a)) tx['prev']=block['block_hash'] else: tx= {'error':'no jackpots'} return tx
def buy_block(DB, args): gap=1#this should be an argument. #we should also let the user delete as many blocks first as they want, to build a fork from a point in history. length=tools.local_get('length') prev_block=tools.db_get(length) txs=tools.local_get('txs') privkey=tools.local_get('privkey') height=tools.local_get('height') block=default_block(length+1, height+gap, txs+[sign(mint_tx(gap), privkey)]) to_hash='' if length>-1: to_hash={'prev_hash':prev_block['block_hash'], 'txs':block['txs']} block['block_hash']=tools.det_hash(to_hash) block['root_hash']=tools.db_root() block=sign(block, privkey) block = tools.unpackage(tools.package(block)) DB['suggested_blocks'].put(block) return block
def connect(msg, host, port): if len(msg)<1 or len(msg)>MAX_MESSAGE_SIZE: print('wrong sized message') return s = socket.socket() try: s.settimeout(4) s.connect((str(host), int(port))) msg['version']=custom.version s.send(tools.package(msg)) response = s.recv(MAX_MESSAGE_SIZE) #print(response) return tools.unpackage(response) except Exception as e: #print('THE ERROR WAS: ' +str(e)) #print('disconnect') return {'error':e}
def build_pm(): tx = {'type': 'prediction_market', 'fees': 0} pubkey = str( raw_input('What is the address or pubkey of the owner of the PM?\n>')) if len(pubkey) > 40: tx['owner'] = tools.make_address([pubkey], 1) else: tx['owner'] = pubkey tx['PM_id'] = str( raw_input( 'What is the unique name for this new prediction market?\n>')) tx['B'] = int( raw_input( 'how big should B be? Initial investment is B*ln(n) where n is the number of states\n>' )) num_decisions = int( raw_input( 'how many decisions is this prediction market to be based upon?\n>' )) tx['decisions'] = [] for i in range(num_decisions): tx['decisions'].append( str( raw_input('What is the unique name of the ' + str(i) + ' decision?\n>'))) num_states = int(raw_input('how many states can this PM result in?\n>')) if num_states > 2**num_decisions: print('too many states') return False tx['states_combinatory'] = [] tx['states'] = [] for i in range(num_states): tx['states'].append( str( raw_input('what is the text title of the ' + str(i) + ' state?\n>'))) if i != num_states - 1: next_comb = (str( raw_input( 'how does the ' + str(i) + ' state depend upon the outcome of the decisions? For example: if there are 2 decisions, and this market only comes true when the first is "yes" and the second is "no", then you would put: "1 0" here.\n>' ))) tx['states_combinatory'].append(map(int, next_comb.split(' '))) print('tx for copy/pasting into pushtx: ' + tools.package(tx).encode('base64')) return tx
def connect(msg, host, port): if len(msg) < 1 or len(msg) > MAX_MESSAGE_SIZE: print("wrong sized message") return s = socket.socket() try: s.settimeout(2) s.connect((str(host), int(port))) msg["version"] = custom.version s.send(tools.package(msg)) response = s.recv(MAX_MESSAGE_SIZE) # print(response) return tools.unpackage(response) except Exception as e: # print('THE ERROR WAS: ' +str(e)) # print('disconnect') return {"error": "error"}
def trade_shares(DB, args): #args = [ PM_id, buy ] privkey = tools.db_get('privkey') pubkey = tools.privtopub(privkey) address = tools.make_address([pubkey], 1) tx = { 'type': 'buy_shares', 'PM_id': args[0], 'buy': csv2vec(args[1]), 'pubkeys': [pubkey], 'count': tools.count(address, {}) } cost = txs_tools.cost_to_buy_shares(tx) tx['price_limit'] = int(cost * 1.01) + 1 tx = tools.unpackage(tools.package(tx)) tx = tools.POW(tx) tx['signatures'] = [tools.sign(tools.det_hash(tx), privkey)] return easy_add_transaction(tx, DB, privkey)
def buy_block(DB, args): gap = 1 # this should be an argument. # we should also let the user delete as many blocks first as they want, to build a fork from a point in history. length = tools.local_get("length") prev_block = tools.db_get(length) txs = tools.local_get("txs") privkey = tools.local_get("privkey") height = tools.local_get("height") block = default_block(length + 1, height + gap, txs + [sign(mint_tx(gap), privkey)]) to_hash = "" if length > -1: to_hash = {"prev_hash": prev_block["block_hash"], "txs": block["txs"]} block["block_hash"] = tools.det_hash(to_hash) block["root_hash"] = tools.db_root() block = sign(block, privkey) block = tools.unpackage(tools.package(block)) DB["suggested_blocks"].put(block) return block
def pushblock(dic, DB): length = tools.db_get('length') block = tools.db_get(length, DB) if 'peer' in dic: peer = dic['peer'] else: peer = False if 'blocks' in dic: if peer != False: a = tools.package(peer) not in blacklist if a not in blacklist or blacklist[a] < 500: for i in range(20): if tools.fork_check(dic['blocks'], DB, length, block): blockchain.delete_block(DB) length -= 1 for block in dic['blocks']: DB['suggested_blocks'].put([block, peer]) else: DB['suggested_blocks'].put([dic['block'], peer]) return 'success'
def connect(msg, host, port): msg['version'] = custom.version msg = tools.package(msg) if len(msg) < 1 or len(msg) > MAX_MESSAGE_SIZE: print('wrong sized message') return s = socket.socket() try: s.settimeout(2) s.connect((str(host), int(port))) s.sendall(msg) response = s.recv(MAX_MESSAGE_SIZE) #print(response) return tools.unpackage(response) except Exception as e: #print('THE ERROR WAS: ' +str(e)) #print('disconnect') return {'error': e}
def buy_block(DB, args): gap = 1 #this should be an argument. #we should also let the user delete as many blocks first as they want, to build a fork from a point in history. length = tools.local_get('length') prev_block = tools.db_get(length) txs = tools.local_get('txs') privkey = tools.local_get('privkey') height = tools.local_get('height') block = default_block(length + 1, height + gap, txs + [sign(mint_tx(gap), privkey)]) to_hash = '' if length > -1: to_hash = {'prev_hash': prev_block['block_hash'], 'txs': block['txs']} block['block_hash'] = tools.det_hash(to_hash) block['root_hash'] = tools.db_root() block = sign(block, privkey) block = tools.unpackage(tools.package(block)) DB['suggested_blocks'].put(block) return block
def easy_add_transaction(tx_orig, DB, privkey='default'): tx = copy.deepcopy(tx_orig) if privkey in ['default', 'Default']: if tools.db_existence('privkey'): privkey = tools.db_get('privkey') else: return ('no private key is known, so the tx cannot be signed. Here is the tx: \n' + str( tools.package(tx_orig).encode('base64').replace('\n', ''))) pubkey = tools.privtopub(privkey) address = tools.make_address([pubkey], 1) if 'count' not in tx: try: tx['count'] = tools.count(address, {}) except: tx['count'] = 1 if 'pubkeys' not in tx: tx['pubkeys'] = [pubkey] if 'signatures' not in tx: tx['signatures'] = [tools.sign(tools.det_hash(tx), privkey)] return (blockchain.add_tx(tx, DB))
def connect(msg, host, port, response_time=1): if len(msg) < 1 or len(msg) > MAX_MESSAGE_SIZE: tools.log('wrong sized message') return('wrong size') s = socket.socket() s.setblocking(0) b=connect_socket(s, str(host), int(port)) if not b: s.close() return ({'error':'cannot connect: '+str(host)}) msg['version'] = custom.version sendall(s, tools.package(msg)) response=recvall(s, MAX_MESSAGE_SIZE, response_time) s.close() try: return tools.unpackage(response) except: pass if 'recvall timeout error' in response: return({'error':'cannot download: '+str(host)})
def serve_once(PORT, handler, heart_queue, server): heart_queue.put('server: '+str(PORT)) time.sleep(0.1) try: client, addr = server.accept() except: return (ip, port) = addr peer=[str(ip), int(port)] try: data=recvall(client, MAX_MESSAGE_SIZE) except: client.close() return if type(data)==type('string'): data=tools.unpackage(data) data['peer']=peer try: sendall(client, tools.package(handler(data))) except: pass client.close()
def serve_once(PORT, handler, heart_queue, server): heart_queue.put('server: ' + str(PORT)) time.sleep(0.1) try: client, addr = server.accept() except: return (ip, port) = addr peer = [str(ip), int(port)] try: data = recvall(client, MAX_MESSAGE_SIZE) except: client.close() return if type(data) == type('string'): data = tools.unpackage(data) data['peer'] = peer try: sendall(client, tools.package(handler(data))) except: pass client.close()
def too_big_block(tx, txs): return len(tools.package(txs+[tx])) > networking.MAX_MESSAGE_SIZE - 5000
def db_put(key, dic, DB): return DB['db'].Put(str(key), tools.package(dic))
def db_put(key, dic, DB): key=str(key) if len(key)==130: key=tools.pub2addr(key) return DB['db'].Put(key, tools.package(dic))
def too_big_block(tx, txs): return len( tools.package(txs + [tx])) > networking.MAX_MESSAGE_SIZE - 5000
def db_put(key, dic, DB): key=str(key) if len(key)==130: key=tools.pub2addr(key)#store by pubkey hash instead of #pubkey to defend against theoretical quantum computing attack. return DB['db'].Put(key, tools.package(dic))
def easy_add_transaction(tx_orig, DB, privkey='default'): tx = copy.deepcopy(tx_orig) try: tx['count'] = tools.count(DB['address'], DB) except: tx['count'] = 1 if privkey=='default': if 'privkey' in DB: privkey=DB['privkey'] else: return('no private key is known, so the tx cannot be signed. Here is the tx: \n'+str(tools.package(tx_orig).encode('base64').replace('\n', ''))) if 'pubkeys' not in tx: tx['pubkeys']=[tools.privtopub(privkey)] tx['signatures'] = [tools.sign(tools.det_hash(tx), privkey)] tools.log('collect winnings 3') return(blockchain.add_tx(tx, DB))
def easy_add_transaction(tx_orig, DB, privkey='default'): tx = copy.deepcopy(tx_orig) if privkey in ['default', 'Default']: if tools.db_existence('privkey'): privkey=tools.db_get('privkey') else: return('no private key is known, so the tx cannot be signed. Here is the tx: \n'+str(tools.package(tx_orig).encode('base64').replace('\n', ''))) pubkey=tools.privtopub(privkey) address=tools.make_address([pubkey], 1) if 'count' not in tx: try: tx['count'] = tools.count(address, {}) except: tx['count'] = 1 if 'pubkeys' not in tx: tx['pubkeys']=[pubkey] if 'signatures' not in tx: tx['signatures'] = [tools.sign(tools.det_hash(tx), privkey)] return(blockchain.add_tx(tx, DB))
def run_command(p): response=connect(p) if is_off(response): print('blockchain is probably off. Use command: "./cli.py start" to turn it on.') return tools.package(response, indent=2, sort_keys=True)