back Home

Overview

Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.

As you will see, it is possible to create contracts for voting, crowdfunding, blind auctions, multi-signature wallets and more.

Getting Started

The solidity compiler can be installed with:

npm install -g solc

where the commands runs as solcjs

The Language

Versioning - the firs line of the solidity contract defines the verson of solidity that was wirtten and compiled under:

 
pragma solidity ^0.4.22;

The start of the contract is used to declare the variables and constants of the contract e.g.

 
 uint public value;

the data types supported:

  • int / uint: Signed and unsigned integers. uint8, uint24, uint32, uint40, uint48, uint176, unint256
  • fixed / ufixed: Signed and unsigned fixed point number of various sizes.
  • bool - boolean value of true or false
  • address: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as a base for all contracts.
    • members of address include types of balance and transfer
    • send is the low-level counterpart of transfer. If the execution fails, the current contract will not stop with an exception, but send will return false.
  • bytes1, bytes2, bytes3, …, bytes32. byte is an alias for bytes1.
  • bytes: Dynamically-sized byte array, see Arrays
  • string: dynamically-sized UTF-8-encoded string. String literals are written with either double or single-quotes “foo” or 'bar'
  • address type. Hexadecimal literals that are between 39 and 41 digits long

Enums Enums are one way to create a user-defined type in Solidity

 enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }

For examples:

 
pragma solidity ^0.4.22;

contract Purchase {
    uint public value;
    address public seller;
    address public buyer;
    enum State { Created, Locked, Inactive }
    State public state;

    // Ensure that `msg.value` is an even number.
    // Division will truncate if it is an odd number.
    // Check via multiplication that it wasn't an odd number.
    constructor() public payable {
        seller = msg.sender;
        value = msg.value / 2;
        require((2 * value) == msg.value, "Value has to be even.");
    }

Functions

Functions are executable code blocks that can be passed variables and return values. Function types can also be used to pass functions to and return functions from function calls.

function f() public view returns (bytes4) {
    return this.f.selector;
  }

A function signature can be:

function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]

Function types come in two flavours - internal and external functions:

  • By default, function types are internal, so the internal keyword can be omitted.
  • Contract functions themselves are public by default, only when used as the name of a type, the default is internal.
  • Internal functions can only be called inside the current contract (more specifically, inside the current code unit, which also includes internal library functions and inherited functions) because they cannot be executed outside of the context of the current contract. Calling an internal function is realized by jumping to its entry label, just like when calling a function of the current contract internally.

Contract by Example

A simple(st) contract:

pragma solidity ^0.4.0;
 
contract SimpleStorage {
    uint storedData;
 
    function set(uint x) public {
        storedData = x;
    }
 
    function get() public view returns (uint) {
        return storedData;
    }
}

Transfer of ownership

pragma solidity ^0.4.19;
 
contract Ownable {
 
    address public owner;
 
    function Ownable() public {
        owner = msg.sender;
    }
 
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
 
    function transferOwnership(address _newOwner) public onlyOwner {
        owner = _newOwner;
    }
}
 
contract ERC721CrowdSale is Ownable {
 
    string public name;
    address public wallet;
    uint256 public token_goal;
 
    function ERC721CrowdSale(string _name, address _wallet, uint256 _token_goal) public {
        name = _name;
        wallet = _wallet;
        token_goal = _token_goal;
    }
    //...
 
}
 
contract CS_Creator is Ownable{
  ERC721CrowdSale _cs;
 
  function create_crowdsale(string _name, address _wallet, uint256 _token_goal) onlyOwner returns(address, address){
      address _new_crowdsale = new ERC721CrowdSale(_name,  _wallet,  _token_goal);
      transfer_CS_ownership(_new_crowdsale, _wallet);
      return (_new_crowdsale, get_CS_ownership(_new_crowdsale));
  }
 
  function transfer_CS_ownership(address _new_crowdsale, address _wallet)  internal {
      _cs = ERC721CrowdSale(_new_crowdsale);
      _cs.transferOwnership(_wallet);
  }
 
  function get_CS_ownership(address _crowdsale) public returns(address) {
      return ERC721CrowdSale(_crowdsale).owner();
  }
}

Contract Best Practice

  • External Calls - Use caution when making external calls. Calls to untrusted contracts can introduce several unexpected risks or errors.
    • External calls may execute malicious code in that contract or any other contract that it depends upon. As such, every external call should be treated as a potential security risk. When it is not possible, or undesirable to remove external calls, use the recommendations in the rest of this section to minimize the danger.

https://consensys.github.io/smart-contract-best-practices/recommendations/

Platforms - Zeppelin-Solidity

Platforms - Truffle

  • Ethereum development framework http://truffleframework.com
    • Ganache CLI, part of the Truffle suite of Ethereum development tools, is the command line version of Ganache, your personal blockchain for Ethereum development.

Ganache

Install

npm install -g ganache-cli
 
smart_contracts.txt · Last modified: 2018/09/04 10:01 by root
 
RSS - 200 © CrosswireDigitialMedia Ltd