xChar

ng4-start

没有完成入门任务的参考安装入门

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);
}

部署 hack 合约

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。

UDC

很容易在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的使用,部分操作需要链下计算。

ng4-summary

Loading comments...