Allow numeric values in a transaction to be odd-lengthed hexstrings (#614).
This commit is contained in:
parent
828c8cfd41
commit
a12030ad29
@ -13,7 +13,7 @@ export type BytesLike = Bytes | string;
|
|||||||
|
|
||||||
export type DataOptions = {
|
export type DataOptions = {
|
||||||
allowMissingPrefix?: boolean;
|
allowMissingPrefix?: boolean;
|
||||||
allowOddLength?: boolean;
|
hexPad?: "left" | "right" | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Hexable {
|
export interface Hexable {
|
||||||
@ -112,9 +112,15 @@ export function arrayify(value: BytesLike | Hexable | number, options?: DataOpti
|
|||||||
|
|
||||||
if (isHexString(value)) {
|
if (isHexString(value)) {
|
||||||
let hex = (<string>value).substring(2);
|
let hex = (<string>value).substring(2);
|
||||||
if (!options.allowOddLength && hex.length % 2) {
|
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);
|
logger.throwArgumentError("hex data is odd-length", "value", value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let i = 0; i < hex.length; i += 2) {
|
for (let i = 0; i < hex.length; i += 2) {
|
||||||
@ -212,9 +218,15 @@ export function hexlify(value: BytesLike | Hexable | number, options?: DataOptio
|
|||||||
if (isHexable(value)) { return value.toHexString(); }
|
if (isHexable(value)) { return value.toHexString(); }
|
||||||
|
|
||||||
if (isHexString(value)) {
|
if (isHexString(value)) {
|
||||||
if (!options.allowOddLength && (<string>value).length % 2) {
|
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);
|
logger.throwArgumentError("hex data is odd-length", "value", value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (<string>value).toLowerCase();
|
return (<string>value).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +285,7 @@ export function hexConcat(items: Array<BytesLike>): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function hexValue(value: BytesLike | Hexable | number): 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"; }
|
if (trimmed === "0x") { return "0x0"; }
|
||||||
return trimmed;
|
return trimmed;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { getAddress } from "@ethersproject/address";
|
import { getAddress } from "@ethersproject/address";
|
||||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
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 { Zero } from "@ethersproject/constants";
|
||||||
import { keccak256 } from "@ethersproject/keccak256";
|
import { keccak256 } from "@ethersproject/keccak256";
|
||||||
import { checkProperties } from "@ethersproject/properties";
|
import { checkProperties } from "@ethersproject/properties";
|
||||||
@ -60,11 +60,11 @@ function handleNumber(value: string): BigNumber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const transactionFields = [
|
const transactionFields = [
|
||||||
{ name: "nonce", maxLength: 32 },
|
{ name: "nonce", maxLength: 32, numeric: true },
|
||||||
{ name: "gasPrice", maxLength: 32 },
|
{ name: "gasPrice", maxLength: 32, numeric: true },
|
||||||
{ name: "gasLimit", maxLength: 32 },
|
{ name: "gasLimit", maxLength: 32, numeric: true },
|
||||||
{ name: "to", length: 20 },
|
{ name: "to", length: 20 },
|
||||||
{ name: "value", maxLength: 32 },
|
{ name: "value", maxLength: 32, numeric: true },
|
||||||
{ name: "data" },
|
{ name: "data" },
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -89,7 +89,9 @@ export function serialize(transaction: UnsignedTransaction, signature?: Signatur
|
|||||||
|
|
||||||
transactionFields.forEach(function(fieldInfo) {
|
transactionFields.forEach(function(fieldInfo) {
|
||||||
let value = (<any>transaction)[fieldInfo.name] || ([]);
|
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
|
// Fixed-width field
|
||||||
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
|
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user