Merge pull request #5353 from ethereum/docInteroperability

[DOCS] Document interoperability between 0.5.0 and pre-0.5.0 contracts.
This commit is contained in:
chriseth 2018-11-08 11:36:44 +01:00 committed by GitHub
commit d3e111d493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,7 +12,8 @@ For the full list check
Contracts compiled with Solidity v0.5.0 can still interface with contracts
and even libraries compiled with older versions without recompiling or
redeploying them. Changing the interfaces to include data locations and
visibility and mutability specifiers suffices.
visibility and mutability specifiers suffices. See the
:ref:`Interoperability With Older Contracts <interoperability>` section below.
Semantic Only Changes
=====================
@ -272,6 +273,83 @@ Syntax
``override``, ``partial``, ``promise``, ``reference``, ``sealed``,
``sizeof``, ``supports``, ``typedef`` and ``unchecked``.
.. _interoperability:
Interoperability With Older Contracts
=====================================
It is still possible to interface with contracts written for Solidity versions prior to
v0.5.0 (or the other way around) by defining interfaces for them.
Consider you have the following pre-0.5.0 contract already deployed:
::
// This will not compile with the current version of the compiler
pragma solidity ^0.4.25;
contract OldContract {
function someOldFunction(uint8 a) {
//...
}
function anotherOldFunction() constant returns (bool) {
//...
}
// ...
}
This will no longer compile with Solidity v0.5.0. However, you can define a compatible interface for it:
::
pragma solidity >0.4.99 <0.6.0;
interface OldContract {
function someOldFunction(uint8 a) external;
function anotherOldFunction() external returns (bool);
}
Note that we did not declare ``anotherOldFunction`` to be ``view``, despite it being declared ``constant`` in the original
contract. This is due to the fact that starting with Solidity v0.5.0 ``staticcall`` is used to call ``view`` functions.
Prior to v0.5.0 the ``constant`` keyword was not enforced, so calling a function declared ``constant`` with ``staticcall``
may still revert, since the ``constant`` function may still attempt to modify storage. Consequently, when defining an
interface for older contracts, you should only use ``view`` in place of ``constant`` in case you are absolutely sure that
the function will work with ``staticcall``.
Given the interface defined above, you can now easily use the already deployed pre-0.5.0 contract:
::
pragma solidity >0.4.99 <0.6.0;
interface OldContract {
function someOldFunction(uint8 a) external;
function anotherOldFunction() external returns (bool);
}
contract NewContract {
function doSomething(OldContract a) public returns (bool) {
a.someOldFunction(0x42);
return a.anotherOldFunction();
}
}
Similarly, pre-0.5.0 libraries can be used by defining the functions of the library without implementation and
supplying the address of the pre-0.5.0 library during linking (see :ref:`commandline-compiler` for how to use the
commandline compiler for linking):
::
pragma solidity >0.4.99 <0.6.0;
library OldLibrary {
function someFunction(uint8 a) public returns(bool);
}
contract NewContract {
function f(uint8 a) public returns (bool) {
return OldLibrary.someFunction(a);
}
}
Example
=======