python 生成pdf收据_python如何与以太坊交互并将区块链信息写入SQLite
關于區塊鏈介紹性的研討會通常以易于理解的點對點網絡和銀行分類賬這類故事開頭,然后直接跳到編寫智能合約,這顯得非常突兀。因此,想象自己走進叢林,想象以太坊區塊鏈是一個你即將研究的奇怪生物。今天我們將觀察該生物,并與其進行交互然后將有關它的所有數據收集到一個集中存儲中供自己使用。
進行第一次設置
首先,你需要安裝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.blockNumber5658173#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翻譯
number
scalar value equal to the number of ancestor blocks (genesis block=0)
標量值相對創始塊的數量,genesis block=0
size
size of the block in bytes
塊的大小,以字節為單位
timestamp
Unix's time() at this block's inception
這個塊開始時的Unix時間
miner
160-bit address for fees collected from successful mining
成功采礦收取以太的160位地址
gasLimit
maximum gas expenditure allowed in this block
此區塊允許的最大氣體消耗量
gasUsed
total gas used by all transactions in this block
此區塊中所有交易使用的總氣體
transactions
list of transaction hashes included in the block
塊中包含的交易哈希列表
parentHash
Keccak256 hash of the parent block's header
父塊區塊頭的Keccak 256哈希值
hash
current block's hash
當前塊的哈希值
extraData
extra data in byte array
字節數組中的額外數據
挖礦相關
Block variableMeaning翻譯
difficulty
scalar value corresponding to the difficulty level of the block
對應于塊的難度級別的標量值
totalDifficulty
integer of the total difficulty of the chain until this block
直到此區塊的鏈的總難度值
nonce
hash of the generated proof-of-work; null when its a pending block
生成工作量證明的哈希值;當區塊掛起時為null
mixHash
256-bit hash which is combined with the nonce and used to prove that sufficient amount of computation has been carried out on this block
256位哈希與nonce結合使用來證明已對此塊執行了足夠的計算量
uncle相關
Block variableMeaning翻譯
uncles
list of uncle hashes
uncle哈希值列表
sha3Uncles
SHA3 of the uncles data in the block
塊中uncles數據的SHA3值
技術相關
Block variableMeaning翻譯
receiptsRoot
Keccak 256-bit hash of the root node of the tree structure populated with receipts of all transactions in this block
Keccak樹結構的根節點的256位哈希填充了此塊中所有交易的收據
stateRoot
Keccak256 hash of the root node if the state trie after all transactions are executed and finalisations applied
在執行所有交易并應用終止后,如狀態為trie根節點的keccak256哈希值
transactionsRoot
Keccak256 hash of the root node of the trie structure populated with the receipts of each transaction in the transactions list
trie結構的根節點的keccak256哈希填充了交易列表中每個交易的收據
logsBloom
the 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翻譯
blockHash
hash of the block the transaction belongs to
交易所屬區塊的哈希值
blockNumber
number of that block
該塊的編號
hash
transaction hash (unique identifier)
交易地址哈希(唯一標識符)
from
160-bit address of a sender of a transaction
來自交易發送方的160位地址哈希
to
address of the recipient or null for a contract creation transaction
收件人的地址或者創建合約交易時為null
value
number of wei to be transfered to the recipient or newly created account (case of contract creation)
要轉移給收件人或新創建帳戶的wei數量(創建合約的情況)
gas
gas consumed by the transaction
交易消耗的天然氣
gasPrice
number of Wei to be paid per unit of gas for all computatioon costs of this transaction
此交易所有計算成本的每單位天然氣的支付數量
nonce
number of transactions/contract creations sent by the sender prior to this one
發送方在此之前發送的交易和創建合約的數量
v/r/s
used to identify the sender; the signature values of the transaction
用于識別發件人交易的簽名值
input
the data sent along with the transaction
與交易一起發送的數據
transactionIndex
index 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翻譯
status
boolean whether the transaction was successfull; false if the EVM (Ethereum Virtual Machine) reverted the transaction
交易是否成功,如果EVM(以太坊虛擬機)還原了交易則返回false
contractAddress
the contract address created if the transaction was a contract creation; otherwise null
如果交易是合約創建,則創建的合同地址;否則為null
gasUsed
the total amount of gas used when this transaction was executed in the block
在區塊中執行此交易時使用的總氣體量
cumulativeGasUsed
the sum of gasUsed by this transaction and all preceding transactions in the same block
此交易使用的gasUse和同一塊中所有先前交易的總和
logs
array 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?Quickcur.execute("SELECT?*?FROM?Quick?LIMIT?5")
a?=?cur.fetchall()?#list?of?tuples?containing?all?elements?of?the?rowprint(a)
conn.close()
本地節點與Infura
如果要構建大型數據庫,則應下載geth并同步節點。同步可以在3種基本模式下完成:
如果你不需要過去的帳戶狀態,則可以在快速模式下同步節點6。
下面的圖表顯示了此代碼寫入數據庫的速度,與本地完全同步的節點(IPC)與Infura(Infura)上的地址進行通信。正如你所看到的,在本地節點上運行此代碼是值得的,因為你可以將速度提升近2個數量級(即100x)!
總結
現在你已擁有自己的本地數據庫,了解區塊鏈上發生的事情,可以開始探索它。例如,你可以計算自其起源以來的交易數量,查看作為時間函數生成的地址數量——天空是你可以了解的有關區塊鏈的限制。我們為你的數據科學游樂場奠定了基礎。因此,請繼續探討,或查看下一篇文章,了解潛在的應用。
總結
以上是生活随笔為你收集整理的python 生成pdf收据_python如何与以太坊交互并将区块链信息写入SQLite的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样快速画出一个正方体_人教版小学数学五
- 下一篇: python apscheduler 阻