def process_operations(self, op_id): op_info = self.node_api.get_objects([op_id]) for operation in op_info[::-1]: if operation["op"][0] != 0: return op = operation["op"][1] trx = {} # trx["timestamp"] = datetime.datetime.utcnow().strftime( # "%Y%m%d %H:%M") trx["block_num"] = operation["block_num"] block_info = self.node_api.get_block(trx["block_num"]) trx["timestamp"] = block_info["timestamp"] trx["trx_id"] = operation["id"] # Get amount asset_info = self.get_asset_info(op["amount"]["asset_id"]) trx["asset"] = asset_info["symbol"] trx["amount"] = float(op["amount"]["amount"]) / float(10**int( asset_info["precision"])) # Get accounts involved trx["from_id"] = op["from"] trx["to_id"] = op["to"] trx["from"] = self.node_api.get_objects([op["from"]])[0]["name"] trx["to"] = self.node_api.get_objects([op["to"]])[0]["name"] # Decode the memo if "memo" in op: memo = op["memo"] trx["nonce"] = memo["nonce"] try: privkey = PrivateKey(self.memo_key) if trx["to_id"] == self.account["id"]: pubkey = PublicKey(memo["from"], prefix=self.prefix) else: pubkey = PublicKey(memo["to"], prefix=self.prefix) trx["memo"] = Memo.decode_memo(privkey, pubkey, memo["nonce"], memo["message"]) except Exception: trx["memo"] = None else: trx["nonce"] = None trx["memo"] = None if trx["from_id"] == self.account["id"]: self.onSent(trx) elif trx["to_id"] == self.account["id"]: self.onReceive(trx)
def verify_signature(accUsername, auth_sig_hash, auth_sig): dacom = BitShares(DACOM_NODE_WSS) account = dacom.rpc.get_account(accUsername) signature = unhexlify(auth_sig) pub = PublicKey(account['active']['key_auths'][0][0], 'FLO') vk = ecdsa.VerifyingKey.from_public_point(pub.point(), curve=ecdsa.SECP256k1) sig = bytes(signature)[1:] recoverParameter = (bytes(signature)[0]) - 4 - 27 digest = hashlib.sha256(auth_sig_hash).digest() # digest = hashlib.sha256(b'sdf').digest() p = _recover_public_key(digest, sig, recoverParameter) if p.to_der() != vk.to_der(): raise ValueError()
def ovaltine(memo, private_key): """ Decode BitShares Transfer Memo """ return ( decode_memo( PrivateKey(private_key), # associated with memo["to"] public key PublicKey(memo["from"], prefix=PREFIX), memo["nonce"], memo["message"], ) .replace("\n", "") .replace(" ", "") )
def process_operations(self, operations): for operation in operations[::-1]: opID = operation["id"] block = operation["block_num"] op = operation["op"][1] if operation["op"][0] != 0: continue " Get assets involved in Fee and Transfer " fee_asset = graphene.getObject(op["fee"]["asset_id"]) amount_asset = graphene.getObject(op["amount"]["asset_id"]) " Amounts for fee and transfer " fee_amount = float(op["fee"]["amount"]) / float(10**int( fee_asset["precision"])) amount_amount = float(op["amount"]["amount"]) / float(10**int( amount_asset["precision"])) " Get accounts involved " from_account = graphene.getObject(op["from"]) to_account = graphene.getObject(op["to"]) " Decode the memo " memomsg = "" if "memo" in op: memo = op["memo"] try: account_name = to_account["name"] if account_name not in self.memo_wif_keys: memomsg = "-- missing wif key for %s" % account_name else: privkey = PrivateKey(self.memo_wif_keys[account_name]) pubkey = PublicKey(memo["from"], prefix=self.prefix) memomsg = Memo.decode_memo(privkey, pubkey, memo["nonce"], memo["message"]) except Exception as e: memomsg = "--cannot decode-- (%s)" % str(e) " Print out " print(("last_op: %s | block:%s | from %s -> to: %s " + "| fee: %f %s | amount: %f %s | memo: %s") % (opID, block, from_account["name"], to_account["name"], fee_amount, fee_asset["symbol"], amount_amount, amount_asset["symbol"], memomsg)) " Store this as last op seen" self.last_op = opID
def __init__(self, ip, port): self.stream = Buffer() self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((ip, port)) raw_pk = self.s.recv(33) self.pk = GraphenePublicKey(raw_pk.hex()) sk = PrivateKey() point = self.pk.point() * int.from_bytes(bytes(sk), "big") x: int = point.x() raw_data = x.to_bytes(32, "big") self.shared_secret = sha512(raw_data).digest() key = sha256(self.shared_secret).digest() crc = cityhash.CityHash128(self.shared_secret) data = crc.to_bytes(16, "little") iv = data[8:16] + data[:8] self.s.sendall(bytes.fromhex(repr(sk.pubkey))) self.encryptor = AES.new(key, AES.MODE_CBC, iv) self.test = AES.new(key, AES.MODE_CBC, iv) self.decryptor = AES.new(key, AES.MODE_CBC, iv) self.worker_thread = threading.Thread(target=self.worker) self.worker_thread.start() self.send( 5006, { "user_agent": "Haruka Mock Client", "core_protocol_version": 106, "inbound_address": "0.0.0.0", "inbound_port": 0, "outbound_port": 0, "node_public_key": sk.pubkey, "signed_shared_secret": ecdsa.sign_message(self.shared_secret, str(sk)), "chain_id": bytes.fromhex( "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" ), "user_data": { "platform": String("unknown") } })
def process_operations(self, operations) : for operation in operations[::-1] : opID = operation["id"] block = operation["block_num"] op = operation["op"][1] " Consider only Transfer operations " if operation["op"][0] != 0: continue # Get assets involved in Fee and Transfer fee_asset = api.getObject(op["fee"]["asset_id"]) amount_asset = api.getObject(op["amount"]["asset_id"]) # Amounts for fee and transfer fee_amount = float(op["fee"]["amount"]) / float(10 ** int(fee_asset["precision"])) amount_amount = float(op["amount"]["amount"]) / float(10 ** int(amount_asset["precision"])) # Get accounts involved from_account = api.getObject(op["from"]) to_account = api.getObject(op["to"]) # Decode the memo memomsg = "" if "memo" in op : memo = op["memo"] try : # if possible privkey = PrivateKey(config.memo_wif_key) pubkey = PublicKey(memo["from"], prefix=prefix) memomsg = Memo.decode_memo(privkey, pubkey, memo["nonce"], memo["message"]) except Exception as e: # if not possible memomsg = "--cannot decode-- %s" % str(e) # Print out print("last_op: %s | block:%s | from %s -> to: %s | fee: %f %s | amount: %f %s | memo: %s" % ( opID, block, from_account["name"], to_account["name"], fee_amount, fee_asset["symbol"], amount_amount, amount_asset["symbol"], memomsg))
def process_operations(self, operations): for operation in operations[::-1]: opID = operation["id"] block = operation["block_num"] op = operation["op"][1] if not "amount" in op: continue # Get assets involved in Fee and Transfer fee_asset = api.getObject(op["fee"]["asset_id"]) amount_asset = api.getObject(op["amount"]["asset_id"]) # Amounts for fee and transfer fee_amount = float(op["fee"]["amount"]) / float(10**int( fee_asset["precision"])) amount_amount = float(op["amount"]["amount"]) / float(10**int( amount_asset["precision"])) # Get accounts involved from_account = api.getObject(op["from"]) to_account = api.getObject(op["to"]) # Decode the memo memo = op["memo"] try: # if possible privkey = PrivateKey(config.memo_wif_key) pubkey = PublicKey(memo["from"], prefix=prefix) memomsg = Memo.decode_memo(privkey, pubkey, memo["nonce"], memo["message"]) except Exception as e: # if not possible print("--cannot decode-- %s" % e) continue # Print out print( "last_op: %s | block:%s | from %s -> to: %s | fee: %f %s | amount: %f %s | memo: %s" % (opID, block, from_account["name"], to_account["name"], fee_amount, fee_asset["symbol"], amount_amount, amount_asset["symbol"], memomsg)) # Parse the memo pattern = re.compile('[A-Z0-9]{3}-[A-Z0-9-]{8}') searchResults = pattern.search(memomsg) if not searchResults: continue ref_code = searchResults.group(0) email = "" pattern = re.compile('[a-z0-9][-a-z0-9_\+\.]*[a-z0-9]\@.+\.[a-z]+') searchResults = pattern.search(memomsg.lower()) if searchResults: email = searchResults.group(0) # Request to Faucet headers = {'content-type': 'text/plain'} query = "refcode[code]=%s&refcode[account]=%s&refcode[asset_symbol]=%s&refcode[asset_amount]=%s&refcode[send_to]=%s" % ( ref_code, from_account["name"], amount_asset["symbol"], op["amount"]["amount"], email) print("--- query: %s" % query) response = requests.post(config.faucet_url, params=query, headers=headers)
class Connection: def __init__(self, ip, port): self.stream = Buffer() self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((ip, port)) raw_pk = self.s.recv(33) self.pk = GraphenePublicKey(raw_pk.hex()) sk = PrivateKey() point = self.pk.point() * int.from_bytes(bytes(sk), "big") x: int = point.x() raw_data = x.to_bytes(32, "big") self.shared_secret = sha512(raw_data).digest() key = sha256(self.shared_secret).digest() crc = cityhash.CityHash128(self.shared_secret) data = crc.to_bytes(16, "little") iv = data[8:16] + data[:8] self.s.sendall(bytes.fromhex(repr(sk.pubkey))) self.encryptor = AES.new(key, AES.MODE_CBC, iv) self.test = AES.new(key, AES.MODE_CBC, iv) self.decryptor = AES.new(key, AES.MODE_CBC, iv) self.worker_thread = threading.Thread(target=self.worker) self.worker_thread.start() self.send( 5006, { "user_agent": "Haruka Mock Client", "core_protocol_version": 106, "inbound_address": "0.0.0.0", "inbound_port": 0, "outbound_port": 0, "node_public_key": sk.pubkey, "signed_shared_secret": ecdsa.sign_message(self.shared_secret, str(sk)), "chain_id": bytes.fromhex( "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" ), "user_data": { "platform": String("unknown") } }) def send(self, msg_type, data: dict): message_type = message_type_table[msg_type] message = message_type(data) res = message.pack() # for name, type_ in definition.items(): # res.extend(pack_field(data.get(name, None), type_)) length = len(res) if length % 16 != 8: pad_length = (8 - length % 16) if pad_length < 0: pad_length += 16 res += b"\x00" * pad_length res = pack("<II", length, msg_type) + res data = self.encryptor.encrypt(res) logging.debug("SEND >>> %s" % res) parse_message(res, None, 1) self.s.sendall(data) def worker(self): data = bytearray() while True: data.extend(self.s.recv(65535)) if len(data) % 16 == 0: msg = self.decryptor.decrypt(bytes(data)) else: continue data = bytearray() self.stream.write(msg) if len(msg) == 0: break logging.debug("RECV <<< %s" % msg) while self.stream.count(): size = unpack("<I", self.stream.peek(4))[0] expect = size + 8 + (16 - (size + 8) % 16) % 16 logging.debug("expect %s have %s" % (expect, self.stream.count())) if expect <= self.stream.count(): parse_message(self.stream.read(expect), self, 2) else: break