วันอังคารที่ 29 ตุลาคม พ.ศ. 2562

Smart Contract คืออะไร ???

          ในการทำ สัญญา อาจจะมีปัญญาเรื่องความปลอดภัย เช่น การปลอมแปลงเอกสารแบบกระดาษ  หรือขั้นตอนในการมานั่งตรวจสอบเอกสาร
Nick Szabo จึงมองเห็นว่า "ในเมื่อหนึ่งในแนวคิดของ Blockchain คือการให้ทุกคนถือเอกสารชุดเดียวกัน เมื่อมีการอัปเดตก็จะอัปเดตด้วยกัน โดยมั่นใจได้ว่าเอกสารเหล่านั้น เชื่อถือได้แน่นอนไม่มีการปลอมแปลง" Nick Szabo จึงคิดริเริ่มนำ Blockchain มาประยุกต์ในการทำ สัญญา การทำดังกล่าวจึงได้ชื่อเรียกว่า Smart contect เจ้าสิ่งนี้สามารถแก้ปัญญาเรื่องความปลอดภัยและการปลอมแปลงเอกสารแบบกระดาษ อีกทั้งยังไม่ต้องผ่านคนกลาง อีกทั้ง Smart contect ยังมีความสามารถ กำหนดขั้นตอนการทำธุรกรรมโดยอัตโนมัติไว้ล่วงหน้า เพราะ สัญญาเกิดจากการเขียนโค้ดคอมพิวเตอร์ จึงสามารถกำหนด ธุรกรรม ล่วงหน้าได้
โดย Smart Contract มีคุณสมบัติว่า

1) ไม่สามารถเปลี่ยนแปลงได้
2) ทุกคนสามารถเข้าถึงและดูได้ว่าโค้ดเขียนไว้อย่างไร
3) สามารถสร้างลอจิคการทำงานได้ตามที่ต้องการ
4) สามารถบันทึกข้อมูลที่ต้องการลงใน Blockchain ได้
5) ข้อมูลที่ถูกบันทึกไว้จะอยู่ตลอดไป หากข้อมูลมีการเปลี่ยนแปลงก็สามารถตรวจสอบได้ เพราะข้อมูลไม่มีทางหายไป

            แต่ถึงแม้ว่า Smart Contract จะสามารถพัฒนาสัญญาแบบเก่าได้ แต่ก็ไม่มีอะไรที่ไม่มีข้อเสียเลย ในกรณีที่เขียนโค้ดผิดพลาดก็จะเกิดความเสียหายได้มหาศาล แม้กระทั่ง Vitalik Buterin ผู้สร้าง Ethereum Blockchain เองยังออกมาเตือนว่าไม่ควรทำ Smart Contract ที่มีมูลค่าสูงมาก ดังนั้นการศึกษาเรื่องกฎหมายที่เกี่ยวข้องกับ Blockchain จึงมีความจำเป็นมาก

ต่อไปนี้คือ บันทึกการทดลองทำ Smart Contract ของผมนะครับ


เขียน Smart Contract


การเขียน Ethereum Smart Contract จะใช้ภาษา Solidity ซึ่ง IDE ที่ช่วยเขียนในที่นี้เราจะใช้ Remix เนื่องจาก ง่ายต่อการใช้งาน ไม่ต้องติดตั้ง และมี env สำหรับการ Deploy Contract




Link: www.remix.ethereum.org

ซึ่ง Code จะเป็นการเก็บค่า balance และดึงค่า balance


pragma solidity >=0.4.22 <0.7.0;
contract SimpleContract {
    uint balance;
 
    constructor() public { // caleed since it deploy to blockchain
        balance = 1000;
    }
 
    function setBalance(uint newBalance) public {
        balance = newBalance;
    }
 
    function getBalance() public view returns (uint) {
        return balance;
    }
}
Pic: remix.ethereum

จากนั้นกด compile


Pic: remix.ethereum

จากนั้นเราจะมา deploy Smart Contract เราโดยเลือก Env = JavaScript VM แล้ว deploy


Pic: remix.ethereum

ทำการ Test Method โดยเรา Test Method getBalance จะได้ 1000 ตาม constructor ที่เรากำหนดไว้ตอนแรก

Pic: remix.ethereum


จากนั้นเราจะเขียน Solidity ทำ Contract "Smart Lock" กันครับ ว่าแต่ Smart Lock คืออะไร คือ Contract การเช่าห้อง หรือเช่าล็อกเกอร์ครับ โดยจะตัดเงินเราทุกๆวันที่ X ของทุกๆเดือน โดย Code Solidity ที่เราจะเขียนจะเป็นแบบนี้ครับ

Code
pragma solidity >=0.4.22 <0.7.0;
contract SimpleContract {    uint balance;        constructor() public { // caleed since it deploy to blockchain        balance = 1000;    }        function setBalance(uint newBalance) public {         balance = newBalance;    }        function getBalance() public view returns (uint) {        return balance;    }        function checkLock() public view returns (uint) {        if(balance < 1000){            return 0; //False: Lock         }else{         return 1; //True: Open      }                      }    }


Pic

Pic: remix.ethereum

        จะเห็นได้ว่าเราเพิ่ม method "checkLock" เจ้า method จัวนี้เมื่อเราเรียกใช้จะทำการเช็ค balance ว่ามีเท่าไหร่ถ้ามีไม่ถึงตามที่เรากำหนดไว้ (ในตัวอย่างนี้คือ 1000) จะ return 0 หรือ false แต่ถ้าถึงตามที่กำหนดจะ return 1 หรือ true ถึงตอนนี้ทุกคนคงสงสัยว่า แล้วแบบนี้จะเป็น Smart Lock ได้อย่างไรถ้าเราต้องมาเรียกใช้ method นี้ทุกๆเดือน ดังนั้นเราจึงต้องสร้าง DApp ครับ เพื่อให้เจ้า DApp มาติดต่อกับ Smart Contract ให้เราครับ 

        ขอนอกเรื่องนิดนึง DApp หรือ Decentralized Application เป็นการเอา Smart Contract เข้ามาใช้ร่วมด้วยกับ application ดังนั้นแอพของเราจะได้ประโยชน์จากความปลอดภัย ของ blockchain และแอพยังสามารถเรียกใช้ method ของ Smart Contract ได้ด้วย 

        ดังนั้นเราจะทำการ Deploy Contract ของเราเข้าไปใน Network ของ blockchain ซึ่งในบทความนี้จะใช้ blockchain ของ Kovan ครับ ซึ่ง kovan คือ Network ที่มีไว้ทดสอบ Deploy Smart Contract ของเราได้ แต่ก่อนที่เราจะ Deploy เราจะต้องมี EtherWallet ก่อน 

Metamask EtherWallet

โดยเราจะเลือกใช้ Metamask 

1) ติดตั้ง Browser Extension ชื่อว่า Metamask เป็น กระเป๋าตังค์ Ethereum 
2) ติดตั้งเสร็จจะได้ icon รูปหมาจิ้งจอก 

Pic: Metamask

        ให้กดเพื่อทำการตั้ง password ให้เรียบร้อย จากนั้นก็ Next ๆๆ Accept ๆๆ ให้เรียบร้อย (อย่าลืมจด Secret Backup Phrase 12 คำ ไว้ด้วยเอาไว้กู้ Account Wallet กลับมาและเอาไว้ confirm ในหน้าถัดไป)

3) เมื่อกดเข้าไปใน icon หมาจิ้งจอก ตั้งแต่นี้จะเรียก Metamask นะ จะได้หน้าต่างแบบนี้ครับ ให้เราเลือก กดปุ่มตามลูกศรสีแดงในรูปเพื่อไปเอา address wallet ครับ

Pic: Metamark

Pic: Metamark

4) ซึ่งในขั้นตอนนี้กดเปลี่ยนเป็น Kovan ด้วยนะ จึงทำการขอเหรียญ Ethereum ซึงขอฟรีได้วันละ 1 เหรียญ แต่เนื่องจากเหรียญฟรี จึงใช้ได้แค่ test นะครับใช้จริงไม่ได้นะ 




Pic: faucet.kovan

5) เราจะสามารถกดดูเหรียญของเราได้ที่ Metamark ครับ

Pic: Metamark

Deploy Contract

1) จากนั้นมา Deploy Smart Contract ไปที่ Injected Web3 แล้วกด Deploy


Pic: Remix

2) หน้าต่าง pop up Metamark จะเด้งขึ้นมา เป็นการเก็บค่าธรรมเนียมนิดหน่อยครับ

 
Pic: Metamark

3) เมื่อเรา Deploy เสร็จแล้วให้เข้ามาที่ Metamark ไปในส่วนของ history จะเจอส่วนของ Contract Deployment แล้วกดที่วงกลมสีแดงตามรูปเพื่อเข้าไปยังหน้าต่าง Kovan Network เพื่อเอา address 

Pic: Metamark

Pic: Kovan


4) จากนั้นไปเอา ABI จากหน้า remix ในส่วนของ complie 

Pic: Remix

5) สร้างไฟล์ index.html โดยมี code ดังนี้ โดยให้เอา address และ abi ของเราไปใส่ใน code ส่วนของ script 

*** ในส่วนของการอธิบาย Code ผมได้ทำเป็นบทความแยกไว้นะครับ ***
Link: https://selectedtopicenarudon.blogspot.com/2019/11/code-client-smart-contract_3.html

Code


  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
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Digital Lock</title>
  <style>
  body {
    background-color:#F0F0F0;
    padding: 2em;
    font-family: 'Raleway','Source Sans Pro', 'Arial';
  }
  .container {
    width: 50%;
    margin: 0 auto;
  }
  label {
    display:block;
    margin-bottom:10px;
  }
  input {
    padding:10px;
    width: 50%;
    margin-bottom: 1em;
  }
  button {
    margin: 2em 0;
    padding: 1em 4em;
    display:block;
  }

  #balance {
    padding:1em;
    background-color:#fff;
    margin: 1em 0;
  }
  #status {
    font-weight:normal;
    font-family: monospace;
    padding:1em;
    background-color:#fff;
    margin: 1em 0;
  }
  </style>
</head>
<body>
  <!-- Form -->
  <div class="container">
    <h1>Basic Digital Lock</h1>

    <h2 id="showStatus">Status Room = <span id="statusRoom"></span></h2>
    <h3 id="time"> Time:  <span id="timeCount"></span></h3>

    <hr/>
    <br/>
    <h4 id="balance">Current Balance = <span id="currentBalance"></span></h4>
    <button id="button" style="display: block" onclick="javascript:getBalance()">Get New Balance</button>
    <hr/>
    <br/>
    <label for="newBalance" class="col-lg-2 control-label"><strong>New Balance</strong></label>
    <input id="newBalance" type="number" value="300" style="display: inline-block">
    <button id="button" style="display: inline-block" onclick="javascript:setBalance()">Set New Balance</button>
    <br/>
    <label><strong>Status</strong></label>
    <h4 id="status"></h4>
  </div>
</body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.37/dist/"></script>
<script>
function addStatusLine(text) {
  document.getElementById("status").innerHTML = text + "<br/><br/>" + document.getElementById("status").innerHTML;
}
var countTime = setInterval(checkLock, 1000);
function checkLock() {
  var d = new Date();
  // TODO: Call checkLock Smart Contract
  //addStatusLine("calling checkLock");
  document.getElementById("timeCount").innerHTML = d.toLocaleTimeString();
  SimpleContract.checkLock(function(errorLock,resultLock){
    if (resultLock == 1) {
      document.getElementById("statusRoom").innerText = "OPEN";
   }else {
      document.getElementById("statusRoom").innerText = "LOCK";
   }

  })
}
function getBalance() {
  //var d = new Date();
  addStatusLine("");
  addStatusLine("calling getBalance()");
  // TODO: Call getBalance Smart Contract
  SimpleContract.getBalance(function(errorGet,resultGet){
    addStatusLine("Current balance =" + resultGet);
    document.getElementById('currentBalance').innerText=resultGet;
  })
}
function setBalance() {
  // TODO: Call setBalance Smart Contract
  //addStatusLine("called");
  newBalance =parseInt(document.getElementById('newBalance').value);
  //addStatusLine(newBalance);
  SimpleContract.setBalance(newBalance,function(error,result){
    if(error){
      addStatusLine(error);
      return;
    }
    // addStatusLine("");
    addStatusLine("calling setBalance("+newBalance+")");
    txHash = result;
    addStatusLine("TxHash = <a href='https://kovan.etherscan.io/tx/"+
    result + "' target='_blank'>" + result + "</a>");
  });
}
// Initializing
if (typeof web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider); // inject from Metamask plugin
}
// Get default address
web3.eth.defaultAccount = web3.eth.accounts[0];
window.ethereum.enable();
// TODO: Replace your SimpleContract contract address here
var contractAddress = 'ใส่ address ของเรา';
// TODO: Replace your SimpleContract abi here
var abi = ใส่ ABI ของเรา;
// Create an interface to SimpleContract on TomoChain
var SimpleContractContract = web3.eth.contract(abi);
var SimpleContract = SimpleContractContract.at(contractAddress);
// Get Balance on the first load
getBalance();
</script>
</html>


Test

1) ทำการติดตั้ง Web Server for Chrome แล้วกด Launch app 

Pic: Web Server for Chrome

2) ทำการเลือก folder ที่เรา save index.html 

Pic: Web Server for Chrome

3) ทำการเปิด browser url http://127.0.0.1:8887 เราจะได้ web application ของเราซึ่งจะมีการนับเวลาเพื่อทำการเช็ค Balance ของเรา ซึ่งตอนนี้ Balance ของเรามีอยู่ 1200 ดังนั้น Status Room = OPEN 
แต่ถ้าเรา setBalance ใหม่ให้ต่ำกว่า 1000 เมื่อถึงเวลาที่เราตั้งไว้ ก็จะพบว่า Status Room = close 

Pic: Basic Digital Lock 

Pic: Basic Digital Lock 

ครั้งหน้าเราจะมาทำให้ DApp ของเราตัดเงินได้อัตโนมัตินะครับ
Update 1/11/2019

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Code Client Smart Contract auto transfer

ในครั้งนี้เราจะมาทำให้ Smart Contract ของเรา transfer auto กันครับ โดยเริ่มจากส่วนของ Smart contract ของเราก่อน เราได้เพิ่มฟังก์ชั่น ...