-
Notifications
You must be signed in to change notification settings - Fork 238
Correctly support signing and serializing of EIP155 valid transaction #143
Conversation
16b8138
to
2948ee7
Compare
One question that came to when when writing the above PR description: what should happen when v and chainId are provided to the transaction constructor, but they are incompatible? I am inclined to think that an error should be thrown. But would appreciate other opinions. |
d7c98ea
to
4d75731
Compare
2948ee7
to
224abf7
Compare
10cca64
to
85df7a9
Compare
Hi Dan, just only came to read this, thanks for this fantastic write-up, this is really an outstanding and super-transparent summary! 😀🤗 I would also suggest/tend to throw with incompatible v and chainId. |
Once you've merged #131 can you the here so that one can better see the change diff? |
What's the status of this (typo in the above comment: "the"-> "rebase"), also can #131 be merged? I would really like to get this over the finish line and do an in-between release, one doesn't even dare to look any more when we started this work. |
This PR seems correct. I don't get why it changes Regarding incompatible |
Hi @danjm I've now merged #131. Can you rebase and address the comment from @alcuadrado so that we can also merge here, there is more and more work building in top of your changes, and otherwise things get a bit too messy. 🙂 |
85df7a9
to
eb7ae3c
Compare
I've rebased this branch. @alcuadrado To be clear, you don't think further changes are needed to this PR, correct? |
That's correct @danjm, thanks for rebasing this. |
This PR is branched off of the branch for #131
This fixes #123 and is an improvement over #124. It also fixes an additional issue introduced in #131 that was necessary to get the transaction tests passing.
The first commit in this PR adds two failing tests, one of which is strictly based off the example in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md. This is the example used in the explanation of #123. The second commit fixes these tests.
Further explanation
Consider the test added in this PR:
Note that there are three assertions. The first, which checks the serialized tx before signing, currently fails on master. #124 would fix that assertion, but break signing which relies on our current behaviour of defaulting to v to
0x1c
even whenchainId
s are passed. This behaviour is tested by the'sign tx with chainId specified in params'
test intest/api.js
, and is consistent with part of EIP-155 that says "The currently existing signature scheme using v = 27 and v = 28 remains valid and continues to operate under the same rules as it does now."This PR provides a backwards compatible fix of the first assertion by taking advantage of the new
common
andchain
options. Developers who need to correctly serialize transactions with a chainId before they are signed will be able to do so if the chainId is indicated through those options. Thev
value used for serialization will be set by those if provided.After #131, the 3rd assertion in the above test fails. This is because that PR changed the conditions which determine whether the EIP155 alterations to signature values (v, r, s) would be applied to the hash used when signing. It replaced the simple check as to whether chainId was being used (chaindId > 0) with the check defined in the EIP (v is chainId*2 + 35 or 36, and the current block > 2,675,000). This was necessary to get all transaction tests to pass.
However, this had the unintended side effect of using the incorrect hash when signing EIP155 transactions with chainId's but no explicit v, r and s values. This side effect is not caught by the transaction tests because those are all already signed. Basically, transactions seeking replay protection need to be signed with the v, r and s values specified under EIP155 rules, even when not provided a
v
at time of creation. The EIP155 example implies that a transaction should be signed with a hash created with a v = chainId, if chainId is explicitly provided, even when v is not explicitly provided. This PR fixes the 3rd assertion in the above test by ensuring this happens.The other test added in this PR checks that signing is done correctly when using a chain other than mainnet.