web3Tools.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. from web3 import Web3, HTTPProvider, WebsocketProvider, IPCProvider
  2. import time, datetime, traceback, random, json, requests
  3. from web3.middleware import geth_poa_middleware
  4. import re
  5. import os
  6. from web3._utils.module import attach_modules
  7. from osTools import *
  8. from config import *
  9. from sqlTools import *
  10. class debug():
  11. def __init__(self):
  12. self.decodeCCAddress = '0x0000004885B7FF4bfc4dDB48e921cc25c4c877e1'
  13. self.decodeAbi = json.loads(open('abi/decode.json').read())
  14. self.decodeContract = w3.eth.contract(address=self.decodeCCAddress, abi=self.decodeAbi)
  15. def traceCall(self, fromAdd, toAdd , data, value = 0 , blockNumber = 'latest'):
  16. if type(blockNumber) == int:
  17. blockNumber = hex(blockNumber)
  18. value = hex(int(value))
  19. try:
  20. r = w3.provider.make_request('debug_traceCall', [
  21. {
  22. 'from': fromAdd,
  23. 'to': toAdd,
  24. 'data': data,
  25. 'value':value,
  26. },
  27. blockNumber,
  28. {
  29. "tracer": "callTracer", "timeout" : '0.1s'
  30. }
  31. ])
  32. return r['result']
  33. except BaseException as err:
  34. print('trace err', r)
  35. return False
  36. def traceTransaction(self, hash):
  37. try:
  38. return w3.provider.make_request('debug_traceTransaction', [hash, {
  39. "tracer": "callTracer", "timeout" : '1s'
  40. }])['result']
  41. except:
  42. return False
  43. def functionDecodeFromCallData(self, data):
  44. tradeInfo = []
  45. for call in (data):
  46. try:
  47. #print(call['input'])
  48. if 'calls' in call:
  49. tradeInfo = tradeInfo + self.functionDecodeFromCallData(call['calls'])
  50. inputData = call['input']
  51. function = inputData[0:10]
  52. if function == '0x60806040':
  53. continue
  54. #空input无效
  55. if inputData == '0x':
  56. continue
  57. callType = call['type']
  58. toAdd = call['to']
  59. #空地址调用无效
  60. if toAdd[:38] == '0x000000000000000000000000000000000000':
  61. continue
  62. fromAdd = call['from']
  63. functionInput, decodeInput = self.decodeContract.decode_function_input(inputData)
  64. outPut = self.decodeOutput(call['output'])
  65. print(fromAdd, toAdd, functionInput, decodeInput, outPut)
  66. if str(functionInput) == '<Function transfer(address,uint256)>':
  67. #printTime(toAdd, fromAdd, decodeInput['dst'], decodeInput['wad'])
  68. tradeInfo.append({
  69. 'token': toAdd.lower(),
  70. 'from': fromAdd.lower(),
  71. 'to': decodeInput['dst'].lower(),
  72. 'amount': decodeInput['wad']})
  73. if str(functionInput) == '<Function transferFrom(address,address,uint256)>':
  74. #printTime(toAdd, decodeInput['src'], decodeInput['dst'], decodeInput['wad'])
  75. tradeInfo.append({
  76. 'token': toAdd.lower(),
  77. 'from': decodeInput['src'].lower(),
  78. 'to': decodeInput['dst'].lower(),
  79. 'amount': decodeInput['wad']})
  80. #print(functionInput, decodeInput, toAdd, outPut)
  81. except:
  82. #print('err', inputData, toAdd)
  83. continue
  84. return tradeInfo
  85. def decodeOutput(self, outputData):
  86. info = []
  87. outputData = outputData[2:]
  88. i = 0
  89. iMax = len(outputData) / 64
  90. while i < iMax:
  91. r = outputData[(0 + 64 * i):(64 + 64 * i)]
  92. if int(r[:24], 16) == 0 and int(r[24:28], 16) != 0:
  93. r = '0x' + r[24:]
  94. else :
  95. r = int(r, 16)
  96. info.append(r)
  97. i = i + 1
  98. return info
  99. def transferDecodeFromCalldata(self, calldata):
  100. tradeInfo = []
  101. for call in (calldata):
  102. if 'calls' in call:
  103. tradeInfo = tradeInfo + self.transferDecodeFromCalldata(call['calls'])
  104. inputData = call['input']
  105. function = inputData[0:10]
  106. toAdd = call['to']
  107. fromAdd = call['from']
  108. if 'value' in call:
  109. value = int(call['value'],16)
  110. if value != 0 :
  111. tradeInfo.append({
  112. 'token': '0xethw',
  113. 'from': fromAdd.lower(),
  114. 'to': toAdd.lower(),
  115. 'amount': value})
  116. try:
  117. #'<Function transferFrom(address,address,uint256)>'
  118. if function == '0x23b872dd':
  119. tradeInfo.append({
  120. 'token':toAdd,
  121. 'from':'0x' + inputData[34:74],
  122. 'to': '0x' + inputData[34 + 64:74+ 64],
  123. 'amount':int(inputData[34 + 64 *2 :74+ 64 *2 ],16)})
  124. #'<Function transfer(address,uint256)>'
  125. if function == '0xa9059cbb':
  126. tradeInfo.append({
  127. 'token':toAdd,
  128. 'from':fromAdd,
  129. 'to': '0x' + inputData[34 :74],
  130. 'amount':int(inputData[34 + 64 :74+ 64],16)})
  131. except:
  132. print('trace err', inputData)
  133. return tradeInfo
  134. def transferDecodeHashFromLogs(self, hs):
  135. r = w3.eth.getTransactionReceipt(hs)
  136. tradeInfo = []
  137. for logI in r['logs']:
  138. toAdd = logI['address'].lower()
  139. data = logI['data']
  140. if len(logI['topics']) == 3 and logI['topics'][0].hex() == '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef':
  141. tradeInfo.append({
  142. 'token':toAdd,
  143. 'from':'0x' + logI['topics'][1].hex()[26:],
  144. 'to': '0x' + logI['topics'][2].hex()[26:],
  145. 'amount':int(data,16)})
  146. if len(logI['topics']) == 2 and logI['topics'][
  147. 0].hex() == '0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c':
  148. tradeInfo.append({
  149. 'token': '0xeth',
  150. 'from': '0x',
  151. 'to': '0x' + logI['topics'][1].hex()[26:],
  152. 'amount': int(data, 16)})
  153. if len(logI['topics']) == 2 and logI['topics'][
  154. 0].hex() == '0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65':
  155. tradeInfo.append({
  156. 'token': '0xeth',
  157. 'from': '0x',
  158. 'to': '0x' + logI['topics'][1].hex()[26:],
  159. 'amount': int(data, 16)})
  160. return tradeInfo
  161. def transferDecodeHashFromTrace2(self, data):
  162. tradeInfo = []
  163. for call in data:
  164. try:
  165. if 'calls' in call:
  166. tradeInfoi = self.transferDecodeHashFromTrace2(call['calls'])
  167. if tradeInfoi:
  168. tradeInfo = tradeInfo + tradeInfoi
  169. inputData = call['input']
  170. function = inputData[0:10]
  171. callType = call['type']
  172. toAdd = call['to']
  173. value = int(call['value'],16)
  174. fromAdd = call['from']
  175. if value > 1e9:
  176. tradeInfo.append({
  177. 'token': '0xethw',
  178. 'from': fromAdd.lower(),
  179. 'to': toAdd.lower(),
  180. 'amount': value})
  181. continue
  182. functionInput, decodeInput = self.decodeContract.decode_function_input(inputData)
  183. outPut = self.decodeOutput(call['output'])
  184. if str(functionInput) == '<Function transfer(address,uint256)>':
  185. tradeInfo.append({
  186. 'token': toAdd.lower(),
  187. 'from': fromAdd.lower(),
  188. 'to': decodeInput['dst'].lower(),
  189. 'amount': decodeInput['wad']})
  190. if str(functionInput) == '<Function transferFrom(address,address,uint256)>':
  191. #print(toAdd, decodeInput['src'], decodeInput['dst'], decodeInput['wad'])
  192. tradeInfo.append({
  193. 'token': toAdd.lower(),
  194. 'from': decodeInput['src'].lower(),
  195. 'to': decodeInput['dst'].lower(),
  196. 'amount': decodeInput['wad']})
  197. if str(functionInput) == '<Function withdraw(uint256)>':
  198. #print(toAdd, decodeInput['src'], decodeInput['dst'], decodeInput['wad'])
  199. tradeInfo.append({
  200. 'token': toAdd.lower(),
  201. 'from': fromAdd.lower(),
  202. 'to': toAdd.lower(),
  203. 'amount': decodeInput['wad']})
  204. except:
  205. continue
  206. return tradeInfo
  207. def transferDecodeHashFromTrace(self, hs):
  208. try:
  209. r = self.traceTransaction(hs)
  210. tradeInfo = []
  211. value = int(r['value'], 16)
  212. fromAdd = r['from']
  213. toAdd = r['to']
  214. if value > 1e9:
  215. tradeInfo.append({
  216. 'token': '0xethw',
  217. 'from': fromAdd.lower(),
  218. 'to': toAdd.lower(),
  219. 'amount': value})
  220. if 'calls' in r:
  221. tradeInfo = tradeInfo + self.transferDecodeFromCalldata(r['calls'])
  222. return tradeInfo
  223. except:
  224. return []
  225. class dex():
  226. def __init__(self):
  227. toolsddress = '0xDE93d2cd45b7E0056671A542FfB4343DFd67dA51'
  228. toolsAbi = json.loads(open('abi/tools.json').read())
  229. self.abi = toolsAbi
  230. self.contractAddress = w3.toChecksumAddress(toolsddress)
  231. self.contract = w3.eth.contract(address=self.contractAddress, abi=self.abi)
  232. def getTokenBalance(self, address, token, block = 'latest'):
  233. address = address.replace('0x', '')
  234. data = "0x70a08231000000000000000000000000" + address
  235. r = web3Call(myAddress, token, data, block)
  236. r = int(r, 16)
  237. return r
  238. def getERC20Info(self, address):
  239. address = w3.toChecksumAddress(address)
  240. abi = json.loads(open('abi/ERC20.json').read())
  241. contractAddress = w3.toChecksumAddress(address)
  242. contract = w3.eth.contract(address=contractAddress, abi=abi)
  243. decimals = contract.functions.decimals().call()
  244. name = contract.functions.name().call()
  245. symbol = contract.functions.symbol().call()
  246. try:
  247. name = re.sub(r'[^A-Za-z0-9 ]+', '', name)
  248. except:
  249. name = 'T' + address[2:6]
  250. try:
  251. symbol = re.sub(r'[^A-Za-z0-9 ]+', '', symbol)
  252. except:
  253. symbol = 'T' + address[2:6]
  254. return {'name': name, 'symbol': symbol, 'decimals': decimals}
  255. def getFactory(self, address, block = 'latest'):
  256. address = w3.toChecksumAddress(address)
  257. info = self.contract.functions.getFactory(address).call(block_identifier = block)
  258. return info
  259. def getTotalPairV2(self, address, block = 'latest'):
  260. address = w3.toChecksumAddress(address)
  261. info = self.contract.functions.getTotalPair(address,).call(block_identifier = block)
  262. return info
  263. def getPairAddSV2(self, factoryAddr, token0, token1, block = 'latest'):
  264. addressNew = factoryAddr
  265. data = {}
  266. inputData = '0x8979b282' + encodeInput(0x60, token0, token1, addressNew)
  267. info = web3Call(toolsAddress, toolsAddress, inputData, block)
  268. info = w3.debug.decodeOutput(info)
  269. for i in range(0, len(addressNew)):
  270. fee = topFactoryFee[addressNew[i].lower()]
  271. address = info[i + 2]
  272. if address == 0:
  273. continue
  274. data[address] = fee
  275. return data
  276. def getPairFromIdSInfoV2(self, facrotyAddress, ids, block = 'latest'):
  277. facrotyAddress = w3.toChecksumAddress(facrotyAddress)
  278. info = self.contract.functions.getPairIdSInfo(facrotyAddress, ids).call(block_identifier = block)
  279. return info
  280. def getPairSBalance(self, addressNew, block = 'latest'):
  281. inputData = '0xd94ccee1' + encodeInput(0x20, addressNew)
  282. r = web3Call(myAddress, toolsAddress, inputData, block)
  283. r = w3.debug.decodeOutput(r)
  284. info = {}
  285. length = len(addressNew)
  286. for index in range(0, length):
  287. lpAddress = addressNew[index]
  288. r0 = r[index + 3]
  289. r1 = r[index + 4 + length]
  290. info[lpAddress] = [r0, r1]
  291. return info
  292. def getPairAddV3AllFee(self, token0Address , token1Address, block = 'latest'):
  293. fee = [100,500,3000,10000]
  294. data = {}
  295. token0Address = w3.toChecksumAddress(token0Address)
  296. token1Address = w3.toChecksumAddress(token1Address)
  297. for feeI in fee:
  298. try:
  299. info = self.contract.functions.getPoolV3(token0Address, token1Address, feeI).call(block_identifier = block)
  300. if info != '0x0000000000000000000000000000000000000000':
  301. data[info] = feeI
  302. except:
  303. info = '0x'
  304. return data
  305. def getPairAddV3(self, token0Address, token1Address, fee, block = 'latest'):
  306. token0Address = w3.toChecksumAddress(token0Address)
  307. token1Address = w3.toChecksumAddress(token1Address)
  308. info = self.contract.functions.getPoolV3(token0Address, token1Address, fee).call(block_identifier = block)
  309. return info
  310. def getPairInfoFromIdV3(self, ids, block = 'latest'):
  311. info = self.contract.functions.getPairInfoV3(ids).call(block_identifier = block)
  312. return info
  313. def getAmountOutV3(self, tokenIn, tokenOut, fee, amountIn, block = 'latest'):
  314. tokenIn = w3.toChecksumAddress(tokenIn)
  315. tokenOut = w3.toChecksumAddress(tokenOut)
  316. fee = int(fee)
  317. amountIn = int(amountIn)
  318. try:
  319. info = self.contract.functions.getAmountOutV3(tokenIn, tokenOut, fee, amountIn, 0).call(block_identifier = block)
  320. except:
  321. info = 0
  322. return info
  323. def getAmountInV3(self, tokenIn, tokenOut, fee, amountOut, block = 'latest'):
  324. tokenIn = w3.toChecksumAddress(tokenIn)
  325. tokenOut = w3.toChecksumAddress(tokenOut)
  326. fee = int(fee)
  327. amountOut = int(amountOut)
  328. try:
  329. info = self.contract.functions.getAmountOutV3(tokenIn, tokenOut, fee, amountOut, 0).call(block_identifier = block)
  330. except:
  331. info = 0
  332. return info
  333. class new():
  334. def resultManager(self, result):
  335. if 'error' in result:
  336. raise NameError(result['error'])
  337. if 'result' in result:
  338. return result['result']
  339. return False
  340. def getBlock(self, blockNumber = 'pending', state = False):
  341. if blockNumber == 'pending' or blockNumber == 'latest':
  342. blockNumber = blockNumber
  343. elif type(blockNumber) == str and blockNumber[:2] != '0x':
  344. blockNumber = int(blockNumber)
  345. elif type(blockNumber) == int:
  346. blockNumber = hex(blockNumber)
  347. r = w3.provider.make_request('eth_getBlockByNumber', params=[blockNumber, state])
  348. return self.resultManager(r)
  349. def getTransaction(self, hash):
  350. r = w3.provider.make_request('eth_getTransactionByHash', params=[hash])
  351. return self.resultManager(r)
  352. def getTransactionReceipt(self, hash):
  353. r = w3.provider.make_request('eth_getTransactionReceipt', params=[hash])
  354. return self.resultManager(r)
  355. def blcokNumber(self):
  356. r = w3.provider.make_request('eth_blockNumber', params=[])
  357. return int(self.resultManager(r),16)
  358. def sendTransaction(self, fromAdd, toAdd, inputData, nonce, gasPrice, gasLimit):
  359. params = {}
  360. params['from'] = fromAdd
  361. params['to'] = toAdd
  362. params['data'] = inputData
  363. params['nonce'] = hex(int(nonce))
  364. params['gasPrice'] = hex(int(gasPrice))
  365. params['gas'] = hex(int(gasLimit))
  366. params['value'] = hex(0)
  367. params['chainId'] = hex(10001)
  368. r = w3.provider.make_request('eth_sendTransaction', params=[params])
  369. try:
  370. hs = self.resultManager(r)
  371. printTime('https://www.oklink.com/en/ethw/tx/' + str(hs))
  372. return str(hs)
  373. except BaseException as err:
  374. printTime('sendTransaction err', params['from'], params['nonce'], err)
  375. return False
  376. def getTransactionCount(self, address, blockNumber = "latest"):
  377. r = w3.provider.make_request('eth_getTransactionCount', [address, blockNumber])
  378. return self.resultManager(r)
  379. def getPendingTxpool():
  380. try:
  381. data = json.dumps({
  382. 'jsonrpc': '2.0',
  383. 'method': 'txpool_content',
  384. 'params': [],
  385. 'id': int(time.time() * 1000)
  386. })
  387. headers = {'Content-type': 'application/json'}
  388. rspnow = requests.post(url, data=data, headers=headers).json()
  389. transactionArray = []
  390. for x in rspnow['result']['pending']:
  391. addressTransaction = (rspnow['result']['pending'][x])
  392. for addressTransactioni in addressTransaction.values():
  393. transactionArray.append(addressTransactioni)
  394. return transactionArray
  395. except BaseException as err:
  396. print(traceback.format_exc())
  397. print(err)
  398. def getBaseGasPrice(blockNumber = 'pending'):
  399. try:
  400. return int(w3.new.getBlock(blockNumber)['baseFeePerGas'],16)
  401. except:
  402. return w3.eth.gasPrice
  403. def getTokenTradeFromBlock(blockNumber):
  404. tokenArray = []
  405. info = w3.eth.getBlock(blockNumber, True)
  406. info = (info['transactions'])
  407. for hsI in info:
  408. try:
  409. hsInfo = {}
  410. hsInfo['block'] = hsI['blockNumber']
  411. hsInfo['gasUsed'] = hsI['gas']
  412. hsInfo['fromAdd'] = hsI['from'].lower()
  413. hsInfo['toAdd'] = str(hsI['to']).lower()
  414. hsInfo['input'] = hsI['input']
  415. hsInfo['value'] = hsI['value']
  416. hsInfo['nonce'] = hsI['nonce'] # 对比nonce
  417. hsInfo['function'] = hsInfo['input'][:10]
  418. hsInfo['hs'] = hsI['hash'].hex()
  419. # 创建合约
  420. if hsInfo['gasUsed'] < 90000:
  421. continue
  422. if hsInfo['function'] == '0x77c46431' or hsInfo['function'] == '0x60806040':
  423. continue
  424. if hsInfo['input'] == '0x':
  425. continue
  426. if len(hsInfo['input']) < 76:
  427. continue
  428. if len(hsInfo['input']) > 64 * 64:
  429. continue
  430. # opensea
  431. if hsInfo['toAdd'] == '0x00000000006c3852cbef3e08e8df289169ede581':
  432. continue
  433. # X2Y2
  434. if hsInfo['toAdd'] == '0x74312363e45dcaba76c59ec49a7aa8a65a67eed3':
  435. continue
  436. tradeInfo = w3.debug.transferDecodeHashFromLogs(hsInfo['hs'])
  437. #tradeInfo = w3.debug.transferDecodeHashFromTrace(hsInfo['hs'])
  438. if tradeInfo:
  439. # 进行了token交易或者转载两次
  440. if len(tradeInfo) < 2:
  441. continue
  442. # 是否来来回交易
  443. tokenAyyay = []
  444. tradeType = False
  445. for tradeI in tradeInfo:
  446. token = tradeI['token']
  447. fromAdd = tradeI['from']
  448. to = tradeI['to']
  449. if token not in tokenAyyay:
  450. tokenAyyay.append(token)
  451. for tradeII in tradeInfo:
  452. fromAddI = tradeII['from']
  453. toI = tradeII['to']
  454. if fromAdd == toI or to == fromAddI:
  455. tradeType = True
  456. break
  457. if not tradeType:
  458. continue
  459. # 是否有两个币交易过
  460. if len(tokenAyyay) < 2:
  461. continue
  462. for tradeI in tradeInfo:
  463. token = tradeI['token']
  464. if token == '0xeth':
  465. continue
  466. if token in tokenArray:
  467. continue
  468. tokenArray.append(token)
  469. except BaseException as err:
  470. continue
  471. return tokenArray
  472. def web3Call(fromAddress, toAddress = None, inputData = None, blockNumber = 'latest'):
  473. if type(fromAddress) == dict:
  474. input = fromAddress
  475. else:
  476. input = {'from': fromAddress, 'to':toAddress, 'data':inputData}
  477. if type(blockNumber) == int:
  478. blockNumber = hex(blockNumber)
  479. r = w3.provider.make_request('eth_call', params=[input, blockNumber])
  480. if 'result' in r:
  481. return r['result']
  482. else:
  483. raise NameError(r)
  484. def encodeInput(*array):
  485. data = ''
  486. for i in array:
  487. if type(i) == str:
  488. if len(i) > 64:
  489. i = i.replace('0x', '')
  490. times = int(len(i) / 64 ) + 1
  491. i = i.ljust(64*times, '0')
  492. else:
  493. i = i.replace('0x', '').rjust(64, '0')
  494. data = data + i
  495. elif type(i) == int:
  496. i = hex((i)).replace('0x', '').rjust(64, '0')
  497. data = data + i
  498. elif type(i) == float:
  499. i = hex(int(i)).replace('0x', '').rjust(64, '0')
  500. data = data + i
  501. elif type(i) == list:
  502. data = data + hex(len(i)).replace('0x', '').rjust(64, '0')
  503. for j in i:
  504. data = data + encodeInput(j)
  505. return data
  506. def encodeFunction( string):
  507. string = w3.toBytes(text=string)
  508. string = w3.sha3(string)
  509. string = w3.toHex(string)
  510. string = string[:10]
  511. return string
  512. def batchCall(paramsDataArray ,blockNumber = 'latest'):
  513. if blockNumber == 'pending' or blockNumber == 'latest':
  514. blockNumber = blockNumber
  515. elif type(blockNumber) == str and blockNumber[:2] != '0x':
  516. blockNumber = int(blockNumber)
  517. elif type(blockNumber) == int:
  518. blockNumber = hex(blockNumber)
  519. if type(paramsDataArray) != list:
  520. paramsDataArray = [paramsDataArray]
  521. r = w3.provider.make_request('eth_batchCall', [{"Block": blockNumber, "Calls": paramsDataArray}])
  522. return r
  523. def decodeBatchCall(result):
  524. info = []
  525. for i in result:
  526. if 'Return' in i:
  527. info.append(w3.debug.decodeOutput(i['Return']))
  528. return info
  529. #url = 'http://3.227.34.41:18545'
  530. #w3 = Web3(WebsocketProvider('ws://127.0.0.1:8546'))
  531. w3= Web3(IPCProvider('/ethereum_pow_800/data/geth.ipc'))
  532. attach_modules(w3, {"debug": (debug,)})
  533. attach_modules(w3, {"dex": (dex,)})
  534. attach_modules(w3, {"new": (new,)})
  535. printTime('Web3:OK', )
  536. printTime('Now Block Number:', w3.eth.blockNumber, 'Now Gas:', getBaseGasPrice())