Preamble
Solidity is a programming language familiar to blockchain application developers, used to build smart contracts. In this 0.6 version, solidity has made significant changes to support the construction of smart contracts.
Major changes
Abstract
The abstract
keyword used to denote a contract is abstract (only declare the function, not implement its functions) – similar to the abstract class in Java. Contract must be declared abstract when at least 1 function is not implemented, but it is still possible to declare a contract as abstract even though all of its functions have been implemented.
Need to distinguish abstract
from interface
. All functions in the interface
are not implemented.
For example:
1 2 3 4 5 6 7 8 9 10 | pragma solidity <span class="token operator">^</span> <span class="token number">0.6</span> <span class="token number">.0</span> <span class="token punctuation">;</span> abstract contract Feline <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">utterance</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> virtual <span class="token function">returns</span> <span class="token punctuation">(</span> bytes32 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> contract Cat is Feline <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">utterance</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> override <span class="token function">returns</span> <span class="token punctuation">(</span> bytes32 <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"miaow"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Note: When a contract inherits from 1
abstract
contract. and do not execute all non-implemented functions by overriding it, the contract must also be declared asabstract
.
Virtual and override
A function can now only be overridden if it is declared with virtual
keyword or defined in interface
or abstract
contract. When we want to override or change a function, we use the override
keyword. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | pragma solidity <span class="token operator">>=</span> <span class="token number">0.6</span> <span class="token number">.0</span> <span class="token operator"><</span> <span class="token number">0.7</span> <span class="token number">.0</span> <span class="token punctuation">;</span> contract Base <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> virtual <span class="token keyword">public</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> contract Middle is Base <span class="token punctuation">{</span> <span class="token punctuation">}</span> contract Inherited is Middle <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> override <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
In case of multiple inheritance, the original function with the same name needs to be explicitly specified after the override
keyword. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | pragma solidity <span class="token operator">>=</span> <span class="token number">0.6</span> <span class="token number">.0</span> <span class="token operator"><</span> <span class="token number">0.7</span> <span class="token number">.0</span> <span class="token punctuation">;</span> contract Base1 <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> virtual <span class="token keyword">public</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> contract Base2 <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> virtual <span class="token keyword">public</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> contract Inherited is Base1 <span class="token punctuation">,</span> Base2 <span class="token punctuation">{</span> <span class="token comment">// Derives from multiple bases defining foo(), so we must explicitly</span> <span class="token comment">// override it</span> <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token function">override</span> <span class="token punctuation">(</span> Base1 <span class="token punctuation">,</span> Base2 <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Note: the private function cannot be declared as virtual.
Length of array
Access to the length of arrays will always be read-only, even for storage arrays. Now we cannot change the length of the array by assigning a new value to its length. Instead, we'll use the push
and pop
functions, or you can assign a whole new array to the old array.
The function push(value)
for dynamic arrays no longer returns the new length of the array. Example of old usage:
1 2 | uint length <span class="token operator">=</span> zombies <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> <span class="token function">Zombie</span> <span class="token punctuation">(</span> _name <span class="token punctuation">,</span> _dna <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Now the push function merely adds a new element to the array and returns nothing else.
Fallback function
The function without a previous name implies that the fallback function in this version will be split as fallback
and receive
, without the preceding function
keyword. For example:
How to declare old fallback:
1 2 3 4 5 6 7 8 9 10 | contract Test <span class="token punctuation">{</span> <span class="token comment">// This function is called for all messages sent to</span> <span class="token comment">// this contract (there is no other function).</span> <span class="token comment">// Sending Ether to this contract will cause an exception,</span> <span class="token comment">// because the fallback function does not have the `payable`</span> <span class="token comment">// modifier.</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> external <span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> uint x <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
New declaration method:
1 2 3 4 5 6 7 8 9 10 | contract Test <span class="token punctuation">{</span> <span class="token comment">// This function is called for all messages sent to</span> <span class="token comment">// this contract (there is no other function).</span> <span class="token comment">// Sending Ether to this contract will cause an exception,</span> <span class="token comment">// because the fallback function does not have the `payable`</span> <span class="token comment">// modifier.</span> <span class="token function">fallback</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> external <span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> uint x <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Receive function: A contract has at least 1 receive function, using the syntax receive() external payable { ... }
. This function has no parameters nor returns anything. It is called when calling the contract without any data transfer but only eth transfer. If no functions receive
, it will fall into the fallback
is declared as payable
. Without both the receive
and fallback
functions with payable
, the contract will not be able to accept eth and fire an exception.
1 2 3 4 5 6 7 8 9 10 11 | pragma solidity <span class="token operator">^</span> <span class="token number">0.6</span> <span class="token number">.0</span> <span class="token punctuation">;</span> <span class="token comment">// This contract keeps all Ether sent to it with no way</span> <span class="token comment">// to get it back.</span> contract Sink <span class="token punctuation">{</span> event <span class="token function">Received</span> <span class="token punctuation">(</span> address <span class="token punctuation">,</span> uint <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">receive</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> external payable <span class="token punctuation">{</span> emit <span class="token function">Received</span> <span class="token punctuation">(</span> msg <span class="token punctuation">.</span> sender <span class="token punctuation">,</span> msg <span class="token punctuation">.</span> value <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Try / Catch
An external call
upon failure can be captured by the try/catch
as shown in the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | pragma solidity <span class="token operator">^</span> <span class="token number">0.6</span> <span class="token number">.0</span> <span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">DataFeed</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">getData</span> <span class="token punctuation">(</span> address token <span class="token punctuation">)</span> external <span class="token function">returns</span> <span class="token punctuation">(</span> uint value <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> contract FeedConsumer <span class="token punctuation">{</span> DataFeed feed <span class="token punctuation">;</span> uint errorCount <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">rate</span> <span class="token punctuation">(</span> address token <span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token function">returns</span> <span class="token punctuation">(</span> uint value <span class="token punctuation">,</span> bool success <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Permanently disable the mechanism if there are</span> <span class="token comment">// more than 10 errors.</span> <span class="token function">require</span> <span class="token punctuation">(</span> errorCount <span class="token operator"><</span> <span class="token number">10</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">try</span> feed <span class="token punctuation">.</span> <span class="token function">getData</span> <span class="token punctuation">(</span> token <span class="token punctuation">)</span> <span class="token function">returns</span> <span class="token punctuation">(</span> uint v <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> v <span class="token punctuation">,</span> <span class="token boolean">true</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token function">Error</span> <span class="token punctuation">(</span> string memory <span class="token comment">/*reason*/</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// This is executed in case</span> <span class="token comment">// revert was called inside getData</span> <span class="token comment">// and a reason string was provided.</span> errorCount <span class="token operator">++</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token boolean">false</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">bytes</span> memory <span class="token comment">/*lowLevelData*/</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// This is executed in case revert() was used</span> <span class="token comment">// or there was a failing assertion, division</span> <span class="token comment">// by zero, etc. inside getData.</span> errorCount <span class="token operator">++</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token boolean">false</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Struct and Enum:
Struct and enum can now be declared at the file level.
Address:
Cannot convert from external function
type to address
type. Instead, the external function type will have 1 component as the address. For example:
address(f)
converts to f.address
with f being the external function type.
- It is possible to convert the
address
type to theaddress payable
type using the payable (x) syntax, where x is the address type.
Conclude
Above are the noticeable changes in version 0.6.0 of Solidity. Hopefully the above article will help you in developing your Dapp.
Source:
https://solidity.readthedocs.io/en/v0.6.7/060-breaking-changes.html