web3.py 做 Ethereum Data Analysis <2> ERC20 Token

chuchuhao
chuchuhao
Sep 4, 2018 · 11 min read

此篇是接續上篇沒有提到的部分繼續講,如果還沒看過上篇的話,建議就先回去複習一下吧!如果還不了解 Token是什麼的人,建議先去閱讀一下 Roy大大的神作

今天這一篇我們要講使用 web3.py來爬 Etheruem Token的交易資料,根據我們上篇的經驗可以知道,單純的把 Chain上的資料爬下來並做視覺化其實是沒有辦法得到什麼有用的資訊的!所以我們今天的目標是爬下 Binance Token Voting Round 8時發生的 BNB Token交易,來看這些交易跟投票進展是不是有關係 (抖


Binance Token Voting Round 8

這裡我先來說明一下什麼是 Binance Token Voting Round 8,Binance是目前全球虛擬貨幣交易量最大的交易所之一,如果一個虛擬貨幣能被 Binance列入其可交易的貨幣時,幾乎是保證此貨幣價值和流通量會有一波的增長,因此大家都希望自己持有的貨幣可以上到 Binance交易所,而 Binance每個月有會舉辦一次上幣投票,也就是 Binance會選出 5個候選的貨幣,並且由社群來投票覺得誰可以被列入可交易貨幣

Round 8是 Binance第八次舉行的社群投票上幣活動,這次投票的規則是每一個 Binance帳號,可以選擇一個自己喜歡的 Token把票投給他,而這個帳號投出的票數就是他在投票這段期間所持有的 BNB Token (為 Binance發行的 Token),此外一個帳號最多可以投的票數為 500票。也就是說如果我想要盡全力支持給一個我很希望他上幣的 Token,我可以做的事情就是到市場上買 500個 BNB Token放到我 Binance的帳號裡面,投票給它,並且到投票結束前,不能去動用這 500個 BNB Token (Binance根本靠這招來衝高 BNB價

Round 8 投票結果

而 Round 8之所以有趣是因為在投票結束後的幾天,Binance宣布此次可列入可交易貨幣的是由得票數第四名的 POLY當選,並且隱晦地說不容許任何的選票操作,換句話說,最終投票結果認定得票數前 1~3名的投票者被 Binance認為有選票上的操作而被取消資格!

網路上也有一些人透過 Etheruem Chain的公開資料,提出一些疑似選票操作質疑,下面就是一篇 NKK的鐵粉質疑 MITH選票的文章 (兩個都是這次投票的候選 Token),我覺得這一篇挺有趣的

So, there — we’ve tracked down the account that is distributing 80000 BNB to two majority-holding MITH accounts accounting for 80000 colluded votes from 2 addresses. There may be more connections if you can find them. Nonetheless, these are thus two examples of clear voter manipulation by Mithril. This is sufficient evidence by any estimation.

好了好了,前情提要講太多了,我們這篇的重點是要跟大家分享如何去爬 Ethereum Chain上 Token的交易資料,我們現在進入主題~


ERC20 Token Contract

Contract就是執行在 Ethereum上的程式碼,而 Token的建立以及操作都是透過 Contract來執行,而要執行 Token的操作我們必須要先知道 Token的 ABI,透過 ABI我們可以知道這個 Contract提供了哪些可以使用的操作 (ERC20只是其中一種寫 Contract的規範)

來一個很爛的比喻,ABI就像是甜點店的菜單,如果沒有菜單,你去甜點店會根本不知道可以幹嘛,有了菜單你知道可以花120元買到一個提拉米蘇(但是你仍然不知道這個提拉米蘇是怎麼做出來, 為什麼要花到 120元),如果要知道這個餐點怎麼做出來,我們就要去看 Contract內容

所以接著要找 BNB的 ABI來看 BNB提供哪些操作,我們可以在 Etherscan上面找到 BNB相關的資料

Search BNB on Etherscan

接著我們進入到 BNB的頁面,點選 Contract後面的地址後,可以看到 BNB這個 Token是跑在哪一個 Contract之下

BNB Page on Etherscan

Ethereum的地址分為兩種,一種是 Contract Address,另一種是 Account Address,現在我們點進來看到的這個就是 Contract Address,在這個地址上他是執行著一個 Contract

點進 Code的地方可以看到運行的 Contract
往下拉就可以看到我們要的 ABI了

Etherscan

在要進入 web3.py前,我們複習以下四個東西 blocks, transaction, receipts, logs,這四個名詞一定要搞清楚他們的職責才能清楚地知道自己要爬的資料在哪裡

Chain, Block, Transaction, Receipts and Logs

一樣的我們從大家熟悉的 Etherscan來看這四個東西分別會在哪裡吧!

首先我偷偷先查了一個有 BNB Transaction的 Block

接著再點進去看 transactions的資訊,在 #6259346這個 Block裡面總共有 90個 Transactions,第一個欄位 TxHash是每一筆 Transaction的 Hash值, Hash值代表這個 Transaction的交易編號,在整個 Chain裡面不會重複。第三列 TxHash為0xba4 … 就是記錄著從 0x987 …這個地址轉 Ether到 BinanceToken的地址去執行智能合約,BinanceToken前面有個小Logo,代表他是在執行一個智能合約,之所以不是顯示 0x開頭的地址是因為 Etherscan已經把他知道擁有者的地址做些轉換了

我們繼續來看 TxHash為 0xba4 … 的這一筆 Transaction,在 Etherscan的頁面中, 已經把 transaction, receipt和 Logs混合成統一的顯示格式了,因此可能會以為 receipt只有一個 status的欄位,然後沒有 logs,但其實不是這樣,我們換去用 web3.py看實際有那些東西

transaction logs

web3.py

如上次所說 Receipt是一個 transaction執行後的 outcome, 而 logs則是當這個 transaction是執行 smart contract時,會把 smart contract的 event記錄在 logs裡面,可以看到下面是執行 BNB的 Contract時 logs就有記錄發生了什麼事

receipt & logs

第一次看到這結構的時候,我最疑惑的是,為什麼 logs是用一個 list來存 `多個 log`呢?執行 contract裡面的 transaction不就只會有一個交易的 log嗎?但其實 contract可以完成很多的功能,contract可以執行一個 function把一個地址的 BNB Token執行 BNB contract的 Transfer給多個地址,這樣就有可能會出現多個 logs

接下來我們要從 Solidity的角度來看,我們要的轉帳地址跟轉帳金額分別放在哪裡。

Solidity

剛剛在 web3.py所看到 receipt裡面的 logs是 Solidity中 event這個指令的產物,而 event中有加上 indexed的參數會被放到 log的 topics中,一個 event至多只能有四個 topics,其中第一個 topic固定為此 event的 hash值,可以用來判斷這個 log是屬於甚麼 event至於其他的參數則會被放到 log的 data

從上面這段 Solidity我們可以知道

topic[0] 的 “0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" 是 BNB transfer的 hash值

topic[1]的 “ 0x00000000000000000000000098702707fe04c38ce752afad9c392f4a46289274” 是 transfer的 from_address

topic[2]的 “ 0x0000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be” 是 transfer的 from_address

這個地址跟我們想的不一樣是因為他們被 padding成 32 bytes但 Ethereum地址只用 20bytes (也就是後面 40個字元),所以我們要從 topic取出地址的時候就要做相對印的處理

另外 data放的就是轉的金額拉 (uint256的 value) “ 0x00000000000000000000000000000000000000000000000075f610f70ed20000” 值得注意的是這裡的單位是 Wei


BNB Transaction Crawler

統整我們剛剛所介紹的,就可以寫出一個爬 BNB Transfer的 Crawler囉

crawler

爬資料真的很花時間

其實用 infura爬真的很花時間,這次剛好有把爬的時間紀錄下來, 可以供大家做個參考,從 #6024435爬到#6060060 總共 35626個 Block

總共花費 6860s

平均每個 block花費 3.79s,

最短的時間為 0.21s

最長為 11.86s


Visualization

為了讓大家不用花時間再爬一次,已經把扒下來的資料整理成 CSV檔案公開在 Kaggle了,要是你有什麼想法想要試試看就直接開個 Kernel來試試看吧

GO

下面我們就簡單用兩張圖來看一下投票數的變化與 BNB Token的交易關係吧

得票數 vs 流通量

我把隨著時間五個候選人的得票數跟這段期間 BNB Token的流通量放在一起來看 … 流通量就是指 Transaction Amount的累加

平均得票數 vs 平均流通量

另外我們也來看看每五分鐘內,增加的平均交易量(五分鐘內總交易量除以交易筆數)與五個候選人平均新增票數(五分鐘內新增票數除以投票人數)

所以你有看出什麼了嗎?其實單從這樣簡單視覺化的角度來看,我不覺得可以很輕易的判斷哪一位候選人確實執行了選票操作,相信 Binance也在這問題上頭疼了一會兒~


結論

今天(其實打了好多天)這篇好像打了比較多話,發佈這篇的時候 Binance Round 9也已經結束了,可以看到他們在 Round 9的時候也改變了投票的規則,不過如果你跟我一樣都沒有持有 Round 9候選人的幣的話,那就沒那麼重要拉。

感謝眾大神教學,釐清一些我不太懂的地方,花點時間練習打了這兩篇文章,紀錄一下自己學習的心得,也看有沒有機會幫助到剛好也需要爬 Ethereum Blockchain資料的人~要是有什麼建議 8拖快跟我說~

那我們下次再見

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade