File size: 5,916 Bytes
43c0549
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5c33ba8
9ab57a6
5c33ba8
 
 
9ab57a6
 
 
fbe598b
9ab57a6
 
4930535
9ab57a6
 
 
 
 
 
 
 
 
853f7c8
9ab57a6
 
 
853f7c8
9ab57a6
 
43c0549
 
04beda8
43c0549
853f7c8
43c0549
 
853f7c8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43c0549
853f7c8
 
 
 
4930535
853f7c8
 
 
 
 
 
 
 
 
43c0549
853f7c8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# EthPen.com

# 导入运行代码所需要的库
import streamlit as st  # streamlit app
from web3 import Web3  # 与以太坊交互的库
import hashlib  # 用于数据哈希
import re  # 用于正则表达式
import time  # 用于时间相关


# 许可使用开关
approved_use = False


# 检查 ETH 地址是否有效
def is_valid_eth_address(address):
    if re.match("^0x[0-9a-fA-F]{40}$", address):
        return True
    return False


# 检查 Ethereum 私钥是否有效
def is_valid_eth_private_key(private_key):
    if re.match("^[0-9a-fA-F]{64}$", private_key):
        return True
    return False


# 验证输入的铭文文本是否含有空格和换行符,而且字母全部为小写
def validate_input(data_str):
    if re.search(r'[A-Z\s\n]', data_str):  # 查找大写字母、空格或换行符
        return False
    return True


# 把文字转换成 16 进制
def text_to_hex(text):
    return ''.join(format(byte, '02x') for byte in text.encode('utf-8'))


# 使用sha256算法计算哈希
def sha256(input_string):
    sha256 = hashlib.sha256()
    sha256.update(input_string.encode('utf-8'))
    return sha256.hexdigest()


# 发送自己到自己 0ETH 的交易
def send_transaction(w3, account_address, private_key, chain_id, input_data, the_id):
    try:
        gas_price = w3.eth.gas_price
        # 自动获取最新的 nonce
        current_nonce = w3.eth.get_transaction_count(account_address)
        # 设置交易的相关信息
        tx = {
            'chainId': chain_id,  # 网络 ID
            'gas': 200000,  # 如果交易 gas 过低,可适当调高
            'gasPrice': gas_price,  # gas 的价格
            'nonce': current_nonce,
            'to': '0x88cF5dbD0F2F92E8B223AB94A8B08Ea6901048fa',  # 接收地址为自己
            'value': 0,  # 金额为 0ETH
            'data': text_to_hex(input_data),  # 铭文内容
        }

        # 用私钥签名这个交易
        signed_tx = w3.eth.account.sign_transaction(tx, private_key)
        # 发送签名后的交易并获取交易哈希
        tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
        # 打印结果信息
        st.toast(f'{the_id},上链了!', icon='✅')
        # 返回铭文还有交易哈希
        return input_data, tx_hash.hex()
    except Exception as e:
        st.toast(f'{the_id},不用管!', icon='❌')
        time.sleep(1)  # 延迟1秒后继续运行代码
        return None, None



# 网页前端显示
st.set_page_config(page_title="EthPen - 批量 Mint Polygon inscription", page_icon="🪙", layout='centered', initial_sidebar_state='auto')

# 网页标题
st.subheader(r'🪙 :rainbow[EthPen - 批量 Mint Polygon inscription]', anchor=False, divider='rainbow')


st.markdown('## 批量题写 Polygon inscription 代币')

# 这里配置 Ethereum PRC URL,如果你没有,请到 infura.io 或者 alchemy.com 申请一个免费的 API
token_eth_prc_url = st.text_input(
    f'**Polygon PRC 链接**:选填,你可以去 [infura.io](https://app.infura.io/) 或者 [alchemy.com](https://alchemy.com/) 免费申请一个',
    f'https://polygon-mainnet.infura.io/v3/ae62dc706386486189a47641e73b43c0')
w3 = Web3(Web3.HTTPProvider(f'{token_eth_prc_url}'))

# 初始化当前账户索引为 0
current_account_index = 0
# 收集和显示所有交易的结果
transaction_results = []
# 创建账户列表
accounts = []
# 使用字典来跟踪每个地址的nonce
nonces = {}

account_address = st.text_input('填写你的 **ETH 地址**:')
private_key = st.text_input('填写你的 **ETH 地址对应的私钥**:', type="password")
if account_address and private_key:  # 如果地址和私钥有内容
    if is_valid_eth_address(account_address) and is_valid_eth_private_key(private_key):  # 验证地址和私钥
        current_nonce = w3.eth.get_transaction_count(account_address)  # 获取地址的 nonce
        nonces[account_address] = current_nonce  # 记录地址的 nonce
        accounts.append((account_address.strip(), private_key.strip()))  # 保存地址和私钥还有 nonce
    else:
        st.error("地址或私钥无效,请检查!")
        st.stop()

# 配置铭文文本
input_data = st.text_input('填写需要题写代币铭文文本', '')
token_amount = st.number_input('填写需要题写代币铭文数量(张)', min_value=1, value=100, step=1)
# 判断铭文文本里是否包含空格、换行符,而且所有的字母都必须为小写。
if not validate_input(f'{input_data}'):
    st.warning("**请注意**:通常代币铭文文本里不能包含空格、换行符,而且所有的字母都必须为小写。")

sleep_05s = st.toggle('每次完成交易后暂停 0.5 秒')
# 每次交易成功后暂停 3 秒
if sleep_05s:
    sleep_05s = True
else:
    sleep_05s = False

# 点击发送交易开始
if st.button(f'开始**发送交易**'):
    st.toast(f'开始任务,需要题写的铭文总量为:{token_amount}', icon='😎')
    # 对代币铭文 id 进行循环
    for the_id in range(token_amount):
        # 使用当前账户发送交易,获取当前账户的 nonce
        address, key = accounts[current_account_index]
        # 使用 current_nonce 发送交易
        data, tx_hash = send_transaction(w3, address, key, 137, input_data, the_id)
        # 记录最后输出的结果
        transaction_results.append(f"Transaction Hash: https://polygonscan.com/tx/{tx_hash}")
        # 交易成功后,手动增加 nonce 值
        # 更新当前账户索引,确保索引始终在账户列表的范围内
        current_account_index = (current_account_index + 1) % len(accounts)
        # 暂停 3 秒
        if sleep_05s:
            time.sleep(0.5)  # 暂停三秒
    st.toast(f'所有任务已经完成。', icon='🎉')
    # 庆祝动画
    st.balloons()
    # 显示所有交易的结果
    st.code('\n'.join(transaction_results))