diff options
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/miscellaneous.rst | 5 | ||||
-rw-r--r-- | docs/units-and-global-variables.rst | 25 | ||||
-rw-r--r-- | libsolidity/analysis/StaticAnalyzer.cpp | 30 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/constructor_this.sol | 12 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol | 28 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/parsing/constructor_super.sol | 10 |
7 files changed, 105 insertions, 6 deletions
diff --git a/Changelog.md b/Changelog.md index 201450c7..91048cd5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Features: * General: Allow providing reason string for ``revert()`` and ``require()``. * General: Limit the number of errors output in a single run to 256. * General: Support accessing dynamic return data in post-byzantium EVMs. + * General: Add encoding routines ``abi.encodePacked``, ``abi.encode``, ``abi.encodeWithSelector`` and ``abi.encodeWithSignature``. * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract. * Optimizer: Optimize ``SHL`` and ``SHR`` only involving constants (Constantinople only). * Optimizer: Remove useless ``SWAP1`` instruction preceding a commutative instruction (such as ``ADD``, ``MUL``, etc). diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 8270727f..c7c32528 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -317,6 +317,11 @@ The following is the order of precedence for operators, listed in order of evalu Global Variables ================ +- ``abi.encode(...) returns (bytes)``: :ref:`ABI <ABI>`-encodes 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 + starting from the second and prepends the given four-byte selector +- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(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.coinbase`` (``address``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 9d5821d5..51f7b9f3 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -44,9 +44,10 @@ Special Variables and Functions =============================== There are special variables and functions which always exist in the global -namespace and are mainly used to provide information about the blockchain. +namespace and are mainly used to provide information about the blockchain +or are general-use utility functions. -.. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin +.. index:: abi, block, coinbase, difficulty, encode, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin Block and Transaction Properties @@ -90,6 +91,26 @@ Block and Transaction Properties You can only access the hashes of the most recent 256 blocks, all other values will be zero. +.. index:: abi, encoding, packed + +ABI Encoding Functions +---------------------- + +- ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes)``: Performes packed encoding of 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 +- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(signature), ...)``` + +.. note:: + 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 + explicit way to compute ``keccak256(a, b)``, which will be deprecated in future + versions. + +See the documentation about the :ref:`ABI <ABI>` and the +:ref:`tightly packed encoding <abi_packed_mode>` for details about the encoding. + .. index:: assert, revert, require Error Handling diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 51aa0b28..00a581d0 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -206,10 +206,32 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) ); } - if (m_constructor && m_currentContract) - if (ContractType const* type = dynamic_cast<ContractType const*>(_memberAccess.expression().annotation().type.get())) - if (type->contractDefinition() == *m_currentContract) - m_errorReporter.warning(_memberAccess.location(), "\"this\" used in constructor."); + if (m_constructor) + { + auto const* expr = &_memberAccess.expression(); + while(expr) + { + if (auto id = dynamic_cast<Identifier const*>(expr)) + { + if (id->name() == "this") + m_errorReporter.warning( + id->location(), + "\"this\" used in constructor. " + "Note that external functions of a contract " + "cannot be called while it is being constructed."); + break; + } + else if (auto tuple = dynamic_cast<TupleExpression const*>(expr)) + { + if (tuple->components().size() == 1) + expr = tuple->components().front().get(); + else + break; + } + else + break; + } + } return true; } diff --git a/test/libsolidity/syntaxTests/constructor_this.sol b/test/libsolidity/syntaxTests/constructor_this.sol new file mode 100644 index 00000000..9d22a161 --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor_this.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure {} + constructor() public { + C c = this; + c.f(); // this does not warn now, but should warn in the future + this.f(); + (this).f(); + } +} +// ---- +// Warning: (172-176): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed. +// Warning: (191-195): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed. diff --git a/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol new file mode 100644 index 00000000..9f714aea --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol @@ -0,0 +1,28 @@ +contract A { + function a() public pure { + } +} +contract B { + constructor(address) public { + } + function b(address) public returns (A) { + return new A(); + } +} +contract C { + B m_b; + C m_c; + constructor(C other_c) public { + m_c = other_c; + m_b = new B(this); + m_b.b(this).a(); + g(this).f(); + other_c.f(); + m_c.f(); + } + function f() public pure { + } + function g(C) public view returns (C) { + return m_c; + } +} diff --git a/test/libsolidity/syntaxTests/parsing/constructor_super.sol b/test/libsolidity/syntaxTests/parsing/constructor_super.sol new file mode 100644 index 00000000..fa1be187 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constructor_super.sol @@ -0,0 +1,10 @@ +contract A { + function x() pure internal {} +} + +contract B is A { + constructor() public { + // used to trigger warning about using ``this`` in constructor + super.x(); + } +} |