[區塊鏈-以太坊] 募資平台建立-Part 4. 核准
7 min readJun 7, 2018
上一篇Part 3. 提出資金花費項目之後,接下來我們要讓贊助人核准。
- 由首頁的合約位址點入,帶到該募資計畫的詳細頁面。
- 從募資計畫的詳細頁面點選「查看花費項目」。
- 在花費項目頁面列出所有的花費項目,包含投票中,以及提案人已確認的花費。
- 針對投票中的花費項目,贊助人可以按「核准」,核准人數會統計加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. 確認資金花費項目