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)
|
### 0.4.3 (unreleased)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
* Inline assembly: support both `sucide` and `selfdestruct` opcodes
|
* Inline assembly: support both `sucide` and `selfdestruct` opcodes
|
||||||
(note: `suicide` is deprecated)
|
(note: `suicide` is deprecated)
|
||||||
|
* Include `keccak256()` as an alias to `sha3()`
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Disallow unknown options in `solc`
|
* Disallow unknown options in `solc`
|
||||||
|
@ -136,7 +136,7 @@ This means that cyclic creation dependencies are impossible.
|
|||||||
) returns (bool ok) {
|
) returns (bool ok) {
|
||||||
// Check some arbitrary condition.
|
// Check some arbitrary condition.
|
||||||
address tokenAddress = msg.sender;
|
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.
|
indexed arguments in the user interface.
|
||||||
|
|
||||||
If arrays (including ``string`` and ``bytes``) are used as indexed arguments, the
|
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
|
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
|
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
|
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
|
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.
|
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.
|
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
|
The mapping or the dynamic array itself
|
||||||
occupies an (unfilled) slot in storage at some position ``p`` according to the above rule (or by
|
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).
|
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
|
Array data is located at ``keccak256(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
|
``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 ``sha3(k . p)``.
|
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::
|
So for the following contract snippet::
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ So for the following contract snippet::
|
|||||||
mapping(uint => mapping(uint => s)) data;
|
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
|
Esoteric Features
|
||||||
@ -281,7 +281,7 @@ The following is the order of precedence for operators, listed in order of evalu
|
|||||||
| *16* | Comma operator | ``,`` |
|
| *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
|
Global Variables
|
||||||
================
|
================
|
||||||
@ -299,7 +299,8 @@ Global Variables
|
|||||||
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
||||||
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||||
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
- ``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
|
- ``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
|
- ``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
|
- ``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
|
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
|
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
|
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
|
Recommendations
|
||||||
|
@ -415,7 +415,7 @@ high or low invalid bids.
|
|||||||
revealEnd = biddingEnd + _revealTime;
|
revealEnd = biddingEnd + _revealTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Place a blinded bid with `_blindedBid` = sha3(value,
|
/// Place a blinded bid with `_blindedBid` = keccak256(value,
|
||||||
/// fake, secret).
|
/// fake, secret).
|
||||||
/// The sent ether is only refunded if the bid is correctly
|
/// The sent ether is only refunded if the bid is correctly
|
||||||
/// revealed in the revealing phase. The bid is valid if the
|
/// 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 bid = bids[msg.sender][i];
|
||||||
var (value, fake, secret) =
|
var (value, fake, secret) =
|
||||||
(_values[i], _fake[i], _secret[i]);
|
(_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.
|
// Bid was not actually revealed.
|
||||||
// Do not refund deposit.
|
// Do not refund deposit.
|
||||||
continue;
|
continue;
|
||||||
|
@ -106,7 +106,7 @@ the function ``call`` is provided which takes an arbitrary number of arguments o
|
|||||||
|
|
||||||
address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
|
address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
|
||||||
nameReg.call("register", "MyName");
|
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).
|
``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
|
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
|
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
|
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".
|
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
|
You can only access the hashes of the most recent 256 blocks, all other
|
||||||
values will be zero.
|
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
|
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``.
|
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)``:
|
``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``.
|
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)``:
|
``sha3(...) returns (bytes32)``:
|
||||||
compute the Ethereum-SHA-3 (KECCAK-256) hash of the (tightly packed) arguments
|
alias to `keccak256()`
|
||||||
``sha256(...) returns (bytes32)``:
|
``sha256(...) returns (bytes32)``:
|
||||||
compute the SHA-256 hash of the (tightly packed) arguments
|
compute the SHA-256 hash of the (tightly packed) arguments
|
||||||
``ripemd160(...) returns (bytes20)``:
|
``ripemd160(...) returns (bytes20)``:
|
||||||
@ -100,18 +102,18 @@ Mathematical and Cryptographic Functions
|
|||||||
In the above, "tightly packed" means that the arguments are concatenated without padding.
|
In the above, "tightly packed" means that the arguments are concatenated without padding.
|
||||||
This means that the following are all identical::
|
This means that the following are all identical::
|
||||||
|
|
||||||
sha3("ab", "c")
|
keccak256("ab", "c")
|
||||||
sha3("abc")
|
keccak256("abc")
|
||||||
sha3(0x616263)
|
keccak256(0x616263)
|
||||||
sha3(6382179)
|
keccak256(6382179)
|
||||||
sha3(97, 98, 99)
|
keccak256(97, 98, 99)
|
||||||
|
|
||||||
If padding is needed, explicit type conversions can be used: ``sha3("\x00\x12")`` is the
|
If padding is needed, explicit type conversions can be used: ``keccak256("\x00\x12")`` is the
|
||||||
same as ``sha3(uint16(0x12))``.
|
same as ``keccak256(uint16(0x12))``.
|
||||||
|
|
||||||
Note that constants will be packed using the minimum number of bytes required to store them.
|
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
|
This means that, for example, ``keccak256(0) == keccak256(uint8(0))`` and
|
||||||
``sha3(0x12345678) == sha3(uint32(0x12345678))``.
|
``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.
|
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<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Location::MulMod)),
|
||||||
make_shared<MagicVariableDeclaration>("sha3",
|
make_shared<MagicVariableDeclaration>("sha3",
|
||||||
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)),
|
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<MagicVariableDeclaration>("log0",
|
||||||
make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)),
|
make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)),
|
||||||
make_shared<MagicVariableDeclaration>("log1",
|
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)
|
BOOST_AUTO_TEST_CASE(generic_call)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"**(
|
char const* sourceCode = R"**(
|
||||||
|
Loading…
Reference in New Issue
Block a user