Example #1
0
 def from_base64(self, b64_claim: str, is_big_endian: bool = True):
     try:
         b64_head, b64_payload, b64_signature, b64_blk_proof = b64_claim.split('.')
     except ValueError:
         raise SDKException(ErrorCode.invalid_b64_claim_data)
     self.__head = Header.from_base64(b64_head)
     self.__payload = Payload.from_base64(b64_payload)
     self.__signature = base64.b64decode(b64_signature)
     self.__blk_proof = BlockchainProof(self.__sdk).from_base64(b64_blk_proof, is_big_endian)
Example #2
0
 def test_proof(self):
     proof_node = [{
         'Direction':
         'Left',
         'TargetHash':
         '328c513fcfcd715e8ec537ab7d9d3a40a4a0cab6147afb2342b5a45226eaf134'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         '3035c97472f112e92ab0f72d0d2d7d5ee36ae4d46aae0c08874cef90f1f32f0c'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         '94237b775cb687b15413ada5166fb723ea7f0767fa4ecbf899af5db6932444e5'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         'c8c494ae321875dd94d9622ebb38f013c477edece714f7d68d605b42b0abe09e'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         '610f87fbcbdd3b4c316946086d9177f85db5d40b2335f797ab8b869fe0248a90'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         '92f41a0485e2591ccd11efd41b9a931fab56349bebe340e9fd81a0281bb1ef73'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         'bcbc040368a66ec9d1dfcf489eb00aaa424e286ac84c53979c325531e9d0ea80'
     }, {
         'Direction':
         'Left',
         'TargetHash':
         '84bb65ae876c5cc67c3c57fad08382ba18d0ddd6758e6b37794fd461c173cea4'
     }]
     tx_hash = 'c6e2b089a835821916bc612a046e3eaada3c6abc0c274062303384d0a8c71b56'
     hex_contract_address = '36bb5c053b6b839c8f6b923fe852f91239b9fccc'
     merkle_root = 'ed7f4d2e91925917d4242b3a59a3f47830d77bca383ffc78e078a1f93ddb62c4'
     blk_height = 705043
     proof = BlockchainProof(tx_hash, hex_contract_address, blk_height,
                             merkle_root, proof_node)
     self.assertTrue(isinstance(proof, BlockchainProof))
     self.assertTrue(proof.validate_blk_proof())
     dict_proof = dict(proof)
     self.assertTrue(isinstance(dict_proof, dict))
     proof.merkle_root = 'ed7f4d2e91925917d4242b3a59a3f47830d77bca383ffc78e078a1f93ddb62c5'
     self.assertFalse(proof.validate_blk_proof())
Example #3
0
    def generate_blk_proof(self,
                           iss_acct: Account,
                           payer: Account,
                           gas_limit: int,
                           gas_price: int,
                           hex_contract_address: str = ''):
        if not isinstance(hex_contract_address, str):
            raise SDKException(ErrorCode.require_str_params)
        if len(hex_contract_address) != 0:
            self.__sdk.neo_vm.claim_record(
            ).hex_contract_address = hex_contract_address

        tx_hash = self.__sdk.neo_vm.claim_record().commit(
            self.payload.jti, iss_acct, self.payload.sub, payer, gas_limit,
            gas_price)
        sleep(12)
        hex_contract_address = self.__sdk.neo_vm.claim_record(
        ).hex_contract_address
        merkle_proof = self.__sdk.get_network().get_merkle_proof(tx_hash)
        current_block_height = merkle_proof['CurBlockHeight']
        target_hash = merkle_proof['TransactionsRoot']
        merkle_root = merkle_proof['CurBlockRoot']
        tx_block_height = self.__sdk.get_network().get_block_height_by_tx_hash(
            tx_hash)
        target_hash_list = merkle_proof['TargetHashes']
        proof_node = MerkleVerifier.get_proof(tx_block_height,
                                              target_hash_list,
                                              current_block_height)
        result = MerkleVerifier.validate_proof(proof_node, target_hash,
                                               merkle_root)
        if not result:
            raise SDKException(ErrorCode.other_error('Invalid merkle proof'))
        self.__blk_proof = BlockchainProof(tx_hash, hex_contract_address,
                                           current_block_height, merkle_root,
                                           proof_node)
        return self.__blk_proof
Example #4
0
 def __init__(self, sdk):
     self.__sdk = sdk
     self.__head = None
     self.__payload = None
     self.__signature = b''
     self.__blk_proof = BlockchainProof(sdk)
Example #5
0
class Claim(object):
    def __init__(self, sdk):
        self.__sdk = sdk
        self.__head = None
        self.__payload = None
        self.__signature = b''
        self.__blk_proof = BlockchainProof(sdk)

    def __iter__(self):
        data = dict(Header=dict(self.__head), Payload=dict(self.__payload), Signature=self.to_str_signature(),
                    Proof=dict(self.__blk_proof))
        for key, value in data.items():
            yield (key, value)

    @property
    def claim_id(self):
        if not isinstance(self.__payload, Payload):
            return ''
        return self.__payload.jti

    @property
    def head(self):
        return self.__head

    @head.setter
    def head(self, kid: str):
        if not isinstance(kid, str):
            raise SDKException(ErrorCode.require_str_params)
        self.__head = Header(kid)

    @property
    def payload(self):
        return self.__payload

    @property
    def signature(self):
        return self.__signature

    @property
    def blk_proof(self):
        return self.__blk_proof

    @blk_proof.setter
    def blk_proof(self, blk_proof: dict):
        self.__blk_proof.proof = blk_proof

    def set_claim(self, kid: str, iss_ont_id: str, sub_ont_id: str, exp: int, context: str, clm: dict, clm_rev: dict,
                  jti: str = '', ver: str = 'v1.0'):
        if not isinstance(jti, str):
            raise SDKException(ErrorCode.require_str_params)
        if jti == '':
            jti = Digest.sha256(uuid.uuid1().bytes, is_hex=True)
        self.__head = Header(kid)
        self.__payload = Payload(ver, iss_ont_id, sub_ont_id, int(time()), exp, context, clm, clm_rev, jti)

    def generate_signature(self, iss: Account, verify_kid: bool = True):
        if not isinstance(self.__head, Header) or not isinstance(self.__payload, Payload):
            raise SDKException(ErrorCode.other_error('Please set claim parameters first.'))
        if verify_kid:
            key_index = int(self.__head.kid.split('-')[1])
            result = self.__sdk.native_vm.ont_id().verify_signature(iss.get_ont_id(), key_index, iss)
            if not result:
                raise SDKException(ErrorCode.other_error('Issuer account error.'))
        b64_head = self.__head.to_base64()
        b64_payload = self.__payload.to_base64()
        msg = f'{b64_head}.{b64_payload}'.encode('utf-8')
        self.__signature = iss.generate_signature(msg)
        return self.__signature

    def validate_signature(self, b64_claim: str):
        try:
            b64_head, b64_payload, b64_signature, _ = b64_claim.split('.')
        except ValueError:
            raise SDKException(ErrorCode.invalid_b64_claim_data)
        head = Header.from_base64(b64_head)
        payload = Payload.from_base64(b64_payload)
        signature = base64.b64decode(b64_signature)
        kid = head.kid
        iss_ont_id = payload.iss
        msg = f'{b64_head}.{b64_payload}'.encode('ascii')
        pk = ''
        pub_keys = self.__sdk.native_vm.ont_id().get_public_keys(iss_ont_id)
        if len(pub_keys) == 0:
            raise SDKException(ErrorCode.invalid_claim_head_params)
        for pk_info in pub_keys:
            if kid == pk_info.get('PubKeyId', ''):
                pk = pk_info.get('Value', '')
                break
        if pk == '':
            raise SDKException(ErrorCode.invalid_b64_claim_data)
        handler = SignatureHandler(head.alg)
        result = handler.verify_signature(pk, msg, signature)
        return result

    def to_bytes_signature(self):
        return self.__signature

    def to_str_signature(self):
        return self.__signature.decode('latin-1')

    def to_b64_signature(self):
        return base64.b64encode(self.to_bytes_signature()).decode('ascii')

    @staticmethod
    def from_base64_signature(b64_signature: str):
        return bytes.hex(base64.b64decode(b64_signature))

    def generate_blk_proof(self, iss_acct: Account, payer: Account, gas_limit: int, gas_price: int,
                           is_big_endian: bool = True, hex_contract_address: str = ''):
        if not isinstance(hex_contract_address, str):
            raise SDKException(ErrorCode.require_str_params)
        if len(hex_contract_address) != 0 and len(hex_contract_address) == 40:
            self.__sdk.neo_vm.claim_record().hex_contract_address = hex_contract_address
        tx_hash = self.__sdk.neo_vm.claim_record().commit(self.payload.jti, iss_acct, self.payload.sub, payer,
                                                          gas_limit, gas_price)
        sleep(12)
        hex_contract_address = self.__sdk.neo_vm.claim_record().hex_contract_address
        merkle_proof = self.__sdk.get_network().get_merkle_proof(tx_hash)
        tx_block_height = merkle_proof['BlockHeight']
        current_block_height = merkle_proof['CurBlockHeight']
        target_hash = merkle_proof['TransactionsRoot']
        merkle_root = merkle_proof['CurBlockRoot']
        target_hash_list = merkle_proof['TargetHashes']
        proof_node = MerkleVerifier.get_proof(tx_block_height, target_hash_list, current_block_height)
        result = MerkleVerifier.validate_proof(proof_node, target_hash, merkle_root, is_big_endian)
        if not result:
            raise SDKException(ErrorCode.other_error('Invalid merkle proof'))
        self.__blk_proof.set_proof(tx_hash, hex_contract_address, tx_block_height, merkle_root, proof_node)
        return self.__blk_proof

    def validate_blk_proof(self, is_big_endian: bool = True):
        return self.__blk_proof.validate_blk_proof(is_big_endian)

    def to_base64(self):
        b64_head = self.__head.to_base64()
        b64_payload = self.__payload.to_base64()
        b64_signature = self.to_b64_signature()
        b64_blockchain_proof = self.__blk_proof.to_base64()
        return f'{b64_head}.{b64_payload}.{b64_signature}.{b64_blockchain_proof}'

    def from_base64(self, b64_claim: str, is_big_endian: bool = True):
        try:
            b64_head, b64_payload, b64_signature, b64_blk_proof = b64_claim.split('.')
        except ValueError:
            raise SDKException(ErrorCode.invalid_b64_claim_data)
        self.__head = Header.from_base64(b64_head)
        self.__payload = Payload.from_base64(b64_payload)
        self.__signature = base64.b64decode(b64_signature)
        self.__blk_proof = BlockchainProof(self.__sdk).from_base64(b64_blk_proof, is_big_endian)
Example #6
0
 def blockchain_proof(self):
     return BlockchainProof(self.__sdk)
Example #7
0
 def blockchain_proof(self):
     if self.__blockchain_proof is None:
         self.__blockchain_proof = BlockchainProof(self.__sdk)
     return self.__blockchain_proof