Skip to content

Commit

Permalink
feat: encodeDeployData
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Jan 29, 2023
1 parent 957922d commit 94b32ab
Show file tree
Hide file tree
Showing 20 changed files with 409 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-poets-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Added `encodeDeployData`.
8 changes: 4 additions & 4 deletions site/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ export const sidebar: DefaultTheme.Sidebar = {
link: '/docs/contract/decodeAbi',
},
{
text: 'decodeConstructorData 🚧',
link: '/docs/contract/decodeConstructorData',
text: 'decodeDeployData 🚧',
link: '/docs/contract/decodeDeployData',
},
{
text: 'decodeErrorData 🚧',
Expand All @@ -458,8 +458,8 @@ export const sidebar: DefaultTheme.Sidebar = {
link: '/docs/contract/encodeAbi',
},
{
text: 'encodeConstructorData 🚧',
link: '/docs/contract/encodeConstructorData',
text: 'encodeDeployData',
link: '/docs/contract/encodeDeployData',
},
{
text: 'encodeErrorData 🚧',
Expand Down
6 changes: 3 additions & 3 deletions site/docs/actions/test/setCode.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { testClient } from '.'

await setCode(testClient, { // [!code focus:4]
address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79',
bytecode: '60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...'
bytecode: '0x60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...'
})
```

Expand All @@ -31,7 +31,7 @@ The account address.
```ts
await setCode(testClient, {
address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79', // [!code focus]
bytecode: '60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...'
bytecode: '0x60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...'
})
```

Expand All @@ -44,6 +44,6 @@ The stored bytecode.
```ts
await setCode(testClient, {
address: '0xe846c6fcf817734ca4527b28ccb4aea2b6663c79',
bytecode: '60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...' // [!code focus]
bytecode: '0x60806040526000600355600019600955600c80546001600160a01b031916737a250d5630b4cf539739df...' // [!code focus]
})
```
File renamed without changes.
16 changes: 8 additions & 8 deletions site/docs/contract/deployContract.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { walletClient } from './client'

await deployContract(walletClient, {
abi,
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
})
```

Expand Down Expand Up @@ -59,7 +59,7 @@ import { walletClient } from './client'
await deployContract(walletClient, {
abi,
args: [69420],
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
})
```

Expand Down Expand Up @@ -101,15 +101,15 @@ import { wagmiAbi } from './abi'
import { walletClient } from './client'

const address = getContractAddress({
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
from: '0xc961145a54C96E3aE9bAA048c4F4D6b04C13916b',
opcode: 'CREATE2',
salt: 'hello',
})

await deployContract(walletClient, {
abi,
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
salt: 'hello',
})
```
Expand Down Expand Up @@ -149,7 +149,7 @@ The contract's ABI.
```ts
await deployContract(walletClient, {
abi: wagmiAbi, // [!code focus]
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
})
```

Expand All @@ -162,7 +162,7 @@ The contract's bytecode.
```ts
await deployContract(walletClient, {
abi: wagmiAbi,
bytecode: '608060405260405161083e38038061083e833981016040819052610...', // [!code focus]
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', // [!code focus]
})
```

Expand All @@ -175,7 +175,7 @@ Constructor arguments to call upon deployment.
```ts
await deployContract(walletClient, {
abi: wagmiAbi,
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
args: [69] // [!code focus]
})
```
Expand All @@ -189,7 +189,7 @@ An arbitrary value provided by the sender for `CREATE2` deployments.
```ts
await deployContract(walletClient, {
abi: wagmiAbi,
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
salt: 'hello' // [!code focus]
})
```
3 changes: 0 additions & 3 deletions site/docs/contract/encodeConstructorData.md

This file was deleted.

146 changes: 146 additions & 0 deletions site/docs/contract/encodeDeployData.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# encodeDeployData

Encodes deploy data (bytecode & constructor args) into an ABI encoded value.

## Install

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

## Usage

Below is a very basic example of how to encode deploy data.

::: code-group

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

const data = encodeDeployData({
abi: wagmiAbi,
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...'
})
// 0x608060405260405161083e38038061083e833981016040819052610...
```

```ts
export const wagmiAbi = [
...
{
inputs: [],
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()
})
```

:::

### Passing Arguments

If your constructor requires argument(s), you can pass them through with the `args` attribute.

TypeScript types for `args` will be inferred from the constructor & ABI, to guard you from inserting the wrong values.

For example, the `constructor` below requires an **address** argument, and it is typed as `["0x${string}"]`.

::: code-group

```ts {8} [example.ts]
import { encodeFunctionData } from 'viem'
import { publicClient } from './client'
import { wagmiAbi } from './abi'

const data = encodeFunctionData({
abi: wagmiAbi,
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
// 0x608060405260405161083e38038061083e833981016040819052610...00000000000000000000000000000000a5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC
```

```ts [abi.ts]
export const wagmiAbi = [
...
{
inputs: [{ name: 'owner', type: 'address' }],
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

`Hex`

ABI encoded data (bytecode & constructor arguments).

## Parameters

### abi

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

The contract's ABI.

```ts
const data = encodeFunctionData({
abi: wagmiAbi, // [!code focus]
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
```

### bytecode

- **Type:** `Hex`

Contract bytecode.

```ts
const data = encodeFunctionData({
abi: wagmiAbi,
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', // [!code focus]
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
```

### args (optional)

- **Type:** Inferred from ABI.

Arguments to pass to function call.

```ts
const data = encodeFunctionData({
abi: wagmiAbi,
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'] // [!code focus]
})
```
6 changes: 3 additions & 3 deletions site/docs/utilities/getContractAddress.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The opcode to invoke the contract deployment. Defaults to `"CREATE"`.

```ts
getContractAddress({
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
from: '0xc961145a54C96E3aE9bAA048c4F4D6b04C13916b',
opcode: 'CREATE2', // [!code focus:1]
salt: encodeBytes('wagmi'),
Expand All @@ -81,7 +81,7 @@ The to-be-deployed contract’s bytecode

```ts
getContractAddress({
bytecode: '608060405260405161083e38038061083e833981016040819052610...', // [!code focus:1]
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', // [!code focus:1]
from: '0xc961145a54C96E3aE9bAA048c4F4D6b04C13916b',
opcode: 'CREATE2',
salt: encodeBytes('wagmi'),
Expand All @@ -97,7 +97,7 @@ An arbitrary value provided by the sender.

```ts
getContractAddress({
bytecode: '608060405260405161083e38038061083e833981016040819052610...',
bytecode: '0x608060405260405161083e38038061083e833981016040819052610...',
from: '0xc961145a54C96E3aE9bAA048c4F4D6b04C13916b',
opcode: 'CREATE2',
salt: encodeBytes('wagmi'), // [!code focus:1]
Expand Down
30 changes: 30 additions & 0 deletions src/errors/abi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import { Hex } from '../types'
import { BaseError } from './base'

export class AbiConstructorNotFoundError extends BaseError {
name = 'AbiConstructorNotFoundError'
constructor() {
super(
[
'Constructor arguments were provided (`args`), but 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',
},
)
}
}

export class AbiConstructorParamsNotFoundError extends BaseError {
name = 'AbiConstructorParamsNotFoundError'
constructor() {
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',
},
)
}
}

export class AbiDecodingDataSizeInvalidError extends BaseError {
name = 'AbiDecodingDataSizeInvalidError'
constructor(size: number) {
Expand Down
2 changes: 2 additions & 0 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export {
AbiConstructorNotFoundError,
AbiConstructorParamsNotFoundError,
AbiDecodingDataSizeInvalidError,
AbiEncodingArrayLengthMismatchError,
AbiEncodingLengthMismatchError,
Expand Down
5 changes: 5 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import * as actions from './index'
test('exports actions', () => {
expect(actions).toMatchInlineSnapshot(`
{
"AbiConstructorNotFoundError": [Function],
"AbiConstructorParamsNotFoundError": [Function],
"AbiDecodingDataSizeInvalidError": [Function],
"AbiEncodingArrayLengthMismatchError": [Function],
"AbiEncodingLengthMismatchError": [Function],
"AbiFunctionNotFoundError": [Function],
"AbiFunctionOutputsNotFoundError": [Function],
"AbiFunctionSignatureNotFoundError": [Function],
"BaseError": [Function],
"BlockNotFoundError": [Function],
"DataLengthTooLongError": [Function],
Expand Down Expand Up @@ -73,6 +77,7 @@ test('exports actions', () => {
"dropTransaction": [Function],
"encodeAbi": [Function],
"encodeBytes": [Function],
"encodeDeployData": [Function],
"encodeFunctionData": [Function],
"encodeFunctionResult": [Function],
"encodeHex": [Function],
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,14 @@ export {
export { etherUnits, gweiUnits, transactionType, weiUnits } from './constants'

export {
AbiConstructorNotFoundError,
AbiConstructorParamsNotFoundError,
AbiDecodingDataSizeInvalidError,
AbiEncodingArrayLengthMismatchError,
AbiEncodingLengthMismatchError,
AbiFunctionNotFoundError,
AbiFunctionOutputsNotFoundError,
AbiFunctionSignatureNotFoundError,
BaseError,
BlockNotFoundError,
DataLengthTooLongError,
Expand Down Expand Up @@ -275,6 +279,7 @@ export {
decodeRlp,
encodeAbi,
encodeBytes,
encodeDeployData,
encodeFunctionData,
encodeFunctionResult,
encodeHex,
Expand Down
Loading

3 comments on commit 94b32ab

@vercel
Copy link

@vercel vercel bot commented on 94b32ab Jan 29, 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-wagmi-dev.vercel.app
viem-benchmark-git-main-wagmi-dev.vercel.app
viem-benchmark.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 94b32ab Jan 29, 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-git-main-wagmi-dev.vercel.app
viem-site-wagmi-dev.vercel.app
viem-site.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 94b32ab Jan 29, 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-git-main-wagmi-dev.vercel.app
viem-playground.vercel.app
viem-playground-wagmi-dev.vercel.app

Please sign in to comment.