--- tags: 2020, Ethereum --- 智能合約 (Smart contract) === ## 概要 * 將程式建構於區塊鏈上的一種特殊協議 * 具有類似第三方認證的信任機制 * 交易可追蹤、佈署後不可撤回 ## 佈署教學 ### 預處理 1. 安裝並建立 [Metamask](https://golden.com/wiki/Metamask) 帳戶 * 瀏覽器和以太坊網絡之間的橋樑 > :warning: **助憶詞跟私鑰請小心保存**, 那是代表你的唯一依據 2. 選 Ropsten 測試網路, 存入->測試水管->取得乙太幣 3. ~~嘗試跟人轉轉幣看看, 發送->輸入公鑰位置->確認~~ > ~~迷之音: 你沒有朋友~~ 5. 開啟 [Remix IDE](https://remix.ethereum.org/) * Ethereum 官方 IDE * 等等用來寫智能合約用 ### hello world 1. Remix IDE 選擇 solidity, 開新檔案 2. 輸入以下程序 ```solidity pragma solidity ^0.4.25; contract helloworld { function sayhi() public pure returns (string){ return "Hello World"; } } ``` 3. Solidity compiler->compile 4. Deploy->Environment->injected Web3->Metamask, Deploy * Deploy->At Address->... * Deployed Contracts->... ### HW.1 ```solidity pragma solidity ^0.4.25; contract owo { struct incoming { uint amount; string cause; } struct outgoing { uint amount; string cause; } uint currentTotal = 0; uint totalIncoming = 0; uint totalOutgoing = 0; incoming[] private IncomingList; outgoing[] private OutgoingList; function pushIncoming(uint amount, string cause) public { if (amount >= 0) { incoming memory update = incoming(amount, cause); IncomingList.push(update); totalIncoming++; currentTotal += amount; } } function pushOutgoing(uint amount, string cause) public { if (amount >= 0 && amount <= currentTotal) { outgoing memory update = outgoing(amount, cause); OutgoingList.push(update); totalOutgoing++; currentTotal -= amount; } } function viewBalance() public view returns (uint) { return currentTotal; } function viewTotalNumOfIncoming() public view returns (uint) { return totalIncoming; } function viewTotalNumOfOutgoing() public view returns (uint) { return totalOutgoing; } function viewIncomingRecord(uint i) public view returns (uint, string) { if (i > 0 && i <= totalIncoming) { return (IncomingList[i-1].amount, IncomingList[i-1].cause); } else { return (0, 'index out of range.'); } } function viewOutgoingRecord(uint i) public view returns (uint, string) { if (i > 0 && i <= totalOutgoing) { return (OutgoingList[i-1].amount, OutgoingList[i-1].cause); } else { return (0, 'index out of range.'); } } } ```