[區塊鏈-以太坊] 募資平台建立-Part 4. 核准

Chiwen Lai
7 min readJun 7, 2018

--

上一篇Part 3. 提出資金花費項目之後,接下來我們要讓贊助人核准。

  1. 由首頁的合約位址點入,帶到該募資計畫的詳細頁面。
  2. 從募資計畫的詳細頁面點選「查看花費項目」。
  3. 在花費項目頁面列出所有的花費項目,包含投票中,以及提案人已確認的花費。
  4. 針對投票中的花費項目,贊助人可以按「核准」,核准人數會統計加1。

STEP 1: Backend

▼開啟/contracts/Campaign.sol,加上核准花費項目的Function。

function approveRequest(uint index) public {
// 1 - 宣告
Request storage request = requests[index];
// 2 - 檢查
require(contributors[msg.sender]);
require(!request.approvals[msg.sender]);
// 3 - 核准
request.approvals[msg.sender] = true;
request.approvalCount++;

}

// 1 — 宣告request為Request型態的變數,index由前端帶入,也就是當使用者在頁面核准的時候就指定是哪一筆花費項目。
// 2 — 檢查1是否為贊助者,2是否已核准過該筆花費項目,已成為贊助者,且未核准過該筆花費項目,才可做核准動作,也就是每位贊助者只能夠核准一次。
// 3 — 核准花費項目,將msg.sender位址記錄到核准者的mapping裏,再將核准人數加1。

STEP 2: 重新部署

▼合約寫好後需重新部署。

$ node compile.js
$ node deploy.js
Contract deployed to 0x1A5A0B196Ff86B5120df3724F63c1b5ef401Fc3E

▼將新的合約位址更新到factory.js,如下。

import web3 from "./web3";
import CampaignFactory from "./build/CampaignFactory.json";
const instance = new web3.eth.Contract(
JSON.parse(CampaignFactory.interface),
"0x1A5A0B196Ff86B5120df3724F63c1b5ef401Fc3E"
);
export default instance;

STEP 3: Frontend

▼在components目錄下面新增檔案RequestRow.js,作為列出花費項目的元件。在其中包含了核准的功能。按下核准按鈕,呼叫剛剛我們在合約內新增的onApprove()功能。

import React, { Component } from "react";
import { Table, Button } from "semantic-ui-react";
import web3 from "../ethereum/web3";
import Campaign from "../ethereum/campaign";
class RequestRow extends Component {
// 核准
onApprove = async () => {
const campaign = Campaign(this.props.address);
const accounts = await web3.eth.getAccounts();
await campaign.methods.approveRequest(this.props.id).send({
from: accounts[0]
});
};
render() {
const { Row, Cell } = Table;
const { id, request, contributorsCount } = this.props;
const readyToFinalize = request.approvalCount > contributorsCount / 2;
return (
<Row
disabled={request.complete}
positive={readyToFinalize && !request.complete}
>
<Cell>{id}</Cell>
<Cell>{request.description}</Cell>
<Cell>{web3.utils.fromWei(request.value, "ether")}</Cell>
<Cell>{request.recipient}</Cell>
<Cell>
{request.approvalCount}/{contributorsCount}
</Cell>
<Cell>
{request.complete ? null : (
<Button color="green" basic onClick={this.onApprove}>
核准
</Button>
)}

</Cell>
</Row>
);
}
}
export default RequestRow;

▼在花費項目頁面/campaigns/requests/index.js加上匯入RequestRow元件。

import RequestRow from "../../../components/RequestRow";

增加renderRows() Function,呼叫RequestRow。

  static async getInitialProps(props) {
const { address } = props.query;
const campaign = Campaign(address);
const requestCount = await campaign.methods.getRequestsCount().call();
// 增加核准人數的變數
const contributorsCount = await campaign.methods.contributorsCount().call();
const requests = await Promise.all(
Array(parseInt(requestCount))
.fill()
.map((element, index) => {
return campaign.methods.requests(index).call();
})
);
return { address, requests, requestCount, contributorsCount };
}
renderRows() {
return this.props.requests.map((request, index) => {
return (
<RequestRow
key={index}
id={index}
request={request}
address={this.props.address}
contributorsCount={this.props.contributorsCount}
/>
);
});
}

在render() Function裡的Table表頭下面加上呼叫renderRows() Function,並顯示花費項目的數量。

        <Table>
<Header>
<Row>
<HeaderCell>ID</HeaderCell>
<HeaderCell>花費項目</HeaderCell>
<HeaderCell>金額</HeaderCell>
<HeaderCell>廠商位址(以太幣接收方)</HeaderCell>
<HeaderCell>核准人數</HeaderCell>
<HeaderCell>核准</HeaderCell>
<HeaderCell>提案人確認</HeaderCell>
</Row>
</Header>
<Body>{this.renderRows()}</Body>
</Table>
<div>總共有 {this.props.requestCount} 個花費項目。</div>

▼接下來直接在終端機crowdfunding目錄下面輸入

$ npm run dev

即可在瀏覽器http://localhost:3000觀看到更新後的畫面。

>>>下一篇:Part 5. 確認資金花費項目

--

--