Safer transaction serialization, matching signature.v with chainId (#708).
This commit is contained in:
parent
15bb840907
commit
edb7c5da91
@ -2,7 +2,7 @@
|
||||
|
||||
import { getAddress } from "@ethersproject/address";
|
||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
||||
import { arrayify, BytesLike, DataOptions, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
|
||||
import { arrayify, BytesLike, DataOptions, hexDataSlice, hexlify, hexZeroPad, isBytesLike, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
|
||||
import { Zero } from "@ethersproject/constants";
|
||||
import { keccak256 } from "@ethersproject/keccak256";
|
||||
import { checkProperties } from "@ethersproject/properties";
|
||||
@ -109,17 +109,30 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
||||
raw.push(hexlify(value));
|
||||
});
|
||||
|
||||
if (transaction.chainId != null && transaction.chainId !== 0) {
|
||||
raw.push(hexlify(transaction.chainId));
|
||||
let chainId = 0;
|
||||
if (transaction.chainId != null) {
|
||||
// A chainId was provided; if non-zero we'll use EIP-155
|
||||
chainId = transaction.chainId;
|
||||
|
||||
if (typeof(chainId) !== "number") {
|
||||
logger.throwArgumentError("invalid transaction.chainId", "transaction", transaction);
|
||||
}
|
||||
|
||||
} else if (signature && !isBytesLike(signature) && signature.v > 28) {
|
||||
// No chainId provided, but the signature is signing with EIP-155; derive chainId
|
||||
chainId = Math.floor((signature.v - 35) / 2);
|
||||
}
|
||||
|
||||
// We have an EIP-155 transaction (chainId was specified and non-zero)
|
||||
if (chainId !== 0) {
|
||||
raw.push(hexlify(chainId));
|
||||
raw.push("0x");
|
||||
raw.push("0x");
|
||||
}
|
||||
|
||||
const unsignedTransaction = RLP.encode(raw);
|
||||
|
||||
// Requesting an unsigned transation
|
||||
if (!signature) {
|
||||
return unsignedTransaction;
|
||||
return RLP.encode(raw);
|
||||
}
|
||||
|
||||
// The splitSignature will ensure the transaction has a recoveryParam in the
|
||||
@ -128,11 +141,18 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
||||
|
||||
// We pushed a chainId and null r, s on for hashing only; remove those
|
||||
let v = 27 + sig.recoveryParam
|
||||
if (raw.length === 9) {
|
||||
if (chainId !== 0) {
|
||||
raw.pop();
|
||||
raw.pop();
|
||||
raw.pop();
|
||||
v += transaction.chainId * 2 + 8;
|
||||
v += chainId * 2 + 8;
|
||||
|
||||
// If an EIP-155 v (directly or indirectly; maybe _vs) was provided, check it!
|
||||
if (sig.v > 28 && sig.v !== v) {
|
||||
logger.throwArgumentError("transaction.chainId/signature.v mismatch", "signature", signature);
|
||||
}
|
||||
} else if (sig.v !== v) {
|
||||
logger.throwArgumentError("transaction.chainId/signature.v mismatch", "signature", signature);
|
||||
}
|
||||
|
||||
raw.push(hexlify(v));
|
||||
|
Loading…
x
Reference in New Issue
Block a user