I’ve been thinking more about the approach of extending msg.value
to support arbitrary tokens and I’d really like some feedback on the idea:
msg.value
is extended to be the following object:
{
"amount": uint256,
"token": Address,
}
Now let’s imagine user A wants to send tokens to contract B. User A crafts a transaction using the new msg.value
definition and sends it to contract B’s deposit
function:
contract B {
mapping(address => mapping(address => uint256)) deposits;
function deposit() payable {
deposits[msg.sender][msg.value.token] += msg.value.amount;
get_msg_value();
}
}
The deposit
function updates its records and calls get_msg_value()
, which is defined as an opcode or EEI host function.
function get_msg_value() {
token = GenericTransferableTokenInterface(msg.value.token)
delegatecall(token.transfer(self, msg.value.amount))
}
The msg.sender
and msg.value
of the call to contract B is forwarded to the token contract using a delegate call and self
is the address of the current execution context, contract B in this example. By nature of signing and sending the original transaction, user A approved the transfer to contract B.