本文第一部分探讨了从以太坊区块链提取和转换CryptoKitties数据的技术细节。文章详细讲述了如何解码区块链数据以及智能合约函数调用的实现,提供了对交易和日志信息的深入分析,同时引入了ETL的方法。该系列文章的第二部分将专注于游戏数据分析,提供更多有趣的发现。
来源:https://www.cryptokitties.co/kitty/101
如果你正在阅读这篇文章,你可能已经听说过在过去几个月里引起每个人关注的以太坊网络上的游戏:CryptoKitties!
简而言之,这个游戏的内容是收集虚拟猫。猫是由游戏玩家创建的,玩家可以通过繁殖两只猫来生成一只新的猫。每只猫都有自己独特的基因序列,这决定了它们的物理属性。它们的基因组是其父母基因加上一些随机因素的函数。除了繁殖之外,背后公司的 Axiom Zen 还可以创建多达 50,000 只特征预定义的猫。存在一个市场用于买卖猫,还有一个市场用于“出租”猫进行繁殖。你可以在这里阅读有关游戏的更多信息。
Block Science是一家专注于去中心化经济系统设计与评估的技术研究和分析公司。分析 CryptoKitties 经济的各个方面似乎是一个很好的机会,可以在提高我们数据提取工具的同时获取一些来自实际(且生动!)去中心化应用程序的真实世界数据。
这篇博客文章分为两个部分:
尽管以太坊网络上发生的所有事情都记录在区块链上,但将这些比特转换为有意义的数据并不总是直截了当的。提取事务数据是简单的,可以提取交易数据,表明在某个区块中账户 A 向账户 B 发送了一些以太(ETH),并设置了该事务处理的某个 gas 价格。然而,当我们处理发送到合约的事务时,解码区块链数据是实现从多个固定宽度文本文件的ETL,其格式仅在创建它们的软件源代码中描述。
以一笔发送到合约 0xb1690c08e213a35ed9bab7b318de14420fb57d8c 的交易为例,该交易数据字段中的内容如下:
0x454a2ab300000000000000000000000000000000000000000000000000000000000871ad
它做了什么?
数据字段的第一部分(0x454a2ab3)表示该交易调用的智能合约中的函数。它们是函数签名哈希的前四个字节,该签名定义为函数名称后面跟着其参数的数据类型。
keccak256(“<function>(<type_of_data_1>,<…>,<type_of_data_N>)”)
剩下的字节是函数参数的值。你可以在这里详细阅读相关内容。
即使知道这4个字节,我们如何知道调用的是哪个函数,或它有多少个参数?在这种特定情况下,我们知道合约 0xb1690c… 是 CryptoKitties 拍卖智能合约,即买卖猫的市场。并且因为它的源代码是公开的,我们知道它有一个名为 bid 的函数。
/// 对开放拍卖出价,完成拍卖并
/// 如果提供了足够的以太,转移 NFT 的所有权。
/// param _tokenID: 要出价的代币 ID。
function bid (uint256 _tokenId)
如果我们计算 bid 函数签名的哈希,可以看到前四个字节正是交易数据中存在的字节。
keccak256(“bid(uint256)”) = 454a2ab3c602fd9…
因为该函数只接受一个参数,我们可以判断在交易数据中位于前四个字节之后的所有内容就是该参数。换句话说,该交易是在对猫编号 0x871ad ( 553389 ) 进行出价。
智能合约在执行过程中记录信息是很常见的。通过调用 JSON RPC API eth_getlogs 方法,可以获得合约记录的日志。与调用合约函数的交易一样,我们需要知道合约的源代码才能解码由该 API 返回的数据。例如,以下数据的日志意味着什么?
blockNumber: 0x51968f
topics: [0x0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad5]data: 0x0000000000000000000000001b8f7b13b14a59d9770f7c1789cf727046f7e542000000000000000000000000000000000000000000000000000000000009fac1000000000000000000000000000000000000000000000000000000000009f80e000000000000000000000000000000000000000000000000000000000008957200004a50b390a6738697012a030ac21d585b4c8214ae39446194054b98e0b98f
当合约触发事件时,会记录日志。在我们示例中,topics 数组的第一个元素(它在我们这个例子中只有一个元素)是事件签名的哈希。在 CryptoKitties 的情况下,怀孕和出生的猫时会记录日志。
/// 当两只猫成功繁殖并
/// 妊娠计时器开始时,触发 Pregnant 事件。
event Pregnant (address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock);/// 当一只新的小猫诞生时,触发 Birth 事件。
/// 这显然包括通过 giveBirth 方法创建的任何猫,
/// 但它在创建新的 gen0 猫时也会被触发。
event Birth (address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes);
看看哈希的 Birth 事件签名与我们示例中的日志值是否对应。
keccak256(“Birth(address,uint256,uint256,uint256,uint256)”) = 0x0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad5
到目前为止,我们知道在区块号 51968F (5346959) 中诞生了一只 CryptoKitties!我们解码过程的下一步是根据 Birth 事件的五个参数拆分 data 字段。第一个参数是以太坊地址,长度为 160 位,但用 256 位编码(在地址的左侧填充零)。其他参数是 256 位整数。因此,data 字段分为 5 个部分,每个部分为 256 位(64 个十六进制字符)。
owner: 0000000000000000000000001b8f7b13b14a59d9770f7c1789cf727046f7e542
kittyId:
000000000000000000000000000000000000000000000000000000000009fac1
matronId:
000000000000000000000000000000000000000000000000000000000009f80e
sireId:
0000000000000000000000000000000000000000000000000000000000089572
genes:
00004a50b390a6738697012a030ac21d585b4c8214ae39446194054b98e0b98f
看,这是不是我所说的 “从多个固定宽度文本文件中实施 ETL,其格式仅在创建它们的软件源代码中描述”? :-)
继续阅读第二部分,我们将分享在分析 CryptoKitties 游戏数据时遇到的一些有趣事实!
特别感谢 Block Science 团队提供的研究、见解和审阅。
- 原文链接: medium.com/block-science...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!