当前位置: 首页 > news >正文

20260531 区块链与数字货币 实验二:图算法与社交网络分析

摘要

本实验围绕 TuGraph 图数据库的存储过程机制,针对 Elliptic 比特币交易数据集开展图算法分析。以高入度的非法交易节点作为起点,编写并上传双向广度优先遍历(BFS)的 Python 存储过程,在三层邻域内提取 905 个相关交易节点,结合 Cypher 复杂查询统计这些节点的类别构成,并与全图基线占比进行对照分析。实验结果显示,BFS 邻域内的非法节点绝对数量较少,但相邻已标注节点中的非法交易占比与全图持平,反映出非法资金在比特币交易图中存在沿多跳路径扩散的迹象,也暴露出公开标签覆盖率偏低对图分析结论稳定性的影响。

一、实验目的

熟悉 TuGraph 图数据库的存储过程开发、上传与调用流程;掌握 Cypher 语言中聚合统计、过滤、参数化查询等复杂语法;结合 Elliptic 比特币交易数据集,体会图算法在反洗钱、可疑交易追踪等金融场景中的应用价值。

二、实验环境

操作系统为 Windows 10;图数据库为 TuGraph 4.3.1,通过 Docker 容器部署,镜像名为 tugraph/tugraph-runtime-ubuntu18.04:4.3.1;宿主机端口 7070 映射容器内 Web 管理端口,端口 7687 映射 Bolt 协议端口,端口9090 映射 RPC 端口;客户端使用 Chrome 浏览器访问 http://localhost:7070,并辅以 Python 3.11 通过 RESTful 接口完成自动化任务。

TuGraph 容器启动命令如下,其中 --enable_plugin true 用于开启 Python 存储过程的加载与删除权限。

docker run -d -v D:\wangmaoning:/mnt -p 7070:7070 -p 7687:7687 -p 9090:9090 \ tugraph/tugraph-runtime-ubuntu18.04:4.3.1 \ lgraph_server -d run --enable_plugin true

三、实验原理

3.1广度优先搜索(BFS

广度优先搜索按距离起点的层级递增依次访问图中节点。算法维护一个先进先出的队列,从起点出发,每弹出一个节点便将其尚未访问过的邻居入队,并记录被访问节点距离起点的跳数。在金融交易图中,BFS 适合用于追踪某一笔可疑交易在若干跳之内涉及到的全部上下游交易,进而构建该可疑节点的局部交易网络。

3.2 Elliptic比特币交易数据集

Elliptic 数据集是当前公开的比特币交易匿名标注数据集之一,节点表示一笔比特币链上交易,边由出币方交易指向入币方交易,描述交易之间的资金流转关系。节点的类别标签 class 取值为 1 表示非法交易(与勒索软件、黑市等行为关联),取值为 2 表示合法交易,取值为 unknown 表示未标注。本实验使用其中两份原始文件:elliptic_txs_classes.csv 与 elliptic_txs_edgelist.csv,在 TuGraph 中建模为 Transaction 节点与 Refers 关系。

四、实验数据集与建模

Elliptic 比特币交易数据集在 TuGraph 中按属性图建模如下:节点标签为 Transaction,包含 txId(长整型主键)与 class(字符串类别)两个属性;边标签为 Refers,方向由 txId1 指向 txId2,表示前者向后者发起资金转移。数据规模为 203,769 个交易节点与 234,355 条 Refers 边。其中非法节点 4,545 个,合法节点 42,019 个,未标注节点 157,205 个,全图非法交易占比为 2.23%。

1全图节点类别分布

五、算法选择与问题设计

本次实验从 PPT 列出的六类图算法中选取广度优先搜索(BFS)作为研究对象,原因有三:其一,BFS 的存储过程是 PPT 中明确给出的示例代码 ceshi_BFS.py,便于检验存储过程上传机制;其二,BFS 在稀疏图上的复杂度为 O(V+E),能够在大规模交易图上快速返回结果;其三,BFS 的输出形式天然适合作为下游统计分析的输入。

结合 Elliptic 数据集的金融含义,本实验设计的核心问题是:选取一个具有较大入度的非法(class=1)交易节点作为研究起点,在 TuGraph 中调用 BFS 存储过程获取其三层双向邻域,再借助 Cypher 复杂查询统计该邻域内 class 标签的分布,考察非法资金是否在比特币交易图中表现出明显的局部聚集与扩散现象。

六、实验步骤

6.1启动TuGraph并登录

启动 Docker 容器后,浏览器访问 http://localhost:7070 进入 TuGraph 登录页,使用 admin 账号完成认证,系统跳转至默认的查询工作台,左侧导航栏包含查询、建模、导入、插件、帮助五个模块。

2 TuGraph 4.3.1 Web管理端登录页面

3登录后的查询工作台主界面

6.2数据规模核验

为确认数据集已正确导入,先以两条 Cypher 语句分别统计顶点与边的数量。

MATCH (n) RETURN count(n) AS vertices

4顶点数量查询(203,769

MATCH ()-[r]->() RETURN count(r) AS edges

5边数量查询(234,355

6.3类别分布与起点选取(基础查询)

执行下列 Cypher 语句,统计全图 Transaction 节点的 class 分布。

MATCH (n:Transaction) RETURN n.class AS class, count(*) AS cnt ORDER BY cnt DESC

6全图节点类别分布查询结果

在已知非法节点中筛选入度最高者作为 BFS 起点,选定 txId=30179316(内部 vid=148166)作为研究对象,其入度为 177。

MATCH (n:Transaction {class:'1'})<-[:Refers]-(m) RETURN n.txId AS txId, id(n) AS vid, count(m) AS in_deg ORDER BY in_deg DESC LIMIT 1

7高入度非法节点筛选结果

6.4 BFS存储过程编写与上传

BFS 存储过程基于 TuGraph 4.x 的 Python 插件接口编写,实现以指定节点为起点的双向广度优先遍历,并在结果中同时记录每个节点距离起点的层数,便于后续分层统计。存储过程的关键代码片段如下。

# -*- coding: utf-8 -*- """BFS plug-in for TuGraph (Elliptic Transactions). Input JSON: {"start_vid": <int>, "max_depth": <int>, "direction": "out"|"in"|"both"} Output: JSON list of [vid, depth] pairs, depth=0 for the seed itself. """ import json def Process(db, input): parsed = json.loads(input) start_vid = int(parsed["start_vid"]) max_depth = int(parsed.get("max_depth", 3)) direction = parsed.get("direction", "both") txn = db.CreateReadTxn() visited = {start_vid: 0} frontier = [start_vid] for depth in range(1, max_depth + 1): next_frontier = [] for vid in frontier: v = txn.GetVertexIterator(vid) if not v.IsValid(): continue if direction in ("out", "both"): eit = v.GetOutEdgeIterator() while eit.IsValid(): nb = eit.GetDst() if nb not in visited: visited[nb] = depth next_frontier.append(nb) eit.Next() if direction in ("in", "both"): eit = v.GetInEdgeIterator() while eit.IsValid(): nb = eit.GetSrc() if nb not in visited: visited[nb] = depth next_frontier.append(nb) eit.Next() frontier = next_frontier if not frontier: break txn.Abort() return (True, json.dumps([[vid, d] for vid, d in visited.items()]))


将文件以 Base64 编码后,借助 Cypher 内置过程 db.plugin.loadPlugin 完成上传,随后调用 db.plugin.listPlugin可以查询到已上传的 Python 插件描述。

8 Python存储过程列表,bfs插件已成功上传

6.5调用BFS进行三层双向遍历

执行 db.plugin.callPlugin 调用 bfs 存储过程,传入 JSON 参数 start_vid=148166,max_depth=3,direction=both。

CALL db.plugin.callPlugin('PY','bfs','{"start_vid": 148166, "max_depth": 3, "direction": "both"}',60.0,false)

9 BFS存储过程调用与返回结果

返回值为 905 个 [vid, layer] 二元组,按层划分依次为:第 0 层 1 个、第 1 层 177 个、第 2 层 22 个、第 3 层705 个;插件本体执行耗时仅 0.0066 秒,体现出 TuGraph 在大规模稀疏图上的访问效率。

10 BFS各层邻居节点数量分布

6.6邻域类别分布统计(复杂查询)

在 BFS 返回的节点集合上执行带 IN 列表过滤的 Cypher 复杂查询,聚合统计每一层的类别构成,与全图基线进行对照。

MATCH (n:Transaction) WHERE id(n) IN [<vid 列表>]
RETURN n.class AS class, count(*) AS cnt ORDER BY cnt DESC

统计结果显示,三层邻域内共有未标注节点 777 个、合法节点 115 个、非法节点 13 个,邻域非法占比为1.44%。

11 BFS各层邻居的类别构成

12 BFS邻域非法占比与全图基线对比(仅统计已标注节点)

七、实验结果与分析

若以全部 Transaction 节点(含未标注)为分母,BFS 邻域内非法节点的占比为 1.44%,略低于全图基线2.23%。造成该现象的主要原因是邻域中未标注节点的比重过高(777 / 905),稀释了非法节点的占比。

若仅在已标注节点之间进行对照,BFS 邻域内非法占比为 10.16%(13 个非法 / 128 个已标注),全图已标注节点中的非法占比为 9.76%(4545 / 46564)。两者均处于 9% 至 11% 区间,邻域非法占比与全图基线大体持平,并未出现显著富集。

按层细看可发现一处值得关注的现象:第 1 层 177 个直接邻居中并未出现已知的非法交易,而新增的 12 个非法节点全部出现在第 3 层。这种延后出现的特征与比特币交易混淆策略相符,非法交易往往在直接资金来源中隐藏自身,而借由多跳转账与下游资金接收方建立联系。

实验也反映出公开标签覆盖率不足对结论的限制。全图节点中 77.1% 处于未标注状态,BFS 邻域内这一比例为 85.9%,缺乏可对照的真实标签将削弱图算法在反洗钱场景中的可解释性。若引入半监督学习或借助Node2Vec 等节点嵌入方法对 unknown 节点做风险预测,结论的稳定性将进一步提升。

八、结论

本次实验以双向 BFS 存储过程为核心,在 TuGraph 平台上完成了从存储过程编写、上传、调用到结果统计的完整流程。实验数据显示,以高入度非法交易为起点的三层邻域共覆盖 905 个节点,邻域内已标注节点的非法占比与全图基线持平,非法节点呈现出延后出现并集中在第三层的分布特征。这一结果说明 BFS 等图遍历算法可作为非法资金扩散路径追踪的可行手段,同时也指出公开标签稀疏对结论稳定性的潜在影响。

九、学习与使用TuGraph平台的感受

TuGraph 在 Cypher 兼容性、存储过程灵活性与查询性能三个方面给人留下深刻印象。Cypher 语法与 Neo4j 高度一致,使过往掌握的查询经验能够直接迁移,无需重新学习查询语言;Python 存储过程仅以简单的Process(db, input) 函数即可挂接到图数据库内部,省去了在外部进程中反复请求图数据的网络开销;在 20 万节点级别的稀疏图上,单次三层双向 BFS 在毫秒级完成,性能足以支撑实验级别的图分析任务。

美中不足之处在于配置项与 API 文档的版本差异较大,部分 PPT 示例语法在 4.3.1 中并不完全适用,例如WITH UNWIND 子查询连接在该版本尚未实现,需要改写为 IN 列表过滤的形式;存储过程的加载默认关闭,需要在配置文件中显式开启 enable_plugin 选项才能正常工作。若后续版本能在 Web 端提供更直观的存储过程上传、调试与日志查看入口,将进一步提升使用体验。

http://www.jsqmd.com/news/926208/

相关文章:

  • 2026优质玻璃纤维制造商标杆名录:玻璃纤维销售厂家、玻璃纤维企业、玻璃纤维优质厂家、玻璃纤维供应厂家、玻璃纤维供货商选择指南 - 优质品牌商家
  • 【稳定性评测】同样的 Prompt 测试十次结果都不一样?如何通过系统提示控制一致性
  • `build-your-own-x` 涨了817星,但今天真正该装的是这个
  • web 第二次作业
  • MiMo Vision Router:让纯文本模型秒变多模态
  • 我写了十年代码,直到AI出现
  • 【Android】手机屏幕劫持防护
  • Keil C51编译器Makefile选项解析与替代方案
  • Kimi LeetCode 2911. 得到 K 个半回文串的最少修改次数 Java实现
  • 机械臂角度识别 机械臂自由度识别 yolov8机械臂关键点检测模型部署+教程+代码+数据集+工业应用
  • 量子计算冗余架构:双星设计提升容错与并行能力
  • 避坑指南:在Ubuntu 20.04上从零搭建XTDrone仿真环境(附解决MAVROS连接失败)
  • 数据结构 算法解释,排序、查找
  • 【元器件专题】MOS管内部结构
  • LEGO框架:空间加速器设计的动态数据流优化
  • 2026年Q2炉渣钢渣供应商评测:上阳建材适配性分析 - 优质品牌商家
  • 2026年汽车静电阻隔面料实测评测:四家企业横向对比 - 优质品牌商家
  • 阿里云旗舰级顶级代理商|年销4亿+官方可查,直享7折,稳靠不跑-路
  • 主流人工智能模型与工具开发商概览
  • 别再死记硬背了!用C语言手写一个test_and_set(),彻底搞懂操作系统硬件锁
  • 书匠策AI:你的课程论文救急神器,用过的人都说“真香“
  • 乐高wedo《套圈游戏》
  • AMP算法实战:用Python从零实现压缩感知信号恢复(附完整代码与避坑指南)
  • 实战落地+数据可视化:6月最新重庆优质GEO优化服务商榜单深度测评 - 品牌官
  • Codex+Vscode+Remote ssh+ 服务器自定义第三方API配置保姆级教程
  • 2026年苏州防水维修标杆机构专业市场分析与全场景渗漏治理选型适配指南 专业防水公司排名推荐(2026年5月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 最新Python爬虫实战(多线程爬虫篇)——案例26:多线程爬取斗罗大陆3龙王传说小说批量保存到txt(附上完整爬虫代码)
  • 深度学习焊接缝识别 yolov8焊接缝缺陷分割代码+web部署
  • 2026年5月秦皇岛酒店之选:为何万怡酒店脱颖而出 - 2026年企业资讯
  • 基于MATLAB的simulink汽车防抱死仿真模型,汽车制动防抱死模型ABS仿真模型