コード例 #1
0
    def authorize_validator_signer_and_bls(
            self, signer: str, proof_of_signing_key_possession: 'Signature',
            bls_pub_key: str, bls_pop: str) -> str:
        """
        Authorizes an address to sign consensus messages on behalf of the contract's account. Also switch BLS key at the same time

        Parameters:
            signer: str
                The address of the signing key to authorize
            proof_of_signing_key_possession: Signature object
                The contract's account address signed by the signer address
            bls_pub_key: str
                The BLS public key that the validator is using for consensus, should pass proof
                of possession. 48 bytes
            bls_pop: str
                The BLS public key proof-of-possession, which consists of a signature on the
                account address. 96 bytes
        Returns:
            str
                Transaction hash
        """
        account = self.__wallet.active_account.address
        message = self.web3.soliditySha3(['address'], [account]).hex()
        prefixed_msg = hash_utils.hash_message_with_prefix(self.web3, message)
        prefixed_msg = encode_defunct(hexstr=prefixed_msg)
        pub_key = Account.recover_hash_to_pub(
            prefixed_msg, vrs=proof_of_signing_key_possession.vrs).to_hex()
        func_call = self._contract.functions.authorizeValidatorSignerWithKeys(
            signer, proof_of_signing_key_possession.v,
            self.web3.toBytes(proof_of_signing_key_possession.r),
            self.web3.toBytes(proof_of_signing_key_possession.s), pub_key,
            bls_pub_key, bls_pop)

        return self.__wallet.send_transaction(func_call)
コード例 #2
0
    def validate_attestation_code(self, identifier: str, account: str,
                                  issuer: str, code: str) -> bool:
        """
        Validates a given code by the issuer on-chain

        Parameters:
            identifier: str
                Attestation identifier (e.g. phone hash)
            account: str
                The address of the account which requested attestation
            issuer: str
                The address of the issuer of the attestation
            code: str
                The code send by the issuer
        """
        accounts_contract = self.create_and_get_contract_by_name('Accounts')
        attestation_signer = accounts_contract.get_attestation_signer(issuer)

        message = self.web3.soliditySha3(['bytes32', 'address'],
                                         [identifier, account]).hex()
        message = encode_defunct(hexstr=message)
        signer_address = Account.recoverHash(message, signature=code)

        if signer_address != attestation_signer:
            raise Exception("Signature was not signed by attestation signer")

        signature_bytes = HexBytes(code)
        signature_bytes_standard = to_standard_signature_bytes(signature_bytes)
        signature_obj = Signature(signature_bytes=signature_bytes_standard)
        v, r, s = signature_obj.vrs

        result = self._contract.functions.validateAttestationCode(
            identifier, account, v, r, s).call()

        return result != self.null_address
コード例 #3
0
    def find_matching_issuer(self, identifier: str, account: str, code: str,
                             issuers: list) -> str:
        """
        Given a list of issuers, finds the matching issuer for a given code

        Parameters:
            identifier: str
                Attestation identifier (e.g. phone hash)
            account: str
                Address of the account
            code: str
                The code received by the validator (signature)
            issuers: list
                The list of potential issuers
        """
        accounts_contract = self.create_and_get_contract_by_name('Accounts')
        message = self.web3.soliditySha3(['bytes32', 'address'],
                                         [identifier, account]).hex()
        message = encode_defunct(hexstr=message)
        signer_address = Account.recoverHash(message, signature=code)

        for issuer in issuers:
            attestation_signer = accounts_contract.get_attestation_signer(
                issuer)

            if attestation_signer == signer_address:
                return issuer
        return None
コード例 #4
0
    def complete(self, identifier: str, account: str, issuer: str,
                 code: str) -> str:
        """
        Completes an attestation with the corresponding code

        Parameters:
            identifier: str
                Attestation identifier (e.g. phone hash)
            account: str
                Address of the account
            issuer: str
                The issuer of the attestation
            code: str
                The code received by the validator (signature)
        Returns:
            Transaction hash
        """
        accounts_contract = self.create_and_get_contract_by_name('Accounts')
        attestation_signer = accounts_contract.get_attestation_signer(issuer)

        message = self.web3.soliditySha3(['bytes32', 'address'],
                                         [identifier, account]).hex()
        message = encode_defunct(hexstr=message)
        signer_address = Account.recoverHash(message, signature=code)

        if signer_address != attestation_signer:
            raise Exception("Signature was not signed by attestation signer")

        signature_bytes = HexBytes(code)
        signature_bytes_standard = to_standard_signature_bytes(signature_bytes)
        signature_obj = Signature(signature_bytes=signature_bytes_standard)
        v, r, s = signature_obj.vrs
        func_call = self._contract.functions.complete(identifier, v, r, s)

        return self.__wallet.send_transaction(func_call)
コード例 #5
0
ファイル: accounts_tests.py プロジェクト: idekel/celo-sdk-py
    def test_pub_key_recovering(self):
        accounts = self.kit.w3.eth.accounts

        account = accounts[0]
        signer = accounts[1]

        self.kit.w3.eth.defaultAccount = signer
        self.kit.wallet_change_account = signer

        message = self.kit.w3.soliditySha3(['address'], [signer]).hex()
        message = encode_defunct(hexstr=message)
        signature = self.kit.wallet.active_account.sign_message(message)

        self.assertEqual(
            Account.recover_hash_to_pub(message, vrs=signature.vrs).to_hex(),
            test_data.recovered_pub_key)
コード例 #6
0
    def authorize_validator_signer(
            self, signer: str,
            proof_of_signing_key_possession: 'Signature') -> str:
        """
        Authorizes an address to sign validation messages on behalf of the account

        Parameters:
            signer: str
                The address of the validator signing key to authorize
            proof_of_signing_key_possession: Signature object
                The account address signed by the signer address
        Returns:
            str
                Transaction hash
        """
        validators_contract = self.create_and_get_contract_by_name(
            'Validators')
        account = self.__wallet.active_account.address

        if validators_contract.is_validator(account):
            message = self.web3.soliditySha3(['address'], [account]).hex()
            prefixed_msg = hash_utils.hash_message_with_prefix(
                self.web3, message)
            prefixed_msg = encode_defunct(hexstr=prefixed_msg)
            pub_key = Account.recover_hash_to_pub(
                prefixed_msg,
                vrs=proof_of_signing_key_possession.vrs).to_hex()
            func_call = self._contract.functions.authorizeValidatorSignerWithPublicKey(
                signer, proof_of_signing_key_possession.v,
                self.web3.toBytes(proof_of_signing_key_possession.r),
                self.web3.toBytes(proof_of_signing_key_possession.s), pub_key)

            return self.__wallet.send_transaction(func_call)
        else:
            func_call = self._contract.functions.authorizeValidatorSigner(
                signer, proof_of_signing_key_possession.v,
                self.web3.toBytes(proof_of_signing_key_possession.r),
                self.web3.toBytes(proof_of_signing_key_possession.s))

            return self.__wallet.send_transaction(func_call)