Mining

如何使用 infura Rinkeby 端點獲取區塊的礦工地址?

  • January 29, 2022

我已經在網上閱讀了一些文件,要獲取與乙太坊 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())
}

0x7ffC57839B00206D1ad20c69A1981b489f772031mined byetherscan.io上輸出相同的礦工地址

引用自:https://ethereum.stackexchange.com/questions/73030