在 TON 的 Stonfi 上寻找 memecoin,或者 Notcoin 之外还有其他生命吗
Memcoin 和 NFT 是我最不喜欢的加密货币趋势之一,没有技术含量,只有营销手段。但 2024 年第一季度的爆炸式增长吸引了人们对 memecoin 的关注。(据 coingecko 称,这是 2024 年第一季度最赚钱的叙事,但其方法论存在一些疑问)。因此,我建议尝试在 TON 区块链上寻找 memecoin,方法是尝试搭建一个简单的 memecoin 仪表盘。
在本文中,我想弄清楚为什么 memecoin 分析平台看起来像是这些 memecoin 的实时购买信息。通过运行新的 Stonfi API,来自该 DEX 的数据现在显示在 Dexscreener 上,并且为此出现了单独的开放 API,这极大地影响了数据的可用性(这在 TON 中是一个问题)。第三,看看你关于矿池的一些统计假设。
我们要寻找什么?
如果你在谷歌上搜索 memecoin 的定义,你会发现各种定义,从我们这个时代的金字塔到社交科技领域的新词——数字 meme 货币,不一而足。因此,在本文中,我给出了我的定义:Memcoin 是一种动态增长的代币,没有初始效用,使用 Fomo 机制来确保增长。这个定义让我可以提出一个假设:Memcoin 是快速增长的小型项目,这意味着你可以先根据池子容量(总锁定价值)筛选大型项目,然后再根据例如最近一天的交换次数来筛选小型项目。
为 Stonfi 矿池构建 TVL 图表 - 寻找 memecoin 的阈值
让我们从 TVL 开始。Stonfi 有两个 API:v1/pools(返回池的当前状态)和 v1/stats/pools(获取一段时间内池的统计数据)。我们使用 v1/pools,需要池地址、组成池的代币地址以及 lp_total_supply_usd(池中 LP 代币的总供应量)。LP 代币由 DEX 自动生成,并记入流动性提供者账户,用于向流动性池贡献资产。这些代币代表了流动性池赚取的佣金的一部分。因此,它们的美元供应量将反映 TVL。
import requests
r = requests.get('https://api.ston.fi/v1/pools')
result = r.json()['pool_list']
temp_pool_list = [{'pool_address': pool['address'], 'token0_address': pool['token0_address'], 'token1_address': pool['token1_address'], 'tvl': round(float(pool['lp_total_supply_usd']),2)} for pool in result]
# Let's sort
sorted_pool_list = sorted(temp_pool_list, key=lambda d: d['tvl'],reverse=True)
sorted_pool_list[0:5]
排序后我们得到:
视觉上更容易感知信息,所以让我们绘制一个图表:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
pool_addresses = [d['pool_address'][-4:] for d in sorted_pool_list]
tvl_values = [d['tvl'] for d in sorted_pool_list]
plt.bar(pool_addresses, tvl_values, color='skyblue',log=True)
plt.xlabel('Pool Address')
plt.ylabel('TVL')
plt.title('TVL for Pools')
plt.xticks(color='w')
plt.tight_layout()
结果:
该图清楚地表明,前几个池子在交易量上覆盖了所有其他池子,同时也清楚地表明存在着平台期,并且锁定资金的数量可以将代币分为几个等级,从小额资金池到简单的大型资金池。
为了进行假设,让我们制作一个饼图,将所有池除以某个阈值,并在名称中输入池的数量,这样就会非常清楚,例如,按数量计算的前三个池包含超过一半的锁定流动性。
threshold = 10000000
big_pools = sum(item['tvl'] for item in sorted_pool_list if item['tvl']>=threshold)
small_pools = sum(item['tvl'] for item in sorted_pool_list if item['tvl']<threshold)
big_pools_count = len([item['tvl'] for item in sorted_pool_list if item['tvl']>=threshold])
small_pools_count = len([item['tvl'] for item in sorted_pool_list if item['tvl']<threshold])
labels = 'Big pools', 'Small pools'
sizes = [big_pools, small_pools]
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels)
ax.set_title("Big pools count:{}, Small pools count {} ".format(big_pools_count,small_pools_count))
结果:
Solana 区块链上有一个 pump fun 启动板,它的限额为 69,000 美元,即您可以启动您的代币,但一旦它增长到 69,000 美元以上,它就会“进入”大型交易所,让我们试试这个阈值:
但这里有一些细微差别,池子可以包含任意数量的 Jetton(TON 上的代币标准)或 TON。但在大多数情况下,这些池子是:
- jetton - TON
- jetton - 稳定币
- jetton - Notcoin
Notcoin 可以说是 TON 中最大的 memecoin,所以我们简单的仪表盘应该从 Notcoin 的主导地位开始。我们来看一下图表:
Notcoin = 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT'
not_pools = sum(item['tvl'] for item in sorted_pool_list if item['token0_address']==Notcoin or item['token1_address']==Notcoin )
notnot_pools = sum(item['tvl'] for item in sorted_pool_list if item['token0_address']!=Notcoin or item['token1_address']!=Notcoin )
not_count = len([item['tvl'] for item in sorted_pool_list if item['token0_address']==Notcoin or item['token1_address']==Notcoin])
notnot_count = len([item['tvl'] for item in sorted_pool_list if item['token0_address']!=Notcoin or item['token1_address']!=Notcoin])
labels = 'Notcoin pools', 'Other pools count'
sizes = [not_pools, notnot_pools]
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels)
ax.set_title("Notcoin pools count:{}, Other pools count {} ".format(not_count,notnot_count))
结果:
如您所见,与其他代币相比,Notcoin 规模巨大,在审查 TON memecoin 市场时,其主导地位值得考虑。
流动性问题
好吧,假设你已经设定了某个 TVL 阈值,并考察了 Notcoin 的主导地位,但进一步考察 TVL 就毫无意义了。小型矿池存在流动性问题——它们根本没有足够的交换量。而且它们锁定的流动性也不允许你比较它们。
这就是为什么 memecoin 分析平台通常看起来像实时数据流。应用程序会扫描区块,查找小型矿池中的交换情况。这样,你大约一分钟就能看到哪些 memecoin 正在增长。为了更清楚地展示它的样子,我为 Stonfi 矿池整理了一个类似的网站:
tonhotshot.fun
首先,扫描池并找到最大的池,高达 69k TVL - 山丘之王
,然后扫描每个块以查找高达 69k 的池中的 Stonfi 交易。
这些数据取自我之前提到的公开的 Stonfi API。让我们尝试基于这些数据构建我们自己的仪表板。
Stonfi 上的 Memcoins 排名
我们将从为 Dexscreener 创建的新 API(即事件 API (export/dexscreener/v1/events))中获取交换数据。此 API 返回两个区块之间的所有 DEX Stonfi 事件。假设我们为仪表板选择了一天中的某个时间段,那么我们可以从哪里获取当前区块的起始时间呢?有两个选项:
第一个选项是使用邻近的句柄 export/dexscreener/v1/latest-block,它将返回交易所后端处理的最后一个区块,该后端索引区块链并允许我们以聚合形式获取数据。这种方法的优点是我们可以获得索引器处理的最后一个区块,缺点是该句柄平均需要 10 秒才能完成,这并不总是很方便。
ltb = requests.get('https://api.ston.fi/v1/screener/latest-block')
lastest_block = ltb.json()['block']['blockNumber']
第二种选择是简单地从区块链中取出最后一个区块,是的,区块链中的最后一个区块不等于交换索引器处理的最后一个区块,但它很快,这是如何做到这一点的选项之一:
# RPS 1 sec
ltb = requests.get('https://toncenter.com/api/v3/masterchainInfo')
return ltb.json()['last']['seqno']
假设我们获取了所有事件,那么如何移除大块数据呢?就像我们一开始做的那样——获取所有池子,然后移除那些不需要的:
def get_block_list(sorted_pool_list,threshold):
Notcoin = 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT'
return [item['pool_address'] for item in sorted_pool_list if item['tvl']>=threshold or item['token0_address'] == Notcoin or item['token1_address'] == Notcoin]
我们还将立即删除带有 notcoin 的池,因为我们正在寻找新的 memecoin。
收集事件后,我们将立即使用 Counter 进行计数:
def count_swap_events(sorted_pool_list,threshold):
blocker = get_block_list(sorted_pool_list,threshold)
ltb = requests.get('https://api.ston.fi/v1/screener/latest-block')
lastest_block = ltb.json()['block']['blockNumber']
start_block=lastest_block - int(86400/5) # TON "sync" block every 5 second, in a day 86400 second
payload = {'fromBlock': start_block, 'toBlock': lastest_block}
r = requests.get('https://api.ston.fi/export/dexscreener/v1/events', params=payload)
count_arr=[]
for item in r.json()['events']:
if(item['eventType']=='swap'):
if(item["pairId"] not in blocker):
count_arr.append(item)
c = Counter()
for event in count_arr:
c[event["pairId"]] += 1
为了获取更多句柄,我们将仅使用池地址来丰富我们的数据,为此我们将使用 /export/dexscreener/v1/pair/ 来获取令牌地址并使用 /v1/assets/ 来获取令牌名称或 TON。
def pool_pair(pool_addr):
p = requests.get('https://api.ston.fi/export/dexscreener/v1/pair/{}'.format(pool_addr))
try:
pair=p.json()['pool']
return jetton_name(pair['asset0Id']) +"-"+ jetton_name(pair['asset1Id'])
except:
return pool_addr
这里需要说明的是,这只是一个教程,所有代码都尽可能简洁,方便读者理解。接下来我们来丰富一下计数器,并进行排序:
def count_swap_events(sorted_pool_list,threshold):
blocker = get_block_list(sorted_pool_list,threshold)
ltb = requests.get('https://api.ston.fi/v1/screener/latest-block')
lastest_block = ltb.json()['block']['blockNumber']
start_block=lastest_block - int(86400/5) # TON "обновляет" блоки каждые 5 секунд в дне 86400 секунд
payload = {'fromBlock': start_block, 'toBlock': lastest_block}
r = requests.get('https://api.ston.fi/export/dexscreener/v1/events', params=payload)
count_arr=[]
for item in r.json()['events']:
if(item['eventType']=='swap'):
if(item["pairId"] not in blocker):
count_arr.append(item)
c = Counter()
for event in count_arr:
c[event["pairId"]] += 1
enriched_arr=[]
for pool in sorted(list(c.items()), key=lambda d: d[1],reverse=True)[0:30]:
enriched_arr.append({"pool": pool_pair(pool[0]),'24h_swaps':pool[1]})
return enriched_arr
结果是这样的:
当然,还有很多可以改进的地方,但我建议读者自己完成仪表板,所有 Stonfi API 都可以在这里查看 - https://api.ston.fi/swagger-ui/
结论
我欣赏 TON 区块链的技术优雅,至少它不是以太坊的翻版,以太坊依靠大量资本加速发展,而且用户通常需要它。如果您想了解更多关于 TON 区块链的信息,我有一些开源课程,您可以通过这些课程学习如何在 TON 上创建功能齐全的应用程序。
https://github.com/romanovichim/TonFunClessons_ENG
文章来源:https://dev.to/roma_i_m/looking-for-memecoins-on-stonfi-in-ton-or-is-there-life-beyond-notcoin-29b8