Skip to content Skip to footer

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:

  1. Smart Contract Transactions: These are written to the public ledger and require gas fees for computation and processing.
  2. 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 that msg.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 that msg.sender either represents the true caller or is nullified when authenticity cannot be confirmed.
  • 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 that msg.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 that msg.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 that msg.sender either represents the true caller or is nullified when authenticity cannot be confirmed.
  • 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 that msg.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.