Spaces:
Running
Running
Commit
·
cfb38a1
1
Parent(s):
3cf2443
Add application file
Browse files- .DS_Store +0 -0
- data/.DS_Store +0 -0
- data/config.ini +0 -1
- data/eths_data.db +0 -0
- data/ethscriptions_data.db +2 -2
- data/huggingface_name_code.py +275 -0
- data/huggingface_token_code.py +259 -0
- data/python_name_code.py +201 -0
- data/python_token_code.py +189 -0
- pages/.DS_Store +0 -0
- pages/2_🆔_ 批量题写域名铭文.py +200 -154
- pages/3_🪙_ 批量题写代币铭文.py +202 -156
- pages/6_📢_推送通知服务.py +1 -0
- pages/7_ℹ️️_关于 EthPen.com.py +3 -0
- 🖊️EthPen-以太之笔.py +2 -977
.DS_Store
CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
|
|
data/.DS_Store
CHANGED
Binary files a/data/.DS_Store and b/data/.DS_Store differ
|
|
data/config.ini
CHANGED
@@ -1,3 +1,2 @@
|
|
1 |
[thread_start_state]
|
2 |
state = 0
|
3 |
-
|
|
|
1 |
[thread_start_state]
|
2 |
state = 0
|
|
data/eths_data.db
CHANGED
Binary files a/data/eths_data.db and b/data/eths_data.db differ
|
|
data/ethscriptions_data.db
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2aa2e9d27d60d328f874d31297df4af05e340f629f8a99f8047c482cf4a67c27
|
3 |
+
size 400236544
|
data/huggingface_name_code.py
ADDED
@@ -0,0 +1,275 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 9 月 5 日
|
3 |
+
|
4 |
+
|
5 |
+
# 导入运行代码所需要的库
|
6 |
+
import streamlit as st # streamlit app
|
7 |
+
from web3 import Web3 # 与以太坊交互的库
|
8 |
+
import hashlib # 用于数据哈希
|
9 |
+
import requests # 用于发送网络请求
|
10 |
+
import re # 用于正则表达式
|
11 |
+
import time # 用于时间相关
|
12 |
+
import os # 用于操作系统文件
|
13 |
+
|
14 |
+
|
15 |
+
# 许可使用开关
|
16 |
+
approved_use = False
|
17 |
+
|
18 |
+
|
19 |
+
# 检查 ETH 地址是否有效
|
20 |
+
def is_valid_eth_address(address):
|
21 |
+
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
22 |
+
return True
|
23 |
+
return False
|
24 |
+
|
25 |
+
|
26 |
+
# 检查 Ethereum 私钥是否有效
|
27 |
+
def is_valid_eth_private_key(private_key):
|
28 |
+
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
29 |
+
return True
|
30 |
+
return False
|
31 |
+
|
32 |
+
|
33 |
+
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
34 |
+
def validate_input(data_str):
|
35 |
+
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
36 |
+
return False
|
37 |
+
return True
|
38 |
+
|
39 |
+
|
40 |
+
# 分隔文本函数
|
41 |
+
def split_and_append(ethscriptions_str, name_selected_option):
|
42 |
+
separators = [' ', '\n', ',']
|
43 |
+
split_texts = [ethscriptions_str] # 初始时只有一个完整文本
|
44 |
+
|
45 |
+
for sep in separators:
|
46 |
+
pieces = []
|
47 |
+
for text in split_texts:
|
48 |
+
pieces.extend(text.split(sep))
|
49 |
+
split_texts = pieces
|
50 |
+
|
51 |
+
# 移除空字符串
|
52 |
+
split_texts = [text.strip() + name_selected_option for text in split_texts if text.strip() != '']
|
53 |
+
|
54 |
+
return split_texts
|
55 |
+
|
56 |
+
|
57 |
+
# 把文字转换成 16 进制
|
58 |
+
def text_to_hex(text):
|
59 |
+
return ''.join(format(byte, '02x') for byte in text.encode('utf-8'))
|
60 |
+
|
61 |
+
|
62 |
+
# 使用sha256算法计算哈希
|
63 |
+
def sha256(input_string):
|
64 |
+
sha256 = hashlib.sha256()
|
65 |
+
sha256.update(input_string.encode('utf-8'))
|
66 |
+
return sha256.hexdigest()
|
67 |
+
|
68 |
+
|
69 |
+
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
70 |
+
def check_content_exists(sha):
|
71 |
+
# 定义请求的网址
|
72 |
+
endpoint = f"/ethscriptions/exists/{sha}"
|
73 |
+
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
74 |
+
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
75 |
+
if response.status_code == 200:
|
76 |
+
return response.json()['result']
|
77 |
+
|
78 |
+
|
79 |
+
# 发送自己到自己 0ETH 的交易
|
80 |
+
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
81 |
+
|
82 |
+
# 设置交易的相关信息
|
83 |
+
tx = {
|
84 |
+
'chainId': chain_id, # 网络 ID
|
85 |
+
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
86 |
+
'gasPrice': gas_price, # gas 的价格
|
87 |
+
'nonce': current_nonce,
|
88 |
+
'to': account_address, # 接收地址为自己
|
89 |
+
'value': 0, # 金额为 0ETH
|
90 |
+
'data': text_to_hex(input_data), # 铭文内容
|
91 |
+
}
|
92 |
+
|
93 |
+
# 用私钥签名这个交易
|
94 |
+
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
95 |
+
# 发送签名后的交易并获取交易哈希
|
96 |
+
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
97 |
+
# 打印结果信息
|
98 |
+
st.toast(f'{input_data}', icon='✅')
|
99 |
+
# 返回铭文还有交易哈希
|
100 |
+
return input_data, tx_hash.hex()
|
101 |
+
|
102 |
+
|
103 |
+
# 网页前端显示
|
104 |
+
st.set_page_config(page_title="EthPen - 批量题写域名铭文", page_icon="🆔", layout='centered', initial_sidebar_state='auto')
|
105 |
+
|
106 |
+
# 网页标题
|
107 |
+
st.subheader(r'🆔 :rainbow[EthPen - 域名铭文批量题写]', anchor=False, divider='rainbow')
|
108 |
+
|
109 |
+
# 提醒
|
110 |
+
st.markdown('### 在开始使用前,请仔细阅读相关说明,并在确认无误后打上 ✅。感谢您的理解与配合。')
|
111 |
+
|
112 |
+
open_source = st.checkbox('我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[2_🆔_批量题写域名铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)',)
|
113 |
+
|
114 |
+
ask_ai = st.checkbox('如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。',)
|
115 |
+
|
116 |
+
huggingface = st.checkbox('复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。',)
|
117 |
+
|
118 |
+
site = st.checkbox('请务必确保你正在访问的是 **[EthPen.com](https://ethpen.com)** 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。',)
|
119 |
+
|
120 |
+
use = st.checkbox('在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。',)
|
121 |
+
|
122 |
+
wallet = st.checkbox('为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。',)
|
123 |
+
|
124 |
+
test = st.checkbox('首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络��用。',)
|
125 |
+
|
126 |
+
feedback = st.checkbox('若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。',)
|
127 |
+
|
128 |
+
if open_source and ask_ai and huggingface and site and use and wallet and test and feedback:
|
129 |
+
approved_use = True
|
130 |
+
else:
|
131 |
+
approved_use = False
|
132 |
+
|
133 |
+
if approved_use:
|
134 |
+
|
135 |
+
st.markdown('## 批量题写域名铭文')
|
136 |
+
|
137 |
+
# 连接的网络 ID。比如说,1 代表主网络,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
138 |
+
net_options = {
|
139 |
+
'1': 'Mainnet',
|
140 |
+
'5': 'Goerli',
|
141 |
+
'11155111': 'Sepolia'
|
142 |
+
}
|
143 |
+
selected_option = st.selectbox(
|
144 |
+
'**网络 ID**',
|
145 |
+
list(net_options.keys()),
|
146 |
+
format_func=lambda x: f"{x} ({net_options[x]})"
|
147 |
+
)
|
148 |
+
chain_id = int(selected_option)
|
149 |
+
|
150 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
151 |
+
token_eth_prc_url = st.text_input(
|
152 |
+
f'**Ethereum PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
153 |
+
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
154 |
+
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
155 |
+
# 初始化当前账户索引为 0
|
156 |
+
current_account_index = 0
|
157 |
+
# 收集和显示所有交易的结果
|
158 |
+
transaction_results = []
|
159 |
+
# 创建账户列表
|
160 |
+
accounts = []
|
161 |
+
# 使用字典来跟踪每个地址的nonce
|
162 |
+
nonces = {}
|
163 |
+
|
164 |
+
# 启用多账户操作
|
165 |
+
multipl_accounts = st.toggle('启用**多账户**操作')
|
166 |
+
if multipl_accounts:
|
167 |
+
# 多账户的文本框
|
168 |
+
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
169 |
+
if account_list: # 如果账户列表有内容
|
170 |
+
for line in account_list.split('\n'): # 根据换行符划分账户
|
171 |
+
if ',' in line: # 检查是否包含逗号
|
172 |
+
address, key = line.split(',') # 分开地址和私钥
|
173 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
174 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
175 |
+
nonces[address] = current_nonce # 记录地址的 nonce
|
176 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
177 |
+
else:
|
178 |
+
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
179 |
+
st.stop()
|
180 |
+
else:
|
181 |
+
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
182 |
+
st.stop()
|
183 |
+
else:
|
184 |
+
account_address = st.text_input('填写你的 **ETH 地址**:')
|
185 |
+
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
186 |
+
if account_address and private_key: # 如果地址和私钥有内容
|
187 |
+
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
188 |
+
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
189 |
+
nonces[account_address] = current_nonce # 记录地址的 nonce
|
190 |
+
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
191 |
+
else:
|
192 |
+
st.error("地址或私钥无效,请检查!")
|
193 |
+
st.stop()
|
194 |
+
|
195 |
+
# 配置铭文文本
|
196 |
+
ethscriptions_str = st.text_area(f'输入**多个域名铭文或其他**,可以用`空格`、`换行符`、`英文逗号(,)`分开,不要带 `data:,` 前缀,不要带`域名后缀`:')
|
197 |
+
|
198 |
+
name_selected_option = st.radio("选择域名后缀:", ['🎨 自定义', '🆔.eths', '🆔.eth', '🌲.tree', '🦛.honk', '🔄.etch', '🌐.com'], index=1, horizontal=True)
|
199 |
+
if name_selected_option == '🎨 自定义':
|
200 |
+
name_selected_option = st.text_input('输入**域名后缀**:')
|
201 |
+
|
202 |
+
# 以空格、换行符、英文逗号分隔文本并加上后缀
|
203 |
+
ethscription_list = split_and_append(ethscriptions_str, name_selected_option)
|
204 |
+
|
205 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
206 |
+
if not validate_input(''.join(ethscription_list)):
|
207 |
+
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
208 |
+
|
209 |
+
token_check = st.toggle('题写前**检查是否被题写** `主网` `查重`')
|
210 |
+
# 题写铭文之前检查该铭文有没有被题写
|
211 |
+
if token_check:
|
212 |
+
token_check = True
|
213 |
+
else:
|
214 |
+
token_check = False
|
215 |
+
sleep_3s = st.toggle('每次完成交易后暂停 3 秒')
|
216 |
+
# 每次交易成功后暂停 3 秒
|
217 |
+
if sleep_3s:
|
218 |
+
sleep_3s = True
|
219 |
+
else:
|
220 |
+
sleep_3s = False
|
221 |
+
|
222 |
+
# 点击发送交易开始
|
223 |
+
if st.button(f'开始**发送交易**'):
|
224 |
+
if not accounts or not ethscriptions_str or not name_selected_option: # 检查是否留空
|
225 |
+
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
226 |
+
st.stop()
|
227 |
+
else:
|
228 |
+
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
229 |
+
|
230 |
+
st.toast(f'开始任务,需要题写的铭文总量为:{len(ethscription_list)}', icon='😎')
|
231 |
+
|
232 |
+
# 对代币铭文 id 进行循环
|
233 |
+
for name_str in ethscription_list:
|
234 |
+
# 使用当前账户发送交易,获取当前账户的 nonce
|
235 |
+
address, key = accounts[current_account_index]
|
236 |
+
# 获取 gas
|
237 |
+
gas_price = w3.eth.gas_price
|
238 |
+
# 得到完整的铭文文本
|
239 |
+
if not name_str.startswith('data:,'):
|
240 |
+
input_data = f'data:,{name_str}'
|
241 |
+
|
242 |
+
# 根据是否检查的开关进行
|
243 |
+
if token_check:
|
244 |
+
# 这里是开了检查后请求 Ethscriptions API
|
245 |
+
if check_content_exists(sha256(input_data)):
|
246 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
247 |
+
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
248 |
+
else:
|
249 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
250 |
+
# 使用 current_nonce 发送交易
|
251 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
252 |
+
# 记录最后输出的结果
|
253 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
254 |
+
# 交易成功后,手动增加 nonce 值
|
255 |
+
nonces[address] += 1
|
256 |
+
else:
|
257 |
+
# 这里是未开检查后直接发送交易
|
258 |
+
# 使用 current_nonce 发送交易
|
259 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
260 |
+
# 记录最后输出的结果
|
261 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
262 |
+
# 交易成功后,手动增加 nonce 值
|
263 |
+
nonces[address] += 1
|
264 |
+
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
265 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
266 |
+
# 暂停 3 秒
|
267 |
+
if sleep_3s:
|
268 |
+
time.sleep(3) # 暂停三秒
|
269 |
+
st.toast(f'所有任务已经完成。', icon='🎉')
|
270 |
+
# 庆祝动画
|
271 |
+
st.balloons()
|
272 |
+
# 显示所有交易的结果
|
273 |
+
st.code('\n'.join(transaction_results))
|
274 |
+
else:
|
275 |
+
st.error('# 阅读并打勾 ✅ 后方可使用。')
|
data/huggingface_token_code.py
ADDED
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 9 月 5 日
|
3 |
+
|
4 |
+
|
5 |
+
# 导入运行代码所需要的库
|
6 |
+
import streamlit as st # streamlit app
|
7 |
+
from web3 import Web3 # 与以太坊交互的库
|
8 |
+
import hashlib # 用于数据哈希
|
9 |
+
import requests # 用于发送网络请求
|
10 |
+
import re # 用于正则表达式
|
11 |
+
import time # 用于时间相关
|
12 |
+
import os # 用于操作系统文件
|
13 |
+
|
14 |
+
|
15 |
+
# 许可使用开关
|
16 |
+
approved_use = False
|
17 |
+
|
18 |
+
|
19 |
+
# 检查 ETH 地址是否有效
|
20 |
+
def is_valid_eth_address(address):
|
21 |
+
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
22 |
+
return True
|
23 |
+
return False
|
24 |
+
|
25 |
+
|
26 |
+
# 检查 Ethereum 私钥是否有效
|
27 |
+
def is_valid_eth_private_key(private_key):
|
28 |
+
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
29 |
+
return True
|
30 |
+
return False
|
31 |
+
|
32 |
+
|
33 |
+
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
34 |
+
def validate_input(data_str):
|
35 |
+
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
36 |
+
return False
|
37 |
+
return True
|
38 |
+
|
39 |
+
|
40 |
+
# 把文字转换成 16 进制
|
41 |
+
def text_to_hex(text):
|
42 |
+
return ''.join(format(byte, '02x') for byte in text.encode('utf-8'))
|
43 |
+
|
44 |
+
|
45 |
+
# 使用sha256算法计算哈希
|
46 |
+
def sha256(input_string):
|
47 |
+
sha256 = hashlib.sha256()
|
48 |
+
sha256.update(input_string.encode('utf-8'))
|
49 |
+
return sha256.hexdigest()
|
50 |
+
|
51 |
+
|
52 |
+
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
53 |
+
def check_content_exists(sha):
|
54 |
+
# 定义请求的网址
|
55 |
+
endpoint = f"/ethscriptions/exists/{sha}"
|
56 |
+
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
57 |
+
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
58 |
+
if response.status_code == 200:
|
59 |
+
return response.json()['result']
|
60 |
+
|
61 |
+
|
62 |
+
# 发送自己到自己 0ETH 的交易
|
63 |
+
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
64 |
+
|
65 |
+
# 设置交易的相关信息
|
66 |
+
tx = {
|
67 |
+
'chainId': chain_id, # 网络 ID
|
68 |
+
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
69 |
+
'gasPrice': gas_price, # gas 的价格
|
70 |
+
'nonce': current_nonce,
|
71 |
+
'to': account_address, # 接收地址为自己
|
72 |
+
'value': 0, # 金额为 0ETH
|
73 |
+
'data': text_to_hex(input_data), # 铭文内容
|
74 |
+
}
|
75 |
+
|
76 |
+
# 用私钥签名这个交易
|
77 |
+
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
78 |
+
# 发送签名后的交易并获取交易哈希
|
79 |
+
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
80 |
+
# 打印结果信息
|
81 |
+
st.toast(f'{input_data}', icon='✅')
|
82 |
+
# 返回铭文还有交易哈希
|
83 |
+
return input_data, tx_hash.hex()
|
84 |
+
|
85 |
+
|
86 |
+
# 网页前端显示
|
87 |
+
st.set_page_config(page_title="EthPen - 批量题写代币铭文", page_icon="🪙", layout='centered', initial_sidebar_state='auto')
|
88 |
+
|
89 |
+
# 网页标题
|
90 |
+
st.subheader(r'🪙 :rainbow[EthPen - 代币铭文批量题写]', anchor=False, divider='rainbow')
|
91 |
+
|
92 |
+
# 提醒
|
93 |
+
st.markdown('### 在开始使用前,请仔细阅读相关说明,并在确认无误后打上 ✅。感谢您的理解与配合。')
|
94 |
+
|
95 |
+
open_source = st.checkbox('我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[3_🪙_ 批量题写代币铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)',)
|
96 |
+
|
97 |
+
ask_ai = st.checkbox('如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。',)
|
98 |
+
|
99 |
+
huggingface = st.checkbox('复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。',)
|
100 |
+
|
101 |
+
site = st.checkbox('请务必确保你正在访问的是 **[EthPen.com](https://ethpen.com)** 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。',)
|
102 |
+
|
103 |
+
use = st.checkbox('在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。',)
|
104 |
+
|
105 |
+
wallet = st.checkbox('为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。',)
|
106 |
+
|
107 |
+
test = st.checkbox('首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络使用。',)
|
108 |
+
|
109 |
+
feedback = st.checkbox('若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。',)
|
110 |
+
|
111 |
+
if open_source and ask_ai and huggingface and site and use and wallet and test and feedback:
|
112 |
+
approved_use = True
|
113 |
+
else:
|
114 |
+
approved_use = False
|
115 |
+
|
116 |
+
if approved_use:
|
117 |
+
|
118 |
+
st.markdown('## 批量题写代币铭文')
|
119 |
+
|
120 |
+
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
121 |
+
net_options = {
|
122 |
+
'1': 'Mainnet',
|
123 |
+
'5': 'Goerli',
|
124 |
+
'11155111': 'Sepolia'
|
125 |
+
}
|
126 |
+
selected_option = st.selectbox(
|
127 |
+
'**网络 ID**',
|
128 |
+
list(net_options.keys()),
|
129 |
+
format_func=lambda x: f"{x} ({net_options[x]})"
|
130 |
+
)
|
131 |
+
chain_id = int(selected_option)
|
132 |
+
|
133 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
134 |
+
token_eth_prc_url = st.text_input(
|
135 |
+
f'**Ethereum PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
136 |
+
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
137 |
+
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
138 |
+
|
139 |
+
# 初始化当前账户索引为 0
|
140 |
+
current_account_index = 0
|
141 |
+
# 收集和显示所有交易的结果
|
142 |
+
transaction_results = []
|
143 |
+
# 创建账户列表
|
144 |
+
accounts = []
|
145 |
+
# 使用字典来跟踪每个地址的nonce
|
146 |
+
nonces = {}
|
147 |
+
|
148 |
+
# 启用多账户操作
|
149 |
+
multipl_accounts = st.toggle('启用**多账户**操作')
|
150 |
+
if multipl_accounts:
|
151 |
+
# 多账户的文本框
|
152 |
+
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
153 |
+
if account_list: # 如果账户列表有内容
|
154 |
+
for line in account_list.split('\n'): # 根据换行符划分账户
|
155 |
+
if ',' in line: # 检查是否包含逗号
|
156 |
+
address, key = line.split(',') # 分开地址和私钥
|
157 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
158 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
159 |
+
nonces[address] = current_nonce # 记录地址的 nonce
|
160 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
161 |
+
else:
|
162 |
+
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
163 |
+
st.stop()
|
164 |
+
else:
|
165 |
+
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
166 |
+
st.stop()
|
167 |
+
else:
|
168 |
+
account_address = st.text_input('填写你的 **ETH 地址**:')
|
169 |
+
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
170 |
+
if account_address and private_key: # 如果地址和私钥有内容
|
171 |
+
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
172 |
+
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
173 |
+
nonces[account_address] = current_nonce # 记录地址的 nonce
|
174 |
+
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
175 |
+
else:
|
176 |
+
st.error("地址或私钥无效,请检查!")
|
177 |
+
st.stop()
|
178 |
+
|
179 |
+
# 配置铭文文本
|
180 |
+
token_protocol = st.text_input('填写需要题写代币铭文协议 **Protocol(p)**:', 'erc-20')
|
181 |
+
token_operation = st.text_input('填写需要题写代币铭文操作 **Operation(op)**:', 'mint')
|
182 |
+
token_ticker = st.text_input('填写需要题写代币铭文简称 **Ticker(tick)**:')
|
183 |
+
token_min_id = st.number_input('填写需要题写代币铭文范围的**最小 ID(id)**:', min_value=1, value=1, step=1)
|
184 |
+
token_max_id = st.number_input('填写需要题写代币铭文范围的**最大 ID(id)**:', value=21000, step=1)
|
185 |
+
token_amount = st.number_input('填写需要题写代币铭文数量 **Amount(amt)**:', min_value=1, value=1000, step=1)
|
186 |
+
st.markdown('###### 预览代币铭文:')
|
187 |
+
st.code(
|
188 |
+
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}',
|
189 |
+
language="json", line_numbers=False)
|
190 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
191 |
+
if not validate_input(
|
192 |
+
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}'):
|
193 |
+
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
194 |
+
|
195 |
+
token_check = st.toggle('题写前**检查是否被题写** `主网` `查重`')
|
196 |
+
# 题写铭文之前检查该铭文有没有被题写
|
197 |
+
if token_check:
|
198 |
+
token_check = True
|
199 |
+
else:
|
200 |
+
token_check = False
|
201 |
+
sleep_3s = st.toggle('每次完成交易后暂停 3 秒')
|
202 |
+
# 每次交易成功后暂停 3 秒
|
203 |
+
if sleep_3s:
|
204 |
+
sleep_3s = True
|
205 |
+
else:
|
206 |
+
sleep_3s = False
|
207 |
+
|
208 |
+
# 点击发送交易开始
|
209 |
+
if st.button(f'开始**发送交易**'):
|
210 |
+
if not accounts or not token_protocol or not token_operation or not token_ticker: # 检查是否留空
|
211 |
+
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
212 |
+
st.stop()
|
213 |
+
else:
|
214 |
+
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
215 |
+
|
216 |
+
st.toast(f'开始任务,需要题写的铭文总量为:{token_max_id - token_min_id + 1}', icon='😎')
|
217 |
+
|
218 |
+
# 对代币铭文 id 进行循环
|
219 |
+
for the_id in range(token_min_id, token_max_id + 1):
|
220 |
+
# 使用当前账户发送交易,获取当前账户的 nonce
|
221 |
+
address, key = accounts[current_account_index]
|
222 |
+
# 得到完整的铭文文本
|
223 |
+
input_data = f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{the_id}","amt":"{token_amount}"}}'
|
224 |
+
# 获取 gas
|
225 |
+
gas_price = w3.eth.gas_price
|
226 |
+
# 根据是否检查的开关进行
|
227 |
+
if token_check:
|
228 |
+
# 这里是开了检查后请求 Ethscriptions API
|
229 |
+
if check_content_exists(sha256(input_data)):
|
230 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
231 |
+
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
232 |
+
else:
|
233 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
234 |
+
# 使用 current_nonce 发送交易
|
235 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
236 |
+
# 记录最后输出的结果
|
237 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
238 |
+
# 交易成功后,手动增加 nonce 值
|
239 |
+
nonces[address] += 1
|
240 |
+
else:
|
241 |
+
# 这里是未开检查后直接发送交易
|
242 |
+
# 使用 current_nonce 发送交易
|
243 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
244 |
+
# 记录最后输出的结果
|
245 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
246 |
+
# 交易成功后,手动增加 nonce 值
|
247 |
+
nonces[address] += 1
|
248 |
+
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
249 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
250 |
+
# 暂停 3 秒
|
251 |
+
if sleep_3s:
|
252 |
+
time.sleep(3) # 暂停三秒
|
253 |
+
st.toast(f'所有任务已经完成。', icon='🎉')
|
254 |
+
# 庆祝动画
|
255 |
+
st.balloons()
|
256 |
+
# 显示所有交易的结果
|
257 |
+
st.code('\n'.join(transaction_results))
|
258 |
+
else:
|
259 |
+
st.error('# 阅读并打勾 ✅ 后方可使用。')
|
data/python_name_code.py
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 8 月 18 日
|
3 |
+
|
4 |
+
# 在开始使用前,请仔细阅读相关说明。感谢您的理解与配合。
|
5 |
+
# 我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[2_🆔_批量题写域名铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)
|
6 |
+
# 如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。
|
7 |
+
# 复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。
|
8 |
+
# 请务必确保你正在访问的是 [EthPen.com](https://ethpen.com) 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。
|
9 |
+
# 在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。
|
10 |
+
# 为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。
|
11 |
+
# 首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络使用。
|
12 |
+
# 若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。
|
13 |
+
|
14 |
+
# 导入运行代码所需要的库
|
15 |
+
from web3 import Web3 # 与以太坊交互的库,安装的命令是 pip install web3
|
16 |
+
import hashlib # 用于数据哈希,安装的命令是 pip install hashlib
|
17 |
+
import requests # 用于发送网络请求,安装的命令是 pip install requests
|
18 |
+
import re # 用于正则表达式
|
19 |
+
import time # 用于时间相关
|
20 |
+
|
21 |
+
# ---------- 以下是基础配置 ----------
|
22 |
+
|
23 |
+
# 填写你的多个 ETH 地址及私钥,建议填写新建的钱包,用英文逗号分隔(,),如下:地址,私钥。
|
24 |
+
accounts_str = '''
|
25 |
+
账户1,私钥1
|
26 |
+
账户2,私钥2
|
27 |
+
账户3,私钥3
|
28 |
+
'''
|
29 |
+
|
30 |
+
# 需要题写的铭文内容,在三个单引号内输入多个域名铭文,可以用空格、换行符、英文逗号(,)分开,不要带 data:, 开头
|
31 |
+
# 不要带 data:, 开头
|
32 |
+
# 不要带 data:, 开头
|
33 |
+
ethscription = '''
|
34 |
+
123
|
35 |
+
abcedfg
|
36 |
+
xyz 987
|
37 |
+
哈哈哈 你好
|
38 |
+
👋 😊
|
39 |
+
ethpen.com
|
40 |
+
'''
|
41 |
+
# 你希望添加的后缀
|
42 |
+
suffix = '.eths'
|
43 |
+
# 以空格、换行符、英文逗号分隔文本,并加上后缀
|
44 |
+
ethscription_list = [item.strip() + suffix for item in re.split(r'[\s,]+', ethscription) if item]
|
45 |
+
|
46 |
+
# 决定是否在题写铭文之前检查该铭文有没有被题写过,如果需要检查就填写 Ture 如果不需要就填 False
|
47 |
+
check = False
|
48 |
+
|
49 |
+
# 每次交易成功后暂停 N 秒,0 为不暂停
|
50 |
+
sleep_sec = 0
|
51 |
+
|
52 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
53 |
+
w3 = Web3(Web3.HTTPProvider('https://sepolia.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206'))
|
54 |
+
|
55 |
+
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
56 |
+
chain_id = 11155111
|
57 |
+
|
58 |
+
# ---------- 以上是基础配置 ----------
|
59 |
+
|
60 |
+
|
61 |
+
# 检查 ETH 地址是否有效
|
62 |
+
def is_valid_eth_address(address):
|
63 |
+
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
64 |
+
return True
|
65 |
+
return False
|
66 |
+
|
67 |
+
|
68 |
+
# 检查 Ethereum 私钥是否有效
|
69 |
+
def is_valid_eth_private_key(private_key):
|
70 |
+
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
71 |
+
return True
|
72 |
+
return False
|
73 |
+
|
74 |
+
|
75 |
+
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
76 |
+
def validate_input(data_str):
|
77 |
+
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
78 |
+
return False
|
79 |
+
return True
|
80 |
+
|
81 |
+
|
82 |
+
# 把文字转换成 16 进制
|
83 |
+
def text_to_hex(text):
|
84 |
+
return ''.join(format(ord(char), '02x') for char in text)
|
85 |
+
|
86 |
+
|
87 |
+
# 使用sha256算法计算哈希
|
88 |
+
def sha256(input_string):
|
89 |
+
sha256 = hashlib.sha256()
|
90 |
+
sha256.update(input_string.encode('utf-8'))
|
91 |
+
return sha256.hexdigest()
|
92 |
+
|
93 |
+
|
94 |
+
# 使用 Ethscriptions API(主网)检查某个铭文是否已存在
|
95 |
+
def check_content_exists(sha):
|
96 |
+
# 定义请求的网址
|
97 |
+
endpoint = f"/ethscriptions/exists/{sha}"
|
98 |
+
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
99 |
+
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
100 |
+
if response.status_code == 200:
|
101 |
+
return response.json()['result']
|
102 |
+
|
103 |
+
|
104 |
+
# 发送自己到自己 0ETH 的交易
|
105 |
+
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
106 |
+
|
107 |
+
# 设置交易的相关信息
|
108 |
+
tx = {
|
109 |
+
'chainId': chain_id, # 网络 ID
|
110 |
+
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
111 |
+
'gasPrice': gas_price, # gas 的价格
|
112 |
+
'nonce': current_nonce, # 账户的交易数
|
113 |
+
'to': account_address, # 接收地址为自己
|
114 |
+
'value': 0, # 金额为 0ETH
|
115 |
+
'data': text_to_hex(input_data), # 铭文内容
|
116 |
+
}
|
117 |
+
|
118 |
+
# 用私钥签名这个交易
|
119 |
+
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
120 |
+
# 发送签名后的交易并获取交易哈希
|
121 |
+
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
122 |
+
# 打印结果信息
|
123 |
+
print(f'{account_address} | {input_data} | Transaction Hash: {tx_hash.hex()}')
|
124 |
+
|
125 |
+
|
126 |
+
# 初始化当前账户索引为 0
|
127 |
+
current_account_index = 0
|
128 |
+
# 创建账户列表
|
129 |
+
accounts = []
|
130 |
+
# 使用字典来跟踪每个地址的nonce
|
131 |
+
nonces = {}
|
132 |
+
|
133 |
+
|
134 |
+
if accounts_str: # 如果账户列表有内容
|
135 |
+
for line in accounts_str.strip().split('\n'): # 先去掉首尾的空白,然后根据换行符划分账户
|
136 |
+
if ',' in line: # 检查是否包含逗号
|
137 |
+
address, key = line.split(',') # 分开地址和私钥
|
138 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
139 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
140 |
+
nonces[address] = current_nonce # 记录地址的 nonce
|
141 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
142 |
+
else:
|
143 |
+
print(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
144 |
+
exit()
|
145 |
+
else:
|
146 |
+
print(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
147 |
+
exit()
|
148 |
+
|
149 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
150 |
+
if not validate_input(ethscription):
|
151 |
+
print("请注意:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
152 |
+
|
153 |
+
# 检查是否留空
|
154 |
+
if not accounts or not ethscription:
|
155 |
+
print('请正确谨慎地填写内容,每一项都不应留空。')
|
156 |
+
exit()
|
157 |
+
else:
|
158 |
+
print('看起来你输入的内容均无没有问题!')
|
159 |
+
|
160 |
+
# 认真检查铭文内容,如果发现错误,输入 1 结束
|
161 |
+
for i in ethscription_list:
|
162 |
+
print(f'\033[44m{i}\033[m')
|
163 |
+
if input('请预览铭文,输入任意内容继续,输入 1 退出程序:') == '1':
|
164 |
+
exit()
|
165 |
+
print(f'开始任务,需要题写的铭文总量为:{len(ethscription_list)}')
|
166 |
+
|
167 |
+
# 对代币铭文 id 进行循环
|
168 |
+
for name_str in ethscription_list:
|
169 |
+
# 使用当前账户发送交易
|
170 |
+
address, key = accounts[current_account_index]
|
171 |
+
# 得到完整的铭文文本
|
172 |
+
if not name_str.startswith('data:,'):
|
173 |
+
input_data = f'data:,{name_str}'
|
174 |
+
else:
|
175 |
+
input_data = name_str
|
176 |
+
# 获取 gas
|
177 |
+
gas_price = w3.eth.gas_price
|
178 |
+
# 根据是否检查的开关进行
|
179 |
+
if check:
|
180 |
+
# 这里是开了检查后请求 Ethscriptions API
|
181 |
+
if check_content_exists(sha256(input_data)):
|
182 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
183 |
+
print(f'{input_data} 已经被题写!')
|
184 |
+
else:
|
185 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
186 |
+
# 使用 current_nonce 发送交易
|
187 |
+
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
188 |
+
# 交易成功后,手动增加 nonce 值
|
189 |
+
nonces[address] += 1
|
190 |
+
else:
|
191 |
+
# 这里是未开检查后直接发送交易
|
192 |
+
# 使用 current_nonce 发送交易
|
193 |
+
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
194 |
+
# 交易成功后,手动增加 nonce 值
|
195 |
+
nonces[address] += 1
|
196 |
+
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
197 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
198 |
+
# 暂停 sleep_sec 秒
|
199 |
+
time.sleep(sleep_sec)
|
200 |
+
|
201 |
+
print(f'所有任务已经完成。')
|
data/python_token_code.py
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 8 月 18 日
|
3 |
+
|
4 |
+
# 在开始使用前,请仔细阅读相关说明。感谢您的理解与配合。
|
5 |
+
# 我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[3_🪙_ 批量题写代币铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)
|
6 |
+
# 如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。
|
7 |
+
# 复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。
|
8 |
+
# 请务必确保你正在访问的是 [EthPen.com](https://ethpen.com) 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。
|
9 |
+
# 在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。
|
10 |
+
# 为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。
|
11 |
+
# 首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络使用。
|
12 |
+
# 若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。
|
13 |
+
|
14 |
+
|
15 |
+
# 导入运行代码所需要的库
|
16 |
+
from web3 import Web3 # 与以太坊交互的库,安装的命令是 pip install web3
|
17 |
+
import hashlib # 用于数据哈希,安装的命令是 pip install hashlib
|
18 |
+
import requests # 用于发送网络请求,安装的命令是 pip install requests
|
19 |
+
import re # 用于正则表达式
|
20 |
+
import time # 用于时间相关
|
21 |
+
|
22 |
+
# ---------- 以下是基础配置 ----------
|
23 |
+
|
24 |
+
# 填写你的多个 ETH 地址及私钥,建议填写新建的钱包,用英文逗号分隔(,),如下:地址,私钥。
|
25 |
+
accounts_str = '''
|
26 |
+
账户1,私钥1
|
27 |
+
账户2,私钥2
|
28 |
+
账户3,私钥3
|
29 |
+
'''
|
30 |
+
|
31 |
+
# 需要题写的代币铭文内容,变动的部分文本如 id 请用 "@#" 代替,例如:'data:,{"p":"erc-20","op":"mint","tick":"eths","id":"@#","amt":"1000"}'
|
32 |
+
ethscription = 'data:,{"p":"erc-20","op":"mint","tick":"eths","id":"@#","amt":"1000"}'
|
33 |
+
|
34 |
+
# 设置代币铭文 id 的起始和结束范围
|
35 |
+
min_id = 100 # 开始的整数
|
36 |
+
max_id = 888 # 结束的整数
|
37 |
+
|
38 |
+
# 决定是否在题写铭文之前检查该铭文有没有被题写过,如果需要检查就填写 Ture 如果不需要就填 False
|
39 |
+
check = False
|
40 |
+
|
41 |
+
# 每次交易成功后暂停 N 秒,0 为不暂停
|
42 |
+
sleep_sec = 0
|
43 |
+
|
44 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
45 |
+
w3 = Web3(Web3.HTTPProvider('https://sepolia.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206'))
|
46 |
+
|
47 |
+
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
48 |
+
chain_id = 11155111
|
49 |
+
|
50 |
+
# ---------- 以上是基础配置 ----------
|
51 |
+
|
52 |
+
|
53 |
+
# 检查 ETH 地址是否有效
|
54 |
+
def is_valid_eth_address(address):
|
55 |
+
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
56 |
+
return True
|
57 |
+
return False
|
58 |
+
|
59 |
+
|
60 |
+
# 检查 Ethereum 私钥是否有效
|
61 |
+
def is_valid_eth_private_key(private_key):
|
62 |
+
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
63 |
+
return True
|
64 |
+
return False
|
65 |
+
|
66 |
+
|
67 |
+
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
68 |
+
def validate_input(data_str):
|
69 |
+
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
70 |
+
return False
|
71 |
+
return True
|
72 |
+
|
73 |
+
|
74 |
+
# 把文字转换成 16 进制
|
75 |
+
def text_to_hex(text):
|
76 |
+
return ''.join(format(ord(char), '02x') for char in text)
|
77 |
+
|
78 |
+
|
79 |
+
# 使用sha256算法计算哈希
|
80 |
+
def sha256(input_string):
|
81 |
+
sha256 = hashlib.sha256()
|
82 |
+
sha256.update(input_string.encode('utf-8'))
|
83 |
+
return sha256.hexdigest()
|
84 |
+
|
85 |
+
|
86 |
+
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
87 |
+
def check_content_exists(sha):
|
88 |
+
# 定义请求的网址
|
89 |
+
endpoint = f"/ethscriptions/exists/{sha}"
|
90 |
+
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
91 |
+
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
92 |
+
if response.status_code == 200:
|
93 |
+
return response.json()['result']
|
94 |
+
|
95 |
+
|
96 |
+
# 发送自己到自己 0ETH 的交易
|
97 |
+
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
98 |
+
|
99 |
+
# 设置交易的相关信息
|
100 |
+
tx = {
|
101 |
+
'chainId': chain_id, # 网络 ID
|
102 |
+
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
103 |
+
'gasPrice': gas_price, # gas 的价格
|
104 |
+
'nonce': current_nonce, # 账户的交易数
|
105 |
+
'to': account_address, # 接收地址为自己
|
106 |
+
'value': 0, # 金额为 0ETH
|
107 |
+
'data': text_to_hex(input_data), # 铭文内容
|
108 |
+
}
|
109 |
+
|
110 |
+
# 用私钥签名这个交易
|
111 |
+
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
112 |
+
# 发送签名后的交易并获取交易哈希
|
113 |
+
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
114 |
+
# 打印结果信息
|
115 |
+
print(f'{account_address} | {input_data} | Transaction Hash: {tx_hash.hex()}')
|
116 |
+
|
117 |
+
|
118 |
+
# 初始化当前账户索引为 0
|
119 |
+
current_account_index = 0
|
120 |
+
# 创建账户列表
|
121 |
+
accounts = []
|
122 |
+
# 使用字典来跟踪每个地址的nonce
|
123 |
+
nonces = {}
|
124 |
+
|
125 |
+
|
126 |
+
if accounts_str: # 如果账户列表有内容
|
127 |
+
for line in accounts_str.strip().split('\n'): # 先去掉首尾的空白,然后根据换行符划分账户
|
128 |
+
if ',' in line: # 检查是否包含逗号
|
129 |
+
address, key = line.split(',') # 分开地址和私钥
|
130 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
131 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
132 |
+
nonces[address] = current_nonce # 记录地址的 nonce
|
133 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
134 |
+
else:
|
135 |
+
print(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
136 |
+
exit()
|
137 |
+
else:
|
138 |
+
print(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
139 |
+
exit()
|
140 |
+
|
141 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
142 |
+
if not validate_input(ethscription):
|
143 |
+
print("请注意:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
144 |
+
|
145 |
+
# 检查是否留空
|
146 |
+
if not accounts or not ethscription:
|
147 |
+
print('请正确谨慎地填写内容,每一项都不应留空。')
|
148 |
+
exit()
|
149 |
+
else:
|
150 |
+
print('看起来你输入的内容均无没有问题!')
|
151 |
+
|
152 |
+
# 认真检查铭文内容,如果发现错误,输入 1 结束
|
153 |
+
print(f'铭文文本:\033[44m{ethscription}\033[m,题写 id 范围为:{min_id} - {max_id}。')
|
154 |
+
if input('请预览铭文,输入任意内容继续,输入 1 退出程序:') == '1':
|
155 |
+
exit()
|
156 |
+
print(f'开始任务,需要题写的铭文总量为:{max_id - min_id + 1}')
|
157 |
+
|
158 |
+
# 对代币铭文 id 进行循环
|
159 |
+
for the_id in range(min_id, max_id + 1):
|
160 |
+
# 使用当前账户发送交易
|
161 |
+
address, key = accounts[current_account_index]
|
162 |
+
# 得到完整的铭文文本
|
163 |
+
input_data = ethscription.replace('@#', str(the_id))
|
164 |
+
# 获取 gas
|
165 |
+
gas_price = w3.eth.gas_price
|
166 |
+
# 根据是否检查的开关进行
|
167 |
+
if check:
|
168 |
+
# 这里是开了检查后请求 Ethscriptions API
|
169 |
+
if check_content_exists(sha256(input_data)):
|
170 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
171 |
+
print(f'{input_data} 已经被题写!')
|
172 |
+
else:
|
173 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
174 |
+
# 使用 current_nonce 发送交易
|
175 |
+
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
176 |
+
# 交易成功后,手动增加 nonce 值
|
177 |
+
nonces[address] += 1
|
178 |
+
else:
|
179 |
+
# 这里是未开检查后直接发送交易
|
180 |
+
# 使用 current_nonce 发送交易
|
181 |
+
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
182 |
+
# 交易成功后,手动增加 nonce 值
|
183 |
+
nonces[address] += 1
|
184 |
+
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
185 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
186 |
+
# 暂停 sleep_sec 秒
|
187 |
+
time.sleep(sleep_sec)
|
188 |
+
|
189 |
+
print(f'所有任务已经完成。')
|
pages/.DS_Store
CHANGED
Binary files a/pages/.DS_Store and b/pages/.DS_Store differ
|
|
pages/2_🆔_ 批量题写域名铭文.py
CHANGED
@@ -1,13 +1,6 @@
|
|
1 |
-
#
|
2 |
-
# 最后更新日期:2023 年
|
3 |
|
4 |
-
# 在使用之前,敬请仔细阅读说明,感谢您的配合。
|
5 |
-
# 请务必访问 ethpen.com 官方网站。您可以确保这里的代码无恶意,安全地复制。
|
6 |
-
# 你只需要拥有一个 HuggingFace.co 账户。
|
7 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
8 |
-
# 我们建议您使用备用账号,并避免在账号中存放大额资金。
|
9 |
-
# 若您对此代码存有疑虑,建议您利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
10 |
-
# 请查看我们的例子 https://ethscriptions-name.hf.space。
|
11 |
|
12 |
# 导入运行代码所需要的库
|
13 |
import streamlit as st # streamlit app
|
@@ -16,6 +9,11 @@ import hashlib # 用于数据哈希
|
|
16 |
import requests # 用于发送网络请求
|
17 |
import re # 用于正则表达式
|
18 |
import time # 用于时间相关
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
|
21 |
# 检查 ETH 地址是否有效
|
@@ -58,7 +56,7 @@ def split_and_append(ethscriptions_str, name_selected_option):
|
|
58 |
|
59 |
# 把文字转换成 16 进制
|
60 |
def text_to_hex(text):
|
61 |
-
return ''.join(format(
|
62 |
|
63 |
|
64 |
# 使用sha256算法计算哈希
|
@@ -101,152 +99,200 @@ def send_transaction(w3, account_address, private_key, chain_id, gas_price, inpu
|
|
101 |
# 返回铭文还有交易哈希
|
102 |
return input_data, tx_hash.hex()
|
103 |
|
104 |
-
|
105 |
# 网页前端显示
|
|
|
|
|
106 |
# 网页标题
|
107 |
st.subheader(r'🆔 :rainbow[EthPen - 域名铭文批量题写]', anchor=False, divider='rainbow')
|
108 |
|
109 |
# 提醒
|
110 |
-
st.
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
#
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
#
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
#
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
#
|
179 |
-
|
180 |
-
#
|
181 |
-
|
182 |
-
#
|
183 |
-
|
184 |
-
#
|
185 |
-
|
186 |
-
|
187 |
-
#
|
188 |
-
|
189 |
-
|
190 |
-
#
|
191 |
-
|
192 |
-
#
|
193 |
-
#
|
194 |
-
#
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
#
|
199 |
-
#
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
#
|
210 |
-
#
|
211 |
-
#
|
212 |
-
#
|
213 |
-
#
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
#
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
#
|
226 |
-
|
227 |
-
|
228 |
-
#
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
#
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
#
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
#
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 9 月 5 日
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
# 导入运行代码所需要的库
|
6 |
import streamlit as st # streamlit app
|
|
|
9 |
import requests # 用于发送网络请求
|
10 |
import re # 用于正则表达式
|
11 |
import time # 用于时间相关
|
12 |
+
import os # 用于操作系统文件
|
13 |
+
|
14 |
+
|
15 |
+
# 许可使用开关
|
16 |
+
approved_use = False
|
17 |
|
18 |
|
19 |
# 检查 ETH 地址是否有效
|
|
|
56 |
|
57 |
# 把文字转换成 16 进制
|
58 |
def text_to_hex(text):
|
59 |
+
return ''.join(format(byte, '02x') for byte in text.encode('utf-8'))
|
60 |
|
61 |
|
62 |
# 使用sha256算法计算哈希
|
|
|
99 |
# 返回铭文还有交易哈希
|
100 |
return input_data, tx_hash.hex()
|
101 |
|
102 |
+
|
103 |
# 网页前端显示
|
104 |
+
st.set_page_config(page_title="EthPen - 批量题写域名铭文", page_icon="🆔", layout='centered', initial_sidebar_state='auto')
|
105 |
+
|
106 |
# 网页标题
|
107 |
st.subheader(r'🆔 :rainbow[EthPen - 域名铭文批量题写]', anchor=False, divider='rainbow')
|
108 |
|
109 |
# 提醒
|
110 |
+
st.markdown('### 在开始使用前,请仔细阅读相关��明,并在确认无误后打上 ✅。感谢您的理解与配合。')
|
111 |
+
|
112 |
+
open_source = st.checkbox('我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[2_🆔_批量题写域名铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)',)
|
113 |
+
|
114 |
+
ask_ai = st.checkbox('如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。',)
|
115 |
+
|
116 |
+
huggingface = st.checkbox('复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。',)
|
117 |
+
|
118 |
+
site = st.checkbox('请务必确保你正在访问的是 **[EthPen.com](https://ethpen.com)** 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。',)
|
119 |
+
|
120 |
+
use = st.checkbox('在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。',)
|
121 |
+
|
122 |
+
wallet = st.checkbox('为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。',)
|
123 |
+
|
124 |
+
test = st.checkbox('首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络使用。',)
|
125 |
+
|
126 |
+
feedback = st.checkbox('若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。',)
|
127 |
+
|
128 |
+
# st.expander
|
129 |
+
huggingface_expander = st.expander("显示 HuggingFace 平台环境的代码", expanded=False)
|
130 |
+
python_expander = st.expander("显示 Python 本地环境的代码", expanded=False)
|
131 |
+
|
132 |
+
current_dir = os.path.dirname(__file__)
|
133 |
+
parent_dir = os.path.dirname(current_dir)
|
134 |
+
python_file = os.path.join(parent_dir, 'data', 'python_name_code.py')
|
135 |
+
huggingface_file = os.path.join(parent_dir, 'data', 'huggingface_name_code.py')
|
136 |
+
with open(huggingface_file, "r", encoding="utf-8") as file:
|
137 |
+
huggingface_content = file.read()
|
138 |
+
huggingface_expander.markdown(f'Python 代码 `app.py`:')
|
139 |
+
huggingface_expander.code(huggingface_content, 'python', line_numbers=False)
|
140 |
+
huggingface_expander.markdown(f"依赖包清单 `requirements.txt`:")
|
141 |
+
huggingface_expander.code(f'''
|
142 |
+
Requests
|
143 |
+
streamlit
|
144 |
+
web3
|
145 |
+
''')
|
146 |
+
with open(python_file, "r", encoding="utf-8") as file:
|
147 |
+
python_content = file.read()
|
148 |
+
python_expander.markdown(f'Python 代码:')
|
149 |
+
python_expander.code(python_content, 'python', line_numbers=False)
|
150 |
+
|
151 |
+
if open_source and ask_ai and huggingface and site and use and wallet and test and feedback:
|
152 |
+
approved_use = True
|
153 |
+
else:
|
154 |
+
approved_use = False
|
155 |
+
|
156 |
+
if approved_use:
|
157 |
+
|
158 |
+
st.markdown('## 批量题写域名铭文')
|
159 |
+
|
160 |
+
# 连接的网络 ID。比如说,1 代表主网络,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
161 |
+
net_options = {
|
162 |
+
'1': 'Mainnet',
|
163 |
+
'5': 'Goerli',
|
164 |
+
'11155111': 'Sepolia'
|
165 |
+
}
|
166 |
+
selected_option = st.selectbox(
|
167 |
+
'**网络 ID**',
|
168 |
+
list(net_options.keys()),
|
169 |
+
format_func=lambda x: f"{x} ({net_options[x]})"
|
170 |
+
)
|
171 |
+
chain_id = int(selected_option)
|
172 |
+
|
173 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
174 |
+
token_eth_prc_url = st.text_input(
|
175 |
+
f'**Ethereum PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
176 |
+
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
177 |
+
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
178 |
+
# 初始化当前账户索引为 0
|
179 |
+
current_account_index = 0
|
180 |
+
# 收集和显示所有交易的结果
|
181 |
+
transaction_results = []
|
182 |
+
# 创建账户列表
|
183 |
+
accounts = []
|
184 |
+
# 使用字典来跟踪每个地址的nonce
|
185 |
+
nonces = {}
|
186 |
+
|
187 |
+
# 启用多账户操作
|
188 |
+
multipl_accounts = st.toggle('启用**多账户**操作')
|
189 |
+
if multipl_accounts:
|
190 |
+
# 多账户的文本框
|
191 |
+
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
192 |
+
if account_list: # 如果账户列表有内容
|
193 |
+
for line in account_list.split('\n'): # 根据换行符划分账户
|
194 |
+
if ',' in line: # 检查是否包含逗号
|
195 |
+
address, key = line.split(',') # 分开地址和私钥
|
196 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
197 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
198 |
+
nonces[address] = current_nonce # ���录地址的 nonce
|
199 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
200 |
+
else:
|
201 |
+
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
202 |
+
st.stop()
|
203 |
+
else:
|
204 |
+
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
205 |
+
st.stop()
|
206 |
+
else:
|
207 |
+
account_address = st.text_input('填写你的 **ETH 地址**:')
|
208 |
+
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
209 |
+
if account_address and private_key: # 如果地址和私钥有内容
|
210 |
+
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
211 |
+
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
212 |
+
nonces[account_address] = current_nonce # 记录地址的 nonce
|
213 |
+
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
214 |
+
else:
|
215 |
+
st.error("地址或私钥无效,请检查!")
|
216 |
+
st.stop()
|
217 |
+
|
218 |
+
# 配置铭文文本
|
219 |
+
ethscriptions_str = st.text_area(f'输入**多个域名铭文或其他**,可以用`空格`、`换行符`、`英文逗号(,)`分开,不要带 `data:,` 前缀,不要带`域名后缀`:')
|
220 |
+
|
221 |
+
name_selected_option = st.radio("选择域名后缀:", ['🎨 自定义', '🆔.eths', '🆔.eth', '🌲.tree', '🦛.honk', '🔄.etch', '🌐.com'], index=1, horizontal=True)
|
222 |
+
if name_selected_option == '🎨 自定义':
|
223 |
+
name_selected_option = st.text_input('输入**域名后缀**:')
|
224 |
+
|
225 |
+
# 以空格、换行符、英文逗号分隔文本并加上后缀
|
226 |
+
ethscription_list = split_and_append(ethscriptions_str, name_selected_option)
|
227 |
+
|
228 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
229 |
+
if not validate_input(''.join(ethscription_list)):
|
230 |
+
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
231 |
+
|
232 |
+
token_check = st.toggle('题写前**检查是否被题写** `主网` `查重`')
|
233 |
+
# 题写铭文之前检查该铭文有没有被题写
|
234 |
+
if token_check:
|
235 |
+
token_check = True
|
236 |
+
else:
|
237 |
+
token_check = False
|
238 |
+
sleep_3s = st.toggle('每次完成交易后暂停 3 秒')
|
239 |
+
# 每次交易成功后暂停 3 秒
|
240 |
+
if sleep_3s:
|
241 |
+
sleep_3s = True
|
242 |
+
else:
|
243 |
+
sleep_3s = False
|
244 |
+
|
245 |
+
# 点击发送交易开始
|
246 |
+
if st.button(f'开始**发送交易**'):
|
247 |
+
if not accounts or not ethscriptions_str or not name_selected_option: # 检查是否留空
|
248 |
+
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
249 |
+
st.stop()
|
250 |
+
else:
|
251 |
+
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
252 |
+
|
253 |
+
st.toast(f'开始任务,需要题写的铭文总量为:{len(ethscription_list)}', icon='😎')
|
254 |
+
|
255 |
+
# 对代币铭文 id 进行循环
|
256 |
+
for name_str in ethscription_list:
|
257 |
+
# 使用当前账户发送交易,获取当前账户的 nonce
|
258 |
+
address, key = accounts[current_account_index]
|
259 |
+
# 获取 gas
|
260 |
+
gas_price = w3.eth.gas_price
|
261 |
+
# 得到完整的铭文文本
|
262 |
+
if not name_str.startswith('data:,'):
|
263 |
+
input_data = f'data:,{name_str}'
|
264 |
+
|
265 |
+
# 根据是否检查的开关进行
|
266 |
+
if token_check:
|
267 |
+
# 这里是开了检查后请求 Ethscriptions API
|
268 |
+
if check_content_exists(sha256(input_data)):
|
269 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
270 |
+
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
271 |
+
else:
|
272 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
273 |
+
# 使用 current_nonce 发送交易
|
274 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
275 |
+
# 记录最后输出的结果
|
276 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
277 |
+
# 交易成功后,手动增加 nonce 值
|
278 |
+
nonces[address] += 1
|
279 |
+
else:
|
280 |
+
# 这里是未开检查后直接发送交易
|
281 |
+
# 使用 current_nonce 发送交易
|
282 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
283 |
+
# 记录最后输出的结果
|
284 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
285 |
+
# 交易成功后,手动增加 nonce 值
|
286 |
+
nonces[address] += 1
|
287 |
+
# 更新��前账户索引,确保索引始终在账户列表的范围内
|
288 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
289 |
+
# 暂停 3 秒
|
290 |
+
if sleep_3s:
|
291 |
+
time.sleep(3) # 暂停三秒
|
292 |
+
st.toast(f'所有任务已经完成。', icon='🎉')
|
293 |
+
# 庆祝动画
|
294 |
+
st.balloons()
|
295 |
+
# 显示所有交易的结果
|
296 |
+
st.code('\n'.join(transaction_results))
|
297 |
+
else:
|
298 |
+
st.error('# 阅读并打勾 ✅ 后方可使用。')
|
pages/3_🪙_ 批量题写代币铭文.py
CHANGED
@@ -1,13 +1,6 @@
|
|
1 |
-
#
|
2 |
-
# 最后更新日期:2023 年
|
3 |
|
4 |
-
# 在使用之前,敬请仔细阅读说明,感谢您的配合。
|
5 |
-
# 请务必访问 ethpen.com 官方网站。您可以确保这里的代码无恶意,安全地复制。
|
6 |
-
# 你只需要拥有一个 HuggingFace.co 账户。
|
7 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
8 |
-
# 我们建议您使用备用账号,并避免在账号中存放大额资金。
|
9 |
-
# 若您对此代码存有疑虑,建议您利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
10 |
-
# 请查看我们的例子 https://ethscriptions-name.hf.space。
|
11 |
|
12 |
# 导入运行代码所需要的库
|
13 |
import streamlit as st # streamlit app
|
@@ -16,6 +9,11 @@ import hashlib # 用于数据哈希
|
|
16 |
import requests # 用于发送网络请求
|
17 |
import re # 用于正则表达式
|
18 |
import time # 用于时间相关
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
|
21 |
# 检查 ETH 地址是否有效
|
@@ -41,7 +39,7 @@ def validate_input(data_str):
|
|
41 |
|
42 |
# 把文字转换成 16 进制
|
43 |
def text_to_hex(text):
|
44 |
-
return ''.join(format(
|
45 |
|
46 |
|
47 |
# 使用sha256算法计算哈希
|
@@ -84,153 +82,201 @@ def send_transaction(w3, account_address, private_key, chain_id, gas_price, inpu
|
|
84 |
# 返回铭文还有交易哈希
|
85 |
return input_data, tx_hash.hex()
|
86 |
|
87 |
-
|
88 |
# 网页前端显示
|
|
|
|
|
89 |
# 网页标题
|
90 |
st.subheader(r'🪙 :rainbow[EthPen - 代币铭文批量题写]', anchor=False, divider='rainbow')
|
|
|
91 |
# 提醒
|
92 |
-
st.
|
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 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
#
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
#
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
#
|
162 |
-
|
163 |
-
#
|
164 |
-
|
165 |
-
#
|
166 |
-
|
167 |
-
#
|
168 |
-
|
169 |
-
|
170 |
-
#
|
171 |
-
|
172 |
-
|
173 |
-
#
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
#
|
178 |
-
#
|
179 |
-
#
|
180 |
-
#
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
#
|
193 |
-
|
194 |
-
#
|
195 |
-
|
196 |
-
#
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
#
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
#
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
#
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
#
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
#
|
231 |
-
|
232 |
-
#
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# EthPen.com
|
2 |
+
# 最后更新日期:2023 年 9 月 5 日
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
# 导入运行代码所需要的库
|
6 |
import streamlit as st # streamlit app
|
|
|
9 |
import requests # 用于发送网络请求
|
10 |
import re # 用于正则表达式
|
11 |
import time # 用于时间相关
|
12 |
+
import os # 用于操作系统文件
|
13 |
+
|
14 |
+
|
15 |
+
# 许可使用开关
|
16 |
+
approved_use = False
|
17 |
|
18 |
|
19 |
# 检查 ETH 地址是否有效
|
|
|
39 |
|
40 |
# 把文字转换成 16 进制
|
41 |
def text_to_hex(text):
|
42 |
+
return ''.join(format(byte, '02x') for byte in text.encode('utf-8'))
|
43 |
|
44 |
|
45 |
# 使用sha256算法计算哈希
|
|
|
82 |
# 返回铭文还有交易哈希
|
83 |
return input_data, tx_hash.hex()
|
84 |
|
85 |
+
|
86 |
# 网页前端显示
|
87 |
+
st.set_page_config(page_title="EthPen - 批量题写代币铭文", page_icon="🪙", layout='centered', initial_sidebar_state='auto')
|
88 |
+
|
89 |
# 网页标题
|
90 |
st.subheader(r'🪙 :rainbow[EthPen - 代币铭文批量题写]', anchor=False, divider='rainbow')
|
91 |
+
|
92 |
# 提醒
|
93 |
+
st.markdown('### 在开始使用前,请仔细阅读相关说明,并在确认无误后打上 ✅。感谢您的理解与配合。')
|
94 |
+
|
95 |
+
open_source = st.checkbox('我们已将网站代码完全开源。您可以访问并仔细阅读此页面的源码:[3_🪙_ 批量题写代币铭文.py](https://huggingface.co/spaces/Ethscriptions/eths/tree/main/pages)',)
|
96 |
+
|
97 |
+
ask_ai = st.checkbox('如果你对此代码存有疑虑,建议你利用如 [OpenAI - ChetGPT](https://chat.openai.com/)、[Google - Bard](https://bard.google.com/)、[Anthropic - Claude](https://claude.ai/)、[抖音 - 豆包](https://www.doubao.com/)、[百度 - 文心一言](https://yiyan.baidu.com/)、[阿里 - 通义千问](https://qianwen.aliyun.com/) 等知名 AI 平台进行问询,这可以帮助你判断代码是否含有恶意内容。',)
|
98 |
+
|
99 |
+
huggingface = st.checkbox('复制我们的代码,你同样可以在 [HuggingFace](https://HuggingFace.co) 上搭建专属于你的域名铭文批量题写工具。',)
|
100 |
+
|
101 |
+
site = st.checkbox('请务必确保你正在访问的是 **[EthPen.com](https://ethpen.com)** 网站。我们保证站内代码不包含窃取私钥或其他恶意行为,你可以安心使用。',)
|
102 |
+
|
103 |
+
use = st.checkbox('在使用过程中,请按照提示准确地填写信息,这样可以确保程序的顺畅运行。',)
|
104 |
+
|
105 |
+
wallet = st.checkbox('为了安全起见,我们建议您使用备用账号(小号)并确保账号中不存放大额资金。',)
|
106 |
+
|
107 |
+
test = st.checkbox('首次使用时,我们建议您先在测试网络中操作。确认一切无误后,再切换至主网络使用。',)
|
108 |
+
|
109 |
+
feedback = st.checkbox('若您在使用过程中遇到问题,请及时向我们反馈。我们明白程序可能存在不完善之处,并且我们的能力也有限。真心希望得到各位程序员大佬的指导和交流。',)
|
110 |
+
|
111 |
+
# st.expander
|
112 |
+
huggingface_expander = st.expander("显示 HuggingFace 平台环境的代码", expanded=False)
|
113 |
+
python_expander = st.expander("显示 Python 本地环境的代码", expanded=False)
|
114 |
+
|
115 |
+
current_dir = os.path.dirname(__file__)
|
116 |
+
parent_dir = os.path.dirname(current_dir)
|
117 |
+
python_file = os.path.join(parent_dir, 'data', 'python_token_code.py')
|
118 |
+
huggingface_file = os.path.join(parent_dir, 'data', 'huggingface_token_code.py')
|
119 |
+
with open(huggingface_file, "r", encoding="utf-8") as file:
|
120 |
+
huggingface_content = file.read()
|
121 |
+
huggingface_expander.markdown(f'Python 代码 `app.py`:')
|
122 |
+
huggingface_expander.code(huggingface_content, 'python', line_numbers=False)
|
123 |
+
huggingface_expander.markdown(f"依赖包清单 `requirements.txt`:")
|
124 |
+
huggingface_expander.code(f'''
|
125 |
+
Requests
|
126 |
+
streamlit
|
127 |
+
web3
|
128 |
+
''')
|
129 |
+
with open(python_file, "r", encoding="utf-8") as file:
|
130 |
+
python_content = file.read()
|
131 |
+
python_expander.markdown(f'Python 代码:')
|
132 |
+
python_expander.code(python_content, 'python', line_numbers=False)
|
133 |
+
|
134 |
+
if open_source and ask_ai and huggingface and site and use and wallet and test and feedback:
|
135 |
+
approved_use = True
|
136 |
+
else:
|
137 |
+
approved_use = False
|
138 |
+
|
139 |
+
if approved_use:
|
140 |
+
|
141 |
+
st.markdown('## 批量题写代币铭文')
|
142 |
+
|
143 |
+
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
144 |
+
net_options = {
|
145 |
+
'1': 'Mainnet',
|
146 |
+
'5': 'Goerli',
|
147 |
+
'11155111': 'Sepolia'
|
148 |
+
}
|
149 |
+
selected_option = st.selectbox(
|
150 |
+
'**网络 ID**',
|
151 |
+
list(net_options.keys()),
|
152 |
+
format_func=lambda x: f"{x} ({net_options[x]})"
|
153 |
+
)
|
154 |
+
chain_id = int(selected_option)
|
155 |
+
|
156 |
+
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
157 |
+
token_eth_prc_url = st.text_input(
|
158 |
+
f'**Ethereum PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
159 |
+
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
160 |
+
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
161 |
+
|
162 |
+
# 初始化当前账户索引为 0
|
163 |
+
current_account_index = 0
|
164 |
+
# 收集和显示所有交易的结果
|
165 |
+
transaction_results = []
|
166 |
+
# 创建账户列表
|
167 |
+
accounts = []
|
168 |
+
# 使用字典来跟踪每个地址的nonce
|
169 |
+
nonces = {}
|
170 |
+
|
171 |
+
# 启用多账户操作
|
172 |
+
multipl_accounts = st.toggle('启用**多账户**操作')
|
173 |
+
if multipl_accounts:
|
174 |
+
# 多账户的文本框
|
175 |
+
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
176 |
+
if account_list: # 如果账户列表有内容
|
177 |
+
for line in account_list.split('\n'): # 根据换行符划分账户
|
178 |
+
if ',' in line: # 检查是否包含逗号
|
179 |
+
address, key = line.split(',') # 分开地址和私钥
|
180 |
+
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
181 |
+
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
182 |
+
nonces[address] = current_nonce # 记录地址的 nonce
|
183 |
+
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
184 |
+
else:
|
185 |
+
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
186 |
+
st.stop()
|
187 |
+
else:
|
188 |
+
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
189 |
+
st.stop()
|
190 |
+
else:
|
191 |
+
account_address = st.text_input('填写你的 **ETH 地址**:')
|
192 |
+
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
193 |
+
if account_address and private_key: # 如果地址和私钥有内容
|
194 |
+
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
195 |
+
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
196 |
+
nonces[account_address] = current_nonce # 记录地址的 nonce
|
197 |
+
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
198 |
+
else:
|
199 |
+
st.error("地址或私钥无效,请检查!")
|
200 |
+
st.stop()
|
201 |
+
|
202 |
+
# 配置铭文文本
|
203 |
+
token_protocol = st.text_input('填写需要题写代币铭文协议 **Protocol(p)**:', 'erc-20')
|
204 |
+
token_operation = st.text_input('填写需要题写代币铭文操作 **Operation(op)**:', 'mint')
|
205 |
+
token_ticker = st.text_input('填写需要题写代币铭文简称 **Ticker(tick)**:')
|
206 |
+
token_min_id = st.number_input('填写需要题写代币铭文范围的**最小 ID(id)**:', min_value=1, value=1, step=1)
|
207 |
+
token_max_id = st.number_input('填写需要题写代币铭文范围的**最大 ID(id)**:', value=21000, step=1)
|
208 |
+
token_amount = st.number_input('填写需要题写代币铭文数量 **Amount(amt)**:', min_value=1, value=1000, step=1)
|
209 |
+
st.markdown('###### 预览代币铭文:')
|
210 |
+
st.code(
|
211 |
+
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}',
|
212 |
+
language="json", line_numbers=False)
|
213 |
+
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
214 |
+
if not validate_input(
|
215 |
+
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}'):
|
216 |
+
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
217 |
+
|
218 |
+
token_check = st.toggle('题写前**检查是否被题写** `主网` `查重`')
|
219 |
+
# 题写铭文之前检查该铭文有没有被题写
|
220 |
+
if token_check:
|
221 |
+
token_check = True
|
222 |
+
else:
|
223 |
+
token_check = False
|
224 |
+
sleep_3s = st.toggle('每次完成交易后暂停 3 秒')
|
225 |
+
# 每次交易成功后暂停 3 秒
|
226 |
+
if sleep_3s:
|
227 |
+
sleep_3s = True
|
228 |
+
else:
|
229 |
+
sleep_3s = False
|
230 |
+
|
231 |
+
# 点击发送交易开始
|
232 |
+
if st.button(f'开始**发送交易**'):
|
233 |
+
if not accounts or not token_protocol or not token_operation or not token_ticker: # 检查是否留空
|
234 |
+
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
235 |
+
st.stop()
|
236 |
+
else:
|
237 |
+
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
238 |
+
|
239 |
+
st.toast(f'开始任务,需要题写的铭文总量为:{token_max_id - token_min_id + 1}', icon='😎')
|
240 |
+
|
241 |
+
# 对代币铭文 id 进行循环
|
242 |
+
for the_id in range(token_min_id, token_max_id + 1):
|
243 |
+
# 使用当前账户发送交易,获取当前账户的 nonce
|
244 |
+
address, key = accounts[current_account_index]
|
245 |
+
# 得到完整的铭文文本
|
246 |
+
input_data = f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{the_id}","amt":"{token_amount}"}}'
|
247 |
+
# 获取 gas
|
248 |
+
gas_price = w3.eth.gas_price
|
249 |
+
# 根据是否检查的开关进行
|
250 |
+
if token_check:
|
251 |
+
# 这里是开了检查后请求 Ethscriptions API
|
252 |
+
if check_content_exists(sha256(input_data)):
|
253 |
+
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
254 |
+
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
255 |
+
else:
|
256 |
+
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
257 |
+
# 使用 current_nonce 发送交易
|
258 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
259 |
+
# 记录最后输出的结果
|
260 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
261 |
+
# 交易成功后,手动增加 nonce 值
|
262 |
+
nonces[address] += 1
|
263 |
+
else:
|
264 |
+
# 这里是未开检查后直接发送交易
|
265 |
+
# 使用 current_nonce 发送交易
|
266 |
+
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
267 |
+
# 记录最后输出的结果
|
268 |
+
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
269 |
+
# 交易成功后,手动增加 nonce 值
|
270 |
+
nonces[address] += 1
|
271 |
+
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
272 |
+
current_account_index = (current_account_index + 1) % len(accounts)
|
273 |
+
# 暂停 3 秒
|
274 |
+
if sleep_3s:
|
275 |
+
time.sleep(3) # 暂停三秒
|
276 |
+
st.toast(f'所有任务已经完成。', icon='🎉')
|
277 |
+
# 庆祝动画
|
278 |
+
st.balloons()
|
279 |
+
# 显示所有交易的结果
|
280 |
+
st.code('\n'.join(transaction_results))
|
281 |
+
else:
|
282 |
+
st.error('# 阅读并打勾 ✅ 后方可使用。')
|
pages/6_📢_推送通知服务.py
CHANGED
@@ -11,3 +11,4 @@ st.set_page_config(page_title="EthPen - 推送通知服务", page_icon="📢", l
|
|
11 |
st.subheader(r'📢 :rainbow[EthPen - 推送通知服务]', anchor=False, divider='rainbow')
|
12 |
st.error('开发中,仅供参考...')
|
13 |
st.error('如果你有更好的想法,可以联系我。')
|
|
|
|
11 |
st.subheader(r'📢 :rainbow[EthPen - 推送通知服务]', anchor=False, divider='rainbow')
|
12 |
st.error('开发中,仅供参考...')
|
13 |
st.error('如果你有更好的想法,可以联系我。')
|
14 |
+
|
pages/7_ℹ️️_关于 EthPen.com.py
CHANGED
@@ -45,3 +45,6 @@ st.markdown('对了,我叫 pztuya,期待你们和我更多的商业交流
|
|
45 |
st.markdown(f'''{my_style}<span class="tag"><a href="https://twitter.com/pztuya" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "x.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @pztuya</span></a>
|
46 |
<span class="tag"><a href="https://t.me/NervosCKB" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "telegram.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @NervosCKB</span></a>
|
47 |
''', unsafe_allow_html=True)
|
|
|
|
|
|
|
|
45 |
st.markdown(f'''{my_style}<span class="tag"><a href="https://twitter.com/pztuya" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "x.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @pztuya</span></a>
|
46 |
<span class="tag"><a href="https://t.me/NervosCKB" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "telegram.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @NervosCKB</span></a>
|
47 |
''', unsafe_allow_html=True)
|
48 |
+
|
49 |
+
st.markdown(f'''# <span class="tag"><a href="https://huggingface.co/spaces/Ethscriptions/eths" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "huggingface_logo.svg"))}" alt="Image" width="60px" height="60px" style="border-radius: 9px;" /> @Ethscriptions </span></a>
|
50 |
+
''', unsafe_allow_html=True)
|
🖊️EthPen-以太之笔.py
CHANGED
@@ -44,911 +44,6 @@ token_list = [{'p': 'erc-20', 'tick': 'eths', 'id': 21000, 'amt': '1000'},
|
|
44 |
{'p': 'erc-20', 'tick': 'etch', 'id': 21000, 'amt': '1000'},
|
45 |
{'p': 'erc-20', 'tick': 'dumb', 'id': 21000, 'amt': '1000'}]
|
46 |
|
47 |
-
ethscrptions_logo = """<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-0.53 -2.18 14.000028839170737 20.067148724063962" style="enable-background:new 0 0 100 16.4081;" xml:space="preserve" width="19" height="25" xmlns:svgjs="http://svgjs.dev/svgjs">
|
48 |
-
<g>
|
49 |
-
<path d="M11.6219,5.1455c-0.0003-0.0017-0.0012-0.0032-0.0015-0.0048c-0.0033-0.0173-0.0083-0.0343-0.0161-0.0502 		c-0.0086-0.0175-0.0199-0.034-0.0338-0.0487c-0.0053-0.0055-0.0119-0.0088-0.0176-0.0136 		c-0.0246-0.0207-0.0525-0.0365-0.0832-0.0431c-0.0378-0.0083-0.078-0.0056-0.1153,0.0093L8.399,6.1767 		C8.3763,6.1858,8.3568,6.1999,8.3393,6.216C8.3361,6.219,8.3329,6.2215,8.3299,6.2246c-0.0158,0.0166-0.0284,0.0357-0.0376,0.057 		c-0.0008,0.0018-0.0024,0.003-0.0032,0.0048l-0.5395,1.349L6.4982,1.1993c-0.002-0.0102-0.007-0.0192-0.0104-0.0288L6.3012,0.2141 		C6.2857,0.1355,6.2244,0.074,6.1459,0.0585C6.0681,0.0434,5.9871,0.0767,5.9433,0.1434l-4.9257,7.487 		c-0.011,0.0167-0.0187,0.0347-0.0241,0.0533c-0.0002,0.0007-0.0008,0.0012-0.001,0.002c-0.0007,0.0024,0,0.0049-0.0005,0.0072 		C0.9871,7.713,0.9859,7.7333,0.9875,7.7538c0.0005,0.0061,0.0009,0.0118,0.0019,0.0178c0.0039,0.0229,0.0104,0.0454,0.0224,0.0662 		L2.046,9.6167L0.3277,8.494C0.2674,8.4544,0.1902,8.4511,0.1269,8.4852c-0.0635,0.0341-0.1033,0.1001-0.104,0.172L0,11.2824 		c-0.0002,0.0267,0.0066,0.0516,0.0162,0.0753c0.0024,0.0058,0.0048,0.011,0.0077,0.0166c0.0118,0.0227,0.0266,0.0438,0.0464,0.0605 		c0.0003,0.0002,0.0003,0.0006,0.0007,0.0008l5.9106,4.9268c0.0031,0.0026,0.007,0.0035,0.0102,0.0058 		C6,16.3744,6.0082,16.3805,6.0173,16.3852c0.0028,0.0014,0.0053,0.003,0.0082,0.0043c0.0027,0.0012,0.0055,0.0016,0.0083,0.0028 		c0.0047,0.0019,0.0091,0.0037,0.0139,0.0053c0.0066,0.0022,0.0133,0.0039,0.0202,0.0053c0.003,0.0006,0.0055,0.0022,0.0085,0.0027 		c0.0104,0.0017,0.021,0.0025,0.0313,0.0025c0.0001,0,0.0001,0,0.0002,0c0.0001,0,0.0001-0.0001,0.0002-0.0001 		c0.0093,0,0.0186-0.0005,0.0279-0.0021c0.002-0.0003,0.0036-0.0017,0.0056-0.002c0.0068-0.0012,0.0137-0.0022,0.0203-0.0041 		c0.0051-0.0015,0.0098-0.0037,0.0148-0.0056c0.0024-0.0009,0.0049-0.0005,0.0072-0.0014c0.002-0.0008,0.0032-0.0025,0.0051-0.0034 		c0.0066-0.003,0.0131-0.0062,0.0193-0.01c0.0028-0.0016,0.0053-0.0032,0.0079-0.0049c0.002-0.0013,0.0042-0.0017,0.0061-0.0031 		c0.0022-0.0015,0.0032-0.0039,0.0053-0.0055c0.0049-0.0037,0.0099-0.0069,0.0144-0.0111c0.0025-0.0024,0.0042-0.0052,0.0066-0.0077 		c0.0081-0.0084,0.0164-0.0167,0.023-0.0267l0.0014-0.0022c0.0001,0,0.0001,0,0.0001-0.0001l1.1807-1.771l1.5889-2.3833 		l0.7754-1.1632c0.0443-0.0663,0.0441-0.153-0.0004-0.2191c-0.0446-0.0662-0.1239-0.0981-0.2028-0.0833l-0.5723,0.1161L11.6064,5.26 		c0.0038-0.0083,0.0048-0.0171,0.0074-0.0256c0.0032-0.0103,0.0076-0.0204,0.0089-0.031c0.0004-0.003-0.0003-0.006-0.0001-0.009 		C11.6241,5.178,11.6245,5.1616,11.6219,5.1455z M0.4138,9.021l0.2456,0.1605l0.2141,1.193l-0.4754,0.4488L0.4138,9.021z 		 M0.4938,11.2751l0.5787-0.5465l3.2682,3.7531L0.4938,11.2751z M2.8047,10.1374L1.4545,7.8151l1.8657-1.0145l0.268,0.9764 		l1.9285,7.0254L2.8047,10.1374z M3.299,6.3636L1.7791,7.19l4.2278-6.4264l0.0874,0.4481L3.299,6.3636z M9.2254,11.1793 		L8.813,11.7979l-0.738-0.3853l0.6649-0.1348c0.0001,0,0.0001,0,0.0003,0L9.2254,11.1793z M7.7577,10.2479L7.8786,8.374 		l0.6604-1.651l0.5335,0.5794L7.7577,10.2479z M10.7687,6.1234l-0.3365,0.2091L9.3397,7.0111l-0.529-0.5746l2.2278-0.8912 		L10.7687,6.1234z"/>
|
50 |
-
<g>
|
51 |
-
<polygon points="14.6965,13.7003 21.6177,13.7003 21.6177,11.5939 17.3105,11.5939 17.3105,9.9388 21.2789,9.9388 21.2789,7.8323 			17.3105,7.8323 17.3105,6.1773 21.636,6.1773 21.636,4.0719 14.6965,4.0719 		"/>
|
52 |
-
<path d="M26.4696,11.8007c-0.1051,0.0194-0.1966,0.0291-0.2748,0.0291c-0.1131,0-0.2058-0.0172-0.2774-0.0495 			c-0.0722-0.0334-0.1255-0.083-0.16-0.1509c-0.0345-0.0668-0.0518-0.1509-0.0518-0.251V8.3593h1.2413V6.479h-1.2413V4.7486h-2.5951 			V6.479h-0.9218v1.8803h0.9218v3.2637c-0.0065,0.5042,0.0921,0.9244,0.2957,1.2596c0.2037,0.3351,0.508,0.5807,0.9121,0.7359 			c0.4046,0.1552,0.9046,0.2166,1.4999,0.1853c0.2947-0.0162,0.5495-0.0485,0.7644-0.0991 			c0.2144-0.0496,0.3798-0.0916,0.4957-0.1261l-0.3761-1.8242C26.6522,11.7663,26.5747,11.7824,26.4696,11.8007z"/>
|
53 |
-
<path d="M33.9108,6.7322c-0.3777-0.2316-0.8222-0.348-1.3329-0.348c-0.5328,0-0.9891,0.1293-1.3684,0.3879 			c-0.3793,0.2586-0.6503,0.6185-0.8135,1.0797h-0.0749V4.0719h-2.5014v9.6284h2.5951V9.6382 			c0.0032-0.2382,0.0479-0.4429,0.1342-0.6131c0.0862-0.1713,0.2085-0.3028,0.3669-0.3955c0.1578-0.0927,0.3421-0.139,0.5522-0.139 			c0.3325,0,0.5884,0.1024,0.7688,0.306c0.1805,0.2037,0.2688,0.4838,0.2656,0.8415v4.0621h2.5956V9.093 			c0.0027-0.5269-0.0996-0.9935-0.3082-1.4007C34.5815,7.2839,34.2884,6.965,33.9108,6.7322z"/>
|
54 |
-
<path d="M40.6348,9.3559L39.1678,9.093c-0.2758-0.0506-0.4617-0.1207-0.5571-0.2112c-0.0959-0.0916-0.1423-0.1896-0.139-0.2963 			c-0.0033-0.1509,0.0754-0.2672,0.2349-0.348c0.16-0.0819,0.3513-0.1228,0.5738-0.1228c0.1724,0,0.3297,0.0291,0.4725,0.0872 			c0.1427,0.0582,0.2602,0.1401,0.3507,0.2468c0.0905,0.1067,0.1422,0.2338,0.1551,0.3815h2.3877 			c-0.0312-0.765-0.348-1.3641-0.9514-1.7962c-0.6034-0.4332-1.4277-0.6498-2.4712-0.6498c-0.6864,0-1.2796,0.0927-1.7795,0.2759 			c-0.4999,0.1832-0.8841,0.4493-1.1518,0.7995c-0.2678,0.3491-0.4003,0.7747-0.3971,1.2757 			c-0.0032,0.5679,0.1783,1.0312,0.5452,1.3921c0.3669,0.3599,0.9186,0.6044,1.655,0.7338l1.279,0.2252 			c0.2818,0.0506,0.4898,0.1163,0.6234,0.1972c0.1325,0.0819,0.2004,0.1918,0.2047,0.3297c-0.0043,0.1497-0.083,0.2661-0.2382,0.348 			c-0.1551,0.0808-0.3518,0.1218-0.5899,0.1218c-0.2947,0-0.5387-0.0614-0.7311-0.1853c-0.1928-0.1239-0.3065-0.3006-0.341-0.529 			h-2.5768c0.0722,0.7391,0.4192,1.335,1.0414,1.7865c0.6222,0.4515,1.4853,0.6767,2.5887,0.6767 			c0.6681,0,1.2628-0.1024,1.7844-0.3071c0.5215-0.2058,0.9342-0.4967,1.2369-0.8749c0.3017-0.3782,0.4547-0.8232,0.4579-1.3372 			c-0.0032-0.5334-0.1853-0.959-0.5474-1.2769C41.9256,9.718,41.374,9.4906,40.6348,9.3559z"/>
|
55 |
-
<path d="M46.4252,8.5166c0.1692-0.1293,0.3664-0.1951,0.5926-0.1951c0.2888,0,0.5237,0.1002,0.7079,0.2985 			c0.1832,0.1993,0.292,0.4881,0.3265,0.8674h2.4071c-0.0032-0.626-0.1476-1.1723-0.4321-1.6378 			c-0.2855-0.4655-0.6874-0.8264-1.2068-1.0818c-0.5183-0.2554-1.1324-0.3836-1.8403-0.3836c-0.7833,0-1.4546,0.1562-2.0127,0.4687 			c-0.5571,0.3114-0.9859,0.7467-1.2833,1.307c-0.2974,0.5592-0.4461,1.2089-0.4461,1.9481c0,0.7402,0.1487,1.39,0.4461,1.9491 			c0.2974,0.5592,0.7262,0.9956,1.2833,1.307c0.5581,0.3114,1.2294,0.4676,2.0127,0.4676c0.7144,0,1.3296-0.1283,1.8457-0.3847 			c0.5151-0.2575,0.9137-0.6217,1.196-1.0937c0.2824-0.4719,0.4278-1.0257,0.4375-1.6615h-2.4071 			c-0.0194,0.25-0.0743,0.4622-0.167,0.6368c-0.0926,0.1735-0.2122,0.3049-0.3599,0.3943 			c-0.1476,0.0895-0.3168,0.1347-0.5075,0.1347c-0.2263,0-0.4234-0.0657-0.5926-0.195c-0.1691-0.1304-0.3006-0.3265-0.3943-0.5883 			c-0.0948-0.2618-0.1411-0.5894-0.1411-0.9848c0-0.3955,0.0463-0.723,0.1411-0.9849C46.1246,8.8431,46.2561,8.6469,46.4252,8.5166z 			"/>
|
56 |
-
<path d="M55.4319,6.3842c-0.3857,0-0.7219,0.1186-1.0085,0.3534c-0.2866,0.2349-0.4957,0.6067-0.6271,1.1142h-0.0755V6.479 			h-2.5202v7.2213h2.5957V9.9388c0-0.2759,0.0571-0.5161,0.1735-0.7208c0.1164-0.2058,0.2747-0.3653,0.4773-0.4806 			c0.2026-0.1142,0.4299-0.1714,0.6842-0.1714c0.1347,0,0.2963,0.0108,0.4838,0.0334c0.1886,0.0215,0.3469,0.055,0.4752,0.0981 			V6.4833c-0.1034-0.0313-0.2112-0.056-0.3222-0.0733C55.6571,6.3928,55.5451,6.3842,55.4319,6.3842z"/>
|
57 |
-
<path d="M57.908,5.7269c0.3501,0,0.6507-0.1164,0.8997-0.348c0.25-0.2322,0.3739-0.5112,0.3739-0.8372 			c0-0.3259-0.1239-0.605-0.3739-0.8367c-0.2489-0.2322-0.5506-0.348-0.9051-0.348c-0.3513,0-0.6519,0.1159-0.903,0.348 			c-0.25,0.2317-0.3761,0.5108-0.3761,0.8367c0,0.326,0.1261,0.605,0.3761,0.8372C57.2507,5.6105,57.5535,5.7269,57.908,5.7269z"/>
|
58 |
-
<rect x="56.6053" y="6.479" width="2.5957" height="7.2213"/>
|
59 |
-
<path d="M66.2111,6.7656c-0.431-0.2543-0.8846-0.3815-1.3609-0.3815c-0.3577,0-0.6713,0.0625-0.9407,0.1865 			c-0.2694,0.1239-0.4957,0.2877-0.6767,0.4934c-0.1821,0.2058-0.32,0.4299-0.4138,0.6745h-0.0571V6.479h-2.5762v9.929h2.5956 			v-3.8919h0.0377c0.1002,0.2446,0.2435,0.4622,0.4299,0.6551c0.1864,0.1929,0.4116,0.3448,0.6767,0.4569 			c0.2651,0.111,0.5667,0.1659,0.9051,0.1659c0.514,0,0.987-0.1346,1.418-0.4041c0.431-0.2693,0.7758-0.6788,1.0344-1.2272 			c0.2586-0.5485,0.3879-1.2392,0.3879-2.0731c0-0.8717-0.1358-1.5796-0.4073-2.1248C66.9934,7.4186,66.6421,7.0199,66.2111,6.7656z 			 M64.8664,11.0088c-0.0895,0.2554-0.2177,0.4514-0.3857,0.5883c-0.1681,0.1358-0.3707,0.2036-0.6088,0.2036 			c-0.2382,0-0.4429-0.0689-0.6131-0.209c-0.1714-0.139-0.3028-0.3373-0.3955-0.5926c-0.0927-0.2554-0.139-0.5581-0.139-0.9094 			c0-0.3578,0.0463-0.6637,0.139-0.9191c0.0927-0.2554,0.2241-0.4515,0.3955-0.5883c0.1702-0.1358,0.375-0.2037,0.6131-0.2037 			c0.2381,0,0.4406,0.0678,0.6088,0.2037c0.1681,0.1368,0.2963,0.3329,0.3857,0.5883C64.9558,9.4259,65,9.7319,65,10.0897 			C65,10.4474,64.9558,10.7534,64.8664,11.0088z"/>
|
60 |
-
<path d="M72.2601,11.8007c-0.1046,0.0194-0.1972,0.0291-0.2748,0.0291c-0.1131,0-0.2058-0.0172-0.2779-0.0495 			c-0.0722-0.0334-0.125-0.083-0.1595-0.1509c-0.0345-0.0668-0.0518-0.1509-0.0518-0.251V8.3593h1.2413V6.479h-1.2413V4.7486 			h-2.5956V6.479h-0.9213v1.8803h0.9213v3.2637c-0.0065,0.5042,0.0926,0.9244,0.2963,1.2596 			c0.2037,0.3351,0.5075,0.5807,0.9126,0.7359c0.4041,0.1552,0.9041,0.2166,1.4999,0.1853 			c0.2941-0.0162,0.5495-0.0485,0.7639-0.0991c0.2144-0.0496,0.3803-0.0916,0.4957-0.1261l-0.3761-1.8242 			C72.4433,11.7663,72.3657,11.7824,72.2601,11.8007z"/>
|
61 |
-
<path d="M74.762,5.7269c0.3502,0,0.6508-0.1164,0.8997-0.348c0.25-0.2322,0.3738-0.5112,0.3738-0.8372 			c0-0.3259-0.1239-0.605-0.3738-0.8367c-0.2489-0.2322-0.5507-0.348-0.9051-0.348c-0.3512,0-0.6519,0.1159-0.903,0.348 			c-0.25,0.2317-0.376,0.5108-0.376,0.8367c0,0.326,0.126,0.605,0.376,0.8372C74.1048,5.6105,74.4076,5.7269,74.762,5.7269z"/>
|
62 |
-
<rect x="73.4594" y="6.479" width="2.5957" height="7.2213"/>
|
63 |
-
<path d="M82.5318,6.8529c-0.5581-0.3125-1.2294-0.4687-2.0127-0.4687c-0.7834,0-1.4546,0.1562-2.0127,0.4687 			c-0.5571,0.3114-0.9859,0.7467-1.2833,1.307c-0.2974,0.5592-0.4461,1.2089-0.4461,1.9481c0,0.7402,0.1487,1.39,0.4461,1.9491 			c0.2974,0.5592,0.7262,0.9956,1.2833,1.307c0.5581,0.3114,1.2294,0.4676,2.0127,0.4676c0.7833,0,1.4546-0.1562,2.0127-0.4676 			c0.5571-0.3114,0.9848-0.7478,1.2833-1.307c0.2974-0.5592,0.4461-1.2089,0.4461-1.9491c0-0.7392-0.1487-1.3889-0.4461-1.9481 			C83.5166,7.5996,83.0888,7.1643,82.5318,6.8529z M81.478,11.0627c-0.0873,0.2726-0.2112,0.4827-0.3717,0.6303 			c-0.1595,0.1476-0.3491,0.2209-0.5689,0.2209c-0.2317,0-0.431-0.0733-0.597-0.2209c-0.1659-0.1476-0.2931-0.3578-0.3803-0.6303 			c-0.0883-0.2726-0.1314-0.597-0.1314-0.973c0-0.3793,0.0431-0.7047,0.1314-0.9751c0.0873-0.2715,0.2144-0.4806,0.3803-0.6282 			c0.166-0.1476,0.3653-0.2209,0.597-0.2209c0.2198,0,0.4094,0.0733,0.5689,0.2209c0.1606,0.1476,0.2845,0.3567,0.3717,0.6282 			c0.0883,0.2705,0.1314,0.5958,0.1314,0.9751C81.6094,10.4657,81.5663,10.79,81.478,11.0627z"/>
|
64 |
-
<path d="M91.0752,6.7355c-0.3782-0.2338-0.8221-0.3513-1.3329-0.3513c-0.5301,0-0.9934,0.1304-1.39,0.3912 			c-0.3965,0.2596-0.6723,0.6184-0.8297,1.0764h-0.0754V6.479h-2.4632v7.2213h2.5957V9.6382 			c0.0022-0.2382,0.0463-0.4429,0.1314-0.6131c0.0841-0.1713,0.2058-0.3028,0.3642-0.3955c0.1584-0.0927,0.3438-0.139,0.5571-0.139 			c0.3265,0,0.5807,0.1024,0.7639,0.306c0.1832,0.2037,0.2737,0.4838,0.2705,0.8415v4.0621h2.5957V9.093 			c0.0032-0.5237-0.1002-0.9891-0.3082-1.3965C91.7454,7.2893,91.4534,6.9682,91.0752,6.7355z"/>
|
65 |
-
</g>
|
66 |
-
<path d="M99.4526,10.0358c-0.362-0.3178-0.9137-0.5452-1.6529-0.6798L96.3322,9.093c-0.2758-0.0506-0.4612-0.1207-0.5571-0.2112 		c-0.0959-0.0916-0.1411-0.1896-0.1379-0.2963c-0.0032-0.1509,0.0743-0.2672,0.2349-0.348 		c0.1595-0.0819,0.3502-0.1228,0.5732-0.1228c0.1723,0,0.3297,0.0291,0.473,0.0872c0.1422,0.0582,0.2586,0.1401,0.3501,0.2468 		c0.0905,0.1067,0.1423,0.2338,0.1552,0.3815h2.3877c-0.0313-0.765-0.348-1.3641-0.9514-1.7962 		c-0.6034-0.4332-1.4277-0.6498-2.4707-0.6498c-0.6863,0-1.28,0.0927-1.78,0.2759s-0.8836,0.4493-1.1519,0.7995 		c-0.2683,0.3491-0.4008,0.7747-0.3976,1.2757c-0.0032,0.5679,0.1788,1.0312,0.5452,1.3921 		c0.3674,0.3599,0.9191,0.6044,1.655,0.7338l1.279,0.2252c0.2823,0.0506,0.4902,0.1163,0.6239,0.1972 		c0.1325,0.0819,0.2004,0.1918,0.2036,0.3297c-0.0032,0.1497-0.0819,0.2661-0.237,0.348c-0.1551,0.0808-0.3524,0.1218-0.5905,0.1218 		c-0.2942,0-0.5377-0.0614-0.7305-0.1853c-0.1929-0.1239-0.3071-0.3006-0.3416-0.529h-2.5762 		c0.0722,0.7391,0.4192,1.335,1.0419,1.7865c0.6217,0.4515,1.4848,0.6767,2.5881,0.6767c0.668,0,1.2628-0.1024,1.7843-0.3071 		c0.5215-0.2058,0.9342-0.4967,1.237-0.8749c0.3017-0.3782,0.4547-0.8232,0.4579-1.3372 		C99.9968,10.7793,99.8147,10.3537,99.4526,10.0358z"/>
|
67 |
-
</g>
|
68 |
-
</svg>
|
69 |
-
"""
|
70 |
-
|
71 |
-
python_token_code = r"""
|
72 |
-
# ethpen.com
|
73 |
-
# 最后更新日期:2023 年 8 月 18 日
|
74 |
-
|
75 |
-
# 在使用之前,敬请仔细阅读说明,感谢你的配合。
|
76 |
-
# 请务必访问 ethpen.com 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
77 |
-
# 你只需要掌握一些 python 相关的基础。
|
78 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
79 |
-
# 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
80 |
-
# 若你对此代码存有疑虑,建议你利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
81 |
-
# 如果你在使用的过程中发现 BUG 或者有什么想法和建议,欢迎与我联系。
|
82 |
-
|
83 |
-
# 导入运行代码所需要的库
|
84 |
-
from web3 import Web3 # 与以太坊交互的库,安装的命令是 pip install web3
|
85 |
-
import hashlib # 用于数据哈希,安装的命令是 pip install hashlib
|
86 |
-
import requests # 用于发送网络请求,安装的命令是 pip install requests
|
87 |
-
import re # 用于正则表达式
|
88 |
-
import time # 用于时间相关
|
89 |
-
|
90 |
-
# ---------- 以下是基础配置 ----------
|
91 |
-
|
92 |
-
# 填写你的多个 ETH 地址及私钥,建议填写新建的钱包,用英文逗号分隔(,),如下:地址,私钥。
|
93 |
-
accounts_str = '''
|
94 |
-
0xa62C8d0bB4F4530b9B68a14DaF8A949Cb01dB986,4de9b2812d51ba0ebbe7c990947b12544f7926a7aa1ebac084d42f6c7c8afbc1
|
95 |
-
0x71D10cc20Abe0af4EC16170C502a4319DE0e40B4,377f4a19719337b63d8280f0a52769a42b534343de1eccab4f6d204d1ca04815
|
96 |
-
0xBe169Ae4AD317B5632DE6Ae0e1EfeF0b22B1f91e,24fdf2ed0b820307582b06e1ed0b2047b4371e9d682e0b32455d310e08baafc5
|
97 |
-
'''
|
98 |
-
|
99 |
-
# 需要题写的代币铭文内容,变动的部分文本如 id 请用 "@#" 代替,例如:'data:,{"p":"erc-20","op":"mint","tick":"eths","id":"@#","amt":"1000"}'
|
100 |
-
ethscription = 'data:,{"p":"erc-20","op":"mint","tick":"eths","id":"@#","amt":"1000"}'
|
101 |
-
|
102 |
-
# 设置代币铭文 id 的起始和结束范围
|
103 |
-
min_id = 100 # 开始的整数
|
104 |
-
max_id = 888 # 结束的整数
|
105 |
-
|
106 |
-
# 决定是否在题写铭文之前检查该铭文有没有被题写过,如果需要检查就填写 Ture 如果不需要就填 False
|
107 |
-
check = False
|
108 |
-
|
109 |
-
# 每次交易成功后暂停 N 秒,0 为不暂停
|
110 |
-
sleep_sec = 0
|
111 |
-
|
112 |
-
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
113 |
-
w3 = Web3(Web3.HTTPProvider('https://sepolia.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206'))
|
114 |
-
|
115 |
-
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
116 |
-
chain_id = 11155111
|
117 |
-
|
118 |
-
# ---------- 以上是基础配置 ----------
|
119 |
-
|
120 |
-
|
121 |
-
# 检查 ETH 地址是否有效
|
122 |
-
def is_valid_eth_address(address):
|
123 |
-
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
124 |
-
return True
|
125 |
-
return False
|
126 |
-
|
127 |
-
|
128 |
-
# 检查 Ethereum 私钥是否有效
|
129 |
-
def is_valid_eth_private_key(private_key):
|
130 |
-
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
131 |
-
return True
|
132 |
-
return False
|
133 |
-
|
134 |
-
|
135 |
-
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
136 |
-
def validate_input(data_str):
|
137 |
-
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
138 |
-
return False
|
139 |
-
return True
|
140 |
-
|
141 |
-
|
142 |
-
# 把文字转换成 16 进制
|
143 |
-
def text_to_hex(text):
|
144 |
-
return ''.join(format(ord(char), '02x') for char in text)
|
145 |
-
|
146 |
-
|
147 |
-
# 使用sha256算法计算哈希
|
148 |
-
def sha256(input_string):
|
149 |
-
sha256 = hashlib.sha256()
|
150 |
-
sha256.update(input_string.encode('utf-8'))
|
151 |
-
return sha256.hexdigest()
|
152 |
-
|
153 |
-
|
154 |
-
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
155 |
-
def check_content_exists(sha):
|
156 |
-
# 定义请求的网址
|
157 |
-
endpoint = f"/ethscriptions/exists/{sha}"
|
158 |
-
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
159 |
-
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
160 |
-
if response.status_code == 200:
|
161 |
-
return response.json()['result']
|
162 |
-
|
163 |
-
|
164 |
-
# 发送自己到自己 0ETH 的交易
|
165 |
-
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
166 |
-
|
167 |
-
# 设置交易的相关信息
|
168 |
-
tx = {
|
169 |
-
'chainId': chain_id, # 网络 ID
|
170 |
-
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
171 |
-
'gasPrice': gas_price, # gas 的价格
|
172 |
-
'nonce': current_nonce, # 账户的交易数
|
173 |
-
'to': account_address, # 接收地址为自己
|
174 |
-
'value': 0, # 金额为 0ETH
|
175 |
-
'data': text_to_hex(input_data), # 铭文内容
|
176 |
-
}
|
177 |
-
|
178 |
-
# 用私钥签名这个交易
|
179 |
-
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
180 |
-
# 发送签名后的交易并获取交易哈希
|
181 |
-
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
182 |
-
# 打印结果信息
|
183 |
-
print(f'{account_address} | {input_data} | Transaction Hash: {tx_hash.hex()}')
|
184 |
-
|
185 |
-
|
186 |
-
# 初始化当前账户索引为 0
|
187 |
-
current_account_index = 0
|
188 |
-
# 创建账户列表
|
189 |
-
accounts = []
|
190 |
-
# 使用字典来跟踪每个地址的nonce
|
191 |
-
nonces = {}
|
192 |
-
|
193 |
-
|
194 |
-
if accounts_str: # 如果账户列表有内容
|
195 |
-
for line in accounts_str.strip().split('\n'): # 先去掉首尾的空白,然后根据换行符划分账户
|
196 |
-
if ',' in line: # 检查是否包含逗号
|
197 |
-
address, key = line.split(',') # 分开地址和私钥
|
198 |
-
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
199 |
-
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
200 |
-
nonces[address] = current_nonce # 记录地址的 nonce
|
201 |
-
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
202 |
-
else:
|
203 |
-
print(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
204 |
-
exit()
|
205 |
-
else:
|
206 |
-
print(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
207 |
-
exit()
|
208 |
-
|
209 |
-
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
210 |
-
if not validate_input(ethscription):
|
211 |
-
print("请注意:通常代币铭文文本里不��包含空格、换行符,而且所有的字母都必须为小写。")
|
212 |
-
|
213 |
-
# 检查是否留空
|
214 |
-
if not accounts or not ethscription:
|
215 |
-
print('请正确谨慎地填写内容,每一项都不应留空。')
|
216 |
-
exit()
|
217 |
-
else:
|
218 |
-
print('看起来你输入的内容均无没有问题!')
|
219 |
-
|
220 |
-
# 认真检查铭文内容,如果发现错误,输入 1 结束
|
221 |
-
print(f'铭文文本:\033[44m{ethscription}\033[m,题写 id 范围为:{min_id} - {max_id}。')
|
222 |
-
if input('请预览铭文,输入任意内容继续,输入 1 退出程序:') == '1':
|
223 |
-
exit()
|
224 |
-
print(f'开始任务,需要题写的铭文总量为:{max_id - min_id + 1}')
|
225 |
-
|
226 |
-
# 对代币铭文 id 进行循环
|
227 |
-
for the_id in range(min_id, max_id + 1):
|
228 |
-
# 使用当前账户发送交易
|
229 |
-
address, key = accounts[current_account_index]
|
230 |
-
# 得到完整的铭文文本
|
231 |
-
input_data = ethscription.replace('@#', str(the_id))
|
232 |
-
# 获取 gas
|
233 |
-
gas_price = w3.eth.gas_price
|
234 |
-
# 根据是否检查的开关进行
|
235 |
-
if check:
|
236 |
-
# 这里是开了检查后请求 Ethscriptions API
|
237 |
-
if check_content_exists(sha256(input_data)):
|
238 |
-
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
239 |
-
print(f'{input_data} 已经被题写!')
|
240 |
-
else:
|
241 |
-
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
242 |
-
# 使用 current_nonce 发送交易
|
243 |
-
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
244 |
-
# 交易成功后,手动增加 nonce 值
|
245 |
-
nonces[address] += 1
|
246 |
-
else:
|
247 |
-
# 这里是未开检查后直接发送交易
|
248 |
-
# 使用 current_nonce 发送交易
|
249 |
-
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
250 |
-
# 交易成功后,手动增加 nonce 值
|
251 |
-
nonces[address] += 1
|
252 |
-
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
253 |
-
current_account_index = (current_account_index + 1) % len(accounts)
|
254 |
-
# 暂停 sleep_sec 秒
|
255 |
-
time.sleep(sleep_sec)
|
256 |
-
|
257 |
-
print(f'所有任务已经完成。')
|
258 |
-
|
259 |
-
"""
|
260 |
-
|
261 |
-
python_name_code = r"""
|
262 |
-
# ethpen.com
|
263 |
-
# 最后更新日期:2023 年 8 月 18 日
|
264 |
-
|
265 |
-
# 在使用之前,敬请仔细阅读说明,感谢你的配合。
|
266 |
-
# 请务必访问 ethpen.com 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
267 |
-
# 你只需要掌握一些 python 相关的基础。
|
268 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
269 |
-
# 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
270 |
-
# 若你对此代码存有疑虑,建议你利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
271 |
-
# 如果你在使用的过程中发现 BUG 或者有什么想法和建议,欢迎与我联系。
|
272 |
-
|
273 |
-
# 导入运行代码所需要的库
|
274 |
-
from web3 import Web3 # 与以太坊交互的库,安装的命令是 pip install web3
|
275 |
-
import hashlib # 用于数据哈希,安装的命令是 pip install hashlib
|
276 |
-
import requests # 用于发送网络请求,安装的命令是 pip install requests
|
277 |
-
import re # 用于正则表达式
|
278 |
-
import time # 用于时间相关
|
279 |
-
|
280 |
-
# ---------- 以下是基础配置 ----------
|
281 |
-
|
282 |
-
# 填写你的多个 ETH 地址及私钥,建议填写新建的钱包,用英文逗号分隔(,),如下:地址,私钥。
|
283 |
-
accounts_str = '''
|
284 |
-
0xa62C8d0bB4F4530b9B68a14DaF8A949Cb01dB986,4de9b2812d51ba0ebbe7c990947b12544f7926a7aa1ebac084d42f6c7c8afbc1
|
285 |
-
0x71D10cc20Abe0af4EC16170C502a4319DE0e40B4,377f4a19719337b63d8280f0a52769a42b534343de1eccab4f6d204d1ca04815
|
286 |
-
0xBe169Ae4AD317B5632DE6Ae0e1EfeF0b22B1f91e,24fdf2ed0b820307582b06e1ed0b2047b4371e9d682e0b32455d310e08baafc5
|
287 |
-
'''
|
288 |
-
|
289 |
-
# 需要题写的铭文内容,在三个单引号内输入多个域名铭文,可以用空格、换行符、英文逗号(,)分开,不要带 data:, 开头
|
290 |
-
# 不要带 data:, 开头
|
291 |
-
# 不要带 data:, 开头
|
292 |
-
ethscription = '''
|
293 |
-
123
|
294 |
-
12313131
|
295 |
-
2131 21313
|
296 |
-
12313 32313
|
297 |
-
423213v ethpen.com
|
298 |
-
'''
|
299 |
-
# 你希望添加的后缀
|
300 |
-
suffix = '.eths'
|
301 |
-
# 以空格、换行符、英文逗号分隔文本,并加上后缀
|
302 |
-
ethscription_list = [item.strip() + suffix for item in re.split(r'[\s,]+', ethscription) if item]
|
303 |
-
|
304 |
-
# 决定是否在题写铭文之前检查该铭文有没有被题写过,如果需要检查就填写 Ture 如果不需要就填 False
|
305 |
-
check = False
|
306 |
-
|
307 |
-
# 每次交易成功后暂停 N 秒,0 为不暂停
|
308 |
-
sleep_sec = 0
|
309 |
-
|
310 |
-
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
311 |
-
w3 = Web3(Web3.HTTPProvider('https://sepolia.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206'))
|
312 |
-
|
313 |
-
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
314 |
-
chain_id = 11155111
|
315 |
-
|
316 |
-
# ---------- 以上是基础配置 ----------
|
317 |
-
|
318 |
-
|
319 |
-
# 检查 ETH 地址是否有效
|
320 |
-
def is_valid_eth_address(address):
|
321 |
-
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
322 |
-
return True
|
323 |
-
return False
|
324 |
-
|
325 |
-
|
326 |
-
# 检查 Ethereum 私钥是否有效
|
327 |
-
def is_valid_eth_private_key(private_key):
|
328 |
-
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
329 |
-
return True
|
330 |
-
return False
|
331 |
-
|
332 |
-
|
333 |
-
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
334 |
-
def validate_input(data_str):
|
335 |
-
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
336 |
-
return False
|
337 |
-
return True
|
338 |
-
|
339 |
-
|
340 |
-
# 把文字转换成 16 进制
|
341 |
-
def text_to_hex(text):
|
342 |
-
return ''.join(format(ord(char), '02x') for char in text)
|
343 |
-
|
344 |
-
|
345 |
-
# 使用sha256算法计算哈希
|
346 |
-
def sha256(input_string):
|
347 |
-
sha256 = hashlib.sha256()
|
348 |
-
sha256.update(input_string.encode('utf-8'))
|
349 |
-
return sha256.hexdigest()
|
350 |
-
|
351 |
-
|
352 |
-
# 使用 Ethscriptions API(主网)检查某个铭文是否已存在
|
353 |
-
def check_content_exists(sha):
|
354 |
-
# 定义请求的网址
|
355 |
-
endpoint = f"/ethscriptions/exists/{sha}"
|
356 |
-
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
357 |
-
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
358 |
-
if response.status_code == 200:
|
359 |
-
return response.json()['result']
|
360 |
-
|
361 |
-
|
362 |
-
# 发送自己到自己 0ETH 的交易
|
363 |
-
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
364 |
-
|
365 |
-
# 设置交易的相关信息
|
366 |
-
tx = {
|
367 |
-
'chainId': chain_id, # 网络 ID
|
368 |
-
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
369 |
-
'gasPrice': gas_price, # gas 的价格
|
370 |
-
'nonce': current_nonce, # 账户的交易数
|
371 |
-
'to': account_address, # 接收地址为自己
|
372 |
-
'value': 0, # 金额为 0ETH
|
373 |
-
'data': text_to_hex(input_data), # 铭文内容
|
374 |
-
}
|
375 |
-
|
376 |
-
# 用私钥签名这个交易
|
377 |
-
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
378 |
-
# 发送签名后的交易并获取交易哈希
|
379 |
-
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
380 |
-
# 打印结果信息
|
381 |
-
print(f'{account_address} | {input_data} | Transaction Hash: {tx_hash.hex()}')
|
382 |
-
|
383 |
-
|
384 |
-
# 初始化当前账户索引为 0
|
385 |
-
current_account_index = 0
|
386 |
-
# 创建账户列表
|
387 |
-
accounts = []
|
388 |
-
# 使用字典来跟踪每个地址的nonce
|
389 |
-
nonces = {}
|
390 |
-
|
391 |
-
|
392 |
-
if accounts_str: # 如果账户列表有内容
|
393 |
-
for line in accounts_str.strip().split('\n'): # 先去掉首尾的空白,然后根据换行符划分账户
|
394 |
-
if ',' in line: # 检查是否包含逗号
|
395 |
-
address, key = line.split(',') # 分开地址和私钥
|
396 |
-
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
397 |
-
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
398 |
-
nonces[address] = current_nonce # 记录地址的 nonce
|
399 |
-
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
400 |
-
else:
|
401 |
-
print(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
402 |
-
exit()
|
403 |
-
else:
|
404 |
-
print(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
405 |
-
exit()
|
406 |
-
|
407 |
-
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
408 |
-
if not validate_input(ethscription):
|
409 |
-
print("请注意:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
410 |
-
|
411 |
-
# 检查是否留空
|
412 |
-
if not accounts or not ethscription:
|
413 |
-
print('请正确谨慎地填写内容,每一项都不应留空。')
|
414 |
-
exit()
|
415 |
-
else:
|
416 |
-
print('看起来你输入的内容均无没有问题!')
|
417 |
-
|
418 |
-
# 认真检查铭文内容,如果发现错误,输入 1 结束
|
419 |
-
for i in ethscription_list:
|
420 |
-
print(f'\033[44m{i}\033[m')
|
421 |
-
if input('请预览铭文,输入任意内容继续,输入 1 退出程序:') == '1':
|
422 |
-
exit()
|
423 |
-
print(f'开始任务,需要题写的铭文总量为:{len(ethscription_list)}')
|
424 |
-
|
425 |
-
# 对代币铭文 id 进行循环
|
426 |
-
for name_str in ethscription_list:
|
427 |
-
# 使用当前账户发送交易
|
428 |
-
address, key = accounts[current_account_index]
|
429 |
-
# 得到完整的铭文文本
|
430 |
-
if not name_str.startswith('data:,'):
|
431 |
-
input_data = f'data:,{name_str}'
|
432 |
-
else:
|
433 |
-
input_data = name_str
|
434 |
-
# 获取 gas
|
435 |
-
gas_price = w3.eth.gas_price
|
436 |
-
# 根据是否检查的开关进行
|
437 |
-
if check:
|
438 |
-
# 这里是开了检查后请求 Ethscriptions API
|
439 |
-
if check_content_exists(sha256(input_data)):
|
440 |
-
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
441 |
-
print(f'{input_data} 已经被题写!')
|
442 |
-
else:
|
443 |
-
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
444 |
-
# 使用 current_nonce 发送交易
|
445 |
-
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
446 |
-
# 交易成功后,手动增加 nonce 值
|
447 |
-
nonces[address] += 1
|
448 |
-
else:
|
449 |
-
# 这里是未开���查后直接发送交易
|
450 |
-
# 使用 current_nonce 发送交易
|
451 |
-
send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
452 |
-
# 交易成功后,手动增加 nonce 值
|
453 |
-
nonces[address] += 1
|
454 |
-
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
455 |
-
current_account_index = (current_account_index + 1) % len(accounts)
|
456 |
-
# 暂停 sleep_sec 秒
|
457 |
-
time.sleep(sleep_sec)
|
458 |
-
|
459 |
-
print(f'所有任务已经完成。')
|
460 |
-
|
461 |
-
"""
|
462 |
-
|
463 |
-
hf_token_code = r"""
|
464 |
-
# ethpen.com
|
465 |
-
# 最后更新日期:2023 年 8 月 18 日
|
466 |
-
|
467 |
-
# 在使用之前,敬请仔细阅读说明,感谢你的配合。
|
468 |
-
# 请务必访问 ethpen.com 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
469 |
-
# 你只需要拥有一个 HuggingFace.co 账户。
|
470 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
471 |
-
# 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
472 |
-
# 若你对此代码存有疑虑,建议你利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
473 |
-
# 请查看我们的例子 https://ethscriptions-name.hf.space。
|
474 |
-
|
475 |
-
# 导入运行代码所需要的库
|
476 |
-
import streamlit as st # streamlit app
|
477 |
-
from web3 import Web3 # 与以太坊交互的库
|
478 |
-
import hashlib # 用于数据哈希
|
479 |
-
import requests # 用于发送网络请求
|
480 |
-
import re # 用于正则表达式
|
481 |
-
import time # 用于时间相关
|
482 |
-
|
483 |
-
|
484 |
-
# 检查 ETH 地址是否有效
|
485 |
-
def is_valid_eth_address(address):
|
486 |
-
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
487 |
-
return True
|
488 |
-
return False
|
489 |
-
|
490 |
-
|
491 |
-
# 检查 Ethereum 私钥是否有效
|
492 |
-
def is_valid_eth_private_key(private_key):
|
493 |
-
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
494 |
-
return True
|
495 |
-
return False
|
496 |
-
|
497 |
-
|
498 |
-
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
499 |
-
def validate_input(data_str):
|
500 |
-
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
501 |
-
return False
|
502 |
-
return True
|
503 |
-
|
504 |
-
|
505 |
-
# 把文字转换成 16 进制
|
506 |
-
def text_to_hex(text):
|
507 |
-
return ''.join(format(ord(char), '02x') for char in text)
|
508 |
-
|
509 |
-
|
510 |
-
# 使用sha256算法计算哈希
|
511 |
-
def sha256(input_string):
|
512 |
-
sha256 = hashlib.sha256()
|
513 |
-
sha256.update(input_string.encode('utf-8'))
|
514 |
-
return sha256.hexdigest()
|
515 |
-
|
516 |
-
|
517 |
-
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
518 |
-
def check_content_exists(sha):
|
519 |
-
# 定义请求的网址
|
520 |
-
endpoint = f"/ethscriptions/exists/{sha}"
|
521 |
-
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
522 |
-
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
523 |
-
if response.status_code == 200:
|
524 |
-
return response.json()['result']
|
525 |
-
|
526 |
-
|
527 |
-
# 发送自己到自己 0ETH 的交易
|
528 |
-
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
529 |
-
|
530 |
-
# 设置交易的相关信息
|
531 |
-
tx = {
|
532 |
-
'chainId': chain_id, # 网络 ID
|
533 |
-
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
534 |
-
'gasPrice': gas_price, # gas 的价格
|
535 |
-
'nonce': current_nonce,
|
536 |
-
'to': account_address, # 接收地址为自己
|
537 |
-
'value': 0, # 金额为 0ETH
|
538 |
-
'data': text_to_hex(input_data), # 铭文内容
|
539 |
-
}
|
540 |
-
|
541 |
-
# 用私钥签名这个交易
|
542 |
-
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
543 |
-
# 发送签名后的交易并获取交易哈希
|
544 |
-
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
545 |
-
# 打印结果信息
|
546 |
-
st.toast(f'{input_data}', icon='✅')
|
547 |
-
# 返回铭文还有交易哈希
|
548 |
-
return input_data, tx_hash.hex()
|
549 |
-
|
550 |
-
# 网页前端显示
|
551 |
-
# 网页标题
|
552 |
-
st.markdown('# [ethpen.com](https://ethpen.com) 代币铭文批量题写')
|
553 |
-
# 提醒
|
554 |
-
st.info('''在使用之前,敬请仔细阅读说明,感谢你的配合。
|
555 |
-
- 请务必访问 **[ethpen.com](https://ethpen.com)** 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
556 |
-
- 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
557 |
-
- 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
558 |
-
- 若你对此代码存有疑虑,建议你利用如 [ChetGPT](https://chat.openai.com/)、[Bard](https://bard.google.com/) 或 [Claude](https://claude.ai/) 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
559 |
-
''')
|
560 |
-
|
561 |
-
# 连接的网络 ID。比如说,1 代表 Mainnet,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
562 |
-
net_options = {
|
563 |
-
'1': 'Mainnet',
|
564 |
-
'5': 'Goerli',
|
565 |
-
'11155111': 'Sepolia'
|
566 |
-
}
|
567 |
-
selected_option = st.selectbox(
|
568 |
-
'**网络 ID**',
|
569 |
-
list(net_options.keys()),
|
570 |
-
format_func=lambda x: f"{x} ({net_options[x]})"
|
571 |
-
)
|
572 |
-
chain_id = int(selected_option)
|
573 |
-
|
574 |
-
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
575 |
-
token_eth_prc_url = st.text_input(
|
576 |
-
f'**Ethereum PRC ���接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
577 |
-
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
578 |
-
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
579 |
-
|
580 |
-
# 初始化当前账户索引为 0
|
581 |
-
current_account_index = 0
|
582 |
-
# 收集和显示所有交易的结果
|
583 |
-
transaction_results = []
|
584 |
-
# 创建账户列表
|
585 |
-
accounts = []
|
586 |
-
# 使用字典来跟踪每个地址的nonce
|
587 |
-
nonces = {}
|
588 |
-
|
589 |
-
# 启用多账户操作
|
590 |
-
if st.checkbox(f'启用**多账户**操作'):
|
591 |
-
# 多账户的文本框
|
592 |
-
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
593 |
-
if account_list: # 如果账户列表有内容
|
594 |
-
for line in account_list.split('\n'): # 根据换行符划分账户
|
595 |
-
if ',' in line: # 检查是否包含逗号
|
596 |
-
address, key = line.split(',') # 分开地址和私钥
|
597 |
-
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
598 |
-
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
599 |
-
nonces[address] = current_nonce # 记录地址的 nonce
|
600 |
-
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
601 |
-
else:
|
602 |
-
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
603 |
-
st.stop()
|
604 |
-
else:
|
605 |
-
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
606 |
-
st.stop()
|
607 |
-
else:
|
608 |
-
account_address = st.text_input('填写你的 **ETH 地址**:')
|
609 |
-
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
610 |
-
if account_address and private_key: # 如果地址和私钥有内容
|
611 |
-
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
612 |
-
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
613 |
-
nonces[account_address] = current_nonce # 记录地址的 nonce
|
614 |
-
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
615 |
-
else:
|
616 |
-
st.error("地址或私钥无效,请检查!")
|
617 |
-
st.stop()
|
618 |
-
|
619 |
-
# 配置铭文文本
|
620 |
-
token_protocol = st.text_input('填写需要题写代币铭文协议 **Protocol(p)**:', 'erc-20')
|
621 |
-
token_operation = st.text_input('填写需要题写代币铭文操作 **Operation(op)**:', 'mint')
|
622 |
-
token_ticker = st.text_input('填写需要题写代币铭文简称 **Ticker(tick)**:')
|
623 |
-
token_min_id = st.number_input('填写需要题写代币铭文范围的**最小 ID(id)**:', min_value=1, value=1, step=1)
|
624 |
-
token_max_id = st.number_input('填写需要题写代币铭文范围的**最大 ID(id)**:', value=21000, step=1)
|
625 |
-
token_amount = st.number_input('填写需要题写代币铭文数量 **Amount(amt)**:', min_value=1, value=1000, step=1)
|
626 |
-
st.markdown('###### 预览你需要题写的代币铭文:')
|
627 |
-
st.code(
|
628 |
-
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}',
|
629 |
-
language="json", line_numbers=False)
|
630 |
-
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
631 |
-
if not validate_input(
|
632 |
-
f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{token_min_id}","amt":"{token_amount}"}}'):
|
633 |
-
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
634 |
-
|
635 |
-
# 题写铭文之前检查该铭文有没有被题写
|
636 |
-
if st.checkbox(f'题写铭文之前**检查该铭文有没有被题写**'):
|
637 |
-
token_check = True
|
638 |
-
else:
|
639 |
-
token_check = False
|
640 |
-
|
641 |
-
# 每次交易成功后暂停 3 秒
|
642 |
-
if st.checkbox(f'每次交易完成后暂停 3 秒'):
|
643 |
-
sleep_3s = True
|
644 |
-
else:
|
645 |
-
sleep_3s = False
|
646 |
-
|
647 |
-
# 点击发送交易开始
|
648 |
-
if st.button(f'开始**发送交易**'):
|
649 |
-
if not accounts or not token_protocol or not token_operation or not token_ticker: # 检查是否留空
|
650 |
-
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
651 |
-
st.stop()
|
652 |
-
else:
|
653 |
-
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
654 |
-
|
655 |
-
st.toast(f'开始任务,需要题写的铭文总量为:{token_max_id - token_min_id + 1}', icon='😎')
|
656 |
-
|
657 |
-
# 对代币铭文 id 进行循环
|
658 |
-
for the_id in range(token_min_id, token_max_id + 1):
|
659 |
-
# 使用当前账户发送交易,获取当前账户的 nonce
|
660 |
-
address, key = accounts[current_account_index]
|
661 |
-
# 得到完整的铭文文本
|
662 |
-
input_data = f'data:,{{"p":"{token_protocol}","op":"{token_operation}","tick":"{token_ticker}","id":"{the_id}","amt":"{token_amount}"}}'
|
663 |
-
# 获取 gas
|
664 |
-
gas_price = w3.eth.gas_price
|
665 |
-
# 根据是否检查的开关进行
|
666 |
-
if token_check:
|
667 |
-
# 这里是开了检查后请求 Ethscriptions API
|
668 |
-
if check_content_exists(sha256(input_data)):
|
669 |
-
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
670 |
-
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
671 |
-
else:
|
672 |
-
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
673 |
-
# 使用 current_nonce 发送交易
|
674 |
-
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
675 |
-
# 记录最后输出的结果
|
676 |
-
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
677 |
-
# 交易成功后,手动增加 nonce 值
|
678 |
-
nonces[address] += 1
|
679 |
-
else:
|
680 |
-
# 这里是未开检查后直接发送交易
|
681 |
-
# 使用 current_nonce 发送交易
|
682 |
-
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
683 |
-
# 记录最后输出的结果
|
684 |
-
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
685 |
-
# 交易成功后,手动增加 nonce 值
|
686 |
-
nonces[address] += 1
|
687 |
-
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
688 |
-
current_account_index = (current_account_index + 1) % len(accounts)
|
689 |
-
# 暂停 3 秒
|
690 |
-
if sleep_3s:
|
691 |
-
time.sleep(3) # 暂停三秒
|
692 |
-
st.toast(f'所有任务已经完成。', icon='🎉')
|
693 |
-
# 庆祝动画
|
694 |
-
st.balloons()
|
695 |
-
# 显示所有交易的结果
|
696 |
-
st.code('\n'.join(transaction_results))
|
697 |
-
|
698 |
-
"""
|
699 |
-
|
700 |
-
hf_name_code = r"""
|
701 |
-
# ethpen.com
|
702 |
-
# 最后更新日期:2023 年 8 月 18 日
|
703 |
-
|
704 |
-
# 在使用之前,敬请仔细阅读说明,感谢你的配合。
|
705 |
-
# 请务必访问 ethpen.com 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
706 |
-
# 你只需要拥有一个 HuggingFace.co 账户。
|
707 |
-
# 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
708 |
-
# 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
709 |
-
# 若你对此代码存有疑虑,建议你利用如 ChetGPT、Bard 或 Claude 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
710 |
-
# 请查看我们的例子 https://ethscriptions-name.hf.space。
|
711 |
-
|
712 |
-
# 导入运行代码所需要的库
|
713 |
-
import streamlit as st # streamlit app
|
714 |
-
from web3 import Web3 # 与以太坊交互的库
|
715 |
-
import hashlib # 用于数据哈希
|
716 |
-
import requests # 用于发送网络请求
|
717 |
-
import re # 用于正则表达式
|
718 |
-
import time # 用于时间相关
|
719 |
-
|
720 |
-
|
721 |
-
# 检查 ETH 地址是否有效
|
722 |
-
def is_valid_eth_address(address):
|
723 |
-
if re.match("^0x[0-9a-fA-F]{40}$", address):
|
724 |
-
return True
|
725 |
-
return False
|
726 |
-
|
727 |
-
|
728 |
-
# 检查 Ethereum 私钥是否有效
|
729 |
-
def is_valid_eth_private_key(private_key):
|
730 |
-
if re.match("^[0-9a-fA-F]{64}$", private_key):
|
731 |
-
return True
|
732 |
-
return False
|
733 |
-
|
734 |
-
|
735 |
-
# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
|
736 |
-
def validate_input(data_str):
|
737 |
-
if re.search(r'[A-Z\s\n]', data_str): # 查找大写字母、空格或换行符
|
738 |
-
return False
|
739 |
-
return True
|
740 |
-
|
741 |
-
|
742 |
-
# 分隔文本函数
|
743 |
-
def split_and_append(ethscriptions_str, name_selected_option):
|
744 |
-
separators = [' ', '\n', ',']
|
745 |
-
split_texts = [ethscriptions_str] # 初始时只有一个完整文本
|
746 |
-
|
747 |
-
for sep in separators:
|
748 |
-
pieces = []
|
749 |
-
for text in split_texts:
|
750 |
-
pieces.extend(text.split(sep))
|
751 |
-
split_texts = pieces
|
752 |
-
|
753 |
-
# 移除空字符串
|
754 |
-
split_texts = [text.strip() + name_selected_option for text in split_texts if text.strip() != '']
|
755 |
-
|
756 |
-
return split_texts
|
757 |
-
|
758 |
-
|
759 |
-
# 把文字转换成 16 进制
|
760 |
-
def text_to_hex(text):
|
761 |
-
return ''.join(format(ord(char), '02x') for char in text)
|
762 |
-
|
763 |
-
|
764 |
-
# 使用sha256算法计算哈希
|
765 |
-
def sha256(input_string):
|
766 |
-
sha256 = hashlib.sha256()
|
767 |
-
sha256.update(input_string.encode('utf-8'))
|
768 |
-
return sha256.hexdigest()
|
769 |
-
|
770 |
-
|
771 |
-
# 使用 Ethscriptions API(主网)检查某个铭文是否已题写
|
772 |
-
def check_content_exists(sha):
|
773 |
-
# 定义请求的网址
|
774 |
-
endpoint = f"/ethscriptions/exists/{sha}"
|
775 |
-
response = requests.get('https://mainnet-api.ethscriptions.com/api' + endpoint)
|
776 |
-
# 如果返回状态码是200,说明请求成功,然后返回结果(Ture or False)
|
777 |
-
if response.status_code == 200:
|
778 |
-
return response.json()['result']
|
779 |
-
|
780 |
-
|
781 |
-
# 发送自己到自己 0ETH 的交易
|
782 |
-
def send_transaction(w3, account_address, private_key, chain_id, gas_price, input_data, current_nonce):
|
783 |
-
|
784 |
-
# 设置交易的相关信息
|
785 |
-
tx = {
|
786 |
-
'chainId': chain_id, # 网络 ID
|
787 |
-
'gas': 25000, # 如果交易 gas 过低,可适当调高
|
788 |
-
'gasPrice': gas_price, # gas 的价格
|
789 |
-
'nonce': current_nonce,
|
790 |
-
'to': account_address, # 接收地址为自己
|
791 |
-
'value': 0, # 金额�� 0ETH
|
792 |
-
'data': text_to_hex(input_data), # 铭文内容
|
793 |
-
}
|
794 |
-
|
795 |
-
# 用私钥签名这个交易
|
796 |
-
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
|
797 |
-
# 发送签名后的交易并获取交易哈希
|
798 |
-
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
799 |
-
# 打印结果信息
|
800 |
-
st.toast(f'{input_data}', icon='✅')
|
801 |
-
# 返回铭文还有交易哈希
|
802 |
-
return input_data, tx_hash.hex()
|
803 |
-
|
804 |
-
# 网页前端显示
|
805 |
-
# 网页标题
|
806 |
-
st.markdown('# [ethpen.com](https://ethpen.com) 域名铭文批量题写')
|
807 |
-
# 提醒
|
808 |
-
st.info('''在使用之前,敬请仔细阅读说明,感谢你的配合。
|
809 |
-
- 请务必访问 **[ethpen.com](https://ethpen.com)** 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
810 |
-
- 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
811 |
-
- 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
812 |
-
- 若你对此代码存有疑虑,建议你利用如 [ChetGPT](https://chat.openai.com/)、[Bard](https://bard.google.com/) 或 [Claude](https://claude.ai/) 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
813 |
-
''')
|
814 |
-
|
815 |
-
# 连接的网络 ID。比如说,1 代表主网络,5 代表 Goerli 测试网络,11155111 代表 Sepolia 测试网络,如果你不放心,可以先用测试网试试。
|
816 |
-
net_options = {
|
817 |
-
'1': 'Mainnet',
|
818 |
-
'5': 'Goerli',
|
819 |
-
'11155111': 'Sepolia'
|
820 |
-
}
|
821 |
-
selected_option = st.selectbox(
|
822 |
-
'**网络 ID**',
|
823 |
-
list(net_options.keys()),
|
824 |
-
format_func=lambda x: f"{x} ({net_options[x]})"
|
825 |
-
)
|
826 |
-
chain_id = int(selected_option)
|
827 |
-
|
828 |
-
# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
|
829 |
-
token_eth_prc_url = st.text_input(
|
830 |
-
f'**Ethereum PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
|
831 |
-
f'https://{net_options[str(chain_id)]}.infura.io/v3/eab7f935b9af45e1a54f7d7ed06c5206')
|
832 |
-
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))
|
833 |
-
# 初始化当前账户索引为 0
|
834 |
-
current_account_index = 0
|
835 |
-
# 收集和显示所有交易的结果
|
836 |
-
transaction_results = []
|
837 |
-
# 创建账户列表
|
838 |
-
accounts = []
|
839 |
-
# 使用字典来跟踪每个地址的nonce
|
840 |
-
nonces = {}
|
841 |
-
|
842 |
-
# 启用多账户操作
|
843 |
-
if st.checkbox(f'启用**多账户**操作'):
|
844 |
-
# 多账户的文本框
|
845 |
-
account_list = st.text_area(f'输入多个 **ETH 地址及其对应的私钥**,用英文逗号分隔(,),如下:地址,私钥')
|
846 |
-
if account_list: # 如果账户列表有内容
|
847 |
-
for line in account_list.split('\n'): # 根据换行符划分账户
|
848 |
-
if ',' in line: # 检查是否包含逗号
|
849 |
-
address, key = line.split(',') # 分开地址和私钥
|
850 |
-
if is_valid_eth_address(address) and is_valid_eth_private_key(key): # 验证地址和私钥
|
851 |
-
current_nonce = w3.eth.get_transaction_count(address) # 获取地址的 nonce
|
852 |
-
nonces[address] = current_nonce # 记录地址的 nonce
|
853 |
-
accounts.append((address.strip(), key.strip())) # 保存地址和私钥还有 nonce
|
854 |
-
else:
|
855 |
-
st.error(f"地址 {address} 或私钥 {key} 无效,请检查!")
|
856 |
-
st.stop()
|
857 |
-
else:
|
858 |
-
st.error(f"输入格式错误,请确保每行包含一个地址和一个私钥,并使用英文逗号分隔(,)。错误行:**{line}**")
|
859 |
-
st.stop()
|
860 |
-
else:
|
861 |
-
account_address = st.text_input('填写你的 **ETH 地址**:')
|
862 |
-
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
|
863 |
-
if account_address and private_key: # 如果地址和私钥有内容
|
864 |
-
if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key): # 验证地址和私钥
|
865 |
-
current_nonce = w3.eth.get_transaction_count(account_address) # 获取地址的 nonce
|
866 |
-
nonces[account_address] = current_nonce # 记录地址的 nonce
|
867 |
-
accounts.append((account_address.strip(), private_key.strip())) # 保存地址和私钥还有 nonce
|
868 |
-
else:
|
869 |
-
st.error("地址或私钥无效,请检查!")
|
870 |
-
st.stop()
|
871 |
-
|
872 |
-
# 配置铭文文本
|
873 |
-
ethscriptions_str = st.text_area(f'输入**多个域名铭文或其他**,可以用空格、换行符、英文逗号(,)分开,不要带 data:, 前缀,不要带域名后缀')
|
874 |
-
name_options = ["自定义", ".eth", ".eths", ".tree", ".honk", ".etch"]
|
875 |
-
name_selected_option = st.selectbox(f'选择**域名后缀**', name_options)
|
876 |
-
if name_selected_option == '自定义':
|
877 |
-
name_selected_option = st.text_input('输入**自定义的域名**:')
|
878 |
-
# 以空格、换行符、英文逗号分隔文本并加上后缀
|
879 |
-
ethscription_list = split_and_append(ethscriptions_str, name_selected_option)
|
880 |
-
|
881 |
-
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
|
882 |
-
if not validate_input(''.join(ethscription_list)):
|
883 |
-
st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")
|
884 |
-
|
885 |
-
# 题写铭文之前检查该铭文有没有被题写
|
886 |
-
if st.checkbox(f'题写铭文之前**检查该铭文有没有被题写**'):
|
887 |
-
token_check = True
|
888 |
-
else:
|
889 |
-
token_check = False
|
890 |
-
|
891 |
-
# 每次交易成功后暂停 3 秒
|
892 |
-
if st.checkbox(f'每次交易完成后暂停 3 秒'):
|
893 |
-
sleep_3s = True
|
894 |
-
else:
|
895 |
-
sleep_3s = False
|
896 |
-
|
897 |
-
# 点击发送交易开始
|
898 |
-
if st.button(f'开始**发送交易**'):
|
899 |
-
if not accounts or not ethscriptions_str or not name_selected_option: # 检查是否留空
|
900 |
-
st.error(f'请正确谨慎地填写内容,每一项都**不应留空**。')
|
901 |
-
st.stop()
|
902 |
-
else:
|
903 |
-
st.toast('看起来你输入的内容均无没有问题!', icon='🥳')
|
904 |
-
|
905 |
-
st.toast(f'开始任务,需要题写的铭文总量为:{len(ethscription_list)}', icon='😎')
|
906 |
-
|
907 |
-
# 对代币铭文 id 进行循环
|
908 |
-
for name_str in ethscription_list:
|
909 |
-
# 使用当前账户发送交易,获取当前账户的 nonce
|
910 |
-
address, key = accounts[current_account_index]
|
911 |
-
# 获取 gas
|
912 |
-
gas_price = w3.eth.gas_price
|
913 |
-
# 得到完整的铭文文本
|
914 |
-
if not name_str.startswith('data:,'):
|
915 |
-
input_data = f'data:,{name_str}'
|
916 |
-
|
917 |
-
# 根据是否检查的开关进行
|
918 |
-
if token_check:
|
919 |
-
# 这里是开了检查后请求 Ethscriptions API
|
920 |
-
if check_content_exists(sha256(input_data)):
|
921 |
-
# 返回数据为 Ture,说明该铭文已经被题写,打印信息
|
922 |
-
st.toast(f'{input_data} 已经被题写!', icon='☹️')
|
923 |
-
else:
|
924 |
-
# 返回数据为 False,说明该铭文还没被题写,发送交易
|
925 |
-
# 使用 current_nonce 发送交易
|
926 |
-
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
927 |
-
# 记录最后输出的结果
|
928 |
-
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
929 |
-
# 交易成功后,手动增加 nonce 值
|
930 |
-
nonces[address] += 1
|
931 |
-
else:
|
932 |
-
# 这里是未开检查后直接发送交易
|
933 |
-
# 使用 current_nonce 发送交易
|
934 |
-
data, tx_hash = send_transaction(w3, address, key, chain_id, gas_price, input_data, nonces[address])
|
935 |
-
# 记录最后输出的结果
|
936 |
-
transaction_results.append(f"{address} | {data} | Transaction Hash: {tx_hash}")
|
937 |
-
# 交易成功后,手动增加 nonce 值
|
938 |
-
nonces[address] += 1
|
939 |
-
# 更新当前账户索引,确保索引始终在账户列表的范围内
|
940 |
-
current_account_index = (current_account_index + 1) % len(accounts)
|
941 |
-
# 暂停 3 秒
|
942 |
-
if sleep_3s:
|
943 |
-
time.sleep(3) # 暂停三秒
|
944 |
-
st.toast(f'所有任务已经完成。', icon='🎉')
|
945 |
-
# 庆祝动画
|
946 |
-
st.balloons()
|
947 |
-
# 显示所有交易的结果
|
948 |
-
st.code('\n'.join(transaction_results))
|
949 |
-
|
950 |
-
"""
|
951 |
-
|
952 |
my_style = '''
|
953 |
<style>
|
954 |
.tag {
|
@@ -1206,10 +301,10 @@ st.markdown('')
|
|
1206 |
st.markdown(f'同时我们也可以前往 <span class="tag"><a href="https://ethscriptions.com/" target="_blank" style="text-decoration: none;"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "ethscriptions_logo_litto.png"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;"/> Ethscriptions</span></a> 官方网站查看我们的铭文。', unsafe_allow_html=True)
|
1207 |
st.markdown(f'如果你觉得上述的方法步骤繁琐,我们建议你使用 Ethscriptions 官方推荐的 [EthScriber](https://ethscriber.xyz/) 还有 [Etherscan IDM](https://etherscan.io/idm),其他题写工具须在你确保安全的情况下使用,因为你不能确定它要发送什么铭文的交易。', unsafe_allow_html=True)
|
1208 |
st.markdown(f'EthPen.com 不仅为你提供优质的工具,还有详尽的教程供你参考。欢迎你前来探索!', unsafe_allow_html=True)
|
|
|
1209 |
# st.expander
|
1210 |
search_rune_expander = st.expander("查询 Ethscriptions")
|
1211 |
-
|
1212 |
-
token_no_code_expander = st.expander("一键式铭文批量题写,无需编码知识!")
|
1213 |
st.markdown(f'🎉 更多功能尽在左上角的 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "greater-than.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 菜单栏</span>', unsafe_allow_html=True)
|
1214 |
# 查询铭文页面
|
1215 |
search_rune_expander.info(
|
@@ -1327,76 +422,6 @@ if search_rune_expander.button('🔍 查询', key='批量查询铭文'):
|
|
1327 |
mime="text/csv"
|
1328 |
)
|
1329 |
|
1330 |
-
# 题写铭文页面
|
1331 |
-
create_rune_expander.markdown("##### 文本转换到十六进制")
|
1332 |
-
input_ethscriptions_str = create_rune_expander.text_input(
|
1333 |
-
'输入需要转换的文本,默认以 "data:," 开头,换行和回车字符不应出现。', '')
|
1334 |
-
if create_rune_expander.button('🔁 转换', key='文本转换到十六进制'):
|
1335 |
-
if not input_ethscriptions_str.startswith('data:,'):
|
1336 |
-
input_ethscriptions_str = f'data:,{input_ethscriptions_str}'
|
1337 |
-
input_ethscriptions_hex = text_to_hex(input_ethscriptions_str)
|
1338 |
-
create_rune_expander.markdown(f':green[{input_ethscriptions_str}] 转换到十六进制:')
|
1339 |
-
create_rune_expander.code(input_ethscriptions_hex, line_numbers=False)
|
1340 |
-
input_ethscriptions_sha = sha256(input_ethscriptions_str)
|
1341 |
-
ethscriptions_data = check_content_exists(input_ethscriptions_sha)
|
1342 |
-
if ethscriptions_data['result']:
|
1343 |
-
create_rune_expander.markdown(f'###### :green[{ethscriptions_str}] 相关信息如下:')
|
1344 |
-
selected_data = {
|
1345 |
-
'当前拥有者': ethscriptions_data["ethscription"]["current_owner"],
|
1346 |
-
'题写时间': ethscriptions_data["ethscription"]["creation_timestamp"],
|
1347 |
-
'铭文编号': f'#{ethscriptions_data["ethscription"]["ethscription_number"]}',
|
1348 |
-
'铭文完整内容': ethscriptions_data["ethscription"]["content_uri"],
|
1349 |
-
}
|
1350 |
-
create_rune_expander.json(selected_data)
|
1351 |
-
else:
|
1352 |
-
create_rune_expander.markdown(f'###### :green[{input_ethscriptions_str}] 铭文还没被题写!快前去题写吧。')
|
1353 |
-
|
1354 |
-
create_rune_expander.markdown("##### 批量自动题写铭文")
|
1355 |
-
create_rune_expander.info("""在使用之前,敬请仔细阅读说明,感谢你的配合。
|
1356 |
-
1. 请务必访问 **[ethpen.com](https://ethpen.com)** 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
1357 |
-
2. 你只需要掌握一些 python 相关的基础。
|
1358 |
-
3. 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
1359 |
-
4. 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
1360 |
-
5. 若你对此代码存有疑虑,建议你利用如 [ChetGPT](https://chat.openai.com/)、[Bard](https://bard.google.com/) 或 [Claude](https://claude.ai/) 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
1361 |
-
6. 如果你在使用的过程中发现 BUG 或者有什么想法和建议,欢迎与我联系。
|
1362 |
-
""")
|
1363 |
-
if create_rune_expander.button('🖨 打印代币代码', key='输出代币铭文 Python 代码'):
|
1364 |
-
create_rune_expander.code(python_token_code, 'python', line_numbers=False)
|
1365 |
-
if create_rune_expander.button('🖨 打印域名代码', key='输出域名铭文 Python 代码'):
|
1366 |
-
create_rune_expander.code(python_name_code, 'python', line_numbers=False)
|
1367 |
-
|
1368 |
-
# 全新不用懂代码的铭文批量题写页面
|
1369 |
-
token_no_code_expander.markdown("##### 安全的简易的批量自动题写铭文")
|
1370 |
-
token_no_code_expander.info("""在使用之前,敬请仔细阅读说明,感谢你的配合。
|
1371 |
-
1. 请务必访问 **[ethpen.com](https://ethpen.com)** 官方网站。你可以确保这里的代码无恶意,安全地复制。
|
1372 |
-
2. 你只需要拥有一个 [HuggingFace.co](https://huggingface.co) 账户。
|
1373 |
-
3. 在使用过程中,请根据规定准确填写信息,以确保程序顺畅运行。
|
1374 |
-
4. 我们建议你使用备用账号,并避免在账号中存放大额资金。
|
1375 |
-
5. 若你对此代码存有疑虑,建议你利用如 [ChetGPT](https://chat.openai.com/)、[Bard](https://bard.google.com/) 或 [Claude](https://claude.ai/) 等知名 AI 平台进行查询,以判断是否含有恶意代码。
|
1376 |
-
6. 请查看我们的例子 [token-example](https://huggingface.co/spaces/Ethscriptions/token) / [name-example](https://huggingface.co/spaces/Ethscriptions/name)。
|
1377 |
-
""")
|
1378 |
-
if token_no_code_expander.button('🖨️ 打印代币代码', key='输出 Token 铭文 Python 代码'):
|
1379 |
-
token_no_code_expander.markdown(
|
1380 |
-
f'**为 [HuggingFace.co](https://huggingface.co) 平台与 [Streamlit.io](https://streamlit.io/) 框架量身打造的代币铭文专业 Python 代码(app.py):**')
|
1381 |
-
token_no_code_expander.code(hf_token_code, 'python', line_numbers=False)
|
1382 |
-
token_no_code_expander.markdown(f"**依赖包清单(requirements.txt):**")
|
1383 |
-
token_no_code_expander.code('''
|
1384 |
-
Requests
|
1385 |
-
streamlit
|
1386 |
-
web3
|
1387 |
-
''')
|
1388 |
-
if token_no_code_expander.button('🖨️ 打印域名代码', key='输出 Name 铭文 Python 代码'):
|
1389 |
-
token_no_code_expander.markdown(
|
1390 |
-
f'**为 [HuggingFace.co](https://huggingface.co) 平台与 [Streamlit.io](https://streamlit.io/) 框架量身打造的域名铭文专业 Python 代码(app.py):**')
|
1391 |
-
token_no_code_expander.code(hf_name_code, 'python', line_numbers=False)
|
1392 |
-
token_no_code_expander.markdown(f"**依赖包清单(requirements.txt):**")
|
1393 |
-
token_no_code_expander.code('''
|
1394 |
-
Requests
|
1395 |
-
streamlit
|
1396 |
-
web3
|
1397 |
-
''')
|
1398 |
-
|
1399 |
-
|
1400 |
st.markdown('#### Ethscriptions 上的龙头代币是?')
|
1401 |
st.markdown(
|
1402 |
f'毫无疑问,当之无愧,它必须是 Ethscriptions 上第一个代币 <span class="tag"><a href="https://www.etch.market/market/token?category=token&collectionName=erc-20%20eths" target="_blank" style="text-decoration: none;"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "eths_logo.png"))}" alt="Image" width="20px" height="20px"/> $eths</span></a>',
|
|
|
44 |
{'p': 'erc-20', 'tick': 'etch', 'id': 21000, 'amt': '1000'},
|
45 |
{'p': 'erc-20', 'tick': 'dumb', 'id': 21000, 'amt': '1000'}]
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
my_style = '''
|
48 |
<style>
|
49 |
.tag {
|
|
|
301 |
st.markdown(f'同时我们也可以前往 <span class="tag"><a href="https://ethscriptions.com/" target="_blank" style="text-decoration: none;"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "ethscriptions_logo_litto.png"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;"/> Ethscriptions</span></a> 官方网站查看我们的铭文。', unsafe_allow_html=True)
|
302 |
st.markdown(f'如果你觉得上述的方法步骤繁琐,我们建议你使用 Ethscriptions 官方推荐的 [EthScriber](https://ethscriber.xyz/) 还有 [Etherscan IDM](https://etherscan.io/idm),其他题写工具须在你确保安全的情况下使用,因为你不能确定它要发送什么铭文的交易。', unsafe_allow_html=True)
|
303 |
st.markdown(f'EthPen.com 不仅为你提供优质的工具,还有详尽的教程供你参考。欢迎你前来探索!', unsafe_allow_html=True)
|
304 |
+
|
305 |
# st.expander
|
306 |
search_rune_expander = st.expander("查询 Ethscriptions")
|
307 |
+
|
|
|
308 |
st.markdown(f'🎉 更多功能尽在左上角的 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "greater-than.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 菜单栏</span>', unsafe_allow_html=True)
|
309 |
# 查询铭文页面
|
310 |
search_rune_expander.info(
|
|
|
422 |
mime="text/csv"
|
423 |
)
|
424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
st.markdown('#### Ethscriptions 上的龙头代币是?')
|
426 |
st.markdown(
|
427 |
f'毫无疑问,当之无愧,它必须是 Ethscriptions 上第一个代币 <span class="tag"><a href="https://www.etch.market/market/token?category=token&collectionName=erc-20%20eths" target="_blank" style="text-decoration: none;"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "eths_logo.png"))}" alt="Image" width="20px" height="20px"/> $eths</span></a>',
|