From 5af4a3f27f81b12c49a855ead54acaadfe4bcc22 Mon Sep 17 00:00:00 2001 From: Dhaiwat Date: Sat, 5 Oct 2024 14:51:05 +0530 Subject: [PATCH 1/5] implement script deploy pseudocode --- .../src/cli/commands/deploy/deployScripts.ts | 55 ++++++------------- .../fuels/src/cli/commands/deploy/index.ts | 2 +- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/packages/fuels/src/cli/commands/deploy/deployScripts.ts b/packages/fuels/src/cli/commands/deploy/deployScripts.ts index 543332f88cb..4e83105d957 100644 --- a/packages/fuels/src/cli/commands/deploy/deployScripts.ts +++ b/packages/fuels/src/cli/commands/deploy/deployScripts.ts @@ -1,15 +1,11 @@ import type { WalletUnlocked } from '@fuel-ts/account'; +import type { DeployContractOptions } from '@fuel-ts/contract'; +import { ContractFactory } from '@fuel-ts/contract'; +import { hash } from '@fuel-ts/hasher'; import { debug, log } from 'console'; +import { readFileSync } from 'fs'; -import type { ForcToml } from '../../config/forcUtils'; -import { - getClosestForcTomlDir, - getBinaryPath, - getABIPath, - getStorageSlotsPath, - getContractName, - readForcToml, -} from '../../config/forcUtils'; +import { getBinaryPath, getABIPath, getContractName } from '../../config/forcUtils'; import type { FuelsConfig, DeployedScript } from '../../types'; import { createWallet } from './createWallet'; @@ -21,24 +17,21 @@ export async function deployScript( wallet: WalletUnlocked, binaryPath: string, abiPath: string, - storageSlotsPath: string, - scriptPath: string, - tomlContents: ForcToml + configurableConstants?: DeployContractOptions['configurableConstants'] ) { debug(`Deploying script for ABI: ${abiPath}`); - // Implement script deploy - await Promise.resolve({ - wallet, - binaryPath, - abiPath, - storageSlotsPath, - scriptPath, - tomlContents, - }); + const bytecode = readFileSync(binaryPath, 'utf-8'); + const abi = JSON.parse(readFileSync(abiPath, 'utf-8')); + const factory = new ContractFactory(bytecode, abi, wallet); - // TODO: implement me - return 'deployed-blob-id'; + const { waitForResult } = await factory.deployAsBlobTxForScript(configurableConstants); + const { loaderBytecode } = await waitForResult(); + + return { + blobId: hash(bytecode), + loaderBytecode, + }; } /** @@ -55,25 +48,11 @@ export async function deployScripts(config: FuelsConfig) { for (let i = 0; i < scriptsLen; i++) { const scriptPath = config.scripts[i]; - const forcTomlPath = getClosestForcTomlDir(scriptPath); const binaryPath = getBinaryPath(scriptPath, config); const abiPath = getABIPath(scriptPath, config); - const storageSlotsPath = getStorageSlotsPath(scriptPath, config); const projectName = getContractName(scriptPath); - // const scriptName = getContractCamelCase(scriptPath); - const tomlContents = readForcToml(forcTomlPath); - - const blobId = await deployScript( - wallet, - binaryPath, - abiPath, - storageSlotsPath, - scriptPath, - tomlContents - ); - // TODO: implement me - const loaderBytecode = `0x${blobId}`; + const { blobId, loaderBytecode } = await deployScript(wallet, binaryPath, abiPath); debug(`Script deployed: ${projectName} - ${blobId}`); diff --git a/packages/fuels/src/cli/commands/deploy/index.ts b/packages/fuels/src/cli/commands/deploy/index.ts index 4b094de34cb..22268a77cdc 100644 --- a/packages/fuels/src/cli/commands/deploy/index.ts +++ b/packages/fuels/src/cli/commands/deploy/index.ts @@ -24,7 +24,7 @@ export async function deploy(config: FuelsConfig) { * After saving the script files, we need to * re-generate types for them. * - * This time, the script will have to binaries: + * This time, the script will have two binaries: * - the original one * - the loader one (after deploy) * From 1c9e6229055e13f2b38956489ea0081dd1130b3c Mon Sep 17 00:00:00 2001 From: Dhaiwat Date: Sat, 5 Oct 2024 15:17:05 +0530 Subject: [PATCH 2/5] fix --- nodemon.config.json | 3 ++- packages/contract/src/contract-factory.ts | 11 +++++++---- .../fuels/src/cli/commands/deploy/deployScripts.ts | 7 +++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/nodemon.config.json b/nodemon.config.json index b6bdc61c001..fcbc36f5086 100644 --- a/nodemon.config.json +++ b/nodemon.config.json @@ -14,6 +14,7 @@ "**/out/release/**", "apps/demo-typegen/src/contract-types/**", "apps/demo-typegen/src/predicate-types/**", - "apps/demo-typegen/src/script-types/**" + "apps/demo-typegen/src/script-types/**", + "packages/fuels/src/cli/commands/deploy/proxy/types/**" ] } diff --git a/packages/contract/src/contract-factory.ts b/packages/contract/src/contract-factory.ts index ca8f7ea1517..d053cc9c31e 100644 --- a/packages/contract/src/contract-factory.ts +++ b/packages/contract/src/contract-factory.ts @@ -381,11 +381,14 @@ export default class ContractFactory { transactionResult: TransactionResult; loaderBytecode: string; }>; + blobId: string; }> { const account = this.getAccount(); - if (configurableConstants) { - this.setConfigurableConstants(configurableConstants); - } + + // TODO: Implement me + // if (configurableConstants) { + // this.setConfigurableConstants(configurableConstants); + // } // Generate the associated create tx for the loader contract const blobId = hash(this.bytecode); @@ -444,7 +447,7 @@ export default class ContractFactory { return { transactionResult: result, loaderBytecode: hexlify(loaderBytecode) }; }; - return { waitForResult }; + return { waitForResult, blobId }; } /** diff --git a/packages/fuels/src/cli/commands/deploy/deployScripts.ts b/packages/fuels/src/cli/commands/deploy/deployScripts.ts index 4e83105d957..aac27973caa 100644 --- a/packages/fuels/src/cli/commands/deploy/deployScripts.ts +++ b/packages/fuels/src/cli/commands/deploy/deployScripts.ts @@ -1,7 +1,6 @@ import type { WalletUnlocked } from '@fuel-ts/account'; import type { DeployContractOptions } from '@fuel-ts/contract'; import { ContractFactory } from '@fuel-ts/contract'; -import { hash } from '@fuel-ts/hasher'; import { debug, log } from 'console'; import { readFileSync } from 'fs'; @@ -21,15 +20,15 @@ export async function deployScript( ) { debug(`Deploying script for ABI: ${abiPath}`); - const bytecode = readFileSync(binaryPath, 'utf-8'); + const bytecode = readFileSync(binaryPath); const abi = JSON.parse(readFileSync(abiPath, 'utf-8')); const factory = new ContractFactory(bytecode, abi, wallet); - const { waitForResult } = await factory.deployAsBlobTxForScript(configurableConstants); + const { waitForResult, blobId } = await factory.deployAsBlobTxForScript(configurableConstants); const { loaderBytecode } = await waitForResult(); return { - blobId: hash(bytecode), + blobId, loaderBytecode, }; } From 988c1c56539c3086102d866ad10126b1ff9279d6 Mon Sep 17 00:00:00 2001 From: Dhaiwat Date: Sat, 5 Oct 2024 15:21:37 +0530 Subject: [PATCH 3/5] add comment --- packages/contract/src/contract-factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contract/src/contract-factory.ts b/packages/contract/src/contract-factory.ts index d053cc9c31e..608fbb9d82c 100644 --- a/packages/contract/src/contract-factory.ts +++ b/packages/contract/src/contract-factory.ts @@ -385,7 +385,7 @@ export default class ContractFactory { }> { const account = this.getAccount(); - // TODO: Implement me + // TODO: We think that we should not be setting configurable constants here, but rather when we try to call the script. // if (configurableConstants) { // this.setConfigurableConstants(configurableConstants); // } From b9918117f516d18dc02b70654fded5f3346c4066 Mon Sep 17 00:00:00 2001 From: Dhaiwat Date: Sat, 5 Oct 2024 15:27:14 +0530 Subject: [PATCH 4/5] refactor --- packages/contract/src/contract-factory.ts | 3 ++- packages/fuels/src/cli/commands/deploy/deployScripts.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/contract/src/contract-factory.ts b/packages/contract/src/contract-factory.ts index 608fbb9d82c..ae8a4615a12 100644 --- a/packages/contract/src/contract-factory.ts +++ b/packages/contract/src/contract-factory.ts @@ -382,6 +382,7 @@ export default class ContractFactory { loaderBytecode: string; }>; blobId: string; + loaderBytecode: string; }> { const account = this.getAccount(); @@ -447,7 +448,7 @@ export default class ContractFactory { return { transactionResult: result, loaderBytecode: hexlify(loaderBytecode) }; }; - return { waitForResult, blobId }; + return { waitForResult, blobId, loaderBytecode: hexlify(loaderBytecode) }; } /** diff --git a/packages/fuels/src/cli/commands/deploy/deployScripts.ts b/packages/fuels/src/cli/commands/deploy/deployScripts.ts index aac27973caa..8f17edbe32d 100644 --- a/packages/fuels/src/cli/commands/deploy/deployScripts.ts +++ b/packages/fuels/src/cli/commands/deploy/deployScripts.ts @@ -24,8 +24,9 @@ export async function deployScript( const abi = JSON.parse(readFileSync(abiPath, 'utf-8')); const factory = new ContractFactory(bytecode, abi, wallet); - const { waitForResult, blobId } = await factory.deployAsBlobTxForScript(configurableConstants); - const { loaderBytecode } = await waitForResult(); + const { waitForResult, blobId, loaderBytecode } = + await factory.deployAsBlobTxForScript(configurableConstants); + await waitForResult(); return { blobId, From 55de8dfa5125801f4b41fc209f3fcf6e966d9bb4 Mon Sep 17 00:00:00 2001 From: Dhaiwat Date: Sat, 5 Oct 2024 16:07:36 +0530 Subject: [PATCH 5/5] save script files to disk --- packages/contract/src/contract-factory.ts | 10 ++++++++-- .../fuels/src/cli/commands/deploy/deployScripts.ts | 10 ++++++++-- .../fuels/src/cli/commands/deploy/saveScriptFiles.ts | 12 ++++++++++++ packages/fuels/src/cli/config/forcUtils.ts | 5 +++++ packages/fuels/src/cli/types.ts | 3 ++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/packages/contract/src/contract-factory.ts b/packages/contract/src/contract-factory.ts index ae8a4615a12..8dd7141c5a4 100644 --- a/packages/contract/src/contract-factory.ts +++ b/packages/contract/src/contract-factory.ts @@ -382,7 +382,8 @@ export default class ContractFactory { loaderBytecode: string; }>; blobId: string; - loaderBytecode: string; + loaderBytecode: Uint8Array; + loaderBytecodeHexlified: string; }> { const account = this.getAccount(); @@ -448,7 +449,12 @@ export default class ContractFactory { return { transactionResult: result, loaderBytecode: hexlify(loaderBytecode) }; }; - return { waitForResult, blobId, loaderBytecode: hexlify(loaderBytecode) }; + return { + waitForResult, + blobId, + loaderBytecode, + loaderBytecodeHexlified: hexlify(loaderBytecode), + }; } /** diff --git a/packages/fuels/src/cli/commands/deploy/deployScripts.ts b/packages/fuels/src/cli/commands/deploy/deployScripts.ts index 8f17edbe32d..19b5a2ad665 100644 --- a/packages/fuels/src/cli/commands/deploy/deployScripts.ts +++ b/packages/fuels/src/cli/commands/deploy/deployScripts.ts @@ -24,13 +24,14 @@ export async function deployScript( const abi = JSON.parse(readFileSync(abiPath, 'utf-8')); const factory = new ContractFactory(bytecode, abi, wallet); - const { waitForResult, blobId, loaderBytecode } = + const { waitForResult, blobId, loaderBytecode, loaderBytecodeHexlified } = await factory.deployAsBlobTxForScript(configurableConstants); await waitForResult(); return { blobId, loaderBytecode, + loaderBytecodeHexlified, }; } @@ -52,7 +53,11 @@ export async function deployScripts(config: FuelsConfig) { const abiPath = getABIPath(scriptPath, config); const projectName = getContractName(scriptPath); - const { blobId, loaderBytecode } = await deployScript(wallet, binaryPath, abiPath); + const { blobId, loaderBytecode, loaderBytecodeHexlified } = await deployScript( + wallet, + binaryPath, + abiPath + ); debug(`Script deployed: ${projectName} - ${blobId}`); @@ -60,6 +65,7 @@ export async function deployScripts(config: FuelsConfig) { path: scriptPath, blobId, loaderBytecode, + loaderBytecodeHexlified, }); } diff --git a/packages/fuels/src/cli/commands/deploy/saveScriptFiles.ts b/packages/fuels/src/cli/commands/deploy/saveScriptFiles.ts index 4e571e33d67..debad231dd6 100644 --- a/packages/fuels/src/cli/commands/deploy/saveScriptFiles.ts +++ b/packages/fuels/src/cli/commands/deploy/saveScriptFiles.ts @@ -1,3 +1,6 @@ +import { writeFileSync } from 'fs'; + +import { getScriptName } from '../../config/forcUtils'; import type { DeployedScript, FuelsConfig } from '../../types'; export async function saveScriptFiles(scripts: DeployedScript[], _config: FuelsConfig) { @@ -9,6 +12,15 @@ export async function saveScriptFiles(scripts: DeployedScript[], _config: FuelsC * - Hash file for scripts * - Root file for predicates */ + const scriptName = getScriptName(path); + const buildMode = _config.buildMode; + + const scriptBlobIdPath = `${path}/out/${buildMode}/${scriptName}-deployed-bin-hash`; + writeFileSync(scriptBlobIdPath, blobId); + + const loaderBytecodePath = `${path}/out/${buildMode}/${scriptName}-deployed.bin`; + writeFileSync(loaderBytecodePath, loaderBytecode); + await Promise.resolve({ path, blobId, loaderBytecode }); } } diff --git a/packages/fuels/src/cli/config/forcUtils.ts b/packages/fuels/src/cli/config/forcUtils.ts index 9a5bde4d961..bfcb023b347 100644 --- a/packages/fuels/src/cli/config/forcUtils.ts +++ b/packages/fuels/src/cli/config/forcUtils.ts @@ -119,6 +119,11 @@ export function getContractName(contractPath: string) { return project.name; } +export function getScriptName(scriptPath: string) { + const { project } = readForcToml(scriptPath); + return project.name; +} + export function getContractCamelCase(contractPath: string) { const projectName = getContractName(contractPath); return camelCase(projectName); diff --git a/packages/fuels/src/cli/types.ts b/packages/fuels/src/cli/types.ts index 65c7dccb853..6e7192a1ca8 100644 --- a/packages/fuels/src/cli/types.ts +++ b/packages/fuels/src/cli/types.ts @@ -43,7 +43,8 @@ export type DeployedContract = { export type DeployedScript = { path: string; blobId: string; - loaderBytecode: string; + loaderBytecode: Uint8Array; + loaderBytecodeHexlified: string; }; export type ContractDeployOptions = {