Skip to content

Commit

Permalink
temp commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mpetrunic committed Jun 19, 2023
1 parent 2130d22 commit ba40305
Show file tree
Hide file tree
Showing 28 changed files with 938 additions and 12 deletions.
8 changes: 4 additions & 4 deletions packages/web3-errors/src/errors/utils_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ import { InvalidValueError } from '../web3_error_base.js';
export class InvalidBytesError extends InvalidValueError {
public code = ERR_INVALID_BYTES;

public constructor(value: unknown) {
super(value, 'can not parse as byte data');
public constructor(value: unknown, msg?: string) {
super(value, msg ?? 'can not parse as byte data');
}
}

export class InvalidNumberError extends InvalidValueError {
public code = ERR_INVALID_NUMBER;

public constructor(value: unknown) {
super(value, 'can not parse as number data');
public constructor(value: unknown, msg?: string) {
super(value, msg ?? 'can not parse as number data');
}
}

Expand Down
10 changes: 5 additions & 5 deletions packages/web3-eth-abi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@
"test:integration": "jest --config=./test/integration/jest.config.js --passWithNoTests"
},
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/bignumber": "^5.7.0",
"web3-errors": "^1.0.0",
"web3-types": "^1.0.0",
"web3-utils": "^4.0.1"
"@ethersproject/abi": "^5.6.4",
"web3-errors": "^0.1.1-alpha.4",
"web3-types": "^0.1.1-alpha.4",
"web3-utils": "^4.0.1-alpha.5",
"web3-validator": "^0.1.0-alpha.0"
},
"devDependencies": {
"@humeris/espresso-shot": "^4.0.0",
Expand Down
45 changes: 45 additions & 0 deletions packages/web3-eth-abi/src/coders/base/address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import { AbiParameter, Address } from "web3-types";
import { hexToBytes, isAddress } from "web3-utils";
import { AbiCoderError, AbiCoderErrors } from "../../errors";
import { CoderResultStatic } from "../types";
import { alloc, WORD_SIZE } from "../utils";

export function encodeAddress(param: AbiParameter, input: Address): CoderResultStatic {
let address = input.toLowerCase()
if(!address.startsWith("0x")) {
address = `0x${address}`
}
if(!isAddress(address)) {
throw new AbiCoderError("provided input is not valid address", AbiCoderErrors.INVALID_ARGUMENT, {
value: input,
name: param.name,
type: param.type
})
}
// for better performance, we could convert hex to destination bytes directly

const addressBytes = hexToBytes(address)
// expand address to WORD_SIZE
const encoded = alloc(WORD_SIZE);
encoded.set(addressBytes, WORD_SIZE - addressBytes.length)
return {
dynamic: false,
encoded
}
}
39 changes: 39 additions & 0 deletions packages/web3-eth-abi/src/coders/base/bool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import { InvalidBooleanError } from "web3-errors";
import { AbiParameter } from "web3-types";
import { toBool } from "web3-utils";
import { AbiCoderError, AbiCoderErrors } from "../../errors";
import { CoderResultStatic } from "../types";
import { encodeNumber } from "./number";

export function encodeBoolean(param: AbiParameter, input: boolean | string | number): CoderResultStatic {
let value;
try {
value = toBool(input);
} catch (e) {
if (e instanceof InvalidBooleanError) {
throw new AbiCoderError("provided input is not valid boolean value", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input,
name: param.name
})
}
}

return encodeNumber({ type: "uint8", name: "" }, Number(value))
}
67 changes: 67 additions & 0 deletions packages/web3-eth-abi/src/coders/base/bytes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import { AbiParameter, Bytes } from "web3-types";
import { bytesToBuffer } from "web3-utils";
import { isBytes } from "web3-validator";
import { AbiCoderError, AbiCoderErrors } from "../../errors";
import { CoderResultDynamic, CoderResultStatic } from "../types";
import { alloc, WORD_SIZE } from "../utils";
import { encodeNumber } from "./number";

export function encodeBytes(param: AbiParameter, input: Bytes): CoderResultDynamic|CoderResultStatic {
if(!isBytes(input)) {
throw new AbiCoderError("provided input is not valid bytes value", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input,
name: param.name
})
}
const bytes = bytesToBuffer(input);
const [, size] = param.type.split('bytes')
// fixed size
if(size) {
if(Number(size) !== bytes.length) {
throw new AbiCoderError("provided input size is different than type size", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input,
name: param.name
})
}
const encoded = alloc(WORD_SIZE)
encoded.set(bytes)
return {
dynamic: false,
encoded
}
}

const partsLength = Math.ceil(bytes.length / WORD_SIZE)
// one word for length of data + WORD for each part of actual data
const encoded = alloc(WORD_SIZE + partsLength * WORD_SIZE)

encoded.set(encodeNumber({type: "uint32", name: ""}, bytes.length).encoded)
let offset = WORD_SIZE
for(let i = 0; i < partsLength; i+=1) {
encoded.set(bytes.subarray(i* WORD_SIZE, (i+1)*WORD_SIZE), offset)
offset += WORD_SIZE
}
return {
dynamic: true,
size: bytes.length,
encoded
}
}
31 changes: 31 additions & 0 deletions packages/web3-eth-abi/src/coders/base/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import { AbiParameter } from "web3-types";
import { CoderResultDynamic, CoderResultStatic } from "../types";

export {encodeBytes} from "./bytes";
export {encodeString} from "./string";
export {encodeNumber} from "./number";
export {encodeBoolean} from "./bool";
export {encodeAddress} from "./address";

export function encodeParam(param: AbiParameter, value: unknown): CoderResultStatic|CoderResultDynamic {
switch(param.type) {
case ""
}
}
111 changes: 111 additions & 0 deletions packages/web3-eth-abi/src/coders/base/number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import type { AbiParameter, Numbers } from "web3-types";
import { toBigInt } from "web3-utils";
import { AbiCoderError, AbiCoderErrors } from "../../errors";
import { CoderResultStatic } from "../types";
import { allocUnsafe, WORD_SIZE } from "../utils";

function bigIntToUint8Array(value: bigint, byteLength = WORD_SIZE): Uint8Array {
const uint8Array = allocUnsafe(byteLength);
let isNegative = false;

let a = value

// Convert the BigInt value to a positive number and set the sign flag if it's negative.
if (value < BigInt(0)) {
a = -value;
isNegative = true;
}

// Write the binary representation of the value to the Uint8Array.
for (let i = byteLength - 1; i >= 0; i -= 1) {
// eslint-disable-next-line no-bitwise
const byteValue = Number(a & BigInt(0xff));
uint8Array[i]= byteValue;
// eslint-disable-next-line no-bitwise
a >>= BigInt(8);
}

// If the value is negative, convert it to two's complement.
if (isNegative) {
for (let i = 0; i < byteLength; i+=1) {
// eslint-disable-next-line no-bitwise
uint8Array[i] = ~uint8Array[i];
}
for (let i = byteLength - 1; i >= 0; i-=1) {
const byteValue = uint8Array[i] + 1;
// eslint-disable-next-line no-bitwise
uint8Array[i] = byteValue & 0xff;
if (byteValue <= 0xff) {
break;
}
}
}

return uint8Array;
}

const numberLimits = new Map<string, {min: bigint; max: bigint}>()

// precalculate all the limits
for(let i = 8; i <= 256; i*=2 ) {
numberLimits.set(`uint${i}`, {
min: BigInt(0),
max: BigInt(2) ** BigInt(i) - BigInt(1)
});
numberLimits.set(`int${i}`, {
min: -(BigInt(2) ** BigInt(i/2)),
max: BigInt(2) ** BigInt(i/2) - BigInt(1)
});
}

export function encodeNumber(param: AbiParameter, input: Numbers): CoderResultStatic {
let value
try {
value = toBigInt(input)
} catch(e) {
throw new AbiCoderError("provided input is not number value", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input,
name: param.name,
})
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const limit = numberLimits.get(param.type)!;
if(value < limit.min) {
throw new AbiCoderError("provided input is less then minimum for given type", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input.toString(),
name: param.name,
minimum: limit.min.toString()
})
}
if(value > limit.max) {
throw new AbiCoderError("provided input is greater then maximum for given type", AbiCoderErrors.INVALID_ARGUMENT, {
type: param.type,
value: input.toString(),
name: param.name,
maximum: limit.max.toString()
})
}
return {
dynamic: false,
encoded: bigIntToUint8Array(value)
}
}
25 changes: 25 additions & 0 deletions packages/web3-eth-abi/src/coders/base/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import { AbiParameter } from "web3-types";
import { utf8ToBytes } from "web3-utils";
import { CoderResultDynamic, CoderResultStatic } from "../types";
import { encodeBytes } from "./bytes";

export function encodeString(_param: AbiParameter, input: string): CoderResultDynamic|CoderResultStatic {
const bytes = utf8ToBytes(input);
return encodeBytes({type: "bytes", name: ""}, bytes)
}
Loading

0 comments on commit ba40305

Please sign in to comment.