-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontract_reader.py
More file actions
131 lines (112 loc) · 3.87 KB
/
contract_reader.py
File metadata and controls
131 lines (112 loc) · 3.87 KB
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from web3 import Web3
from datetime import datetime
import requests
# Connect ke Ethereum
rpc = "https://ethereum-rpc.publicnode.com"
w3 = Web3(Web3.HTTPProvider(rpc))
print(f"Connected: {w3.is_connected()}")
# =====================
# ABI minimal untuk ERC-20 token
# =====================
ERC20_ABI = [
{
"constant": True,
"inputs": [],
"name": "name",
"outputs": [{"name": "", "type": "string"}],
"type": "function"
},
{
"constant": True,
"inputs": [],
"name": "symbol",
"outputs": [{"name": "", "type": "string"}],
"type": "function"
},
{
"constant": True,
"inputs": [],
"name": "decimals",
"outputs": [{"name": "", "type": "uint8"}],
"type": "function"
},
{
"constant": True,
"inputs": [],
"name": "totalSupply",
"outputs": [{"name": "", "type": "uint256"}],
"type": "function"
},
{
"constant": True,
"inputs": [{"name": "_owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "balance", "type": "uint256"}],
"type": "function"
}
]
def read_token_contract(contract_address, wallet=None):
"""Baca data dari ERC-20 smart contract"""
# Checksum address
address = Web3.to_checksum_address(contract_address)
# Load contract
contract = w3.eth.contract(address=address, abi=ERC20_ABI)
print(f"\n=== SMART CONTRACT READER ===")
print(f"Update : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Address : {address}\n")
# Baca data dari contract
name = contract.functions.name().call()
symbol = contract.functions.symbol().call()
decimals = contract.functions.decimals().call()
total_supply = contract.functions.totalSupply().call()
# Format total supply
total_supply_formatted = total_supply / (10 ** decimals)
print(f"Name : {name}")
print(f"Symbol : {symbol}")
print(f"Decimals : {decimals}")
print(f"Total Supply : {total_supply_formatted:,.2f} {symbol}")
# Cek balance wallet kalau ada
if wallet:
wallet_address = Web3.to_checksum_address(wallet)
balance = contract.functions.balanceOf(wallet_address).call()
balance_formatted = balance / (10 ** decimals)
print(f"Wallet Balance: {balance_formatted:,.4f} {symbol}")
print("-" * 45)
return {
"name": name,
"symbol": symbol,
"decimals": decimals,
"total_supply": total_supply_formatted
}
def get_contract_bytecode(contract_address):
"""Cek apakah address adalah smart contract"""
address = Web3.to_checksum_address(contract_address)
bytecode = w3.eth.get_code(address)
if bytecode and bytecode != b'':
print(f"\n✅ {address} adalah Smart Contract")
print(f"Bytecode size: {len(bytecode)} bytes")
else:
print(f"\n❌ {address} bukan Smart Contract (EOA wallet)")
# =====================
# Test dengan token populer
# =====================
# USDT Contract
print("\n📋 Reading USDT Contract...")
read_token_contract(
"0xdAC17F958D2ee523a2206206994597C13D831ec7",
wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" # Vitalik wallet
)
# USDC Contract
print("\n📋 Reading USDC Contract...")
read_token_contract(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
)
# SHIB Contract
print("\n📋 Reading SHIB Contract...")
read_token_contract(
"0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE"
)
# Cek apakah address adalah contract
print("\n🔍 Contract Verification:")
get_contract_bytecode("0xdAC17F958D2ee523a2206206994597C13D831ec7") # USDT
get_contract_bytecode("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") # Vitalik wallet