Basically, the prefix has to commit to the relevant parts of the query, so that the gateway can’t provide a valid answer to a different query.
A concrete example may help. Suppose you’re implementing ERC20’s
balanceOf function using Durin:
function balanceOf(address addr) public returns(uint256)
Your implementation wants the gateway to go off and get the result, with some proof data, and call this function:
function balanceOfWithProof(address addr, uint balance, bytes memory proof) returns(uint256)
If the prefix specified by the first function were empty, the gateway could return a call to any function at all on the contract, which would be bad.
If the prefix contains just the 4-byte function ID, the gateway would need to return a call to
balanceOfWithProof, but it could have any arguments at all - meaning it could return a proof of the balance of a different account.
If the prefix contains the function ID and the first argument, the gateway can only return calls with the correct address - so it no longer has the freedom to mislead the caller or the contract.
This can be easily implemented in the contract by making the prefix the result of