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)
def recover_public_key(cls, tx): """ Recover public key from tx. Args: tx (dict): transaction dict Returns: public_key (string) """ # Remember signature data and remove it from tx signature_data = tx.pop('signature_data') # 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 = ECDSA.recover(_keccak, tuple(signature_data.values())) return MinterPrefix.PUBLIC_KEY + public_key