eths / 🖊️EthPen-以太之笔.py
Ethscriptions's picture
Add application file
c18992d
raw
history blame
23.7 kB
import streamlit as st
import requests
import re
import json
import hashlib
import pandas as pd
import base64
import sqlite3
import os
infura_api_key_eths = os.environ.get('infura_api_key_eths', '')
# Ethscriptions Mainnet API 的基础 URL
BASE_URL = "https://mainnet-api.ethscriptions.com/api"
# 获取当前文件目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构造数据库文件路径
eths_db_file = os.path.join(current_dir, 'data', 'eths_data.db')
# Initialize connection to SQLite database
conn = sqlite3.connect(eths_db_file)
c = conn.cursor()
# Create table to store ETHS data
c.execute('''
CREATE TABLE IF NOT EXISTS eths_data
(date text,
eth_price real,
eths_price real,
eths_market_cap integer,
eths_owners integer,
eths_volume24h real,
eths_totalLocked integer,
eths_stakers integer,
eths_tvl real)
''')
# 查询地址所属代币铭文的 token 列表
token_list = [{'p': 'erc-20', 'tick': 'eths', 'id': 21000, 'amt': '1000'},
{'p': 'erc-20', 'tick': 'gwei', 'id': 21000, 'amt': '1000'},
{'p': 'erc-20', 'tick': 'ercs', 'id': 21000, 'amt': '1000'},
{'p': 'erc-20', 'tick': 'etch', 'id': 21000, 'amt': '1000'},
{'p': 'erc-20', 'tick': 'dumb', 'id': 21000, 'amt': '1000'}]
my_style = '''
<style>
.tag {
display: inline-block;
padding: 2px 6px;
background-color: #f2f2f2; /* 默认的背景颜色 */
border-radius: 5px; /* 圆角效果 */
margin: 0 2px;
transition: background-color 0.3s; /* 平滑的颜色过渡效果 */
}
.tag:hover {
background-color: #cffd51; /* 鼠标经过时的背景颜色 */
}
.tag:active {
background-color: #cffd51; /* 鼠标按下时的背景颜色 */
}
</style>
'''
# 图片Base64
def image_to_base64(img_path):
with open(img_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode()
# 验证代币铭文函数
def is_valid_eths(data, p, tick, id, amt):
# 构建匹配1到id-1的正则表达式
pattern_range = "|".join([str(i) for i in range(1, id)])
# 使用 f-string 插入参数到正则表达式
pattern = rf'^data:,{{"p":"{p}","op":"mint","tick":"{tick}","id":"({pattern_range}|{id})","amt":"{amt}"}}$'
return bool(re.match(pattern, data))
# 文本转换到十六进制
def text_to_hex(text):
return '0x' + ''.join(format(byte, '02x') for byte in text.encode('utf-8'))
# str SHA256
def sha256(input_string):
sha256 = hashlib.sha256()
sha256.update(input_string.encode('utf-8'))
return sha256.hexdigest()
# 根据 TX 获取 input data
def get_input_data(tx_hash):
endpoint = infura_api_key_eths
headers = {
"Content-Type": "application/json",
}
data = {
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getTransactionByHash",
"params": [tx_hash]
}
eth_transaction = requests.post(endpoint, headers=headers, data=json.dumps(data))
transaction_data = eth_transaction.json()
return transaction_data['result']['input']
# 获取所有的 ethscriptions
def get_all_ethscriptions(page=None, per_page=None, sort_order=None):
endpoint = "/ethscriptions"
params = {
"page": page, # 页码
"per_page": per_page, # 每页的数量
"sort_order": sort_order # 排序顺序
}
response = requests.get(BASE_URL + endpoint, params=params)
return response.json()
# 根据地址获取 ethscriptions
def get_ethscriptions_by_address(address):
all_ethscriptions = []
page = 1
per_page = 100
while True:
endpoint = f"/ethscriptions/owned_by/{address}"
params = {
"page": page,
"per_page": per_page,
"sort_order": 'asc'
}
response = requests.get(BASE_URL + endpoint, params=params)
if response.status_code != 200:
print(f"Error fetching data: {response.text}")
break
ethscriptions = response.json()
all_ethscriptions.extend(ethscriptions)
if len(ethscriptions) < per_page:
break
page += 1
return all_ethscriptions
# 使用ID或数字获取特定的 ethscription
def get_specific_ethscription(ethscription_identifier):
endpoint = f"/ethscriptions/{ethscription_identifier}"
response = requests.get(BASE_URL + endpoint)
return response.json()
# 获取特定 ethscription 的数据
def get_ethscription_data(ethscription_identifier):
endpoint = f"/ethscriptions/{ethscription_identifier}/data"
response = requests.get(BASE_URL + endpoint)
return response.json()
# 使用 SHA256 值检查内容是否已被 ethscribed
def check_content_exists(sha):
endpoint = f"/ethscriptions/exists/{sha}"
response = requests.get(BASE_URL + endpoint)
if response.status_code == 200:
return response.json()
# 确定索引器是否落后
def get_block_status():
endpoint = "/block_status"
response = requests.get(BASE_URL + endpoint)
return response.json()
# 获取 $eths 价格
def get_eths_price():
params = {
'category': 'token',
'collectionName': 'erc-20 eths',
}
response = requests.get(
'https://www.etch.market/api/markets/collections/details',
params=params
)
if response.status_code == 200:
response = response.json()
if response['message'] == 'success':
return response['data']
return {} # 返回一个空字典作为默认值
# 从 etch.market 那里获取用户地址代币余额
def get_etch_token_amt():
params = {
'category': 'token',
'tokenQuery': '',
}
response = requests.get(
'https://www.etch.market/api/markets/ethscriptions/collections/0x59724739940777947c56C4f2f2C9211cd5130FEf',
params=params
)
if response.status_code == 200:
response = response.json()
if response['message'] == 'success':
return response['data']
return {} # 返回一个空字典作为默认值
# 获取 $eths 质押数据
def get_eths_staking():
response = requests.get('https://www.etch.market/api/staking/statistics/erc-20%20eths')
if response.status_code == 200:
response = response.json()
if response['message'] == 'success':
return response['data']
return {} # 返回一个空字典作为默认值
st.set_page_config(page_title="EthPen - 以太之笔", page_icon="🖊", layout='centered', initial_sidebar_state='auto')
# 首页
st.markdown(
f'# <a href="https://ethpen.com" target="_self"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "ethpen_logo.svg"))}" alt="Image" width="64px" height="64px" style="border-radius: 8px; box-shadow: 3px 3px 10px rgba(0,0,0,0.1);"/></a> :rainbow[EthPen - 以太之笔]',
unsafe_allow_html=True)
st.subheader('', anchor=False, divider='rainbow')
# 最近新闻
st.markdown(f'### 最近新闻')
st.markdown(
f'<a href="https://twitter.com/dumbnamenumbers/status/1696989307871826137" target="_blank"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "news.jpeg"))}" alt="Image" style="max-width: 100%; width: 100%; height: auto; border-radius: 10px; display: block; box-shadow: 5px 5px 15px rgba(0,0,0,0.3);"/></a>',
unsafe_allow_html=True)
st.markdown(f'> 3 周前,我们提出了 Ethscriptions 虚拟机的构想——一种通过将其解释为计算机指令来显著增强 Ethscriptions 功能的方法。今天,我们宣布了该虚拟机的首个实现。已在 Goerli 网络上线,并已在 GitHub 上完全开源!👆')
# 广告位图片
st.markdown(f'### 广告位')
# st.markdown(
# f'<a href="https://twitter.com/EtchMarket/status/1694024108672245953" target="_blank"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "ad.jpg"))}" alt="Image" style="max-width: 100%; width: 100%; height: auto; border-radius: 10px; display: block; box-shadow: 5px 5px 15px rgba(0,0,0,0.3);"/></a>',
# unsafe_allow_html=True)
#
# st.markdown(f'> 拆分方案现在面向所有人推出!让我们一起加入权益挖矿的浪潮,并分享50%的月度服务费。')
st.markdown(f'😭 接不到广告,我太穷了。')
st.markdown(
f'<img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "alipay_qrcode.png"))}" alt="Image" style="max-width: 100%; width: 50%; height: auto; border-radius: 10px; display: block; box-shadow: 5px 5px 15px rgba(0,0,0,0.3);"/>',
unsafe_allow_html=True)
st.markdown('')
st.markdown(f'复制 <span class="tag">845076800</span>。 打开支付宝搜索,赏我一个猪脚饭。🥺', unsafe_allow_html=True)
st.markdown(f'### 什么是 Ethscriptions?', unsafe_allow_html=True)
st.markdown(f'{my_style}<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> 是一种新的在以太坊上创建和分享数字资产的方法,它通过使用交易 calldata 存储数据而不是智能合约来实现,这使其比 NFT 更为经济。它们是完全在链上、无需许可、抗审查的,并且其成本只是 NFT 的一小部分。', unsafe_allow_html=True)
st.markdown(f'<img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "input_data.png"))}" alt="Image" style="max-width: 100%; width: 100%; height: auto; border-radius: 10px; display: block; box-shadow: 3px 3px 10px rgba(0,0,0,0.1);"/>', unsafe_allow_html=True)
st.markdown('')
st.markdown('### 谁创造了 Ethscriptions?')
st.markdown(f'首个 [Ethscription](https://ethscriptions.com/ethscriptions/0) 是在 2016 年创建的,但正式的协议是由 Tom Lehman,又名 <span class="tag"><a href="https://twitter.com/dumbnamenumbers" target="_blank" style="text-decoration: none;"><img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "Middlemarch.jpg"))}" alt="Image" width="20px" height="20px" style="border-radius: 10px;"/> @Middlemarch</span></a> 开发的。除了比特币的铭文,他还受到了来自 Poly Network 黑客的著名的 “原型 - Ethscription” 的启发,你可以在[这笔交易](https://etherscan.io/tx/0x0ae3d3ce3630b5162484db5f3bdfacdfba33724ffb195ea92a6056beaa169490)中看到它。', unsafe_allow_html=True)
st.markdown(f'- 快来加入 <span class="tag"><a href="https://discord.gg/ethscriptions" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "discord.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @ethscriptions</span></a>,一起讨论 Ethscriptions 的未来!', unsafe_allow_html=True)
st.markdown(f'- 快来关注 <span class="tag"><a href="https://twitter.com/ethscriptions" 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;" /> @ethscriptions</span></a>,掌握 Ethscriptions 的最新动态!', unsafe_allow_html=True)
st.markdown('### 如何题写 Ethscriptions?')
st.markdown(f'题写 Ethscriptions 是十分简单的,相当于在发送 ETH 交易时附带一些转账备注,我们就以使用人数最多的 MetaMask 钱包来举例,我们首先打开<span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "0x.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 显示十六进制数据</span>。', unsafe_allow_html=True)
st.markdown(f'1. 打开 <span class="tag"><a href="https://matamask.io" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "metamask.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> Metamask</span></a> 钱包(如果已安装);', unsafe_allow_html=True)
st.markdown(f'2. 在右上角点击打开 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "matamask-more.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 菜单栏</span>;', unsafe_allow_html=True)
st.markdown(f'3. 点击打开 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "metamask-gear.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 设置项</span>;', unsafe_allow_html=True)
st.markdown(f'4. 点击打开 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "metamask-line.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 高级设置</span>;', unsafe_allow_html=True)
st.markdown(f'5. 点击打开 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "0x.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 显示十六进制数据</span>。', unsafe_allow_html=True)
st.markdown(f'然后让我们构思一下我们心仪的铭文,我们需要把铭文的文本转换成十六进制形式的数据,在下方文本框输入。', unsafe_allow_html=True)
input_ethscriptions_str = st.text_input('默认以 `data:,` 开头,输入需要转换的文本:', key='输入需要转换的文本')
if st.button('转换', key='文本转换到十六进制形式'):
if not input_ethscriptions_str.startswith('data:,'):
input_ethscriptions_str = f'data:,{input_ethscriptions_str}'
input_ethscriptions_hex = text_to_hex(input_ethscriptions_str)
input_ethscriptions_sha = sha256(input_ethscriptions_str)
ethscriptions_data = check_content_exists(input_ethscriptions_sha)
if ethscriptions_data['result']:
st.markdown(f'☹️ :green[{input_ethscriptions_str}] 已经被题写!相关信息如下:')
selected_data = {
'当前拥有者': ethscriptions_data["ethscription"]["current_owner"],
'题写时间': ethscriptions_data["ethscription"]["creation_timestamp"],
'铭文编号': f'#{ethscriptions_data["ethscription"]["ethscription_number"]}',
'铭文完整内容': ethscriptions_data["ethscription"]["content_uri"],
}
st.json(selected_data)
else:
st.markdown(f'😄 :green[{input_ethscriptions_str}] 还没被题写!快复制下方文本前去题写吧。')
st.code(input_ethscriptions_hex[2:], line_numbers=False)
st.markdown(f'好,让我们发送一笔交易吧,这笔交易是自己给自己发送 0ETH 的交易。', unsafe_allow_html=True)
st.markdown(f'1. 点击发送 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "send.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 发送交易</span>;', unsafe_allow_html=True)
st.markdown(f'2. 接收地址填写 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "address.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 自己的地址</span>,这是铭文接收的地址,然后金额填写为 0ETH;', unsafe_allow_html=True)
st.markdown(f'3. 填写 <span class="tag"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "0x.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> 十六进制数据</span>,也就是我们刚才复制的文本;', unsafe_allow_html=True)
st.markdown(f'4. 检查确认无误后发送交易。', unsafe_allow_html=True)
st.markdown(f'稍等片刻,我们就可以在 <span class="tag"><a href="https://etherscan.io" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "etherscan-logo.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> Etherscan</span></a> 区块浏览器看到成功的交易。', unsafe_allow_html=True)
st.markdown(f'<img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "etherscan_input_data.png"))}" alt="Image" style="max-width: 100%; width: 100%; height: auto; border-radius: 10px; display: block; box-shadow: 3px 3px 10px rgba(0,0,0,0.1);"/>', unsafe_allow_html=True)
st.markdown('')
st.markdown('我们可以输入铭文文本查询详细的信息,')
col1, col2 = st.columns(2)
ethscriptions_str = col1.text_input('输入完整的铭文文本:', '', label_visibility='collapsed')
search_information = col2.button('🔍 查询', key='查询信息')
if search_information:
if not ethscriptions_str.startswith('data:,'):
ethscriptions_str = f'data:,{ethscriptions_str}'
ethscriptions_all_str = sha256(ethscriptions_str)
ethscriptions_data = check_content_exists(ethscriptions_all_str)
if ethscriptions_data['result']:
st.markdown(f'###### :green[{ethscriptions_str}] 相关信息如下:')
selected_data = {
'当前拥有者': ethscriptions_data["ethscription"]["current_owner"],
'题写时间': ethscriptions_data["ethscription"]["creation_timestamp"],
'铭文编号': f'#{ethscriptions_data["ethscription"]["ethscription_number"]}',
'铭文完整内容': ethscriptions_data["ethscription"]["content_uri"],
}
st.json(selected_data)
else:
st.markdown(f'###### :green[{ethscriptions_str}] 铭文还没被题写!复制下方文本前去题写。')
st.code(f'{text_to_hex(ethscriptions_str)}', line_numbers=False)
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)
st.markdown(f'如果你觉得上述的方法步骤繁琐,我们建议你使用 Ethscriptions 官方推荐的 [EthScriber](https://ethscriber.xyz/) 还有 [Etherscan IDM](https://etherscan.io/idm),其他题写工具须在你确保安全的情况下使用,因为你不能确定它要发送什么铭文的交易。', unsafe_allow_html=True)
st.markdown(f'EthPen.com 不仅为你提供优质的工具,还有详尽的教程供你参考。欢迎你前来探索!', unsafe_allow_html=True)
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)
st.markdown('### Ethscriptions 上的龙头代币是?')
st.markdown(
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>',
unsafe_allow_html=True)
# 查询eths_data表中所有数据
c.execute('SELECT * FROM eths_data')
# 获取所有结果
eths_data = c.fetchall()
# 定义卡片样式
eths_card_style = """
<style>
.card {
border: 1px solid #e1e4e8;
padding: 20px;
border-radius: 15px;
margin: -20px 0;
}
.card p {
margin-top: 7px;
margin-bottom: 7px;
}
.card h5 {
margin-top: 10px;
margin-bottom: -10px;
}
.card a.button {
display: inline-block;
padding: 10px 15px;
border: none;
border-radius: 5px;
background-color: #5bc43b;
color: #fff;
text-align: center;
text-decoration: none;
transition: background-color 0.3s;
}
.card a.button:hover {
background-color: #ccfd51;
}
</style>
"""
st.markdown(eths_card_style, unsafe_allow_html=True)
# 创建卡片的HTML内容
eths_card_content = f"""
<div class="card">
<img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "eths_logo.jpeg"))}" alt="Image" style="max-width: 100%; width: 100%; height: auto; border-radius: 10px; display: block;"/></a>
<p></p>
<div style="display: flex; align-items: center; gap: 10px;">
<img src="data:image/jpeg;base64,{image_to_base64(os.path.join("img", "eths_logo.png"))}" alt="Image" width="40px" height="40px" />
<div>
<h3 style="margin: 0; margin-bottom: -35px; font-size: 30px;">Ethscriptions eths</h3>
<p style="margin: 0; font-size: 40px;"><strong>${eths_data[0][2]:.2f}</strong></p>
</div>
</div>
<p>市值:<span class="tag">${eths_data[0][3]:,.0f}</span></p>
<p>总量:<span class="tag">21,000,000</span></p>
<p>24h 交易量:<span class="tag">${eths_data[0][5]:,.0f}</span></p>
<p>24h 交易所:<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", "etch-market.png"))}" alt="Image" width="20px" height="20px"/> Etch Market</span></a></p>
<h5>INFO</h5>
<p>官网:None</p>
<p>浏览器:<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</a></span></p>
<p>Ethscription ID:<span class="tag"><a href="https://ethscriptions.com/ethscriptions/0x4636542d00d8075360d0303eb224c4ffb638169c23d6308aace55249b0bed2e4" 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;"/> 0x463654......bed2e4</a></span></p>
<p>部署时间:<span class="tag">2023/06/18 05:46:11</span></p>
<p>公链:<span class="tag">Ethereum Ethscriptions</span></p>
<p>持有人数:<span class="tag">{eths_data[0][4]:,.0f}</span></p>
<p>社交:<span class="tag"><a href="https://twitter.com/ethscriptions" 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;" /> @ethscriptions</span></a> <span class="tag"><a href="https://discord.gg/ethscriptions" target="_blank" style="text-decoration: none;"><img src="data:image/svg+xml;base64,{image_to_base64(os.path.join("img", "discord.svg"))}" alt="Image" width="20px" height="20px" style="border-radius: 3px;" /> @ethscriptions</span></a></p>
<h5>Staking</h5>
<p>质押总量:<span class="tag">{eths_data[0][6]:,.0f} $eths</span></p>
<p>质押人数:<span class="tag">{eths_data[0][7]:,.0f}</span></p>
<p>TVL:<span class="tag">${eths_data[0][8]:,.0f}</span></p>
<p><a href="https://www.etch.market/market/token?category=token&collectionName=erc-20%20eths" target="_blank" class="button">立即买入 $eths</a></p>
</div>
"""
st.markdown(eths_card_content, unsafe_allow_html=True)