Skip to content

Commit

Permalink
feat: decodeDeployData
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Jan 31, 2023
1 parent 13a6322 commit 976fd86
Show file tree
Hide file tree
Showing 25 changed files with 421 additions and 74 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-pillows-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Added `decodeDeployData`.
2 changes: 1 addition & 1 deletion site/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ export const sidebar: DefaultTheme.Sidebar = {
link: '/docs/contract/decodeAbi',
},
{
text: 'decodeDeployData 🚧',
text: 'decodeDeployData',
link: '/docs/contract/decodeDeployData',
},
{
Expand Down
113 changes: 111 additions & 2 deletions site/docs/contract/decodeDeployData.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,112 @@
# decodeConstructorData
# decodeDeployData

TODO
Decodes ABI encoded deploy data (bytecode & arguments).

The opposite of [`encodeDeployData`](/docs/contract/encodeDeployData).

## Install

```ts
import { decodeDeployData } from 'viem'
```

## Usage

::: code-group

```ts [example.ts]
import { decodeFunctionData } from 'viem'

const { args } = decodeFunctionData({
abi: wagmiAbi,
bytecode: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c'
})
// { args: [69420n], bytecode: '0x6080604...' }
```

```ts
export const wagmiAbi = [
...
{
inputs: [
{
internalType: 'uint256',
name: 'a',
type: 'uint256',
},
],
stateMutability: 'nonpayable',
type: 'constructor',
},
...
] as const;
```

```ts [client.ts]
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

export const publicClient = createPublicClient({
chain: mainnet,
transport: http()
})
```

:::


## Return Value

```ts
{
args: unknown[] | undefined;
bytecode: Hex;
}
```

Decoded deploy data.

## Parameters

### abi

- **Type:** [`Abi`](/docs/glossary/types#TODO)

The contract's ABI.

```ts
const { args } = decodeFunctionData({
abi: wagmiAbi, // [!code focus]
bytecode: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c'
})
```

### bytecode

- **Type:** `Hex`

Contract bytecode.

```ts
const { args } = decodeFunctionData({
abi: wagmiAbi,
bytecode: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033', // [!code focus]
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c'
})
```

### data

- **Type:** `Hex`

The encoded calldata.

```ts
const { args } = decodeFunctionData({
abi: wagmiAbi,
bytecode: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c' // [!code focus]
})
```
2 changes: 1 addition & 1 deletion src/actions/public/getTransactionCount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ export async function getTransactionCount(
method: 'eth_getTransactionCount',
params: [address, blockNumber ? numberToHex(blockNumber) : blockTag],
})
return hexToNumber(count ?? '0x0')
return hexToNumber(count)
}
12 changes: 8 additions & 4 deletions src/errors/abi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ test('AbiDecodingDataSizeInvalidError', () => {
})

test('InvalidAbiDecodingTypeError', () => {
expect(new InvalidAbiDecodingTypeError('lol')).toMatchInlineSnapshot(`
expect(
new InvalidAbiDecodingTypeError('lol', { docsPath: '/lol' }),
).toMatchInlineSnapshot(`
[InvalidAbiDecodingType: Type "lol" is not a valid decoding type.
Please provide a valid ABI type.
Docs: https://viem.sh/docs/contract/decodeAbi#params
Docs: https://viem.sh/lol
Version: viem@1.0.2]
`)
Expand Down Expand Up @@ -60,11 +62,13 @@ test('AbiEncodingLengthMismatchError', () => {
})

test('InvalidAbiEncodingTypeError', () => {
expect(new InvalidAbiEncodingTypeError('lol')).toMatchInlineSnapshot(`
expect(
new InvalidAbiEncodingTypeError('lol', { docsPath: '/lol' }),
).toMatchInlineSnapshot(`
[InvalidAbiEncodingType: Type "lol" is not a valid encoding type.
Please provide a valid ABI type.
Docs: https://viem.sh/docs/contract/encodeAbi#params
Docs: https://viem.sh/lol
Version: viem@1.0.2]
`)
Expand Down
50 changes: 25 additions & 25 deletions src/errors/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ import { BaseError } from './base'

export class AbiConstructorNotFoundError extends BaseError {
name = 'AbiConstructorNotFoundError'
constructor() {
constructor({ docsPath }: { docsPath: string }) {
super(
[
'Constructor arguments were provided (`args`), but a constructor was not found on the ABI.',
'A constructor was not found on the ABI.',
'Make sure you are using the correct ABI and that the constructor exists on it.',
].join('\n'),
{
docsPath: '/docs/contract/encodeDeployData',
docsPath,
},
)
}
}

export class AbiConstructorParamsNotFoundError extends BaseError {
name = 'AbiConstructorParamsNotFoundError'
constructor() {
constructor({ docsPath }: { docsPath: string }) {
super(
[
'Constructor arguments were provided (`args`), but a constructor parameters (`inputs`) were not found on the ABI.',
'Make sure you are using the correct ABI, and that the `inputs` attribute on the constructor exists.',
].join('\n'),
{
docsPath: '/docs/contract/encodeDeployData',
docsPath,
},
)
}
Expand Down Expand Up @@ -78,135 +78,135 @@ export class AbiEncodingLengthMismatchError extends BaseError {

export class AbiErrorInputsNotFoundError extends BaseError {
name = 'AbiErrorInputsNotFoundError'
constructor(errorName: string) {
constructor(errorName: string, { docsPath }: { docsPath: string }) {
super(
[
`Arguments (\`args\`) were provided to "${errorName}", but "${errorName}" on the ABI does not contain any parameters (\`inputs\`).`,
'Cannot encode error result without knowing what the parameter types are.',
'Make sure you are using the correct ABI and that the inputs exist on it.',
].join('\n'),
{
docsPath: '/docs/contract/encodeErrorResult',
docsPath,
},
)
}
}

export class AbiErrorNotFoundError extends BaseError {
name = 'AbiErrorNotFoundError'
constructor(errorName: string) {
constructor(errorName: string, { docsPath }: { docsPath: string }) {
super(
[
`Error "${errorName}" not found on ABI.`,
'Make sure you are using the correct ABI and that the error exists on it.',
].join('\n'),
{
docsPath: '/docs/contract/encodeErrorResult',
docsPath,
},
)
}
}

export class AbiErrorSignatureNotFoundError extends BaseError {
name = 'AbiErrorSignatureNotFoundError'
constructor(signature: Hex) {
constructor(signature: Hex, { docsPath }: { docsPath: string }) {
super(
[
`Encoded error signature "${signature}" not found on ABI.`,
'Make sure you are using the correct ABI and that the error exists on it.',
`You can look up the signature "${signature}" here: https://sig.eth.samczsun.com/.`,
].join('\n'),
{
docsPath: '/docs/contract/decodeErrorResult',
docsPath,
},
)
}
}

export class AbiEventNotFoundError extends BaseError {
name = 'AbiEventNotFoundError'
constructor(eventName: string) {
constructor(eventName: string, { docsPath }: { docsPath: string }) {
super(
[
`Event "${eventName}" not found on ABI.`,
'Make sure you are using the correct ABI and that the event exists on it.',
].join('\n'),
{
docsPath: '/docs/contract/encodeEventTopics',
docsPath,
},
)
}
}

export class AbiFunctionNotFoundError extends BaseError {
name = 'AbiFunctionNotFoundError'
constructor(functionName: string) {
constructor(functionName: string, { docsPath }: { docsPath: string }) {
super(
[
`Function "${functionName}" not found on ABI.`,
'Make sure you are using the correct ABI and that the function exists on it.',
].join('\n'),
{
docsPath: '/docs/contract/encodeFunctionData',
docsPath,
},
)
}
}

export class AbiFunctionOutputsNotFoundError extends BaseError {
name = 'AbiFunctionOutputsNotFoundError'
constructor(functionName: string) {
constructor(functionName: string, { docsPath }: { docsPath: string }) {
super(
[
`Function "${functionName}" does not contain any \`outputs\` on ABI.`,
'Cannot decode function result without knowing what the parameter types are.',
'Make sure you are using the correct ABI and that the function exists on it.',
].join('\n'),
{
docsPath: '/docs/contract/decodeFunctionResult',
docsPath,
},
)
}
}

export class AbiFunctionSignatureNotFoundError extends BaseError {
name = 'AbiFunctionSignatureNotFoundError'
constructor(signature: Hex) {
constructor(signature: Hex, { docsPath }: { docsPath: string }) {
super(
[
`Encoded function signature "${signature}" not found on ABI.`,
'Make sure you are using the correct ABI and that the function exists on it.',
`You can look up the signature "${signature}" here: https://sig.eth.samczsun.com/.`,
].join('\n'),
{
docsPath: '/docs/contract/decodeFunctionData',
docsPath,
},
)
}
}

export class InvalidAbiEncodingTypeError extends BaseError {
name = 'InvalidAbiEncodingType'
constructor(type: string) {
constructor(type: string, { docsPath }: { docsPath: string }) {
super(
[
`Type "${type}" is not a valid encoding type.`,
'Please provide a valid ABI type.',
].join('\n'),
{ docsPath: '/docs/contract/encodeAbi#params' },
{ docsPath },
)
}
}

export class InvalidAbiDecodingTypeError extends BaseError {
name = 'InvalidAbiDecodingType'
constructor(type: string) {
constructor(type: string, { docsPath }: { docsPath: string }) {
super(
[
`Type "${type}" is not a valid decoding type.`,
'Please provide a valid ABI type.',
].join('\n'),
{ docsPath: '/docs/contract/decodeAbi#params' },
{ docsPath },
)
}
}
Expand All @@ -220,14 +220,14 @@ export class InvalidArrayError extends BaseError {

export class InvalidDefinitionTypeError extends BaseError {
name = 'InvalidDefinitionTypeError'
constructor(type: string) {
constructor(type: string, { docsPath }: { docsPath: string }) {
super(
[
`"${type}" is not a valid definition type.`,
'Valid types: "function", "event", "error"',
].join('\n'),
{
docsPath: '/docs/contract/getDefinition',
docsPath,
},
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/eip1193.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ export type PublicRequests = {
* */
method: 'eth_getTransactionCount'
params: [address: Address, block: BlockNumber | BlockTag | BlockIdentifier]
}): Promise<Quantity | null>
}): Promise<Quantity>
request(args: {
/**
* @description Returns the receipt of a transaction specified by hash
Expand Down
Loading

3 comments on commit 976fd86

@vercel
Copy link

@vercel vercel bot commented on 976fd86 Jan 31, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

viem-benchmark – ./playgrounds/benchmark

viem-benchmark-git-main-wagmi-dev.vercel.app
viem-benchmark-wagmi-dev.vercel.app
viem-benchmark.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 976fd86 Jan 31, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

viem-playground – ./playgrounds/dev

viem-playground-wagmi-dev.vercel.app
viem-playground.vercel.app
viem-playground-git-main-wagmi-dev.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 976fd86 Jan 31, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

viem-site – ./site

viem-site-wagmi-dev.vercel.app
viem-site-git-main-wagmi-dev.vercel.app
viem-site.vercel.app

Please sign in to comment.