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