-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhanced Input Validation and Code Refactoring for Starknet Address S…
…cript (#1553) **Enhanced input validation and refactored address computation logic in Starknet address pre-computation script** --- ### Time spent on this PR: **0.5 days** --- ### Pull request type: - [x] Code style update (formatting, renaming) - [x] Refactoring (no functional changes, no API changes) --- ### What is the current behavior? The original code does not validate hexadecimal inputs for `classHash`, `salt`, and `deployerAddress` fields, which could lead to runtime errors if users provide values in an incorrect format. Additionally, the function and variable names do not fully conform to consistent camelCase styling. --- ### What is the new behavior? - **Input Validation**: Implemented validation for hexadecimal input values using regular expressions to ensure the correct format for `classHash`, `salt`, and `deployerAddress`. - **Improved Naming Conventions**: Updated function and variable names to camelCase for readability and consistency. - **Error Messages**: Added clearer error messages to guide users when input format is incorrect. --- ### Files Changed: 1. **Script File**: - Added input validation to check for hexadecimal format in `classHash`, `salt`, and `deployerAddress`. - Refactored variable and function names to camelCase style. - Improved console output for readability and ease of debugging. 2. **README Documentation**: - Updated usage instructions to reflect new validation requirements. - Provided example inputs that adhere to expected formats. 3. **Environment Configuration (if applicable)**: - No functional changes but updated comments to specify input requirements, particularly around the format for private keys and addresses. <!-- Reviewable:start --> - - - This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/kkrt-labs/kakarot/1553) <!-- Reviewable:end -->
- Loading branch information
Showing
3 changed files
with
79 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,160 +1,132 @@ | ||
// This js script helps in creating unsigned and signed RLP data for tests | ||
|
||
import { ethers, toBeArray } from "ethers"; | ||
import dotevn from "dotenv"; | ||
import { ethers } from "ethers"; | ||
import dotenv from "dotenv"; | ||
import readline from "readline"; | ||
import { readFileSync } from "fs"; | ||
import { readFileSync, existsSync } from "fs"; | ||
|
||
dotevn.config(); | ||
dotenv.config(); | ||
|
||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
|
||
const question = (query: string): Promise<string> => { | ||
return new Promise((resolve, reject) => { | ||
return new Promise((resolve) => { | ||
rl.question(query, (answer) => { | ||
resolve(answer); | ||
}); | ||
}); | ||
}; | ||
|
||
const main = async () => { | ||
const { Transaction, Wallet } = ethers; | ||
const { decodeRlp, getBytes } = ethers; | ||
const { Transaction, Wallet, keccak256, RLP } = ethers; | ||
|
||
if (!process.env.PRIVATE_KEY_RLP_SCRIPT) { | ||
console.log( | ||
"missing private key in environment, please provide PRIVATE_KEY_RLP_SCRIPT environment variable", | ||
console.error( | ||
"Missing private key in environment. Please provide PRIVATE_KEY_RLP_SCRIPT in .env", | ||
); | ||
process.exit(1); | ||
} | ||
|
||
const wallet = new Wallet(process.env.PRIVATE_KEY_RLP_SCRIPT); | ||
console.log("address of the wallet is", wallet.address); | ||
console.log("Address of the wallet:", wallet.address); | ||
|
||
let tx_type = parseInt( | ||
await question( | ||
"enter transaction, 0: legacy, 1: 2930, 2:1559, 3: inc_counter, 4: y_parity_false eip1559: ", | ||
"Enter transaction type (0: legacy, 1: 2930, 2: 1559, 3: inc_counter, 4: y_parity_false eip1559): ", | ||
), | ||
); | ||
|
||
// for type 0 and type 1 | ||
let tx; | ||
|
||
let txFilePath: string; | ||
switch (tx_type) { | ||
case 0: | ||
tx = JSON.parse( | ||
readFileSync("./scripts/data/input_legacy_tx.json", "utf-8"), | ||
); | ||
txFilePath = "./scripts/data/input_legacy_tx.json"; | ||
break; | ||
case 1: | ||
tx = JSON.parse( | ||
readFileSync("./scripts/data/input_access_list_tx.json", "utf-8"), | ||
); | ||
txFilePath = "./scripts/data/input_access_list_tx.json"; | ||
break; | ||
case 2: | ||
tx = JSON.parse( | ||
readFileSync("./scripts/data/input_fee_tx.json", "utf-8"), | ||
); | ||
txFilePath = "./scripts/data/input_fee_tx.json"; | ||
break; | ||
case 3: | ||
tx_type = 1; | ||
tx = JSON.parse( | ||
readFileSync( | ||
"./scripts/data/input_eip_2930_counter_inc_tx.json", | ||
"utf-8", | ||
), | ||
); | ||
txFilePath = "./scripts/data/input_eip_2930_counter_inc_tx.json"; | ||
break; | ||
case 4: | ||
tx_type = 2; | ||
tx = JSON.parse( | ||
readFileSync( | ||
"./scripts/data/input_eip1559_y_parity_false.json", | ||
"utf-8", | ||
), | ||
); | ||
txFilePath = "./scripts/data/input_eip1559_y_parity_false.json"; | ||
break; | ||
default: | ||
throw new Error( | ||
`transaction type ${tx_type} isn't a valid transaction type`, | ||
); | ||
throw new Error(`Invalid transaction type: ${tx_type}`); | ||
} | ||
|
||
if (!existsSync(txFilePath)) { | ||
throw new Error(`Transaction file not found: ${txFilePath}`); | ||
} | ||
|
||
const tx = JSON.parse(readFileSync(txFilePath, "utf-8")); | ||
const transaction = Transaction.from(tx); | ||
transaction.type = tx_type; | ||
|
||
let signed_tx = await wallet.signTransaction(transaction); | ||
|
||
console.log("unsigned serialized tx ----->", transaction.unsignedSerialized); | ||
console.log("unsigned transaction hash", transaction.hash); | ||
|
||
// const bytes = getBytes(signedTX); | ||
const bytes = getBytes(transaction.unsignedSerialized); | ||
|
||
console.log("unsigned RLP encoded bytes for the transaction: "); | ||
const signed_tx = await wallet.signTransaction(transaction); | ||
console.log("Unsigned serialized tx:", transaction.unsignedSerialized); | ||
console.log("Unsigned transaction hash:", transaction.hash); | ||
|
||
// this prints unsigned RLP encoded bytes of the transaction | ||
bytes.forEach((v) => { | ||
console.log(v, ","); | ||
}); | ||
console.log("\n"); | ||
|
||
let bytes2 = Uint8Array.from(transaction.type == 0 ? bytes : bytes.slice(1)); | ||
|
||
let decodedRlp = decodeRlp(bytes2); | ||
console.log("decoded RLP is for unsigned transaction ....\n", decodedRlp); | ||
|
||
let bytes3 = getBytes(signed_tx); | ||
const unsignedBytes = ethers.getBytes(transaction.unsignedSerialized); | ||
console.log("Unsigned RLP encoded bytes:"); | ||
console.log(unsignedBytes.map((v) => `${v},`).join(" ")); | ||
|
||
console.log("signed RLP encoded bytes for the transaction: "); | ||
const unsignedBytes2 = Uint8Array.from( | ||
transaction.type === 0 ? unsignedBytes : unsignedBytes.slice(1), | ||
); | ||
let decodedRlp = RLP.decode(unsignedBytes2); | ||
console.log("Decoded RLP for unsigned transaction:\n", decodedRlp); | ||
|
||
// this prints unsigned RLP encoded bytes of the transaction | ||
bytes3.forEach((v) => { | ||
console.log(v, ","); | ||
}); | ||
console.log("\n"); | ||
const signedBytes = ethers.getBytes(signed_tx); | ||
console.log("Signed RLP encoded bytes:"); | ||
console.log(signedBytes.map((v) => `${v},`).join(" ")); | ||
|
||
bytes3 = Uint8Array.from(transaction.type == 0 ? bytes3 : bytes3.slice(1)); | ||
decodedRlp = decodeRlp(bytes3); | ||
console.log("signed decoded RLP for signed transaction ....\n", decodedRlp); | ||
const signedBytes2 = Uint8Array.from( | ||
transaction.type === 0 ? signedBytes : signedBytes.slice(1), | ||
); | ||
decodedRlp = RLP.decode(signedBytes2); | ||
console.log("Signed decoded RLP for signed transaction:\n", decodedRlp); | ||
|
||
const hash = ethers.keccak256(bytes); | ||
console.log("the hash over which the signature was made:", hash); | ||
const hash = keccak256(unsignedBytes); | ||
console.log("Hash over which the signature was made:", hash); | ||
|
||
console.log("signature details: "); | ||
console.log("Signature details:"); | ||
const v = decodedRlp[decodedRlp.length - 3]; | ||
const r = decodedRlp[decodedRlp.length - 2]; | ||
const s = decodedRlp[decodedRlp.length - 1]; | ||
|
||
const y_parity = | ||
tx_type == 0 | ||
tx_type === 0 | ||
? get_y_parity(BigInt(v), BigInt(tx.chainId)) | ||
: parseInt(v, 16) == 1; | ||
console.log("r: ", r); | ||
console.log("s: ", s); | ||
if (tx_type == 0) { | ||
console.log("v: ", v); | ||
: parseInt(v, 16) === 1; | ||
console.log("r:", r); | ||
console.log("s:", s); | ||
if (tx_type === 0) { | ||
console.log("v:", v); | ||
} | ||
console.log("y parity: ", y_parity); | ||
console.log("y parity:", y_parity); | ||
|
||
rl.close(); | ||
process.exit(0); | ||
}; | ||
|
||
const get_y_parity = (v: bigint, chain_id: bigint): boolean => { | ||
let y_parity = v - (chain_id * BigInt(2) + BigInt(35)); | ||
if (y_parity == BigInt(0) || y_parity == BigInt(1)) { | ||
return y_parity == BigInt(1); | ||
if (y_parity === BigInt(0) || y_parity === BigInt(1)) { | ||
return y_parity === BigInt(1); | ||
} | ||
|
||
y_parity = v - (chain_id * BigInt(2) + BigInt(36)); | ||
if (y_parity == BigInt(0) || y_parity == BigInt(1)) { | ||
return y_parity == BigInt(1); | ||
if (y_parity === BigInt(0) || y_parity === BigInt(1)) { | ||
return y_parity === BigInt(1); | ||
} | ||
|
||
throw new Error("invalid v value"); | ||
throw new Error("Invalid v value"); | ||
}; | ||
|
||
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters