├── .gitignore ├── LICENSE ├── README.md ├── abi ├── dop.json ├── erc20.json ├── mintAll.json └── tpl.json ├── config.py ├── example.py ├── main.py ├── make.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.log 3 | venv 4 | test.* 5 | __pycache__/ 6 | main2.py 7 | !requirements.txt -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 guo shawn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

DopTestnet

2 |

已于24/02/29 22:00:00 结束!此项目已无法运行

3 |

测试网任务 Testnet

4 |

5 | 6 |

7 | 8 | ## ⚡ 安装 9 | + 安装 [python](https://www.google.com/search?client=opera&q=how+install+python) 10 | + [下载项目](https://sites.northwestern.edu/researchcomputing/resources/downloading-from-github) 并解压 11 | + 安装依赖包: 12 | ```python 13 | pip install -r requirements.txt 14 | ``` 15 | 16 | ## 💻 准备 17 | + [nstproxy国外住宅代理购买](https://app.nstproxy.com/register?i=EM00Pe) 18 | + [推特账号购买](https://hdd.cm) [@fooyao](https://twitter.com/fooyao) 19 | 20 | **充值后,创建频道,复制频道名和密码,分别写入config.py的```nstproxy_Channel```,```nstproxy_Password```中** 21 | 22 | **购买后的推特账号,放在项目的tw.txt文件内** 23 | 24 | ``` 25 | 首次执行 python make.py, 仅需执行一次 26 | 跑任务 python main.py 自动检测哪些任务已完成,完成的会跳过,可重复执行 27 | ``` 28 | ```python 29 | # main.py 部分说明 30 | async def main(file_name, code, loop_invite): 31 | global g_fail, g_success 32 | with open(file_name, 'r', encoding='UTF-8') as f, open('dropcoin_success.txt', 'a') as s, open('dropcoin_error.txt', 'a') as e, open('my.txt', 'a') as z: # eth----auth_token 33 | lines = f.readlines() 34 | for twitter in lines: 35 | _auth_tokn = '' 36 | t_list = twitter.split('----') 37 | for tw in t_list: 38 | if len(tw) == 40 and all(c in '0123456789abcdef' for c in tw): 39 | _auth_tokn = tw 40 | break 41 | if not _auth_tokn: 42 | continue 43 | pk = t_list[1] 44 | 45 | _nstproxy = '' 46 | 47 | _nstproxy = f"http://{nstproxy_Channel}-residential-country_ANY-r_5m-s_BsqLCLkiVu:{nstproxy_Password}@gw-us.nstproxy.com:24125" 48 | # _res = httpx.get('https://ip.useragentinfo.com/json', proxies={'all://': _nstproxy}) 49 | # print(_res.text) 50 | dop = Dop(pk=pk, referral=code, auth_token=_auth_tokn, proxy=_nstproxy) 51 | 52 | try: 53 | my_code = await dop.get_my_code() 54 | mail = await dop.get_my_email() 55 | if loop_invite: 56 | code = my_code 57 | log_str = f'{dop.account.address}----{pk}----{mail}----{tw}----{my_code}\n' 58 | res, k = await dop.make_task() 59 | 60 | if res: 61 | dop.add_log(f'任务1-7完成成功') 62 | s.write(log_str) 63 | else: 64 | dop.add_log(f'任务{k}失败') 65 | e.write(log_str) 66 | except Exception as m: 67 | print(f'{m}') 68 | 69 | if __name__ == '__main__': 70 | _referral = 'ZdbWvzM' # 大号邀请码 71 | _file_name = 'tw_bind.txt' # 执行make.py重新生成的文件 72 | _loop_invite = True # 默认滚动邀请,一个号跑完任务,无论是否一次成功,自动变成邀请人,邀请下一个号做任务,False则只用大号邀请码作为邀请人 73 | 74 | asyncio.run(main(_file_name, _referral, _loop_invite)) 75 | ``` 76 | 77 | ## 其他 ✔️ 78 | **推特绑定接口经常出错,可能是账号(比如推特注册时间限制)或者代理问题** 79 | 80 | ## 有问题加群 81 | 82 | 83 | 84 | ## 📧 Contacts 85 | + 推特 - [@shawngmy](https://twitter.com/shawngmy) 86 | + tks for following,if u want get more info 87 | -------------------------------------------------------------------------------- /abi/dop.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "name_", 7 | "type": "string" 8 | }, 9 | { 10 | "internalType": "string", 11 | "name": "symbol_", 12 | "type": "string" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "inputs": [ 20 | { 21 | "internalType": "address", 22 | "name": "spender", 23 | "type": "address" 24 | }, 25 | { 26 | "internalType": "uint256", 27 | "name": "currentAllowance", 28 | "type": "uint256" 29 | }, 30 | { 31 | "internalType": "uint256", 32 | "name": "requestedDecrease", 33 | "type": "uint256" 34 | } 35 | ], 36 | "name": "ERC20FailedDecreaseAllowance", 37 | "type": "error" 38 | }, 39 | { 40 | "inputs": [ 41 | { 42 | "internalType": "address", 43 | "name": "spender", 44 | "type": "address" 45 | }, 46 | { 47 | "internalType": "uint256", 48 | "name": "allowance", 49 | "type": "uint256" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "needed", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "ERC20InsufficientAllowance", 58 | "type": "error" 59 | }, 60 | { 61 | "inputs": [ 62 | { 63 | "internalType": "address", 64 | "name": "sender", 65 | "type": "address" 66 | }, 67 | { 68 | "internalType": "uint256", 69 | "name": "balance", 70 | "type": "uint256" 71 | }, 72 | { 73 | "internalType": "uint256", 74 | "name": "needed", 75 | "type": "uint256" 76 | } 77 | ], 78 | "name": "ERC20InsufficientBalance", 79 | "type": "error" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "address", 85 | "name": "approver", 86 | "type": "address" 87 | } 88 | ], 89 | "name": "ERC20InvalidApprover", 90 | "type": "error" 91 | }, 92 | { 93 | "inputs": [ 94 | { 95 | "internalType": "address", 96 | "name": "receiver", 97 | "type": "address" 98 | } 99 | ], 100 | "name": "ERC20InvalidReceiver", 101 | "type": "error" 102 | }, 103 | { 104 | "inputs": [ 105 | { 106 | "internalType": "address", 107 | "name": "sender", 108 | "type": "address" 109 | } 110 | ], 111 | "name": "ERC20InvalidSender", 112 | "type": "error" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address", 118 | "name": "spender", 119 | "type": "address" 120 | } 121 | ], 122 | "name": "ERC20InvalidSpender", 123 | "type": "error" 124 | }, 125 | { 126 | "anonymous": false, 127 | "inputs": [ 128 | { 129 | "indexed": true, 130 | "internalType": "address", 131 | "name": "owner", 132 | "type": "address" 133 | }, 134 | { 135 | "indexed": true, 136 | "internalType": "address", 137 | "name": "spender", 138 | "type": "address" 139 | }, 140 | { 141 | "indexed": false, 142 | "internalType": "uint256", 143 | "name": "value", 144 | "type": "uint256" 145 | } 146 | ], 147 | "name": "Approval", 148 | "type": "event" 149 | }, 150 | { 151 | "anonymous": false, 152 | "inputs": [ 153 | { 154 | "indexed": true, 155 | "internalType": "address", 156 | "name": "from", 157 | "type": "address" 158 | }, 159 | { 160 | "indexed": true, 161 | "internalType": "address", 162 | "name": "to", 163 | "type": "address" 164 | }, 165 | { 166 | "indexed": false, 167 | "internalType": "uint256", 168 | "name": "value", 169 | "type": "uint256" 170 | } 171 | ], 172 | "name": "Transfer", 173 | "type": "event" 174 | }, 175 | { 176 | "inputs": [ 177 | { 178 | "internalType": "address", 179 | "name": "owner", 180 | "type": "address" 181 | }, 182 | { 183 | "internalType": "address", 184 | "name": "spender", 185 | "type": "address" 186 | } 187 | ], 188 | "name": "allowance", 189 | "outputs": [ 190 | { 191 | "internalType": "uint256", 192 | "name": "", 193 | "type": "uint256" 194 | } 195 | ], 196 | "stateMutability": "view", 197 | "type": "function" 198 | }, 199 | { 200 | "inputs": [ 201 | { 202 | "internalType": "address", 203 | "name": "spender", 204 | "type": "address" 205 | }, 206 | { 207 | "internalType": "uint256", 208 | "name": "value", 209 | "type": "uint256" 210 | } 211 | ], 212 | "name": "approve", 213 | "outputs": [ 214 | { 215 | "internalType": "bool", 216 | "name": "", 217 | "type": "bool" 218 | } 219 | ], 220 | "stateMutability": "nonpayable", 221 | "type": "function" 222 | }, 223 | { 224 | "inputs": [ 225 | { 226 | "internalType": "address", 227 | "name": "account", 228 | "type": "address" 229 | } 230 | ], 231 | "name": "balanceOf", 232 | "outputs": [ 233 | { 234 | "internalType": "uint256", 235 | "name": "", 236 | "type": "uint256" 237 | } 238 | ], 239 | "stateMutability": "view", 240 | "type": "function" 241 | }, 242 | { 243 | "inputs": [ 244 | { 245 | "internalType": "uint256", 246 | "name": "amount", 247 | "type": "uint256" 248 | } 249 | ], 250 | "name": "burn", 251 | "outputs": [ 252 | { 253 | "internalType": "bool", 254 | "name": "", 255 | "type": "bool" 256 | } 257 | ], 258 | "stateMutability": "nonpayable", 259 | "type": "function" 260 | }, 261 | { 262 | "inputs": [ 263 | { 264 | "internalType": "address", 265 | "name": "account", 266 | "type": "address" 267 | }, 268 | { 269 | "internalType": "uint256", 270 | "name": "amount", 271 | "type": "uint256" 272 | } 273 | ], 274 | "name": "burnFrom", 275 | "outputs": [ 276 | { 277 | "internalType": "bool", 278 | "name": "", 279 | "type": "bool" 280 | } 281 | ], 282 | "stateMutability": "nonpayable", 283 | "type": "function" 284 | }, 285 | { 286 | "inputs": [ 287 | 288 | ], 289 | "name": "decimals", 290 | "outputs": [ 291 | { 292 | "internalType": "uint8", 293 | "name": "", 294 | "type": "uint8" 295 | } 296 | ], 297 | "stateMutability": "view", 298 | "type": "function" 299 | }, 300 | { 301 | "inputs": [ 302 | { 303 | "internalType": "address", 304 | "name": "spender", 305 | "type": "address" 306 | }, 307 | { 308 | "internalType": "uint256", 309 | "name": "requestedDecrease", 310 | "type": "uint256" 311 | } 312 | ], 313 | "name": "decreaseAllowance", 314 | "outputs": [ 315 | { 316 | "internalType": "bool", 317 | "name": "", 318 | "type": "bool" 319 | } 320 | ], 321 | "stateMutability": "nonpayable", 322 | "type": "function" 323 | }, 324 | { 325 | "inputs": [ 326 | { 327 | "internalType": "address", 328 | "name": "spender", 329 | "type": "address" 330 | }, 331 | { 332 | "internalType": "uint256", 333 | "name": "addedValue", 334 | "type": "uint256" 335 | } 336 | ], 337 | "name": "increaseAllowance", 338 | "outputs": [ 339 | { 340 | "internalType": "bool", 341 | "name": "", 342 | "type": "bool" 343 | } 344 | ], 345 | "stateMutability": "nonpayable", 346 | "type": "function" 347 | }, 348 | { 349 | "inputs": [ 350 | { 351 | "internalType": "uint256", 352 | "name": "amount", 353 | "type": "uint256" 354 | } 355 | ], 356 | "name": "mint", 357 | "outputs": [ 358 | 359 | ], 360 | "stateMutability": "nonpayable", 361 | "type": "function" 362 | }, 363 | { 364 | "inputs": [ 365 | 366 | ], 367 | "name": "name", 368 | "outputs": [ 369 | { 370 | "internalType": "string", 371 | "name": "", 372 | "type": "string" 373 | } 374 | ], 375 | "stateMutability": "view", 376 | "type": "function" 377 | }, 378 | { 379 | "inputs": [ 380 | 381 | ], 382 | "name": "symbol", 383 | "outputs": [ 384 | { 385 | "internalType": "string", 386 | "name": "", 387 | "type": "string" 388 | } 389 | ], 390 | "stateMutability": "view", 391 | "type": "function" 392 | }, 393 | { 394 | "inputs": [ 395 | 396 | ], 397 | "name": "totalSupply", 398 | "outputs": [ 399 | { 400 | "internalType": "uint256", 401 | "name": "", 402 | "type": "uint256" 403 | } 404 | ], 405 | "stateMutability": "view", 406 | "type": "function" 407 | }, 408 | { 409 | "inputs": [ 410 | { 411 | "internalType": "address", 412 | "name": "to", 413 | "type": "address" 414 | }, 415 | { 416 | "internalType": "uint256", 417 | "name": "value", 418 | "type": "uint256" 419 | } 420 | ], 421 | "name": "transfer", 422 | "outputs": [ 423 | { 424 | "internalType": "bool", 425 | "name": "", 426 | "type": "bool" 427 | } 428 | ], 429 | "stateMutability": "nonpayable", 430 | "type": "function" 431 | }, 432 | { 433 | "inputs": [ 434 | { 435 | "internalType": "address", 436 | "name": "from", 437 | "type": "address" 438 | }, 439 | { 440 | "internalType": "address", 441 | "name": "to", 442 | "type": "address" 443 | }, 444 | { 445 | "internalType": "uint256", 446 | "name": "value", 447 | "type": "uint256" 448 | } 449 | ], 450 | "name": "transferFrom", 451 | "outputs": [ 452 | { 453 | "internalType": "bool", 454 | "name": "", 455 | "type": "bool" 456 | } 457 | ], 458 | "stateMutability": "nonpayable", 459 | "type": "function" 460 | } 461 | ] -------------------------------------------------------------------------------- /abi/erc20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "_name", 7 | "type": "string" 8 | }, 9 | { 10 | "internalType": "string", 11 | "name": "_symbol", 12 | "type": "string" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "_initialSupply", 17 | "type": "uint256" 18 | } 19 | ], 20 | "stateMutability": "nonpayable", 21 | "type": "constructor" 22 | }, 23 | { 24 | "inputs": [ 25 | { 26 | "internalType": "address", 27 | "name": "_user", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "faucet", 32 | "outputs": [], 33 | "stateMutability": "nonpayable", 34 | "type": "function" 35 | }, 36 | { 37 | "anonymous": false, 38 | "inputs": [ 39 | { 40 | "indexed": true, 41 | "internalType": "address", 42 | "name": "owner", 43 | "type": "address" 44 | }, 45 | { 46 | "indexed": true, 47 | "internalType": "address", 48 | "name": "spender", 49 | "type": "address" 50 | }, 51 | { 52 | "indexed": false, 53 | "internalType": "uint256", 54 | "name": "value", 55 | "type": "uint256" 56 | } 57 | ], 58 | "name": "Approval", 59 | "type": "event" 60 | }, 61 | { 62 | "anonymous": false, 63 | "inputs": [ 64 | { 65 | "indexed": true, 66 | "internalType": "address", 67 | "name": "from", 68 | "type": "address" 69 | }, 70 | { 71 | "indexed": true, 72 | "internalType": "address", 73 | "name": "to", 74 | "type": "address" 75 | }, 76 | { 77 | "indexed": false, 78 | "internalType": "uint256", 79 | "name": "value", 80 | "type": "uint256" 81 | } 82 | ], 83 | "name": "Transfer", 84 | "type": "event" 85 | }, 86 | { 87 | "inputs": [ 88 | { 89 | "internalType": "address", 90 | "name": "owner", 91 | "type": "address" 92 | }, 93 | { 94 | "internalType": "address", 95 | "name": "spender", 96 | "type": "address" 97 | } 98 | ], 99 | "name": "allowance", 100 | "outputs": [ 101 | { 102 | "internalType": "uint256", 103 | "name": "", 104 | "type": "uint256" 105 | } 106 | ], 107 | "stateMutability": "view", 108 | "type": "function" 109 | }, 110 | { 111 | "inputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "spender", 115 | "type": "address" 116 | }, 117 | { 118 | "internalType": "uint256", 119 | "name": "amount", 120 | "type": "uint256" 121 | } 122 | ], 123 | "name": "approve", 124 | "outputs": [ 125 | { 126 | "internalType": "bool", 127 | "name": "", 128 | "type": "bool" 129 | } 130 | ], 131 | "stateMutability": "nonpayable", 132 | "type": "function" 133 | }, 134 | { 135 | "inputs": [ 136 | { 137 | "internalType": "address", 138 | "name": "account", 139 | "type": "address" 140 | } 141 | ], 142 | "name": "balanceOf", 143 | "outputs": [ 144 | { 145 | "internalType": "uint256", 146 | "name": "", 147 | "type": "uint256" 148 | } 149 | ], 150 | "stateMutability": "view", 151 | "type": "function" 152 | }, 153 | { 154 | "inputs": [], 155 | "name": "decimals", 156 | "outputs": [ 157 | { 158 | "internalType": "uint8", 159 | "name": "", 160 | "type": "uint8" 161 | } 162 | ], 163 | "stateMutability": "view", 164 | "type": "function" 165 | }, 166 | { 167 | "inputs": [ 168 | { 169 | "internalType": "address", 170 | "name": "spender", 171 | "type": "address" 172 | }, 173 | { 174 | "internalType": "uint256", 175 | "name": "subtractedValue", 176 | "type": "uint256" 177 | } 178 | ], 179 | "name": "decreaseAllowance", 180 | "outputs": [ 181 | { 182 | "internalType": "bool", 183 | "name": "", 184 | "type": "bool" 185 | } 186 | ], 187 | "stateMutability": "nonpayable", 188 | "type": "function" 189 | }, 190 | { 191 | "inputs": [ 192 | { 193 | "internalType": "address", 194 | "name": "spender", 195 | "type": "address" 196 | }, 197 | { 198 | "internalType": "uint256", 199 | "name": "addedValue", 200 | "type": "uint256" 201 | } 202 | ], 203 | "name": "increaseAllowance", 204 | "outputs": [ 205 | { 206 | "internalType": "bool", 207 | "name": "", 208 | "type": "bool" 209 | } 210 | ], 211 | "stateMutability": "nonpayable", 212 | "type": "function" 213 | }, 214 | { 215 | "inputs": [], 216 | "name": "name", 217 | "outputs": [ 218 | { 219 | "internalType": "string", 220 | "name": "", 221 | "type": "string" 222 | } 223 | ], 224 | "stateMutability": "view", 225 | "type": "function" 226 | }, 227 | { 228 | "inputs": [ 229 | { 230 | "internalType": "uint8", 231 | "name": "decimals_", 232 | "type": "uint8" 233 | } 234 | ], 235 | "name": "setupDecimals", 236 | "outputs": [], 237 | "stateMutability": "nonpayable", 238 | "type": "function" 239 | }, 240 | { 241 | "inputs": [], 242 | "name": "symbol", 243 | "outputs": [ 244 | { 245 | "internalType": "string", 246 | "name": "", 247 | "type": "string" 248 | } 249 | ], 250 | "stateMutability": "view", 251 | "type": "function" 252 | }, 253 | { 254 | "inputs": [], 255 | "name": "totalSupply", 256 | "outputs": [ 257 | { 258 | "internalType": "uint256", 259 | "name": "", 260 | "type": "uint256" 261 | } 262 | ], 263 | "stateMutability": "view", 264 | "type": "function" 265 | }, 266 | { 267 | "inputs": [ 268 | { 269 | "internalType": "address", 270 | "name": "recipient", 271 | "type": "address" 272 | }, 273 | { 274 | "internalType": "uint256", 275 | "name": "amount", 276 | "type": "uint256" 277 | } 278 | ], 279 | "name": "transfer", 280 | "outputs": [ 281 | { 282 | "internalType": "bool", 283 | "name": "", 284 | "type": "bool" 285 | } 286 | ], 287 | "stateMutability": "nonpayable", 288 | "type": "function" 289 | }, 290 | { 291 | "inputs": [ 292 | { 293 | "internalType": "address", 294 | "name": "sender", 295 | "type": "address" 296 | }, 297 | { 298 | "internalType": "address", 299 | "name": "recipient", 300 | "type": "address" 301 | }, 302 | { 303 | "internalType": "uint256", 304 | "name": "amount", 305 | "type": "uint256" 306 | } 307 | ], 308 | "name": "transferFrom", 309 | "outputs": [ 310 | { 311 | "internalType": "bool", 312 | "name": "", 313 | "type": "bool" 314 | } 315 | ], 316 | "stateMutability": "nonpayable", 317 | "type": "function" 318 | } 319 | ] -------------------------------------------------------------------------------- /abi/mintAll.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address[]", 6 | "name": "externalTokens_", 7 | "type": "address[]" 8 | } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "anonymous": false, 15 | "inputs": [ 16 | { 17 | "indexed": true, 18 | "internalType": "address", 19 | "name": "recipient", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "tokensClaimed", 24 | "type": "event" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address[]", 30 | "name": "tokens", 31 | "type": "address[]" 32 | }, 33 | { 34 | "internalType": "uint256[]", 35 | "name": "amounts", 36 | "type": "uint256[]" 37 | } 38 | ], 39 | "name": "addMoreTokens", 40 | "outputs": [ 41 | { 42 | "internalType": "bool", 43 | "name": "", 44 | "type": "bool" 45 | } 46 | ], 47 | "stateMutability": "nonpayable", 48 | "type": "function" 49 | }, 50 | { 51 | "inputs": [ 52 | { 53 | "internalType": "address", 54 | "name": "wallet", 55 | "type": "address" 56 | } 57 | ], 58 | "name": "addRole", 59 | "outputs": [ 60 | { 61 | "internalType": "bool", 62 | "name": "", 63 | "type": "bool" 64 | } 65 | ], 66 | "stateMutability": "nonpayable", 67 | "type": "function" 68 | }, 69 | { 70 | "inputs": [ 71 | { 72 | "internalType": "address", 73 | "name": "", 74 | "type": "address" 75 | } 76 | ], 77 | "name": "adminRole", 78 | "outputs": [ 79 | { 80 | "internalType": "bool", 81 | "name": "", 82 | "type": "bool" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [ 90 | { 91 | "internalType": "uint256", 92 | "name": "", 93 | "type": "uint256" 94 | } 95 | ], 96 | "name": "amountTokensInWei", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "address", 111 | "name": "wallet", 112 | "type": "address" 113 | } 114 | ], 115 | "name": "blackListWallet", 116 | "outputs": [ 117 | { 118 | "internalType": "bool", 119 | "name": "", 120 | "type": "bool" 121 | } 122 | ], 123 | "stateMutability": "nonpayable", 124 | "type": "function" 125 | }, 126 | { 127 | "inputs": [ 128 | { 129 | "internalType": "address", 130 | "name": "", 131 | "type": "address" 132 | } 133 | ], 134 | "name": "blackListedWallet", 135 | "outputs": [ 136 | { 137 | "internalType": "bool", 138 | "name": "", 139 | "type": "bool" 140 | } 141 | ], 142 | "stateMutability": "view", 143 | "type": "function" 144 | }, 145 | { 146 | "inputs": [ 147 | { 148 | "internalType": "uint256[]", 149 | "name": "amounts", 150 | "type": "uint256[]" 151 | } 152 | ], 153 | "name": "changeAmounts", 154 | "outputs": [ 155 | { 156 | "internalType": "bool", 157 | "name": "", 158 | "type": "bool" 159 | } 160 | ], 161 | "stateMutability": "nonpayable", 162 | "type": "function" 163 | }, 164 | { 165 | "inputs": [ 166 | { 167 | "internalType": "address[]", 168 | "name": "tokens", 169 | "type": "address[]" 170 | } 171 | ], 172 | "name": "changeTokens", 173 | "outputs": [ 174 | { 175 | "internalType": "bool", 176 | "name": "", 177 | "type": "bool" 178 | } 179 | ], 180 | "stateMutability": "nonpayable", 181 | "type": "function" 182 | }, 183 | { 184 | "inputs": [ 185 | { 186 | "internalType": "address", 187 | "name": "", 188 | "type": "address" 189 | } 190 | ], 191 | "name": "claimedTokens", 192 | "outputs": [ 193 | { 194 | "internalType": "bool", 195 | "name": "", 196 | "type": "bool" 197 | } 198 | ], 199 | "stateMutability": "view", 200 | "type": "function" 201 | }, 202 | { 203 | "inputs": [ 204 | { 205 | "internalType": "uint256", 206 | "name": "", 207 | "type": "uint256" 208 | } 209 | ], 210 | "name": "externalTokens", 211 | "outputs": [ 212 | { 213 | "internalType": "address", 214 | "name": "", 215 | "type": "address" 216 | } 217 | ], 218 | "stateMutability": "view", 219 | "type": "function" 220 | }, 221 | { 222 | "inputs": [ 223 | { 224 | "internalType": "address", 225 | "name": "recipient", 226 | "type": "address" 227 | } 228 | ], 229 | "name": "mintTokens", 230 | "outputs": [ 231 | { 232 | "internalType": "bool", 233 | "name": "", 234 | "type": "bool" 235 | } 236 | ], 237 | "stateMutability": "nonpayable", 238 | "type": "function" 239 | }, 240 | { 241 | "inputs": [ 242 | 243 | ], 244 | "name": "totalClaimed", 245 | "outputs": [ 246 | { 247 | "internalType": "uint256", 248 | "name": "", 249 | "type": "uint256" 250 | } 251 | ], 252 | "stateMutability": "view", 253 | "type": "function" 254 | } 255 | ] -------------------------------------------------------------------------------- /abi/tpl.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "components": [ 6 | { 7 | "internalType": "address", 8 | "name": "target", 9 | "type": "address" 10 | }, 11 | { 12 | "internalType": "bytes", 13 | "name": "callData", 14 | "type": "bytes" 15 | } 16 | ], 17 | "internalType": "struct Multicall3.Call[]", 18 | "name": "calls", 19 | "type": "tuple[]" 20 | } 21 | ], 22 | "name": "aggregate", 23 | "outputs": [ 24 | { 25 | "internalType": "uint256", 26 | "name": "blockNumber", 27 | "type": "uint256" 28 | }, 29 | { 30 | "internalType": "bytes[]", 31 | "name": "returnData", 32 | "type": "bytes[]" 33 | } 34 | ], 35 | "stateMutability": "payable", 36 | "type": "function" 37 | }, 38 | { 39 | "inputs": [ 40 | { 41 | "components": [ 42 | { 43 | "internalType": "address", 44 | "name": "target", 45 | "type": "address" 46 | }, 47 | { 48 | "internalType": "bool", 49 | "name": "allowFailure", 50 | "type": "bool" 51 | }, 52 | { 53 | "internalType": "bytes", 54 | "name": "callData", 55 | "type": "bytes" 56 | } 57 | ], 58 | "internalType": "struct Multicall3.Call3[]", 59 | "name": "calls", 60 | "type": "tuple[]" 61 | } 62 | ], 63 | "name": "aggregate3", 64 | "outputs": [ 65 | { 66 | "components": [ 67 | { 68 | "internalType": "bool", 69 | "name": "success", 70 | "type": "bool" 71 | }, 72 | { 73 | "internalType": "bytes", 74 | "name": "returnData", 75 | "type": "bytes" 76 | } 77 | ], 78 | "internalType": "struct Multicall3.Result[]", 79 | "name": "returnData", 80 | "type": "tuple[]" 81 | } 82 | ], 83 | "stateMutability": "payable", 84 | "type": "function" 85 | }, 86 | { 87 | "inputs": [ 88 | { 89 | "components": [ 90 | { 91 | "internalType": "address", 92 | "name": "target", 93 | "type": "address" 94 | }, 95 | { 96 | "internalType": "bool", 97 | "name": "allowFailure", 98 | "type": "bool" 99 | }, 100 | { 101 | "internalType": "uint256", 102 | "name": "value", 103 | "type": "uint256" 104 | }, 105 | { 106 | "internalType": "bytes", 107 | "name": "callData", 108 | "type": "bytes" 109 | } 110 | ], 111 | "internalType": "struct Multicall3.Call3Value[]", 112 | "name": "calls", 113 | "type": "tuple[]" 114 | } 115 | ], 116 | "name": "aggregate3Value", 117 | "outputs": [ 118 | { 119 | "components": [ 120 | { 121 | "internalType": "bool", 122 | "name": "success", 123 | "type": "bool" 124 | }, 125 | { 126 | "internalType": "bytes", 127 | "name": "returnData", 128 | "type": "bytes" 129 | } 130 | ], 131 | "internalType": "struct Multicall3.Result[]", 132 | "name": "returnData", 133 | "type": "tuple[]" 134 | } 135 | ], 136 | "stateMutability": "payable", 137 | "type": "function" 138 | }, 139 | { 140 | "inputs": [ 141 | { 142 | "components": [ 143 | { 144 | "internalType": "address", 145 | "name": "target", 146 | "type": "address" 147 | }, 148 | { 149 | "internalType": "bytes", 150 | "name": "callData", 151 | "type": "bytes" 152 | } 153 | ], 154 | "internalType": "struct Multicall3.Call[]", 155 | "name": "calls", 156 | "type": "tuple[]" 157 | } 158 | ], 159 | "name": "blockAndAggregate", 160 | "outputs": [ 161 | { 162 | "internalType": "uint256", 163 | "name": "blockNumber", 164 | "type": "uint256" 165 | }, 166 | { 167 | "internalType": "bytes32", 168 | "name": "blockHash", 169 | "type": "bytes32" 170 | }, 171 | { 172 | "components": [ 173 | { 174 | "internalType": "bool", 175 | "name": "success", 176 | "type": "bool" 177 | }, 178 | { 179 | "internalType": "bytes", 180 | "name": "returnData", 181 | "type": "bytes" 182 | } 183 | ], 184 | "internalType": "struct Multicall3.Result[]", 185 | "name": "returnData", 186 | "type": "tuple[]" 187 | } 188 | ], 189 | "stateMutability": "payable", 190 | "type": "function" 191 | }, 192 | { 193 | "inputs": [ 194 | 195 | ], 196 | "name": "getBasefee", 197 | "outputs": [ 198 | { 199 | "internalType": "uint256", 200 | "name": "basefee", 201 | "type": "uint256" 202 | } 203 | ], 204 | "stateMutability": "view", 205 | "type": "function" 206 | }, 207 | { 208 | "inputs": [ 209 | { 210 | "internalType": "uint256", 211 | "name": "blockNumber", 212 | "type": "uint256" 213 | } 214 | ], 215 | "name": "getBlockHash", 216 | "outputs": [ 217 | { 218 | "internalType": "bytes32", 219 | "name": "blockHash", 220 | "type": "bytes32" 221 | } 222 | ], 223 | "stateMutability": "view", 224 | "type": "function" 225 | }, 226 | { 227 | "inputs": [ 228 | 229 | ], 230 | "name": "getBlockNumber", 231 | "outputs": [ 232 | { 233 | "internalType": "uint256", 234 | "name": "blockNumber", 235 | "type": "uint256" 236 | } 237 | ], 238 | "stateMutability": "view", 239 | "type": "function" 240 | }, 241 | { 242 | "inputs": [ 243 | 244 | ], 245 | "name": "getChainId", 246 | "outputs": [ 247 | { 248 | "internalType": "uint256", 249 | "name": "chainid", 250 | "type": "uint256" 251 | } 252 | ], 253 | "stateMutability": "view", 254 | "type": "function" 255 | }, 256 | { 257 | "inputs": [ 258 | 259 | ], 260 | "name": "getCurrentBlockCoinbase", 261 | "outputs": [ 262 | { 263 | "internalType": "address", 264 | "name": "coinbase", 265 | "type": "address" 266 | } 267 | ], 268 | "stateMutability": "view", 269 | "type": "function" 270 | }, 271 | { 272 | "inputs": [ 273 | 274 | ], 275 | "name": "getCurrentBlockDifficulty", 276 | "outputs": [ 277 | { 278 | "internalType": "uint256", 279 | "name": "difficulty", 280 | "type": "uint256" 281 | } 282 | ], 283 | "stateMutability": "view", 284 | "type": "function" 285 | }, 286 | { 287 | "inputs": [ 288 | 289 | ], 290 | "name": "getCurrentBlockGasLimit", 291 | "outputs": [ 292 | { 293 | "internalType": "uint256", 294 | "name": "gaslimit", 295 | "type": "uint256" 296 | } 297 | ], 298 | "stateMutability": "view", 299 | "type": "function" 300 | }, 301 | { 302 | "inputs": [ 303 | 304 | ], 305 | "name": "getCurrentBlockTimestamp", 306 | "outputs": [ 307 | { 308 | "internalType": "uint256", 309 | "name": "timestamp", 310 | "type": "uint256" 311 | } 312 | ], 313 | "stateMutability": "view", 314 | "type": "function" 315 | }, 316 | { 317 | "inputs": [ 318 | { 319 | "internalType": "address", 320 | "name": "addr", 321 | "type": "address" 322 | } 323 | ], 324 | "name": "getEthBalance", 325 | "outputs": [ 326 | { 327 | "internalType": "uint256", 328 | "name": "balance", 329 | "type": "uint256" 330 | } 331 | ], 332 | "stateMutability": "view", 333 | "type": "function" 334 | }, 335 | { 336 | "inputs": [ 337 | 338 | ], 339 | "name": "getLastBlockHash", 340 | "outputs": [ 341 | { 342 | "internalType": "bytes32", 343 | "name": "blockHash", 344 | "type": "bytes32" 345 | } 346 | ], 347 | "stateMutability": "view", 348 | "type": "function" 349 | }, 350 | { 351 | "inputs": [ 352 | { 353 | "internalType": "bool", 354 | "name": "requireSuccess", 355 | "type": "bool" 356 | }, 357 | { 358 | "components": [ 359 | { 360 | "internalType": "address", 361 | "name": "target", 362 | "type": "address" 363 | }, 364 | { 365 | "internalType": "bytes", 366 | "name": "callData", 367 | "type": "bytes" 368 | } 369 | ], 370 | "internalType": "struct Multicall3.Call[]", 371 | "name": "calls", 372 | "type": "tuple[]" 373 | } 374 | ], 375 | "name": "tryAggregate", 376 | "outputs": [ 377 | { 378 | "components": [ 379 | { 380 | "internalType": "bool", 381 | "name": "success", 382 | "type": "bool" 383 | }, 384 | { 385 | "internalType": "bytes", 386 | "name": "returnData", 387 | "type": "bytes" 388 | } 389 | ], 390 | "internalType": "struct Multicall3.Result[]", 391 | "name": "returnData", 392 | "type": "tuple[]" 393 | } 394 | ], 395 | "stateMutability": "payable", 396 | "type": "function" 397 | }, 398 | { 399 | "inputs": [ 400 | { 401 | "internalType": "bool", 402 | "name": "requireSuccess", 403 | "type": "bool" 404 | }, 405 | { 406 | "components": [ 407 | { 408 | "internalType": "address", 409 | "name": "target", 410 | "type": "address" 411 | }, 412 | { 413 | "internalType": "bytes", 414 | "name": "callData", 415 | "type": "bytes" 416 | } 417 | ], 418 | "internalType": "struct Multicall3.Call[]", 419 | "name": "calls", 420 | "type": "tuple[]" 421 | } 422 | ], 423 | "name": "tryBlockAndAggregate", 424 | "outputs": [ 425 | { 426 | "internalType": "uint256", 427 | "name": "blockNumber", 428 | "type": "uint256" 429 | }, 430 | { 431 | "internalType": "bytes32", 432 | "name": "blockHash", 433 | "type": "bytes32" 434 | }, 435 | { 436 | "components": [ 437 | { 438 | "internalType": "bool", 439 | "name": "success", 440 | "type": "bool" 441 | }, 442 | { 443 | "internalType": "bytes", 444 | "name": "returnData", 445 | "type": "bytes" 446 | } 447 | ], 448 | "internalType": "struct Multicall3.Result[]", 449 | "name": "returnData", 450 | "type": "tuple[]" 451 | } 452 | ], 453 | "stateMutability": "payable", 454 | "type": "function" 455 | } 456 | ] -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | from web3 import Web3 2 | tpl = Web3.to_checksum_address("0x321cE961084Fcf3A56De4Be2F2006707A0421aa4") 3 | usdt = Web3.to_checksum_address("0x08394e7e653472694ECd4527656B2881e5701A14") 4 | usdc = Web3.to_checksum_address("0x63355a2ff725B11B6d82071c9FD710C0DCc71900") 5 | shib = Web3.to_checksum_address("0x1cD40deb4196D219097499031922Ff690F9ea813") 6 | link = Web3.to_checksum_address("0x5b41A5c0Df16551f5edeAa2B2eDe2135F1a824DF") 7 | uni = Web3.to_checksum_address("0xD7b45CbC28BA9ba8653665d5FB37167a2Afe35D9") 8 | ape = Web3.to_checksum_address("0x01fa8dEEdDEA8E4e465f158d93e162438d61c9eB") 9 | pepe = Web3.to_checksum_address("0x11dC5C441971BB3b2e933e0256E8a6bC6c41a91a") 10 | chz = Web3.to_checksum_address("0xbe1d0dB61E7562d88eF1FAb7436d02b6d00ce728") 11 | comp = Web3.to_checksum_address("0xd75edf81CD2109D4264624dBf34Bd4Dee36f18B9") 12 | tomi = Web3.to_checksum_address("0xC870a3dc444bF970Da13979E9CFAc1a01c198eac") 13 | dop = Web3.to_checksum_address("0x4873528341D33Ec918c7465F244491aCB75Bc95F") 14 | router = Web3.to_checksum_address("0xC532a74256D3Db42D0Bf7a0400fEFDbad7694008") 15 | mintAll = Web3.to_checksum_address("0x837ad475f0177BcB6cF426A725d5d52Dfb577eE7") 16 | dop_account = Web3.to_checksum_address("0x130c318bef3a60F05541955003b2baa1d691335F") 17 | nstproxy_Channel = '' 18 | nstproxy_Password = '' 19 | 20 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satisfywithmylife/dop/882f353656fde693e30c6eb4bb2d217ab11fd3ad/example.py -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import sys 3 | import httpx 4 | from loguru import logger 5 | from web3 import Web3 6 | from eth_account import Account 7 | from eth_account.messages import encode_defunct 8 | from eth_account.messages import defunct_hash_message 9 | from functools import cached_property 10 | import json 11 | from web3.exceptions import TransactionNotFound 12 | from config import * 13 | from web3.eth import AsyncEth 14 | import time 15 | import random 16 | from eth_abi import encode 17 | 18 | g_success, g_fail = 0, 0 19 | 20 | logger.remove() 21 | logger.add('my.log', format='{time:YYYY-MM-DD HH:mm:ss:SSS} | {level} | {message}') 22 | logger.add(sys.stdout, format='{time:YYYY-MM-DD HH:mm:ss:SSS} | {level} | {message}') 23 | 24 | # https://doptest.dop.org?id=ZdbWvzM 25 | class Dop: 26 | def __init__(self, pk, auth_token, referral='ZdbWvzM', proxy='', gas_scala=1.2): 27 | proxy = { 28 | 'all://': f'{proxy}' if proxy else None 29 | } 30 | self.gas_scala = gas_scala 31 | self.http = httpx.AsyncClient(verify=False, proxies=proxy, timeout=120) 32 | self.Twitter = httpx.AsyncClient(verify=False, proxies=proxy, timeout=120) 33 | self.pk = pk 34 | self.account: Account = Account.from_key(pk) 35 | self.w3 = Web3( 36 | Web3.AsyncHTTPProvider(endpoint_uri='https://gateway.tenderly.co/public/sepolia'), 37 | modules={"eth": (AsyncEth,)} 38 | ) 39 | self.exploer = 'https://sepolia.etherscan.io/tx/{}' 40 | self.proxy_str = proxy 41 | self.Twitter.headers = { 42 | 'Accept-Language': 'en-US,en;q=0.8', 43 | 'Authority': 'twitter.com', 44 | 'Origin': 'https://twitter.com', 45 | 'Referer': 'https://twitter.com/', 46 | 'Sec-Ch-Ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', 47 | 'Sec-Ch-Ua-Mobile': '?0', 48 | 'Sec-Ch-Ua-Platform': "Windows", 49 | 'Sec-Fetch-Dest': 'empty', 50 | 'Sec-Fetch-Mode': 'cors', 51 | 'Sec-Fetch-Site': 'same-origin', 52 | 'Sec-Gpc': '1', 53 | 'User-Agent': 'Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 54 | 'Accept-Encoding': 'gzip, deflate, br', 55 | 56 | } 57 | self.dop_host = 'https://rewards-api.dop.org/{}' 58 | self.Twitter.cookies.update({'auth_token': auth_token}) 59 | self.oauth_token, self.authenticity_token, self.oauth_verifier, self.token = None, None, None, None 60 | self.referral = referral 61 | self.u_info = {} 62 | 63 | def add_log(self, log_str, tx_hash=''): 64 | log_str = f'{self.account.address} ' + log_str 65 | if tx_hash and isinstance(tx_hash, str): 66 | log_str += f' | Tx {self.exploer.format(tx_hash)}' 67 | logger.debug(log_str) 68 | 69 | @cached_property 70 | def _get_sign(self): 71 | address = self.account.address.lower() 72 | sign_str = address + address + 'weareDOPdev' 73 | msghash = encode_defunct(text=sign_str) 74 | sign = Account.sign_message(msghash, self.pk) 75 | 76 | sign = str(sign.signature.hex()) 77 | return sign 78 | 79 | async def get_geo_info(self): 80 | return { 81 | 'location': 'United States' 82 | } 83 | 84 | async def get_ip(self): 85 | res = await self.http.get(url='https://ip.nf/me.json') 86 | res = res.json() 87 | return f"http://{res['ip']['ip']}/" 88 | 89 | async def create_account(self): 90 | url = self.dop_host.format('rewards') 91 | geo = await self.get_geo_info() 92 | payload = { 93 | "email": await self.get_mail(), 94 | "externalWalletAddress": self.account.address, 95 | "internalWalletAddress": self.account.address.lower(), 96 | "ip": await self.get_ip(), 97 | "location": geo['location'], 98 | "referalByCode": self.referral, 99 | "sign": self._get_sign 100 | } 101 | 102 | res = await self.http.post(url=url, json=payload) 103 | res = res.json() 104 | if res['statusCode'] == 201: 105 | return res['data'] 106 | 107 | return False 108 | 109 | async def get_user_info(self): 110 | if self.u_info: 111 | return self.u_info 112 | url = self.dop_host.format('rewards/walletaddress') 113 | payload={ 114 | 'internalWalletAddress': self.account.address.lower(), 115 | 'externalWalletAddress': self.account.address, 116 | 'sign': self._get_sign 117 | } 118 | 119 | res = await self.http.get(url=url, params=payload) 120 | #{'statusCode': 200, 'data': {'updatedReward': {'claim_Sepolia': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'claim_Dop': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'claim_Testnet_Assets': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'encrypt_Assets': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'decrypt_Assets': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'send_Assets': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'follow_Us_On_Twitter': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, 'threeInvites': {'isCompleted': False, 'completedAt': '2024-02-24T19:24:46.103Z'}, '_id': '65da427e8d841d7134ffffcf', 'externalWalletAddress': '0x05b89d24074d6c5cf8dc75490da44663a20acba0', 'internalWalletAddress': '0x05b89d24074d6c5cf8dc75490da44663a20acba0', 'influencerId': {'_id': '65da427e8d841d7134ffffcd', 'referalByCode': 'ZdbWvzM', 'referalCode': 'F3sLV4H', 'email': '1075022284@qq.com', 'isActive': True, 'deleted': False}, 'referedId': '65d9cd968d841d7134e620f1', 'role': 'user', 'ip': 'http://104.28.240.133/', 'location': 'united states', 'referrals': 0, 'status': False, 'completionStatus': 0, 'overallCompletionPercentage': 0, 'createdAt': '2024-02-24T19:24:46.104Z', 'updatedAt': '2024-02-24T19:24:46.104Z', '__v': 0}, 'totalcount': 0, 'stepsCompletionCount': 0}} 121 | res = res.json() 122 | if res['statusCode'] == 404: 123 | self.add_log('账号不存在,开始创建账号') 124 | res = await self.create_account() 125 | if res: 126 | return await self.get_user_info() 127 | self.add_log(f'用户信息: {json.dumps(res)}') 128 | self.u_info = res['data'] 129 | return res['data'] 130 | 131 | async def _get_id(self): 132 | u_info = await self.get_user_info() 133 | return u_info['updatedReward']['_id'] 134 | 135 | 136 | async def get_twitter(self): 137 | try: 138 | response = await self.http.post(self.dop_host.format('rewards/auth/twitter/reverse')) 139 | response = response.json() 140 | if 'oauth_token' in response.keys(): 141 | self.oauth_token = response['oauth_token'] 142 | return True 143 | self.add_log(f'获取oauth_token失败') 144 | return False 145 | except Exception as e: 146 | self.add_log(f'获取oauth_token异常') 147 | return False 148 | 149 | 150 | async def get_twitter_token(self): 151 | 152 | if not await self.get_twitter(): 153 | return False 154 | try: 155 | 156 | url = f'https://api.twitter.com/oauth/authorize?oauth_token={self.oauth_token}' 157 | response = await self.Twitter.get(url) 158 | if 'authenticity_token' in response.text: 159 | self.authenticity_token = response.text.split('authenticity_token" value="')[1].split('"')[0] 160 | return True 161 | self.add_log(f'获取authenticity_token失败') 162 | return False 163 | except: 164 | self.add_log(f'获取authenticity_token异常') 165 | return False 166 | 167 | 168 | async def check_auth_twitter(self): 169 | if not await self.twitter_authorize(): 170 | return False 171 | try: 172 | url = self.dop_host.format('rewards/auth/twitter') 173 | payload = { 174 | 'oauth_verifier': self.oauth_verifier, 175 | 'oauth_token': self.oauth_token 176 | } 177 | res = await self.http.post(url=url, data=payload) 178 | res = res.json() 179 | if res['statusCode'] == 200: 180 | self.add_log('推特认证通过') 181 | return True 182 | self.add_log(f'推特认证失败: {res["message"]}') 183 | return False 184 | except: 185 | self.add_log(f'推特认证异常') 186 | return False 187 | 188 | async def check_twitter_follow(self): 189 | if not await self.check_auth_twitter(): 190 | return False 191 | _id = await self._get_id() 192 | url = self.dop_host.format(f'rewards/{_id}/toggle-twitter') 193 | payload = { 194 | 'oauth_verifier': self.oauth_verifier, 195 | 'oauth_token': self.oauth_token 196 | } 197 | res = await self.http.patch(url=url, params=payload) 198 | res = res.json() 199 | if res['statusCode'] == 200: 200 | return True 201 | return False 202 | 203 | async def twitter_authorize(self): 204 | if not await self.get_twitter_token(): 205 | return False 206 | data = { 207 | 'authenticity_token': self.authenticity_token, 208 | 'redirect_after_login': f'https://api.twitter.com/oauth/authorize?oauth_token={self.oauth_token}', 209 | 'oauth_token': self.oauth_token 210 | } 211 | response = await self.Twitter.post('https://api.twitter.com/oauth/authorize', data=data) 212 | if 'oauth_verifier' in response.text: 213 | self.oauth_verifier = response.text.split('oauth_verifier=')[1].split('"')[0] 214 | self.add_log(f'获取oauth_verifier: {self.oauth_verifier}') 215 | return True 216 | self.add_log(f'获取oauth_verifier失败') 217 | return False 218 | 219 | 220 | async def twitter_login(self): 221 | try: 222 | if not await self.twitter_authorize(): 223 | return False 224 | response = await self.http.get(f'https://dropcoin.online/auth/twitter?oauth_token={self.oauth_token}&oauth_verifier={self.oauth_verifier}') 225 | if 'token' in response.text: 226 | self.token = response.json()['token'] 227 | self.http.headers.update({'Authorization': f'Token {self.token}'}) 228 | return True 229 | self.add_log(f'twitter登录失败') 230 | return False 231 | except Exception as e: 232 | self.add_log(f'{e}, 4444') 233 | return False 234 | 235 | 236 | async def claim_sepolia(self): 237 | url = self.dop_host.format('rewards/getSepolia') 238 | payload = { 239 | 'internalWalletAddress': self.account.address.lower(), 240 | 'externalWalletAddress': self.account.address, 241 | 'sign':self._get_sign 242 | } 243 | res = await self.http.get(url=url, params=payload, timeout=60) 244 | res = res.json() 245 | if res['statusCode'] != 200: 246 | self.add_log(f'领水错误:{res["message"]}') 247 | return False 248 | self.add_log('领sepolia水成功!') 249 | return True 250 | 251 | def load_abi(self, abi_name): 252 | with open(f'./abi/{abi_name}.json', 'r') as f: 253 | json_data = json.load(f) 254 | return json_data 255 | 256 | async def approve(self, token_contract, spender, amount): 257 | allowance = await token_contract.functions.allowance(self.account.address, spender).call() 258 | if allowance >= amount: 259 | return True 260 | tx_data = await self.get_tx_data() 261 | approve_tx = await token_contract.functions.approve( 262 | spender, 263 | amount 264 | ).build_transaction(tx_data) 265 | approve_tx_hash = await self._make_tx(tx=approve_tx) 266 | return True 267 | 268 | async def get_tx_data(self, eth_amount=0, gas_price=0, is_eip1559=False): 269 | net_price = await self.w3.eth.gas_price 270 | tx = { 271 | "chainId": await self.w3.eth.chain_id, 272 | "from": self.account.address, 273 | "value": eth_amount, 274 | "nonce": await self.w3.eth.get_transaction_count(self.account.address), 275 | } 276 | if is_eip1559: 277 | tx.update({'maxFeePerGas': gas_price if gas_price else int(self.gas_scala * net_price)}) 278 | tx.update({'maxPriorityFeePerGas': gas_price if gas_price else int(self.gas_scala * net_price)}) 279 | else: 280 | tx.update({"gasPrice": gas_price if gas_price else int(net_price * self.gas_scala)}) 281 | return tx 282 | 283 | async def get_fee(self, tx, gas=0): 284 | net_fee = await self.w3.eth.estimate_gas(tx) 285 | tx.update({ 286 | 'gas': gas if gas else net_fee 287 | }) 288 | signed_txn = self.account.sign_transaction(tx) 289 | return signed_txn 290 | 291 | async def send_tx(self, signed_txn): 292 | order_hash = await self.w3.eth.send_raw_transaction(signed_txn.rawTransaction) 293 | return order_hash 294 | 295 | async def _make_tx(self, tx, gas=0): 296 | 297 | signed_txn = await self.get_fee(tx, gas) 298 | order_hash = await self.send_tx(signed_txn) 299 | await self.wait_until_tx_finished(order_hash.hex()) 300 | return order_hash.hex() 301 | 302 | async def wait_until_tx_finished(self, hash: str, max_wait_time=180): 303 | start_time = time.time() 304 | while True: 305 | try: 306 | receipts = await self.w3.eth.get_transaction_receipt(hash) 307 | status = receipts.get("status") 308 | if status == 1: 309 | return True 310 | elif status is None: 311 | await asyncio.sleep(0.3) 312 | else: 313 | logger.error(f"[{self.account_id}][{self.address}] {self.explorer}{hash} transaction failed!") 314 | return False 315 | except TransactionNotFound: 316 | if time.time() - start_time > max_wait_time: 317 | self.add_log(f'FAILED TX: {hash}') 318 | return False 319 | await asyncio.sleep(1) 320 | 321 | async def claim_dop(self): 322 | contract = self.w3.eth.contract(address=dop, abi=self.load_abi('dop')) 323 | tx_data = await self.get_tx_data() 324 | tx = await contract.functions.mint(Web3.to_wei(1000, 'ether')).build_transaction(tx_data) 325 | tx_hash = await self._make_tx(tx=tx) 326 | if await self.update_rewards('claim_Dop'): 327 | self.add_log('claim dop 成功', tx_hash) 328 | return True 329 | 330 | return False 331 | 332 | async def claim_testnet_assets(self): 333 | contract = self.w3.eth.contract(address=mintAll, abi=self.load_abi('mintAll')) 334 | tx_data = await self.get_tx_data() 335 | tx = await contract.functions.mintTokens(self.account.address).build_transaction(tx_data) 336 | tx_hash = await self._make_tx(tx=tx) 337 | 338 | if await self.update_rewards('claim_Testnet_Assets'): 339 | self.add_log('claim testnet assets 成功', tx_hash) 340 | return True 341 | 342 | return False 343 | 344 | def encrypt_sign(self, amount): 345 | ts = int(time.time()*1000) 346 | random_int = random.randint(100000, 999999) 347 | sign_list = [str(self.account.address), str(self.account.address), int(amount), random_int, ts] 348 | keck_msg = self.w3.solidity_keccak(['address', 'address', 'uint256', 'uint256', 'uint256'], sign_list) 349 | h = defunct_hash_message(hexstr=keck_msg.hex()) 350 | signed_message = self.account.signHash(h) 351 | r_int, s_int, v = signed_message.r, signed_message.s, signed_message.v 352 | r, s = int.to_bytes(r_int, 32, 'big'), int.to_bytes(s_int, 32, 'big') 353 | r, s = r.hex(), s.hex() 354 | return r,s,v,ts,random_int 355 | 356 | 357 | async def encrypt_assets(self, coin_address=usdt): 358 | token_contract = self.w3.eth.contract(address=coin_address, abi=self.load_abi('erc20')) 359 | # amount = int(random.randint(100, 200) * 1e6) 360 | amount = await token_contract.functions.balanceOf(self.account.address).call() 361 | approve_res = await self.approve(token_contract, tpl, amount) 362 | r,s,v,ts,random_int = self.encrypt_sign(amount) 363 | if approve_res: 364 | method_id = '0x79df7682' 365 | args = [ 366 | self.account.address, 367 | random_int, 368 | ts, 369 | amount, 370 | 21, 371 | v, 372 | Web3.to_bytes(hexstr=r), 373 | Web3.to_bytes(hexstr=s), 374 | ] 375 | tx_data = await self.get_tx_data() 376 | txn_data = method_id + encode(types=["address","uint256","uint256","uint256","uint256","uint256","bytes32","bytes32"], args=args).hex() 377 | 378 | tx_data.update({ 379 | 'data': txn_data, 380 | 'to': tpl 381 | }) 382 | # print(tx_data) 383 | tx_hash = await self._make_tx(tx=tx_data) 384 | if tx_hash: 385 | if await self.update_rewards('encrypt_Assets'): 386 | self.add_log('encrypt assets 成功', tx_hash) 387 | return True 388 | 389 | return False 390 | 391 | async def send_assets(self, coin_address=dop): 392 | token_contract = self.w3.eth.contract(address=coin_address, abi=self.load_abi('erc20')) 393 | # balance = await token_contract.functions.balanceOf(self.account.address).call() 394 | # print(balance) 395 | amount = int(random.randint(1, 3) * 1e4) 396 | balance = await token_contract.functions.balanceOf(self.account.address).call() 397 | approve_res = await self.approve(token_contract, tpl, balance) 398 | r,s,v,ts,random_int = self.encrypt_sign(amount) 399 | if approve_res: 400 | method_id = '0xe54a9a7c' 401 | args = [ 402 | self.account.address, 403 | dop_account, 404 | amount, 405 | random_int, 406 | ts, 407 | 21, 408 | v, 409 | Web3.to_bytes(hexstr=r), 410 | Web3.to_bytes(hexstr=s), 411 | ] 412 | tx_data = await self.get_tx_data() 413 | txn_data = method_id + encode(types=["address","address","uint256","uint256","uint256","uint256","uint256","bytes32","bytes32"], args=args).hex() 414 | 415 | tx_data.update({ 416 | 'data': txn_data, 417 | 'to': tpl 418 | }) 419 | tx_hash = await self._make_tx(tx=tx_data, gas=200000) 420 | if tx_hash: 421 | if await self.update_rewards('send_Assets'): 422 | self.add_log('send assets 成功', tx_hash) 423 | return True 424 | 425 | return False 426 | 427 | 428 | async def decrypt_assets(self, coin_address=usdt): 429 | token_contract = self.w3.eth.contract(address=coin_address, abi=self.load_abi('erc20')) 430 | amount = int(random.randint(3, 7) * 1e6) 431 | approve_res = await self.approve(token_contract, tpl, amount) 432 | r,s,v,ts,random_int = self.encrypt_sign(amount) 433 | if approve_res: 434 | method_id = '0x676df6b3' 435 | args = [ 436 | self.account.address, 437 | self.account.address, 438 | amount, 439 | random_int, 440 | ts, 441 | 21, 442 | v, 443 | Web3.to_bytes(hexstr=r), 444 | Web3.to_bytes(hexstr=s), 445 | ] 446 | tx_data = await self.get_tx_data() 447 | txn_data = method_id + encode(types=["address","address","uint256","uint256","uint256","uint256","uint256","bytes32","bytes32"], args=args).hex() 448 | 449 | tx_data.update({ 450 | 'data': txn_data, 451 | 'to': tpl 452 | }) 453 | # print(tx_data) 454 | 455 | tx_hash = await self._make_tx(tx=tx_data) 456 | if tx_hash: 457 | if await self.update_rewards('decrypt_Assets'): 458 | self.add_log('decrypt assets 成功', tx_hash) 459 | return True 460 | 461 | return False 462 | 463 | # 刷新奖励 464 | async def update_rewards(self, task_name): 465 | _id = await self._get_id() 466 | url = self.dop_host.format(f'rewards/{_id}') 467 | payload = { 468 | 'internalWalletAddress': self.account.address.lower(), 469 | 'externalWalletAddress': self.account.address, 470 | 'sign':self._get_sign, 471 | task_name: { 472 | 'isCompleted': True 473 | } 474 | } 475 | res = await self.http.patch(url=url, json=payload, timeout=60) 476 | res = res.json() 477 | if res['statusCode'] == 200: 478 | return True 479 | 480 | return False 481 | 482 | async def get_my_code(self): 483 | u_info = await self.get_user_info() 484 | return u_info['updatedReward']['influencerId']['referalCode'] 485 | 486 | async def get_my_email(self): 487 | u_info = await self.get_user_info() 488 | return u_info['updatedReward']['influencerId']['email'] 489 | 490 | async def check_my_referor(self): 491 | u_info = await self.get_user_info() 492 | return u_info['updatedReward']['influencerId']['referalByCode'] 493 | 494 | async def three_invites(self): 495 | pass 496 | 497 | async def make_task(self): 498 | u_info = await self.get_user_info() 499 | task_list = [ 500 | ['follow_Us_On_Twitter', self.check_twitter_follow], 501 | ['claim_Sepolia', self.claim_sepolia, 1], 502 | ['claim_Dop', self.claim_dop], 503 | ['claim_Testnet_Assets', self.claim_testnet_assets], 504 | ['encrypt_Assets', self.encrypt_assets], 505 | ['send_Assets', self.send_assets], 506 | ['decrypt_Assets', self.decrypt_assets], 507 | ['threeInvites', None] 508 | ] 509 | for task_config in task_list: 510 | if not u_info['updatedReward'][task_config[0]]['isCompleted'] and task_config[1]: 511 | if not await task_config[1](): 512 | 513 | return False, task_config[0] 514 | elif len(task_config) == 3: 515 | check_times = 50 516 | while check_times: 517 | balance = await self.w3.eth.get_balance(self.account.address) 518 | if not balance: 519 | await asyncio.sleep(1) 520 | check_times -= 1 521 | else: 522 | self.add_log('领水已到账') 523 | break 524 | if not check_times: 525 | self.add_log('水一直未到账,跳过') 526 | return False, task_config[0] 527 | 528 | return True, task_config[0] 529 | 530 | 531 | async def get_mail(self): 532 | while 1: 533 | try: 534 | res = await self.http.get(f'https://www.1secmail.com/api/v1/?action=genRandomMailbox') 535 | if '@' in res.text: 536 | return res.json()[0] 537 | except: 538 | print('获取email失败') 539 | pass 540 | 541 | async def main(file_name, code, loop_invite): 542 | global g_fail, g_success 543 | jump = 1 544 | with open(file_name, 'r', encoding='UTF-8') as f, open('success.txt', 'a') as s, open('error.txt', 'a') as e, open('my.txt', 'a') as z: # eth----auth_token 545 | lines = f.readlines() 546 | for twitter in lines: 547 | _auth_tokn = '' 548 | t_list = twitter.split('----') 549 | for tw in t_list: 550 | if len(tw) == 40 and all(c in '0123456789abcdef' for c in tw): 551 | _auth_tokn = tw 552 | break 553 | if not _auth_tokn: 554 | continue 555 | pk = t_list[1] 556 | 557 | _nstproxy = '' 558 | if not nstproxy_Channel or not nstproxy_Password: 559 | logger.error('请配置 nstproxy 代理信息') 560 | return 561 | _nstproxy = f"http://{nstproxy_Channel}-residential-country_ANY-r_5m-s_BsqLCLkiVu:{nstproxy_Password}@gw-us.nstproxy.com:24125" 562 | # _res = httpx.get('https://ip.useragentinfo.com/json', proxies={'all://': _nstproxy}) 563 | # print(_res.text) 564 | dop = Dop(pk=pk, referral=code, auth_token=_auth_tokn, proxy=_nstproxy) 565 | # if jump and dop.account.address != '0xC08063DB5bC08CeD3084542279aD95aE22e5C8E0': 566 | # continue 567 | jump = 0 568 | try: 569 | my_code = await dop.get_my_code() 570 | email = await dop.get_my_email() 571 | if loop_invite: 572 | code = my_code 573 | log_str = f'{dop.account.address}----{pk}----{email}----{tw}----{my_code}\n' 574 | res, k = await dop.make_task() 575 | 576 | if res: 577 | dop.add_log(f'任务1-7完成成功') 578 | s.write(log_str) 579 | else: 580 | dop.add_log(f'任务{k}失败') 581 | e.write(log_str) 582 | except Exception as m: 583 | print(f'{m}') 584 | 585 | if __name__ == '__main__': 586 | _referral = 'ZdbWvzM' # 大号邀请码 587 | _file_name = 'tw_bind.txt' # 执行make.py重新生成的文件 588 | _loop_invite = True # 默认滚动邀请,一个号跑完任务,无论是否一次成功,自动变成邀请人,邀请下一个号做任务,False则只用大号邀请码作为邀请人 589 | asyncio.run(main(_file_name, _referral, _loop_invite)) 590 | -------------------------------------------------------------------------------- /make.py: -------------------------------------------------------------------------------- 1 | from web3 import Web3 2 | from eth_account import Account 3 | 4 | def make(): 5 | with open('tw.txt', 'r') as f: 6 | for row in f.readlines(): 7 | row = row.strip() 8 | pk = Account.create().key.hex() 9 | ac = Account.from_key(pk) 10 | ac_str = f'{ac.address}----{pk}----{row}\n' 11 | with open('tw_bind.txt', 'a+') as z: 12 | z.write(ac_str) 13 | 14 | if __name__ == '__main__': 15 | '''' 16 | 给购买的推特账号配对随机以太坊钱包账号 17 | 格式:地址----私钥----购买的推特的某行数据 18 | 保存到tw_bind.txt文件夹中 19 | ''' 20 | make() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | loguru>=0.7.0 2 | requests>=2.31.0 3 | Faker>=18.13.0 4 | web3>=6.5.0 5 | aiofiles>=23.2.1 6 | aiohttp>=3.8.4 7 | py-solc-x>=2.0.2 8 | httpx>=0.27.0 --------------------------------------------------------------------------------