Skip to content

Commit

Permalink
Document Formatting (#7222)
Browse files Browse the repository at this point in the history
* Document Formatting

* Add More Example with `getBlockNumber`
  • Loading branch information
danforbes committed Sep 13, 2024
1 parent b86d8ca commit b3cb1b7
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 0 deletions.
121 changes: 121 additions & 0 deletions docs/docs/guides/getting_started/return-formats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
sidebar_position: 3
sidebar_label: Return Formats
---

# Return Formats

By default, Web3.js formats byte values as hexadecimal strings (e.g. `"0x221`") and number values as [`BigInt`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). The default formats can be configured at the global level by updating the [`defaultReturnFormat` configuration option](/guides/web3_config/#defaultreturnformat). Many Web3.js functions (e.g. [`getBlock`](/api/web3-eth/function/getBlock), [`sendTransaction`](/api/web3-eth/function/sendTransaction)) accept an optional parameter named `returnFormat` of the [type `DataFormat`](/api/web3-types#DataFormat) that can be used to configure the format for data returned by that single function invocation.

The following example demonstrates working with return formats:

```ts
import { Block, FMT_BYTES, FMT_NUMBER, Numbers, Web3 } from "web3";

const web3 = new Web3("https://eth.llamarpc.com");

// use the default return format
web3.eth.getBlock().then((block: Block) => {
console.log(`Block #${block.number} Hash: ${block.hash}`);
});
// ↳ Block #20735255 Hash: 0xbaea6dbd46fa810a27be4c9eac782602f8efe7512fb30a8455c127b101a23e22

// specify the return format for a single function invocation
web3.eth
.getBlockNumber({
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.HEX,
})
.then((blockNumber: Numbers) => {
console.log(`Block #${blockNumber}`);
});
// ↳ Block #0x13c6517

// configure default return format for the web3-eth package
web3.eth.defaultReturnFormat = {
bytes: FMT_BYTES.UINT8ARRAY,
number: FMT_NUMBER.HEX,
};

web3.eth.getBlock().then((block: Block) => {
console.log(`Block #${block.number} Hash: [${block.hash}]`);
});
// ↳ Block #0x13c6517 Hash: [186,234,109,...,162,62,34]
```

The supported return formats are:

- Bytes
- [`FMT_BYTES.HEX`](/api/web3-types/enum/FMT_BYTES#HEX): hexadecimal [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"0xdd"`)
```ts
web3.eth
.getBlock(undefined, undefined, {
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.BIGINT,
})
.then((block: Block) => {
console.log(`Block hash: ${block.hash}`);
});
// ↳ Block hash: 0xbaea6dbd46fa810a27be4c9eac782602f8efe7512fb30a8455c127b101a23e22
```
- [`FMT_BYTES.UINT8ARRAY`](/api/web3-types/enum/FMT_BYTES#UINT8ARRAY): [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) (e.g. `[ 2, 33 ]`)
```ts
web3.eth
.getBlock(undefined, undefined, {
bytes: FMT_BYTES.UINT8ARRAY,
number: FMT_NUMBER.BIGINT,
})
.then((block: Block) => {
console.log(`Block hash: [${block.hash}]`);
});
// ↳ Block hash: [186,234,109,...,162,62,34]
```
- Numbers
- [`FMT_NUMBER.BIGINT`](/api/web3-types/enum/FMT_NUMBER#BIGINT): [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) (e.g. `221n`)
```ts
web3.eth
.getBlockNumber({
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.BIGINT,
})
.then((blockNumber: Numbers) => {
console.log(`Block #${blockNumber}`);
});
// ↳ Block #20735255
```
- [`FMT_NUMBER.HEX`](/api/web3-types/enum/FMT_NUMBER#HEX): hexadecimal [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"0xdd"`)
```ts
web3.eth
.getBlockNumber({
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.HEX,
})
.then((blockNumber: Numbers) => {
console.log(`Block #${blockNumber}`);
});
// ↳ Block #0x13c6517
```
- [`FMT_NUMBER.NUMBER`](/api/web3-types/enum/FMT_NUMBER#NUMBER): [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) (e.g. `221`)
```ts
web3.eth
.getBlockNumber({
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.NUMBER,
})
.then((blockNumber: Numbers) => {
console.log(`Block #${blockNumber}`);
});
// ↳ Block #20735255
```
- [`FMT_NUMBER.STR`](/api/web3-types/enum/FMT_NUMBER#STR): [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"221"`)
```ts
web3.eth
.getBlockNumber({
bytes: FMT_BYTES.HEX,
number: FMT_NUMBER.STR,
})
.then((blockNumber: Numbers) => {
console.log(`Block #${blockNumber}`);
});
// ↳ Block #20735255
```
67 changes: 67 additions & 0 deletions docs/docs/guides/web3_utils_module/mastering_web3-utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,70 @@ console.log(web3.utils.compareBlockNumbers(2, 2));
// 0
```

### Formatting

The [`format` function](/api/web3-utils/function/format) in the `web3-utils` package is used to convert data between equivalent formats. For example, bytes that are represented as a [`Uint8Array` type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) can be formatted as a hexademical string (e.g. `"0xdd"`) or primitive JavaScript [`Number` types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) can be formatted as [`BigInt` types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). The `format` function expects two required parameters, `schema` and `data`, and accepts a third optional parameter, `returnFormat`. The `schema` parameter is used to describe how the data should be interpreted. The `data` parameter represents the data that is to be formatted. The [`returnFormat` parameter](#return-formats) specifies how the data should be formatted.

Here are some example that demonstrate the use of the `format` function:

```js
import { format } from "web3-utils";
import { FMT_BYTES, FMT_NUMBER } from "web3-types";

// format a primitive number as a hexidecimal string
console.log(format({ format: "uint" }, 221, { number: FMT_NUMBER.HEX }));
// ↳ 0xdd

// format a primitive number as a BigInt
console.log(format({ format: "uint" }, 221, { number: FMT_NUMBER.BIGINT }));
// ↳ 221n

// format a stringified number as a hexidecimal string
console.log(format({ format: "uint" }, "221", { number: FMT_NUMBER.HEX }));
// ↳ 0xdd

// format a Uint8Array of bytes as a hexidecimal string
console.log(
format({ format: "bytes" }, new Uint8Array([2, 33]), {
bytes: FMT_BYTES.HEX,
}),
);
// ↳ 0x0221

// format an array of values
console.log(
format({ type: "array", items: { format: "uint" } }, ["221", 1983], {
number: FMT_NUMBER.HEX,
}),
);
// ↳ [ '0xdd', '0x7bf' ]

// format an object with multiple properties
console.log(
format(
{
type: "object",
properties: {
aNumber: { format: "uint" },
someBytes: { format: "bytes" },
},
},
{ aNumber: "221", someBytes: new Uint8Array([2, 33]) },
{ bytes: FMT_BYTES.UINT8ARRAY, number: FMT_NUMBER.HEX },
),
);
// ↳ { aNumber: '0xdd', someBytes: Uint8Array(2) [ 2, 33 ] }
```

#### Return Formats

The following return formats are supported:

- Bytes
- [`FMT_BYTES.HEX`](/api/web3-types/enum/FMT_BYTES#HEX): hexadecimal [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"0xdd"`)
- [`FMT_BYTES.UINT8ARRAY`](/api/web3-types/enum/FMT_BYTES#UINT8ARRAY): [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) (e.g. `[ 2, 33 ]`)
- Numbers
- [`FMT_NUMBER.BIGINT`](/api/web3-types/enum/FMT_NUMBER#BIGINT): [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) (e.g. `221n`)
- [`FMT_NUMBER.HEX`](/api/web3-types/enum/FMT_NUMBER#HEX): hexadecimal [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"0xdd"`)
- [`FMT_NUMBER.NUMBER`](/api/web3-types/enum/FMT_NUMBER#NUMBER): [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) (e.g. `221`)
- [`FMT_NUMBER.STR`](/api/web3-types/enum/FMT_NUMBER#STR): [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) (e.g. `"221"`)
5 changes: 5 additions & 0 deletions packages/web3-types/src/data_format_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ export type ByteTypes = {
[FMT_BYTES.UINT8ARRAY]: Uint8Array;
};

/**
* Used to specify how data should be formatted. Bytes can be formatted as hexadecimal strings or
* Uint8Arrays. Numbers can be formatted as BigInts, hexadecimal strings, primitive numbers, or
* strings.
*/
export type DataFormat = {
readonly number: FMT_NUMBER;
readonly bytes: FMT_BYTES;
Expand Down
21 changes: 21 additions & 0 deletions packages/web3-utils/src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,27 @@ export const convert = (
return object;
};

/**
* Given data that can be interpreted according to the provided schema, returns equivalent data that has been formatted
* according to the provided return format.
*
* @param schema - how to interpret the data
* @param data - data to be formatted
* @param returnFormat - how to format the data
* @returns - formatted data
*
* @example
*
* ```js
* import { FMT_NUMBER, utils } from "web3";
*
* console.log(
* utils.format({ format: "uint" }, "221", { number: FMT_NUMBER.HEX }),
* );
* // 0xdd
* ```
*
*/
export const format = <
DataType extends Record<string, unknown> | unknown[] | unknown,
ReturnType extends DataFormat,
Expand Down

1 comment on commit b3cb1b7

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: b3cb1b7 Previous: b86d8ca Ratio
processingTx 21696 ops/sec (±8.85%) 22440 ops/sec (±7.06%) 1.03
processingContractDeploy 40328 ops/sec (±6.93%) 38564 ops/sec (±7.90%) 0.96
processingContractMethodSend 17416 ops/sec (±6.78%) 16696 ops/sec (±7.81%) 0.96
processingContractMethodCall 28028 ops/sec (±7.80%) 27650 ops/sec (±7.82%) 0.99
abiEncode 46457 ops/sec (±6.59%) 44651 ops/sec (±6.88%) 0.96
abiDecode 31537 ops/sec (±7.34%) 30424 ops/sec (±7.61%) 0.96
sign 1584 ops/sec (±0.53%) 1574 ops/sec (±0.58%) 0.99
verify 364 ops/sec (±2.47%) 365 ops/sec (±2.65%) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.