天空 Blond - 加密货币
type: channel
link: https://www.skyblond.info/tag/%E5%8A%A0%E5%AF%86%E8%B4%A7%E5%B8%81/
items: 【歪门邪道】使用AWS记录加密货币的价格
items: 【网站札记】使用CoinHive为你的网站带来一些收入

【歪门邪道】使用AWS记录加密货币的价格
type: item
date: 2021-12-08T10:25:20+08:00
description: 本文将记述如何使用AWS的相关服务完成定时抓取各种加密货币的实时价格，并将它们存入数据库中供以后查询。最近很关注NEO这个区块链，一方面因为他是起源于国内，另一方面则是因为它比比特币环保，比以太坊便于开发，整个社区环境还算不错。前几天尝试了一下他们新主网上的DEX，叫Flamingo，感觉还不错。虽然我不是资深炒币人士，但是偶尔还是有使用加密货币的需求（主要是作为汽油费使用），所以对于历史价格有一个相对直观的把握，有助于我判断到底什么时候买币会更划算一些。而目前现有的各大交易所，大多数都将于2021年12月31日清退中国大陆用户，即便是不清退的，对于历史数据也比较有限，不能提供很好的查询服务。因此我决定自己写一个。实现这个需求的大体思路就是利用Java请求一些公开的API来获取各种加密货币的价格，然后整理出我想要的数据之后存到AWS上，同时尽可能降低成本。所以写一个服务长期运行是不现实了，AWS的EC2贵的要死，为这个专门买一个Lightsail也不划算，所以我决定使用Fargate来达到容器化部署，通过EventBridge实现定时调用，然后将数据存储到DynamoDB中。这样一来整个过程只有Fargate那块是按实际占用时间收费，其他的都是按量付费，例如DynamoDB只是按请求数和存储量收费，具体的每月成本可以看文末的分析。下面先说说程序怎么写。程序程序是比较核心的组件，当Fargate容器拉起来之后，AWS的任务就完成了。我们需要在程序中计算关注的币种的价格。比较无聊的部分就不说了，无非就是调API拿数据，这里我用的是实时价格，因为它可以一次性返回某一时刻，币安上所有交易对的价格数据，这样的话一次HTTP调用，剩下的就用程序找就完了。为了实现最大的灵活性，我并没有采取直接查交易对的方法，因为有些币种，例如GAS，就只有和BTC的交易对，如果要查询GAS的USDT或BUSD价格，那就废了。所以得想办法搜索出一种可能的路径，于是就有了如下的算法： private List<String> resolvePath(LinkedList<String> path, String toSymbol, Map<String, String> priceMap) { String currentSymbol = path.getLast(); if (priceMap.containsKey(currentSymbol + toSymbol)) { path.add(toSymbol); return path; } int currentPathLength = path.size(); var option = priceMap.keySet().stream() // related pair .filter(it -> it.startsWith(currentSymbol)) // get the symbol .map(it -> it.substring(currentSymbol.length())) // not a loop .filter(it -> !path.contains(it)) .map(it -> { var tempPath = new LinkedList<>(path.subList(0, currentPathLength)); tempPath.add(it); return resolvePath(tempPath, toSymbol, priceMap); }) .filter(Objects::nonNull) .min(Comparator.comparingInt(List::size)); if (option.isEmpty()) { // not found return null; } return option.get(); }这个是一个简单的深度优先搜索，具有三个入参：path：当前搜索出的路径toSymbol：目标币种的符号priceMap：全部交易对的价格数据初始时path就是源币种的符号，我们以A币为例（虚拟的，万一以后真有这个币了，跟它没关系，下面的END也一样），初始就是一个[A]。首先我们过一遍所有交易对，如果有A/END，那万事大吉，搜索结束。如果没有，那就找出有哪些相关的交易对，例如A/BTC，A/ETH之类的，然后提取出他们的名字，然后要检查这个币种是否已经搜索过了。搜索过就不要在尝试了，不然就成环了。对于剩下的不会成环的，挨个加到路径里看看行不行就是了。例如选定BTC进行尝试，那么递归调用的入参就变成了[A, BTC]，那么把A换成BTC，再重复这个过程就可以了，最终的结果是：要么找到了交易对；要么搜索遍了所有币种，都没找到一个路径。前者直接返回…

【网站札记】使用CoinHive为你的网站带来一些收入
type: item
date: 2017-11-20T18:54:00+08:00
description: CoinHive是个好东西啊。也请大家能够通过点击网站上方的Start Mining来通过占用您一些CPU资源（只有10%，很少）来自助网站的运行。接下来我想详细的介绍一下这个CoinHive。[...]