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