Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

ethers: Fix encodeTxForRPC to separately handle 0x and 0x0 #508

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 34 additions & 22 deletions ethers-ext/src/core/klaytn_tx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { TransactionRequest } from "@ethersproject/abstract-provider";
import { BigNumber } from "ethers";
import { hexValue, parseTransaction } from "ethers/lib/utils";
import { accessListify } from "@ethersproject/transactions";
import _ from "lodash";

import { FieldSet, FieldSetFactory } from "./field";
Expand Down Expand Up @@ -108,28 +109,39 @@ export function objectFromRLP(value: string): any {
return tx;
}

export function encodeTxForRPC(allowedKeys:string[], tx: TransactionRequest): any {
// TODO: refactoring like below
// https://github.com/ethers-io/ethers.js/blob/master/packages/providers/src.ts/json-rpc-provider.ts#L701
// return {
// from: hexlify(tx.from),
// gas: tx.gasLimit? fromnumber(tx.gasLimit) : null;
// };

const ttx: any = {};
for (const key in tx) {
if (allowedKeys.indexOf(key) != -1) {
let value = _.get(tx, key);

if (value == 0 || value === "0x0000000000000000000000000000000000000000") {
value = "0x";
} else if (typeof(value) == "number" || value instanceof BigNumber) {
// https://github.com/ethers-io/ethers.js/blob/master/packages/providers/src.ts/json-rpc-provider.ts#L701
ttx[key] = hexValue(value);
} else {
ttx[key] = value;
}
export function encodeTxForRPC(tx: TransactionRequest): any {
const formatted: any = {};

const numericFields = ["chainId", "gasLimit", "gasPrice", "type", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "value"];
_.each(numericFields, (key) => {
if (!_.has(tx, key)) {
return;
}

let value = (<any>tx)[key];
value = hexValue(BigNumber.from(value));

if (key == "gasLimit") {
formatted["gas"] = value;
} else {
formatted[key] = value;
}
});

const bytestrFields = ["from", "to", "data", "input"]
_.each(bytestrFields, (key) => {
if (!_.has(tx, key)) {
return;
}

let value = (<any>tx)[key];
value = HexStr.from(value);
formatted[key] = value;
});

if (tx.accessList) {
formatted["accessList"] = accessListify(tx.accessList);
}
return ttx;

return formatted;
}
4 changes: 1 addition & 3 deletions ethers-ext/src/ethers/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ export class Wallet extends EthersWallet {

if (!(tx.gasLimit) && !!(tx.to)) {
if (this.provider instanceof EthersJsonRpcProvider) {
const estimateGasAllowedKeys: string[] = [
"from", "to", "gasLimit", "gasPrice", "value", "input"];
const ttx = encodeTxForRPC(estimateGasAllowedKeys, tx);
const ttx = encodeTxForRPC(tx);

const result = await this.provider.send("klay_estimateGas", [ttx]);
// For the problem that estimateGas does not exactly match,
Expand Down
37 changes: 37 additions & 0 deletions ethers-ext/test/core/klaytn_tx.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert } from "chai";
import { TransactionRequest } from "@ethersproject/abstract-provider";

import { KlaytnTxFactory } from "../../src/core";
import { encodeTxForRPC } from "../../src/core/klaytn_tx";

// Non-canonical types, which are common user-supplied values.
const nonce = 1234;
Expand Down Expand Up @@ -72,3 +74,38 @@ describe("TypedTxFactory", () => {
});
}
});

describe("encodeTxForRPC", () => {
it("success", () => {
let tx: TransactionRequest = {
chainId: 42,
gasLimit: 0x1111,
gasPrice: 0x222,
type: 2,
maxFeePerGas: 0x33,
maxPriorityFeePerGas: 0x4,
nonce: 0,
value: 0,

from: "0x00000000000000000000000000000000000000aa",
to: "0x00000000000000000000000000000000000000bb",
data: "0x",
};

let formatted = encodeTxForRPC(tx);
assert.deepEqual(formatted, {
chainId: '0x2a',
gas: '0x1111',
gasPrice: '0x222',
type: '0x2',
maxFeePerGas: '0x33',
maxPriorityFeePerGas: '0x4',
nonce: '0x0',
value: '0x0',

from: '0x00000000000000000000000000000000000000aa',
to: '0x00000000000000000000000000000000000000bb',
data: '0x',
});
});
});