Esempio n. 1
0
def pts_address(pubkey, compressed, ver, prefix):
    if compressed:
        pubkeybin = PublicKey(pubkey, **{"prefix": prefix}).__bytes__()
    else:
        pubkeybin = unhexlify(
            PublicKey(pubkey, **{
                "prefix": prefix
            }).unCompressed())

    #print(hexlify(pubkeybin),len(pubkeybin))
    bin = '%02x' % (ver) + hexlify(
        ripemd160(hexlify(hashlib.sha256(pubkeybin).digest()).decode(
            'ascii'))).decode("ascii")
    checksum = doublesha256(bin)

    #print('bin',bin)
    #print('csum1',checksum)
    hex = bin + hexlify(checksum[:4]).decode('ascii')
    #print('hex',hex)
    hash = hexlify(ripemd160(hex)).decode('ascii')
    #print('hash',hash)
    checksum2 = ripemd160(hash)
    #print('csum2',checksum2)
    b58 = prefix + base58encode(hash + hexlify(checksum2[:4]).decode('ascii'))
    #print('b58',b58)
    return b58
Esempio n. 2
0
    def decodeMemo(self, **kwargs):
        from_pubkey = kwargs.get('from')
        to_pubkey = kwargs.get('to')
        nonce = kwargs.get('nonce')
        cipher_text = kwargs.get('message')
        #		local_privkey = self.privkeys[0]
        if not isinstance(from_pubkey, PublicKey):
            from_pubkey = PublicKey(from_pubkey, prefix=from_pubkey[0:3])
        if not isinstance(to_pubkey, PublicKey):
            to_pubkey = PublicKey(to_pubkey, prefix=to_pubkey[0:3])
#		if str(self.pubkey) == str(from_pubkey):
#			other_pubkey = to_pubkey
#		elif str(self.pubkey) == str(to_pubkey):
#			other_pubkey = from_pubkey
        if str(from_pubkey) in self.privkeys:
            local_privkey = self.privkeys[str(from_pubkey)]
            other_pubkey = to_pubkey
        elif str(to_pubkey) in self.privkeys:
            local_privkey = self.privkeys[str(to_pubkey)]
            other_pubkey = from_pubkey
        else:
            raise MissingKey(
                "No Private Key found for neither %s nor %s public keys" %
                (str(from_pubkey), str(to_pubkey)))
        clear = BTSMemo.decode_memo(local_privkey, other_pubkey, nonce,
                                    cipher_text)
        return clear
Esempio n. 3
0
    def decrypt(self, memo):
        """ Decrypt a memo

            :param str memo: encrypted memo message
            :returns: encrypted memo
            :rtype: str
        """
        if not memo:
            return None

        # We first try to decode assuming we received the memo
        try:
            memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                memo["to"])
            pubkey = memo["from"]
        except KeyNotFound:
            try:
                # if that failed, we assume that we have sent the memo
                memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                    memo["from"])
                pubkey = memo["to"]
            except KeyNotFound:
                # if all fails, raise exception
                raise MissingKeyError(
                    "Non of the required memo keys are installed!"
                    "Need any of {}".format([memo["to"], memo["from"]]))

        if not hasattr(self, 'chain_prefix'):
            self.chain_prefix = self.blockchain.prefix

        return BtsMemo.decode_memo(PrivateKey(memo_wif),
                                   PublicKey(pubkey, prefix=self.chain_prefix),
                                   memo.get("nonce"), memo.get("message"))
Esempio n. 4
0
    def encrypt(self, memo):
        """ Encrypt a memo

            :param str memo: clear text memo message
            :returns: encrypted memo
            :rtype: str
        """
        if not memo:
            return None

        nonce = str(random.getrandbits(64))
        memo_wif = self.bitshares.wallet.getPrivateKeyForPublicKey(
            self.from_account["options"]["memo_key"])
        if not memo_wif:
            raise MissingKeyError("Memo key for %s missing!" %
                                  self.from_account["name"])

        enc = BtsMemo.encode_memo(
            PrivateKey(memo_wif),
            PublicKey(self.to_account["options"]["memo_key"],
                      prefix=self.bitshares.prefix), nonce, memo)

        return {
            "message": enc,
            "nonce": nonce,
            "from": self.from_account["options"]["memo_key"],
            "to": self.to_account["options"]["memo_key"]
        }
Esempio n. 5
0
    def create_blind_contact(self):
        label = self.ui.blindContactLabel.text().strip()
        public_key = self.ui.blindContactPubkey.text().strip()
        if len(public_key) == 0:
            self.ui.blindContactPubkey.setFocus()
            return
        if len(label) == 0:
            self.ui.blindContactLabel.setFocus()
            return

        from bitsharesbase.account import PublicKey
        try:
            test = PublicKey(public_key)
        except Exception as e:
            showerror("Not a valid Public Key: " + str(e))
            return
        try:
            self.iso.store.blindAccountStorage.add(public_key, label, keys=0)
        except Exception as e:
            showexc(e)
            return

        table = self.ui.blindAccounts
        n = table.rowCount()

        self._insert_blind_account_row(n, label, public_key, 0)

        self.ui.blindContactLabel.setText("")
        self.ui.blindContactPubkey.setText("")
        self.ba_page_balances()
Esempio n. 6
0
 def encodeMemo(self, from_pubkey, to_pubkey, clear_text):
     from_pubkey = self.guessKey(from_pubkey)
     privkey = self.privkeys[str(from_pubkey)]
     if not isinstance(from_pubkey, (PublicKey, GPHPublicKey)):
         from_pubkey = PublicKey(from_pubkey, prefix=from_pubkey[0:3])
     if not isinstance(to_pubkey, (PublicKey, GPHPublicKey)):
         to_pubkey = PublicKey(to_pubkey, prefix=to_pubkey[0:3])
     import random
     nonce = str(random.getrandbits(64))
     cipher = BTSMemo.encode_memo(privkey, to_pubkey, nonce, clear_text)
     return {
         "to": str(to_pubkey),
         "from": str(privkey.pubkey),
         "nonce": nonce,
         "message": cipher
     }
Esempio n. 7
0
    def update_memo_key(self, key, account=None):
        """ Update an account's memo public key

            This method does **not** add any private keys to your
            wallet but merely changes the memo public key.

            :param str key: New memo public key
            :param str account: (optional) the account to allow access
                to (defaults to ``default_account``)
        """
        if not account:
            if "default_account" in config:
                account = config["default_account"]
        if not account:
            raise ValueError("You need to provide an account")

        PublicKey(key, prefix=self.rpc.chain_params["prefix"])

        account = Account(account, bitshares_instance=self)
        account["options"]["memo_key"] = key
        op = operations.Account_update(
            **{
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "account": account["id"],
                "new_options": account["options"],
                "extensions": {}
            })
        return self.finalizeOp(op, account["name"], "active")
Esempio n. 8
0
    async def _encrypt_memo(self, to, memo):
        ''' 加密备注信息
        '''
        if not memo:
            return None

        # 生成nonce
        nonce = str(random.getrandbits(64))
        if SysConfig().memo_key == None:
            raise MissingKeyError('Memo key {0} missing!'.format(SysConfig().account))

        # 加密备注信息
        prefix = self.client.chain_params['prefix']
        to_account = await self.client.get_account_by_name(to)
        enc = BtsMemo.encode_memo(
            PrivateKey(SysConfig().memo_key, prefix=prefix),
            PublicKey(
                prefix=prefix,
                pk=to_account['options']['memo_key']
            ),
            nonce,
            memo
        )

        # 返回结构信息
        memo_data = {
            'nonce': nonce,
            'message': enc,
            'to': to_account['options']['memo_key'],
            'from': self.account['options']['memo_key']
        }
        return to_account['id'], memo_data
Esempio n. 9
0
 def test_encrypt(self):
     for memo in test_cases:
         enc = encode_memo(
             PrivateKey(memo["wif"]),
             PublicKey(memo["to"], prefix="GPH"),
             memo["nonce"],
             memo["plain"],
         )
         self.assertEqual(memo["message"], enc)
Esempio n. 10
0
 def test_decrypt_bugged_padding(self):
     for memo in not_enough_padding:
         dec = decode_memo(
             PrivateKey(memo["wif"]),
             PublicKey(memo["to"], prefix="GPH"),
             memo["nonce"],
             memo["message"],
         )
         self.assertEqual(memo["plain"], dec)
Esempio n. 11
0
 def _create_account(account):
     parent_account = Account(DEFAULT_ACCOUNT, bitshares_instance=bitshares)
     public_key = PublicKey.from_privkey(PRIVATE_KEYS[0], prefix=bitshares.prefix)
     bitshares.create_account(
         account,
         registrar=DEFAULT_ACCOUNT,
         referrer=parent_account['id'],
         referrer_percent=0,
         owner_key=public_key,
         active_key=public_key,
         memo_key=public_key,
         storekeys=False,
     )
Esempio n. 12
0
    def approveproposal(self, proposal_ids, account=None, approver=None):
        """ Approve Proposal

            :param list proposal_id: Ids of the proposals
            :param str account: (optional) the account to allow access
                to (defaults to ``default_account``)
        """
        from .proposal import Proposal
        if not account:
            if "default_account" in config:
                account = config["default_account"]
        if not account:
            raise ValueError("You need to provide an account")
        account = Account(account, bitshares_instance=self)
        is_key = approver and approver[:3] == self.rpc.chain_params["prefix"]
        if not approver and not is_key:
            approver = account
        elif approver and not is_key:
            approver = Account(approver, bitshares_instance=self)
        else:
            approver = PublicKey(approver)

        if not isinstance(proposal_ids, (list, set)):
            proposal_ids = set(proposal_ids)

        op = []
        for proposal_id in proposal_ids:
            proposal = Proposal(proposal_id, bitshares_instance=self)
            update_dict = {
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                'fee_paying_account': account["id"],
                'proposal': proposal["id"],
                "prefix": self.rpc.chain_params["prefix"]
            }
            if is_key:
                update_dict.update({
                    'key_approvals_to_add': [str(approver)],
                })
            else:
                update_dict.update({
                    'active_approvals_to_add': [approver["id"]],
                })
            op.append(operations.Proposal_update(**update_dict))
        if is_key:
            self.txbuffer.appendSigner(account["name"], "active")
            return self.finalizeOp(op, approver, "active")
        else:
            return self.finalizeOp(op, approver["name"], "active")
Esempio n. 13
0
    def verify(self, **kwargs):
        """ Verify a message with an account's memo key

            :param str account: (optional) the account that owns the bet
                (defaults to ``default_account``)

            :returns: True if the message is verified successfully
            :raises InvalidMessageSignature if the signature is not ok
        """
        # Split message into its parts
        parts = re.split("|".join(MESSAGE_SPLIT), self.message)
        parts = [x for x in parts if x.strip()]

        assert len(parts) > 2, "Incorrect number of message parts"

        message = parts[0].strip()
        signature = parts[2].strip()
        # Parse the meta data
        meta = dict(re.findall(r'(\S+)=(.*)', parts[1]))

        # Ensure we have all the data in meta
        assert "account" in meta
        assert "memokey" in meta
        assert "block" in meta
        assert "timestamp" in meta

        # Load account from blockchain
        account = Account(meta.get("account"),
                          bitshares_instance=self.bitshares)

        # Test if memo key is the same as on the blockchain
        if not account["options"]["memo_key"] == meta["memokey"]:
            log.error("Memo Key of account {} on the Blockchain".format(
                account["name"]) +
                      "differs from memo key in the message: {} != {}".format(
                          account["options"]["memo_key"], meta["memokey"]))

        # Reformat message
        message = SIGNED_MESSAGE_META.format(**locals())

        # Verify Signature
        pubkey = verify_message(message, unhexlify(signature))

        # Verify pubky
        pk = PublicKey(hexlify(pubkey).decode("ascii"))
        if format(pk, self.bitshares.prefix) != meta["memokey"]:
            raise InvalidMessageSignature

        return True
Esempio n. 14
0
    def decrypt(self, memo):
        """ Decrypt a memo

            :param str memo: encrypted memo message
            :returns: encrypted memo
            :rtype: str
        """
        if not memo:
            return None

        memo_wif = self.bitshares.wallet.getPrivateKeyForPublicKey(
            self.to_account["options"]["memo_key"])
        if not memo_wif:
            raise MissingKeyError("Memo key for %s missing!" %
                                  self.to_account["name"])

        # TODO: Use pubkeys of the message, not pubkeys of account!
        return BtsMemo.decode_memo(
            PrivateKey(memo_wif),
            PublicKey(self.from_account["options"]["memo_key"],
                      prefix=self.bitshares.rpc.chain_params["prefix"]),
            memo.get("nonce"), memo.get("message"))
Esempio n. 15
0
    def create_account(
        self,
        account_name,
        registrar=None,
        referrer="1.2.35641",
        referrer_percent=50,
        owner_key=None,
        active_key=None,
        memo_key=None,
        password=None,
        additional_owner_keys=[],
        additional_active_keys=[],
        additional_owner_accounts=[],
        additional_active_accounts=[],
        proxy_account="proxy-to-self",
        storekeys=True,
    ):
        """ Create new account on BitShares

            The brainkey/password can be used to recover all generated keys (see
            `bitsharesbase.account` for more details.

            By default, this call will use ``default_account`` to
            register a new name ``account_name`` with all keys being
            derived from a new brain key that will be returned. The
            corresponding keys will automatically be installed in the
            wallet.

            .. warning:: Don't call this method unless you know what
                          you are doing! Be sure to understand what this
                          method does and where to find the private keys
                          for your account.

            .. note:: Please note that this imports private keys
                      (if password is present) into the wallet by
                      default. However, it **does not import the owner
                      key** for security reasons. Do NOT expect to be
                      able to recover it from the wallet if you lose
                      your password!

            :param str account_name: (**required**) new account name
            :param str registrar: which account should pay the registration fee
                                (defaults to ``default_account``)
            :param str owner_key: Main owner key
            :param str active_key: Main active key
            :param str memo_key: Main memo_key
            :param str password: Alternatively to providing keys, one
                                 can provide a password from which the
                                 keys will be derived
            :param array additional_owner_keys:  Additional owner public keys
            :param array additional_active_keys: Additional active public keys
            :param array additional_owner_accounts: Additional owner account names
            :param array additional_active_accounts: Additional acctive account names
            :param bool storekeys: Store new keys in the wallet (default: ``True``)
            :raises AccountExistsException: if the account already exists on the blockchain

        """
        if not registrar and config["default_account"]:
            registrar = config["default_account"]
        if not registrar:
            raise ValueError(
                "Not registrar account given. Define it with " +
                "registrar=x, or set the default_account using uptick")
        if password and (owner_key or active_key or memo_key):
            raise ValueError("You cannot use 'password' AND provide keys!")

        try:
            Account(account_name, bitshares_instance=self)
            raise AccountExistsException
        except:
            pass

        referrer = Account(referrer, bitshares_instance=self)
        registrar = Account(registrar, bitshares_instance=self)

        " Generate new keys from password"
        from bitsharesbase.account import PasswordKey, PublicKey
        if password:
            active_key = PasswordKey(account_name, password, role="active")
            owner_key = PasswordKey(account_name, password, role="owner")
            memo_key = PasswordKey(account_name, password, role="memo")
            active_pubkey = active_key.get_public_key()
            owner_pubkey = owner_key.get_public_key()
            memo_pubkey = memo_key.get_public_key()
            active_privkey = active_key.get_private_key()
            # owner_privkey   = owner_key.get_private_key()
            memo_privkey = memo_key.get_private_key()
            # store private keys
            if storekeys:
                # self.wallet.addPrivateKey(owner_privkey)
                self.wallet.addPrivateKey(active_privkey)
                self.wallet.addPrivateKey(memo_privkey)
        elif (owner_key and active_key and memo_key):
            active_pubkey = PublicKey(active_key,
                                      prefix=self.rpc.chain_params["prefix"])
            owner_pubkey = PublicKey(owner_key,
                                     prefix=self.rpc.chain_params["prefix"])
            memo_pubkey = PublicKey(memo_key,
                                    prefix=self.rpc.chain_params["prefix"])
        else:
            raise ValueError(
                "Call incomplete! Provide either a password or public keys!")
        owner = format(owner_pubkey, self.rpc.chain_params["prefix"])
        active = format(active_pubkey, self.rpc.chain_params["prefix"])
        memo = format(memo_pubkey, self.rpc.chain_params["prefix"])

        owner_key_authority = [[owner, 1]]
        active_key_authority = [[active, 1]]
        owner_accounts_authority = []
        active_accounts_authority = []

        # additional authorities
        for k in additional_owner_keys:
            owner_key_authority.append([k, 1])
        for k in additional_active_keys:
            active_key_authority.append([k, 1])

        for k in additional_owner_accounts:
            addaccount = Account(k, bitshares_instance=self)
            owner_accounts_authority.append([addaccount["id"], 1])
        for k in additional_active_accounts:
            addaccount = Account(k, bitshares_instance=self)
            active_accounts_authority.append([addaccount["id"], 1])

        # voting account
        voting_account = Account(proxy_account or "proxy-to-self")

        op = {
            "fee": {
                "amount": 0,
                "asset_id": "1.3.0"
            },
            "registrar": registrar["id"],
            "referrer": referrer["id"],
            "referrer_percent": referrer_percent * 100,
            "name": account_name,
            'owner': {
                'account_auths': owner_accounts_authority,
                'key_auths': owner_key_authority,
                "address_auths": [],
                'weight_threshold': 1
            },
            'active': {
                'account_auths': active_accounts_authority,
                'key_auths': active_key_authority,
                "address_auths": [],
                'weight_threshold': 1
            },
            "options": {
                "memo_key": memo,
                "voting_account": voting_account["id"],
                "num_witness": 0,
                "num_committee": 0,
                "votes": [],
                "extensions": []
            },
            "extensions": {},
            "prefix": self.rpc.chain_params["prefix"]
        }
        op = operations.Account_create(**op)
        return self.finalizeOp(op, registrar, "active")
Esempio n. 16
0
 def test_shared_secret(self):
     for s in test_shared_secrets:
         priv = PrivateKey(s[0])
         pub = PublicKey(s[1], prefix="GPH")
         shared_secret = get_shared_secret(priv, pub)
         self.assertEqual(s[2], shared_secret)
Esempio n. 17
0
    def disallow(self,
                 foreign,
                 permission="active",
                 account=None,
                 threshold=None):
        """ Remove additional access to an account by some other public
            key or account.

            :param str foreign: The foreign account that will obtain access
            :param str permission: (optional) The actual permission to
                modify (defaults to ``active``)
            :param str account: (optional) the account to allow access
                to (defaults to ``default_account``)
            :param int threshold: The threshold that needs to be reached
                by signatures to be able to interact
        """
        if not account:
            if "default_account" in config:
                account = config["default_account"]
        if not account:
            raise ValueError("You need to provide an account")

        if permission not in ["owner", "active"]:
            raise ValueError(
                "Permission needs to be either 'owner', or 'active")
        account = Account(account, bitshares_instance=self)
        authority = account[permission]

        try:
            pubkey = PublicKey(foreign, prefix=self.rpc.chain_params["prefix"])
            affected_items = list(
                filter(lambda x: x[0] == str(pubkey), authority["key_auths"]))
            authority["key_auths"] = list(
                filter(lambda x: x[0] != str(pubkey), authority["key_auths"]))
        except:
            try:
                foreign_account = Account(foreign, bitshares_instance=self)
                affected_items = list(
                    filter(lambda x: x[0] == foreign_account["id"],
                           authority["account_auths"]))
                authority["account_auths"] = list(
                    filter(lambda x: x[0] != foreign_account["id"],
                           authority["account_auths"]))
            except:
                raise ValueError(
                    "Unknown foreign account or unvalid public key")

        removed_weight = affected_items[0][1]

        # Define threshold
        if threshold:
            authority["weight_threshold"] = threshold

        # Correct threshold (at most by the amount removed from the
        # authority)
        try:
            self._test_weights_treshold(authority)
        except:
            log.critical("The account's threshold will be reduced by %d" %
                         (removed_weight))
            authority["weight_threshold"] -= removed_weight
            self._test_weights_treshold(authority)

        op = operations.Account_update(
            **{
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "account": account["id"],
                permission: authority,
                "extensions": {}
            })
        if permission == "owner":
            return self.finalizeOp(op, account["name"], "owner")
        else:
            return self.finalizeOp(op, account["name"], "active")
    def clean_txs(self, account: Account, symbol: str,
                  transactions: Iterable[dict]) -> Generator[dict, None, None]:
        """
        Filters a list of transactions by the receiving account, yields dict's conforming with
        :class:`payments.models.Deposit`

        :param str account: The 'to' account to filter by
        :param str symbol:  The symbol of the token being filtered
        :param list<dict> transactions:  A list<dict> of transactions to filter
        :return: A generator yielding ``dict`` s conforming to :class:`payments.models.Deposit`
        """
        for tx in transactions:
            try:
                data = tx['op'][
                    1]  # unwrap the transaction structure to get at the data within

                if data['to'] != account['id'] or data['from'] == account['id']:
                    continue

                # cache asset data for 5 mins, so we aren't spamming the RPC node for data
                amount_info = data['amount']
                asset_id = amount_info['asset_id']
                asset_key = 'btsasset:%s' % (asset_id, )
                asset = cache.get(asset_key, default=None)
                if asset is None:
                    asset_obj = self.get_asset_obj(asset_id)
                    if asset_obj is not None:
                        asset = {
                            'symbol': asset_obj.symbol,
                            'precision': asset_obj.precision
                        }
                        cache.set(asset_key, asset, 300)
                    else:
                        continue
                if asset['symbol'] != symbol:
                    continue

                raw_amount = Decimal(int(amount_info['amount']))
                transfer_quantity = raw_amount / (10**asset['precision'])

                # cache account data for 5 mins, so we aren't spamming the RPC node for data
                account_key = 'btsacc:%s' % (data['from'], )
                from_account_name = cache.get(account_key,
                                              default=data['from'])
                if from_account_name == data['from']:
                    from_account = self.get_account_obj(data['from'])
                    if from_account is not None:
                        from_account_name = from_account.name
                        cache.set(account_key, from_account_name, 300)
                    else:
                        log.exception(
                            'From account not found for transaction %s', tx)

                # decrypt the transaction memo
                memo_msg = ''
                if 'memo' in data:
                    memo = data['memo']
                    try:
                        memokey = self.get_private_key(account.name, 'memo')
                        privkey = PrivateKey(memokey)
                        pubkey = PublicKey(memo['from'], prefix='BTS')
                        memo_msg = decode_memo(privkey, pubkey, memo['nonce'],
                                               memo['message'])
                    except Exception as e:
                        memo_msg = '--cannot decode memo--'
                        log.exception(
                            'Error decoding memo %s, got exception %s',
                            memo['message'], e)

                # fetch timestamp from the block containing this transaction
                # (a hugely inefficient lookup but unfortunately no other way to do this)
                tx_datetime = datetime.fromtimestamp(
                    self.get_block_timestamp(tx['block_num']))
                tx_datetime = timezone.make_aware(tx_datetime, pytz.UTC)

                clean_tx = dict(txid=tx['id'],
                                coin=self.coins[symbol].symbol,
                                tx_timestamp=tx_datetime,
                                from_account=from_account_name,
                                to_account=account.name,
                                memo=memo_msg,
                                amount=transfer_quantity)
                yield clean_tx
            except Exception as e:
                log.exception(
                    'Error parsing transaction data. Skipping this TX. tx = %s, exception = %s',
                    tx, e)
                continue
Esempio n. 19
0
    def verify(self, **kwargs):
        """ Verify a message with an account's memo key

            :param str account: (optional) the account that owns the bet
                (defaults to ``default_account``)

            :returns: True if the message is verified successfully
            :raises InvalidMessageSignature if the signature is not ok
        """
        # Split message into its parts
        parts = re.split("|".join(MESSAGE_SPLIT), self.message)
        parts = [x for x in parts if x.strip()]

        assert len(parts) > 2, "Incorrect number of message parts"

        # Strip away all whitespaces before and after the message
        message = parts[0].strip()
        signature = parts[2].strip()
        # Parse the meta data
        meta = dict(re.findall(r'(\S+)=(.*)', parts[1]))

        log.info("Message is: {}".format(message))
        log.info("Meta is: {}".format(json.dumps(meta)))
        log.info("Signature is: {}".format(signature))

        # Ensure we have all the data in meta
        assert "account" in meta, "No 'account' could be found in meta data"
        assert "memokey" in meta, "No 'memokey' could be found in meta data"
        assert "block" in meta, "No 'block' could be found in meta data"
        assert "timestamp" in meta, \
            "No 'timestamp' could be found in meta data"

        account_name = meta.get("account").strip()
        memo_key = meta["memokey"].strip()

        try:
            PublicKey(memo_key)
        except Exception:
            raise InvalidMemoKeyException(
                "The memo key in the message is invalid")

        # Load account from blockchain
        try:
            account = Account(account_name,
                              blockchain_instance=self.blockchain)
        except AccountDoesNotExistsException:
            raise AccountDoesNotExistsException(
                "Could not find account {}. Are you connected to the right chain?"
                .format(account_name))

        # Test if memo key is the same as on the blockchain
        if not account["options"]["memo_key"] == memo_key:
            raise WrongMemoKey(
                "Memo Key of account {} on the Blockchain ".format(
                    account["name"]) +
                "differs from memo key in the message: {} != {}".format(
                    account["options"]["memo_key"], memo_key))

        # Reformat message
        enc_message = SIGNED_MESSAGE_META.format(**locals())

        # Verify Signature
        pubkey = verify_message(enc_message, unhexlify(signature))

        # Verify pubky
        pk = PublicKey(hexlify(pubkey).decode("ascii"))
        if format(pk, self.blockchain.prefix) != memo_key:
            raise InvalidMessageSignature

        return True
Esempio n. 20
0
        print('invalid transaction for bit20 publication: {}'.format(
            json.dumps(trx, indent=4)))
        return False


for f in account_history_b20:

    if not is_valid_bit20_publication(f):
        print('Hijacking attempt of the bit20 feed? trx: {}'.format(
            json.dumps(f, indent=4)))
        continue

    memo = f['op'][1]['memo']

    privkey = PrivateKey(wifkey_announce)
    pubkey = PublicKey(Account(f['op'][1]['from'])['options']['memo_key'])
    memomsg = BtsMemo.decode_memo(privkey, pubkey, memo["nonce"],
                                  memo["message"])

    #print(memomsg)
    if memomsg.startswith('COMPOSITION'):
        # last_updated = re.search('\((.*)\)', memomsg)
        # if last_updated:
        #     last_updated = pendulum.from_format(last_updated.group(1), '%Y/%m/%d')
        #     #print(last_updated)
        bit20 = json.loads(memomsg.split(')', maxsplit=1)[1])
        break

else:
    print(
        "Did not find any bit20 composition in the last {} messages to account bittwenty.feed"
Esempio n. 21
0
    async def _process_transfer_operations(self, client, operation):
        ''' 处理转账操作
        '''
        # 筛选操作类型
        if operation['op'][0] != self.TRANSFER_OPERATION:
            return

        # 操作基本信息
        trx = {}
        op = operation['op'][1]

        # 获取区块信息
        trx['heigth'] = operation['block_num']
        block_info = await client.get_block(trx['heigth'])
        trx['timestamp'] = block_info['timestamp']

        # 获取交易ID
        trx_in_block = operation['trx_in_block']
        transaction = block_info['transactions'][trx_in_block]
        trx['txid'] = await self._get_transaction_id(transaction)

        # 获取转账金额
        asset = await self._get_asset_info(client, op['amount']['asset_id'])
        trx['asset'] = asset['symbol']
        trx['asset_id'] = op['amount']['asset_id']
        trx['amount'] = str(
            float(op['amount']['amount']) / float(10**int(asset['precision'])))

        # 获取转账手续费
        trx['fee'] = {}
        fee = await self._get_asset_info(client, op['fee']['asset_id'])
        trx['fee']['asset'] = fee['symbol']
        trx['fee']['asset_id'] = op['fee']['asset_id']
        trx['fee']['amount'] = str(
            float(op['fee']['amount']) / float(10**int(fee['precision'])))

        # 获取涉案账户
        trx['to_id'] = op['to']
        trx['from_id'] = op['from']
        trx['to'] = (await client.get_objects([op['to']]))[0]['name']
        trx['from'] = (await client.get_objects([op['from']]))[0]['name']

        # 解码备注信息
        if 'memo' in op:
            memo = op['memo']
            trx['nonce'] = memo['nonce']
            try:
                privkey = PrivateKey(SysConfig().memo_key)
                prefix = client.chain_params['prefix']
                if trx['to_id'] == self._account['id']:
                    pubkey = PublicKey(memo['from'], prefix=prefix)
                else:
                    pubkey = PublicKey(memo['to'], prefix=prefix)
                trx['memo'] = BtsMemo.decode_memo(privkey, pubkey,
                                                  memo['nonce'],
                                                  memo['message'])
            except Exception as e:
                logging.warn('Failed to decode memo, %s, %s', operation['id'],
                             str(e))
                trx['memo'] = None
        else:
            trx['memo'] = None
            trx['nonce'] = None
        return trx
Esempio n. 22
0
 def __init__(self,pubkey,period):
     o= GrapheneObject(OrderedDict ([
         ("vesting_period",Uint64(period)),
         ("public_key",PublicKey(pubkey,**{"prefix":"CYB"})) 
     ]))
     super().__init__(o,1)
Esempio n. 23
0
def decrypt_msg(priv_key, pub_key, nonce, msg):
    dec = decode_memo(PrivateKey(priv_key), PublicKey(pub_key, prefix="NEST"),
                      nonce, msg)
    return dec
Esempio n. 24
0
    async def process_operations(self, op_id):
        """ 处理操作
        """
        op_info = await self.node_api.get_objects([op_id])
        for operation in op_info[::-1]:
            if operation["op"][0] != 0:
                return

            # 操作基本信息
            trx = {}
            op = operation['op'][1]
            trx['trx_id'] = operation['id']

            # 获取区块信息
            trx['block_num'] = operation['block_num']
            block_info = await self.node_api.get_block(trx['block_num'])
            trx['timestamp'] = block_info['timestamp']

            # 获取转账金额
            asset = await self.get_asset_info(op['amount']['asset_id'])
            trx['asset'] = asset['symbol']
            trx['asset_id'] = op['amount']['asset_id']
            trx['amount'] = float(op['amount']['amount']) / float(10**int(
                asset['precision']))

            # 获取转账手续费
            trx['fee'] = {}
            fee = await self.get_asset_info(op['fee']['asset_id'])
            trx['fee']['asset'] = fee['symbol']
            trx['fee']['asset_id'] = op['fee']['asset_id']
            trx['fee']['amount'] = float(op['fee']['amount']) / float(10**int(
                fee['precision']))

            # 获取涉案账户
            trx['to_id'] = op['to']
            trx['from_id'] = op['from']
            trx['to'] = (await
                         self.node_api.get_objects([op['to']]))[0]['name']
            trx['from'] = (await
                           self.node_api.get_objects([op['from']]))[0]['name']

            # 解码备注信息
            if 'memo' in op:
                memo = op['memo']
                trx['nonce'] = memo['nonce']
                try:
                    privkey = PrivateKey(self.wifkey)
                    prefix = self.node_api.chain_params['prefix']
                    if trx['to_id'] == self.account['id']:
                        pubkey = PublicKey(memo['from'], prefix=prefix)
                    else:
                        pubkey = PublicKey(memo['to'], prefix=prefix)
                    trx['memo'] = BtsMemo.decode_memo(privkey, pubkey,
                                                      memo['nonce'],
                                                      memo['message'])
                except Exception:
                    trx['memo'] = None
            else:
                trx['memo'] = None
                trx['nonce'] = None

            # 触发转账事件
            if trx['from_id'] == self.account['id']:
                await self.on_sent(trx)
            elif trx['to_id'] == self.account['id']:
                await self.on_receive(trx)
Esempio n. 25
0
    def allow(self,
              foreign,
              weight=None,
              permission="active",
              account=None,
              threshold=None):
        """ Give additional access to an account by some other public
            key or account.

            :param str foreign: The foreign account that will obtain access
            :param int weight: (optional) The weight to use. If not
                define, the threshold will be used. If the weight is
                smaller than the threshold, additional signatures will
                be required. (defaults to threshold)
            :param str permission: (optional) The actual permission to
                modify (defaults to ``active``)
            :param str account: (optional) the account to allow access
                to (defaults to ``default_account``)
            :param int threshold: The threshold that needs to be reached
                by signatures to be able to interact
        """
        from copy import deepcopy
        if not account:
            if "default_account" in config:
                account = config["default_account"]
        if not account:
            raise ValueError("You need to provide an account")

        if permission not in ["owner", "active"]:
            raise ValueError(
                "Permission needs to be either 'owner', or 'active")
        account = Account(account, bitshares_instance=self)

        if not weight:
            weight = account[permission]["weight_threshold"]

        authority = deepcopy(account[permission])
        try:
            pubkey = PublicKey(foreign, prefix=self.rpc.chain_params["prefix"])
            authority["key_auths"].append([str(pubkey), weight])
        except:
            try:
                foreign_account = Account(foreign, bitshares_instance=self)
                authority["account_auths"].append(
                    [foreign_account["id"], weight])
            except:
                raise ValueError(
                    "Unknown foreign account or invalid public key")
        if threshold:
            authority["weight_threshold"] = threshold
            self._test_weights_treshold(authority)

        op = operations.Account_update(
            **{
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "account": account["id"],
                permission: authority,
                "extensions": {},
                "prefix": self.rpc.chain_params["prefix"]
            })
        if permission == "owner":
            return self.finalizeOp(op, account["name"], "owner")
        else:
            return self.finalizeOp(op, account["name"], "active")