文档章节

Python以太坊交互将区块链数据存入sql数据库

geek12345
 geek12345
发布于 09/05 09:49
字数 3924
阅读 1938
收藏 4

关于区块链介绍性的研讨会通常以易于理解的点对点网络和银行分类账这类故事开头,然后直接跳到编写智能合约,这显得非常突兀。因此,想象自己走进丛林,想象以太坊区块链是一个你即将研究的奇怪生物。今天我们将观察该生物,并与其进行交互然后将有关它的所有数据收集到一个集中存储中供自己使用。

进行第一次设置

首先,你需要安装web3py。Web3py是一个用于连接以太坊区块链的Python库。你需要事先知道的是,没有可以从中下载数据的中央管理系统。彼此共享资源的内连节点(“对等体”)存储经验证的数据副本(或其一部分)。网络执行以太坊协议,该协议定义节点彼此之间的交互规则及网络上的智能合约。

如果要访问有关交易,余额,区块或其他任何被写入区块链的信息,协议需要你连接到节点。节点不断地相互共享新数据并验证数据,因此这样你就可以确定那些是未被篡改的数据,那些是最新的数据。

你可以在第一次接触以太坊的方法中使用两种基本类型的节点:本地或托管。本地节点可以在你的计算机上运行,这意味着你首先需要下载像geth这样的客户端,它会将区块链同步到你的设备,要占用存储空间并花费大量时间来完成。对于第一次学习,托管节点是更好的选择——它由其他人控制,但你可以轻松连接到它并自己玩区块链。

去Infura并创建自己的免费帐户以访问此类托管节点。当你完成后,你可以看到mainnet主网(即以太坊区块链)和一堆testnets测试网,它们基本上可以测试你的智能合约,这样你就可以在将昂贵的代码部署到mainnet之前犯错误,并纠正它们。

这第一次我们先导入Web3对象并建立HTTP连接。

from web3 import Web3 
web3 = Web3(Web3.HTTPProvider("https://mainnet.infura.io/your-own-personal-number"))

现在你已经完成了!你可以使用web3 API浏览查询数据结构了。

查询特定区块信息

#current block number
>>> web3.eth.blockNumber
5658173
#get the content of the most recently mined block
>>> web3.eth.getBlock('latest')

此命令返回AttributeDict数据结构,该结构是key-value键值对的字典,如下所示:

AttributeDict({'difficulty': 3297284143124448,
 'extraData': HexBytes('0x65746865726d696e652d6177732d61736961312d34'),
 'gasLimit': 7999992,
 'gasUsed': 7990111,
 'hash': HexBytes('0x8c09ba67123601c08ef5d292acaffd36798ca178b7d6fecd5e1144ce8e3b9e50'),
 'logsBloom': HexBytes('0x348000240b40620836308460180004415000c8ccb260021402420721c22801ca847c625c0a89030482044001523a4d100050100250d100858381260a186312088006c154010000491216446840888200c1812088c12b06000809a808530014160000812c2ac20008a201c83380314d02242338400c0500c2a028005010988c44b0608a020400201032e10e16142b931115469824248066100b082224200222140a41a20aa2006224d608210f1a22811d03969423e8c08058100388c0800402002a000802130c40d289201900c38142a1cc0380a4010f0201040d4022200022018c5801346c168502841906940485ea1d9864044060a00000a00616004d006090'),
 'miner': '0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8',
 'mixHash': HexBytes('0x84320fd71345778b48e437f3403e9021575520ba23aaac48dd7a352c9ce31f75'),
 'nonce': HexBytes('0x98a0b1e00bfabac6'),
 'number': 5658173,
 'parentHash': HexBytes('0x01eda8a47a0151533d1afacf9b9108606d4d89a86e269dddaac9698b6fb12930'),
 'receiptsRoot': HexBytes('0xc40f774ad10ad443457c3a5a0db96b539af3007f8d351b198ca7bf2ef196b7e0'),
 'sha3Uncles': HexBytes('0x55725ec296c6c64257ed6a88d7d8c66160abe7b672f5d89bbad5487779b1d5fe'),
 'size': 27161,
 'stateRoot': HexBytes('0x5bfc7a9a87fb9991f2760807d56319154f1dab91d3cfc9530a597b6c5d064aba'),
 'timestamp': 1527002893,
 'totalDifficulty': 4339832462578780814928,
 'transactions': [HexBytes('0x1ce6bca99701c4e8acae986b10e7649d628d70ec62b7a8314bbb13726a312225'),
  HexBytes('0x6ba5e657243aea5f95afb40090313d10bb9443db41ed1216fbf7e7e60a16749a'),
 loooooots_of_transactions_here],
 'transactionsRoot': HexBytes('0x67e1e1f2f4b1d33791a0fba2d5ebf039bd6c331c665cb8020ff41d0e0eade46e'),
 'uncles': [HexBytes('0x3df1bffa62d73b3847b434e9ea459c10cfdc3e212a2e78ebbf0db58adbef30b5'),
  HexBytes('0x74bdcd4b88427854ae18f9c7ada28d46f26411bed09af6b040cbede66fdb1853')]})

并非所有这些变量都会立即对你有用,因为有些变量非常技术性,只有当你对区块链的实际工作方式有了更深入的了解时,它们的含义才有意义。你可以在所谓的黄皮书中阅读有关它们的更多信息,或暂时跳过它们并使用易于理解的方法。

简而言之,一个包含区块头部信息的区块,一个写入它的已验证交易列表和一个未确认列表(矿工的块标识符,他们的区块太慢,无法进入主区块链,但仍因其计算工作量而获得以太奖励)。下面你可以看到每个变量的含义,我把它分成子类别。

General常规数据

Block variableMeaning翻译
numberscalar value equal to the number of ancestor blocks (genesis block=0)标量值相对创始块的数量,genesis block=0
sizesize of the block in bytes块的大小,以字节为单位
timestampUnix's time() at this block's inception这个块开始时的Unix时间
miner160-bit address for fees collected from successful mining成功采矿收取以太的160位地址
gasLimitmaximum gas expenditure allowed in this block此区块允许的最大气体消耗量
gasUsedtotal gas used by all transactions in this block此区块中所有交易使用的总气体
transactionslist of transaction hashes included in the block块中包含的交易哈希列表
parentHashKeccak256 hash of the parent block's header父块区块头的Keccak 256哈希值
hashcurrent block's hash当前块的哈希值
extraDataextra data in byte array字节数组中的额外数据

挖矿相关

Block variableMeaning翻译
difficultyscalar value corresponding to the difficulty level of the block对应于块的难度级别的标量值
totalDifficultyinteger of the total difficulty of the chain until this block直到此区块的链的总难度值
noncehash of the generated proof-of-work; null when its a pending block生成工作量证明的哈希值;当区块挂起时为null
mixHash256-bit hash which is combined with the nonce and used to prove that sufficient amount of computation has been carried out on this block256位哈希与nonce结合使用来证明已对此块执行了足够的计算量

uncle相关

Block variableMeaning翻译
uncleslist of uncle hashesuncle哈希值列表
sha3UnclesSHA3 of the uncles data in the block块中uncles数据的SHA3值

技术相关

Block variableMeaning翻译
receiptsRootKeccak 256-bit hash of the root node of the tree structure populated with receipts of all transactions in this blockKeccak树结构的根节点的256位哈希填充了此块中所有交易的收据
stateRootKeccak256 hash of the root node if the state trie after all transactions are executed and finalisations applied在执行所有交易并应用终止后,如状态为trie根节点的keccak256哈希值
transactionsRootKeccak256 hash of the root node of the trie structure populated with the receipts of each transaction in the transactions listtrie结构的根节点的keccak256哈希填充了交易列表中每个交易的收据
logsBloomthe Bloom filter from indexable info (logger address and log topics) contained in each log entry from the receipt of each transaction in the transaction list交易列表中每个交易的接收日志条目中包含的可索引信息(记录器地址和日志主题)的Bloom过滤器

交易和收据

现在,我们还可以通过其唯一标识符(即交易哈希)查找区块中的单个交易。

>>> web3.eth.getTransaction('0x1ce6bca99701c4e8acae986b10e7649d628d70ec62b7a8314bbb13726a312225')

AttributeDict({'blockHash': HexBytes('0x8c09ba67123601c08ef5d292acaffd36798ca178b7d6fecd5e1144ce8e3b9e50'),
 'blockNumber': 5658173,
 'from': '0x390dE26d772D2e2005C6d1d24afC902bae37a4bB',
 'gas': 45000,
 'gasPrice': 123400000000,
 'hash': HexBytes('0x1ce6bca99701c4e8acae986b10e7649d628d70ec62b7a8314bbb13726a312225'),
 'input': '0x',
 'nonce': 415710,
 'r': HexBytes('0x1bb901ad0a3add517504cc459fdb1545d193020ec5c63a566e440ee39dbfe131'),
 's': HexBytes('0x4b7ac95eb321b5947948ecb624e1d80b19d9cc876668c69cc2b32670f52b061a'),
 'to': '0xBbA2D99C9B3aF394B0d6417b1D58815eE495029D',
 'transactionIndex': 0,
 'v': 37,
 'value': 1000000000000000000})

和以前一样,web3py返回一个属性字典。下表总结了每个键的含义。

Transaction variableMeaning翻译
blockHashhash of the block the transaction belongs to交易所属区块的哈希值
blockNumbernumber of that block该块的编号
hashtransaction hash (unique identifier)交易地址哈希(唯一标识符)
from160-bit address of a sender of a transaction来自交易发送方的160位地址哈希
toaddress of the recipient or null for a contract creation transaction收件人的地址或者创建合约交易时为null
valuenumber of wei to be transfered to the recipient or newly created account (case of contract creation)要转移给收件人或新创建帐户的wei数量(创建合约的情况)
gasgas consumed by the transaction交易消耗的天然气
gasPricenumber of Wei to be paid per unit of gas for all computatioon costs of this transaction此交易所有计算成本的每单位天然气的支付数量
noncenumber of transactions/contract creations sent by the sender prior to this one发送方在此之前发送的交易和创建合约的数量
v/r/sused to identify the sender; the signature values of the transaction用于识别发件人交易的签名值
inputthe data sent along with the transaction与交易一起发送的数据
transactionIndexindex of the transaction in the block区块中交易的索引

最后,我们还可以查看交易收据:

>>> web3.eth.getTransactionReceipt('0x68c70c5ffe54a42ebf7118e7e931aeac018cee4656a816ffe6a01388da50c851')

AttributeDict({'blockHash': HexBytes('0x44338e1f80302037c7213e8f56dd35d8a473b000319bc200f76e910e62d12f98'),
 'blockNumber': 5617795,
 'contractAddress': None,
 'cumulativeGasUsed': 21004,
 'from': '0xea6e3e41ebaa09d550d3c3f0d72971b3c5ccc261',
 'gasUsed': 21004,
 'logs': [],
 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
 'status': 1,
 'to': '0xd96a6e75d099ce529bbd257cbcb403224cceaebf',
 'transactionHash': HexBytes('0x68c70c5ffe54a42ebf7118e7e931aeac018cee4656a816ffe6a01388da50c851'),
 'transactionIndex': 0})

交易收据包含一些重复和新条目,新的条目解释如下。

Receipt variableMeaning翻译
statusboolean whether the transaction was successfull; false if the EVM (Ethereum Virtual Machine) reverted the transaction交易是否成功,如果EVM(以太坊虚拟机)还原了交易则返回false
contractAddressthe contract address created if the transaction was a contract creation; otherwise null如果交易是合约创建,则创建的合同地址;否则为null
gasUsedthe total amount of gas used when this transaction was executed in the block在区块中执行此交易时使用的总气体量
cumulativeGasUsedthe sum of gasUsed by this transaction and all preceding transactions in the same block此交易使用的gasUse和同一块中所有先前交易的总和
logsarray of log objects which the transaction has generated交易生成的日志对象数组

作为参考,除了黄皮书之外,我还包括各种额外资源来编制这些表格2,3,4,5

如你所见,只需几个简单的命令,就可以连接到网络并获得有关原始格式的交易,区块或状态的基本信息。这将为这些数据打开一个新窗口!

数据库管理系统

当计划将数据写入适当的数据库时,你可能会意识到有许多针对Python爱好者的管理系统解决方案,例如无服务器SQLite,或基于服务器的MySQL,PostgreSQL或Hadoop。根据你的意图,必须确定哪个选项最适合你的项目。总的来说,我发现这些要点很有帮助:

  • 数据库的预期大小是什么(即可以在单个机器系统上处理)?
  • 这些条目是经常编辑还是会保持不变?
  • 数据库是否应该由多方/应用程序同时访问和编辑?

随着时间的推移,以太坊区块链正在稳步增长,截止到2018年6月接近1TB,这个很小,因此对于像Hadoop这样的分布式处理系统来说并不是最佳选择。区块链数据库将被写入一次,然后仅使用新条目进行扩展,保留旧条目不变。此数据库的预期用例由一个通道编写,并由其他通道以只读方式访问,因此我们实际上不需要在服务器上运行它。在你的机器上本地保存数据库将导致快速读取,这对于像SQLite这样的无服务器管理系统是可取的和可实现的。Python有一个内置的库sqlite3,因此我们甚至不需要安装新的包。

数据库设计

下一步是设计数据库。请记住哪些数据字段与你的分析最相关,并且旨在优化搜索和存储。例如,如果你不打算使用stateRoot,则可能需要完全跳过它或将其保存在单独的表中。可以更快地搜索具有较少列的表,如果稍后意识到你实际上具有stateRoot的用例,你仍然可以访问它。你可能还希望将块信息与交易信息分开;如果不这样做,那么区块属性如timestamp将对区块中的所有交易重复N次,浪费大量空间。稍后使用JOIN操作可以轻松地将交易与其块属性进行匹配。

我设计的数据库包含3个表:

  • Quick:最相关的交易信息,用于快速访问和分析。
  • TX:所有剩余的交易信息,
  • Block:指定区块的信息。

变量的命名约定相对于原始的web3py略有改变,以消除歧义,例如将块哈希和交易哈希都称为“哈希”,或使用“from”/“to”作为列名,这在SQL有不同的含义,会使程序崩溃。

交易值,余额和其他大数字需要作为字符串存储在数据库中。原因是SQLite只能处理最多8字节存储的有符号整数,最大值为2的63次方-1大约是9223372036854775807.这通常远低于wei中的交易值(例如,1ETH = 10*18 wei)。

构建你的迷你数据库

完整的代码可以在GitHub上找到。它将根据上层架构组织区块链信息,并输出包含预先指定数量的块数据的blockchain.db文件。要测试它,请转到database.py文件并为要写入的块数选择合理的数字,例如:

Nblocks = 10000

默认情况下,你应该将web3对象指向Infura端点。 如果你有IPC提供商(即你的本地节点),也可以切换到IPC提供商,只需取消注释该行:

# or connection via node on the VM 
#web3 = Web3(Web3.IPCProvider('/path-to-geth.ipc/'))

修改路径,然后只需在命令行python database.py中运行。代码会将最后写入的块的编号转储到lastblock.txt文件中,以防你需要重新启动。

如何使用数据库

一旦将第一个条目写入数据库,就可以通过ipython shell开始与它进行通信。例如,要打印表“Quick”的前5行,你可以运行下面的代码。

import sqlite3 as sq3
conn = sq3.connect("blockchain.db")
cur = conn.cursor()

# some SQL code, e.g. select first five entries of the table Quick
cur.execute("SELECT * FROM Quick LIMIT 5")
a = cur.fetchall() #list of tuples containing all elements of the row
print(a)
conn.close()

本地节点与Infura

如果要构建大型数据库,则应下载geth并同步节点。同步可以在3种基本模式下完成:

如果你不需要过去的帐户状态,则可以在快速模式下同步节点6

下面的图表显示了此代码写入数据库的速度,与本地完全同步的节点(IPC)与Infura(Infura)上的地址进行通信。正如你所看到的,在本地节点上运行此代码是值得的,因为你可以将速度提升近2个数量级(即100x)!

总结

现在你已拥有自己的本地数据库,了解区块链上发生的事情,可以开始探索它。例如,你可以计算自其起源以来的交易数量,查看作为时间函数生成的地址数量——天空是你可以了解的有关区块链的限制。我们为你的数据科学游乐场奠定了基础。因此,请继续探讨,或查看下一篇文章,了解潜在的应用。

python用web3.py库开发以太坊来说非常的方便,有兴趣的用户可以关注我们的python以太坊教程,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。

另外其他语言可以学习的以太坊教程如下:

  • web3j教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • 以太坊教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。

汇智网原创翻译,转载请标明出处。这里是原文

© 著作权归作者所有

共有 人打赏支持
geek12345
粉丝 13
博文 31
码字总数 57465
作品 0
海淀
如何用Python Flask开发以太坊智能合约

将数据存储在数据库中是任何软件应用程序不可或缺的一部分。无论如何控制该数据库都有一个该数据的主控。区块链技术将数据存储到区块链网络内的区块中。因此,只要某个节点与网络同步,它们就...

编程狂魔
08/29
0
0
python与以太坊交互将区块链信息存入SQLite数据库

关于区块链介绍性的研讨会通常以易于理解的点对点网络和银行分类账这类故事开头,然后直接跳到编写智能合约,这显得非常突兀。因此,想象自己走进丛林,想象以太坊区块链是一个你即将研究的奇...

jimi2019
09/05
0
0
以太坊DApp开发入门教程——Node.js和truffle框架打造区块链投票系统

第一节 课程概述 本课程面向初学者,内容涵盖以太坊开发相关的基本概念,并将手把手地教大家如何构建一个 基于以太坊的完整去中心化应用 —— 区块链投票系统。 通过本课程的学习,你将掌握:...

马拉喀什
03/02
0
0
区块链是什么?彻底理解只需40行python代码!

尽管有人认为区块链目前还是个不成熟的解决方案,但它无疑称得上是计算机发展历史上的一个奇迹。但是,到底区块链是什么呢? 我们将通过动手实现一个迷你的区块链来帮你真正理解区块链技术的核...

汇智网教程
05/06
0
0
如何用Python和Flask框架开发以太坊智能合约

将数据存储在数据库中是任何软件应用程序不可或缺的一部分。无论如何控制该数据库都有一个该数据的主控。区块链技术将数据存储到区块链网络内的区块中。因此,只要某个节点与网络同步,它们就...

笔阁
08/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arts-week10

Algorithm 905. Sort Array By Parity - LeetCode Review Who’s Afraid of the Big Bad Preloader? 一文读懂前端缓存 一个网络请求3个步骤:请求,处理,响应,而前端缓存主要在请求处响应这两步...

yysue
今天
1
0
00.编译OpenJDK-8u40的整个过程

前言 历经2天的折腾总算把OpenJDK给编译成功了,要说为啥搞这个,还得从面试说起,最近出去面试经常被问到JVM的相关东西,总感觉自己以前学的太浅薄,所以回来就打算深入学习,目标把《深入理...

凌晨一点
今天
5
0
python: 一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况: def checkContentAndType(obj): print(obj) print(type(obj))if __name__=="__main__": tu...

Oh_really
昨天
6
2
jvm crash分析工具

介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log。里面记录了jvm当时的运行状态以及错误信息,但是内容量比较庞大,不好分析。所以我们要借助工具来帮我们。 Cras...

xpbob
昨天
138
0
Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部