Merge pull request #4097 from ethereum/noPackedExceptForPacked

[BREAKING] call only takes a single argument and does not pad
This commit is contained in:
chriseth 2018-06-27 18:29:01 +02:00 committed by GitHub
commit 4a842ecc82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 358 additions and 352 deletions

View File

@ -1,5 +1,10 @@
### 0.5.0 (unreleased) ### 0.5.0 (unreleased)
How to update your code:
* Change every ``.call()`` to a ``.call("")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types).
* Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``.
Breaking Changes: Breaking Changes:
* ABI Encoder: Properly pad data from calldata (``msg.data`` and external function parameters). Use ``abi.encodePacked`` for unpadded encoding. * ABI Encoder: Properly pad data from calldata (``msg.data`` and external function parameters). Use ``abi.encodePacked`` for unpadded encoding.
* Code Generator: Signed right shift uses proper arithmetic shift, i.e. rounding towards negative infinity. Warning: this may silently change the semantics of existing code! * Code Generator: Signed right shift uses proper arithmetic shift, i.e. rounding towards negative infinity. Warning: this may silently change the semantics of existing code!
@ -22,6 +27,7 @@ Breaking Changes:
* Parser: Disallow trailing dots that are not followed by a number. * Parser: Disallow trailing dots that are not followed by a number.
* Type Checker: Disallow arithmetic operations for boolean variables. * Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
* Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible. * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
* Syntax Checker: Named return values in function types are an error. * Syntax Checker: Named return values in function types are an error.

View File

@ -559,7 +559,7 @@ would result in the JSON:
Non-standard Packed Mode Non-standard Packed Mode
======================== ========================
Solidity supports a non-standard packed mode where: Through ``abi.encodePacked()``, Solidity supports a non-standard packed mode where:
- no :ref:`function selector <abi_function_selector>` is encoded, - no :ref:`function selector <abi_function_selector>` is encoded,
- types shorter than 32 bytes are neither zero padded nor sign extended and - types shorter than 32 bytes are neither zero padded nor sign extended and
@ -577,3 +577,9 @@ More specifically, each statically-sized type takes as many bytes as its range h
and dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded without and dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded without
their length field. This means that the encoding is ambiguous as soon as there are two their length field. This means that the encoding is ambiguous as soon as there are two
dynamically-sized elements. dynamically-sized elements.
Note that constants will be packed using the minimum number of bytes required to store them.
This means that, for example, ``abi.encodePacked(0) == abi.encodePacked(uint8(0)) == hex"00"`` and
``abi.encodePacked(0x12345678) == abi.encodePacked(uint32(0x12345678)) == hex"12345678"``.
If padding is needed, explicit type conversions can be used: ``abi.encodePacked(uint16(0x12)) == hex"0012"``.

View File

@ -113,7 +113,7 @@ This means that cyclic creation dependencies are impossible.
{ {
// Check some arbitrary condition. // Check some arbitrary condition.
address tokenAddress = msg.sender; address tokenAddress = msg.sender;
return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); return (keccak256(abi.encodePacked(newOwner)) & 0xff) == (bytes20(tokenAddress) & 0xff);
} }
} }
@ -377,7 +377,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
/// The `return 7` statement assigns 7 to the return value but still /// The `return 7` statement assigns 7 to the return value but still
/// executes the statement `locked = false` in the modifier. /// executes the statement `locked = false` in the modifier.
function f() public noReentrancy returns (uint) { function f() public noReentrancy returns (uint) {
require(msg.sender.call()); require(msg.sender.call(""));
return 7; return 7;
} }
} }
@ -604,7 +604,7 @@ Like any function, the fallback function can execute complex operations as long
contract Caller { contract Caller {
function callTest(Test test) public { function callTest(Test test) public {
test.call(0xabcdef01); // hash does not exist test.call(abi.encodeWithSignature("nonExistingFunction()"));
// results in test.x becoming == 1. // results in test.x becoming == 1.
// The following will not compile, but even // The following will not compile, but even

View File

@ -322,7 +322,7 @@ Global Variables
- ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments - ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments
- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments
starting from the second and prepends the given four-byte selector starting from the second and prepends the given four-byte selector
- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(signature), ...)``` - ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``. - ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``.
- ``block.coinbase`` (``address``): current block miner's address - ``block.coinbase`` (``address``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty - ``block.difficulty`` (``uint``): current block difficulty
@ -343,10 +343,10 @@ Global Variables
- ``revert()``: abort execution and revert state changes - ``revert()``: abort execution and revert state changes
- ``revert(string message)``: abort execution and revert state changes providing an explanatory string - ``revert(string message)``: abort execution and revert state changes providing an explanatory string
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks - ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
- ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` - ``keccak256(bytes memory) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the input
- ``sha3(...) returns (bytes32)``: an alias to ``keccak256`` - ``sha3(bytes memory) returns (bytes32)``: an alias to ``keccak256``
- ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` - ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input
- ``ripemd160(...) returns (bytes20)``: compute the RIPEMD-160 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` - ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input
- ``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
- ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. - ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
- ``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``. Assert that ``k != 0`` starting from version 0.5.0. - ``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``. Assert that ``k != 0`` starting from version 0.5.0.

View File

@ -86,7 +86,7 @@ as it uses ``call`` which forwards all remaining gas by default:
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() public { function withdraw() public {
if (msg.sender.call.value(shares[msg.sender])()) if (msg.sender.call.value(shares[msg.sender])(""))
shares[msg.sender] = 0; shares[msg.sender] = 0;
} }
} }
@ -140,7 +140,7 @@ Sending and Receiving Ether
(for example in the "details" section in Remix). (for example in the "details" section in Remix).
- There is a way to forward more gas to the receiving contract using - There is a way to forward more gas to the receiving contract using
``addr.call.value(x)()``. This is essentially the same as ``addr.transfer(x)``, ``addr.call.value(x)("")``. This is essentially the same as ``addr.transfer(x)``,
only that it forwards all remaining gas and opens up the ability for the only that it forwards all remaining gas and opens up the ability for the
recipient to perform more expensive actions (and it only returns a failure code recipient to perform more expensive actions (and it only returns a failure code
and does not automatically propagate the error). This might include calling back and does not automatically propagate the error). This might include calling back

View File

@ -428,8 +428,8 @@ high or low invalid bids.
revealEnd = biddingEnd + _revealTime; revealEnd = biddingEnd + _revealTime;
} }
/// Place a blinded bid with `_blindedBid` = keccak256(value, /// Place a blinded bid with `_blindedBid` =
/// fake, secret). /// keccak256(abi.encodePacked(value, 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
/// ether sent together with the bid is at least "value" and /// ether sent together with the bid is at least "value" and
@ -470,7 +470,7 @@ high or low invalid bids.
Bid storage bid = bids[msg.sender][i]; Bid storage bid = bids[msg.sender][i];
(uint value, bool fake, bytes32 secret) = (uint value, bool fake, bytes32 secret) =
(_values[i], _fake[i], _secret[i]); (_values[i], _fake[i], _secret[i]);
if (bid.blindedBid != keccak256(value, fake, secret)) { if (bid.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {
// Bid was not actually revealed. // Bid was not actually revealed.
// Do not refund deposit. // Do not refund deposit.
continue; continue;

View File

@ -143,27 +143,37 @@ Send is the low-level counterpart of ``transfer``. If the execution fails, the c
* ``call``, ``callcode`` and ``delegatecall`` * ``call``, ``callcode`` and ``delegatecall``
Furthermore, to interface with contracts that do not adhere to the ABI, Furthermore, to interface with contracts that do not adhere to the ABI,
the function ``call`` is provided which takes an arbitrary number of arguments of any type. These arguments are padded to 32 bytes and concatenated. One exception is the case where the first argument is encoded to exactly four bytes. In this case, it is not padded to allow the use of function signatures here. or to get more direct control over the encoding,
the function ``call`` is provided which takes a single byte array as input.
The functions ``abi.encode``, ``abi.encodePacked``, ``abi.encodeWithSelector``
and ``abi.encodeWithSignature`` can be used to encode structured data.
:: .. warning::
All these functions are low-level functions and should be used with care.
Specifically, any unknown contract might be malicious and if you call it, you
hand over control to that contract which could in turn call back into
your contract, so be prepared for changes to your state variables
when the call returns. The regular way to interact with other contracts
is to call a function on a contract object (``x.f()``).
address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; :: note::
nameReg.call("register", "MyName"); Previous versions of Solidity allowed these functions to receive
nameReg.call(bytes4(keccak256("fun(uint256)")), a); arbitrary arguments and would also handle a first argument of type
``bytes4`` differently. These edge cases were removed in version 0.5.0.
``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 with plain Solidity. However, using inline assembly it is possible to make a raw ``call`` and access the actual data returned with the ``returndatacopy`` instruction.
It is possible to adjust the supplied gas with the ``.gas()`` modifier:: It is possible to adjust the supplied gas with the ``.gas()`` modifier::
namReg.call.gas(1000000)("register", "MyName"); namReg.call.gas(1000000)(abi.encodeWithSignature("register(string)", "MyName"));
Similarly, the supplied Ether value can be controlled too:: Similarly, the supplied Ether value can be controlled too::
nameReg.call.value(1 ether)("register", "MyName"); nameReg.call.value(1 ether)(abi.encodeWithSignature("register(string)", "MyName"));
Lastly, these modifiers can be combined. Their order does not matter:: Lastly, these modifiers can be combined. Their order does not matter::
nameReg.call.gas(1000000).value(1 ether)("register", "MyName"); nameReg.call.gas(1000000).value(1 ether)(abi.encodeWithSignature("register(string)", "MyName"));
.. note:: .. note::
It is not yet possible to use the gas or value modifiers on overloaded functions. It is not yet possible to use the gas or value modifiers on overloaded functions.
@ -184,13 +194,6 @@ The ``.gas()`` option is available on all three methods, while the ``.value()``
.. note:: .. note::
The use of ``callcode`` is discouraged and will be removed in the future. The use of ``callcode`` is discouraged and will be removed in the future.
.. warning::
All these functions are low-level functions and should be used with care.
Specifically, any unknown contract might be malicious and if you call it, you
hand over control to that contract which could in turn call back into
your contract, so be prepared for changes to your state variables
when the call returns.
.. index:: byte array, bytes32 .. index:: byte array, bytes32

View File

@ -100,16 +100,16 @@ ABI Encoding Functions
---------------------- ----------------------
- ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments - ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments
- ``abi.encodePacked(...) returns (bytes)``: Performes packed encoding of the given arguments - ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments
- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments
starting from the second and prepends the given four-byte selector starting from the second and prepends the given four-byte selector
- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(signature), ...)``` - ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
.. note:: .. note::
These encoding functions can be used to craft data for function calls without actually These encoding functions can be used to craft data for function calls without actually
calling a function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a more calling a function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a way
explicit way to compute ``keccak256(a, b)``, which will be deprecated in future to compute the hash of structured data (although be aware that it is possible to
versions. craft a "hash collision" using different inputs types).
See the documentation about the :ref:`ABI <ABI>` and the See the documentation about the :ref:`ABI <ABI>` and the
:ref:`tightly packed encoding <abi_packed_mode>` for details about the encoding. :ref:`tightly packed encoding <abi_packed_mode>` for details about the encoding.
@ -139,34 +139,18 @@ Mathematical and Cryptographic Functions
compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
``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``. Assert that ``k != 0`` starting from version 0.5.0. compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
``keccak256(...) returns (bytes32)``: ``keccak256(bytes memory) returns (bytes32)``:
compute the Ethereum-SHA-3 (Keccak-256) hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` compute the Ethereum-SHA-3 (Keccak-256) hash of the input
``sha256(...) returns (bytes32)``: ``sha256(bytes memory) returns (bytes32)``:
compute the SHA-256 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` compute the SHA-256 hash of the input
``sha3(...) returns (bytes32)``: ``sha3(bytes memory) returns (bytes32)``:
alias to ``keccak256`` alias to ``keccak256``
``ripemd160(...) returns (bytes20)``: ``ripemd160(bytes memory) returns (bytes20)``:
compute RIPEMD-160 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>` compute RIPEMD-160 hash of the input
``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``:
recover the address associated with the public key from elliptic curve signature or return zero on error recover the address associated with the public key from elliptic curve signature or return zero on error
(`example usage <https://ethereum.stackexchange.com/q/1777/222>`_) (`example usage <https://ethereum.stackexchange.com/q/1777/222>`_)
In the above, "tightly packed" means that the arguments are concatenated without padding.
This means that the following are all identical::
keccak256("ab", "c")
keccak256("abc")
keccak256(0x616263)
keccak256(6382179)
keccak256(97, 98, 99)
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, ``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. 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.
.. index:: balance, send, transfer, call, callcode, delegatecall .. index:: balance, send, transfer, call, callcode, delegatecall
@ -181,12 +165,12 @@ Address Related
send given amount of Wei to :ref:`address`, throws on failure, forwards 2300 gas stipend, not adjustable send given amount of Wei to :ref:`address`, throws on failure, forwards 2300 gas stipend, not adjustable
``<address>.send(uint256 amount) returns (bool)``: ``<address>.send(uint256 amount) returns (bool)``:
send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable
``<address>.call(...) returns (bool)``: ``<address>.call(bytes memory) returns (bool)``:
issue low-level ``CALL``, returns ``false`` on failure, forwards all available gas, adjustable issue low-level ``CALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable
``<address>.callcode(...) returns (bool)``: ``<address>.callcode(bytes memory) returns (bool)``:
issue low-level ``CALLCODE``, returns ``false`` on failure, forwards all available gas, adjustable issue low-level ``CALLCODE`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable
``<address>.delegatecall(...) returns (bool)``: ``<address>.delegatecall(bytes memory) returns (bool)``:
issue low-level ``DELEGATECALL``, returns ``false`` on failure, forwards all available gas, adjustable issue low-level ``DELEGATECALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable
For more information, see the section on :ref:`address`. For more information, see the section on :ref:`address`.

View File

@ -42,7 +42,7 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{
make_shared<MagicVariableDeclaration>("blockhash", make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)), make_shared<MagicVariableDeclaration>("blockhash", make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)),
make_shared<MagicVariableDeclaration>("ecrecover", make_shared<FunctionType>(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Kind::ECRecover, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("ecrecover", make_shared<FunctionType>(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Kind::ECRecover, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft, false, StateMutability::View)), make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft, false, StateMutability::View)),
make_shared<MagicVariableDeclaration>("keccak256", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA3, true, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("keccak256", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA3, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("log0", make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Kind::Log0)), make_shared<MagicVariableDeclaration>("log0", make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Kind::Log0)),
make_shared<MagicVariableDeclaration>("log1", make_shared<FunctionType>(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log1)), make_shared<MagicVariableDeclaration>("log1", make_shared<FunctionType>(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log1)),
make_shared<MagicVariableDeclaration>("log2", make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log2)), make_shared<MagicVariableDeclaration>("log2", make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log2)),
@ -55,10 +55,10 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{
make_shared<MagicVariableDeclaration>("require", make_shared<FunctionType>(strings{"bool", "string memory"}, strings{}, FunctionType::Kind::Require, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("require", make_shared<FunctionType>(strings{"bool", "string memory"}, strings{}, FunctionType::Kind::Require, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings(), strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings(), strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings{"string memory"}, strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings{"string memory"}, strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("ripemd160", make_shared<FunctionType>(strings(), strings{"bytes20"}, FunctionType::Kind::RIPEMD160, true, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("ripemd160", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes20"}, FunctionType::Kind::RIPEMD160, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("selfdestruct", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)), make_shared<MagicVariableDeclaration>("selfdestruct", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)),
make_shared<MagicVariableDeclaration>("sha256", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA256, true, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("sha256", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA256, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("sha3", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA3, true, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("sha3", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA3, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("suicide", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)), make_shared<MagicVariableDeclaration>("suicide", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)),
make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::Transaction)) make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::Transaction))
}) })

View File

@ -1745,35 +1745,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
} }
} }
if (functionType->takesSinglePackedBytesParameter())
{
if (
(arguments.size() > 1) ||
(arguments.size() == 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory)))
)
{
string msg =
"This function only accepts a single \"bytes\" argument. Please use "
"\"abi.encodePacked(...)\" or a similar function to encode the data.";
if (v050)
m_errorReporter.typeError(_functionCall.location(), msg);
else
m_errorReporter.warning(_functionCall.location(), msg);
}
if (arguments.size() == 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory)))
{
string msg =
"The provided argument of type " +
type(*arguments.front())->toString() +
" is not implicitly convertible to expected type bytes memory.";
if (v050)
m_errorReporter.typeError(_functionCall.location(), msg);
else
m_errorReporter.warning(_functionCall.location(), msg);
}
}
if (functionType->takesArbitraryParameters() && arguments.size() < parameterTypes.size()) if (functionType->takesArbitraryParameters() && arguments.size() < parameterTypes.size())
{ {
solAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, ""); solAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, "");
@ -1805,6 +1776,26 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
for (auto const& member: membersRemovedForStructConstructor) for (auto const& member: membersRemovedForStructConstructor)
msg += " " + member; msg += " " + member;
} }
else if (
functionType->kind() == FunctionType::Kind::BareCall ||
functionType->kind() == FunctionType::Kind::BareCallCode ||
functionType->kind() == FunctionType::Kind::BareDelegateCall
)
{
if (arguments.empty())
msg += " This function requires a single bytes argument. Use \"\" as argument to provide empty calldata.";
else
msg += " This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.";
}
else if (
functionType->kind() == FunctionType::Kind::SHA3 ||
functionType->kind() == FunctionType::Kind::SHA256 ||
functionType->kind() == FunctionType::Kind::RIPEMD160
)
msg +=
" This function requires a single bytes argument."
" Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour"
" or abi.encode(...) to use ABI encoding.";
m_errorReporter.typeError(_functionCall.location(), msg); m_errorReporter.typeError(_functionCall.location(), msg);
} }
else if (isPositionalCall) else if (isPositionalCall)
@ -1841,15 +1832,31 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
} }
} }
else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i])) else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
m_errorReporter.typeError( {
arguments[i]->location(), string msg =
"Invalid type for argument in function call. " "Invalid type for argument in function call. "
"Invalid implicit conversion from " + "Invalid implicit conversion from " +
type(*arguments[i])->toString() + type(*arguments[i])->toString() +
" to " + " to " +
parameterTypes[i]->toString() + parameterTypes[i]->toString() +
" requested." " requested.";
); if (
functionType->kind() == FunctionType::Kind::BareCall ||
functionType->kind() == FunctionType::Kind::BareCallCode ||
functionType->kind() == FunctionType::Kind::BareDelegateCall
)
msg += " This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.";
else if (
functionType->kind() == FunctionType::Kind::SHA3 ||
functionType->kind() == FunctionType::Kind::SHA256 ||
functionType->kind() == FunctionType::Kind::RIPEMD160
)
msg +=
" This function requires a single bytes argument."
" Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour"
" or abi.encode(...) to use ABI encoding.";
m_errorReporter.typeError(arguments[i]->location(), msg);
}
} }
} }
else else

View File

@ -599,9 +599,9 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
if (isAddress()) if (isAddress())
return { return {
{"balance", make_shared<IntegerType>(256)}, {"balance", make_shared<IntegerType>(256)},
{"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCall, true, StateMutability::Payable)}, {"call", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool"}, FunctionType::Kind::BareCall, false, StateMutability::Payable)},
{"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCallCode, true, StateMutability::Payable)}, {"callcode", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool"}, FunctionType::Kind::BareCallCode, false, StateMutability::Payable)},
{"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareDelegateCall, true)}, {"delegatecall", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool"}, FunctionType::Kind::BareDelegateCall, false)},
{"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)}, {"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)},
{"transfer", make_shared<FunctionType>(strings{"uint"}, strings(), FunctionType::Kind::Transfer)} {"transfer", make_shared<FunctionType>(strings{"uint"}, strings(), FunctionType::Kind::Transfer)}
}; };
@ -3005,6 +3005,25 @@ ASTPointer<ASTString> FunctionType::documentation() const
return ASTPointer<ASTString>(); return ASTPointer<ASTString>();
} }
bool FunctionType::padArguments() const
{
// No padding only for hash functions, low-level calls and the packed encoding function.
switch (m_kind)
{
case Kind::BareCall:
case Kind::BareCallCode:
case Kind::BareDelegateCall:
case Kind::SHA256:
case Kind::RIPEMD160:
case Kind::SHA3:
case Kind::ABIEncodePacked:
return false;
default:
return true;
}
return true;
}
string MappingType::richIdentifier() const string MappingType::richIdentifier() const
{ {
return "t_mapping" + identifierList(m_keyType, m_valueType); return "t_mapping" + identifierList(m_keyType, m_valueType);

View File

@ -1058,18 +1058,21 @@ public:
ASTPointer<ASTString> documentation() const; ASTPointer<ASTString> documentation() const;
/// true iff arguments are to be padded to multiples of 32 bytes for external calls /// true iff arguments are to be padded to multiples of 32 bytes for external calls
bool padArguments() const { return !(m_kind == Kind::SHA3 || m_kind == Kind::SHA256 || m_kind == Kind::RIPEMD160 || m_kind == Kind::ABIEncodePacked); } /// The only functions that do not pad are hash functions, the low-level call functions
/// and abi.encodePacked.
bool padArguments() const;
bool takesArbitraryParameters() const { return m_arbitraryParameters; } bool takesArbitraryParameters() const { return m_arbitraryParameters; }
/// true iff the function takes a single bytes parameter and it is passed on without padding. /// true iff the function takes a single bytes parameter and it is passed on without padding.
/// @todo until 0.5.0, this is just a "recommendation".
bool takesSinglePackedBytesParameter() const bool takesSinglePackedBytesParameter() const
{ {
// @todo add the call kinds here with 0.5.0 and perhaps also log0.
switch (m_kind) switch (m_kind)
{ {
case FunctionType::Kind::SHA3: case FunctionType::Kind::SHA3:
case FunctionType::Kind::SHA256: case FunctionType::Kind::SHA256:
case FunctionType::Kind::RIPEMD160: case FunctionType::Kind::RIPEMD160:
case FunctionType::Kind::BareCall:
case FunctionType::Kind::BareCallCode:
case FunctionType::Kind::BareDelegateCall:
return true; return true;
default: default:
return false; return false;

View File

@ -699,16 +699,24 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
} }
case FunctionType::Kind::SHA3: case FunctionType::Kind::SHA3:
{ {
TypePointers argumentTypes; solAssert(arguments.size() == 1, "");
for (auto const& arg: arguments)
{
arg->accept(*this);
argumentTypes.push_back(arg->annotation().type);
}
utils().fetchFreeMemoryPointer();
solAssert(!function.padArguments(), ""); solAssert(!function.padArguments(), "");
utils().packedEncode(argumentTypes, TypePointers()); TypePointer const& argType = arguments.front()->annotation().type;
utils().toSizeAfterFreeMemoryPointer(); solAssert(argType, "");
arguments.front()->accept(*this);
// Optimization: If type is bytes or string, then do not encode,
// but directly compute keccak256 on memory.
if (*argType == ArrayType(DataLocation::Memory) || *argType == ArrayType(DataLocation::Memory, true))
{
ArrayUtils(m_context).retrieveLength(ArrayType(DataLocation::Memory));
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
}
else
{
utils().fetchFreeMemoryPointer();
utils().packedEncode({argType}, TypePointers());
utils().toSizeAfterFreeMemoryPointer();
}
m_context << Instruction::KECCAK256; m_context << Instruction::KECCAK256;
break; break;
} }
@ -1802,13 +1810,14 @@ void ExpressionCompiler::appendExternalFunctionCall(
if (_functionType.bound()) if (_functionType.bound())
utils().moveToStackTop(gasValueSize, _functionType.selfType()->sizeOnStack()); utils().moveToStackTop(gasValueSize, _functionType.selfType()->sizeOnStack());
bool const v050 = m_context.experimentalFeatureActive(ExperimentalFeature::V050);
auto funKind = _functionType.kind(); auto funKind = _functionType.kind();
bool returnSuccessCondition = funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::BareDelegateCall; bool returnSuccessCondition = funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::BareDelegateCall;
bool isCallCode = funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::CallCode; bool isCallCode = funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::CallCode;
bool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall; bool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall;
bool useStaticCall = bool useStaticCall =
_functionType.stateMutability() <= StateMutability::View && _functionType.stateMutability() <= StateMutability::View &&
m_context.experimentalFeatureActive(ExperimentalFeature::V050) && v050 &&
m_context.evmVersion().hasStaticCall(); m_context.evmVersion().hasStaticCall();
bool haveReturndatacopy = m_context.evmVersion().supportsReturndata(); bool haveReturndatacopy = m_context.evmVersion().supportsReturndata();
@ -1836,38 +1845,12 @@ void ExpressionCompiler::appendExternalFunctionCall(
// Evaluate arguments. // Evaluate arguments.
TypePointers argumentTypes; TypePointers argumentTypes;
TypePointers parameterTypes = _functionType.parameterTypes(); TypePointers parameterTypes = _functionType.parameterTypes();
bool manualFunctionId = false;
if (
(funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::BareDelegateCall) &&
!_arguments.empty()
)
{
solAssert(_arguments.front()->annotation().type->mobileType(), "");
manualFunctionId =
_arguments.front()->annotation().type->mobileType()->calldataEncodedSize(false) ==
CompilerUtils::dataStartOffset;
}
if (manualFunctionId)
{
// If we have a Bare* and the first type has exactly 4 bytes, use it as
// function identifier.
_arguments.front()->accept(*this);
utils().convertType(
*_arguments.front()->annotation().type,
IntegerType(8 * CompilerUtils::dataStartOffset),
true
);
for (unsigned i = 0; i < gasValueSize; ++i)
m_context << swapInstruction(gasValueSize - i);
gasStackPos++;
valueStackPos++;
}
if (_functionType.bound()) if (_functionType.bound())
{ {
argumentTypes.push_back(_functionType.selfType()); argumentTypes.push_back(_functionType.selfType());
parameterTypes.insert(parameterTypes.begin(), _functionType.selfType()); parameterTypes.insert(parameterTypes.begin(), _functionType.selfType());
} }
for (size_t i = manualFunctionId ? 1 : 0; i < _arguments.size(); ++i) for (size_t i = 0; i < _arguments.size(); ++i)
{ {
_arguments[i]->accept(*this); _arguments[i]->accept(*this);
argumentTypes.push_back(_arguments[i]->annotation().type); argumentTypes.push_back(_arguments[i]->annotation().type);
@ -1903,19 +1886,20 @@ void ExpressionCompiler::appendExternalFunctionCall(
// Copy function identifier to memory. // Copy function identifier to memory.
utils().fetchFreeMemoryPointer(); utils().fetchFreeMemoryPointer();
if (!_functionType.isBareCall() || manualFunctionId) if (!_functionType.isBareCall())
{ {
m_context << dupInstruction(2 + gasValueSize + CompilerUtils::sizeOnStack(argumentTypes)); m_context << dupInstruction(2 + gasValueSize + CompilerUtils::sizeOnStack(argumentTypes));
utils().storeInMemoryDynamic(IntegerType(8 * CompilerUtils::dataStartOffset), false); utils().storeInMemoryDynamic(IntegerType(8 * CompilerUtils::dataStartOffset), false);
} }
// If the function takes arbitrary parameters, copy dynamic length data in place.
// If the function takes arbitrary parameters or is a bare call, copy dynamic length data in place.
// Move arguments to memory, will not update the free memory pointer (but will update the memory // Move arguments to memory, will not update the free memory pointer (but will update the memory
// pointer on the stack). // pointer on the stack).
utils().encodeToMemory( utils().encodeToMemory(
argumentTypes, argumentTypes,
parameterTypes, parameterTypes,
_functionType.padArguments(), _functionType.padArguments(),
_functionType.takesArbitraryParameters(), _functionType.takesArbitraryParameters() || _functionType.isBareCall(),
isCallCode || isDelegateCall isCallCode || isDelegateCall
); );
@ -1996,9 +1980,9 @@ void ExpressionCompiler::appendExternalFunctionCall(
unsigned remainsSize = unsigned remainsSize =
2 + // contract address, input_memory_end 2 + // contract address, input_memory_end
_functionType.valueSet() + (_functionType.valueSet() ? 1 : 0) +
_functionType.gasSet() + (_functionType.gasSet() ? 1 : 0) +
(!_functionType.isBareCall() || manualFunctionId); (!_functionType.isBareCall() ? 1 : 0);
if (returnSuccessCondition) if (returnSuccessCondition)
m_context << swapInstruction(remainsSize); m_context << swapInstruction(remainsSize);

View File

@ -117,7 +117,7 @@ contract moduleHandler is multiOwner, announcementTypes {
@id Index of module. @id Index of module.
@found Was there any result or not. @found Was there any result or not.
*/ */
bytes32 _name = keccak256(name); bytes32 _name = keccak256(bytes(name));
for ( uint256 a=0 ; a<modules.length ; a++ ) { for ( uint256 a=0 ; a<modules.length ; a++ ) {
if ( modules[a].name == _name ) { if ( modules[a].name == _name ) {
return (true, true, a); return (true, true, a);
@ -153,7 +153,7 @@ contract moduleHandler is multiOwner, announcementTypes {
require( _success ); require( _success );
if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) { if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("replaceModule", keccak256(name, addr, callCallback))) ) { if ( ! insertAndCheckDo(calcDoHash("replaceModule", keccak256(abi.encodePacked(name, addr, callCallback)))) ) {
return true; return true;
} }
} }
@ -169,7 +169,7 @@ contract moduleHandler is multiOwner, announcementTypes {
function callReplaceCallback(string moduleName, address newModule) external returns (bool success) { function callReplaceCallback(string moduleName, address newModule) external returns (bool success) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("callReplaceCallback", keccak256(moduleName, newModule))) ) { if ( ! insertAndCheckDo(calcDoHash("callReplaceCallback", keccak256(abi.encodePacked(moduleName, newModule)))) ) {
return true; return true;
} }
(bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName); (bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName);
@ -192,11 +192,11 @@ contract moduleHandler is multiOwner, announcementTypes {
require( _success ); require( _success );
if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) { if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("newModule", keccak256(name, addr, schellingEvent, transferEvent))) ) { if ( ! insertAndCheckDo(calcDoHash("newModule", keccak256(abi.encodePacked(name, addr, schellingEvent, transferEvent)))) ) {
return true; return true;
} }
} }
addModule( modules_s(addr, keccak256(name), schellingEvent, transferEvent), true); addModule( modules_s(addr, keccak256(bytes(name)), schellingEvent, transferEvent), true);
return true; return true;
} }
function dropModule(string name, bool callCallback) external returns (bool success) { function dropModule(string name, bool callCallback) external returns (bool success) {
@ -211,7 +211,7 @@ contract moduleHandler is multiOwner, announcementTypes {
require( _success ); require( _success );
if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) { if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("replaceModule", keccak256(name, callCallback))) ) { if ( ! insertAndCheckDo(calcDoHash("replaceModule", keccak256(abi.encodePacked(name, callCallback)))) ) {
return true; return true;
} }
} }
@ -226,7 +226,7 @@ contract moduleHandler is multiOwner, announcementTypes {
function callDisableCallback(string moduleName) external returns (bool success) { function callDisableCallback(string moduleName) external returns (bool success) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("callDisableCallback", keccak256(moduleName))) ) { if ( ! insertAndCheckDo(calcDoHash("callDisableCallback", keccak256(bytes(moduleName)))) ) {
return true; return true;
} }
(bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName); (bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName);
@ -289,7 +289,7 @@ contract moduleHandler is multiOwner, announcementTypes {
require( _success ); require( _success );
if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) { if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("replaceModuleHandler", keccak256(newHandler))) ) { if ( ! insertAndCheckDo(calcDoHash("replaceModuleHandler", keccak256(abi.encodePacked(newHandler)))) ) {
return true; return true;
} }
} }
@ -419,7 +419,7 @@ contract moduleHandler is multiOwner, announcementTypes {
require( _success ); require( _success );
if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) { if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {
require( block.number < debugModeUntil ); require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("configureModule", keccak256(moduleName, aType, value))) ) { if ( ! insertAndCheckDo(calcDoHash("configureModule", keccak256(abi.encodePacked(moduleName, aType, value)))) ) {
return true; return true;
} }
} }
@ -437,7 +437,7 @@ contract moduleHandler is multiOwner, announcementTypes {
*/ */
require( owners[msg.sender] ); require( owners[msg.sender] );
if ( forever ) { if ( forever ) {
if ( ! insertAndCheckDo(calcDoHash("freezing", keccak256(forever))) ) { if ( ! insertAndCheckDo(calcDoHash("freezing", keccak256(abi.encodePacked(forever)))) ) {
return; return;
} }
} }

View File

@ -21,12 +21,12 @@ contract multiOwner is safeMath {
Externals Externals
*/ */
function insertOwner(address addr) external { function insertOwner(address addr) external {
if ( insertAndCheckDo(calcDoHash("insertOwner", keccak256(addr))) ) { if ( insertAndCheckDo(calcDoHash("insertOwner", keccak256(abi.encodePacked(addr)))) ) {
_addOwner(addr); _addOwner(addr);
} }
} }
function dropOwner(address addr) external { function dropOwner(address addr) external {
if ( insertAndCheckDo(calcDoHash("dropOwner", keccak256(addr))) ) { if ( insertAndCheckDo(calcDoHash("dropOwner", keccak256(abi.encodePacked(addr)))) ) {
_delOwner(addr); _delOwner(addr);
} }
} }
@ -42,7 +42,7 @@ contract multiOwner is safeMath {
return ownerCount * 75 / 100; return ownerCount * 75 / 100;
} }
function calcDoHash(string job, bytes32 data) public constant returns (bytes32 hash) { function calcDoHash(string job, bytes32 data) public constant returns (bytes32 hash) {
return keccak256(job, data); return keccak256(abi.encodePacked(job, data));
} }
function validDoHash(bytes32 doHash) public constant returns (bool valid) { function validDoHash(bytes32 doHash) public constant returns (bool valid) {
return doDB[doHash].length > 0; return doDB[doHash].length > 0;

View File

@ -335,7 +335,7 @@ contract schelling is module, announcementTypes, schellingVars {
require( voter.status == voterStatus.afterPrepareVote ); require( voter.status == voterStatus.afterPrepareVote );
require( voter.roundID < currentRound ); require( voter.roundID < currentRound );
if ( keccak256(vote) == voter.hash ) { if ( keccak256(bytes(vote)) == voter.hash ) {
delete voter.hash; delete voter.hash;
if (round.blockHeight+roundBlockDelay/2 >= block.number) { if (round.blockHeight+roundBlockDelay/2 >= block.number) {
if ( bytes(vote)[0] == aboveChar ) { if ( bytes(vote)[0] == aboveChar ) {

View File

@ -48,6 +48,6 @@ contract CategoricalEvent is Event {
constant constant
returns (bytes32) returns (bytes32)
{ {
return keccak256(collateralToken, oracle, outcomeTokens.length); return keccak256(abi.encodePacked(collateralToken, oracle, outcomeTokens.length));
} }
} }

View File

@ -35,7 +35,7 @@ contract EventFactory {
public public
returns (CategoricalEvent eventContract) returns (CategoricalEvent eventContract)
{ {
bytes32 eventHash = keccak256(collateralToken, oracle, outcomeCount); bytes32 eventHash = keccak256(abi.encodePacked(collateralToken, oracle, outcomeCount));
// Event should not exist yet // Event should not exist yet
require(address(categoricalEvents[eventHash]) == address(0)); require(address(categoricalEvents[eventHash]) == address(0));
// Create event // Create event
@ -63,7 +63,7 @@ contract EventFactory {
public public
returns (ScalarEvent eventContract) returns (ScalarEvent eventContract)
{ {
bytes32 eventHash = keccak256(collateralToken, oracle, lowerBound, upperBound); bytes32 eventHash = keccak256(abi.encodePacked(collateralToken, oracle, lowerBound, upperBound));
// Event should not exist yet // Event should not exist yet
require(address(scalarEvents[eventHash]) == address(0)); require(address(scalarEvents[eventHash]) == address(0));
// Create event // Create event

View File

@ -82,6 +82,6 @@ contract ScalarEvent is Event {
constant constant
returns (bytes32) returns (bytes32)
{ {
return keccak256(collateralToken, oracle, lowerBound, upperBound); return keccak256(abi.encodePacked(collateralToken, oracle, lowerBound, upperBound));
} }
} }

View File

@ -58,7 +58,7 @@ contract SignedMessageOracle is Oracle {
// Result is not set yet and nonce and signer are valid // Result is not set yet and nonce and signer are valid
require( !isSet require( !isSet
&& _nonce > nonce && _nonce > nonce
&& signer == ecrecover(keccak256(descriptionHash, newSigner, _nonce), v, r, s)); && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, newSigner, _nonce)), v, r, s));
nonce = _nonce; nonce = _nonce;
signer = newSigner; signer = newSigner;
emit SignerReplacement(newSigner); emit SignerReplacement(newSigner);
@ -74,7 +74,7 @@ contract SignedMessageOracle is Oracle {
{ {
// Result is not set yet and signer is valid // Result is not set yet and signer is valid
require( !isSet require( !isSet
&& signer == ecrecover(keccak256(descriptionHash, _outcome), v, r, s)); && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, _outcome)), v, r, s));
isSet = true; isSet = true;
outcome = _outcome; outcome = _outcome;
emit OutcomeAssignment(_outcome); emit OutcomeAssignment(_outcome);

View File

@ -66,7 +66,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit {
return 0; return 0;
} }
// determine our operation hash. // determine our operation hash.
_r = keccak256(msg.data, block.number); _r = keccak256(abi.encodePacked(msg.data, block.number));
if (!confirm(_r) && txs[_r].to == address(0)) { if (!confirm(_r) && txs[_r].to == address(0)) {
txs[_r].to = _to; txs[_r].to = _to;
txs[_r].value = _value; txs[_r].value = _value;

View File

@ -82,7 +82,7 @@ contract FixedFeeRegistrar is Registrar {
} }
} }
function disown(string _name, address _refund) onlyrecordowner(_name) { function disown(string _name, address _refund) onlyrecordowner(_name) {
delete m_recordData[uint(keccak256(_name)) / 8]; delete m_recordData[uint(keccak256(bytes(_name))) / 8];
if (!_refund.send(c_fee)) if (!_refund.send(c_fee))
throw; throw;
emit Changed(_name); emit Changed(_name);
@ -118,7 +118,7 @@ contract FixedFeeRegistrar is Registrar {
Record[2**253] m_recordData; Record[2**253] m_recordData;
function m_record(string _name) constant internal returns (Record storage o_record) { function m_record(string _name) constant internal returns (Record storage o_record) {
return m_recordData[uint(keccak256(_name)) / 8]; return m_recordData[uint(keccak256(bytes(_name))) / 8];
} }
uint constant c_fee = 69 ether; uint constant c_fee = 69 ether;
} }

View File

@ -398,7 +398,7 @@ contract Wallet is multisig, multiowned, daylimit {
return 0; return 0;
} }
// determine our operation hash. // determine our operation hash.
_r = keccak256(msg.data, block.number); _r = keccak256(abi.encodePacked(msg.data, block.number));
if (!confirm(_r) && m_txs[_r].to == 0x0000000000000000000000000000000000000000) { if (!confirm(_r) && m_txs[_r].to == 0x0000000000000000000000000000000000000000) {
m_txs[_r].to = _to; m_txs[_r].to = _to;
m_txs[_r].value = _value; m_txs[_r].value = _value;

View File

@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(simple_contract)
contract test { contract test {
bytes32 public shaValue; bytes32 public shaValue;
function f(uint a) { function f(uint a) {
shaValue = keccak256(a); shaValue = keccak256(abi.encodePacked(a));
} }
} }
)"; )";
@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(store_keccak256)
contract test { contract test {
bytes32 public shaValue; bytes32 public shaValue;
function test(uint a) { function test(uint a) {
shaValue = keccak256(a); shaValue = keccak256(abi.encodePacked(a));
} }
} }
)"; )";

View File

@ -1456,7 +1456,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
function test() { function test() {
data = 8; data = 8;
name = "Celina"; name = "Celina";
a_hash = keccak256(123); a_hash = keccak256("\x7b");
an_address = address(0x1337); an_address = address(0x1337);
super_secret_data = 42; super_secret_data = 42;
} }
@ -1992,7 +1992,7 @@ BOOST_AUTO_TEST_CASE(keccak256)
char const* sourceCode = R"( char const* sourceCode = R"(
contract test { contract test {
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
return keccak256(input); return keccak256(abi.encodePacked(input));
} }
} }
)"; )";
@ -2011,7 +2011,7 @@ BOOST_AUTO_TEST_CASE(sha256)
char const* sourceCode = R"( char const* sourceCode = R"(
contract test { contract test {
function a(bytes32 input) returns (bytes32 sha256hash) { function a(bytes32 input) returns (bytes32 sha256hash) {
return sha256(input); return sha256(abi.encodePacked(input));
} }
} }
)"; )";
@ -2036,7 +2036,7 @@ BOOST_AUTO_TEST_CASE(ripemd)
char const* sourceCode = R"( char const* sourceCode = R"(
contract test { contract test {
function a(bytes32 input) returns (bytes32 sha256hash) { function a(bytes32 input) returns (bytes32 sha256hash) {
return ripemd160(input); return ripemd160(abi.encodePacked(input));
} }
} }
)"; )";
@ -2063,7 +2063,7 @@ BOOST_AUTO_TEST_CASE(packed_keccak256)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
var b = 65536; var b = 65536;
uint c = 256; uint c = 256;
return keccak256(8, input, b, input, c); return keccak256(abi.encodePacked(8, input, b, input, c));
} }
} }
)"; )";
@ -2093,9 +2093,9 @@ BOOST_AUTO_TEST_CASE(packed_keccak256_complex_types)
x[0] = y[0] = uint120(-2); x[0] = y[0] = uint120(-2);
x[1] = y[1] = uint120(-3); x[1] = y[1] = uint120(-3);
x[2] = y[2] = uint120(-4); x[2] = y[2] = uint120(-4);
hash1 = keccak256(x); hash1 = keccak256(abi.encodePacked(x));
hash2 = keccak256(y); hash2 = keccak256(abi.encodePacked(y));
hash3 = keccak256(this.f); hash3 = keccak256(abi.encodePacked(this.f));
} }
} }
)"; )";
@ -2115,7 +2115,7 @@ BOOST_AUTO_TEST_CASE(packed_sha256)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
var b = 65536; var b = 65536;
uint c = 256; uint c = 256;
return sha256(8, input, b, input, c); return sha256(abi.encodePacked(8, input, b, input, c));
} }
} }
)"; )";
@ -2142,7 +2142,7 @@ BOOST_AUTO_TEST_CASE(packed_ripemd160)
function a(bytes32 input) returns (bytes32 hash) { function a(bytes32 input) returns (bytes32 hash) {
var b = 65536; var b = 65536;
uint c = 256; uint c = 256;
return ripemd160(8, input, b, input, c); return ripemd160(abi.encodePacked(8, input, b, input, c));
} }
} }
)"; )";
@ -3082,13 +3082,13 @@ BOOST_AUTO_TEST_CASE(inherited_fallback_function)
BOOST_AUTO_TEST_CASE(default_fallback_throws) BOOST_AUTO_TEST_CASE(default_fallback_throws)
{ {
char const* sourceCode = R"( char const* sourceCode = R"YY(
contract A { contract A {
function f() returns (bool) { function f() returns (bool) {
return this.call(); return this.call("");
} }
} }
)"; )YY";
compileAndRun(sourceCode); compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(0)); ABI_CHECK(callContractFunction("f()"), encodeArgs(0));
} }
@ -3503,7 +3503,7 @@ BOOST_AUTO_TEST_CASE(sha256_empty)
char const* sourceCode = R"( char const* sourceCode = R"(
contract C { contract C {
function f() returns (bytes32) { function f() returns (bytes32) {
return sha256(); return sha256("");
} }
} }
)"; )";
@ -3516,7 +3516,7 @@ BOOST_AUTO_TEST_CASE(ripemd160_empty)
char const* sourceCode = R"( char const* sourceCode = R"(
contract C { contract C {
function f() returns (bytes20) { function f() returns (bytes20) {
return ripemd160(); return ripemd160("");
} }
} }
)"; )";
@ -3529,7 +3529,7 @@ BOOST_AUTO_TEST_CASE(keccak256_empty)
char const* sourceCode = R"( char const* sourceCode = R"(
contract C { contract C {
function f() returns (bytes32) { function f() returns (bytes32) {
return keccak256(); return keccak256("");
} }
} }
)"; )";
@ -3543,7 +3543,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments)
contract c { contract c {
function foo(uint a, uint b, uint c) returns (bytes32 d) function foo(uint a, uint b, uint c) returns (bytes32 d)
{ {
d = keccak256(a, b, c); d = keccak256(abi.encodePacked(a, b, c));
} }
} }
)"; )";
@ -3564,7 +3564,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_numeric_literals)
contract c { contract c {
function foo(uint a, uint16 b) returns (bytes32 d) function foo(uint a, uint16 b) returns (bytes32 d)
{ {
d = keccak256(a, b, 145); d = keccak256(abi.encodePacked(a, b, 145));
} }
} }
)"; )";
@ -3589,7 +3589,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_string_literals)
} }
function bar(uint a, uint16 b) returns (bytes32 d) function bar(uint a, uint16 b) returns (bytes32 d)
{ {
d = keccak256(a, b, 145, "foo"); d = keccak256(abi.encodePacked(a, b, 145, "foo"));
} }
} }
)"; )";
@ -3628,7 +3628,7 @@ BOOST_AUTO_TEST_CASE(keccak256_with_bytes)
BOOST_AUTO_TEST_CASE(iterated_keccak256_with_bytes) BOOST_AUTO_TEST_CASE(iterated_keccak256_with_bytes)
{ {
char const* sourceCode = R"( char const* sourceCode = R"ABC(
contract c { contract c {
bytes data; bytes data;
function foo() returns (bytes32) function foo() returns (bytes32)
@ -3637,10 +3637,10 @@ BOOST_AUTO_TEST_CASE(iterated_keccak256_with_bytes)
data[0] = "x"; data[0] = "x";
data[1] = "y"; data[1] = "y";
data[2] = "z"; data[2] = "z";
return keccak256("b", keccak256(data), "a"); return keccak256(abi.encodePacked("b", keccak256(data), "a"));
} }
} }
)"; )ABC";
compileAndRun(sourceCode); compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("foo()"), encodeArgs( ABI_CHECK(callContractFunction("foo()"), encodeArgs(
u256(dev::keccak256(bytes{'b'} + dev::keccak256("xyz").asBytes() + bytes{'a'})) u256(dev::keccak256(bytes{'b'} + dev::keccak256("xyz").asBytes() + bytes{'a'}))
@ -3659,7 +3659,7 @@ BOOST_AUTO_TEST_CASE(generic_call)
function doSend(address rec) returns (uint d) function doSend(address rec) returns (uint d)
{ {
bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)")));
rec.call.value(2)(signature, 23); rec.call.value(2)(abi.encodeWithSelector(signature, 23));
return receiver(rec).received(); return receiver(rec).received();
} }
} }
@ -3689,7 +3689,7 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
function doSend(address rec) payable function doSend(address rec) payable
{ {
bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)")));
if (rec.delegatecall(signature, 23)) {} if (rec.delegatecall(abi.encodeWithSelector(signature, 23))) {}
} }
} }
)**"; )**";
@ -3786,7 +3786,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)
char const* sourceCode = R"( char const* sourceCode = R"(
contract C { contract C {
function f() returns (bytes32) { function f() returns (bytes32) {
return keccak256("abc", msg.data); return keccak256(abi.encodePacked("abc", msg.data));
} }
} }
)"; )";
@ -3855,21 +3855,15 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes_length)
compileAndRun(sourceCode, 0, "sender"); compileAndRun(sourceCode, 0, "sender");
// No additional data, just function selector // No additional data, just function selector
ABI_CHECK(callContractFunction("viaCalldata()"), encodeArgs(0x20)); ABI_CHECK(callContractFunction("viaCalldata()"), encodeArgs(4));
// Should be this with 0.5.0: encodeArgs(4)); ABI_CHECK(callContractFunction("viaMemory()"), encodeArgs(4));
ABI_CHECK(callContractFunction("viaMemory()"), encodeArgs(0x20)); ABI_CHECK(callContractFunction("viaStorage()"), encodeArgs(4));
// Should be this with 0.5.0: encodeArgs(4));
ABI_CHECK(callContractFunction("viaStorage()"), encodeArgs(0x20));
// Should be this with 0.5.0: encodeArgs(4));
// Some additional unpadded data // Some additional unpadded data
bytes unpadded = asBytes(string("abc")); bytes unpadded = asBytes(string("abc"));
ABI_CHECK(callContractFunctionNoEncoding("viaCalldata()", unpadded), encodeArgs(0x20)); ABI_CHECK(callContractFunctionNoEncoding("viaCalldata()", unpadded), encodeArgs(7));
// Should be this with 0.5.0: encodeArgs(7)); ABI_CHECK(callContractFunctionNoEncoding("viaMemory()", unpadded), encodeArgs(7));
ABI_CHECK(callContractFunctionNoEncoding("viaMemory()", unpadded), encodeArgs(0x20)); ABI_CHECK(callContractFunctionNoEncoding("viaStorage()", unpadded), encodeArgs(7));
// Should be this with 0.5.0: encodeArgs(7));
ABI_CHECK(callContractFunctionNoEncoding("viaStorage()", unpadded), encodeArgs(0x20));
// Should be this with 0.5.0: encodeArgs(7));
} }
BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) BOOST_AUTO_TEST_CASE(copying_bytes_multiassign)
@ -6324,7 +6318,7 @@ BOOST_AUTO_TEST_CASE(reusing_memory)
mapping(uint => uint) map; mapping(uint => uint) map;
function f(uint x) returns (uint) { function f(uint x) returns (uint) {
map[x] = x; map[x] = x;
return (new Helper(uint(keccak256(this.g(map[x]))))).flag(); return (new Helper(uint(keccak256(abi.encodePacked(this.g(map[x])))))).flag();
} }
function g(uint a) returns (uint) function g(uint a) returns (uint)
{ {
@ -9312,7 +9306,7 @@ BOOST_AUTO_TEST_CASE(mutex)
// NOTE: It is very bad practice to write this function this way. // NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly. // Please refer to the documentation of how to do this properly.
if (amount > shares) throw; if (amount > shares) throw;
if (!msg.sender.call.value(amount)()) throw; if (!msg.sender.call.value(amount)("")) throw;
shares -= amount; shares -= amount;
return shares; return shares;
} }
@ -9320,7 +9314,7 @@ BOOST_AUTO_TEST_CASE(mutex)
// NOTE: It is very bad practice to write this function this way. // NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly. // Please refer to the documentation of how to do this properly.
if (amount > shares) throw; if (amount > shares) throw;
if (!msg.sender.call.value(amount)()) throw; if (!msg.sender.call.value(amount)("")) throw;
shares -= amount; shares -= amount;
return shares; return shares;
} }
@ -9393,7 +9387,7 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_proper)
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt) function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt)
returns (address) returns (address)
{ {
require(hash == keccak256(blockExpired, salt)); require(hash == keccak256(abi.encodePacked(blockExpired, salt)));
return ecrecover(hash, v, r, s); return ecrecover(hash, v, r, s);
} }
} }
@ -9425,7 +9419,7 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_asm)
BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws) BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
{ {
char const* sourceCode = R"( char const* sourceCode = R"YY(
contract D { function g(); } contract D { function g(); }
contract C { contract C {
D d = D(0x1212); D d = D(0x1212);
@ -9438,11 +9432,11 @@ BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
return 7; return 7;
} }
function h() returns (uint) { function h() returns (uint) {
d.call(); // this does not throw (low-level) d.call(""); // this does not throw (low-level)
return 7; return 7;
} }
} }
)"; )YY";
compileAndRun(sourceCode, 0, "C"); compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f()"), encodeArgs()); ABI_CHECK(callContractFunction("f()"), encodeArgs());
ABI_CHECK(callContractFunction("g()"), encodeArgs()); ABI_CHECK(callContractFunction("g()"), encodeArgs());
@ -11446,17 +11440,17 @@ BOOST_AUTO_TEST_CASE(inlineasm_empty_let)
BOOST_AUTO_TEST_CASE(bare_call_invalid_address) BOOST_AUTO_TEST_CASE(bare_call_invalid_address)
{ {
char const* sourceCode = R"( char const* sourceCode = R"YY(
contract C { contract C {
/// Calling into non-existant account is successful (creates the account) /// Calling into non-existant account is successful (creates the account)
function f() external returns (bool) { function f() external returns (bool) {
return address(0x4242).call(); return address(0x4242).call("");
} }
function h() external returns (bool) { function h() external returns (bool) {
return address(0x4242).delegatecall(); return address(0x4242).delegatecall("");
} }
} }
)"; )YY";
compileAndRun(sourceCode, 0, "C"); compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1))); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1)));
ABI_CHECK(callContractFunction("h()"), encodeArgs(u256(1))); ABI_CHECK(callContractFunction("h()"), encodeArgs(u256(1)));
@ -11474,13 +11468,13 @@ BOOST_AUTO_TEST_CASE(delegatecall_return_value)
return value; return value;
} }
function get_delegated() external returns (bool) { function get_delegated() external returns (bool) {
return this.delegatecall(bytes4(keccak256("get()"))); return this.delegatecall(abi.encodeWithSignature("get()"));
} }
function assert0() external view { function assert0() external view {
assert(value == 0); assert(value == 0);
} }
function assert0_delegated() external returns (bool) { function assert0_delegated() external returns (bool) {
return this.delegatecall(bytes4(keccak256("assert0()"))); return this.delegatecall(abi.encodeWithSignature("assert0()"));
} }
} }
)DELIMITER"; )DELIMITER";

View File

@ -265,18 +265,18 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops)
// Information in joining branches is not retained anymore. // Information in joining branches is not retained anymore.
BOOST_AUTO_TEST_CASE(retain_information_in_branches) BOOST_AUTO_TEST_CASE(retain_information_in_branches)
{ {
// This tests that the optimizer knows that we already have "z == keccak256(y)" inside both branches. // This tests that the optimizer knows that we already have "z == keccak256(abi.encodePacked(y))" inside both branches.
char const* sourceCode = R"( char const* sourceCode = R"(
contract c { contract c {
bytes32 d; bytes32 d;
uint a; uint a;
function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) { function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) {
bytes32 z = keccak256(y); bytes32 z = keccak256(abi.encodePacked(y));
if (x > 8) { if (x > 8) {
z = keccak256(y); z = keccak256(abi.encodePacked(y));
a = x; a = x;
} else { } else {
z = keccak256(y); z = keccak256(abi.encodePacked(y));
a = x; a = x;
} }
r_a = a; r_a = a;
@ -313,19 +313,19 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions)
contract test { contract test {
bytes32 data; bytes32 data;
function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
r_d = keccak256(y); r_d = keccak256(abi.encodePacked(y));
shared(y); shared(y);
r_d = keccak256(y); r_d = keccak256(abi.encodePacked(y));
r_a = 5; r_a = 5;
} }
function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
r_d = keccak256(y); r_d = keccak256(abi.encodePacked(y));
shared(y); shared(y);
r_d = bytes32(uint(keccak256(y)) + 2); r_d = bytes32(uint(keccak256(abi.encodePacked(y))) + 2);
r_a = 7; r_a = 7;
} }
function shared(bytes32 y) internal { function shared(bytes32 y) internal {
data = keccak256(y); data = keccak256(abi.encodePacked(y));
} }
} }
)"; )";
@ -370,7 +370,7 @@ BOOST_AUTO_TEST_CASE(sequence_number_for_calls)
// to storage), so the sequence number should be incremented. // to storage), so the sequence number should be incremented.
char const* sourceCode = R"( char const* sourceCode = R"(
contract test { contract test {
function f(string a, string b) returns (bool) { return sha256(a) == sha256(b); } function f(string a, string b) returns (bool) { return sha256(bytes(a)) == sha256(bytes(b)); }
} }
)"; )";
compileBothVersions(sourceCode); compileBothVersions(sourceCode);

View File

@ -1,12 +1,10 @@
contract C { contract C {
uint constant a = b * c; uint constant a = b * c;
uint constant b = 7; uint constant b = 7;
uint constant c = b + uint(keccak256(d)); uint constant c = b + uint(keccak256(abi.encodePacked(d)));
uint constant d = 2 + a; uint constant d = 2 + a;
} }
// ---- // ----
// Warning: (98-110): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (98-110): The provided argument of type uint256 is not implicitly convertible to expected type bytes memory.
// TypeError: (17-40): The value of the constant a has a cyclic dependency via c. // TypeError: (17-40): The value of the constant a has a cyclic dependency via c.
// TypeError: (71-111): The value of the constant c has a cyclic dependency via d. // TypeError: (71-129): The value of the constant c has a cyclic dependency via d.
// TypeError: (117-140): The value of the constant d has a cyclic dependency via a. // TypeError: (135-158): The value of the constant d has a cyclic dependency via a.

View File

@ -1,9 +1,7 @@
contract C { contract C {
uint constant a = b * c; uint constant a = b * c;
uint constant b = 7; uint constant b = 7;
uint constant c = 4 + uint(keccak256(d)); uint constant c = 4 + uint(keccak256(abi.encode(d)));
uint constant d = 2 + b; uint constant d = 2 + b;
} }
// ---- // ----
// Warning: (98-110): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (98-110): The provided argument of type uint256 is not implicitly convertible to expected type bytes memory.

View File

@ -1,6 +1,6 @@
contract test { contract test {
function f() pure public { function f() pure public {
bytes32 x = sha3(); bytes32 x = sha3("");
x; x;
} }
function g() public { function g() public {
@ -8,5 +8,5 @@ contract test {
} }
} }
// ---- // ----
// TypeError: (58-64): "sha3" has been deprecated in favour of "keccak256" // TypeError: (58-66): "sha3" has been deprecated in favour of "keccak256"
// TypeError: (99-150): "suicide" has been deprecated in favour of "selfdestruct" // TypeError: (101-152): "suicide" has been deprecated in favour of "selfdestruct"

View File

@ -0,0 +1,13 @@
contract C {
function f() public {
require(address(this).call());
require(address(this).call(bytes4(0x12345678)));
require(address(this).call(uint(1)));
require(address(this).call(uint(1), uint(2)));
}
}
// ----
// TypeError: (55-75): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use "" as argument to provide empty calldata.
// TypeError: (113-131): Invalid type for argument in function call. Invalid implicit conversion from bytes4 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
// TypeError: (170-177): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
// TypeError: (197-233): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.

View File

@ -0,0 +1,11 @@
contract C {
function f() public {
require(address(this).callcode());
require(address(this).callcode(uint(1)));
require(address(this).callcode(uint(1), uint(2)));
}
}
// ----
// TypeError: (55-79): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use "" as argument to provide empty calldata.
// TypeError: (121-128): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
// TypeError: (148-188): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.

View File

@ -0,0 +1,11 @@
contract C {
function f() public {
require(address(this).delegatecall());
require(address(this).delegatecall(uint(1)));
require(address(this).delegatecall(uint(1), uint(2)));
}
}
// ----
// TypeError: (55-83): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use "" as argument to provide empty calldata.
// TypeError: (129-136): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
// TypeError: (156-200): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.

View File

@ -0,0 +1,11 @@
contract C {
function f() public {
require(keccak256() != 0);
require(keccak256(uint(1)) != 0);
require(keccak256(uint(1), uint(2)) != 0);
}
}
// ----
// TypeError: (55-66): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (100-107): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (132-159): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.

View File

@ -0,0 +1,11 @@
contract C {
function f() public {
require(ripemd160() != 0);
require(ripemd160(uint(1)) != 0);
require(ripemd160(uint(1), uint(2)) != 0);
}
}
// ----
// TypeError: (55-66): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (100-107): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (132-159): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.

View File

@ -0,0 +1,11 @@
contract C {
function f() public {
require(sha256() != 0);
require(sha256(uint(1)) != 0);
require(sha256(uint(1), uint(2)) != 0);
}
}
// ----
// TypeError: (55-63): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (94-101): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// TypeError: (126-150): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.

View File

@ -0,0 +1,5 @@
contract C {
function f() pure public { abi.encode(2**500); }
}
// ----
// TypeError: (55-61): Invalid rational number (too large or division by zero).

View File

@ -1,7 +0,0 @@
contract C {
function f() public { keccak256(2**500); }
}
// ----
// Warning: (39-56): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (39-56): The provided argument of type int_const 3273...(143 digits omitted)...9376 is not implicitly convertible to expected type bytes memory.
// TypeError: (49-55): Invalid rational number (too large or division by zero).

View File

@ -2,8 +2,8 @@ contract C {
function f() public { function f() public {
address addr; address addr;
uint balance = addr.balance; uint balance = addr.balance;
bool callRet = addr.call(); bool callRet = addr.call("");
bool delegatecallRet = addr.delegatecall(); bool delegatecallRet = addr.delegatecall("");
bool sendRet = addr.send(1); bool sendRet = addr.send(1);
addr.transfer(1); addr.transfer(1);
balance; callRet; delegatecallRet; sendRet; balance; callRet; delegatecallRet; sendRet;

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function () pure returns (bytes32) // TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32)

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-57): Member "gas" not found or not visible after argument-dependent lookup in function () pure returns (bytes32) // TypeError: (47-57): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32)

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function () pure returns (bytes20) // TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes20)

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-62): Member "value" not found or not visible after argument-dependent lookup in function () pure returns (bytes32) - did you forget the "payable" modifier? // TypeError: (47-62): Member "value" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32) - did you forget the "payable" modifier?

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-59): Member "value" not found or not visible after argument-dependent lookup in function () pure returns (bytes32) - did you forget the "payable" modifier? // TypeError: (47-59): Member "value" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32) - did you forget the "payable" modifier?

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (47-62): Member "value" not found or not visible after argument-dependent lookup in function () pure returns (bytes20) - did you forget the "payable" modifier? // TypeError: (47-62): Member "value" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes20) - did you forget the "payable" modifier?

View File

@ -7,9 +7,6 @@ contract C {
function g(bytes32) pure internal {} function g(bytes32) pure internal {}
} }
// ---- // ----
// Warning: (54-72): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. // TypeError: (64-71): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// Warning: (54-72): The provided argument of type uint256 is not implicitly convertible to expected type bytes memory. // TypeError: (92-99): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// Warning: (85-100): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. // TypeError: (123-130): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
// Warning: (85-100): The provided argument of type uint256 is not implicitly convertible to expected type bytes memory.
// Warning: (113-131): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (113-131): The provided argument of type uint256 is not implicitly convertible to expected type bytes memory.

View File

@ -1,13 +1,13 @@
contract C { contract C {
function f() public pure { function f() public pure {
bool a = address(this).call(address(this).delegatecall, super); bool a = address(this).call(abi.encode(address(this).delegatecall, super));
bool b = address(this).delegatecall(log0, tx, mulmod); bool b = address(this).delegatecall(abi.encode(log0, tx, mulmod));
a; b; a; b;
} }
} }
// ---- // ----
// TypeError: (80-106): This type cannot be encoded. // TypeError: (91-117): This type cannot be encoded.
// TypeError: (108-113): This type cannot be encoded. // TypeError: (119-124): This type cannot be encoded.
// TypeError: (160-164): This type cannot be encoded. // TypeError: (183-187): This type cannot be encoded.
// TypeError: (166-168): This type cannot be encoded. // TypeError: (189-191): This type cannot be encoded.
// TypeError: (170-176): This type cannot be encoded. // TypeError: (193-199): This type cannot be encoded.

View File

@ -4,11 +4,10 @@ contract C {
struct T { uint y; } struct T { uint y; }
T t; T t;
function f() public view { function f() public view {
bytes32 a = sha256(s, t); bytes32 a = sha256(abi.encodePacked(s, t));
a; a;
} }
} }
// ---- // ----
// Warning: (132-144): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. // TypeError: (156-157): This type cannot be encoded.
// TypeError: (139-140): This type cannot be encoded. // TypeError: (159-160): This type cannot be encoded.
// TypeError: (142-143): This type cannot be encoded.

View File

@ -6,12 +6,11 @@ contract C {
struct T { uint y; } struct T { uint y; }
T t; T t;
function f() public view { function f() public view {
bytes32 a = sha256(s, t); bytes32 a = sha256(abi.encodePacked(s, t));
a; a;
} }
} }
// ---- // ----
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
// Warning: (167-179): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data. // TypeError: (191-192): This type cannot be encoded.
// TypeError: (174-175): This type cannot be encoded. // TypeError: (194-195): This type cannot be encoded.
// TypeError: (177-178): This type cannot be encoded.

View File

@ -5,12 +5,13 @@ contract C {
T t; T t;
enum A { X, Y } enum A { X, Y }
function f() public pure { function f() public pure {
bool a = address(this).delegatecall(S, A, A.X, T, uint, uint[]); bytes memory a = abi.encodePacked(S, A, A.X, T, uint, uint[]);
a;
} }
} }
// ---- // ----
// TypeError: (176-177): This type cannot be encoded. // TypeError: (174-175): This type cannot be encoded.
// TypeError: (179-180): This type cannot be encoded. // TypeError: (177-178): This type cannot be encoded.
// TypeError: (187-188): This type cannot be encoded. // TypeError: (185-186): This type cannot be encoded.
// TypeError: (190-194): This type cannot be encoded. // TypeError: (188-192): This type cannot be encoded.
// TypeError: (196-202): This type cannot be encoded. // TypeError: (194-200): This type cannot be encoded.

View File

@ -1,26 +1,8 @@
contract C { contract C {
function f() pure public returns (bytes32) {
return keccak256(1);
}
function h() pure public returns (bytes32) {
return sha256(1);
}
function j() pure public returns (bytes32) {
return ripemd160(1);
}
function k() pure public returns (bytes) { function k() pure public returns (bytes) {
return abi.encodePacked(1); return abi.encodePacked(1);
} }
} }
// ---- // ----
// Warning: (87-88): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning. // Warning: (92-93): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
// Warning: (77-89): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (77-89): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// Warning: (168-169): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
// Warning: (161-170): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (161-170): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// Warning: (252-253): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
// Warning: (242-254): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (242-254): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// Warning: (341-342): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.

View File

@ -1,34 +1,9 @@
pragma experimental "v0.5.0"; pragma experimental "v0.5.0";
contract C { contract C {
function f() pure public returns (bytes32) {
return keccak256(1);
}
function g() pure public returns (bytes32) {
return sha3(1);
}
function h() pure public returns (bytes32) {
return sha256(1);
}
function j() pure public returns (bytes32) {
return ripemd160(1);
}
function k() pure public returns (bytes) { function k() pure public returns (bytes) {
return abi.encodePacked(1); return abi.encodePacked(1);
} }
} }
// ---- // ----
// TypeError: (117-118): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. // TypeError: (122-123): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.
// TypeError: (107-119): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// TypeError: (107-119): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// TypeError: (191-198): "sha3" has been deprecated in favour of "keccak256"
// TypeError: (196-197): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.
// TypeError: (191-198): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// TypeError: (191-198): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// TypeError: (277-278): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.
// TypeError: (270-279): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// TypeError: (270-279): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// TypeError: (361-362): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.
// TypeError: (351-363): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// TypeError: (351-363): The provided argument of type int_const 1 is not implicitly convertible to expected type bytes memory.
// TypeError: (450-451): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.

View File

@ -1,13 +1,4 @@
contract C { contract C {
function f() pure public returns (bytes32) {
return keccak256(uint8(1));
}
function h() pure public returns (bytes32) {
return sha256(uint8(1));
}
function j() pure public returns (bytes32) {
return ripemd160(uint8(1));
}
function k() pure public returns (bytes) { function k() pure public returns (bytes) {
return abi.encodePacked(uint8(1)); return abi.encodePacked(uint8(1));
} }
@ -16,9 +7,3 @@ contract C {
} }
} }
// ---- // ----
// Warning: (77-96): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (77-96): The provided argument of type uint8 is not implicitly convertible to expected type bytes memory.
// Warning: (168-184): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (168-184): The provided argument of type uint8 is not implicitly convertible to expected type bytes memory.
// Warning: (256-275): This function only accepts a single "bytes" argument. Please use "abi.encodePacked(...)" or a similar function to encode the data.
// Warning: (256-275): The provided argument of type uint8 is not implicitly convertible to expected type bytes memory.

View File

@ -3,13 +3,13 @@ contract C {
address(this).transfer(1); address(this).transfer(1);
require(address(this).send(2)); require(address(this).send(2));
selfdestruct(address(this)); selfdestruct(address(this));
require(address(this).delegatecall()); require(address(this).delegatecall(""));
require(address(this).call()); require(address(this).call(""));
} }
function g() pure public { function g() pure public {
bytes32 x = keccak256("abc"); bytes32 x = keccak256("abc");
bytes32 y = sha256("abc"); bytes32 y = sha256("abc");
address z = ecrecover(1, 2, 3, 4); address z = ecrecover(bytes32(1), uint8(2), bytes32(3), bytes32(4));
require(true); require(true);
assert(true); assert(true);
x; y; z; x; y; z;