def create_JWK(): """Create a private key and return it formatted as JWK """ # Generate the private key using Ethereum methods acc = Account.create( extra_entropy= "Alastria is the first Public-Permissioned Blockchain Network") # Get the public key publicKey = PublicKey.from_private(acc._key_obj) # The public key is 64 bytes composed of the x and y curve coordinates # x and y are each 32 bytes long # We convert x and y to hex, so the dictionary can be converted to JSON x = publicKey[:32] y = publicKey[32:] # Create the Json Web Key (JWK) representation, as specified by W3C DID Document format key_JWK = JWK(kty="EC", crv="secp256k1", d=base64url_encode(acc.privateKey), x=base64url_encode(x), y=base64url_encode(y)) return key_JWK
def create_account(account_name, password, overwrite=False): """Creates a wallet account. This is essentially a private/public key pair. This is NOT an identity yet in Red T. """ db = get_wallet_db() # If not overwrite and account already exists, just return that account if overwrite == False: acc = get_account(account_name, password) if acc is not None: return acc # Generate the private key using Ethereum methods acc = Account.create( extra_entropy= "Alastria is the first Public-Permissioned Blockchain Network") address = acc.address publicKey = PublicKey.from_private(acc._key_obj).to_hex() # Encrypt the private key and prepare for saving it key_encrypted = acc.encrypt(password) key_encrypted = json.dumps(key_encrypted) db.execute( 'REPLACE INTO testaccount (name, address, publickey, privatekey) VALUES (?, ?, ?, ?)', (account_name, address, publicKey, key_encrypted)) # Commit database db.commit() # Return account to caller return acc
def generate_private_key( entropy: str = "Alastria is the first Public-Permissioned Blockchain Network" ) -> AccountData: # Generate the private key using Ethereum methods eth_acc = Account.create(extra_entropy=entropy) # Get the address, public key and private key into the AccountData structure, # which is independent from eth_account.Account account = AccountData(address=eth_acc.address, publicKey=PublicKey.from_private( eth_acc._key_obj).to_hex(), privateKey=eth_acc.privateKey.hex()) return account
def key_JWK(account_name, password): """Gets the Private key in JWK format. --- Definitions --- {"name": "account_name", "prompt": "Account name", "default": "did:elsi:VATES-A87471264"} {"name": "password", "prompt": "Password to decrypt private key", "default": "Mypassword"} """ # The password is required, to be able to get the private key from the database if password is None: return None db = get_wallet_db() account = db.execute('SELECT * FROM testaccount WHERE name = ?', (account_name, )).fetchone() # Check if account_name was in the database if account is None: return None # Attempt to decrypt the private key with the password and derive the public key private_key = Account.decrypt(account["privatekey"], password) acc = Account.from_key(private_key) publicKey = PublicKey.from_private(acc._key_obj) # The public key is 64 bytes composed of the x and y curve coordinates # x and y are each 32 bytes long # We convert x and y to hex, so the dictionary can be converted to JSON x = publicKey[:32] y = publicKey[32:] # Create the Json Web Key (JWK) representation, as specified by W3C DID Document format key_JWK = JWK(kty="EC", crv="secp256k1", d=base64url_encode(acc.privateKey), x=base64url_encode(x), y=base64url_encode(y)) return key_JWK
def create_and_save_account(account_name, password): db = get_wallet_db() # Generate the private key using Ethereum methods acc = Account.create( extra_entropy= "Alastria is the first Public-Permissioned Blockchain Network") address = acc.address publicKey = PublicKey.from_private(acc._key_obj).to_hex() # Encrypt the private key and prepare for saving it key_encrypted = acc.encrypt(password) key_encrypted = json.dumps(key_encrypted) print(f"Saving {address} and its private key in database)") db.execute( 'REPLACE INTO testaccount (name, address, publickey, privatekey) VALUES (?, ?, ?, ?)', (account_name, address, publicKey, key_encrypted)) # Commit database, just in case db.commit() # Return account to caller return acc
def private_key_to_checksum_address(key): if key.startswith('0x'): key = key[2:] return PublicKey.from_private(PrivateKey( bytes.fromhex(key))).to_checksum_address()
def create_identity(did: str, domain_name: str, website: str, commercial_name: str, parent_node_account: str, password: str, overwrite: bool = False): # Check that node has at least two components s = domain_name.partition(".") if len(s[1]) == 0: return "Domain name has only one component", None this_node = s[0] parent_node = s[2] # The account name will be the unique domain name account_name = did # Create an external account and save the address and private key. # In reality, this should be done by the owner of the identity, and provide only the public key/address account = wallet.create_account(account_name, password, overwrite) publicKey = PublicKey.from_private(account._key_obj) # We assume that the manager account is Alastria, and the password is the one used at creation time Manager_account = wallet.get_account(parent_node_account, "ThePassword") if Manager_account is None: return "Parent node account does not exist", None # Initialize the DIDDocument didDoc = DIDDocument(DID=did, node_name=parent_node, label=this_node, address=account.address, publicKey=publicKey, manager_account=Manager_account) # Add the entity info service = { "id": did + "#info", "type": "EntityCommercialInfo", "serviceEndpoint": website, "name": commercial_name } didDoc.addService(service) # Add the Secure Messaging Server info service = { "id": did + "#sms", "type": "SecureMessagingService", "serviceEndpoint": "https://safeisland.hesusruiz.org/api" } didDoc.addService(service) # Store the info in the blockchain trust framework success, tx_receipt, tx_hash = didDoc.createIdentity(ens, resolver) if not success: return "Failed to create identity in blockchain", None success, tx_receipt, tx_hash = ens.setApprovalForAll( resolver.address(), True, account.key) if not success: return "Failed in setApprovalForAll", None return None, didDoc