-
Notifications
You must be signed in to change notification settings - Fork 375
hw-app-eth does not support EIP155 for chainId >255 #168
Comments
Trezor doesn't support chainid more than 2000 also. It is a normal thing to use chainid smaller than 20 on ethereum networks |
just to be clear, the Ledger device does work with chainId>255 (for instance I was playing with 1337 recently on a DApp and with my Nano S). But using this workaround, the issue is that you have potential collisions: you can sign something that can be broadcasted on a network with the same chainId modulus 256. |
Similar issue has been resolved at the firmware level of the Trezor trezor/trezor-mcu#381 I strongly suspect that the following lines have this issue. |
the latest ledger correctly support 32bits chainId + EIP155 :) |
@hackmod neat. but it's still to be implemented on the js side I guess. what's kinda tricky is code won't be backward compatible I guess. unless we check the version 🤔 |
It was already ok on the device side before the new ETH app which introduced a regression by validating the chainId for the currently run app. On the JS side the best solution is to only use v coming from the device to get the signature "parity" then recompute it according to EIP 155 |
this is a quick hack
diff --git a/app/scripts/uiFuncs.js b/app/scripts/uiFuncs.js
index 6d09394..4af38e5 100644
--- a/app/scripts/uiFuncs.js
+++ b/app/scripts/uiFuncs.js
@@ -56,7 +56,7 @@ uiFuncs.signTxTrezor = function(rawTx, txData, callback) {
);
}
uiFuncs.signTxLedger = function(app, eTx, rawTx, txData, old, callback) {
- eTx.raw[6] = Buffer.from([rawTx.chainId]);
+ eTx.raw[6] = rawTx.chainId; // ethUtil.rlp.encode() can manage it.
eTx.raw[7] = eTx.raw[8] = 0;
var toHash = old ? eTx.raw.slice(0, 6) : eTx.raw;
var txToSign = ethUtil.rlp.encode(toHash);
@@ -69,7 +69,17 @@ uiFuncs.signTxLedger = function(app, eTx, rawTx, txData, old, callback) {
});
return;
}
- rawTx.v = "0x" + result['v'];
+ var v = result['v'].toString(16);
+ if (!old) {
+ // EIP155 support. check/recalc signature v value.
+ var rv = parseInt(v, 16);
+ var cv = rawTx.chainId * 2 + 35;
+ if (rv !== cv && (rv & cv) !== rv) {
+ cv += 1; // add signature v bit.
+ }
+ v = cv.toString(16);
+ }
+ rawTx.v = "0x" + v;
rawTx.r = "0x" + result['r'];
rawTx.s = "0x" + result['s'];
eTx = new ethUtil.Tx(rawTx); |
@hackmod thanks for the references! 🙌 |
chainId != networkId
(networkId is not used at all in the signing process. ony the chainId is used for signing)to support chainId > 255 cases the following
FIXME
annotated line should be fixed.https://github.com/LedgerHQ/ledgerjs/blob/master/packages/web3-subprovider/src/index.js#L160
[1] https://github.com/expanse-org/go-expanse/blob/master/eth/config.go#L42
[2] https://www.ethernodes.org/network/1/nodes
[3] https://github.com/kvhnuke/etherwallet/blob/mercury/app/scripts/nodes.js
[4] https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
[5] ethereum/EIPs#155
[6] https://github.com/LedgerHQ/ledgerjs/blob/master/packages/web3-subprovider/src/index.js#L160
The text was updated successfully, but these errors were encountered: