如何使用 infura Rinkeby 端點獲取區塊的礦工地址?
我已經在網上閱讀了一些文件,要獲取與乙太坊 PoA/Clique 共識(例如 Rinkeby 測試網)執行的特定區塊的礦工/封印者/簽名者地址,我需要呼叫clique_getSnapshot RPC 介面。但是,當我使用 infura Rinkeby 端點嘗試它時,它返回“方法 clique_getSnapshot 不存在/不可用”錯誤。
那麼有什麼方法可以讓我在帶有 infura Rinkeby 端點的 Rinkeby 測試網上獲取特定區塊的礦工/密封/簽名者地址?例如,在 etherscan 上,它顯示塊 4753195 由 0x7ffC57839B00206D1ad20c69A1981b489f772031 開採
https://rinkeby.etherscan.io/block/4753195
我怎樣才能得到這些資訊?
======
感謝@Ha ĐANG,我現在已經到了這個階段:
Web3 = require("web3"); web3 = new Web3("https://rinkeby.infura.io/v3/xxxxxxxxx"); // my infura Rinkeby endpoint ejutils = require("ethereumjs-utils"); (async () => { blk = await web3.eth.getBlock(4753195); blkhash = blk.hash; console.log(blkhash); // 0xdfd0a441a76d0f54bea2b61963871a61bca5eb4adf76f15d60e2d3c7b19cf191 Correct!! extdat = blk.extraData; console.log(extdat); // 0xd883010900846765746888676f312e31322e34856c696e7578000000000000009e4d991ca30e6ff6782058da4b958eb180e54f3af99f00afa9d42ea01c08b1134664c21f408d79c87d93a6ce83354a68d8f0d3fea99bc796029875563acceef801 Correct!! msg = ejutils.toBuffer(blkhash); sig = extdat.slice(-130); r = "0x" + sig.slice(0, 64); s = '0x' + sig.slice(64, 128); v = '0x' + sig.slice(128, 130); v = parseInt(v) + 27; pub = ejutils.ecrecover(msg, v, r, s); addr = ejutils.pubToAddress(pub); addr = ejutils.bufferToHex(addr); console.log(addr); // 0xe2877298e8cf1046ae9f3231e17f73fe85282590 Wrong :( })();
那麼知道上面的程式碼出了什麼問題嗎?謝謝。
非常感謝@Ha ĐANG 的幫助我終於找到了這個解決方案
const Web3 = require("web3"); const web3 = new Web3("https://rinkeby.infura.io/v3/xxxxxx"); // infura Rinkeby endpoint const eju = require("ethereumjs-utils"); (async () => { let blk = await web3.eth.getBlock(4753195); let header = [ eju.toBuffer(blk.parentHash), eju.toBuffer(blk.sha3Uncles), eju.toBuffer(blk.miner), eju.toBuffer(blk.stateRoot), eju.toBuffer(blk.transactionsRoot), eju.toBuffer(blk.receiptsRoot), eju.toBuffer(blk.logsBloom), parseInt(blk.difficulty), parseInt(blk.number), parseInt(blk.gasLimit), parseInt(blk.gasUsed), parseInt(blk.timestamp), eju.toBuffer(blk.extraData.slice(0, blk.extraData.length - 130)), eju.toBuffer(blk.mixHash), eju.toBuffer(blk.nonce) ]; let msg = eju.rlp.encode(header); let msghash = eju.keccak256(msg) let sig = blk.extraData.slice(-130); let r = "0x" + sig.slice(0, 64); let s = '0x' + sig.slice(64, 128); let v = '0x' + sig.slice(128, 130); v = parseInt(v) + 27; let pub = eju.ecrecover(msghash, v, r, s); let addr = eju.pubToAddress(pub); addr = eju.bufferToHex(addr); console.log(addr); // 0x7ffc57839b00206d1ad20c69a1981b489f772031 Correct!! })();
花了整整一個小時的反複試驗,終於得到了正確的結果。不敢相信,完成這樣一個看似簡單的任務,居然這麼難。任何看到這個的人請點贊@Ha ĐANG 的回答,謝謝。
我已經在網上閱讀了一些文件,為了獲取與乙太坊 PoA/Clique 共識(例如 Rinkeby 測試網)執行的特定區塊的礦工/密封/簽名者地址,我需要呼叫 clique_getSnapshot RPC 介面。但是,當我使用 infura Rinkeby 端點嘗試它時,它返回“方法 clique_getSnapshot 不存在/不可用”錯誤。
→ 我們只能
clique_getSnapshot
在節點的控制台上呼叫,不能通過 JSON RPC API 呼叫。那麼有什麼方法可以讓我在帶有 infura Rinkeby 端點的 Rinkeby 測試網上獲取特定區塊的礦工/密封/簽名者地址?例如,在 etherscan 上,它顯示塊 4753195 由 0x7ffC57839B00206D1ad20c69A1981b489f772031 開採
→ 您可以在infura端點上呼叫eth_getBlockByNumber JSON RPC API以獲取塊資訊,然後通過使用函式從儲存在 block.extraData的最後 130 個十六進製字元中的數字簽名中恢復礦工的地址來 找出塊數據中的礦工。
ecrecover
下面是
ecrecover
在 golang 程式碼中使用的程式碼片段package main import ( "context" "log" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" ) func main() { client, err := ethclient.Dial("https://rinkeby.infura.io/v3/xxxxxx") if err != nil { log.Fatal(err) } block, err := client.BlockByNumber(context.Background(), big.NewInt(4753195)) if err != nil { log.Fatal(err) } pubkey, err := crypto.Ecrecover(clique.SealHash(block).Bytes(), block.Extra[len(block.Extra)-65:]) log.Println(pubkey) var signer common.Address copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) log.Println(err) log.Println(signer.Hex()) }
0x7ffC57839B00206D1ad20c69A1981b489f772031
並mined by
在etherscan.io上輸出相同的礦工地址