def create_first_event(self, feed_id, content_identifier, content_parameter): if isinstance(feed_id, str): feed_id = bytes.fromhex(feed_id) elif not isinstance(feed_id, bytes): raise IllegalArgumentTypeException content = Event.Content(content_identifier, content_parameter) meta = Event.Meta(feed_id, 0, None, self._signing_algorithm, self._calculate_hash(content.get_as_cbor())) signature = self._calculate_signature(self._load_private_key(feed_id), meta.get_as_cbor()) return Event.Event(meta, signature, content).get_as_cbor()
def create_event(self, feed_id, last_sequence_number, hash_of_previous_meta, content_identifier, content_parameter): if isinstance(feed_id, str): feed_id = bytes.fromhex(feed_id) elif not isinstance(feed_id, bytes): raise IllegalArgumentTypeException private_key = self._load_private_key(feed_id) content = Event.Content(content_identifier, content_parameter) meta = Event.Meta(feed_id, last_sequence_number + 1, hash_of_previous_meta, self._signing_algorithm, self._calculate_hash(content.get_as_cbor())) signature = self._calculate_signature(private_key, meta.get_as_cbor()) return Event.Event(meta, signature, content).get_as_cbor()
def create_first_event(self, feed_id, app_name, master_feed_id): if not isinstance(master_feed_id, bytes): raise IllegalArgumentTypeException if isinstance(feed_id, str): feed_id = bytes.fromhex(feed_id) elif not isinstance(feed_id, bytes): raise IllegalArgumentTypeException content = Event.Content(app_name + "/MASTER", {'master_feed': master_feed_id}) meta = Event.Meta(feed_id, 0, None, self._signing_algorithm, self._calculate_hash(content.get_as_cbor())) signature = self._calculate_signature(self._load_private_key(feed_id), meta.get_as_cbor()) return Event.Event(meta, signature, content).get_as_cbor()
# First, we create a public key (feed id) and a private key (used to sign messages) # Therefore, we create a random bytes() object of length 32 (32 random bytes) private_key = secrets.token_bytes(32) print("The private key is:", private_key) signing_key = nacl.signing.SigningKey(private_key) # contains both # We can extract the public key as follows (already converting it to bytes() object) public_key_feed_id = signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder) print("The public key is:", str(public_key_feed_id).split("'")[1]) # conv. bytes to str of hex numbers for printing print() # If you need to restart your app, just save the private_key inside the database or a file and then reload it. # You can recreate the object as on line 26 using the old private_key, to sign events again # (The signing_key is an object from the pynacl library that you need to sign messages (i.e. the meta headers)) # Now, let's create some dummy content for a first event content = Event.Content('whateverapp/whateveraction', {'somekey': 'somevalue', 'someotherkey': 753465734265}) # In the meta data of a event, we have to specify the hash of the meta data of the previous event and of # the current content. Therefore we need a hashing algorithm. Currently we support only the 'sha256' algorithm # If you need another algorithm, please contact us # Let's calculate the hash of our content: hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest() # Since this is our first event, and there is no previous one, the hash of the previous meta data is just None hash_of_prev = None # Now we have everything to build our meta header (as specified on the repository): meta = Event.Meta(public_key_feed_id, 0, hash_of_prev, SIGN_INFO['ed25519'], (HASH_INFO['sha256'], hash_of_content)) # Now lets sign the meta header and therewith create a signature signature = signing_key.sign(meta.get_as_cbor())._signature # ignore the access of prot. member, works just fine!