Skip to content

Commit

Permalink
feat: better legacy eip155 tx serializing (wevm#1438)
Browse files Browse the repository at this point in the history
* fix: legacy eip155 tx serializing

* Create fair-lemons-retire.md
  • Loading branch information
jxom authored Nov 3, 2023
1 parent 339fbf1 commit 8e52fcb
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-lemons-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Fixed legacy EIP-155 transaction serializing.
132 changes: 132 additions & 0 deletions src/utils/transaction/serializeTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,135 @@ test('cannot infer type from transaction object', () => {
Version: [email protected]"
`)
})

describe('github', () => {
test('https://github.com/wagmi-dev/viem/issues/1433', () => {
expect(
serializeTransaction(
{
blockHash: null,
blockNumber: null,
from: '0xc702b9950e44f7d321fa16ee88bf8e1a561249ba',
gas: 51627n,
gasPrice: 3000000000n,
hash: '0x3eaa88a766e82cbe53c95218ab4c3cf316325802b5f75d086b5121007b918e92',
input:
'0xa9059cbb00000000000000000000000082fc882199816bcec06baf848eaec51c2f96c85b000000000000000000000000000000000000000000000000eccae3078bacd15d',
nonce: 117,
to: '0x55d398326f99059ff775485246999027b3197955',
transactionIndex: null,
value: 0n,
type: 'legacy',
v: 84475n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
chainId: undefined,
typeHex: '0x0',
},
{
v: 84475n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
},
),
).toMatchInlineSnapshot(
'"0xf8667584b2d05e0082c9ab9455d398326f99059ff775485246999027b31979558080830149fba073b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bfa0354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23"',
)

expect(
serializeTransaction(
{
blockHash: null,
blockNumber: null,
from: '0xc702b9950e44f7d321fa16ee88bf8e1a561249ba',
gas: 51627n,
gasPrice: 3000000000n,
hash: '0x3eaa88a766e82cbe53c95218ab4c3cf316325802b5f75d086b5121007b918e92',
input:
'0xa9059cbb00000000000000000000000082fc882199816bcec06baf848eaec51c2f96c85b000000000000000000000000000000000000000000000000eccae3078bacd15d',
nonce: 117,
to: '0x55d398326f99059ff775485246999027b3197955',
transactionIndex: null,
value: 0n,
type: 'legacy',
v: 84476n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
chainId: undefined,
typeHex: '0x0',
},
{
v: 84476n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
},
),
).toMatchInlineSnapshot(
'"0xf8667584b2d05e0082c9ab9455d398326f99059ff775485246999027b31979558080830149fca073b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bfa0354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23"',
)

expect(
serializeTransaction(
{
blockHash: null,
blockNumber: null,
from: '0xc702b9950e44f7d321fa16ee88bf8e1a561249ba',
gas: 51627n,
gasPrice: 3000000000n,
hash: '0x3eaa88a766e82cbe53c95218ab4c3cf316325802b5f75d086b5121007b918e92',
input:
'0xa9059cbb00000000000000000000000082fc882199816bcec06baf848eaec51c2f96c85b000000000000000000000000000000000000000000000000eccae3078bacd15d',
nonce: 117,
to: '0x55d398326f99059ff775485246999027b3197955',
transactionIndex: null,
value: 0n,
type: 'legacy',
v: 35n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
chainId: undefined,
typeHex: '0x0',
},
{
v: 35n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
},
),
).toMatchInlineSnapshot(
'"0xf8637584b2d05e0082c9ab9455d398326f99059ff775485246999027b319795580801ba073b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bfa0354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23"',
)

expect(
serializeTransaction(
{
blockHash: null,
blockNumber: null,
from: '0xc702b9950e44f7d321fa16ee88bf8e1a561249ba',
gas: 51627n,
gasPrice: 3000000000n,
hash: '0x3eaa88a766e82cbe53c95218ab4c3cf316325802b5f75d086b5121007b918e92',
input:
'0xa9059cbb00000000000000000000000082fc882199816bcec06baf848eaec51c2f96c85b000000000000000000000000000000000000000000000000eccae3078bacd15d',
nonce: 117,
to: '0x55d398326f99059ff775485246999027b3197955',
transactionIndex: null,
value: 0n,
type: 'legacy',
v: 36n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
chainId: undefined,
typeHex: '0x0',
},
{
v: 36n,
r: '0x73b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bf',
s: '0x354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23',
},
),
).toMatchInlineSnapshot(
'"0xf8637584b2d05e0082c9ab9455d398326f99059ff775485246999027b319795580801ca073b39769ff4a36515c8fca546550a3fdafebbf37fa9e22be2d92b44653ade7bfa0354c756a1aa3346e9b3ea5423ac99acfc005e9cce2cd698e14d792f43fa15a23"',
)
})
})
21 changes: 17 additions & 4 deletions src/utils/transaction/serializeTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,23 @@ function serializeTransactionLegacy(
]

if (signature) {
let v = 27n + (signature.v === 27n ? 0n : 1n)
if (chainId > 0) v = BigInt(chainId * 2) + BigInt(35n + signature.v - 27n)
else if (signature.v !== v)
throw new InvalidLegacyVError({ v: signature.v })
const v = (() => {
// EIP-155 (explicit chainId)
if (chainId > 0)
return BigInt(chainId * 2) + BigInt(35n + signature.v - 27n)

// EIP-155 (inferred chainId)
if (signature.v >= 35n) {
const inferredChainId = (signature.v - 35n) / 2n
if (inferredChainId > 0) return signature.v
return 27n + (signature.v === 35n ? 0n : 1n)
}

// Pre-EIP-155 (no chainId)
const v = 27n + (signature.v === 27n ? 0n : 1n)
if (signature.v !== v) throw new InvalidLegacyVError({ v: signature.v })
return v
})()

serializedTransaction = [
...serializedTransaction,
Expand Down

0 comments on commit 8e52fcb

Please sign in to comment.