def create_claim(address_from,workspace_contract_from, address_to, workspace_contract_to,private_key_from, topicname, data, privacy, mode) : """ main reate claim function @data = str @topicname is credential id @privacy is public/private/secret scheme 2 """ # calculate claim_id derived from credential "id" (topicname) topicvalue = topicname2topicvalue(topicname) claim_id = mode.w3.solidityKeccak(['address', 'uint256'], [address_from, topicvalue]).hex() # encrypt data data_encrypted = encrypt_data(workspace_contract_to, {topicname : data}, privacy, mode, address_caller=address_from) if not data_encrypted : logging.warning('data encryption failed') return None # store on IPFS ipfs_hash = Talao_ipfs.ipfs_add(data_encrypted, mode) if not ipfs_hash : logging.error('ipfs failed') return None # fire transaction nonce = mode.w3.eth.getTransactionCount(address_from) contract = mode.w3.eth.contract(workspace_contract_to,abi=constante.workspace_ABI) txn = contract.functions.addClaim(topicvalue, 2, address_from, b'signature', privacy.encode(), ipfs_hash ).buildTransaction({'chainId': mode.CHAIN_ID,'gas': 4000000,'gasPrice': mode.w3.toWei(mode.GASPRICE, 'gwei'),'nonce': nonce,}) signed_txn = mode.w3.eth.account.signTransaction(txn,private_key_from) mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction) transaction_hash = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction)) if not mode.w3.eth.waitForTransactionReceipt(transaction_hash, timeout=2000, poll_latency=1)['status'] logging.error('transaction failed') return None return claim_id
def add_file(address_from, workspace_contract_from, address_to, workspace_contract_to, private_key_from, doctype, file_name, mydays, privacy, mode, synchronous): w3 = mode.w3 file_path = mode.uploads_path + file_name try: this_file = open(file_path, mode='rb') # b is important -> binary except IOError: logging.error('Error : IOEroor open file in File.py') return None, None, None this_data = this_file.read() data = { 'filename': file_name, 'content': b64encode(this_data).decode('utf_8') } # cryptage des données par le user if privacy != 'public': """ contract = w3.eth.contract(workspace_contract_to,abi = constante.workspace_ABI) mydata = contract.functions.identityInformation().call() """ if privacy == 'private': my_aes = privatekey.get_key(address_to, 'aes_key', mode) if privacy == 'secret': my_aes = privatekey(address_to, 'secret_key', mode) if my_aes is None: return None, None, None # coder les datas bytesdatajson = bytes(json.dumps(data), 'utf-8') # dict -> json(str) -> bytes header = b'header' cipher = AES.new( my_aes, AES.MODE_EAX ) #https://pycryptodome.readthedocs.io/en/latest/src/cipher/modern.html cipher.update(header) ciphertext, tag = cipher.encrypt_and_digest(bytesdatajson) json_k = ['nonce', 'header', 'ciphertext', 'tag'] json_v = [ b64encode(x).decode('utf-8') for x in [cipher.nonce, header, ciphertext, tag] ] data = dict(zip(json_k, json_v)) data['filename'] = file_name # calcul de la date if mydays == 0: expires = 0 else: myexpires = datetime.utcnow() + datetime.timedelta(days=mydays, seconds=0) expires = int(myexpires.timestamp()) #envoyer la transaction sur le contrat contract = w3.eth.contract(workspace_contract_to, abi=constante.workspace_ABI) nonce = w3.eth.getTransactionCount(address_from) # stocke sur ipfs les data attention on archive des bytes ipfs_hash = Talao_ipfs.ipfs_add(data, mode) # calcul du checksum en bytes des data, conversion du dictionnaire data en chaine str #_data = json.dumps(data) #checksum = hashlib.md5(bytes(_data, 'utf-8')).hexdigest() # la conversion inverse de bytes(data, 'utf-8') est XXX.decode('utf-8') checksum = b'' encrypted = False if privacy == 'public' else True # Transaction txn = contract.functions.createDocument(doctype, 2, expires, checksum, 1, bytes(ipfs_hash, 'utf-8'), encrypted).buildTransaction({ 'chainId': mode.CHAIN_ID, 'gas': 500000, 'gasPrice': w3.toWei( mode.GASPRICE, 'gwei'), 'nonce': nonce, }) signed_txn = w3.eth.account.signTransaction(txn, private_key_from) w3.eth.sendRawTransaction(signed_txn.rawTransaction) transaction_hash = w3.toHex(w3.keccak(signed_txn.rawTransaction)) if synchronous == True: receipt = w3.eth.waitForTransactionReceipt(transaction_hash, timeout=2000, poll_latency=1) if receipt['status'] == 0: return None, None, None # recuperer l iD du document sur le dernier event DocumentAdded contract = w3.eth.contract(workspace_contract_to, abi=constante.workspace_ABI) myfilter = contract.events.DocumentAdded.createFilter( fromBlock=mode.fromBlock, toBlock='latest') eventlist = myfilter.get_all_entries() document_id = eventlist[-1]['args']['id'] return document_id, ipfs_hash, transaction_hash
def _create(address_from, workspace_contract_from, address_to, workspace_contract_to, private_key_from, doctype, data, mydays, privacy, mode, synchronous, version, id, sequence): # align doctype with privacy if privacy == 'private' and doctype == 20000: doctype = 20001 if privacy == 'secret' and doctype == 20000: doctype = 20002 # @data = dict if isinstance(data, str): data = json.loads(data) logging.error('data must be a dict') #encrypt data with AES key (public, private or secret) Deprecated if version == 3: data = privatekey.encrypt_data(workspace_contract_to, data, privacy, mode) if not data: logging.error('encryption problem') return None, None, None #encrypt server side data as JWE with identity RSA key elif version == 4: jwe = JsonWebEncryption() protected = {'alg': 'RSA-OAEP', 'enc': 'A256GCM'} payload = json.dumps(data).encode() private_rsa_key = privatekey.get_key(address_to, 'rsa_key', mode) RSA_KEY = RSA.import_key(private_rsa_key) public_rsa_key = RSA_KEY.publickey().export_key('PEM').decode('utf-8') if not id: id = str(uuid.uuid1()) if not sequence: sequence = 0 data = { "id": id, "sequence": sequence, "jwe": jwe.serialize_compact(protected, payload, public_rsa_key).decode() } # encrypt data with AES key of identity" elif version == 5: jwe = JsonWebEncryption() protected = {'alg': 'A128KW', 'enc': 'A128CBC-HS256'} payload = json.dumps(data).encode() if privacy == 'public': secret = mode.aes_public_key.encode() else: secret = privatekey.get_key(address_to, privacy, mode) if not id: id = str(uuid.uuid1()) if not sequence: sequence = 0 data = { "id": id, "sequence": sequence, "jwe": jwe.serialize_compact(protected, payload, secret).decode() } # No data encryption. data have been probably encrypted as JWE client side elif version == 6: data = { "id": str(uuid.uuid1()), "sequence": 0, 'jwe': json.dumps(data) } else: logging.error('pb version') return None, None, None # Build transaction contract = mode.w3.eth.contract(workspace_contract_to, abi=constante.workspace_ABI) nonce = mode.w3.eth.getTransactionCount(address_from) # upkoad on ipfs ipfs_hash = Talao_ipfs.ipfs_add(data, mode) if not ipfs_hash: logging.error('IPFS connexion problem') return None, None, None # checksum (bytes) checksum = hashlib.md5(bytes(json.dumps(data), 'utf-8')).hexdigest() # Transaction expires = 0 txn = contract.functions.createDocument(doctype, version, expires, checksum, 1, bytes(ipfs_hash, 'utf-8'), True).buildTransaction({ 'chainId': mode.CHAIN_ID, 'gas': 1000000, 'gasPrice': mode.w3.toWei( mode.GASPRICE, 'gwei'), 'nonce': nonce, }) signed_txn = mode.w3.eth.account.signTransaction(txn, private_key_from) mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction) transaction_hash = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction)) if synchronous: if not mode.w3.eth.waitForTransactionReceipt( transaction_hash, timeout=2000, poll_latency=1)['status']: logging.error('transaction to create document failed') return None, None, None # Get document id on last event contract = mode.w3.eth.contract(workspace_contract_to, abi=constante.workspace_ABI) from_block = mode.w3.eth.blockNumber - 10 myfilter = contract.events.DocumentAdded.createFilter( fromBlock=from_block, toBlock='latest') eventlist = myfilter.get_all_entries() document_id = eventlist[-1]['args']['id'] return document_id, ipfs_hash, transaction_hash else: return None, None, None