aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/miscellaneous.rst5
-rw-r--r--docs/units-and-global-variables.rst25
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp30
-rw-r--r--test/libsolidity/syntaxTests/constructor_this.sol12
-rw-r--r--test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol28
-rw-r--r--test/libsolidity/syntaxTests/parsing/constructor_super.sol10
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();
+ }
+}