経緯
TONコインに興味を持ち注目しています。 時価総額の上昇や関連プロジェクトの盛り上がりもあり、注目度は上がっていると感じています。 特にTelegramとの連携の影響が大きいなという印象があります。
私は主にWalletからTONの取引をしています。また、TONコインの取引履歴はExplorerから確認できるのですが、実際に取引履歴を集計したい状況になり、やり方を調べていました。
現状、Explorerではファイル保存には対応していません。しかし、調べるとTONではAPIが公開されており、取引履歴はAPI経由で取得できることが分かりました。
本記事ではTONコインに関する情報と取引履歴の取得方法(コードを含む)についてまとめた内容になります。
※注意事項は一読をお願いします。
はじめに
注意事項
- 本記事は2024/07/15時点の情報です。
- 本記事は投資を推奨する記事ではなく、内容やコードによって生じたいかなる損害についても責任を負いません。自己責任で参照してください。
- コードで使用するTONAPIの仕様や コード内で使用する暗号資産の損益計算サービスのCryptactが指定するデータ形式は変更される可能性があるため、最新の情報を確認してください。
- コードは特定のTONアドレスに関連するトランザクションデータを取得できることは確認していますが、データの正確性は保証できません。
- トランザクション履歴はトランザクションの状態に依存します。トランザクションデータを確認して、取得したデータが正確でエラーがないことを確認してください。
TONコインについて
公式ドキュメント等の情報を参照ください。
- https://docs.ton.org/develop/overview
- https://www.bitpoint.co.jp/column/tips41/
- https://coinpost.jp/?p=541399
TON仕様の確認と作成コードの前提
TONではプロトコル仕様に基づき、複数のAPIが公開されています。 また、SDKとしてプログラミング言語や用途に合わせて開発もされています。
- https://docs.ton.org/learn/networking/overview
- https://docs.ton.org/develop/dapps/apis/
- https://docs.ton.org/develop/dapps/apis/sdk
今回は取引履歴の取得するために、以下の仕様としました。
一方で、実際にSDKを確認したところ、上記仕様を満たすコードは見当たらず、サンプルなどを見落としている可能性はありますが、単純に取引履歴を件数指定で取得するようなコードは見つけられませんでした。
最終的に、コード作成では一部SDKを使用してAPI仕様に基づき取引履歴を取得するコードを作成することにしました。
API選定について
APIには公式のものと、サードパーティーによって提供されるものがあります。
Toncenter APIs(公式)
TON Index - TON Index collects data from a full node to PostgreSQL database and provides convenient API to an indexed blockchain.
- TON IndexはフルノードからPostgreSQLデータベースにデータを収集し、インデックス化されたブロックチェーンへの便利なAPIを提供する。
- APIのバージョンはV3であり、Masterchain情報を取得することが可能。
- 取引履歴は/api/v3/transactionsでタイムスタンプによる範囲指定で取得可能。
toncenter/v2 - This API enables HTTP access to TON blockchain - getting accounts and wallets information, looking up blocks and transactions, sending messages to the blockchain, calling get methods of smart contracts, and more.
Third party APIs
- tonapi.io - fast indexed API which provides basic data about accounts, transactions, blocks, application-specific data about NFT, Auctions, Jettons, TON DNS, Subscriptions. It also provides annotated data on transaction chains.
- アカウント、トランザクション、ブロックに関する基本データ、NFT, Auctions, Jettons, TON DNS, Subscriptionsに関するアプリケーション固有のデータを提供する高速インデックス付きAPI。また、トランザクションチェーンに関する注釈付きデータも提供する。
- 取引履歴は
/v2/blockchain/accounts/{account_id}/transactionsで取得可能です。仕様はシンプルでわかりやすですが、件数指定に工夫が必要です。 - 一方で、tonapiはWallet(Ton Keeper)とExplorer(Tonviewwer)で使用されており、https://tonconsole.com/というコンソールにも使用されています
- 開発方法では、Streaming API, Rest API, GraphQLが提供されています。
選定結果
上記API情報を確認する中で、最終的には、TON Index を使用して作成することにしました。 最初はtonapi.ioで作成していたのですが、件数指定の部分で変更しました。(GitHubではtonapiのコードもコミットしていますが、コメントアウトしています。)
tonapiには扱いさすやを感じています。実際にAPIも登録して、tonconsoleも使える状態のため、他の用途で使ってみたいなと思っています。
作成したコードについて
コードはGitHubにもコミットしています。(一部コード差異がありますのでご注意ください。)
import json import os import time from datetime import date, datetime, timedelta from pathlib import Path from typing import Any, Dict, List, Optional, TypedDict, Union, cast import requests from tomlkit.toml_file import TOMLFile def save_json_file(data: List[Dict[str, Any]], filename: str) -> None: output_dir = Path(__file__).parent / "output" output_dir.mkdir(exist_ok=True) json_file_path = output_dir / filename if json_file_path.exists(): overwrite = input(f"{json_file_path} already exists. Overwrite? (y/N) ") if overwrite.lower() != "y": print("File not saved.") return with open(json_file_path, "w") as f: json.dump(data, f, indent=2) print(f"JSON file saved: {json_file_path}") def get_transactions_tonindex_api_v3( account: str, start_time: Optional[datetime] = None, end_time: Optional[datetime] = None, limit: int = 100, offset: int = 0, save_json: bool = False, ) -> List[Dict[str, Any]]: base_url = "https://toncenter.com/api/v3/transactions" all_transactions = [] while True: params: Dict[str, Union[str, int]] = { "account": account, "limit": limit, "offset": offset, "sort": "desc", } if start_time: params["start_utime"] = int(start_time.timestamp()) if end_time: params["end_utime"] = int(end_time.timestamp()) try: response = requests.get(base_url, params=params) response.raise_for_status() data = response.json() transactions = data.get("transactions", []) if not transactions: break all_transactions.extend(transactions) offset += len(transactions) if len(transactions) < limit: break time.sleep(1) except requests.exceptions.RequestException as e: print(f"Request error: {e}") break except json.JSONDecodeError: print("JSON decode error. The response is not valid JSON.") break if save_json and all_transactions: filename = f"all_txns_tonindex_v3_N={len(all_transactions)}_{date.today()}.json" save_json_file(all_transactions, filename) return all_transactions class TonInfo(TypedDict): user_friendly_address: str transaction_history_period: float class FileSaveOption(TypedDict): save_allow_json: bool save_allow_csv: bool class Config(TypedDict): ton_info: TonInfo file_save_option: FileSaveOption def load_config() -> Config: script_dir = os.path.dirname(os.path.abspath(__file__)) config_file_path = os.path.join(script_dir, "config.toml") toml_config = TOMLFile(config_file_path) config_data = toml_config.read() if config_data is None: raise ValueError("Failed to read config file") return cast(Config, config_data) if __name__ == "__main__": config = load_config() ACCOUNT_ID = config["ton_info"]["user_friendly_address"] SAVE_JSON = config["file_save_option"]["save_allow_json"] TXNS_HISTORY_PERIOD = config["ton_info"]["transaction_history_period"] end_time = datetime.now() start_time = end_time - timedelta(days=TXNS_HISTORY_PERIOD) response_tonindex = get_transactions_tonindex_api_v3( account=ACCOUNT_ID, start_time=start_time, end_time=end_time, save_json=SAVE_JSON, ) print(f"TON Index API v3: Retrieved {len(response_tonindex)} transactions")
上記はconfig.tomlにユーザー情報を設定して使用するコードですが、以下のように値を指定することで使用することができます。
アドレス仕様については下記を参照してください。 https://docs.ton.org/learn/overviews/addresses#raw-and-user-friendly-addresses
使用例1:スクリプト実行時点(Day)から10日間に存在する取引履歴を取得する例
ACCOUNT_ID = "user_friendly_address" SAVE_JSON = True TXNS_HISTORY_PERIOD = 10 end_time = datetime.now() start_time = end_time - timedelta(days=TXNS_HISTORY_PERIOD) transactions = get_transactions_v3(account=ACCOUNT_ID, start_time=start, end_time=end, save_json=True)
使用例2:日付範囲指定で取得する例
ACCOUNT_ID = "user_friendly_address" start_time = datetime(2024, 1, 1) end_time = datetime(2024, 7, 1) transactions = get_transactions_v3(account=ACCOUNT_ID, start_time=start_time, end_time=end_time, save_json=True)
以上で日付範囲指定で取引履歴をのJSONファイルに保存できます。
補足として、GitHubでは、create_ton_stkrwd_cryptact_custom.pyでWalletへの入金に対してクリプタクトのステーキング報酬履歴としてカスタムファイルを保存するコードをコミットしています。
取引の種類について複雑な部分もあるため、扱いづらさはありますが、興味があればREADME_ja.mdから詳細を確認してみてください。
まとめ
本記事ではTONコインとAPI仕様に関する一部の情報と、TONコインの取引履歴についてTON APIを使用してJSONファイルに保存するPythonコードを紹介しました。
コードはGitHubで公開しているため、使用可能ですが、使用する場合は注意事項を確認し、自己責任でお願いします。
以上です。