---
# System prepended metadata

title: 智能合約 (Smart contract)
tags: ['2020', ' Ethereum']

---

---
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.');
		}
	}
}
```