Explorar el Código

Using extcodehash instead of extcodesize for less gas (#1802)

* Using extcodehash instead of extcodesize for less gas

`extcodehash` uses less gas then `extcodesize`. You can tell which address is a contract by the hash (see EIP-1052).

* Fix

* Add explainer

* Update Address.sol

* add changelog entry
Philippe Castonguay hace 6 años
padre
commit
0282c3608d
Se han modificado 2 ficheros con 13 adiciones y 4 borrados
  1. 5 0
      CHANGELOG.md
  2. 8 4
      contracts/utils/Address.sol

+ 5 - 0
CHANGELOG.md

@@ -5,6 +5,11 @@
 ### New features:
  * `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773))
 
+### Improvements:
+ * `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
+
+### Bugfixes
+
 ## 2.3.0 (2019-05-27)
 
 ### New features:

+ 8 - 4
contracts/utils/Address.sol

@@ -18,11 +18,15 @@ library Address {
         // This method relies in extcodesize, which returns 0 for contracts in
         // construction, since the code is only stored at the end of the
         // constructor execution.
-
-        uint256 size;
+        
+        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
+        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
+        // for accounts without code, i.e. `keccak256('')`
+        bytes32 codehash;
+        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
         // solhint-disable-next-line no-inline-assembly
-        assembly { size := extcodesize(account) }
-        return size > 0;
+        assembly { codehash := extcodehash(account) }
+        return (codehash != 0x0 && codehash != accountHash);
     }
 
     /**