def unpack(self, data, version=2): """Unpack data into transaction object Args: data (bytes): packed binary data version (int): version of the data format Returns: bool: True if successful """ ptr = 0 self.version = version data_size = len(data) try: ptr, self.asset_group_id = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["asset_group_id"] = len(self.asset_group_id) ptr, pt_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.pointers = list() for i in range(pt_num): ptr, size = bbclib_binary.get_n_byte_int(ptr, 2, data) ptr, ptdata = bbclib_binary.get_n_bytes(ptr, size, data) if ptr >= data_size: return False pt = BBcPointer() if not pt.unpack(ptdata): return False self.pointers.append(pt) self.asset = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset = BBcAsset() ptr, astdata = bbclib_binary.get_n_bytes(ptr, astsize, data) if not self.asset.unpack(astdata): return False if version >= 2: self.asset_raw = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset_raw = BBcAssetRaw() ptr, astdata = bbclib_binary.get_n_bytes( ptr, astsize, data) if not self.asset_raw.unpack(astdata): return False self.asset_hash = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset_hash = BBcAssetHash() ptr, astdata = bbclib_binary.get_n_bytes( ptr, astsize, data) if not self.asset_hash.unpack(astdata): return False except: return False return True
def create_asset(self, user_id, asset_body=None, asset_file=None): """Create BBcAsset object and set it to self.asset in the BBcEvent object Args: user_id (byte): user_id to set in BBcAsset object asset_body (*): asset_body to set in BBcAsset object asset_file (byte): asset file to set in BBcAsset object Returns: BBcEvent: this object """ self.asset = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body, id_length=self.idlen_conf, version=self.version) return self
def unpack(self, data): """Unpack into this object Args: data (bytes): packed binary data Returns: bool: True if successful """ ptr = 0 id_length_asgid = 32 id_length_userid = 32 data_size = len(data) try: ptr, self.asset_group_id = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["asset_group_id"] = len(self.asset_group_id) ptr, ref_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.reference_indices = [] for i in range(ref_num): ptr, idx = bbclib_binary.get_n_byte_int(ptr, 2, data) self.reference_indices.append(idx) if ptr >= data_size: return False ptr, appr_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.mandatory_approvers = [] for i in range(appr_num): ptr, appr = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["user_id"] = len(appr) self.mandatory_approvers.append(appr) if ptr >= data_size: return False ptr, self.option_approver_num_numerator = bbclib_binary.get_n_byte_int(ptr, 2, data) ptr, self.option_approver_num_denominator = bbclib_binary.get_n_byte_int(ptr, 2, data) self.option_approvers = [] for i in range(self.option_approver_num_denominator): ptr, appr = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["user_id"] = len(appr) self.option_approvers.append(appr) if ptr >= data_size: return False ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) ptr, astdata = bbclib_binary.get_n_bytes(ptr, astsize, data) self.asset = BBcAsset() self.asset.unpack(astdata) except: return False return True
def add_event_asset(transaction, event_idx, asset_group_id, user_id, asset_body=None, asset_file=None): """Utility to add BBcEvent object with BBcAsset in the transaction""" ast = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body) transaction.events[event_idx].add(asset_group_id=asset_group_id, asset=ast)
def add_relation_asset(transaction, relation_idx, asset_group_id, user_id, asset_body=None, asset_file=None): """Utility to add BBcRelation object with BBcAsset in the transaction Args: transaction (BBcTransaction): transaction object to manipulate relation_idx (int): the number of BBcRelation object to include in the transaction asset_group_id (bytes): asset_group_id of the asset in the object user_id (bytes): user_id of the owner of the asset asset_body (str|bytes|dict): asset data asset_file (bytes): file data (binary) for asset """ ast = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body) transaction.relations[relation_idx].add(asset_group_id=asset_group_id, asset=ast)
def make_relation_with_asset(asset_group_id, user_id, asset_body=None, asset_file=None): """Utility to make BBcRelation object with BBcAsset Args: asset_group_id (bytes): asset_group_id of the asset in the object user_id (bytes): user_id of the owner of the asset asset_body (str|bytes|dict): asset data asset_file (bytes): file data (binary) for asset Returns: BBcRelation: created BBcRelation object """ relation = BBcRelation() ast = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body) relation.add(asset_group_id=asset_group_id, asset=ast) return relation
def make_transaction(event_num=0, relation_num=0, witness=False, version=2): """Utility to make transaction object Args: event_num (int): the number of BBcEvent object to include in the transaction relation_num (int): the number of BBcRelation object to include in the transaction witness (bool): If true, BBcWitness object is included in the transaction version (int): version of the transaction format Returns: BBcTransaction: """ transaction = BBcTransaction(version=version) if event_num > 0: for i in range(event_num): evt = BBcEvent() ast = BBcAsset() evt.add(asset=ast) transaction.add(event=evt) if relation_num > 0: for i in range(relation_num): transaction.add(relation=BBcRelation(version=version)) if witness: transaction.add(witness=BBcWitness()) return transaction
class BBcEvent: """Event part in a transaction""" def __init__(self, asset_group_id=None, id_length=None, version=2): self.version = version self.idlen_conf = id_length_conf.copy() if id_length is not None: if isinstance(id_length, int): for k in self.idlen_conf.keys(): self.idlen_conf[k] = id_length elif isinstance(id_length, dict): for k in id_length.keys(): self.idlen_conf[k] = id_length[k] if asset_group_id is not None: self.asset_group_id = asset_group_id[:self.idlen_conf["asset_group_id"]] else: self.asset_group_id = None self.reference_indices = [] self.mandatory_approvers = [] self.option_approver_num_numerator = 0 self.option_approver_num_denominator = 0 self.option_approvers = [] self.asset = None def __str__(self): ret = " asset_group_id: %s\n" % bbclib_binary.str_binary(self.asset_group_id) ret += " reference_indices: %s\n" % self.reference_indices ret += " mandatory_approvers:\n" if len(self.mandatory_approvers) > 0: for user in self.mandatory_approvers: ret += " - %s\n" % bbclib_binary.str_binary(user) else: ret += " - None\n" ret += " option_approvers:\n" if len(self.option_approvers) > 0: for user in self.option_approvers: ret += " - %s\n" % bbclib_binary.str_binary(user) else: ret += " - None\n" ret += " option_approver_num_numerator: %d\n" % self.option_approver_num_numerator ret += " option_approver_num_denominator: %d\n" % self.option_approver_num_denominator ret += str(self.asset) return ret def add(self, asset_group_id=None, reference_index=None, mandatory_approver=None, option_approver_num_numerator=0, option_approver_num_denominator=0, option_approver=None, asset=None): """Add parts""" if asset_group_id is not None: self.asset_group_id = asset_group_id[:self.idlen_conf["asset_group_id"]] if reference_index is not None: if isinstance(reference_index, list): self.reference_indices.extend(reference_index) else: self.reference_indices.append(reference_index) if mandatory_approver is not None: self.mandatory_approvers.append(mandatory_approver[:self.idlen_conf["user_id"]]) if option_approver_num_numerator > 0: self.option_approver_num_numerator = option_approver_num_numerator if option_approver_num_denominator > 0: self.option_approver_num_denominator = option_approver_num_denominator if option_approver is not None: self.option_approvers.append(option_approver[:self.idlen_conf["user_id"]]) if asset is not None: self.asset = asset return True def set_asset_group(self, asset_group_id): """Set asset_group_id in the BBcEvent object Args: asset_group_id (byte): asset_group_id Returns: BBcEvent: this object """ if asset_group_id is not None: self.asset_group_id = asset_group_id[:self.idlen_conf["asset_group_id"]] return self def add_reference_index(self, index): """Add reference_index value in the reference_indices array of BBcEvent object Args: index (int): index of BBcReference object in transaction to refer to Returns: BBcEvent: this object """ if index > -1: self.reference_indices.append(index) return self def create_asset(self, user_id, asset_body=None, asset_file=None): """Create BBcAsset object and set it to self.asset in the BBcEvent object Args: user_id (byte): user_id to set in BBcAsset object asset_body (*): asset_body to set in BBcAsset object asset_file (byte): asset file to set in BBcAsset object Returns: BBcEvent: this object """ self.asset = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body, id_length=self.idlen_conf, version=self.version) return self def add_mandatory_approver(self, approver): """Add user in the mandatory approver list Args: approver (byte): user_id of the approver Returns: BBcEvent: this object """ self.mandatory_approvers.append(approver[:self.idlen_conf["user_id"]]) return self def add_option_approver(self, approver): """Add user in the option approver list Args: approver (byte): user_id of the approver Returns: BBcEvent: this object """ self.option_approvers.append(approver[:self.idlen_conf["user_id"]]) return self def set_option_parameter(self, numerator, denominator): """Set option parameters in the BBcEvent object Args: numerator (int): necessary number of approvals from the option approver list denominator (int): number of approver candidates in the option approver list Returns: BBcEvent: this object """ if numerator > 0: self.option_approver_num_numerator = numerator if denominator > 0: self.option_approver_num_denominator = denominator return self def pack(self): """Pack this object Returns: bytes: packed binary data """ if self.asset_group_id is None: raise Exception("need asset_group_id in BBcEvent") dat = bytearray(bbclib_binary.to_bigint(self.asset_group_id, size=self.idlen_conf["asset_group_id"])) dat.extend(bbclib_binary.to_2byte(len(self.reference_indices))) for i in range(len(self.reference_indices)): dat.extend(bbclib_binary.to_2byte(self.reference_indices[i])) dat.extend(bbclib_binary.to_2byte(len(self.mandatory_approvers))) for i in range(len(self.mandatory_approvers)): dat.extend(bbclib_binary.to_bigint(self.mandatory_approvers[i], size=self.idlen_conf["user_id"])) dat.extend(bbclib_binary.to_2byte(self.option_approver_num_numerator)) dat.extend(bbclib_binary.to_2byte(self.option_approver_num_denominator)) for i in range(self.option_approver_num_denominator): dat.extend(bbclib_binary.to_bigint(self.option_approvers[i], size=self.idlen_conf["user_id"])) ast = self.asset.pack() dat.extend(bbclib_binary.to_4byte(len(ast))) dat.extend(ast) return bytes(dat) def unpack(self, data): """Unpack into this object Args: data (bytes): packed binary data Returns: bool: True if successful """ ptr = 0 id_length_asgid = 32 id_length_userid = 32 data_size = len(data) try: ptr, self.asset_group_id = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["asset_group_id"] = len(self.asset_group_id) ptr, ref_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.reference_indices = [] for i in range(ref_num): ptr, idx = bbclib_binary.get_n_byte_int(ptr, 2, data) self.reference_indices.append(idx) if ptr >= data_size: return False ptr, appr_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.mandatory_approvers = [] for i in range(appr_num): ptr, appr = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["user_id"] = len(appr) self.mandatory_approvers.append(appr) if ptr >= data_size: return False ptr, self.option_approver_num_numerator = bbclib_binary.get_n_byte_int(ptr, 2, data) ptr, self.option_approver_num_denominator = bbclib_binary.get_n_byte_int(ptr, 2, data) self.option_approvers = [] for i in range(self.option_approver_num_denominator): ptr, appr = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["user_id"] = len(appr) self.option_approvers.append(appr) if ptr >= data_size: return False ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) ptr, astdata = bbclib_binary.get_n_bytes(ptr, astsize, data) self.asset = BBcAsset() self.asset.unpack(astdata) except: return False return True
class BBcRelation: """Relation part in a transaction""" def __init__(self, asset_group_id=None, id_length=None, version=1): self.version = version self.idlen_conf = id_length_conf.copy() if id_length is not None: if isinstance(id_length, int): for k in self.idlen_conf.keys(): self.idlen_conf[k] = id_length elif isinstance(id_length, dict): for k in id_length.keys(): self.idlen_conf[k] = id_length[k] if asset_group_id is not None: self.asset_group_id = asset_group_id[:self. idlen_conf["asset_group_id"]] else: self.asset_group_id = None self.pointers = list() self.asset = None self.asset_raw = None self.asset_hash = None def __str__(self): ret = " asset_group_id: %s\n" % bbclib_binary.str_binary( self.asset_group_id) if len(self.pointers) > 0: ret += " Pointers[]: %d\n" % len(self.pointers) for i, pt in enumerate(self.pointers): ret += " [%d]\n" % i ret += str(pt) if self.asset is not None: ret += str(self.asset) if self.asset_raw is not None: ret += str(self.asset_raw) if self.asset_hash is not None: ret += str(self.asset_hash) return ret def add(self, asset_group_id=None, asset=None, asset_raw=None, asset_hash=None, pointer=None): """Add parts""" if asset_group_id is not None: self.asset_group_id = asset_group_id[:self. idlen_conf["asset_group_id"]] if pointer is not None: if isinstance(pointer, list): self.pointers.extend(pointer) else: self.pointers.append(pointer) if asset is not None: self.asset = asset if asset_raw is not None: self.asset_raw = asset_raw if asset_hash is not None: self.asset_hash = asset_hash return True def set_asset_group(self, asset_group_id): """Set asset_group_id in the BBcRelation object Args: asset_group_id (byte): asset_group_id Returns: BBcRelation: this object """ if asset_group_id is not None: self.asset_group_id = asset_group_id[:self. idlen_conf["asset_group_id"]] return self def create_asset(self, user_id, asset_body=None, asset_file=None): """Create BBcAsset object and set it to self.asset in the BBcRelation object Args: user_id (byte): user_id to set in BBcAsset object asset_body (*): asset_body to set in BBcAsset object asset_file (byte): asset file to set in BBcAsset object Returns: BBcRelation: this object """ self.asset = BBcAsset(user_id=user_id, asset_file=asset_file, asset_body=asset_body, id_length=self.idlen_conf, version=self.version) return self def create_asset_raw(self, asset_id, asset_body=None): """Create BBcAssetRaw object and set it to self.asset in the BBcRelation object Args: asset_id (byte): asset_id to set in BBcAssetRaw object asset_body (*): asset_body to set in BBcAssetRaw object Returns: BBcRelation: this object """ self.asset_raw = BBcAssetRaw(asset_id=asset_id, asset_body=asset_body, id_length=self.idlen_conf, version=self.version) return self def create_asset_hash(self, asset_ids): """Create BBcAssetHash object and set it to self.asset in the BBcRelation object Args: asset_ids (list(byte)): list of asset_ids to set in BBcAssetRaw object Returns: BBcRelation: this object """ self.asset_hash = BBcAssetHash(asset_ids=asset_ids, id_length=self.idlen_conf, version=self.version) return self def create_pointer(self, transaction_id=None, asset_id=None): """Create BBcPointer object and set it to self.asset in the BBcRelation object Args: transaction_id (byte): transaction_id asset_id (byte): asset_id Returns: BBcRelation: this object """ pointer = BBcPointer(transaction_id=transaction_id, asset_id=asset_id, id_length=self.idlen_conf, version=self.version) self.pointers.append(pointer) return self def pack(self): """Pack this object Returns: bytes: packed binary data """ if self.asset_group_id is None: raise Exception("need asset_group_id in BBcRelation") dat = bytearray( bbclib_binary.to_bigint(self.asset_group_id, size=self.idlen_conf["asset_group_id"])) dat.extend(bbclib_binary.to_2byte(len(self.pointers))) for i in range(len(self.pointers)): pt = self.pointers[i].pack() dat.extend(bbclib_binary.to_2byte(len(pt))) dat.extend(pt) if self.asset is not None: ast = self.asset.pack() dat.extend(bbclib_binary.to_4byte(len(ast))) dat.extend(ast) else: dat.extend(bbclib_binary.to_4byte(0)) if self.version >= 2: if self.asset_raw is not None: ast = self.asset_raw.pack() dat.extend(bbclib_binary.to_4byte(len(ast))) dat.extend(ast) else: dat.extend(bbclib_binary.to_4byte(0)) if self.asset_hash is not None: ast = self.asset_hash.pack() dat.extend(bbclib_binary.to_4byte(len(ast))) dat.extend(ast) else: dat.extend(bbclib_binary.to_4byte(0)) return bytes(dat) def unpack(self, data, version=2): """Unpack data into transaction object Args: data (bytes): packed binary data version (int): version of the data format Returns: bool: True if successful """ ptr = 0 self.version = version data_size = len(data) try: ptr, self.asset_group_id = bbclib_binary.get_bigint(ptr, data) self.idlen_conf["asset_group_id"] = len(self.asset_group_id) ptr, pt_num = bbclib_binary.get_n_byte_int(ptr, 2, data) self.pointers = list() for i in range(pt_num): ptr, size = bbclib_binary.get_n_byte_int(ptr, 2, data) ptr, ptdata = bbclib_binary.get_n_bytes(ptr, size, data) if ptr >= data_size: return False pt = BBcPointer() if not pt.unpack(ptdata): return False self.pointers.append(pt) self.asset = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset = BBcAsset() ptr, astdata = bbclib_binary.get_n_bytes(ptr, astsize, data) if not self.asset.unpack(astdata): return False if version >= 2: self.asset_raw = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset_raw = BBcAssetRaw() ptr, astdata = bbclib_binary.get_n_bytes( ptr, astsize, data) if not self.asset_raw.unpack(astdata): return False self.asset_hash = None ptr, astsize = bbclib_binary.get_n_byte_int(ptr, 4, data) if astsize > 0: self.asset_hash = BBcAssetHash() ptr, astdata = bbclib_binary.get_n_bytes( ptr, astsize, data) if not self.asset_hash.unpack(astdata): return False except: return False return True