Solidity Programming
Solidity Programming
• Public − Public state variables can be accessed internally as well as via messages.
For a public state variable, an automatic getter function is generated.
• Internal − Internal state variables can be accessed only internally from the
current contract or contract deriving from it without using this.
• Private − Private state variables can be accessed only internally from the current
contract they are defined not in the derived contract from it.
pragma solidity ^0.5.0;
contract C {
uint public data = 30;
uint internal iData= 10;
contract test {
function testArray() public pure{
uint len = 7;
//dynamic array
uint[] memory a = new uint[](7);
assert(a.length == 7);
assert(b.length == len);
//static array
uint[3] memory c = [uint(1) , 2, 3];
assert(c.length == 3);
}
}
Solidity - Enums
• pragma solidity ^0.5.0;
• contract test {
• enum FreshJuiceSize{ SMALL, MEDIUM, LARGE }
• FreshJuiceSize choice;
• FreshJuiceSize constant defaultChoice = FreshJuiceSize.MEDIUM;
• contract test {
• struct Book {
• string title;
• string author;
• uint book_id;
• }
• Book book;
• contract LedgerBalance {
• mapping(address => uint) public balances;
• contract Test {
• function getResult() public view returns(uint){
• uint a = 1; // local variable
• uint b = 2;
• uint result = a + b;
• return result;
• }
•}
Solidity - Function Modifiers
• Function Modifiers are used to modify the behaviour of a function. • contract Register is Owner {
• pragma solidity ^0.5.0;
• mapping (address => bool) registeredAddresses;
• contract Owner { • uint price;
• address owner; • constructor(uint initialPrice) public { price =
• constructor() public { initialPrice; }
• owner = msg.sender;
•
• }
• modifier onlyOwner { • function register() public payable costs(price) {
• require(msg.sender == owner); • registeredAddresses[msg.sender] = true;
• _;
• }
• }
• modifier costs(uint price) { • function changePrice(uint _price) public
• if (msg.value >= price) { onlyOwner {
• _; • price = _price;
• }
• }
• }
• } • }
Solidity - View Functions
• View functions ensure that they will not modify the state. A function can be declared as view. The following statements if present in the
function are considered modifying the state and compiler will throw warning in such cases.
• Emitting events.
• Using selfdestruct.
• Accessing any of the special variable of block, tx, msg (msg.sig and msg.data can be read).
• Pure functions can use the revert() and require() functions to revert potential state changes if an error occurs.
• pragma solidity ^0.5.0;
• contract Test {
• function getResult() public pure returns(uint product, uint sum){
• uint a = 1;
• uint b = 2;
• product = a * b;
• sum = a + b;
• }
•}
Solidity - Fallback Function
• Fallback function is a special function available to a contract. It has following features −
• It has no name.
• It has no arguments
• If not marked payable, it will throw exception if contract receives plain ether without data.
pragma solidity ^0.5.0;
contract Test {
uint public x ;
function() external { x = 1; }
}
contract Sink {
function() external payable { }
}
contract Caller {
function callTest(Test test) public returns (bool) {
(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
require(success);
// test.x is now 1
• State Variables − Variables per Contract to store the state of the contract.
• Functions − Functions per Contract which can modify the state variables to
alter the state of a contract.
Visibility Quantifiers
• Following are various visibility quantifiers for functions/state variables of a contract.
• external − External functions are meant to be called by other contracts. They cannot be used for
internal call. To call external function within contract this.function_name() call is required. State
variables cannot be marked as external.
• public − Public functions/ Variables can be used both externally and internally. For public state
variable, Solidity automatically creates a getter function.
• internal − Internal functions/ Variables can only be used internally or by derived contracts.
• private − Private functions/ Variables can only be used internally and not even by derived
contracts.
Solidity - Inheritance
• Inheritance is a way to extend functionality of a contract. Solidity supports both single as well as
multiple inheritance. Following are the key highlighsts.
• A derived contract can access all non-private members including internal methods and state
variables. But using this is not allowed.
• Function overriding is allowed provided function signature remains same. In case of difference
of output parameters, compilation will fail.
• We can call a super contract's function using super keyword or using super contract name.
• In case of multiple inheritance, function call using super gives preference to most derived
contract.
Multi-level Inheritance
• Multi-level inheritance is similar to the single level, but the difference
is, it has levels of parent-child relationships. The child contract—
derived from a parent contract—also acts as a parent contract of
another contract. Take a look at the following diagram:
Hierarchical Inheritance
• In hierarchical inheritance, the base contract has over one derived
contract. This inheritance is useful when one common functionality is
used in multiple places. The following diagram is displayed the type
hierarchical, where a single contract is a parent of multiple child
contracts.
Multiple Inheritance
• Unlike C# and Java, Solidity supports multiple-inheritance. The single
contract can be inherited from more than one contract. Here, in the
following diagram, shown is the multiple-inheritance.
Solidity - Error Handling
• Solidity provides various functions for error handling. Generally when an error occurs, the state is reverted back to its
original state. Other checks are to prevent unauthorized code access. Following are some of the important methods used in
error handling −
• assert(bool condition) − In case condition is not met, this method call causes an invalid opcode and any changes done to
state got reverted. This method is to be used for internal errors.
• require(bool condition) − In case condition is not met, this method call reverts to original state. - This method is to be used
for errors in inputs or external components.
• require(bool condition, string memory message) − In case condition is not met, this method call reverts to original state. -
This method is to be used for errors in inputs or external components. It provides an option to provide a custom message.
• revert() − This method aborts the execution and revert any changes done to the state.
• revert(string memory reason) − This method aborts the execution and revert any changes done to the state. It provides an
option to provide a custom message.
Assert Statement
• Its syntax is similar to the require statement. It returns a boolean value after the
evaluation of the condition. Based on the return value either the program will continue
its execution or it will throw an exception. Instead of returning the unused gas, the
assert statement consumes the entire gas supply and the state is then reversed to the
original state. Assert is used to check the current state and function conditions before
the execution of the contract. Below are some cases with assert type exceptions :
• contract Vendor {
• address public seller;
• modifier onlySeller() {
• require(
• msg.sender == seller,
• "Only seller can call this."
• );
• _;
• }
• function sell(uint amount) public payable onlySeller {
• if (amount > msg.value / 2 ether)
• revert("Not enough Ether provided.");
• // Perform the sell operation.
• }
• }