Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-2831 Transaction Replacement Message Type #2831

Merged
merged 7 commits into from
Jul 29, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions EIPS/eip-2831.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
eip: 2831
title: Transaction Replacement Message Type
author: Gregory Markou (@GregTheGreek)
discussions-to: https://ethereum-magicians.org/t/eip-2831-transaction-replacement-message-type/4448
status: Draft
type: Standards Track
category: Interface
created: 2020-07-26
requires: 1193
---

## Summary

An extension to the JavaScript Ethereum Proider API ([EIP-1193](./eip-1193.md)) this creates a new message type in the event a transaction replacement occurs.

## Abstract

The current communication between providers and consumers of providers are fundamentally broken in the event that a transaction in the mempool has been superseded by a newer transactions. Providers currently have no way of communicating a transaction replacement, and consumers are required to poll block by block for the resulting transaction.

## Motivation

Exert from EIP-1193
> A common convention in the Ethereum web application ("dapp") ecosystem is for key management software ("wallets") to expose their API via a JavaScript object in the web page.
This object is called "the Provider".

Many ingenious developments have been made by wallet developers to improve the overall user experience while interacting with the Ethereum blockchain. One specific innovation was transaction replacement, offering users the ability to effectively cancel a previously sent transaction.

Transaction replacement is not a new concept, but unfortunately causes major user experience problems for dapp developers as the replaced transaction is near impossible to track.

This EIP formalizes a way for both providers and dapp developers to track transaction replacements seamlessly.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC-2119](https://www.ietf.org/rfc/rfc2119.txt).

### Definitions

_This section is non-normative._

- Provider
- A JavaScript object made available to a consumer, that provides access to Ethereum by means of a Client.
- Wallet
- An end-user application that manages private keys, performs signing operations, and acts as a middleware between the Provider and the Client.
- Transaction Replacement
- Submitting a transaction with both: the same nonce and a 10% increase in the gas price, of a previous transaction which a user no longer wishes to send. This must occur before the original transaction is included in the blockchain.

### Interface

The `data` parameter contains two values: `oldTx` and `newTx`,the transaction hash that's being superseded and the transaction hash of the successor, respectively. Both `oldTx` and `newTx` should be encoded hex numbers as strings with the `0x` prefixed.

```JavaScript
interface TxReplacement extends ProviderMessage {
readonly type: 'tx_replacement';
readonly data: {
readonly oldTx: string;
readonly newTx: string;
};
}
```

## Rationale

The implementation was chosen to help the ease of implementation for both providers and dapp developers. Since `ProviderMessage` is widely used by dapp developers already it means that the implementation path would be as trivial as adding and additional `if` clause to their existing message listener. This also provides a benefit to dapps in the event that a provider has not yet implemented the `tx_replacement` and will not cause the dapp panic with `undefined` should it be implemented natively (eg: `ethereum.txReplacement(txHash, cb())` which would error with `ethereum.txReplacement()` is not a function).

## Backwards Compatibility

Many Providers adopted EIP-1193, as this EIP extends the arbitrary `message` event, there should be no breaking changes. All providers that do not support the new `tx_replacement` message should either I) Ignore the message or II) Provide some error to the user (Out of scope).

## Implementations

At the time of writing, no projects have working implementations.

## Security Considerations

None at the current time.

## References

- [Web3.js issue with metamask tx cancel](https://github.com/ethereum/web3.js/issues/3585)
- [Browser doesn't know when a transaction is replace](https://github.com/MetaMask/metamask-extension/issues/3347)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

## Appendix I: Examples

These examples assume a web browser environment.

```javascript
// Most Providers are available as window.ethereum on page load.
// This is only a convention, not a standard, and may not be the case in practice.
// Please consult the Provider implementation's documentation.
const ethereum = window.ethereum;

ethereum.on('message', (message) => {
if (message.type === 'tx_replacement') {
const { oldTx, newTx } = message.data;
console.log(`Tx ${oldTx} was cancelled, the new hash is ${newTx}`)
}
});

const transactionParameters = { ... } // Fill in parameters

ethereum
.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
})
.then((txHash) => {
console.log(`Transaction hash ${txHash}`)
})
.catch((error) => {
console.error(`Error sending transaction: ${error.code}: ${error.message}`);
});

```