-
Notifications
You must be signed in to change notification settings - Fork 75
FIX - Viem library refactor #1249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging/product-ia
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9637,8 +9637,6 @@ Page Title: viem for Polkadot Hub Smart Contracts | |||||
|
|
||||||
| # viem | ||||||
|
|
||||||
| !!! smartcontract "PolkaVM Preview Release" | ||||||
| PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. | ||||||
| ## Introduction | ||||||
|
|
||||||
| [viem](https://viem.sh/){target=\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub. | ||||||
|
|
@@ -9668,13 +9666,13 @@ viem-project/ | |||||
| β βββ interact.ts | ||||||
| βββ contracts/ | ||||||
| β βββ Storage.sol | ||||||
| βββ abis/ | ||||||
| β βββ Storage.json | ||||||
| βββ artifacts/ | ||||||
| βββ Storage.json | ||||||
| βββ Storage.polkavm | ||||||
| βββ Storage.bin | ||||||
| ``` | ||||||
|
|
||||||
| ## Set Up the Project | ||||||
|
|
||||||
| First, create a new folder and initialize your project: | ||||||
|
|
||||||
| ```bash | ||||||
|
|
@@ -9685,11 +9683,11 @@ npm init -y | |||||
|
|
||||||
| ## Install Dependencies | ||||||
|
|
||||||
| Install viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} bytecode: | ||||||
| Install viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\_blank}, which enables to compile smart contracts EVM bytecode: | ||||||
|
|
||||||
| ```bash | ||||||
| # Install viem and resolc | ||||||
| npm install viem @parity/resolc | ||||||
| npm install viem solc | ||||||
|
|
||||||
| # Install TypeScript and development dependencies | ||||||
| npm install --save-dev typescript ts-node @types/node | ||||||
|
|
@@ -9792,7 +9790,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- | |||||
| ```js title="src/fetchLastBlock.ts" | ||||||
| import { createPublicClient, http } from 'viem'; | ||||||
|
|
||||||
| const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); | ||||||
| const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready | ||||||
|
|
||||||
| // Configure the Polkadot Hub chain | ||||||
| const polkadotHubTestnet = { | ||||||
|
|
@@ -9806,7 +9804,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- | |||||
| }, | ||||||
| rpcUrls: { | ||||||
| default: { | ||||||
| http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], | ||||||
| http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready | ||||||
|
||||||
| }, | ||||||
| }, | ||||||
| } as const; | ||||||
|
|
@@ -9909,60 +9907,82 @@ contract Storage { | |||||
|
|
||||||
| ## Compile the Contract | ||||||
|
|
||||||
| !!! note "Contracts Code Blob Size Disclaimer" | ||||||
| The maximum contract code blob size on Polkadot Hub networks is _100 kilobytes_, significantly larger than Ethereumβs EVM limit of 24 kilobytes. | ||||||
|
|
||||||
| For detailed comparisons and migration guidelines, see the [EVM vs. PolkaVM](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#current-memory-limits){target=\_blank} documentation page. | ||||||
|
|
||||||
| Create a new file at `src/compile.ts` for handling contract compilation: | ||||||
|
|
||||||
| ```typescript title="src/compile.ts" | ||||||
| import { compile } from '@parity/resolc'; | ||||||
| import { readFileSync, writeFileSync } from 'fs'; | ||||||
| import solc from 'solc'; | ||||||
| import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; | ||||||
| import { basename, join } from 'path'; | ||||||
|
|
||||||
| const compileContract = async ( | ||||||
| const ensureDir = (dirPath: string): void => { | ||||||
| if (!existsSync(dirPath)) { | ||||||
| mkdirSync(dirPath, { recursive: true }); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| const compileContract = ( | ||||||
| solidityFilePath: string, | ||||||
| outputDir: string | ||||||
| ): Promise<void> => { | ||||||
| abiDir: string, | ||||||
| artifactsDir: string | ||||||
| ): void => { | ||||||
| try { | ||||||
| // Read the Solidity file | ||||||
| const source: string = readFileSync(solidityFilePath, 'utf8'); | ||||||
|
|
||||||
| // Construct the input object for the compiler | ||||||
| const input: Record<string, { content: string }> = { | ||||||
| [basename(solidityFilePath)]: { content: source }, | ||||||
| const fileName: string = basename(solidityFilePath); | ||||||
|
|
||||||
| // Construct the input object for the Solidity compiler | ||||||
| const input = { | ||||||
| language: 'Solidity', | ||||||
| sources: { | ||||||
| [fileName]: { | ||||||
| content: source, | ||||||
| }, | ||||||
| }, | ||||||
| settings: { | ||||||
| outputSelection: { | ||||||
| '*': { | ||||||
| '*': ['abi', 'evm.bytecode'], | ||||||
| }, | ||||||
| }, | ||||||
| }, | ||||||
| }; | ||||||
|
|
||||||
| console.log(`Compiling contract: ${basename(solidityFilePath)}...`); | ||||||
|
|
||||||
| console.log(`Compiling contract: ${fileName}...`); | ||||||
| // Compile the contract | ||||||
| const out = await compile(input); | ||||||
|
|
||||||
| for (const contracts of Object.values(out.contracts)) { | ||||||
| for (const [name, contract] of Object.entries(contracts)) { | ||||||
| console.log(`Compiled contract: ${name}`); | ||||||
|
|
||||||
| const output = JSON.parse(solc.compile(JSON.stringify(input))); | ||||||
|
|
||||||
| // Check for errors | ||||||
| if (output.errors) { | ||||||
| const errors = output.errors.filter((error: any) => error.severity === 'error'); | ||||||
| if (errors.length > 0) { | ||||||
| console.error('Compilation errors:'); | ||||||
| errors.forEach((err: any) => console.error(err.formattedMessage)); | ||||||
| return; | ||||||
| } | ||||||
| // Show warnings | ||||||
| const warnings = output.errors.filter((error: any) => error.severity === 'warning'); | ||||||
| warnings.forEach((warn: any) => console.warn(warn.formattedMessage)); | ||||||
| } | ||||||
|
|
||||||
| // Ensure output directories exist | ||||||
| ensureDir(abiDir); | ||||||
| ensureDir(artifactsDir); | ||||||
|
|
||||||
| // Process compiled contracts | ||||||
| for (const [sourceFile, contracts] of Object.entries(output.contracts)) { | ||||||
| for (const [contractName, contract] of Object.entries(contracts as any)) { | ||||||
| console.log(`Compiled contract: ${contractName}`); | ||||||
|
|
||||||
| // Write the ABI | ||||||
| const abiPath = join(outputDir, `${name}.json`); | ||||||
| writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); | ||||||
| const abiPath = join(abiDir, `${contractName}.json`); | ||||||
| writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2)); | ||||||
| console.log(`ABI saved to ${abiPath}`); | ||||||
|
|
||||||
| // Write the bytecode | ||||||
| if ( | ||||||
| contract.evm && | ||||||
| contract.evm.bytecode && | ||||||
| contract.evm.bytecode.object | ||||||
| ) { | ||||||
| const bytecodePath = join(outputDir, `${name}.polkavm`); | ||||||
| writeFileSync( | ||||||
| bytecodePath, | ||||||
| Buffer.from(contract.evm.bytecode.object, 'hex') | ||||||
| ); | ||||||
| console.log(`Bytecode saved to ${bytecodePath}`); | ||||||
| } else { | ||||||
| console.warn(`No bytecode found for contract: ${name}`); | ||||||
| } | ||||||
| const bytecodePath = join(artifactsDir, `${contractName}.bin`); | ||||||
| writeFileSync(bytecodePath, (contract as any).evm.bytecode.object); | ||||||
| console.log(`Bytecode saved to ${bytecodePath}`); | ||||||
| } | ||||||
| } | ||||||
| } catch (error) { | ||||||
|
|
@@ -9971,9 +9991,10 @@ const compileContract = async ( | |||||
| }; | ||||||
|
|
||||||
| const solidityFilePath: string = './contracts/Storage.sol'; | ||||||
| const outputDir: string = './artifacts/'; | ||||||
| const abiDir: string = './abis'; | ||||||
| const artifactsDir: string = './artifacts'; | ||||||
|
|
||||||
| compileContract(solidityFilePath, outputDir); | ||||||
| compileContract(solidityFilePath, abiDir, artifactsDir); | ||||||
| ``` | ||||||
|
|
||||||
| To compile your contract: | ||||||
|
|
@@ -9982,17 +10003,23 @@ To compile your contract: | |||||
| npm run compile | ||||||
| ``` | ||||||
|
|
||||||
| After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. | ||||||
| After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. | ||||||
|
||||||
| After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. | |
| After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.bin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO comments should not be committed to production documentation. These comments reference changing to "paseo asset hub once ready" but appear in user-facing code examples. Either remove the TODO comments or use placeholder text.