Skip to content

Commit ea51ea1

Browse files
committed
fix: viem library to evm
1 parent 4746943 commit ea51ea1

File tree

5 files changed

+105
-67
lines changed

5 files changed

+105
-67
lines changed
Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,76 @@
1-
import { compile } from '@parity/resolc';
2-
import { readFileSync, writeFileSync } from 'fs';
1+
import solc from 'solc';
2+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
33
import { basename, join } from 'path';
44

5-
const compileContract = async (
5+
const ensureDir = (dirPath: string): void => {
6+
if (!existsSync(dirPath)) {
7+
mkdirSync(dirPath, { recursive: true });
8+
}
9+
};
10+
11+
const compileContract = (
612
solidityFilePath: string,
7-
outputDir: string
8-
): Promise<void> => {
13+
abiDir: string,
14+
artifactsDir: string
15+
): void => {
916
try {
1017
// Read the Solidity file
1118
const source: string = readFileSync(solidityFilePath, 'utf8');
12-
13-
// Construct the input object for the compiler
14-
const input: Record<string, { content: string }> = {
15-
[basename(solidityFilePath)]: { content: source },
19+
const fileName: string = basename(solidityFilePath);
20+
21+
// Construct the input object for the Solidity compiler
22+
const input = {
23+
language: 'Solidity',
24+
sources: {
25+
[fileName]: {
26+
content: source,
27+
},
28+
},
29+
settings: {
30+
outputSelection: {
31+
'*': {
32+
'*': ['abi', 'evm.bytecode'],
33+
},
34+
},
35+
},
1636
};
17-
18-
console.log(`Compiling contract: ${basename(solidityFilePath)}...`);
19-
37+
38+
console.log(`Compiling contract: ${fileName}...`);
39+
2040
// Compile the contract
21-
const out = await compile(input);
22-
23-
for (const contracts of Object.values(out.contracts)) {
24-
for (const [name, contract] of Object.entries(contracts)) {
25-
console.log(`Compiled contract: ${name}`);
26-
41+
const output = JSON.parse(solc.compile(JSON.stringify(input)));
42+
43+
// Check for errors
44+
if (output.errors) {
45+
const errors = output.errors.filter((error: any) => error.severity === 'error');
46+
if (errors.length > 0) {
47+
console.error('Compilation errors:');
48+
errors.forEach((err: any) => console.error(err.formattedMessage));
49+
return;
50+
}
51+
// Show warnings
52+
const warnings = output.errors.filter((error: any) => error.severity === 'warning');
53+
warnings.forEach((warn: any) => console.warn(warn.formattedMessage));
54+
}
55+
56+
// Ensure output directories exist
57+
ensureDir(abiDir);
58+
ensureDir(artifactsDir);
59+
60+
// Process compiled contracts
61+
for (const [sourceFile, contracts] of Object.entries(output.contracts)) {
62+
for (const [contractName, contract] of Object.entries(contracts as any)) {
63+
console.log(`Compiled contract: ${contractName}`);
64+
2765
// Write the ABI
28-
const abiPath = join(outputDir, `${name}.json`);
29-
writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));
66+
const abiPath = join(abiDir, `${contractName}.json`);
67+
writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2));
3068
console.log(`ABI saved to ${abiPath}`);
31-
69+
3270
// Write the bytecode
33-
if (
34-
contract.evm &&
35-
contract.evm.bytecode &&
36-
contract.evm.bytecode.object
37-
) {
38-
const bytecodePath = join(outputDir, `${name}.polkavm`);
39-
writeFileSync(
40-
bytecodePath,
41-
Buffer.from(contract.evm.bytecode.object, 'hex')
42-
);
43-
console.log(`Bytecode saved to ${bytecodePath}`);
44-
} else {
45-
console.warn(`No bytecode found for contract: ${name}`);
46-
}
71+
const bytecodePath = join(artifactsDir, `${contractName}.bin`);
72+
writeFileSync(bytecodePath, (contract as any).evm.bytecode.object);
73+
console.log(`Bytecode saved to ${bytecodePath}`);
4774
}
4875
}
4976
} catch (error) {
@@ -52,6 +79,7 @@ const compileContract = async (
5279
};
5380

5481
const solidityFilePath: string = './contracts/Storage.sol';
55-
const outputDir: string = './artifacts/';
82+
const abiDir: string = './abis';
83+
const artifactsDir: string = './artifacts';
5684

57-
compileContract(solidityFilePath, outputDir);
85+
compileContract(solidityFilePath, abiDir, artifactsDir);

.snippets/code/smart-contracts/libraries/viem/deploy.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import { readFileSync } from 'fs';
2-
import { join } from 'path';
3-
import { createWallet } from './createWallet';
4-
import { publicClient } from './createClient';
1+
import { existsSync, readFileSync } from 'fs';
2+
import { dirname, join } from 'path';
3+
import { fileURLToPath } from 'url';
4+
import { createWallet } from './createWallet.ts';
5+
import { publicClient } from './createClient.ts';
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = dirname(__filename);
9+
const ABIS_DIR = join(__dirname, '../abis');
10+
const ARTIFACTS_DIR = join(__dirname, '../artifacts');
511

612
const deployContract = async (
713
contractName: string,
@@ -10,16 +16,20 @@ const deployContract = async (
1016
try {
1117
console.log(`Deploying ${contractName}...`);
1218

19+
const abiPath = join(ABIS_DIR, `${contractName}.json`);
20+
const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`);
21+
22+
if (!existsSync(abiPath) || !existsSync(bytecodePath)) {
23+
throw new Error(
24+
`Missing artifacts for ${contractName}. Try running "npm run compile" first.`
25+
);
26+
}
27+
1328
// Read contract artifacts
1429
const abi = JSON.parse(
15-
readFileSync(
16-
join(__dirname, '../artifacts', `${contractName}.json`),
17-
'utf8'
18-
)
30+
readFileSync(abiPath, 'utf8')
1931
);
20-
const bytecode = `0x${readFileSync(
21-
join(__dirname, '../artifacts', `${contractName}.polkavm`)
22-
).toString('hex')}` as `0x${string}`;
32+
const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`;
2333

2434
// Create wallet
2535
const wallet = createWallet(privateKey);

.snippets/code/smart-contracts/libraries/viem/fetchLastBlock.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createPublicClient, http } from 'viem';
22

3-
const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io');
3+
const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready
44

55
// Configure the Polkadot Hub chain
66
const polkadotHubTestnet = {
@@ -14,7 +14,7 @@ const polkadotHubTestnet = {
1414
},
1515
rpcUrls: {
1616
default: {
17-
http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'],
17+
http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready
1818
},
1919
},
2020
} as const;

.snippets/code/smart-contracts/libraries/viem/interact.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { publicClient } from './createClient';
2-
import { createWallet } from './createWallet';
31
import { readFileSync } from 'fs';
2+
import { dirname, join } from 'path';
3+
import { fileURLToPath } from 'url';
4+
import { publicClient } from './createClient.ts';
5+
import { createWallet } from './createWallet.ts';
46

5-
const STORAGE_ABI = JSON.parse(
6-
readFileSync('./artifacts/Storage.json', 'utf8')
7-
);
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = dirname(__filename);
9+
const ABI_PATH = join(__dirname, '../abis/Storage.json');
10+
11+
const STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8'));
812

913
const interactWithStorage = async (
1014
contractAddress: `0x${string}`,
@@ -48,4 +52,4 @@ const interactWithStorage = async (
4852
const PRIVATE_KEY = 'INSERT_PRIVATE_KEY';
4953
const CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS';
5054

51-
interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);
55+
interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);

smart-contracts/libraries/viem.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ categories: Smart Contracts, Tooling
66

77
# viem
88

9-
--8<-- 'text/smart-contracts/polkaVM-warning.md'
10-
119
## Introduction
1210

1311
[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.
@@ -37,13 +35,13 @@ viem-project/
3735
│ └── interact.ts
3836
├── contracts/
3937
│ └── Storage.sol
38+
├── abis/
39+
│ └── Storage.json
4040
└── artifacts/
41-
├── Storage.json
42-
└── Storage.polkavm
41+
└── Storage.bin
4342
```
4443

45-
## Set Up the Project
46-
44+
## Set Up the Proje
4745
First, create a new folder and initialize your project:
4846

4947
```bash
@@ -54,11 +52,11 @@ npm init -y
5452

5553
## Install Dependencies
5654

57-
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:
55+
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:
5856

5957
```bash
6058
# Install viem and resolc
61-
npm install viem @parity/resolc
59+
npm install viem solc
6260

6361
# Install TypeScript and development dependencies
6462
npm install --save-dev typescript ts-node @types/node
@@ -144,8 +142,6 @@ You can use the following contract to interact with the blockchain. Paste the fo
144142

145143
## Compile the Contract
146144

147-
--8<-- 'text/smart-contracts/code-size.md'
148-
149145
Create a new file at `src/compile.ts` for handling contract compilation:
150146

151147
```typescript title="src/compile.ts"
@@ -158,7 +154,7 @@ To compile your contract:
158154
npm run compile
159155
```
160156

161-
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.
157+
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.
162158

163159
## Deploy the Contract
164160

0 commit comments

Comments
 (0)