diff --git a/EIPS/eip-2566.md b/EIPS/eip-2566.md index a876efc926ff01..6ffc47a9e2ee5b 100644 --- a/EIPS/eip-2566.md +++ b/EIPS/eip-2566.md @@ -2,7 +2,7 @@ eip: 2566 title: Human Readable Parameters for Contract Function Execution author: Joseph Stockermans (@jstoxrocky) -discussions-to: https://ethereum-magicians.org/t/human-readable-parameters-for-contract-function-execution/4154, https://github.com/ethereum/EIPs/issues/2567 +discussions-to: https://ethereum-magicians.org/t/human-readable-parameters-for-contract-function-execution/4154 status: Draft type: Standards Track category: Interface @@ -10,12 +10,12 @@ created: 2020-03-23 --- ## Simple Summary -This EIP proposes a new Ethereum RPC method `eth_sendTransactionToContract` that accepts a human readable version of `eth_sendTransaction`'s `data` field. This change will allow ProviderWallets (hybrid Ethereum provider / wallet software) like Metamask and Geth to display confirmation screens with human readable details of a function call to a contract. +New Ethereum RPC method `eth_sendTransactionToContractFunction` that parallels `eth_sendTransaction` but allows for human-readable contract function execution data to be displayed to users. ## Abstract When a dapp prompts a user to execute a smart contract function via a ProviderWallet, confirmation screens displayed in the ProviderWallet layer cannot display the human readable details of the function to be called and the arguments to be passed. This is because the Ethereum RPC method used for contract function execution (`eth_sendTransaction`) accepts information about what function to call in a non-human readable (and non-recoverable) format. As such, when a ProviderWallet receives this non-human readable information from a dapp, they are unable to display a human readable version since they never received one and cannot recover one from the data. -This creates a poor and potentially dangerous user experience. For example, a malicious dapp could swap out the `address` argument in a token contract's `transfer(address,uint256)` function and reroute the tokens intended for someone else to themselves. This slight-of-hand would be quiet and unlikely to be picked up by a casual user glancing over the non-human readable data. By adding a new Ethereum RPC method (`eth_sendTransactionToContract`) that accepts a human readable version of the function-executing data, ProviderWallets can display the human readable details of contract function execution to users. +This creates a poor and potentially dangerous user experience. For example, a malicious dapp could swap out the `address` argument in a token contract's `transfer(address,uint256)` function and reroute the tokens intended for someone else to themselves. This slight-of-hand would be quiet and unlikely to be picked up by a casual user glancing over the non-human readable data. By adding a new Ethereum RPC method (`eth_sendTransactionToContractFunction`) that accepts the function ABI, ProviderWallets can recreate and display the human readable details of contract function execution to users. ## Motivation ### ProviderWallet Definition @@ -33,35 +33,18 @@ At one point or another, a dapp will ask a user to interact with a contract. The The accepted format for `eth_sendTransaction`'s `data` field is the hexadecimal encoding of the first four bytes of the keccak256 digest of the function signature. This abbreviated hash is then concatenated with the ABI encoded arguments to the function. Since the keccak256 digest of the function signature cannot be converted back into the function signature, the `data` field is not only non-human readable, its non-recoverable as well. On top of this, additional insight into the concatenated argument values is further obfuscated as information about their data types are held in the function signature preimage. -### Illustrated Example -When a ProviderWallet receives an `eth_sendTransaction` method call, it has the opportunity to display an information-rich confirmation prompt before signing and broadcasting the transaction to the Ethereum network. Unfortunately, as mentioned above, no human readable contract function-execution data is available at this stage. To illustrate, below we see a Metamask confirmation prompt. For context, this transaction executes the function `transferTokens(address,uint256)` at contract address `0xe44127f6fA8A00ee0228730a630fc1F3162C4d52`. The `from` address is aliased as `Account`, the value for the `address` argument passed to the function is `0x6Aa89e52c9a826496A8f311c1a9db62fd477E256`, and the `uint256` value is `100000000000`. - - - -There are a two main issues with what we are seeing. First, the recipient address shown is the destination contract - not the token recipient. While this is technically correct, users might not think about their actions in this way. In their minds, they might think of the recipient as the address to which they are attempting to transfer tokens to. This distinction can become clear with human readable function-execution data. Second, the hexadecimal encoded function-execution data is not very readable. In fact it's very unlikely that a regular user will even look at this information - let alone parse any insight from it. - -Let's compare what we see in the images above with what a user would see if a malicious dapp swaps out the address argument for one of their own. We will leave all other information the same but replace `0x6Aa89e52c9a826496A8f311c1a9db62fd477E256` with `0x9e0A8333984D617562a29a935123F17257aD4dEc`. - - - -You can see how quiet this slight-of-hand is. The hexadecimal encoded function-execution data has changed to include the new address but it is very unlikely that this non-human readable data field would cause any user to suspect that a dapp is stealing from them. Although this attack would likely be obvious to many examining the dapps front end source code, we cannot assume that all users have the ability to identify such an attack. We should strive to give end users much better security when interacting with contracts. Something like the following can be easily imagined with the `eth_sendTransactionToContractFunction` method. - - - -The Ethereum community is trending toward tools that better inform users about their actions. ProviderWallets will remain an integral part of the Ethereum community - serving as the backbone for dapp interconnectivity. The Ethereum RPC API specs should be augmented with methods like `eth_sendTransactionToContract` that allow ProviderWallets to better inform users. - ## Specification -This EIP proposes increasing the set of Ethereum RPC methods to include a new method - `eth_sendTransactionToContractFunction`. This method roughly parallels `eth_sendTransaction` with the only difference being the human readable `data` field representing the non-encoded arguments to the contract function, and the inclusion of the contract function's `abi` field. +This EIP proposes increasing the set of Ethereum RPC methods to include a new method - `eth_sendTransactionToContractFunction`. This method parallels `eth_sendTransaction` with the only difference being the inclusion of the contract function's `abi` field. Parameters 1. `Object` - The transaction object - * `from`: `DATA`, 20 Bytes - The address the transaction is send from. + * `from`: `DATA`, 20 Bytes - The address the transaction is sent from. * `to`: `DATA`, 20 Bytes - (optional when creating new contract) The address the transaction is directed to. * `gas`: `QUANTITY` - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas. * `gasPrice`: `QUANTITY` - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas * `value`: `QUANTITY` - (optional) Integer of the value sent with this transaction - * `data`: `DATA` - The arguments to the function (not ABI encoded) + * `data`: `DATA` - The hash of the invoked method signature and encoded parameters * `abi`: `DATA` - The function ABI * `nonce`: `QUANTITY` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. @@ -89,10 +72,7 @@ Example Parameters "stateMutability": "nonpayable", "type": "function" }", - "data": [ - "0x6Aa89e52c9a826496A8f311c1a9db62fd477E256", - 100000000000 - ] + "data": "0xbec3fa170000000000000000000000006Aa89e52c9a826496A8f311c1a9db62fd477E256000000000000000000000000000000000000000000000000000000174876E800" }] ``` @@ -111,18 +91,16 @@ curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransactionToContractFun } ## Rationale -With backwards compatibility in mind, this EIP proposes augmenting the set of Ethereum RPC methods with an additional method instead of mutating the existing method. Precedent for adding a new RPC method comes from [EIP 712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) in which adding the method `eth_signTypedData` is proposed for confirmation prompt security. As an alternate approach, the `eth_sendTransaction` method could be changed to accept its `data` argument in a human readable format, but this would break all existing code attempting to execute a contract function. Breaking this backwards compatibility would be a far bigger issue than the readability of an `data` argument so this EIP does not recommended this approach. +This EIP's proposed `eth_sendTransactionToContractFunction` method is intended to parallel `eth_sendTransaction` as much as possible since both methods result in the same behaviour when executing a contract function. The newly introduced `abi` field is an element of the contract's ABI that corresponds to the intended function. The `data` field is the same `data` field from `eth_sendTransaction`. The `abi` field can be combined with values parsed from the `data` field to recreate human readable contract function execution information. -This EIP's proposed `eth_sendTransactionToContractFunction` method is intended to parallel `eth_sendTransaction` as much as possible since both methods result in the same behaviour when executing a contract function. The `abi` field is an element of the contract's ABI that corresponds to the intended function. The `data` field is a non ABI-encoded array of arguments to be passed to the contract function. Dapps need not ABI-encode arguments as the data types of these arguments can be inferred from the `abi` field on the ProviderWallet side and encoded at that time. +## Implementation +The `data` field in `eth_sendTransactionToContractFunction` is the same as that required for `eth_sendTransaction` allowing the transaction to be completed via the existing mechanisms used for `eth_sendTransaction`. The input argument values can be parsed from the `data` field and since we know their types from the `abi` field, the provider wallet can use this info to encode and display the values in an appropriate human readable format. Furthermore, the hashed and truncated function signature in the `data` field can be reconstructed using the information provided in the `abi` field providing an additional check to ensure that the supplied ABI matches the `data` field. ## Backwards Compatibility -This EIP does not break backwards compatibility and addresses that point above. - -## Implementation -The `data` field from `eth_sendTransaction` can be reconstructed in its non-human readable format from the `abi` and `data` fields in `eth_sendTransactionToContractFunction`. This allows implementations to broadcast a transaction with data in the correct format for the Ethereum virtual machine. The function signature can be built and hashed from the function ABI, and the arguments can be ABI-encoded according to the data types specified in the function ABI. +With backwards compatibility in mind, this EIP proposes augmenting the set of Ethereum RPC methods with an additional method instead of mutating the existing method. Precedent for adding a new RPC method comes from [EIP 712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) in which adding the method `eth_signTypedData` is proposed for confirmation prompt security. As an alternate approach, the `eth_sendTransaction` method could be changed to accept an additional `abi` argument, but this would break all existing code attempting to execute a contract function. ## Security Considerations -Displaying the contract address, function name, and argument name/values can provide additional security to users but it is not a guarantee that a function will execute as the user expects. A poorly implemented contract can still name its function `transfer` and accept `address` and `uint256` arguments - but there is nothing short of contract examination that will let a user know that this contract is indeed a valid ERC20 contract. This EIP does not intend to solve the larger problem around trust in a contract's code, but instead intends to give users better tools to understand exactly what is contained within the data they are broadcasting to the Ethereum network. +Displaying the contract address, function name, and argument values can provide additional security to users, but it is not a guarantee that a function will execute as the user expects. A poorly implemented contract can still name its function `transfer` and accept `address` and `uint256` arguments - but there is nothing short of contract examination that will let a user know that this contract is indeed a valid ERC20 contract. This EIP does not intend to solve the larger problem around trust in a contract's code, but instead intends to give users better tools to understand exactly what is contained within the data they are broadcasting to the Ethereum network. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).