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)
Exemple #2
0
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()
Exemple #3
0
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(" ", "")
    )
Exemple #4
0
    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
Exemple #5
0
 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")
             }
         })
Exemple #6
0
    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))
Exemple #7
0
    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)
Exemple #8
0
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