def getZeroExOrderHashV2(self, order):

    def pad_20_bytes_to_32(twenty_bytes):
        return (bytes(12) + twenty_bytes)

    def int_to_32_big_endian_bytes(i):
        return i.to_bytes(32, byteorder='big')

    def to_bytes(value):
        if (not isinstance(value, str)):
            raise TypeError('Value must be an instance of str')
        if (len(value) % 2):
            value = ('0x0' + self.remove_0x_prefix(value))
        return base64.b16decode(self.remove_0x_prefix(value), casefold=True)
    domain_struct_header = b"\x91\xab=\x17\xe3\xa5\n\x9d\x89\xe6?\xd3\x0b\x92\xbe\x7fS6\xb0;({\xb9Fxz\x83\xa9\xd6*'f\xf0\xf2F\x18\xf4\xc4\xbe\x1eb\xe0&\xfb\x03\x9a \xef\x96\xf4IR\x94\x81}\x10'\xff\xaam\x1fp\xe6\x1e\xad|[\xef\x02x\x16\xa8\x00\xda\x176DO\xb5\x8a\x80~\xf4\xc9`;xHg?~:h\xeb\x14\xa5"
    order_schema_hash = b'w\x05\x01\xf8\x8a&\xed\xe5\xc0J \xef\x87yi\xe9a\xeb\x11\xfc\x13\xb7\x8a\xafAKc=\xa0\xd4\xf8o'
    header = b'\x19\x01'
    domain_struct_hash = self.web3.sha3((domain_struct_header + pad_20_bytes_to_32(to_bytes(order['exchangeAddress']))))
    order_struct_hash = self.web3.sha3(((((((((((((order_schema_hash + pad_20_bytes_to_32(to_bytes(order['makerAddress']))) + pad_20_bytes_to_32(to_bytes(order['takerAddress']))) + pad_20_bytes_to_32(to_bytes(order['feeRecipientAddress']))) + pad_20_bytes_to_32(to_bytes(order['senderAddress']))) + int_to_32_big_endian_bytes(int(order['makerAssetAmount']))) + int_to_32_big_endian_bytes(int(order['takerAssetAmount']))) + int_to_32_big_endian_bytes(int(order['makerFee']))) + int_to_32_big_endian_bytes(int(order['takerFee']))) + int_to_32_big_endian_bytes(int(order['expirationTimeSeconds']))) + int_to_32_big_endian_bytes(int(order['salt']))) + self.web3.sha3(to_bytes(order['makerAssetData']))) + self.web3.sha3(to_bytes(order['takerAssetData']))))
    sha3 = self.web3.sha3(((header + domain_struct_hash) + order_struct_hash))
    return ('0x' + base64.b16encode(sha3).decode('ascii').lower())
def getZeroExOrderHashV2(self, order):

    def pad_20_bytes_to_32(twenty_bytes):
        return (bytes(12) + twenty_bytes)

    def int_to_32_big_endian_bytes(i):
        return i.to_bytes(32, byteorder='big')

    def to_bytes(value):
        if (not isinstance(value, str)):
            raise TypeError('Value must be an instance of str')
        if (len(value) % 2):
            value = ('0x0' + self.remove_0x_prefix(value))
        return base64.b16decode(self.remove_0x_prefix(value), casefold=True)
    domain_struct_header = b"\x91\xab=\x17\xe3\xa5\n\x9d\x89\xe6?\xd3\x0b\x92\xbe\x7fS6\xb0;({\xb9Fxz\x83\xa9\xd6*'f\xf0\xf2F\x18\xf4\xc4\xbe\x1eb\xe0&\xfb\x03\x9a \xef\x96\xf4IR\x94\x81}\x10'\xff\xaam\x1fp\xe6\x1e\xad|[\xef\x02x\x16\xa8\x00\xda\x176DO\xb5\x8a\x80~\xf4\xc9`;xHg?~:h\xeb\x14\xa5"
    order_schema_hash = b'w\x05\x01\xf8\x8a&\xed\xe5\xc0J \xef\x87yi\xe9a\xeb\x11\xfc\x13\xb7\x8a\xafAKc=\xa0\xd4\xf8o'
    header = b'\x19\x01'
    domain_struct_hash = self.web3.sha3((domain_struct_header + pad_20_bytes_to_32(to_bytes(order['exchangeAddress']))))
    order_struct_hash = self.web3.sha3(((((((((((((order_schema_hash + pad_20_bytes_to_32(to_bytes(order['makerAddress']))) + pad_20_bytes_to_32(to_bytes(order['takerAddress']))) + pad_20_bytes_to_32(to_bytes(order['feeRecipientAddress']))) + pad_20_bytes_to_32(to_bytes(order['senderAddress']))) + int_to_32_big_endian_bytes(int(order['makerAssetAmount']))) + int_to_32_big_endian_bytes(int(order['takerAssetAmount']))) + int_to_32_big_endian_bytes(int(order['makerFee']))) + int_to_32_big_endian_bytes(int(order['takerFee']))) + int_to_32_big_endian_bytes(int(order['expirationTimeSeconds']))) + int_to_32_big_endian_bytes(int(order['salt']))) + self.web3.sha3(to_bytes(order['makerAssetData']))) + self.web3.sha3(to_bytes(order['takerAssetData']))))
    sha3 = self.web3.sha3(((header + domain_struct_hash) + order_struct_hash))
    return ('0x' + base64.b16encode(sha3).decode('ascii').lower())