Skip to content

Commit 9af8561

Browse files
kumaryash90jnsdls
andauthored
[SDK] ZkSync deterministic deployments (#2592)
Signed-off-by: Yash <72552910+kumaryash90@users.noreply.github.com> Co-authored-by: Jonas Daniels <jonas.daniels@outlook.com>
1 parent 2e12c76 commit 9af8561

22 files changed

+826
-70
lines changed

.changeset/rotten-spoons-trade.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@thirdweb-dev/sdk": patch
3+
---
4+
5+
ZkSync deterministic deployments

legacy_packages/sdk/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@
109109
"rimraf": "5.0.5",
110110
"typedoc-gen": "workspace:*",
111111
"typescript": "5.4.3",
112-
"zksync-web3": "^0.14.4"
112+
"zksync-ethers": "^5.6.0"
113113
},
114114
"peerDependencies": {
115115
"@aws-sdk/client-secrets-manager": "^3.215.0",
116116
"ethers": "^5",
117117
"ethers-aws-kms-signer": "^1.3.2",
118-
"zksync-web3": "^0.14.3"
118+
"zksync-ethers": "^5.6.0"
119119
},
120120
"peerDependenciesMeta": {
121121
"@aws-sdk/client-secrets-manager": {
@@ -124,7 +124,7 @@
124124
"ethers-aws-kms-signer": {
125125
"optional": true
126126
},
127-
"zksync-web3": {
127+
"zksync-ethers": {
128128
"optional": true
129129
}
130130
},

legacy_packages/sdk/src/evm/common/any-evm-utils/fetchAndCacheDeployMetadata.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
FullPublishMetadata,
88
PreDeployMetadataFetched,
99
} from "../../schema/contracts/custom";
10+
import { CompilerOptions } from "../../types/compiler/compiler-options";
1011

1112
type DeployAndPublishMetadata = {
1213
compilerMetadata: PreDeployMetadataFetched;
@@ -22,14 +23,24 @@ const deployMetadataCache =
2223
export async function fetchAndCacheDeployMetadata(
2324
publishMetadataUri: string,
2425
storage: ThirdwebStorage,
26+
compilerOptions?: CompilerOptions,
2527
): Promise<DeployMetadata> {
26-
const cached = deployMetadataCache.get(publishMetadataUri);
28+
const compiler = compilerOptions
29+
? `${compilerOptions.compilerType}_${
30+
compilerOptions.compilerVersion || ""
31+
}_${compilerOptions.evmVersion || ""}
32+
`
33+
: "default";
34+
const cacheKey = `${compiler}_${publishMetadataUri}`;
35+
36+
const cached = deployMetadataCache.get(cacheKey);
2737
if (cached) {
2838
return cached;
2939
}
3040
const compilerMetadata = await fetchPreDeployMetadata(
3141
publishMetadataUri,
3242
storage,
43+
compilerOptions,
3344
);
3445
let extendedMetadata;
3546
try {
@@ -44,6 +55,6 @@ export async function fetchAndCacheDeployMetadata(
4455
compilerMetadata,
4556
extendedMetadata,
4657
};
47-
deployMetadataCache.put(publishMetadataUri, data);
58+
deployMetadataCache.put(cacheKey, data);
4859
return data;
4960
}

legacy_packages/sdk/src/evm/common/feature-detection/fetchPreDeployMetadata.ts

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
import { fetchContractMetadata } from "../fetchContractMetadata";
66
import { ThirdwebStorage } from "@thirdweb-dev/storage";
77
import { fetchRawPredeployMetadata } from "./fetchRawPredeployMetadata";
8+
import { CompilerOptions } from "../../types/compiler/compiler-options";
9+
import invariant from "tiny-invariant";
810

911
/**
1012
* Fetch the metadata coming from CLI, this is before deploying or releasing the contract.
@@ -15,15 +17,63 @@ import { fetchRawPredeployMetadata } from "./fetchRawPredeployMetadata";
1517
export async function fetchPreDeployMetadata(
1618
publishMetadataUri: string,
1719
storage: ThirdwebStorage,
20+
compilerOptions?: CompilerOptions,
1821
): Promise<PreDeployMetadataFetched> {
1922
const rawMeta = await fetchRawPredeployMetadata(publishMetadataUri, storage);
20-
const deployBytecode = await (
21-
await storage.download(rawMeta.bytecodeUri)
22-
).text();
23-
const parsedMeta = await fetchContractMetadata(rawMeta.metadataUri, storage);
23+
let bytecodeUri;
24+
let metadataUri;
25+
26+
// TODO: Add an invariant, throw if no compilers in rawMeta in case compilerOptions are provided.
27+
// Keeping it this way until all contracts are republished with new metadata.
28+
if (compilerOptions && rawMeta.compilers) {
29+
let metadata;
30+
switch (compilerOptions.compilerType) {
31+
case "solc": {
32+
if (compilerOptions.compilerVersion) {
33+
metadata = rawMeta.compilers.solc?.find(
34+
(m) =>
35+
m.compilerVersion === compilerOptions.compilerVersion &&
36+
m.evmVersion === compilerOptions.evmVersion,
37+
);
38+
} else if (rawMeta.compilers.solc) {
39+
const len = rawMeta.compilers.solc.length;
40+
metadata = rawMeta.compilers.solc[len - 1];
41+
}
42+
break;
43+
}
44+
case "zksolc": {
45+
if (compilerOptions.compilerVersion) {
46+
metadata = rawMeta.compilers.zksolc?.find(
47+
(m) =>
48+
m.compilerVersion === compilerOptions.compilerVersion &&
49+
m.evmVersion === compilerOptions.evmVersion,
50+
);
51+
} else if (rawMeta.compilers.zksolc) {
52+
const len = rawMeta.compilers.zksolc.length;
53+
metadata = rawMeta.compilers.zksolc[len - 1];
54+
}
55+
break;
56+
}
57+
}
58+
invariant(metadata, "Compiler or EVM version not found");
59+
60+
bytecodeUri = metadata.bytecodeUri;
61+
metadataUri = metadata.metadataUri;
62+
} else {
63+
bytecodeUri = rawMeta.bytecodeUri;
64+
metadataUri = rawMeta.metadataUri;
65+
}
66+
67+
const [deployBytecode, parsedMeta] = await Promise.all([
68+
storage.download(bytecodeUri),
69+
fetchContractMetadata(metadataUri, storage),
70+
]);
71+
2472
return PreDeployMetadataFetchedSchema.parse({
2573
...rawMeta,
2674
...parsedMeta,
27-
bytecode: deployBytecode,
75+
bytecode: await deployBytecode.text(),
76+
fetchedMetadataUri: metadataUri,
77+
fetchedBytecodeUri: bytecodeUri,
2878
});
2979
}

legacy_packages/sdk/src/evm/schema/contracts/custom.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ export const CompilerMetadataFetchedSchema = /* @__PURE__ */ (() =>
377377
export const PreDeployMetadataFetchedSchema = /* @__PURE__ */ (() =>
378378
PreDeployMetadata.merge(CompilerMetadataFetchedSchema).extend({
379379
bytecode: z.string(),
380+
fetchedMetadataUri: z.string(),
381+
fetchedBytecodeUri: z.string(),
380382
}))();
381383

382384
export type PreDeployMetadataFetched = z.infer<
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { CompilerType } from "../../schema/contracts/custom";
2+
3+
export type CompilerOptions = {
4+
compilerType: CompilerType;
5+
compilerVersion?: string;
6+
evmVersion?: string;
7+
};

legacy_packages/sdk/src/evm/types/deploy/deploy-options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import {
33
PreDeployMetadataFetched,
44
} from "../../schema/contracts/custom";
55
import { DeployedContractType } from "../any-evm/deploy-data";
6+
import { CompilerOptions } from "../compiler/compiler-options";
67

78
export type DeployOptions = {
89
forceDirectDeploy?: boolean;
910
saltForProxyDeploy?: string;
11+
compilerOptions?: CompilerOptions;
1012
notifier?: (
1113
status: "deploying" | "deployed",
1214
contractType: DeployedContractType | string,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// import type { DeploymentPreset } from "../../types/any-evm/deploy-data";
2+
3+
export const caches = {
4+
deploymentPresets: {} as Record<string, any>,
5+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const SINGLETON_FACTORY = "0xa51baf6a9c0ef5Db8C1898d5aDD92Bf3227d6088";
2+
export const KNOWN_CODES_STORAGE = "0x0000000000000000000000000000000000008004";
3+
export const PUBLISHED_PRIVATE_KEY = "";
4+
export const PUBLISHED_SIGNER = "0xf472c04EFF6F76eFe570723a55F730126281421a";
5+
6+
export const getMarkerAbi = [
7+
"function getMarker(bytes32) public view returns (uint256)",
8+
];
9+
10+
export const singletonDeployAbi = [
11+
"function deploy(bytes32,bytes32,bytes) external payable",
12+
];

legacy_packages/sdk/src/evm/zksync/constants/addresses.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/* eslint-disable no-useless-computed-key */
22

3+
import { constants } from "ethers";
4+
import { ChainId } from "../../constants/chains/ChainId";
5+
import { NativeToken } from "../../types/currency";
6+
37
const AddressZero = "0x0000000000000000000000000000000000000000";
48

59
/**
@@ -25,6 +29,39 @@ export const CONTRACT_ADDRESSES: Record<
2529
},
2630
};
2731

32+
/**
33+
* @public
34+
*/
35+
export const NATIVE_TOKEN_ADDRESS =
36+
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
37+
38+
/**
39+
* @public
40+
*/
41+
export const NATIVE_TOKENS: Record<number, NativeToken> = /* @__PURE__ */ {
42+
// eslint-disable-next-line no-useless-computed-key
43+
[280]: {
44+
name: "zkSync Era Testnet",
45+
symbol: "ETH",
46+
decimals: 18,
47+
wrapped: {
48+
address: "0x20b28B1e4665FFf290650586ad76E977EAb90c5D",
49+
name: "Wrapped Ether",
50+
symbol: "WETH",
51+
},
52+
},
53+
[324]: {
54+
name: "zkSync Era Mainnet",
55+
symbol: "ETH",
56+
decimals: 18,
57+
wrapped: {
58+
address: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91",
59+
name: "Wrapped Ether",
60+
symbol: "WETH",
61+
},
62+
},
63+
};
64+
2865
export const blockExplorerApiMap: Record<number, string> = {
2966
[324]: "https://block-explorer-api.mainnet.zksync.io/api",
3067
[280]: "https://block-explorer-api.testnets.zksync.dev/api",
@@ -123,3 +160,23 @@ export function zkGetDefaultTrustedForwarders(
123160
// it doesn’t need a forwarder
124161
return [];
125162
}
163+
164+
/**
165+
* Returns the native token for a given chain
166+
* @param chainId - the chain id
167+
* @public
168+
*/
169+
export function getZkNativeTokenByChainId(chainId: ChainId): NativeToken {
170+
return (
171+
NATIVE_TOKENS[chainId] || {
172+
name: "Ether",
173+
symbol: "ETH",
174+
decimals: 18,
175+
wrapped: {
176+
address: constants.AddressZero,
177+
name: "Wrapped Ether",
178+
symbol: "WETH",
179+
},
180+
}
181+
);
182+
}

0 commit comments

Comments
 (0)