Skip to content

Commit d9f4546

Browse files
committed
first commit
1 parent 68a7612 commit d9f4546

File tree

4 files changed

+218
-0
lines changed

4 files changed

+218
-0
lines changed

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"cSpell.words": ["csvfile", "standardabi"]
3+
}

main.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import sys
2+
import csv
3+
import os
4+
from web3 import Web3
5+
from standardabi import erc721_abi
6+
import polars as pl
7+
8+
erc721_abi = erc721_abi
9+
10+
# Make sure to add the correct RPC provider
11+
w3 = Web3(Web3.HTTPProvider("https://canto.slingshot.finance/"))
12+
13+
14+
def main():
15+
if len(sys.argv) != 2:
16+
print("Error: You can only enter the Contract Address")
17+
else:
18+
for arg in sys.argv[1:]:
19+
token_owners = total_supply(arg)
20+
snapshot_file = "snapshot.csv"
21+
if not os.path.exists(snapshot_file):
22+
write_to_csv(token_owners, snapshot_file)
23+
create_clean_snapshot(snapshot_file, "snapshot_clean.csv")
24+
25+
26+
def total_supply(contract):
27+
erc721_contract = w3.eth.contract(
28+
address=w3.to_checksum_address(contract), abi=erc721_abi
29+
)
30+
total_supply = erc721_contract.functions.totalSupply().call()
31+
32+
token_owners = {}
33+
for i in range(1, total_supply + 1):
34+
owner = erc721_contract.functions.ownerOf(i).call()
35+
token_owners[i] = owner
36+
37+
return token_owners
38+
39+
40+
def write_to_csv(token_owners, file_name):
41+
with open(file_name, "w", newline="") as csvfile:
42+
fieldnames = ["id", "wallet"]
43+
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
44+
45+
writer.writeheader()
46+
for token_id, wallet in token_owners.items():
47+
writer.writerow({"id": token_id, "wallet": wallet})
48+
49+
50+
def create_clean_snapshot(input_file, output_file):
51+
if not os.path.exists(output_file):
52+
df = pl.read_csv(input_file)
53+
df_clean = df.groupby("wallet").agg(pl.col("id").alias("holdings").count())
54+
df_clean.write_csv(output_file)
55+
56+
57+
if __name__ == "__main__":
58+
main()

requirements.txt

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
aiohttp==3.8.4
2+
aiosignal==1.3.1
3+
async-timeout==4.0.2
4+
attrs==22.2.0
5+
bitarray==2.7.3
6+
black==23.3.0
7+
certifi==2022.12.7
8+
charset-normalizer==3.1.0
9+
click==8.1.3
10+
cytoolz==0.12.1
11+
eth-abi==4.0.0
12+
eth-account==0.8.0
13+
eth-hash==0.5.1
14+
eth-keyfile==0.6.1
15+
eth-keys==0.4.0
16+
eth-rlp==0.3.0
17+
eth-typing==3.3.0
18+
eth-utils==2.1.0
19+
frozenlist==1.3.3
20+
hexbytes==0.3.0
21+
idna==3.4
22+
jsonschema==4.17.3
23+
lru-dict==1.1.8
24+
multidict==6.0.4
25+
mypy==1.2.0
26+
mypy-extensions==1.0.0
27+
packaging==23.1
28+
parsimonious==0.9.0
29+
pathspec==0.11.1
30+
platformdirs==3.2.0
31+
polars==0.17.2
32+
protobuf==4.22.3
33+
pycryptodome==3.17
34+
pyrsistent==0.19.3
35+
regex==2023.3.23
36+
requests==2.28.2
37+
rlp==3.0.0
38+
toolz==0.12.0
39+
typing_extensions==4.5.0
40+
urllib3==1.26.15
41+
web3==6.2.0
42+
websockets==11.0.1
43+
yarl==1.8.2

standardabi.py

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
erc721_abi = [
2+
{
3+
"inputs": [{"internalType": "address", "name": "owner", "type": "address"}],
4+
"name": "balanceOf",
5+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
6+
"payable": False,
7+
"stateMutability": "view",
8+
"type": "function",
9+
"constant": True,
10+
},
11+
{
12+
"inputs": [],
13+
"name": "name",
14+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
15+
"stateMutability": "view",
16+
"type": "function",
17+
"constant": True,
18+
},
19+
{
20+
"inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}],
21+
"name": "ownerOf",
22+
"outputs": [{"internalType": "address", "name": "", "type": "address"}],
23+
"payable": False,
24+
"stateMutability": "view",
25+
"type": "function",
26+
"constant": True,
27+
},
28+
{
29+
"inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}],
30+
"name": "tokenURI",
31+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
32+
"payable": False,
33+
"stateMutability": "view",
34+
"type": "function",
35+
"constant": True,
36+
},
37+
{
38+
"inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}],
39+
"name": "uri",
40+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
41+
"payable": False,
42+
"stateMutability": "view",
43+
"type": "function",
44+
"constant": True,
45+
},
46+
{
47+
"inputs": [],
48+
"name": "symbol",
49+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
50+
"stateMutability": "view",
51+
"type": "function",
52+
"constant": True,
53+
},
54+
{
55+
"inputs": [],
56+
"name": "totalSupply",
57+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
58+
"stateMutability": "view",
59+
"type": "function",
60+
"constant": True,
61+
},
62+
{
63+
"inputs": [
64+
{"internalType": "address", "name": "owner", "type": "address"},
65+
{"internalType": "uint256", "name": "index", "type": "uint256"},
66+
],
67+
"name": "tokenOfOwnerByIndex",
68+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
69+
"stateMutability": "view",
70+
"type": "function",
71+
},
72+
{
73+
"inputs": [{"internalType": "address", "name": "_owner", "type": "address"}],
74+
"name": "walletOfOwner",
75+
"outputs": [{"internalType": "uint256[]", "name": "", "type": "uint256[]"}],
76+
"stateMutability": "view",
77+
"type": "function",
78+
},
79+
{
80+
"inputs": [
81+
{"internalType": "address", "name": "owner", "type": "address"},
82+
{"internalType": "address", "name": "nft", "type": "address"},
83+
{"internalType": "uint256", "name": "start", "type": "uint256"},
84+
{"internalType": "uint256", "name": "end", "type": "uint256"},
85+
],
86+
"name": "getOwnerNFTs",
87+
"outputs": [{"internalType": "uint256[]", "name": "", "type": "uint256[]"}],
88+
"stateMutability": "view",
89+
"type": "function",
90+
},
91+
{
92+
"inputs": [{"internalType": "address", "name": "addr", "type": "address"}],
93+
"name": "checkAccess",
94+
"outputs": [{"internalType": "bool", "name": "val", "type": "bool"}],
95+
"stateMutability": "view",
96+
"type": "function",
97+
},
98+
{
99+
"inputs": [{"internalType": "uint256", "name": "_tokenId", "type": "uint256"}],
100+
"name": "accessAddressPerTokenId",
101+
"outputs": [
102+
{"internalType": "address[]", "name": "addresses", "type": "address[]"}
103+
],
104+
"stateMutability": "view",
105+
"type": "function",
106+
},
107+
{
108+
"inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
109+
"name": "balances",
110+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
111+
"stateMutability": "view",
112+
"type": "function",
113+
},
114+
]

0 commit comments

Comments
 (0)