diff --git a/contracts/deploy/Factory.sol b/contracts/deploy/Factory.sol index f63bf71..2408a58 100644 --- a/contracts/deploy/Factory.sol +++ b/contracts/deploy/Factory.sol @@ -4,54 +4,87 @@ import "../common/Controlled.sol"; contract Factory is Controlled { - event NewKernel(address newKernel, bytes infohash); + event NewKernel(address newKernel, bytes32 codeHash); struct Version { uint256 blockNumber; uint256 timestamp; address kernel; - bytes infohash; + bytes32 codeHash; } + mapping (address => uint256) versionMap; Version[] versionLog; uint256 latestUpdate; address latestKernel; - function Factory(address _kernel, bytes _infohash) + function Factory(address _kernel) public { - _setKernel(_kernel, _infohash); + _setKernel(_kernel); } - function setKernel(address _kernel, bytes _infohash) + function setKernel(address _kernel) external onlyController { - _setKernel(_kernel, _infohash); + _setKernel(_kernel); } - function getVersion(uint256 index) public view - returns(uint256 blockNumber, - uint256 timestamp, - address kernel, - bytes infohash) + function getVersion(uint256 index) + public + view + returns( + uint256 blockNumber, + uint256 timestamp, + address kernel, + bytes32 codeHash + ) { - return (versionLog[index].blockNumber, - versionLog[index].timestamp, - versionLog[index].kernel, - versionLog[index].infohash); + return ( + versionLog[index].blockNumber, + versionLog[index].timestamp, + versionLog[index].kernel, + versionLog[index].codeHash + ); } - function _setKernel(address _kernel, bytes _infohash) + function getCodeHash(address _addr) + public + view + returns (bytes32 codeHash) + { + bytes memory o_code; + uint size; + assembly { + // retrieve the size of the code, this needs assembly + size := extcodesize(_addr) + } + require (size > 0); + assembly { + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), bnot(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(_addr, add(o_code, 0x20), 0, size) + } + codeHash = keccak256(o_code); + } + + function _setKernel(address _kernel) internal { require(_kernel != latestKernel); + bytes32 _codeHash = getCodeHash(_kernel); versionMap[_kernel] = versionLog.length; - versionLog.push(Version({blockNumber: block.number, timestamp: block.timestamp, kernel: _kernel, infohash: _infohash})); + versionLog.push(Version({blockNumber: block.number, timestamp: block.timestamp, kernel: _kernel, codeHash: _codeHash})); latestUpdate = block.timestamp; latestKernel = _kernel; - NewKernel(_kernel, _infohash); + NewKernel(_kernel, _codeHash); } - } \ No newline at end of file