Task 2: Signed View Calls
As seen earlier in our code, contracts store the author information using the msg.sender
object.
There are two primary ways to interact with smart contracts:
- Smart Contract Transactions: These are written to the public ledger and require gas fees for computation and processing.
- View Calls: These are read-only calls to a smart contract. They happen locally on a compute node, do not modify the blockchain, and return the result immediately.
View calls are unique because they can also be encrypted, ensuring that the node operator cannot access your call data or the response. What makes Oasis Sapphire particularly special is that the msg.sender
object in these view calls always corresponds to the caller who initiated the contract view.
For this reason, view calls must be signed. If a view call is unsigned, Oasis Sapphire automatically nullifies the msg.sender
field by setting it to zero. This ensures the integrity and security of view call interactions.
Impersonation
How Does Ethereum Handle This?
In Ethereum, msg.sender
can be manipulated during view calls. By design, developers can set msg.sender
to any value in a read-only context. This allows impersonation of another account to execute view calls in their name, which Sapphire aims to prevent.
- Transactions:
In both Ethereum and Sapphire, transactions are signed by the caller, ensuring thatmsg.sender
reflects the signer. For transactions,msg.sender
always corresponds to the caller in both systems. - View Calls:
- In Ethereum, there is no built-in protection for
msg.sender
during view calls, allowing impersonation. - In Sapphire, view calls must be signed to verify the identity of the caller. If a view call is unsigned or attempts impersonation, Sapphire sets
msg.sender
to zero. This guarantees thatmsg.sender
either represents the true caller or is nullified when authenticity cannot be confirmed.
- In Ethereum, there is no built-in protection for
- Internal Transactions:
In both Ethereum and Sapphire, when a contract calls a function on another contract,msg.sender
represents the original caller of the internal transaction. This consistent behavior ensures thatmsg.sender
refers to the contract initiating the call, not the account submitting the original transaction.
In Ethereum, msg.sender
can be manipulated during view calls. By design, developers can set msg.sender
to any value in a read-only context. This allows impersonation of another account to execute view calls in their name, which Sapphire aims to prevent.
- Transactions:
In both Ethereum and Sapphire, transactions are signed by the caller, ensuring thatmsg.sender
reflects the signer. For transactions,msg.sender
always corresponds to the caller in both systems. - View Calls:
- In Ethereum, there is no built-in protection for
msg.sender
during view calls, allowing impersonation. - In Sapphire, view calls must be signed to verify the identity of the caller. If a view call is unsigned or attempts impersonation, Sapphire sets
msg.sender
to zero. This guarantees thatmsg.sender
either represents the true caller or is nullified when authenticity cannot be confirmed.
- In Ethereum, there is no built-in protection for
- Internal Transactions:
In both Ethereum and Sapphire, when a contract calls a function on another contract,msg.sender
represents the original caller of the internal transaction. This consistent behavior ensures thatmsg.sender
refers to the contract initiating the call, not the account submitting the original transaction.
Task 2: View Calls & Impersonation
This is the task:
This is pretty straightforward but one thing we need to do is to make the message private
We will enforce a rule where the message is returned only if the requester is the author. This approach ensures that the message remains private.
The logic is simple:
If msg.sender
does not match the message author, the contract will revert with an error like “not allowed.” Otherwise, the message is returned.
This return path will only be accessible to the author of the message. In Hardhat, we are already using the signed version, as the original signer is utilized here. Let’s deploy this updated contract to test the implementation.
This new contract is now deployed. Now let’s set a message:
if we want to receive the message it should work and this message call will be signed using this key so the smart contract will know that our author matches the the private key we signed the transaction with and this is the content confidential Hello world
If we use the unwrapped transaction so the original ethereum transaction which is not signed . Let’s use the code here:
and run the message function:
We received a “not allowed” exception, confirming that unsigned view calls result in the msg.sender
being nullified, causing the condition to fail.
This approach provides an effective way to enforce access control and mitigate gas cost attacks. By verifying that the query originates from the authorized author, unauthorized users cannot extract information about the contract’s behavior or access the stored data, regardless of their attempts.