當前位置:首頁 » 以太坊知識 » go以太坊讀取

go以太坊讀取

發布時間: 2023-01-07 23:47:16

『壹』 用Go來做以太坊開發⑤事件日誌

智能合約具有在執行期間「發出」事件的能力。 事件在以太坊中也稱為「日誌」。 事件的輸出存儲在日誌部分下的事務處理中。 事件已經在以太坊智能合約中被廣泛使用,以便在發生相對重要的動作時記錄,特別是在代幣合約(即ERC-20)中,以指示代幣轉賬已經發生。 這些部分將引導您完成從區塊鏈中讀取事件以及訂閱事件的過程,以便交易事務被礦工打包入塊的時候及時收到通知。

為了訂閱事件日誌,我們需要做的第一件事就是撥打啟用websocket的以太坊客戶端。 幸運的是,Infura支持websockets。

下一步是創建篩選查詢。 在這個例子中,我們將閱讀來自我們在之前課程中創建的示例合約中的所有事件。

我們接收事件的方式是通過Go channel。 讓我們從go-ethereum core/types 包創建一個類型為 Log 的channel。

現在我們所要做的就是通過從客戶端調用 SubscribeFilterLogs 來訂閱,它接收查詢選項和輸出通道。 這將返回包含unsubscribe和error方法的訂閱結構。

最後,我們要做的就是使用select語句設置一個連續循環來讀入新的日誌事件或訂閱錯誤。

我們會在下個章節介紹如何解析日誌。

Commands

Store.sol

event_subscribe.go

智能合約可以可選地釋放「事件」,其作為交易收據的一部分存儲日誌。讀取這些事件相當簡單。首先我們需要構造一個過濾查詢。我們從go-ethereum包中導入 FilterQuery 結構體並用過濾選項初始化它。我們告訴它我們想過濾的區塊范圍並指定從中讀取此日誌的合約地址。在示例中,我們將從在 智能合約章節 創建的智能合約中讀取特定區塊所有日誌。

下一步是調用ethclient的 FilterLogs ,它接收我們的查詢並將返回所有的匹配事件日誌。

返回的所有日誌將是ABI編碼,因此它們本身不會非常易讀。為了解碼日誌,我們需要導入我們智能合約的ABI。為此,我們導入編譯好的智能合約Go包,它將包含名稱格式為 <Contract>ABI 的外部屬性。之後,我們使用go-ethereum中的 accounts/abi 包的 abi.JSON 函數返回一個我們可以在Go應用程序中使用的解析過的ABI介面。

現在我們可以通過日誌進行迭代並將它們解碼為我么可以使用的類型。若您回憶起我們的樣例合約釋放的日誌在Solidity中是類型為 bytes32 ,那麼Go中的等價物將是 [32]byte 。我們可以使用這些類型創建一個匿名結構體,並將指針作為第一個參數傳遞給解析後的ABI介面的 Unpack 函數,以解碼原始的日誌數據。第二個參數是我們嘗試解碼的事件名稱,最後一個參數是編碼的日誌數據。

此外,日誌結構體包含附加信息,例如,區塊摘要,區塊號和交易摘要。

若您的solidity事件包含 indexed 事件類型,那麼它們將成為 主題 而不是日誌的數據屬性的一部分。在solidity中您最多隻能有4個主題,但只有3個可索引的事件類型。第一個主題總是事件的簽名。我們的示例合約不包含可索引的事件,但如果它確實包含,這是如何讀取事件主題。

正如您所見,首個主題只是被哈希過的事件簽名。

這就是閱讀和解析日誌的全部內容。要學習如何訂閱日誌,閱讀上個章節。

命令

Store.sol

event_read.go

首先,創建ERC-20智能合約的事件日誌的interface文件 erc20.sol :

然後在給定abi使用 abigen 創建Go包

現在在我們的Go應用程序中,讓我們創建與ERC-20事件日誌簽名類型相匹配的結構類型:

初始化以太坊客戶端

按照ERC-20智能合約地址和所需的塊范圍創建一個「FilterQuery」。這個例子我們會用 ZRX 代幣:

用 FilterLogs 來過濾日誌:

接下來我們將解析JSON abi,稍後我們將使用解壓縮原始日誌數據:

為了按某種日誌類型進行過濾,我們需要弄清楚每個事件日誌函數簽名的keccak256哈希值。 事件日誌函數簽名哈希始終是 topic [0] ,我們很快就會看到。 以下是使用go-ethereum crypto 包計算keccak256哈希的方法:

現在我們將遍歷所有日誌並設置switch語句以按事件日誌類型進行過濾:

現在要解析 Transfer 事件日誌,我們將使用 abi.Unpack 將原始日誌數據解析為我們的日誌類型結構。 解包不會解析 indexed 事件類型,因為它們存儲在 topics 下,所以對於那些我們必須單獨解析,如下例所示:

Approval 日誌也是類似的方法:

最後,把所有的步驟放一起:

我們可以把解析的日誌與etherscan的數據對比: https://etherscan.io/tx/#eventlog

Commands

erc20.sol

event_read_erc20.go

solc version used for these examples

要讀取 0x Protocol 事件日誌,我們必須首先將solidity智能合約編譯為一個Go包。

安裝solc版本 0.4.11

為例如 Exchange.sol 的事件日誌創建0x Protocol交易所智能合約介面:

Create the 0x protocol exchange smart contract interface for event logs as Exchange.sol :

接著給定abi,使用 abigen 來創建Go exchange 包:

Then use abigen to create the Go exchange package given the abi:

現在在我們的Go應用程序中,讓我們創建與0xProtocol事件日誌簽名類型匹配的結構體類型:

初始化以太坊客戶端:

創建一個 FilterQuery ,並為其傳遞0x Protocol智能合約地址和所需的區塊范圍:

用 FilterLogs 查詢日誌:

接下來我們將解析JSON abi,我們後續將使用解壓縮原始日誌數據:

為了按某種日誌類型過濾,我們需要知曉每個事件日誌函數簽名的keccak256摘要。正如我們很快所見到的那樣,事件日誌函數簽名摘要總是 topic[0] :

現在我們迭代所有的日誌並設置一個switch語句來按事件日誌類型過濾:

現在要解析 LogFill ,我們將使用 abi.Unpack 將原始數據類型解析為我們自定義的日誌類型結構體。Unpack不會解析 indexed 事件類型,因為這些它們存儲在 topics 下,所以對於那些我們必須單獨解析,如下例所示:

對於 LogCancel 類似:

最後是 LogError :

將它們放在一起並運行我們將看到以下輸出:

將解析後的日誌輸出與etherscan上的內容進行比較: https://etherscan.io/tx/

命令

Exchange.sol

event_read_0xprotocol.go

這些示例使用的solc版本

『貳』 對於go版的以太坊,有哪位大神指導,裡面的一個方法:GetStorageAt是幹嘛用的么

這是以太坊提供的一個可以讀取區塊鏈賬本中數據的介面,參數依次表示所要讀取存儲的賬戶地址、存儲相對索引位置、以及區塊號。可以參見web3.eth.getStorageAt介面以及以太坊ethapi/api.go對應的GetStorageAt函數。

若解決了你的問題,請採納

『叄』 以太坊是什麼丨以太坊開發入門指南

以太坊是什麼丨以太坊開發入門指南
很多同學已經躍躍欲試投入到區塊鏈開發隊伍當中來,可是又感覺無從下手,本文將基於以太坊平台,以通俗的方式介紹以太坊開發中涉及的各晦澀的概念,輕松帶大家入門。
以太坊是什麼
以太坊(Ethereum)是一個建立在區塊鏈技術之上, 去中心化應用平台。它允許任何人在平台中建立和使用通過區塊鏈技術運行的去中心化應用。
對這句話不理解的同學,姑且可以理解為以太坊是區塊鏈里的Android,它是一個開發平台,讓我們就可以像基於Android Framework一樣基於區塊鏈技術寫應用。
在沒有以太坊之前,寫區塊鏈應用是這樣的:拷貝一份比特幣代碼,然後去改底層代碼如加密演算法,共識機制,網路協議等等(很多山寨幣就是這樣,改改就出來一個新幣)。
以太坊平台對底層區塊鏈技術進行了封裝,讓區塊鏈應用開發者可以直接基於以太坊平台進行開發,開發者只要專注於應用本身的開發,從而大大降低了難度。
目前圍繞以太坊已經形成了一個較為完善的開發生態圈:有社區的支持,有很多開發框架、工具可以選擇。
智能合約
什麼是智能合約
以太坊上的程序稱之為智能合約, 它是代碼和數據(狀態)的集合。
智能合約可以理解為在區塊鏈上可以自動執行的(由事件驅動的)、以代碼形式編寫的合同(特殊的交易)。
在比特幣腳本中,我們講到過比特幣的交易是可以編程的,但是比特幣腳本有很多的限制,能夠編寫的程序也有限,而以太坊則更加完備(在計算機科學術語中,稱它為是「圖靈完備的」),讓我們就像使用任何高級語言一樣來編寫幾乎可以做任何事情的程序(智能合約)。
智能合約非常適合對信任、安全和持久性要求較高的應用場景,比如:數字貨幣、數字資產、投票、保險、金融應用、預測市場、產權所有權管理、物聯網、點對點交易等等。
目前除數字貨幣之外,真正落地的應用還不多(就像移動平台剛開始出來一樣),相信1到3年內,各種殺手級會慢慢出現。
編程語言:Solidity
智能合約的默認的編程語言是Solidity,文件擴展名以.sol結尾。
Solidity是和JavaScript相似的語言,用它來開發合約並編譯成以太坊虛擬機位元組代碼。
還有長像Python的智能合約開發語言:Serpent,不過建議大家還是使用Solidity。
Browser-Solidity是一個瀏覽器的Solidity IDE, 大家可以點進去看看,以後我們更多文章介紹Solidity這個語言。
運行環境:EVM
EVM(Ethereum Virtual Machine)以太坊虛擬機是以太坊中智能合約的運行環境。
Solidity之於EVM,就像之於跟JVM的關系一樣,這樣大家就容易理解了。
以太坊虛擬機是一個隔離的環境,在EVM內部運行的代碼不能跟外部有聯系。
而EVM運行在以太坊節點上,當我們把合約部署到以太坊網路上之後,合約就可以在以太坊網路中運行了。
合約的編譯
以太坊虛擬機上運行的是合約的位元組碼形式,需要我們在部署之前先對合約進行編譯,可以選擇Browser-Solidity Web IDE或solc編譯器。
合約的部署
在以太坊上開發應用時,常常要使用到以太坊客戶端(錢包)。平時我們在開發中,一般不接觸到客戶端或錢包的概念,它是什麼呢?
以太坊客戶端(錢包)
以太坊客戶端,其實我們可以把它理解為一個開發者工具,它提供賬戶管理、挖礦、轉賬、智能合約的部署和執行等等功能。
EVM是由以太坊客戶端提供的。
Geth是典型的開發以太坊時使用的客戶端,基於Go語言開發。 Geth提供了一個互動式命令控制台,通過命令控制台中包含了以太坊的各種功能(API)。Geth的使用我們之後會有文章介紹,這里大家先有個概念。
Geth控制台和Chrome瀏覽器開發者工具里的面的控制台是類似,不過是跑在終端里。
相對於Geth,Mist則是圖形化操作界面的以太坊客戶端。
如何部署
智能合約的部署是指把合約位元組碼發布到區塊鏈上,並使用一個特定的地址來標示這個合約,這個地址稱為合約賬戶。
以太坊中有兩類賬戶:
· 外部賬戶
該類賬戶被私鑰控制(由人控制),沒有關聯任何代碼。
· 合約賬戶
該類賬戶被它們的合約代碼控制且有代碼與之關聯。
和比特幣使用UTXO的設計不一樣,以太坊使用更為簡單的賬戶概念。
兩類賬戶對於EVM來說是一樣的。
外部賬戶與合約賬戶的區別和關系是這樣的:一個外部賬戶可以通過創建和用自己的私鑰來對交易進行簽名,來發送消息給另一個外部賬戶或合約賬戶。
在兩個外部賬戶之間傳送消息是價值轉移的過程。但從外部賬戶到合約賬戶的消息會激活合約賬戶的代碼,允許它執行各種動作(比如轉移代幣,寫入內部存儲,挖出一個新代幣,執行一些運算,創建一個新的合約等等)。
只有當外部賬戶發出指令時,合同賬戶才會執行相應的操作。
合約部署就是將編譯好的合約位元組碼通過外部賬號發送交易的形式部署到以太坊區塊鏈上(由實際礦工出塊之後,才真正部署成功)。
運行
合約部署之後,當需要調用這個智能合約的方法時只需要向這個合約賬戶發送消息(交易)即可,通過消息觸發後智能合約的代碼就會在EVM中執行了。
Gas
和雲計算相似,佔用區塊鏈的資源(不管是簡單的轉賬交易,還是合約的部署和執行)同樣需要付出相應的費用(天下沒有免費的午餐對不對!)。
以太坊上用Gas機制來計費,Gas也可以認為是一個工作量單位,智能合約越復雜(計算步驟的數量和類型,佔用的內存等),用來完成運行就需要越多Gas。
任何特定的合約所需的運行合約的Gas數量是固定的,由合約的復雜度決定。
而Gas價格由運行合約的人在提交運行合約請求的時候規定,以確定他願意為這次交易願意付出的費用:Gas價格(用以太幣計價) * Gas數量。
Gas的目的是限制執行交易所需的工作量,同時為執行支付費用。當EVM執行交易時,Gas將按照特定規則被逐漸消耗,無論執行到什麼位置,一旦Gas被耗盡,將會觸發異常。當前調用幀所做的所有狀態修改都將被回滾, 如果執行結束還有Gas剩餘,這些Gas將被返還給發送賬戶。
如果沒有這個限制,就會有人寫出無法停止(如:死循環)的合約來阻塞網路。
因此實際上(把前面的內容串起來),我們需要一個有以太幣余額的外部賬戶,來發起一個交易(普通交易或部署、運行一個合約),運行時,礦工收取相應的工作量費用。
以太坊網路
有些著急的同學要問了,沒有以太幣,要怎麼進行智能合約的開發?可以選擇以下方式:
選擇以太坊官網測試網路Testnet
測試網路中,我們可以很容易獲得免費的以太幣,缺點是需要發很長時間初始化節點。
使用私有鏈
創建自己的以太幣私有測試網路,通常也稱為私有鏈,我們可以用它來作為一個測試環境來開發、調試和測試智能合約。
通過上面提到的Geth很容易就可以創建一個屬於自己的測試網路,以太幣想挖多少挖多少,也免去了同步正式網路的整個區塊鏈數據。
使用開發者網路(模式)
相比私有鏈,開發者網路(模式)下,會自動分配一個有大量余額的開發者賬戶給我們使用。
使用模擬環境
另一個創建測試網路的方法是使用testrpc,testrpc是在本地使用內存模擬的一個以太坊環境,對於開發調試來說,更方便快捷。而且testrpc可以在啟動時幫我們創建10個存有資金的測試賬戶。
進行合約開發時,可以在testrpc中測試通過後,再部署到Geth節點中去。
更新:testrpc 現在已經並入到Truffle 開發框架中,現在名字是Ganache CLI。
Dapp:去中心化的應用程序
以太坊社區把基於智能合約的應用稱為去中心化的應用程序(DecentralizedApp)。如果我們把區塊鏈理解為一個不可篡改的資料庫,智能合約理解為和資料庫打交道的程序,那就很容易理解Dapp了,一個Dapp不單單有智能合約,比如還需要有一個友好的用戶界面和其他的東西。
Truffle
Truffle是Dapp開發框架,他可以幫我們處理掉大量無關緊要的小事情,讓我們可以迅速開始寫代碼-編譯-部署-測試-打包DApp這個流程。
總結
我們現在來總結一下,以太坊是平台,它讓我們方便的使用區塊鏈技術開發去中心化的應用,在這個應用中,使用Solidity來編寫和區塊鏈交互的智能合約,合約編寫好後之後,我們需要用以太坊客戶端用一個有餘額的賬戶去部署及運行合約(使用Truffle框架可以更好的幫助我們做這些事情了)。為了開發方便,我們可以用Geth或testrpc來搭建一個測試網路。
註:本文中為了方便大家理解,對一些概念做了類比,有些嚴格來不是准確,不過我也認為對於初學者,也沒有必要把每一個概念掌握的很細致和准確,學習是一個逐步深入的過程,很多時候我們會發現,過一段後,我們會對同一個東西有不一樣的理解。

『肆』 以太坊 cd go-ethereum 、make geth超時問題

解決https://proxy.golang.org/github.com 報443 超時問題

make geth

go: github.com/Azure/[email protected]: Get "https://proxy.golang.org/github.com/%21azure/azure-storage-blob-go/@v/v0.7.0.mod": dial tcp 172.217.24.17:443: i/o timeout

make: *** [geth] Error 1

替換一個國內的代理地址

終端命令執行:

go env -w GOPROXY=https://goproxy.cn

重新執行make geth 

『伍』 以太坊源碼go-ethereum怎麼運行

以太幣(ETH)是以太坊(Ethereum)的一種數字代幣,開發者們需要支付以太幣(ETH)來支撐應用的運行。以太幣和其他數字貨幣一樣,可以在交易平台上進行買賣。
通俗一點說,以太坊是開源平台數字貨幣和區塊鏈平台,它為開發者提供在區塊鏈上搭建...

『陸』 以太坊之賬戶

外部賬戶創建流程:

當使用 geth account new 命令新建賬戶,最終調用 accountCreate(accountcmd.go)=>keystore.StoreKey=>storeNewKey(key.go)

storeNewKey完成私鑰、公鑰、地址的生產,最後保存成keystore文件到指定路徑。

最後保存的keystore文件為json格式,如下:

以下為用密碼可以推出私鑰的流程

對交易發起人的地址和nonce進行RLP編碼,再算出Keccak哈希值,取後20個位元組作為該合約的地址,即: Keccak-256(RLP(sender, nonce))[12:]
函數位於: crypto/crypto.go

賬戶在區塊鏈上的存儲結構,內外賬戶的結構都是一樣

文章github地址

『柒』 以太坊GasLimit的計算方法

以太坊黃皮書上說的gasLimit的計算方法:

gasLimit = Gtransaction + Gtxdatanonzero × dataByteLength

需要注意的是這只是靜態的gas消耗,實際gas消耗還需要加上合約執行的開銷。

計算 IntrinsicGas的源碼位置 core/state_transition.go

相關源碼位置:internal/ethapi/api.go

EstimateGas 採用二分查找法獲取要評估交易的gas值。二分查找的下限是 param.TxGas , 如果 args 參數指定 Gas 大於 param.Gas ,那麼二分查找的上限就是 args.Gas ,否則以當前pending塊的block gas limit(後面簡稱BGL)作為二分查找的上限。 doCall 函數模擬智能合約的執行,經過多次嘗試找到智能合約能夠成功運行的最佳gas值。

由於二分查找的上限和BGL有關,而BGL和不是固定不變的,因此每次gas評估的結果不一定都是相同的,可能每個區塊周期就會變動一次。

在實際進行gas評估的時候,可能會出現類似下面的錯誤

該錯誤出現的最可能是合約執行中出錯。

How do you calculate gas limit for transaction with data in Ethereum?

『捌』 用Go來做以太坊開發④智能合約

在這個章節中我們會介紹如何用Go來編譯,部署,寫入和讀取智能合約。

與智能合約交互,我們要先生成相應智能合約的應用二進制介面ABI(application binary interface),並把ABI編譯成我們可以在Go應用中調用的格式。

第一步是安裝 Solidity編譯器 ( solc ).

Solc 在Ubuntu上有snapcraft包。

Solc在macOS上有Homebrew的包。

其他的平台或者從源碼編譯的教程請查閱官方solidity文檔 install guide .

我們還得安裝一個叫 abigen 的工具,來從solidity智能合約生成ABI。

假設您已經在計算機上設置了Go,只需運行以下命令即可安裝 abigen 工具。

我們將創建一個簡單的智能合約來測試。 學習更復雜的智能合約,或者智能合約的開發的內容則超出了本書的范圍。 我強烈建議您查看 truffle framework 來學習開發和測試智能合約。

這里只是一個簡單的合約,就是一個鍵/值存儲,只有一個外部方法來設置任何人的鍵/值對。 我們還在設置值後添加了要發出的事件。

雖然這個智能合約很簡單,但它將適用於這個例子。

現在我們可以從一個solidity文件生成ABI。

它會將其寫入名為「Store_sol_Store.abi」的文件中

現在讓我們用 abigen 將ABI轉換為我們可以導入的Go文件。 這個新文件將包含我們可以用來與Go應用程序中的智能合約進行交互的所有可用方法。

為了從Go部署智能合約,我們還需要將solidity智能合約編譯為EVM位元組碼。 EVM位元組碼將在事務的數據欄位中發送。 在Go文件上生成部署方法需要bin文件。

現在我們編譯Go合約文件,其中包括deploy方法,因為我們包含了bin文件。

在接下來的課程中,我們將學習如何部署智能合約,然後與之交互。

Commands

Store.sol

solc version used for these examples

如果你還沒看之前的章節,請先學習 編譯智能合約的章節 因為這節內容,需要先了解如何將智能合約編譯為Go文件。

假設你已經導入從 abigen 生成的新創建的Go包文件,並設置ethclient,載入您的私鑰,下一步是創建一個有配置密匙的交易發送器(tansactor)。 首先從go-ethereum導入 accounts/abi/bind 包,然後調用傳入私鑰的 NewKeyedTransactor 。 然後設置通常的屬性,如nonce,燃氣價格,燃氣上線限制和ETH值。

如果你還記得上個章節的內容, 我們創建了一個非常簡單的「Store」合約,用於設置和存儲鍵/值對。 生成的Go合約文件提供了部署方法。 部署方法名稱始終以單詞 Deploy 開頭,後跟合約名稱,在本例中為 Store 。

deploy函數接受有密匙的事務處理器,ethclient,以及智能合約構造函數可能接受的任何輸入參數。我們測試的智能合約接受一個版本號的字元串參數。 此函數將返回新部署的合約地址,事務對象,我們可以交互的合約實例,還有錯誤(如果有)。

就這么簡單:)你可以用事務哈希來在Etherscan上查詢合約的部署狀態: https://rinkeby.etherscan.io/tx/

Commands

Store.sol

contract_deploy.go

solc version used for these examples

這寫章節需要了解如何將智能合約的ABI編譯成Go的合約文件。如果你還沒看, 前先讀 上一個章節 。

一旦使用 abigen 工具將智能合約的ABI編譯為Go包,下一步就是調用「New」方法,其格式為「New<contractname style="box-sizing: border-box; font-size: 16px; -ms-text-size-adjust: auto; -webkit-tap-highlight-color: transparent;">」,所以在我們的例子中如果你 回想一下它將是 NewStore 。 此初始化方法接收智能合約的地址,並返回可以開始與之交互的合約實例。</contractname>

Commands

Store.sol

contract_load.go

solc version used for these examples

這寫章節需要了解如何將智能合約的ABI編譯成Go的合約文件。如果你還沒看, 前先讀 上一個章節 。

在上個章節我們學習了如何在Go應用程序中初始化合約實例。 現在我們將使用新合約實例提供的方法來閱讀智能合約。 如果你還記得我們在部署過程中設置的合約中有一個名為 version 的全局變數。 因為它是公開的,這意味著它們將成為我們自動創建的getter函數。 常量和view函數也接受 bind.CallOpts 作為第一個參數。了解可用的具體選項要看相應類的 文檔 一般情況下我們可以用 nil 。

Commands

Store.sol

contract_read.go

solc version used for these examples

這寫章節需要了解如何將智能合約的ABI編譯成Go的合約文件。如果你還沒看, 前先讀 上一個章節 。

寫入智能合約需要我們用私鑰來對交易事務進行簽名。

我們還需要先查到nonce和燃氣價格。

接下來,我們創建一個新的keyed transactor,它接收私鑰。

然後我們需要設置keyed transactor的標准交易選項。

現在我們載入一個智能合約的實例。如果你還記得 上個章節 我們創建一個名為 Store 的合約,並使用 abigen 工具生成一個Go文件。 要初始化它,我們只需調用合約包的 New 方法,並提供智能合約地址和ethclient,它返回我們可以使用的合約實例。

我們創建的智能合約有一個名為 SetItem 的外部方法,它接受solidity「bytes32」格式的兩個參數(key,value)。 這意味著Go合約包要求我們傳遞一個長度為32個位元組的位元組數組。 調用 SetItem 方法需要我們傳遞我們之前創建的 auth 對象(keyed transactor)。 在幕後,此方法將使用它的參數對此函數調用進行編碼,將其設置為事務的 data 屬性,並使用私鑰對其進行簽名。 結果將是一個已簽名的事務對象。

現在我就可以看到交易已經成功被發送到了以太坊網路了: https://rinkeby.etherscan.io/tx/

要驗證鍵/值是否已設置,我們可以讀取智能合約中的值。

搞定!

Commands

Store.sol

contract_write.go

solc version used for these examples

有時您需要讀取已部署的智能合約的位元組碼。 由於所有智能合約位元組碼都存在於區塊鏈中,因此我們可以輕松獲取它。

首先設置客戶端和要讀取的位元組碼的智能合約地址。

現在你需要調用客戶端的 codeAt 方法。 codeAt 方法接受智能合約地址和可選的塊編號,並以位元組格式返回位元組碼。

你也可以在etherscan上查詢16進制格式的位元組碼 https://rinkeby.etherscan.io/address/#code

contract_bytecode.go

首先創建一個ERC20智能合約interface。 這只是與您可以調用的函數的函數定義的契約。

然後將interface智能合約編譯為JSON ABI,並使用 abigen 從ABI創建Go包。

假設我們已經像往常一樣設置了以太坊客戶端,我們現在可以將新的 token 包導入我們的應用程序並實例化它。這個例子里我們用 Golem 代幣的地址.

我們現在可以調用任何ERC20的方法。 例如,我們可以查詢用戶的代幣余額。

我們還可以讀ERC20智能合約的公共變數。

我們可以做一些簡單的數學運算將余額轉換為可讀的十進制格式。

同樣的信息也可以在etherscan上查詢: https://etherscan.io/token/?a=

Commands

erc20.sol

contract_read_erc20.go

solc version used for these examples

『玖』 【深度知識】以太坊數據序列化RLP編碼/解碼原理

RLP(Recursive Length Prefix),中文翻譯過來叫遞歸長度前綴編碼,它是以太坊序列化所採用的編碼方式。RLP主要用於以太坊中數據的網路傳輸和持久化存儲。

對象序列化方法有很多種,常見的像JSON編碼,但是JSON有個明顯的缺點:編碼結果比較大。例如有如下的結構:

變數s序列化的結果是{"name":"icattlecoder","sex":"male"},字元串長度35,實際有效數據是icattlecoder 和male,共計16個位元組,我們可以看到JSON的序列化時引入了太多的冗餘信息。假設以太坊採用JSON來序列化,那麼本來50GB的區塊鏈可能現在就要100GB,當然實際沒這么簡單。

所以,以太坊需要設計一種結果更小的編碼方法。

RLP編碼的定義只處理兩類數據:一類是字元串(例如位元組數組),一類是列表。字元串指的是一串二進制數據,列表是一個嵌套遞歸的結構,裡面可以包含字元串和列表,例如["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]就是一個復雜的列表。其他類型的數據需要轉成以上的兩類,轉換的規則不是RLP編碼定義的,可以根據自己的規則轉換,例如struct可以轉成列表,int可以轉成二進制(屬於字元串一類),以太坊中整數都以大端形式存儲。

從RLP編碼的名字可以看出它的特點:一個是遞歸,被編碼的數據是遞歸的結構,編碼演算法也是遞歸進行處理的;二是長度前綴,也就是RLP編碼都帶有一個前綴,這個前綴是跟被編碼數據的長度相關的,從下面的編碼規則中可以看出這一點。

對於值在[0, 127]之間的單個位元組,其編碼是其本身。

例1:a的編碼是97。

如果byte數組長度l <= 55,編碼的結果是數組本身,再加上128+l作為前綴。

例2:空字元串編碼是128,即128 = 128 + 0。

例3:abc編碼結果是131 97 98 99,其中131=128+len("abc"),97 98 99依次是a b c。

如果數組長度大於55, 編碼結果第一個是183加數組長度的編碼的長度,然後是數組長度的本身的編碼,最後是byte數組的編碼。

請把上面的規則多讀幾篇,特別是數組長度的編碼的長度。

例4:編碼下面這段字元串:

The length of this sentence is more than 55 bytes, I know it because I pre-designed it
這段字元串共86個位元組,而86的編碼只需要一個位元組,那就是它自己,因此,編碼的結果如下:

184 86 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116
其中前三個位元組的計算方式如下:

184 = 183 + 1,因為數組長度86編碼後僅佔用一個位元組。
86即數組長度86
84是T的編碼
例5:編碼一個重復1024次"a"的字元串,其結果為:185 4 0 97 97 97 97 97 97 ...。
1024按 big endian編碼為004 0,省略掉前面的零,長度為2,因此185 = 183 + 2。

規則1~3定義了byte數組的編碼方案,下面介紹列表的編碼規則。在此之前,我們先定義列表長度是指子列表編碼後的長度之和。

如果列表長度小於55,編碼結果第一位是192加列表長度的編碼的長度,然後依次連接各子列表的編碼。

注意規則4本身是遞歸定義的。
例6:["abc", "def"]的編碼結果是200 131 97 98 99 131 100 101 102。
其中abc的編碼為131 97 98 99,def的編碼為131 100 101 102。兩個子字元串的編碼後總長度是8,因此編碼結果第一位計算得出:192 + 8 = 200。

如果列表長度超過55,編碼結果第一位是247加列表長度的編碼長度,然後是列表長度本身的編碼,最後依次連接各子列表的編碼。

規則5本身也是遞歸定義的,和規則3相似。

例7:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]
的編碼結果是:

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116
其中前兩個位元組的計算方式如下:

248 = 247 +1
88 = 86 + 2,在規則3的示例中,長度為86,而在此例中,由於有兩個子字元串,每個子字元串本身的長度的編碼各佔1位元組,因此總共佔2位元組。
第3個位元組179依據規則2得出179 = 128 + 51
第55個位元組163同樣依據規則2得出163 = 128 + 35

例8:最後我們再來看個稍復雜點的例子以加深理解遞歸長度前綴,

["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]
編碼結果是:

248 94 131 97 98 99 248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116
列表第一項字元串abc根據規則2,編碼結果為131 97 98 99,長度為4。
列表第二項也是一個列表項:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]
根據規則5,結果為

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116
長度為90,因此,整個列表的編碼結果第二位是90 + 4 = 94, 佔用1個位元組,第一位247 + 1 = 248

以上5條就是RPL的全部編碼規則。

各語言在具體實現RLP編碼時,首先需要將對像映射成byte數組或列表兩種形式。以go語言編碼struct為例,會將其映射為列表,例如Student這個對象處理成列表["icattlecoder","male"]

如果編碼map類型,可以採用以下列表形式:

[["",""],["",""],["",""]]

解碼時,首先根據編碼結果第一個位元組f的大小,執行以下的規則判斷:

1.如果f∈ [0,128),那麼它是一個位元組本身。

2.如果f∈[128,184),那麼它是一個長度不超過55的byte數組,數組的長度為 l=f-128

3.如果f∈[184,192),那麼它是一個長度超過55的數組,長度本身的編碼長度ll=f-183,然後從第二個位元組開始讀取長度為ll的bytes,按照BigEndian編碼成整數l,l即為數組的長度。

4.如果f∈(192,247],那麼它是一個編碼後總長度不超過55的列表,列表長度為l=f-192。遞歸使用規則1~4進行解碼。

5.如果f∈(247,256],那麼它是編碼後長度大於55的列表,其長度本身的編碼長度ll=f-247,然後從第二個位元組讀取長度為ll的bytes,按BigEndian編碼成整數l,l即為子列表長度。然後遞歸根據解碼規則進行解碼。

以上解釋了什麼叫遞歸長度前綴編碼,這個名字本身很好的解釋了編碼規則。

(1) 以太坊源碼學習—RLP編碼( https://segmentfault.com/a/1190000011763339 )
(2)簡單分析RLP編碼原理
( https://blog.csdn.net/itchosen/article/details/78183991 )

熱點內容
安妮股份為何是區塊鏈 發布:2024-11-19 13:20:34 瀏覽:804
trx智能合約鏈怎麼樣 發布:2024-11-19 13:20:27 瀏覽:543
幣圈二爺發話視頻 發布:2024-11-19 13:18:05 瀏覽:878
區塊鏈銷售和運營哪個有前景 發布:2024-11-19 13:17:15 瀏覽:918
比特幣的中國創始人是誰 發布:2024-11-19 13:11:07 瀏覽:611
區塊鏈技術力助大健康事業 發布:2024-11-19 12:53:20 瀏覽:217
區塊鏈怎麼解決的拜占庭問題 發布:2024-11-19 12:52:31 瀏覽:474
2018年區塊鏈粉絲經濟 發布:2024-11-19 12:40:44 瀏覽:65
預防比特幣補丁 發布:2024-11-19 12:39:03 瀏覽:895
比特處分叉幣是什麼意思 發布:2024-11-19 12:32:27 瀏覽:9