mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #1164 from ethereum/keccak256-alias
Add alias keccak256() for sha3()
This commit is contained in:
		
						commit
						3f833c9ef4
					
				| @ -1,8 +1,10 @@ | ||||
| ### 0.4.3 (unreleased) | ||||
| 
 | ||||
| Features: | ||||
| 
 | ||||
|  * Inline assembly: support both `sucide` and `selfdestruct` opcodes | ||||
|    (note: `suicide` is deprecated) | ||||
|  * Include `keccak256()` as an alias to `sha3()` | ||||
| 
 | ||||
| Bugfixes: | ||||
|  * Disallow unknown options in `solc` | ||||
|  | ||||
| @ -136,7 +136,7 @@ This means that cyclic creation dependencies are impossible. | ||||
|         ) returns (bool ok) { | ||||
|             // Check some arbitrary condition. | ||||
|             address tokenAddress = msg.sender; | ||||
|             return (sha3(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); | ||||
|             return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -544,7 +544,7 @@ to be searched for: It is possible to filter for specific values of | ||||
| indexed arguments in the user interface. | ||||
| 
 | ||||
| If arrays (including ``string`` and ``bytes``) are used as indexed arguments, the | ||||
| sha3-hash of it is stored as topic instead. | ||||
| Keccak-256 hash of it is stored as topic instead. | ||||
| 
 | ||||
| The hash of the signature of the event is one of the topics except if you | ||||
| declared the event with ``anonymous`` specifier. This means that it is | ||||
| @ -622,7 +622,7 @@ as topics. The event call above can be performed in the same way as | ||||
|     ); | ||||
| 
 | ||||
| where the long hexadecimal number is equal to | ||||
| ``sha3("Deposit(address,hash256,uint256)")``, the signature of the event. | ||||
| ``keccak256("Deposit(address,hash256,uint256)")``, the signature of the event. | ||||
| 
 | ||||
| Additional Resources for Understanding Events | ||||
| ============================================== | ||||
|  | ||||
| @ -34,17 +34,17 @@ Statically-sized variables (everything except mapping and dynamically-sized arra | ||||
| 
 | ||||
| The elements of structs and arrays are stored after each other, just as if they were given explicitly. | ||||
| 
 | ||||
| Due to their unpredictable size, mapping and dynamically-sized array types use a ``sha3`` | ||||
| Due to their unpredictable size, mapping and dynamically-sized array types use a Keccak-256 hash | ||||
| computation to find the starting position of the value or the array data. These starting positions are always full stack slots. | ||||
| 
 | ||||
| The mapping or the dynamic array itself | ||||
| occupies an (unfilled) slot in storage at some position ``p`` according to the above rule (or by | ||||
| recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). | ||||
| Array data is located at ``sha3(p)`` and the value corresponding to a mapping key | ||||
| ``k`` is located at ``sha3(k . p)`` where ``.`` is concatenation. If the value is again a | ||||
| non-elementary type, the positions are found by adding an offset of ``sha3(k . p)``. | ||||
| Array data is located at ``keccak256(p)`` and the value corresponding to a mapping key | ||||
| ``k`` is located at ``keccak256(k . p)`` where ``.`` is concatenation. If the value is again a | ||||
| non-elementary type, the positions are found by adding an offset of ``keccak256(k . p)``. | ||||
| 
 | ||||
| ``bytes`` and ``string`` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most ``31`` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores ``length * 2``. If it is longer, the main slot stores ``length * 2 + 1`` and the data is stored as usual in ``sha3(slot)``. | ||||
| ``bytes`` and ``string`` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most ``31`` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores ``length * 2``. If it is longer, the main slot stores ``length * 2 + 1`` and the data is stored as usual in ``keccak256(slot)``. | ||||
| 
 | ||||
| So for the following contract snippet:: | ||||
| 
 | ||||
| @ -54,7 +54,7 @@ So for the following contract snippet:: | ||||
|       mapping(uint => mapping(uint => s)) data; | ||||
|     } | ||||
| 
 | ||||
| The position of ``data[4][9].b`` is at ``sha3(uint256(9) . sha3(uint256(4) . uint256(1))) + 1``. | ||||
| The position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``. | ||||
| 
 | ||||
| ***************** | ||||
| Esoteric Features | ||||
| @ -281,7 +281,7 @@ The following is the order of precedence for operators, listed in order of evalu | ||||
| | *16*       | Comma operator                      | ``,``                                      | | ||||
| +------------+-------------------------------------+--------------------------------------------+ | ||||
| 
 | ||||
| .. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin, sha3, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send | ||||
| .. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send | ||||
| 
 | ||||
| Global Variables | ||||
| ================ | ||||
| @ -299,7 +299,8 @@ Global Variables | ||||
| - ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``) | ||||
| - ``tx.gasprice`` (``uint``): gas price of the transaction | ||||
| - ``tx.origin`` (``address``): sender of the transaction (full call chain) | ||||
| - ``sha3(...) returns (bytes32)``: compute the Ethereum-SHA-3 (KECCAK-256) hash of the (tightly packed) arguments | ||||
| - ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments | ||||
| - ``sha3(...) returns (bytes32)``: an alias to `keccak256()` | ||||
| - ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the (tightly packed) arguments | ||||
| - ``ripemd160(...) returns (bytes20)``: compute the RIPEMD-160 hash of the (tightly packed) arguments | ||||
| - ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with the public key from elliptic curve signature, return zero on error | ||||
|  | ||||
| @ -207,7 +207,7 @@ Minor Details | ||||
|   You can craft transactions that call a function ``f(uint8 x)`` with a raw byte argument | ||||
|   of ``0xff000001`` and with ``0x00000001``. Both are fed to the contract and both will | ||||
|   look like the number ``1`` as far as ``x`` is concerned, but ``msg.data`` will | ||||
|   be different, so if you use ``sha3(msg.data)`` for anything, you will get different results. | ||||
|   be different, so if you use ``keccak256(msg.data)`` for anything, you will get different results. | ||||
| 
 | ||||
| *************** | ||||
| Recommendations | ||||
|  | ||||
| @ -415,7 +415,7 @@ high or low invalid bids. | ||||
|             revealEnd = biddingEnd + _revealTime; | ||||
|         } | ||||
| 
 | ||||
|         /// Place a blinded bid with `_blindedBid` = sha3(value, | ||||
|         /// Place a blinded bid with `_blindedBid` = keccak256(value, | ||||
|         /// fake, secret). | ||||
|         /// The sent ether is only refunded if the bid is correctly | ||||
|         /// revealed in the revealing phase. The bid is valid if the | ||||
| @ -459,7 +459,7 @@ high or low invalid bids. | ||||
|                 var bid = bids[msg.sender][i]; | ||||
|                 var (value, fake, secret) = | ||||
|                         (_values[i], _fake[i], _secret[i]); | ||||
|                 if (bid.blindedBid != sha3(value, fake, secret)) { | ||||
|                 if (bid.blindedBid != keccak256(value, fake, secret)) { | ||||
|                     // Bid was not actually revealed. | ||||
|                     // Do not refund deposit. | ||||
|                     continue; | ||||
|  | ||||
| @ -106,7 +106,7 @@ the function ``call`` is provided which takes an arbitrary number of arguments o | ||||
| 
 | ||||
|     address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; | ||||
|     nameReg.call("register", "MyName"); | ||||
|     nameReg.call(bytes4(sha3("fun(uint256)")), a); | ||||
|     nameReg.call(bytes4(keccak256("fun(uint256)")), a); | ||||
| 
 | ||||
| ``call`` returns a boolean indicating whether the invoked function terminated (``true``) or caused an EVM exception (``false``). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). | ||||
| 
 | ||||
| @ -610,7 +610,7 @@ can actually be any type, including mappings. | ||||
| Mappings can be seen as hashtables which are virtually initialized such that | ||||
| every possible key exists and is mapped to a value whose byte-representation is | ||||
| all zeros: a type's :ref:`default value <default-value>`. The similarity ends here, though: The key data is not actually stored | ||||
| in a mapping, only its ``sha3`` hash used to look up the value. | ||||
| in a mapping, only its ``keccak256`` hash used to look up the value. | ||||
| 
 | ||||
| Because of this, mappings do not have a length or a concept of a key or value being "set". | ||||
| 
 | ||||
|  | ||||
| @ -79,7 +79,7 @@ Block and Transaction Properties | ||||
|     You can only access the hashes of the most recent 256 blocks, all other | ||||
|     values will be zero. | ||||
| 
 | ||||
| .. index:: sha3, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send | ||||
| .. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send | ||||
| 
 | ||||
| Mathematical and Cryptographic Functions | ||||
| ---------------------------------------- | ||||
| @ -88,8 +88,10 @@ Mathematical and Cryptographic Functions | ||||
|     compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. | ||||
| ``mulmod(uint x, uint y, uint k) returns (uint)``: | ||||
|     compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. | ||||
| ``keccak256(...) returns (bytes32)``: | ||||
|     compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments | ||||
| ``sha3(...) returns (bytes32)``: | ||||
|     compute the Ethereum-SHA-3 (KECCAK-256) hash of the (tightly packed) arguments | ||||
|     alias to `keccak256()` | ||||
| ``sha256(...) returns (bytes32)``: | ||||
|     compute the SHA-256 hash of the (tightly packed) arguments | ||||
| ``ripemd160(...) returns (bytes20)``: | ||||
| @ -100,18 +102,18 @@ Mathematical and Cryptographic Functions | ||||
| In the above, "tightly packed" means that the arguments are concatenated without padding. | ||||
| This means that the following are all identical:: | ||||
| 
 | ||||
|     sha3("ab", "c") | ||||
|     sha3("abc") | ||||
|     sha3(0x616263) | ||||
|     sha3(6382179) | ||||
|     sha3(97, 98, 99) | ||||
|     keccak256("ab", "c") | ||||
|     keccak256("abc") | ||||
|     keccak256(0x616263) | ||||
|     keccak256(6382179) | ||||
|     keccak256(97, 98, 99) | ||||
| 
 | ||||
| If padding is needed, explicit type conversions can be used: ``sha3("\x00\x12")`` is the | ||||
| same as ``sha3(uint16(0x12))``. | ||||
| If padding is needed, explicit type conversions can be used: ``keccak256("\x00\x12")`` is the | ||||
| same as ``keccak256(uint16(0x12))``. | ||||
| 
 | ||||
| Note that constants will be packed using the minimum number of bytes required to store them. | ||||
| This means that, for example, ``sha3(0) == sha3(uint8(0))`` and | ||||
| ``sha3(0x12345678) == sha3(uint32(0x12345678))``. | ||||
| This means that, for example, ``keccak256(0) == keccak256(uint8(0))`` and | ||||
| ``keccak256(0x12345678) == keccak256(uint32(0x12345678))``. | ||||
| 
 | ||||
| It might be that you run into Out-of-Gas for ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net. | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,8 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared< | ||||
| 						make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Location::MulMod)), | ||||
| 					make_shared<MagicVariableDeclaration>("sha3", | ||||
| 							make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)), | ||||
| 					make_shared<MagicVariableDeclaration>("keccak256", | ||||
| 							make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)), | ||||
| 					make_shared<MagicVariableDeclaration>("log0", | ||||
| 							make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)), | ||||
| 					make_shared<MagicVariableDeclaration>("log1", | ||||
|  | ||||
| @ -2872,6 +2872,24 @@ BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes) | ||||
| 	)); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments) | ||||
| { | ||||
| 	char const* sourceCode = R"( | ||||
| 		contract c { | ||||
| 			function foo(uint a, uint b, uint c) returns (bytes32 d) | ||||
| 			{ | ||||
| 				d = keccak256(a, b, c); | ||||
| 			} | ||||
| 		})"; | ||||
| 	compileAndRun(sourceCode); | ||||
| 
 | ||||
| 	BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs( | ||||
| 					dev::sha3( | ||||
| 						toBigEndian(u256(10)) + | ||||
| 						toBigEndian(u256(12)) + | ||||
| 						toBigEndian(u256(13))))); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(generic_call) | ||||
| { | ||||
| 	char const* sourceCode = R"**( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user