diff --git a/lib/opFns.js b/lib/opFns.js index cdef721e20..df6a88c21b 100644 --- a/lib/opFns.js +++ b/lib/opFns.js @@ -288,6 +288,30 @@ module.exports = { cb(null) }) }, + EXTCODEHASH: function (address, runState, cb) { + if (!runState._common.gteHardfork('constantinople')) { + trap(ERROR.INVALID_OPCODE) + } + var stateManager = runState.stateManager + address = addressToBuffer(address) + + stateManager.getAccount(address, function (err, account) { + if (err) return cb(err) + + if (account.isEmpty()) { + return cb(null, new BN(0)) + } + + stateManager.getContractCode(address, function (err, code) { + if (err) return cb(err) + if (code.length === 0) { + return cb(null, new BN(utils.KECCAK256_NULL)) + } + + return cb(null, new BN(utils.keccak256(code))) + }) + }) + }, RETURNDATASIZE: function (runState) { return new BN(runState.lastReturned.length) }, diff --git a/lib/opcodes.js b/lib/opcodes.js index bc23ce977e..6093e269f0 100644 --- a/lib/opcodes.js +++ b/lib/opcodes.js @@ -49,6 +49,7 @@ const codes = { 0x3c: ['EXTCODECOPY', 700, 4, 0, true, true], 0x3d: ['RETURNDATASIZE', 2, 0, 1, true], 0x3e: ['RETURNDATACOPY', 3, 3, 0, true], + 0x3f: ['EXTCODEHASH', 400, 1, 1, true, true], // '0x40' range - block operations 0x40: ['BLOCKHASH', 20, 1, 1, true, true],