Skip to content

Commit

Permalink
Allow numeric values in a transaction to be odd-lengthed hexstrings (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Sep 28, 2019
1 parent 828c8cf commit a12030a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
24 changes: 18 additions & 6 deletions packages/bytes/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type BytesLike = Bytes | string;

export type DataOptions = {
allowMissingPrefix?: boolean;
allowOddLength?: boolean;
hexPad?: "left" | "right" | null;
};

export interface Hexable {
Expand Down Expand Up @@ -112,8 +112,14 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti

if (isHexString(value)) {
let hex = (<string>value).substring(2);
if (!options.allowOddLength && hex.length % 2) {
logger.throwArgumentError("hex data is odd-length", "value", value);
if (hex.length % 2) {
if (options.hexPad === "left") {
hex = "0x0" + hex.substring(2);
} else if (options.hexPad === "right") {
hex += "0";
} else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}

let result = [];
Expand Down Expand Up @@ -212,8 +218,14 @@ export function hexlify(value: BytesLike | Hexable | number, options?: DataOptio
if (isHexable(value)) { return value.toHexString(); }

if (isHexString(value)) {
if (!options.allowOddLength && (<string>value).length % 2) {
logger.throwArgumentError("hex data is odd-length", "value", value);
if ((<string>value).length % 2) {
if (options.hexPad === "left") {
value = "0x0" + (<string>value).substring(2);
} else if (options.hexPad === "right") {
value += "0";
} else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}
return (<string>value).toLowerCase();
}
Expand Down Expand Up @@ -273,7 +285,7 @@ export function hexConcat(items: Array<BytesLike>): string {
}

export function hexValue(value: BytesLike | Hexable | number): string {
let trimmed = hexStripZeros(hexlify(value, { allowOddLength: true }));
let trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
if (trimmed === "0x") { return "0x0"; }
return trimmed;
}
Expand Down
11 changes: 11 additions & 0 deletions packages/tests/src.ts/test-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,14 @@ describe('Test Signing Messages', function() {
});
});
});

describe("Serialize Transactions", function() {
it("allows odd-length numeric values", function() {
const result = ethers.utils.serializeTransaction({
gasLimit: "0x1",
gasPrice: "0x1",
value: "0x1"
});
console.log(result);
});
});
14 changes: 8 additions & 6 deletions packages/transactions/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { getAddress } from "@ethersproject/address";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, BytesLike, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { arrayify, BytesLike, DataOptions, hexDataSlice, hexlify, hexZeroPad, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { Zero } from "@ethersproject/constants";
import { keccak256 } from "@ethersproject/keccak256";
import { checkProperties } from "@ethersproject/properties";
Expand Down Expand Up @@ -60,11 +60,11 @@ function handleNumber(value: string): BigNumber {
}

const transactionFields = [
{ name: "nonce", maxLength: 32 },
{ name: "gasPrice", maxLength: 32 },
{ name: "gasLimit", maxLength: 32 },
{ name: "nonce", maxLength: 32, numeric: true },
{ name: "gasPrice", maxLength: 32, numeric: true },
{ name: "gasLimit", maxLength: 32, numeric: true },
{ name: "to", length: 20 },
{ name: "value", maxLength: 32 },
{ name: "value", maxLength: 32, numeric: true },
{ name: "data" },
];

Expand All @@ -89,7 +89,9 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur

transactionFields.forEach(function(fieldInfo) {
let value = (<any>transaction)[fieldInfo.name] || ([]);
value = arrayify(hexlify(value));
const options: DataOptions = { };
if (fieldInfo.numeric) { options.hexPad = "left"; }
value = arrayify(hexlify(value, options));

// Fixed-width field
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
Expand Down

0 comments on commit a12030a

Please sign in to comment.