區塊鏈技術暨金融科技應用研習營

- 智能合約

Ming-der Wang, twitter @mingderwang

ming@Log4Analytics.com

 

JULY 17, 2016

王銘德

本課程你能學到

  • 了解什麼是智能合約
  • 至少能看得懂 Solidity 程式碼
  • 動手做: 至少能寫你第一張 "智能合約" Hello World
  • 能執行你的合約, 跟別人交換合約來執行

 

如果你做了你的客製化 "tokens" (代幣)

  • 透過你的Ethereum Wallet, 跟別個同學互相交換 tokens

blockchain 網路

如何在 blockchain 網路上開發應用 (app)?

也就是寫一個所謂的"智能合約“

 

 

Bitcoin 這個 blockchain 只能

執行它現有的功能, 不能開發程式

 

比如:

轉帳(A, B, 多少錢)

Ethereum 網路

Ethereum 是一個 blockchain

可以轉帳 (Ether幣), 也能寫程式

也就是寫一個所謂的"智能合約“

 

那什麼是 "智能合約" - Smart Contracts ?

舉一個簡單的例子

你跟你的好朋友, 賭明天是好天氣或壞天氣, 輸的人給對方 50 塊

 

舉一個簡單的例子

你跟你的好朋友, 賭明天是好天氣或壞天氣, 輸的人給對方 50 塊

 

但如果跟一個不認識的賭呢?

 

對方可能會不認帳

舉一個簡單的例子

你跟你的好朋友, 賭明天是好天氣或壞天氣, 輸的人給對方 50 塊

 

那先一個人交出 50 塊, 有第三人來仲裁?

 

第三人可能拿了錢落跑 !!

舉一個簡單的例子

這麼簡單的問題, 就寫成一個 "智能合約"

合約可寫成以下三個功能:

 

繳錢(帳號位址)

檢查結果

發錢

 

什麼東西可以寫成或利用 S.C.

  • 需要 3rd Party Trusts (“第三方信託") 時
  • 需要公開透明, 卻又不能篡改的東西 (比如說, 歷史?x, 音樂版權?)
  • 你跟政府有簽合約嗎? 你為何相信政府的鈔票? (美金呢?)

 

例如:

  • 眾籌募資: Digix        , WeiFund,        TheDAO 
  • 選舉, 選委員, 民主投票, 公證, 契約...
  • 網路樂透, 
  • 想些超大的應用? 你生活周遭發生的事, 能用 S.C.來解決嗎?

開發環境

  • 開發程式, 你不會用真 Ether幣, 在真的 Ethereum 網路跑程式, 你要用 TEST-NET

  • 建議用 Ethereum 官方網站的 Wallet (mist) 選用 TEST-NET 來測試程式

  • 確定都沒問題, 再到真的 Ethereum 網路去執行

  •  微軟的 Visual Studio 也可以開發 Ethereum, 但不確定成熟度如何

  • Solidity Realtime Compiler 是一個 online 編輯器和編譯器, 也可以用用看

 

Ethereum Wallet

Solidity Realtime Compiler

Solidiy 語言的特性

  • 它也是物件導向程式語言
  • 除了 float 以外, 有各種 types
  • 也有 structs 結構
  • 有 mappings (a kind of arrays)
  • 有 arrays
  • 有一個 address 特殊 object
  • data location 資料放哪?
  • 有 functions and exceptions
  • 完整的說明文件

Mortal

contract mortal {
    address owner;
    function mortal() {

          owner = msg.sender;     }

    /* Function to recover the funds on the contract */
    function kill() {

          if (msg.sender == owner)

     selfdestruct(owner);    }
}

HelloWorld

contract helloworld is mortal {

    /* helloworld inherits all behaviors of mortal, such as function mortal(), kill() and owner */ 

string storeData;
  function set(string x) {
    storeData = x;  }
  function get() constant returns (string data) {
    return storeData;  }

}

Object-Oriented - inheritance

Types

bool

int8, int16, int24 ... int256

uint8, uint16,  ... uint256

uint and int are aliases for uint256 and int256,

address

string

bytes1, bytes2, bytes3, ..., bytes32.

byte is an alias for bytes1

structs

 struct Funder {
    address addr;
    uint amount;
  }
  • NO rational number so far.

Explicit Conv. 

int8 y = -3;
uint x = uint(y);

Type Deduction

uint20 x = 0x123;
var y = x;

// y will be unit20 too

uint32 a = 0x12345678;
uint16 b = uint16(a); 
// b will be 0x5678 now
  • The type is only deduced from the first assignment, so the loop in the following snippet is infinite, as i will have the type uint8 and any value of this type is smaller than 2000. for (var i = 0; i < 2000; i++) { ... }

mappings

  • Mapping types are declared as mapping (_KeyType => _ValueType), where _KeyType can be almost any type except for a mapping and _ValueType can actually be any type, including mappings.
  • Mappings are only allowed for state variables (or as storage reference types in internal functions).
  • no length

contract MyToken { /* This creates an array with all balances */

mapping (address => uint256) public balanceOf;

function MyToken() {
     balanceOf[msg.sender] =
21000000; }

}

Arrays

contract C {
  function f(uint len) {
    uint[] memory a = new uint[](7);
    bytes memory b = new bytes(len);// memory
    // Here we have a.length == 7 and b.length == len
    a[6] = 8;
  }
}
  • An array of fixed size k and element type T is written as T[k], an array of dynamic size as T[].

bytes and string

Variables of type bytes and string are special arrays. A bytes is similar to byte[], but it is packed tightly in calldata. string is equal to bytes but does not allow length or index access (for now).

 

  • So bytes should always be preferred over byte[] because it is cheaper.
  • also, array has a member called, length and push.
  • push is for appending elements.

Functions and Exceptions

contract Sharer {
    function sendHalf(address addr) returns (uint balance) {
        if (!addr.send(msg.value/2))
            throw; // also reverts the transfer to Sharer
        return this.balance;
    }
}

// 後註: throw 已經改用 require 或 assert.

// 詳見: https://medium.com/taipei-ethereum-meetup/solidity-weekly-7-587ccd90ec3e

Hands-On

To create a new contract, such as "Greeter"

https://www.ethereum.org/token#the-code

Hands-On 2

To use "MyToken" contract to send tokens

address' Methods

address holds a 20 byte value (size of an Ethereum address). Address types also have members, like send()

 

address x = 0x123;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.send(10);

All contracts inherit the members of address, so it is possible to query the balance of the current contract using this.balance.

if the address is a contract

address nameReg = 
0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2
; nameReg.call("register", "MyName"); nameReg.call(bytes4(sha3("fun(uint256)")), a);
  • call returns a boolean indicating whether the invoked function terminated (true) or caused an EVM exception (false).
  • delegatecall is to use library code which is stored in another contract.
  • callcode was available that did not provide access to the original msg.sender and msg.value values.

Data Location

calldata”, which is a non-modifyable non-persistent area where function arguments are stored. Function parameters (not return parameters) of external functions are forced to “calldata” and it behaves mostly like memory.

  • memory (which is not persisting)
  • storage (where the state variables are held).
  • calldata

Every complex type, i.e. arrays and structs, has an additional annotation, the “data location”.

Data Location (continue)

  •  Depending on the context, there is always a default, but it can be overridden by appending either storage or memory to the type.
  • The default for function parameters (including return parameters) is memory, the default for local variables is storage and the location is forced to storage for state variables (obviously).

// 後記:memory 省 gas

Example

contract c {

  uint[] x; // the data location of x is storage
  // the data location of memoryArray is memory
  
function f(uint[] memoryArray) {
    x = memoryArray; // works, copies the whole array to storage
    var y = x; // works, assigns a pointer, data location of y is storage
    y[7]; // fine, returns the 8th element
    y.length = 2; // fine, modifies x through y


    delete x; // fine, clears the array, also modifies y
    y = memoryArray; // not working
    delete y; // not working
    g(x); // calls g, handing over a reference to x
    h(x); // calls h and creates an independent, temporary copy in memory
  }
  function g(uint[] storage storageArray) internal {}
  function h(uint[] memoryArray) {}
}

delete

contract DeleteExample {
  uint data;
  uint[] dataArray;

  function f() {
    uint x = data;
    delete x; // sets x to 0, does not affect data
    delete data; // sets data to 0, does not affect x which still holds a copy
    
  }

    uint[] y = dataArray;

    delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
    // y is affected which is an alias to the storage object
    // On the other hand: "delete y" is not valid, as assignments to local variables
    // referencing storage objects can only be made from existing storage objects.
  }
}

Solidity Doc

如何讓別人執行你的Contract

[ { "constant": false, "inputs": [], "name": "kill", "outputs": [], "type": "function" }, { "constant": false, "inputs": [ { "name": "x", "type": "string" } ], "name": "set", "outputs": [], "type": "function" }, { "constant": true, "inputs": [], "name": "get", "outputs": [ { "name": "data", "type": "string", "value": "hello CCLiang" } ], "type": "function" } ]

跟你的 Contract Address

 
0x141fd413A40a4163A8ecF1A02f902A1abE8ff7c5

 

寄給他們 Contract JSON

按 Show Interface

點擊

Contract Address

Contract JSON Interface

想執行別人的 Contract

點擊

填入地址跟Contract JSON

Hello Contract

我有哪些 DApps 可以參考

http://dapps.ethercasts.com/

我還可以用其他語言寫 S.C. 嗎?

  • Solidity - Javascript/C++ like
  • Serpent - Python-like
  • LLL - Lisp-like
  • EtherScript - Scratch-like
    • ​類似早期的 Lego MindStroms
  • ​eris

 

 

Ethereum-based

Bitcoin-based

  • sidechain, counterparty, ...
  • ...

Q & A

EtherTW.slack.com 線上討論

https://goo.gl/S6nhKv   <---- 加入slack

 

ming@log4analytics.com

Further Reading: https://medium.com/@ConsenSys/a-101-noob-intro-to-programming-smart-contracts-on-ethereum-695d15c1dab4#.wxbzewj7w

JULY 17, 2016, 區塊鏈技術暨金融科技應用研習營 - 智能合約

By Ming-der Wang

JULY 17, 2016, 區塊鏈技術暨金融科技應用研習營 - 智能合約

  • 1,450