9

We need to detect that the submitted work became an uncle. How would I do this with geth api? I thought of checking the submitted block number later for any uncles that match my block's hash. Is there a better way?

6

Here's my scripts to check and print blocks, uncles and transactions. You will see the logic to retrieve the uncle details within the getMinedBlocks() function.

I've listed them separately for easier reading. If you intend to use it in geth, you would probably want to concatenate the following 5 functions into a single file for easy copy-pasting into the geth console.

printTransaction(txHash)

function printTransaction(txHash) {
  var tx = eth.getTransaction(txHash);
  if (tx != null) {
    console.log("  tx hash          : " + tx.hash + "\n"
      + "   nonce           : " + tx.nonce + "\n"
      + "   blockHash       : " + tx.blockHash + "\n"
      + "   blockNumber     : " + tx.blockNumber + "\n"
      + "   transactionIndex: " + tx.transactionIndex + "\n"
      + "   from            : " + tx.from + "\n" 
      + "   to              : " + tx.to + "\n"
      + "   value           : " + tx.value + "\n"
      + "   gasPrice        : " + tx.gasPrice + "\n"
      + "   gas             : " + tx.gas + "\n"
      + "   input           : " + tx.input);
  }
}

printBlock(block)

function printBlock(block) {
  console.log("Block number     : " + block.number + "\n"
    + " hash            : " + block.hash + "\n"
    + " parentHash      : " + block.parentHash + "\n"
    + " nonce           : " + block.nonce + "\n"
    + " sha3Uncles      : " + block.sha3Uncles + "\n"
    + " logsBloom       : " + block.logsBloom + "\n"
    + " transactionsRoot: " + block.transactionsRoot + "\n"
    + " stateRoot       : " + block.stateRoot + "\n"
    + " miner           : " + block.miner + "\n"
    + " difficulty      : " + block.difficulty + "\n"
    + " totalDifficulty : " + block.totalDifficulty + "\n"
    + " extraData       : " + block.extraData + "\n"
    + " size            : " + block.size + "\n"
    + " gasLimit        : " + block.gasLimit + "\n"
    + " gasUsed         : " + block.gasUsed + "\n"
    + " timestamp       : " + block.timestamp + "\n"
    + " transactions    : " + block.transactions + "\n"
    + " uncles          : " + block.uncles);
    if (block.transactions != null) {
      console.log("--- transactions ---");
      block.transactions.forEach( function(e) {
        printTransaction(e);
      })
    }
}

printUncle(block, uncleNumber, uncle)

function printUncle(block, uncleNumber, uncle) {
  console.log("Block number     : " + block.number + " , uncle position: " + uncleNumber + "\n"
    + " Uncle number    : " + uncle.number + "\n"
    + " hash            : " + uncle.hash + "\n"
    + " parentHash      : " + uncle.parentHash + "\n"
    + " nonce           : " + uncle.nonce + "\n"
    + " sha3Uncles      : " + uncle.sha3Uncles + "\n"
    + " logsBloom       : " + uncle.logsBloom + "\n"
    + " transactionsRoot: " + uncle.transactionsRoot + "\n"
    + " stateRoot       : " + uncle.stateRoot + "\n"
    + " miner           : " + uncle.miner + "\n"
    + " difficulty      : " + uncle.difficulty + "\n"
    + " totalDifficulty : " + uncle.totalDifficulty + "\n"
    + " extraData       : " + uncle.extraData + "\n"
    + " size            : " + uncle.size + "\n"
    + " gasLimit        : " + uncle.gasLimit + "\n"
    + " gasUsed         : " + uncle.gasUsed + "\n"
    + " timestamp       : " + uncle.timestamp + "\n"
    + " transactions    : " + uncle.transactions + "\n");
}

getMinedBlocks(miner, startBlockNumber, endBlockNumber)

If startBlockNumber is not specified, it will default to the last 10,000 blocks. This takes some time to scan, so reduce this number to 1000 to reduce the scanning time.

If endBlockNumber is not specified, it will default to the latest block number.

function getMinedBlocks(miner, startBlockNumber, endBlockNumber) {
  if (endBlockNumber == null) {
    endBlockNumber = eth.blockNumber;
    console.log("Using endBlockNumber: " + endBlockNumber);
  }
  if (startBlockNumber == null) {
    startBlockNumber = endBlockNumber - 10000;
    console.log("Using startBlockNumber: " + startBlockNumber);
  }
  console.log("Searching for miner \"" + miner + "\" within blocks "  + startBlockNumber + " and " + endBlockNumber + "\"");

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {
    if (i % 1000 == 0) {
      console.log("Searching block " + i);
    }
    var block = eth.getBlock(i);
    if (block != null) {
      if (block.miner == miner || miner == "*") {
        console.log("Found block " + block.number);
        printBlock(block);
      }
      if (block.uncles != null) {
        for (var j = 0; j < 2; j++) {
          var uncle = eth.getUncle(i, j);
          if (uncle != null) {
            if (uncle.miner == miner || miner == "*") {
              console.log("Found uncle " + block.number + " uncle " + j);
              printUncle(block, j, uncle);
            }
          }          
        }
      }
    }
  }
}

getMyMinedBlocks(startBlockNumber, endBlockNumber)

function getMyMinedBlocks(startBlockNumber, endBlockNumber) {
  getMinedBlocks(eth.accounts[0], startBlockNumber, endBlockNumber);
}

Examples For Using The Function Above

Here are some examples of using the above functions on the public mainnet Ethereum network.

  • Print block mined by "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5". See https://etherscan.io/block/1325630

    getMinedBlocks("0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", 1325620, 1325640);
    
  • Print block with uncles mined by "0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb". See https://etherscan.io/block/1325635

    getMinedBlocks("0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb", 1325630, 1325640);
    

    with the output:

    > getMinedBlocks("0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb", 1325630, 1325640);
    Searching for miner "0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb" within blocks 1325630 and 1325640"
    Found uncle 1325635 uncle 0
    Block number     : 1325635 , uncle position: 0
     Uncle number    : 1325634
     hash            : 0xae03bb2d5f1fbde4e22bf79850307ab6ae7d8545a9f0de4a5f529095546308c0
     parentHash      : 0x771b46e0310666780a55b1d603648d89e7d8cc3feac20a175117b4cb7e206a75
     nonce           : 0xeff5922de2f569e8
     sha3Uncles      : 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
     logsBloom       : 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     transactionsRoot: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
     stateRoot       : 0xafca80bc836c00c7eeb4b6f3254573f72d38a0738ce4793da7d5222ed6c0c5cd
     miner           : 0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb
     difficulty      : 26564802678158
     totalDifficulty : 0
     extraData       : 0x426974436c756220455448204d696e696e6720506f6f6c
     size            : 0
     gasLimit        : 4712388
     gasUsed         : 0
     timestamp       : 1460501836
     transactions    : undefined
    
  • Print block with uncles. See https://etherscan.io/block/907703

    getMinedBlocks("*", 907703, 907703);
    
  • Print blocks my miner has mined between blocks 1321603 and 1321605

    getMyMinedBlocks(1321603, 1321605);
    
2

usually you would see it in the miner...

but if you would need it for a transaction purpose, I would suggest using this command

https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethgetuncle

  • I need to do it from code. – bolaum Apr 12 '16 at 23:03
  • wat do you mean "from code"? Like you need to know from Solidity? If so that's not possible. But the command I showed you above should work in JS...you'll have to hack it a bit but you'll be able to figure it out from that command I just linked you. – VoR0220 Apr 13 '16 at 0:12
  • 1
    I meant 'programmatically', inside js code. When you said 'usually you would see it in the miner...' I thought you meant geth logs or something. Thanks for the link, I'll check it out along with the solution above. – bolaum Apr 13 '16 at 1:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.