Skip to content

Commit

Permalink
for PoA network like Rinkeby "miner" field is empty due to consensus …
Browse files Browse the repository at this point in the history
…algorithm ethereum/EIPs#225

Miner address is derivable from "extra" field. Last 65 bytes are miner signature
  • Loading branch information
ramilexe committed Jun 18, 2021
1 parent 4c7395f commit 919d1a2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/utils/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Contract from "../models/contract/contract";
import {decodeStorageCid, getContractsFromLogs, increaseHexByOne, mhDataToBuffer} from "./index";
import {decodeStorageCid, extractMinerFromExtra, getContractsFromLogs, increaseHexByOne, mhDataToBuffer} from "./index";
import {EthStorageCid} from "../types";

function dummyContract(address: string): Contract {
Expand Down Expand Up @@ -90,4 +90,12 @@ describe('utils', () => {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c]));
});

test('extractMinerFromExtra', () => {
// block 8647996 on Rinkeby
const blockRlp = "f9025ca00a84ebb80b8616551e251a42273bc0860e1db619affc009a7d17b96b8dba6cbaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0d7ce7224e063acb68e6dd5ba4e0ef90d4c6e61d4e30cdc6b6b5ef5adfc32a8c6a09db0cbfa54f72435c8f15326d01924bb0b9c1aa4ffa1b05eef9e4dbafc4179a1a0e9602d458a57dd10df00ac06b014da188c1bfb2276fd8b39cde58a82cf78169eb9010000020100400000100000400040008800000000100404008000000000004000000000820100000800210000400080200000010000800000000800000000a00240000000820000000800000008008000000000000800000401100000400000001430000000200000000000000010808000200090000000001520080010400000000100000100042000001840000100000080000040104088000000010000040000228000000000400040200000040000040000084000100020000000004000800000104002200000000000000000000047012080010000040040001000000000a00010000000000040000000020000120000000080000006008000100001000000018383f53c8398c5278324527d8460ad1423b861d883010a04846765746888676f312e31362e33856c696e7578000000000000009e5b0e7ed267a159861a0c8a5b982adb1c3d4cfd12cd85eed6389e113ba614e23350342cd4cfeb8ea0d34bcaacadfa1a108be9c204ea5c95642fb8c03b6493df01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000";
const miner = "0x7ffc57839b00206d1ad20c69a1981b489f772031";

expect(extractMinerFromExtra(blockRlp)).toEqual(miner);
});
});
27 changes: 26 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {rlp, BN} from 'ethereumjs-util';
import {rlp, BN, fromRpcSig, keccak, ecrecover, addHexPrefix, pubToAddress} from 'ethereumjs-util';
import Contract from "../models/contract/contract";
import {EthStorageCid} from "../types";

Expand Down Expand Up @@ -99,4 +99,29 @@ export const decodeExtra = (data: string) => { // eslint-disable-line
}
return `${str}/${value.toString('utf-8')}`
}, '');
}

/**
* Returns miner address for PoA networks. Extract it from block extra field
*
* @param blockRlp
*/
export const extractMinerFromExtra = (blockRlp: string): string => {
const blockRlpBuf = mhDataToBuffer(blockRlp);
const decoded: any = rlp.decode(blockRlpBuf);
const extra = decoded[12];
// last 65 bytes are miner signature
const sig = extra.slice(extra.length - 65);
// convert hex signature to v, r, s format
const signature = fromRpcSig(sig as any as string);

// to recovery miner address from signature we need to get block hash without this signature
decoded[12] = extra.slice(0, extra.length - 65);
const encodedBlock = rlp.encode(decoded);
const blockHash = keccak(encodedBlock);
console.log(blockHash, signature);
const pub = ecrecover(blockHash, signature.v, signature.r, signature.s)
const address = addHexPrefix(pubToAddress(pub).toString('hex'));

return address;
}

0 comments on commit 919d1a2

Please sign in to comment.