-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
63 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
--- | ||
eip: 191 | ||
title: Signed Data Standard | ||
authors: Martin Holst Swende (@holiman), Nick Johnson <arachnid@notdot.net> | ||
Status: Draft | ||
Type: Standards Track | ||
Category: ERC | ||
Created: 2016-01-20 | ||
--- | ||
|
||
# Abstract | ||
|
||
This ERC proposes a specification about how to handle signed data in Etherum contracts. | ||
|
||
# Motivation | ||
|
||
Several multisignature wallet implementations have been created which accepts `presigned` transactions. A `presigned` transaction is a chunk of binary `signed_data`, along with signature (`r`, `s` and `v`). The interpretation of the `signed_data` has not been specified, leading to several problems: | ||
|
||
* Standard Ethereum transactions can be submitted as `signed_data`. An Ethereum transaction can be unpacked, into the following components: `RLP<nonce, gasPrice, startGas, to, value, data>` (hereby called `RLPdata`), `r`, `s` and `v`. If there are no syntactical constraints on `signed_data`, this means that `RLPdata` can be used as a syntactically valid `presigned` transaction. | ||
* Multisignature wallets have also had the problem that a `presigned` transaction has not been tied to a particular `validator`, i.e a specific wallet. Example: | ||
1. Users `A`, `B` and `C` have the `2/3`-wallet `X` | ||
2. Users `A`, `B` and `D` have the `2/3`-wallet `Y` | ||
3. User `A` and `B` submites `presigned` transaction to `X`. | ||
4. Attacker can now reuse their presigned transactions to `X`, and submit to `Y`. | ||
|
||
## Specification | ||
|
||
We propose the following format for `signed_data` | ||
|
||
``` | ||
0x19 <1 byte version> <version specific data> <data to sign>. | ||
``` | ||
Version `0` has `<20 byte address>` for the version specific data, and the `address` is the intended validator. In the case of a Multisig wallet, that is the wallet's own address . | ||
|
||
The initial `0x19` byte is intended to ensure that the `signed_data` is not valid [RLP](https://github.com/ethereum/wiki/wiki/RLP) | ||
|
||
> For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding. | ||
That means that any `signed_data` cannot be one RLP-structure, but a 1-byte `RLP` payload followed by something else. Thus, any ERC-191 `signed_data` can never be an Ethereum transaction. | ||
|
||
Additionally, `0x19` has been chosen because since ethereum/go-ethereum#2940 , the following is prepended before hashing in personal_sign: | ||
|
||
``` | ||
"\x19Ethereum Signed Message:\n" + len(message). | ||
``` | ||
|
||
Using `0x19` thus makes it possible to extend the scheme by defining a version `0x45` (`E`) to handle these kinds of signatures. | ||
|
||
### Example | ||
|
||
function submitTransactionPreSigned(address destination, uint value, bytes data, uint nonce, uint8 v, bytes32 r, bytes32 s) | ||
public | ||
returns (bytes32 transactionHash) | ||
{ | ||
// Arguments when calculating hash to validate | ||
// 1: byte(0x19) - the initial 0x19 byte | ||
// 2: byte(0) - the version byte | ||
// 4: this - the validator address | ||
// 4-7 : Application specific data | ||
transactionHash = keccak256(byte(0x19),byte(0),this,destination, value, data, nonce); | ||
sender = ecrecover(transactionHash, v, r, s); | ||
// ... | ||
} |