Reference for incomplete introductory tasks Installation Introduction
Vanity Addresses is a standalone CTF task in Cairo, similar to CREATE2 in Solidity. It deploys contract addresses with specific prefixes and suffixes by modifying the salt, and then uses this contract to call the target contract. Specifically, it generates a contract address with the prefix 0x04515 and calls the find_oasis function below.
fn find_oasis(ref self: ContractState) {
let caller = get_caller_address();
assert(is_oasis(caller), 'NOT_OASIS');
self.is_oasis_found.write(true);
}
Deploy the hack contract#
Since all wallets on StarkNet are contracts, you can deploy a standard AA wallet account for this question, or write a separate contract. Either way, you need to understand how Starknet contracts are generated. I chose to write a hack contract: AA -> hack contract -> find_oasis.
In Cairo, to implement contract A calling contract B, you need to use DispatcherTrait, which can be referred to in test_contract.cairo in corelib. This hack contract is relatively simple.
After writing it, deploy the contract. I used starkli recommended in the StarkNet Book. If you are not familiar with the process, you can refer to the detailed tutorial in metaschool. The general process is scarb build -> starkli declare -> starkli deploy.
Use salt=0 to deploy hack.cairo and verify if the subsequent calculation is correct. The command is
starkli deploy [classHash] --salt 0 --network=goerli-1
classhash is generated by starkli declare.
The last line of the text that appears after deployment is the contract address. Next, you need to use the calculation function of the contract in any language's SDK to verify if the address is correct when salt=0. If it is correct, write a loop to find the target salt.
Calculate the contract address that meets the conditions#
The contract address in StarkNet is calculated using pedersen, as described in the StarkNet official documentation: contract_address := pedersen( “STARKNET_CONTRACT_ADDRESS”, deployer_address, salt, class_hash, constructor_calldata_hash)
In the Cairo Star Telegram group, I found two Rust libraries that can calculate the address:
Option 1: starkli lab https://github.com/xJonathanLEI/starkli/blob/e4d23076b67c05fccc2d7bda069561daaa1fde06/src/subcommands/lab/mine_udc_salt.rs#L37
Option 2: @th0rgal0 's vanity address in their github https://github.com/Th0rgal/vanity-starknet
After trying, I found that I couldn't use starkli lab, and vanity-starknet could only generate addresses with the prefix 0x0000.... So I had to write my own SDK. I used Starknet.js.
After observing the transaction of the previously deployed contract, starkli deploy
actually calls the UniversalDeployer(UDC) contract, which is responsible for instantiating the classhash into a new contract. The parameters required are classHash, salt, calldata, and calldata _len and unique should be automatically handled by starkli. The hack contract I deployed has no constructor parameters, so calldata is an empty array.
It is easy to find an example in the starknet.js library that calculates the address.
Create a local Node.js project, install dependencies such as starknet, jest, and typescript, and write a test based on the example. I found that the address calculated when salt=0 did not match.
So I searched for other test cases in the library and found that when unique=1, the salt used for calculation needs to be hash(deployer, salt), where deployerAddress is UDC, in order to match starkli.
The address calculated by the code starts with 0x593c
, while the deployed address is 0x0593c
. When comparing, just remove one 0. That is, the comparison should be "0x4515"
instead of "0x04515"
.
I calculated the required value when the salt was close to 40,000, without any optimization or multithreading, and it took more than 10 minutes.
After changing the salt, deploy the new contract (the salt needs to be converted to hex before passing it), and get the Hack contract address 0x04515bf8e9d0c....
Use starkli invoke
to call the hack method locally to complete the task.
Update: After receiving a response from the author of starkli,
starkli lab mine-udc-salt
can obtain results in a few seconds. Please refer to https://github.com/xJonathanLEI/starkli/issues/45#issuecomment-1810015094 for details.
Summary#
Apart from the introductory tasks, this is the first question in CTF. It is not difficult, but it requires familiarity with StarkNet-related content. Writing contracts to solve problems is a common operation in CTF, and NG's questions are no exception, so it is necessary to be familiar with the invocation between contracts. In addition, this question also introduces the use of SDK, and some operations require off-chain calculations.