Simple Summary
Disallow using the msg context in public functions which are called internally.
Abstract
This is kind of a follow-up to the discussion in #901. The currently implemented behavior is to disallow msg.sender in private functions, forcing the caller to pass it as an explicit function argument. The behavior proposed here is to extend this restriction to public functions which are called internally, and also to extend it to the entire msg context. If a user really wants to call an internal @public function which accesses the msg context, they are forced to refactor the function to pass msg.sender explicitly (and optionally change it to @private).
Motivation
msg.sender can have different values depending on if the function call is generated from an external caller or an internal caller. For instance,
@public
def call1() -> address:
return msg.sender
@private
def call2(addr: address) -> address:
return addr # Can't access `msg.sender` here, must pass as arg
@public
def call3() -> address:
return call1()
@public
def call4() -> address:
return call2(msg.sender)
In this example, call1 and call4 return the address of the caller, but call3 returns the address of this contract. This goes against Vyper's principle of auditability since extra context needs to be reasoned about when reading code. This proposal would force the above implementation of call1 to be changed to pass msg.sender as an argument, mimicking call2.
Additionally, the current behavior is an extra point of confusion for users coming from Solidity because Vyper's @public is more analogous to Solidity's external keyword than Solidity's public keyword (Solidity has a fine-grained distinction between public and external - public uses a jump which does not change the msg context, while external uses a message call).
Specification
In addition to disallowing msg.sender in private functions, additionally disallow any msg values (off the top of my head: msg.sender, msg.value, proposed msg.data) in internal calls to public functions by raising an exception.
Backwards Compatibility
msg.sender and friends are no longer allowed in public functions which are called internally.
Copyright
Copyright and related rights waived via CC0
Simple Summary
Disallow using the
msgcontext in public functions which are called internally.Abstract
This is kind of a follow-up to the discussion in #901. The currently implemented behavior is to disallow
msg.senderin private functions, forcing the caller to pass it as an explicit function argument. The behavior proposed here is to extend this restriction to public functions which are called internally, and also to extend it to the entiremsgcontext. If a user really wants to call an internal@publicfunction which accesses themsgcontext, they are forced to refactor the function to passmsg.senderexplicitly (and optionally change it to@private).Motivation
msg.sendercan have different values depending on if the function call is generated from an external caller or an internal caller. For instance,In this example,
call1andcall4return the address of the caller, butcall3returns the address of this contract. This goes against Vyper's principle of auditability since extra context needs to be reasoned about when reading code. This proposal would force the above implementation ofcall1to be changed to passmsg.senderas an argument, mimickingcall2.Additionally, the current behavior is an extra point of confusion for users coming from Solidity because Vyper's
@publicis more analogous to Solidity'sexternalkeyword than Solidity'spublickeyword (Solidity has a fine-grained distinction betweenpublicandexternal-publicuses a jump which does not change themsgcontext, whileexternaluses a message call).Specification
In addition to disallowing
msg.senderin private functions, additionally disallow anymsgvalues (off the top of my head:msg.sender,msg.value, proposedmsg.data) in internal calls to public functions by raising an exception.Backwards Compatibility
msg.senderand friends are no longer allowed in public functions which are called internally.Copyright
Copyright and related rights waived via CC0