没有完成入门任务的参考安装入门
Vanity Addresses 是 Cairo 的 CTF 独立任务,类似Solidity中的CREATE2,通过修改salt来部署特定前缀后缀的合约地址,再用这个合约去调用目标合约。具体是生成一个开头是0x04515的合约地址,去调用下方的find_oasis函数。
fn find_oasis(ref self: ContractState) {
let caller = get_caller_address();
assert(is_oasis(caller), 'NOT_OASIS');
self.is_oasis_found.write(true);
}
StarkNet 上全是合约钱包,所以这题可以部署标准的 AA钱包账户,也可以单独再写一个合约,不管哪种方式都需要了解 Starknet 的合约是怎么生成的。我采取的方式是编写 hack 合约: AA -> hack合约 -> find_oasis。
Cairo 中要实现 A合约调用 B 合约,需要用 DispatcherTrait,可参考corelib里的 test_contract.cairo。这个 hack 合约比较简单。
写完后进行合约部署,我采用 StarkNet Book 中推荐的 starkli,如果不清楚流程,metaschool 里有详细教学。大致流程是scarb build -> starkli declare -> starkli deploy。
需要用salt=0去部署 hack.cairo,验证后面计算是否正确,命令是
starkli deploy [classHash] --salt 0 --network=goerli-1
classhash 是 starkli declare 生成的。
deploy后出现的文字最后一行就是合约地址。接下来需要用任意语言的SDK中计算合约的函数去验证salt=0时地址是否正确,如果正确就写个循环去找目标salt。
StarkNet中的合约地址是通过 pedersen计算得出的,具体见StarkNet官方文档:contract_address := pedersen( “STARKNET_CONTRACT_ADDRESS”, deployer_address, salt, class_hash, constructor_calldata_hash)
在 Cario Star 电报群搜索群里,发现2个rust库可以计算地址:
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
尝试后发现 starkli lab 不会用,vanity-starknet 只能生成前缀 0x0000... 的地址,所以得找个SDK自己写。我采用的是 Starknet.js。
观察之前部署合约的transaction,starkli deploy
其实是调用了 UniversalDeployer(UDC) 合约,这个合约统一负责把classhash实例化成新合约。参数需要 classHash, salt, calldata,而calldata _len和unique应该是starkli自动处理的。我部署的Hack合约没有构造参数,所以calldata是空array。
很容易在starknet.js的库里搜到计算地址的 例子。
本地建一个nodejs项目,安装starknet、jest、typescript等依赖后,按例子写了测试,发现salt=0的地址对不上。
于是又在库里搜其他测试用例,发现当unique=1时,计算用的salt需要是 hash(deployer, salt),deployerAddress是 UDC,才和 starkli 能对上。
代码计算出的地址开头是 0x593c
,而部署的是0x0593c
,对比时直接去掉一个0就行了。也就是需要对比的是"0x4515"
而不是"0x04515"
。
我在 salt 接近4万的时候计算到了需要的值,没做任何优化和多线程,用了10多分钟。
更换 salt 后部署的新合约(salt要转为hex再传),得到Hack合约地址 0x04515bf8e9d0c....
在本地用 starkli invoke
调用 hack 方法后完成任务。
更新:得到 starkli 作者的回答后,
starkli lab mine-udc-salt
能在几秒内得到结果,具体见 https://github.com/xJonathanLEI/starkli/issues/45#issuecomment-1810015094
除去入门,这是 CTF 的第一题,不算难,但需要熟悉 StarkNet 相关内容。编写合约去解题是CTF的常规操作,NG的题目也不例外,所以需要熟悉合约间的调用。另外本题也开始接触到了SDK的使用,部分操作需要链下计算。