コード例 #1
0
ファイル: transactions.py プロジェクト: 2lewis/minter-sdk
    def get_sender_address(cls, tx):
        """
        Get sender address from tx.
        Recover public key from tx and then get address from public key, if tx has single signature type, or get
        decoded sender address, if tx has multi signature type.
        Args:
            tx (dict): transaction dict
        Returns:
            Minter address (string)
        """

        # Remember signature data and remove it from tx
        signature_data = tx.pop('signature_data')

        # If there is sender address in signature data (multi signature tx), return it
        if signature_data.get('from_mx'):
            return signature_data['from_mx']

        # Otherwise (single signature tx), recover public key and get address from public key
        # Unhexlify (convert to bin (ascii)) all non-numeric dict values
        tx = MinterHelper.hex2bin_recursive(tx)

        # Encode tx data to RLP
        tx['data'] = rlp.encode(list(tx['data'].values()))

        # Message
        tx_rlp = rlp.encode(list(tx.values()))
        _keccak = MinterHelper.keccak_hash(tx_rlp)

        # Recover public key
        public_key = MinterPrefix.PUBLIC_KEY + ECDSA.recover(_keccak, tuple(signature_data.values()))

        return MinterWallet.get_address_from_public_key(public_key)
コード例 #2
0
ファイル: check.py プロジェクト: vrntsv/minter-sdk
    def from_raw(cls, rawcheck):
        """
        Create check instance from raw check
        Args:
            rawcheck (str)
        Returns:
            MinterCheck
        """

        # Remove check prefix and RLP decode it
        rawcheck = MinterPrefix.remove_prefix(
            string=rawcheck,
            prefix=MinterPrefix.CHECK
        )
        rawcheck = binascii.unhexlify(rawcheck)
        decoded = rlp.decode(rawcheck)

        # Create MinterCheck instance
        kwargs = {
            'nonce': int(decoded[0].decode()),
            'chain_id': MinterHelper.bin2int(decoded[1]),
            'due_block': MinterHelper.bin2int(decoded[2]),
            'coin': MinterConvertor.decode_coin_name(decoded[3]),
            'value': MinterConvertor.convert_value(
                value=MinterHelper.bin2int(decoded[4]),
                to='bip'
            ),
            'lock': binascii.hexlify(decoded[5]).decode(),
            'signature': {
                'v': MinterHelper.bin2int(decoded[6]),
                'r': MinterHelper.bin2hex(decoded[7]),
                's': MinterHelper.bin2hex(decoded[8])
            }
        }
        check = MinterCheck(**kwargs)

        # Recover owner address
        msg_hash = cls.__hash(data=[
            int(binascii.hexlify(str(check.nonce).encode()), 16),
            check.chain_id,
            check.due_block,
            MinterConvertor.encode_coin_name(check.coin),
            MinterConvertor.convert_value(value=check.value, to='pip'),
            MinterHelper.hex2bin(check.lock)
        ])
        public_key = ECDSA.recover(msg_hash, list(check.signature.values()))
        public_key = MinterPrefix.PUBLIC_KEY + public_key

        check.owner = MinterWallet.get_address_from_public_key(public_key)

        return check
コード例 #3
0
    def from_raw(cls, rawcheck):
        """
        Create check instance from raw check
        Args:
            rawcheck (str)
        Returns:
            MinterCheck
        """

        # Remove check prefix and RLP decode it
        rawcheck = MinterHelper.prefix_remove(rawcheck)
        rawcheck = bytes.fromhex(rawcheck)
        decoded = rlp.decode(rawcheck)

        # Create MinterCheck instance
        kwargs = {
            'nonce': int(decoded[0].decode()),
            'chain_id': int.from_bytes(decoded[1], 'big'),
            'due_block': int.from_bytes(decoded[2], 'big'),
            'coin': MinterHelper.decode_coin_name(decoded[3]),
            'value': MinterHelper.to_bip(int.from_bytes(decoded[4], 'big')),
            'gas_coin': MinterHelper.decode_coin_name(decoded[5]),
            'lock': decoded[6].hex(),
            'signature': {
                'v': int.from_bytes(decoded[7], 'big'),
                'r': decoded[8].hex(),
                's': decoded[9].hex()
            }
        }
        check = MinterCheck(**kwargs)

        # Recover owner address
        msg_hash = cls.__hash(data=[
            int(str(check.nonce).encode().hex(), 16), check.chain_id,
            check.due_block,
            MinterHelper.encode_coin_name(check.coin),
            MinterHelper.to_pip(check.value),
            MinterHelper.encode_coin_name(check.gas_coin),
            bytes.fromhex(check.lock)
        ])
        public_key = ECDSA.recover(msg_hash, tuple(check.signature.values()))
        public_key = MinterHelper.prefix_add(public_key, PREFIX_PUBKEY)

        check.owner = MinterWallet.get_address_from_public_key(public_key)

        return check
コード例 #4
0
ファイル: transactions.py プロジェクト: vrntsv/minter-sdk
    def from_raw(cls, raw_tx):
        """
        Generate tx object from raw tx
        Args:
            raw_tx (string)
        Returns:
            MinterTx child instance
        """

        tx = rlp.decode(binascii.unhexlify(raw_tx))

        # Populate structure dict with decoded tx data
        struct = copy.copy(cls._STRUCTURE_DICT)
        struct.update({
            'nonce': int(binascii.hexlify(tx[0]), 16),
            'chain_id': int(binascii.hexlify(tx[1]), 16),
            'gas_price': int(binascii.hexlify(tx[2]), 16),
            'gas_coin': tx[3].decode(),
            'type': int(binascii.hexlify(tx[4]), 16),
            'payload': tx[6].decode().replace(chr(0), ''),
            'service_data': tx[7].decode().replace(chr(0), ''),
            'signature_type': int(binascii.hexlify(tx[8]), 16)
        })

        # Get signature data
        signature_data = rlp.decode(tx[9])
        struct.update({
            'signature_data': {
                'v': int(binascii.hexlify(signature_data[0]), 16),
                'r': binascii.hexlify(signature_data[1]).decode(),
                's': binascii.hexlify(signature_data[2]).decode()
            }
        })

        # Find out which of tx instance need to create depending on it's type
        data = rlp.decode(tx[5])
        if struct['type'] == MinterDelegateTx.TYPE:
            _class = MinterDelegateTx
        elif struct['type'] == MinterSendCoinTx.TYPE:
            _class = MinterSendCoinTx
        elif struct['type'] == MinterBuyCoinTx.TYPE:
            _class = MinterBuyCoinTx
        elif struct['type'] == MinterCreateCoinTx.TYPE:
            _class = MinterCreateCoinTx
        elif struct['type'] == MinterDeclareCandidacyTx.TYPE:
            _class = MinterDeclareCandidacyTx
        elif struct['type'] == MinterRedeemCheckTx.TYPE:
            _class = MinterRedeemCheckTx
        elif struct['type'] == MinterSellAllCoinTx.TYPE:
            _class = MinterSellAllCoinTx
        elif struct['type'] == MinterSellCoinTx.TYPE:
            _class = MinterSellCoinTx
        elif struct['type'] == MinterSetCandidateOffTx.TYPE:
            _class = MinterSetCandidateOffTx
        elif struct['type'] == MinterSetCandidateOnTx.TYPE:
            _class = MinterSetCandidateOnTx
        elif struct['type'] == MinterUnbondTx.TYPE:
            _class = MinterUnbondTx
        elif struct['type'] == MinterEditCandidateTx.TYPE:
            _class = MinterEditCandidateTx
        elif struct['type'] == MinterMultiSendCoinTx.TYPE:
            _class = MinterMultiSendCoinTx
        else:
            raise Exception('Undefined tx type.')

        # Set tx data to minter dict
        struct.update({'data': _class._data_from_raw(data)})

        # Recover public key.
        # We should not change curent struct, so pass copy
        # of the struct to recover method.
        public_key = cls.recover_public_key(copy.copy(struct))
        struct.update({
            'from_mx':
            MinterWallet.get_address_from_public_key(public_key),
            'signed_tx':
            raw_tx
        })

        # Prepare **kwargs for creating _class instance.
        # Pass copy of the struct.
        kwargs = _class._structure_to_kwargs(copy.copy(struct))

        return _class(**kwargs)