def binary(self): """ Returns a binary encoded version of the CoinOutput """ result = bytearray() result.extend(binary.encode(self._value, type_='currency')) result.extend(binary.encode(self._condition)) return result
def binary(self): """ Returns a binary encoded version of the unlockhashcondition """ result = bytearray() result.extend(self._type) # add the size of the unlockhash result.extend(binary.encode(self._unlockhash_size)) result.extend(binary.encode(self._unlockhash)) return result
def data(self): """ Retruns the binary format of the data on the condition """ result = bytearray() result.extend(binary.encode(self._min_nr_sig)) result.extend(binary.encode(len(self._unlockhashes))) for unlockhash in self._unlockhashes: result.extend(binary.encode(UnlockHash.from_string(unlockhash))) return result
def binary(self): """ Returns a binary encoded versoin of the LockTimeCondition """ result = bytearray() result.extend(self._type) # encode the length of all properties: len(locktime) = 8 + len(binary(condition)) - 8 # the -8 in the above statement is due to the fact that we do not need to include the length of the interal condition's data result.extend(binary.encode(len(self._condition.binary))) result.extend(binary.encode(self._locktime)) result.extend(self._condition.type) result.extend(binary.encode(self._condition.data)) return result
def binary(self): """ Returns a binary encoded versoin of the AtomicSwapCondition """ result = bytearray() result.extend(self._type) # 106 size of the atomicswap condition in binary form result.extend(binary.encode(106)) result.extend(binary.encode(UnlockHash.from_string(self._sender))) result.extend(binary.encode(UnlockHash.from_string(self._reciever))) result.extend(binary.encode(self._hashed_secret, type_='hex')) result.extend(binary.encode(self._locktime)) return result
def binary(self): """ Returns a binary encoded versoin of the MultiSignatureCondition """ result = bytearray() result.extend(self._type) condition_binary = bytearray() condition_binary.extend(binary.encode(self._min_nr_sig)) condition_binary.extend(binary.encode(len(self._unlockhashes))) for unlockhash in self._unlockhashes: condition_binary.extend( binary.encode(UnlockHash.from_string(unlockhash))) result.extend(binary.encode(condition_binary, type_='slice')) return result
def _generate_multisig_address(self, ulhs): """ Generates a multisig address """ mtree = Tree(hash_func=utils.hash) mtree.push(binary.encode(self._nr_of_cosigners)) # make sure that regardless of the order of the unlockhashes, we sort them so that we always # produce the same multisig address for ulh in sorted(ulhs): mtree.push(binary.encode(UnlockHash.from_string(ulh))) mtree.push(binary.encode(self._required_sig)) address_hash = mtree.root() ulh = UnlockHash(unlock_type=UNLOCK_TYPE_MULTISIG, hash=address_hash) return str(ulh)
def test_encode_binary(): """ Test encode binary values """ value = b'hello world' output = binary.encode(value) assert output == value, "Failed to encode binary value to binary"
def test_encode_hex(): """ Test encode hex values """ value = b'hello world' output = binary.encode(value.hex(), type_='hex') assert output == value, "Failed to encode hex value to binary"
def test_encode_bool(): """ Test encode bool values """ value = True output = binary.encode(value) expected_output = bytearray(b'\x01') assert output == expected_output, "Failed to encode boolean value to binary"
def test_encode_list(): """ Test encode list values """ value = [15, True] output = binary.encode(value) expected_output = bytearray(b'\x0f\x00\x00\x00\x00\x00\x00\x00\x01') assert output == expected_output, "Failed to encode list value to binary"
def test_encode_int(): """ Test encode int values """ value = 15 output = binary.encode(value) expected_output = b'\x0f\x00\x00\x00\x00\x00\x00\x00' assert output == expected_output, "Failed to encode integer value to binary"
def test_encode_None(): """ Test encode None value """ # test encoding None values result = binary.encode(None) assert len( result) == 0, "Wrong length of bytearray after encoding None value" assert type(result) == bytearray, "Wrong type after encoding None value"
def test_encode_currency(): """ Test encode currency values """ value = 15000000000000000 expected_output = bytearray( b'\x07\x00\x00\x00\x00\x00\x00\x005Jk\xa7\xa1\x80\x00') output = binary.encode(value, type_='currency') assert output == expected_output, "Failed to encode currency value to binary"
def test_encode_slice(): """ Test encode slice values """ value = [15, True] expected_output = bytearray( b'\x02\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x01' ) output = binary.encode(value, type_='slice') assert output == expected_output, "Failed to encode slice value to binary"
def hash(data, encoding_type=None): """ Hashes the input binary data using the blake2b algorithm @param data: Input data to be hashed @param encoding_type: Type of the data to guide the binary encoding before hashing @returns: Hashed value of the input data """ binary_data = binary.encode(data, type_=encoding_type) return blake2b(binary_data, digest_size=HASH_SIZE).digest()
def binary(self): """ Encodes the public key into binary format """ key_value = bytearray() s = bytearray(SPECIFIER_SIZE) s[:len(self._algorithm)] = bytearray(self._algorithm, encoding='utf-8') key_value.extend(s) key_value.extend(binary.encode(self._pub_key, type_='slice')) return key_value
def test_encode_object(): """ Test encode custom object that implement the binary property """ expected_output = b'custom object here' class CustomObj: @property def binary(self): return expected_output output = binary.encode(CustomObj()) assert output == expected_output, "Failed to encode custom value to binary"
def get_input_signature_hash(self, input_index, extra_objects=None): """ Builds a signature hash for an input @param input_index: Index of the input we will get signature hash for """ if extra_objects is None: extra_objects = [] buffer = bytearray() # encode the transaction version buffer.extend(self._version) # encode the input index buffer.extend(binary.encode(input_index)) # encode extra objects if exists for extra_object in extra_objects: buffer.extend(binary.encode(extra_object)) # encode the number of coins inputs buffer.extend(binary.encode(len(self._coins_inputs))) # encode inputs parent_ids for coin_input in self._coins_inputs: buffer.extend(binary.encode(coin_input.parent_id, type_='hex')) # encode coin outputs buffer.extend(binary.encode(self._coins_outputs, type_='slice')) # encode the number of blockstakes buffer.extend(binary.encode(len(self._blockstakes_inputs))) # encode blockstack inputs parent_ids for bs_input in self._blockstakes_inputs: buffer.extend(binary.encode(bs_input.parent_id, type_='hex')) # encode blockstake outputs buffer.extend(binary.encode(self._blockstakes_outputs, type_='slice')) # encode miner fees buffer.extend(binary.encode(len(self._minerfees))) for miner_fee in self._minerfees: buffer.extend(binary.encode(miner_fee, type_='currency')) # encode custom data_ buffer.extend(binary.encode(self._data, type_='slice')) # now we need to return the hash value of the binary array # return bytes(buffer) return hash(data=buffer)
def test_encode_unknown_type(): """ Test encode unknown data type """ with pytest.raises(ValueError): binary.encode('hello', type_='not supported type')