ethgetblock
轉自: https://zhuanlan.hu.com/p/23558268
getblocktemplate協議誕生於2012年中葉,此時礦池已經出現。礦池採用getblocktemplate協議與節點客戶端交互,採用stratum協議與礦工交互,這是最典型的礦池搭建模式。
與getwork相比,getblocktemplate協議最大的不同點是:getblocktemplate協議讓礦工自行構造區塊。如此一來,節點和挖礦完全分離。對於getwork來說,區塊鏈是黑暗的,getwork對區塊鏈一無所知,他只知道修改data欄位的4個位元組。對於getblocktemplate來說,整個區塊鏈是透明的,getblocktemplate掌握區塊鏈上與挖礦有關的所有信息,包括待確認交易池,getblocktemplate可以自己選擇包含進區塊的交易。
挖礦有兩種方式,一種叫SOLO挖礦,另一種是去礦池挖礦。前文所述的在節點客戶端直接啟動CPU挖礦,以及依靠getwork+cgminer驅動顯卡直接連接節點客戶端挖礦,都是SOLO挖礦,SOLO好比自己獨資買彩票,不輕易中獎,中獎則收益全部歸自己所有。去礦池挖礦好比合買彩票,大家一起出錢,能買一堆彩票,中獎後按出資比率分配收益。理論上,礦機可以藉助getblocktemplate協議鏈接節點客戶端SOLO挖礦,但其實早已沒有礦工會那麼做,在寫這篇文章時,比特幣全網算力1600P+,而當前最先進的礦機算力10T左右,如此算來,單台礦機SOLO挖到一個塊的概率不到16萬分之一,礦工(人)投入真金白銀購買礦機、交付電費,不會做風險那麼高的投資,顯然投入礦池抱團挖礦以降低風險,獲得穩定收益更加適合。因此礦池的出現是必然,也不可消除,無論是否破壞系統的去中心化原則。
礦池的核心工作是給礦工分配任務,統計工作量並分發收益。礦池將區塊難度分成很多難度更小的任務下發給礦工計算,礦工完成一個任務後將工作量提交給礦池,叫提交一個share。假如全網區塊難度要求Hash運算結果的前70個比特位都是0,那麼礦池給礦工分配的任務可能只要求前30位是0(根據礦工算力調節),礦工完成指定難度任務後上交share,礦池再檢測在滿足前30位為0的基礎上,看看是否碰巧前70位都是0。
礦池會根據每個礦工的算力情況分配不同難度的任務,礦池是如何判斷礦工算力大小以分配合適的任務難度呢?調節思路和比特幣區塊難度一樣,礦池需要藉助礦工的share率,礦池希望給每個礦工分配的任務都足夠讓礦工運算一定時間,比如說1秒,如果礦工在一秒之內完成了幾次任務,說明礦池當前給到的難度低了,需要調高,反之。如此下來,經過一段時間調節,礦池能給礦工分配合理難度,並計算出礦工的算力。
礦池通過getblocktemplate協議與網路節點交互,以獲得區塊鏈的最新信息,通過stratum協議與礦工交互。此外,為了讓之前用getwork協議挖礦的軟體也可以連接到礦池挖礦,礦池一般也支持getwork協議,通過階層挖礦代理機制實現(Stratum mining proxy)。須知在礦池剛出現時,顯卡挖礦還是主力,getwork用起來非常方便,另外早期的FPGA礦機有些是用getwork實現的,stratum與礦池採用TCP方式通信,數據使用JSON封裝格式。
先來說一下getblocktemplate遺留下來的幾個問題:
礦工驅動:在getblocktemplate協議里,依然是由礦工主動通過HTTP方式調用RPC介面向節點申請挖礦數據,這就意味著,網路最新區塊的變動無法及時告知礦工,造成算力損失。
數據負載:如上所述,如今正常的一次getblocktemplate調用節點都會反饋回1.5M左右的數據,其中主要數據是交易列表,礦工與礦池需頻繁交互數據,顯然不能每次分配工作都要給礦工附帶那麼多信息。再者巨大的內存需求將大大影響礦機性能,增加成本。
Stratum協議徹底解決了以上問題。
Stratum協議採用主動分配任務的方式,也就是說,礦池任何時候都可以給礦工指派新任務,對於礦工來說,如果收到礦池指派的新任務,應立即無條件轉向新任務;礦工也可以主動跟礦池申請新任務。
現在最核心的問題是如何讓礦工獲得更大的搜索空間,如果參照getwork協議,僅僅給礦工可以改變nNonce和nTime欄位,則交互的數據量很少,但這點搜索空間肯定是不夠的。想增加搜索空間,只能在hashMerkleroot下功夫,如果讓礦工自己構造coinbase,那麼搜索空間的問題將迎刃而解,但代價是必要要把區塊包含的所有交易都交給礦工,礦工才能構造交易列表的Merkleroot,這對於礦工來說壓力更大,對於礦池帶寬要求也更高。
Stratum協議巧妙解決了這個問題,成功實現既可以給礦工增加足夠的搜索空間,又只需要交互很少的數據量,這也是Stratum協議最具創新的地方。
再來回顧一下區塊頭的6個欄位80位元組,這個很關鍵,nVersion,nBits,hashPrevBlock這3個欄位是固定的,nNonce,nTime這兩個欄位是礦工現在就可以改變的。增加搜索空間只能從hashMerkleroot下手,這個繞不過去。Stratum協議讓礦工自己構造coinbase交易,coinbase的scriptSig欄位有很多位元組可以讓礦工自由填充,而coinbase的改動意味著hashMerkleroot的改變。從coinbase構造hashMerkleroot無需全部交易,
如上圖所示,假如區塊將包含13筆交易,礦池先對這13筆交易進行處理,最後只要把圖中的4個黑點(Hash值)交付給礦工,同時將構造coinbase需要的信息交付給礦工,礦工就可以自己構造hashMerkleroot(圖中的綠點都是礦工自行計算獲得,兩兩合並Hash時,規定下一個黑點代表的hash值總是放在右邊)
。按照這種方式,假如區塊包含N筆交易,礦池可以濃縮成log2(N)個hash值交付給礦工,這大大降低了礦池和礦工交互的數據量。
Stratum協議嚴格規定了礦工和礦池交互的介面數據結構和交互邏輯,具體如下:
1. 礦工訂閱任務
啟動挖礦機器,使用mining.subscribe方法鏈接礦池
返回數據很重要,礦工需本地記錄,在整個挖礦過程中都用到,其中:
Extranonce1,和 Extranonce2對於挖礦很重要,增加的搜索空間就在這里,現在,我們至少有了8個位元組的搜索空間,即nNonce的4個位元組,以及 Extranonce2的4個位元組。
2. 礦池授權
在礦池注冊一個賬號 ,添加礦工,礦池允許每個賬號任意添加礦工數,並取不同名字以區分。礦工使用mining.authorize方法申請授權,只有被礦池授權的礦工才能收到礦池指派任務。
3. 礦池分配任務
以上每個欄位信息都是必不可少,其中:
有了以上信息,再加上之前拿到的Extranonce1 和Extranonce2_size,就可以挖礦了。
4. 挖礦
1) 構造coinbase交易
用到的信息包括Coinb1, Extranonce1, Extranonce2_size 以及Coinb2,構造很簡單:
為啥可以這樣,因為礦池幫礦工做了很多工作,礦池已經構建了coinbase交易,系列化後在指定位置分割成coinb1和coinb2,coinb1和coinb2包含指定信息,比如coinb1包含區塊高度,coinb2包含了礦工的收益地址和收益額等信息,但是這些信息對於礦工來說無關緊要,礦工挖礦的地方只是Extranonce2 的4個位元組。另外Extranonce1是礦池寫入區塊的指定信息,一般來說,每個礦池會寫入自己礦池的信息,比如礦池名字或者域名,我們就是根據這個信息統計每個礦池在全網的算力比重。
2) 構建Merkleroot
利用coinbase和merkle_branch,按照上圖方式構造hashMerkleroot欄位。
3) 構建區塊頭
填充餘下的5個欄位,現在,礦池可以在nNonce和Extranonce2 里搜索進行挖礦,如果嫌搜索空間還不夠,只要增加Extranonce2_size為多幾個位元組就可輕而易舉解決。
5. 礦工提交工作量
當礦工找到一個符合難度的shares時,提交給礦池,提交的信息量很少,都是必不可少的欄位:
礦池拿到以上5個欄位後,首先根據任務號ID找出之前分配任務前存儲的信息(主要是構建的coinbase交易以及包含的交易列表等),然後重構區塊,再驗證shares難度,對於符合難度要求的shares,再檢測是否符合全網難度。
6. 礦池給礦工調節難度
礦池記錄每個礦工的難度,並根據shares率不斷調節以指定合適難度。礦池可以隨時通過mining.set_difficulty方法給礦工發消息另其改變難度。
如上,Stratum協議核心理念基本解析清楚,在getblocktemplate協議和Stratum協議的配合下,礦池終於可以大聲的對礦工說,讓算力來的更猛烈些吧。
2. eth是什麼意思
eth的意思是以太坊。
eth是英文Ethereum的縮寫,意思是以太坊,它是一個開源的有智能合約功能的公共區塊鏈平台,通過其專用加密貨幣以太幣提供去中心化的以太虛擬機來處理點對點合約。
相關短語
1、Enterprise Ethereum Alliance:企業以太坊聯盟,企業以太坊同盟,太坊區塊鏈聯盟。
2、Ethereum Foundation:以太坊基金會。
3、Ethereum Classic:以太坊經典,以太經典,以太坊原鏈,古典以太坊。
4、Enterprise Ethereum:企業以太坊,以太坊企業。
5、Ethereum virtual machine:以太坊虛擬機。
6、Decentral and Ethereum:加拿大。
7、Ethereum Island:以太坊島。
8、Ethereum Classi:以太坊經典。
9、Ethereum blockchain alliance:以太坊區塊鏈聯盟。
3. Chainge技術沙龍(0414)-區塊鏈技術的安全隱患
虛擬機設計
零錢整理
慢霧科技介紹
01| The Dao事件
以太坊第一個安全大事件
智能合約的取款
新建一個Bank,存入一部分錢,用Dao框架不停取錢。
取款-判斷余額-取款操作框架-轉空該賬戶下的所有錢。
簡單的例子就是,你的銀行卡有餘額100萬,你需要買一個10塊錢的飲料,但是支付的過程有漏洞,所以你銀行卡的所有錢都被轉走。
一、外部調用
02| 以太坊黑色情人節
起源:第一轉賬時間是2.14
ETH節點統計
客戶端、客戶端版本、OS系統。整個系統的龐雜
蜜罐檢測 (部署陷阱能檢測出黑客的點來)
net_version
判斷是主網還是測試網,只攻擊主網
3000+主網節點完全暴露
eth_accounts
獲取錢包賬號,涉及錢包賬號
eth_getBanlance
獲取有多少錢,被盜46000+ETH
why?
unlockAccount 函數介紹
該函數將使用密碼從本地的keystore 里提取private key 並存儲在內存中,函數第三個參數ration 表示解密後private key 在內存中保存默認是300 秒; 如果設置為0,則表的時間,示永久存留在內存,直至Geth/Parity 退出。
詳見:
https://github.com/ethereumgethereum/wiki/Management-APIs#personal_unlockaccount
節點存用戶的keystore信息(嚴重危險)
eth_getBlockByNumber
墨子掃描引擎,掃描有問題的節點,慢霧的以太坊安全事件的披露
被盜ETH,市值,被盜錢包數
具體內容可以查看慢霧發布的 以太坊黑色情人節專題
生態相關
ETH:礦池、錢包、web3、smart contract、dapp
BTC:礦池、錢包、Lightning Network
BTC RPC
防禦建議
管理數十萬用戶安全的接近百萬的比特幣
華人世界唯一被bitcoin.org網站展示的錢包
比特派多種區塊鏈資產(BTC、ETH、Token、分叉)
冷熱結合,確保安全
比特派-熱錢包
比特護盾-冷錢包/硬體錢包
區塊鏈安全事件
私鑰決定了區塊鏈資產的所有權,丟了私鑰也就相當於丟了一切。私鑰就是一個隨機數,這個隨機數的概率空間很大(256 位,即2^256)
錢包=生態入口
需要在安全的同時做到盡可能的開放
玩法的開放,技術的開放,通用的技術介面,生態的開放,把自己的資源進行導入。合作夥伴計劃:技術咨詢、區塊鏈技術支持、開放平台、入口支持、生態支持、海外市場合作。幫助夥伴實現區塊鏈轉型或區塊鏈項目孵化,安全、便捷實現真正落地的區塊鏈應用場景。
聯系方式 [email protected]
用戶風控系統,數百萬的數字貨幣用戶。
最大可能保持我們的數字資產
騙子故事:搶數字貨幣份額,錢沒到賬,冒充官方,交出助記詞
惡意錢包地址庫
詐騙錢包、黑客錢包、羊毛黨錢包
惡意網站庫
釣魚網站、空投網站、交易所、眾籌
風險合約庫
重名幣、空格幣、風險合約
安全事件庫
歷史安全事件提醒
最新事件提醒
盜幣風險監控
安全意識教育
可能出現被盜的情況
游戲即資產,稀缺資源,成為游戲運營者。最後大BOSS死於暴露了自己的密鑰。
通過社工(社會工程學)【欺騙的藝術】黑客攻擊手法,虛擬景象做出錯誤判斷讓自己陷入危機。
人始終是系統中最薄弱的環節,幣安背鍋的黑客事件。大客戶泄露自己的賬戶,調用API介面,自動交易。雖然沒丟幣但是黑客在期貨市場盈利。
關於安全錢包的帖子(來自小白憤怒控訴,實際沒有理解整個機制):
1、我沒私鑰和交易密碼,東西都在你們那我不知道安全在哪裡
2、密語算個毛,你告訴我拿著你們的密語能做什麼。
汽車和自行車事件,出了問題之後,弱勢的一方被原諒。負責的是更大的一方。平台替沒有安全意識的用戶背鍋。
對於大部分用戶來說,交易所的安全性比普通用戶自己管理的安全性要高,用戶的安全意識沒有提高,交給交易所幫助、協助你來管理你的錢包提示很多風險操作。
為什麼要隨機生成256位的密鑰,為什麼不能用戶自己去設置,如果自己設置會處於一個集中的區域,隨機值不夠,私鑰生成時就處於危險的狀態。
自己的安全認識不夠,所以自己造成的損失,先懟交易所先懟錢包。先想到得是你們的問題和漏洞造成的,不是我的操作失誤和密鑰泄露造成的。
幣派做的是大神和小白的交流之間的翻譯,做畫漫畫,寫段子的逗比。
幣小寶防騙指南漫畫,貢獻題材和內容。
4. 以太坊多節點私有鏈部署
假設兩台電腦A和B
要求:
1、兩台電腦要在一個網路中,能ping通
2、兩個節點使用相同的創世區塊文件
3、禁用ipc;同時使用參數--nodiscover
4、networkid要相同,埠號可以不同
1.4 搭建私有鏈
1.4.1 創建目錄和genesis.json文件
創建私有鏈根目錄./testnet
創建數據存儲目錄./testnet/data0
創建創世區塊配置文件./testnet/genesis.json
1.4.2 初始化操作
cd ./eth_test
geth --datadir data0 init genesis.json
1.4.3 啟動私有節點
1.4.4 創建賬號
personal.newAccount()
1.4.5 查看賬號
eth.accounts
1.4.6 查看賬號余額
eth.getBalance(eth.accounts[0])
1.4.7 啟動&停止挖礦
啟動挖礦:
miner.start(1)
其中 start 的參數表示挖礦使用的線程數。第一次啟動挖礦會先生成挖礦所需的 DAG 文件,這個過程有點慢,等進度達到 100% 後,就會開始挖礦,此時屏幕會被挖礦信息刷屏。
停止挖礦,在 console 中輸入:
miner.stop()
挖到一個區塊會獎勵5個以太幣,挖礦所得的獎勵會進入礦工的賬戶,這個賬戶叫做 coinbase,默認情況下 coinbase 是本地賬戶中的第一個賬戶,可以通過 miner.setEtherbase() 將其他賬戶設置成 coinbase。
1.4.8 轉賬
目前,賬戶 0 已經挖到了 3 個塊的獎勵,賬戶 1 的余額還是0:
我們要從賬戶 0 向賬戶 1 轉賬,所以要先解鎖賬戶 0,才能發起交易:
發送交易,賬戶 0 -> 賬戶 1:
需要輸入密碼 123456
此時如果沒有挖礦,用 txpool.status 命令可以看到本地交易池中有一個待確認的交易,可以使用 eth.getBlock("pending", true).transactions 查看當前待確認交易。
使用 miner.start() 命令開始挖礦:
miner.start(1);admin.sleepBlocks(1);miner.stop();
新區塊挖出後,挖礦結束,查看賬戶 1 的余額,已經收到了賬戶 0 的以太幣:
web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
用同樣的genesis.json初始化操作
cd ./eth_test
geth --datadir data1 init genesis.json
啟動私有節點一,修改 rpcport 和port
可以通過 admin.addPeer() 方法連接到其他節點,兩個節點要要指定相同的 chainID。
假設有兩個節點:節點一和節點二,chainID 都是 1024,通過下面的步驟就可以從節點二連接到節點一。
首先要知道節點一的 enode 信息,在節點一的 JavaScript console 中執行下面的命令查看 enode 信息:
admin.nodeInfo.enode
" enode://@[::]:30303 "
然後在節點二的 JavaScript console 中執行 admin.addPeer(),就可以連接到節點一:
addPeer() 的參數就是節點一的 enode 信息,注意要把 enode 中的 [::] 替換成節點一的 IP 地址。連接成功後,節點一就會開始同步節點二的區塊,同步完成後,任意一個節點開始挖礦,另一個節點會自動同步區塊,向任意一個節點發送交易,另一個節點也會收到該筆交易。
通過 admin.peers 可以查看連接到的其他節點信息,通過 net.peerCount 可以查看已連接到的節點數量。
除了上面的方法,也可以在啟動節點的時候指定 --bootnodes 選項連接到其他節點。 bootnode 是一個輕量級的引導節點,方便聯盟鏈的搭建 下一節講 通過 bootnode 自動找到節點
參考: https://cloud.tencent.com/developer/article/1332424
5. Entrynamenotfound
報錯。
在調用queryBlockByNumber()方法時,向peer發送一個proposal,調用fabric的系統鏈碼qscc,從下面的錯誤描述看出,由於鏈碼執行出現錯誤,因此報了代碼為500的錯。
相對應的,peer端也有相應的錯誤日誌列印,如下所示,即peer模擬執行交易失敗。
查詢流程分析
查詢的流程涉及到SDK端、Peer端以及peer上運行的系統鏈碼,下面進行分析:
SDK端
程序調用Channel對象的queryBlockByNumber()方法;
Channel對象創建QuerySCCRequest請求,設置Fcb為GetBlockByNumber,設置Args為通道的名字和區塊號;
調用sendProposal方法將請求發給peer(通過Endorser對象的ProcessProposal方法進行grpc調用)。
Peer端
core/endoser/endorser.go文件中的ProcessProposal方法處理請求;
對proposal進行一系列預處理;
調用simulateProposal方法模擬執行交易;;
調用callChaincode方法將proposal交給智能合約執行;
調用core/chaincode/chaincodeexec.go中的ExecuteChaincode方法執行交易;
core/chaincode/exectransaction.go中的Execute方法執行交易,如果chaincode沒有運行先調用launch方法啟動chaincode;
然後調用theChaincodeSupport.Execute方法執行交易;
調用handler.sendExecuteMessage方法把proposal發給chaincode實例進行執行,由於是QueryScc請求,所以發給qscc合約進行執行。
Peer端的qscc系統鏈碼
core/scc/qscc/qscc.go根據fcn的名字調用GetBlockByNumber方法進行執行;
調用core/ledger包中的GetBlockByNumber介面從賬本中獲取區塊;
調用core/ledger/kvledger包中的kvLedger對象的GetBlockByNumber方法,從kv賬本中獲取區塊;
調用common/ledger/blkstorage包中BlockStore對象的RetrieveBlockByNumber方法從區塊存儲中獲取區塊;
調用common/ledger/blkstorage/fsblkstorage包中的fsBlockStore對象的RetrieveBlockByNumber方法;
調用common/ledger/blkstorage/fsblkstorage包中的blockfileMgr對象的retrieveBlockByNumber方法;
調用common/ledger/blkstorage/fsblkstorage包中的index介面中的getBlockLocByBlockNum方法從leveldb的index中獲取區塊位置。由於從index中獲取區塊不存在,所以返回Entrynotfoundinindex錯誤。
6. Android,getBlockSize() 過時了用哪個方法獲取磁碟大小
在API level 18中已經使用getBlockSizeLong () 來代替getBlockSize ()這個方法了。
但是需要注意的是,getBlockSizeLong ()這個方法在API level 18版本之前是沒有的,如果開發的應用需要兼容18版本以前的系統,最好還是使用getBlockSize()方法。
7. Web3py簡單使用方法(三)
一.Web3py的一些使用的例子:
1.查詢區塊:
···
web3.eth.getBlock(12345)
web3.eth.getBlock('')
web3.eth.getBlock('latest')
web3.eth.blockNumber
二.web3py還提供幾個詳細模塊的api,具體可上文檔查詢。
1.Web3.eth : http://web3py.readthedocs.io/en/latest/web3.eth.html
2.Web3.shh : http://web3py.readthedocs.io/en/latest/web3.shh.html
3.Web3.personal : http://web3py.readthedocs.io/en/latest/web3.personal.html
4.Web3.version : http://web3py.readthedocs.io/en/latest/web3.version.html
5.Web3.txpool : http://web3py.readthedocs.io/en/latest/web3.txpool.html
6.Web3.miner : http://web3py.readthedocs.io/en/latest/web3.miner.html
7.Web3.admin : http://web3py.readthedocs.io/en/latest/web3.admin.html
8. ETH開發實踐——批量發送交易
在使用同一個地址連續發送交易時,每筆交易往往不可能立即到賬, 當前交易還未到賬的情況下,下一筆交易無論是通過 eth.getTransactionCount() 獲取nonce值來設置,還是由節點自動從區塊中查詢,都會獲得和前一筆交易同樣的nonce值,這時節點就會報錯 Error: replacement transaction underpriced
在構建一筆新的交易時,在交易數據結構中會產生一個nonce值, nonce是當前區塊鏈下,發送者(from地址)發出的交易(成功記錄進區塊的)總數, 再加上1。例如新構建一筆從A發往B的交易,A地址之前的交易次數為10,那麼這筆交易中的nonce則會設置成11, 節點驗證通過後則會放入交易池(txPool),並向其他節點廣播,該筆交易等待礦工將其打包進新的區塊。
那麼,如果在先構建並發送了一筆從地址A發出的,nonce為11的交易,在該交易未打包進區塊之前, 再次構建一筆從A發出的交易,並將它發送到節點,不管是先通過web3的eth.getTransactionCount(A)獲取到的過往的交易數量,還是由節點自行填寫nonce, 後面的這筆交易的nonce同樣是11, 此時就出現了問題:
實際場景中,會有批量從一個地址發送交易的需求,首先這些操作可能也應該是並行的,我們不會等待一筆交易成功寫入區塊後再發起第二筆交易,那麼此時有什麼好的解決辦法呢?先來看看geth節點中交易池對交易的處理流程
如之前所說,構建一筆交易時如果不手動設置nonce值,geth節點會默認計算發起地址此前最大nonce數(寫入區塊的才算數),然後將其加上1, 然後將這筆交易放入節點交易池中的pending隊列,等到節點將其打包進區塊。
構建交易時,nonce值是可以手動設置的,如果當前的nonce本應該設置成11, 但是我手動設置成了13, 在節點收到這筆交易時, 發現pending隊列中並沒有改地址下nonce為11及12的交易, 就會將這筆nonce為13的交易放入交易池的queued隊列中。只有當前面的nonce補齊(nonce為11及12的交易被發現並放入pending隊列)之後,才會將它放入pending隊列中等待打包。
我們把pending隊列中的交易視為可執行的,因為它們可能被礦工打包進最新的區塊。 而queue隊列因為前面的nonce存在缺失,暫時無法被礦工打包,稱為不可執行交易。
那麼實際開發中,批量從一個地址發送交易時,應該怎麼辦呢?
方案一:那麼在批量從一個地址發送交易時, 可以持久化一個本地的nonce,構建交易時用本地的nonce去累加,逐一填充到後面的交易。(要注意本地的nonce可能會出現偏差,可能需要定期從區塊中重新獲取nonce,更新至本地)。這個方法也有一定的局限性,適合內部地址(即只有這個服務會使用該地址發送交易)。
說到這里還有個坑,許多人認為通過 eth.getTransactionCount(address, "pending") ,第二個參數為 pending , 就能獲得包含本地交易池pending隊列的nonce值,但是實際情況並不是這樣, 這里的 pending 只包含待放入打包區塊的交易, 假設已寫入交易區塊的數量為20, 又發送了nonce為21,22,23的交易, 通過上面方法取得nonce可能是21(前面的21,22,23均未放入待打包區塊), 也可能是22(前面的21放入待打包區塊了,但是22,23還未放入)。
方案二是每次構建交易時,從geth節點的pending隊列取到最後一筆可執行交易的nonce, 在此基礎上加1,再發送給節點。可以通過 txpool.content 或 txpool.inspect 來獲得交易池列表,裡面可以看到pending及queue的交易列表。
啟動節點時,是可以設置交易池中的每個地址的pending隊列的容量上限,queue隊列的上容量上限, 以及整個交易池的pending隊列和queue隊列的容量上限。所以高並發的批量交易中,需要增加節點的交易池容量。
當然,除了擴大交易池,控制發送頻率,更要設置合理的交易手續費,eth上交易寫入區塊的速度取決於手續費及eth網路的擁堵狀況,發送每筆交易時,設置合理的礦工費用,避免大量的交易積壓在交易池。
9. eth挖礦是什麼原理
凡是涉及到幣,就一定離不開挖礦。以太坊網路中,想要獲得以太坊,也要通過挖礦來實現。說到挖礦,就一定離不開共識機制。
不知道大家還記得比特幣的共識機制是什麼嗎?比特幣的共識機制是 PoW (這是英文 Proof of Work 的縮寫,意思是「工作量證明機制」)。簡單來說,就是多勞多得,你付出的計算工作越高,那麼你就越有可能第一個找到正確的哈希值,就越有可能得到比特幣獎勵。
但是,比特幣的PoW存在著一定的缺陷,就是它處理交易的速度太慢,礦工們需要不斷地通過計算來碰撞哈希值,這是勞民傷財且效率低下的。對區塊鏈知識有涉獵的朋友們應該看到這樣一種說法:
以太坊為了彌補比特幣的不足,提出了新的共識機制,名叫 PoS(這是英文的縮寫,意思是「權益證明」,也有翻譯成「股權證明」的)。
PoS 簡單來講,其實就跟它的字面意思一樣:權益嘛,股權嘛,你持有的幣越多相當於你的股權越多,你的權益越高。
以太坊的PoS就是說:你持幣越多,你持有幣的時間越久,你的計算難度就會降低,挖礦會容易一些。
在以太坊最初的設定中,以太坊希望能夠通過階段性的升級,在前期依舊採用PoW來構建一個相對穩定的系統,之後逐漸採用 PoW+PoS,最後完全過渡到 PoS。所以,說以太坊的共識機制是PoS,沒錯,但是PoS只是以太坊發布之初的一個計劃或者說目標,目前以太坊還沒有過渡到 PoS,以太坊採用的共識機制仍是 PoW,就是比特幣那個 PoW,但是又和比特幣的PoW稍稍不同。
這里的信息量有點大,
第一個信息點是:以太坊目前採用的共識機制也是PoW,但是和比特幣的PoW稍稍不同。那麼,和比特幣的PoW到底有什麼不同呢:簡單來說,就是以太坊挖礦難度可以調節,比特幣挖礦難度不能調節。就好比咱們高考,因為各個省份的教學情況、生源人數都不一樣,所以高考分為全國卷和各省自主命題。
以太坊說我贊成這樣分地區出題,比特幣說:不行,必須全國同一卷,大家難度都一樣!
通俗解釋,就是,比特幣是利用計算機算力做大量的哈希碰撞,列舉出各種可能性,來找到一個正確哈希值。而以太坊系統呢,它有一個特殊的公式用來計算之後的每個塊的難度。如果某個區塊比前一個區塊驗證的更快,以太坊協議就會增加區塊的難度。通過調整區塊難度,就可以調整驗證區塊所需的時間。
以太坊協議規定,難度的動態調整方式是使全網創建新區塊的時間間隔為 15 秒,網路用 15 秒時間創建區塊鏈,這樣一來,因為時間太快,系統的同步性就大大提升,惡意參與者很難在如此短的時間發動51%(也就是半數以上)的算力去修改歷史數據。
第二個信息點是:以太坊最初的設定中,希望通過階段性升級來最終實現由 PoW 向
PoS過渡的。
時間追溯到 2014 年,在以太坊發布之初,團隊宣布將項目的發布分為四個階段,即 Froniter(前沿)、Homestead(家園)、Metropolis(大都會)和 Serenity(寧靜)。前三個階段共識機制採用 PoW(工作量證明機制),第四個階段切換到 PoS(權益證明機制)。
2015年7月30號,以太坊第一個階段「前沿」正式發布,這個階段只適用於開發者使用,開發人員可於在以太坊網路上編寫智能合約和去中心化應用程序 DAPP,礦工開始進入以太坊網路維護網路安全並挖礦得到以太幣。前沿版本類似於測試版,證明以太坊網路到底是不是可靠的。
2016年3月14日,以太坊進入到第二個階段「家園」,這一階段,以太坊提供了錢包功能,讓普通用戶也可以方便體驗和使用以太坊。其他方面沒有什麼明顯的技術提升,只是表明以太坊網路已經可以平穩運行。
2017 年 9 月,以太坊已經進行到第三個階段「大都會」。「大都會」由拜占庭和君士坦丁堡兩次升級組成,這個階段的的目標是希望能夠引入 PoW 和 PoS 的混合鏈模式,為 PoW向PoS的順滑過渡做准備。最近比較熱門的「以太坊君士坦丁堡升級」升級的就是這個,在君士坦丁堡升級中呢,以太坊將對底層協議和演算法做一些改變,來為實現 PoW 和
PoS奠定良好的基礎。
以太坊挖礦會得到對多少獎勵呢?贏得區塊創建競爭成功的礦工會得到這么幾項收入:
1、 靜態獎勵,5個以太坊;
2、 區塊內所花費的燃料成本,也就是Gas,這部分我們上一期內容講過;
3、 作為區塊組成部分,包含「叔區塊」的額外獎勵,叔就是叔叔的叔,每個叔區塊可以得到挖礦報酬的1/32作為獎勵,也就是5乘以1/32,等於0.15625 個以太坊。這里我們簡單解釋一下「叔區塊」,「叔區塊」這個概念是以太坊提出來的,為什麼要引進叔塊的概念?這還要從比特幣說起。在比特幣協議中,最長的鏈被認為是絕對的正確。如果一個塊不是最長鏈的一部分,那麼它被稱為是「孤塊」。一個孤立的塊是一個塊,它也是合法的,但是可能發現的稍晚,或者是網路傳輸稍慢,而沒有能成為最長的鏈的一部分。在比特幣中,孤塊沒有意義,隨後將被拋棄掉,發現這個孤塊的礦工也拿不到采礦相關的獎勵。
但是,以太坊不認為孤塊是沒有價值的,以太坊系統也會給與發現孤塊的礦工回報。在以太坊中,孤塊被稱為「叔塊」(uncle block),它們可以為主鏈的安全作出貢獻。 以太坊十幾秒的出塊間隔太快了,會降低安全性,通過鼓勵引用叔塊,使引用主鏈獲得更多的安全保證(因為孤塊本身也是合法的) ,而且,支付報酬給叔塊,還能激發礦工積極挖礦,積極引用叔塊,所以,以太坊認為,它是有價值的。
10. 【ETH錢包開發03】web3j轉賬ETH
在之前的文章中,講解了創建、導出、導入錢包。
【ETH錢包開發01】創建、導出錢包
【ETH錢包開發02】導入錢包
本文主要講解以太坊轉賬相關的一些知識。交易分為ETH轉賬和ERC-20 Token轉賬,本篇先講一下ETH轉賬。
1、解鎖賬戶發起交易。錢包keyStore文件保存在geth節點上,用戶發起交易需要解鎖賬戶,適用於中心化的交易所。
2、錢包文件離線簽名發起交易。錢包keyStore文件保存在本地,用戶使用密碼+keystore的方式做離線交易簽名來發起交易,適用於dapp,比如錢包。
本文主要講一下第二種方式,也就是錢包離線簽名轉賬的方式。
交易流程
1、通過keystore載入轉賬所需的憑證Credentials
2、創建一筆交易RawTransaction
3、使用Credentials對象對交易簽名
4、發起交易
注意以下幾點:
1、Credentials
這里,我是通過獲取私鑰的方式來載入 Credentials
還有另外一種方式,通過密碼+錢包文件keystore方式來載入 Credentials
2、nonce
nonce是指發起交易的賬戶下的交易筆數,每一個賬戶nonce都是從0開始,當nonce為0的交易處理完之後,才會處理nonce為1的交易,並依次加1的交易才會被處理。
可以通過 eth_gettransactioncount 獲取nonce
3、gasPrice和gasLimit
交易手續費由gasPrice 和gasLimit來決定,實際花費的交易手續費是 gasUsed * gasPrice 。所有這兩個值你可以自定義,也可以使用系統參數獲取當前兩個值
關於 gas ,你可以參考我之前的一篇文章。
以太坊(ETH)GAS詳解
gasPrice和gasLimit影響的是轉賬的速度,如果gas過低,礦工會最後才打包你的交易。在app中,通常給定一個默認值,並且允許用戶自己選擇手續費。
如果不需要自定義的話,還有一種方式來獲取。獲取以太坊網路最新一筆交易的 gasPrice ,轉賬的話, gasLimit 一般設置為21000就可以了。
Web3j還提供另外一種簡單的方式來轉賬以太幣,這種方式的好處是不需要管理nonce,不需要設置gasPrice和gasLimit,會自動獲取最新一筆交易的gasPrice,gasLimit 為21000(轉賬一般設置成這個值就夠用了)。
這個問題,我想是很多朋友所關心的吧。但是到目前為止,我還沒有看到有講解這方面的博客。
之前問過一些朋友,他們說可以通過區塊號、區塊哈希來判斷,也可以通過Receipt日誌來判斷。但是經過我的一番嘗試,只有 BlockHash 是可行的,在web3j中根據 blocknumber 和 transactionReceipt 都會報空指針異常。
原因大致是這樣的:在發起一筆交易之後,會返回 txHash ,然後我們可以根據這個 txHash 去查詢這筆交易相關的信息。但是剛發起交易的時候,由於手續費問題或者乙太網絡擁堵問題,會導致你的這筆交易還沒有被礦工打包進區塊,因此一開始是查不到的,通常需要幾十秒甚至更長的時間才能獲取到結果。我目前的解決方案是輪詢的去刷 BlockHash ,一開始的時候 BlockHash 的值為0x00000000000,等到打包成功的時候就不再是0了。
這里我使用的是rxjava的方式去輪詢刷的,5s刷新一次。
正常情況下,幾十秒內就可以獲取到區塊信息了。
區塊確認數=當前區塊高度-交易被打包時的區塊高度。