目錄
區(qū)塊鏈原理與技術(shù) 1
一、方案設(shè)計 1
合約機(jī)制 1
賬戶體系 2
案例 3
數(shù)據(jù)流圖 4
二、存儲設(shè)計 4
區(qū)塊鏈合約存儲 4
區(qū)塊鏈數(shù)據(jù)庫表結(jié)構(gòu) 5
服務(wù)器數(shù)據(jù)庫表結(jié)構(gòu) 6
三、合約核心功能 7
合約事件 7
金融機(jī)構(gòu)和政府機(jī)構(gòu)注冊 7
企業(yè)注冊 8
轉(zhuǎn)賬 8
還款 9
四、功能測試 12
創(chuàng)建用戶 12
賬戶審核 12
用戶注冊 15
給予信用額度 17
企業(yè)申請和轉(zhuǎn)移信用憑證 19
返還 20
五、界面展示 22
注冊頁面 23
管理面板 23
審核面板 24
轉(zhuǎn)賬頁面 25
確認(rèn)轉(zhuǎn)賬 26
還款頁面 27
確認(rèn)返還 28
查詢面板 29
六、心得體會 30
一、方案設(shè)計
合約機(jī)制
信用憑證
信用憑證指企業(yè)間簽發(fā)的應(yīng)收賬款單據(jù),以及金融機(jī)構(gòu)向車企簽發(fā)的應(yīng)收賬款單據(jù)。簡單來說,信用憑證指對企業(yè)未來盈利能力的衡量,或者企業(yè)債務(wù)。應(yīng)收賬款單據(jù)包含金額、逾期時間、和收款雙方。
信用憑證由債務(wù)方向債權(quán)方提供,表示債務(wù)方在一定時間前將會償還。因此信用憑證的流動方向和人民幣的流動方向相反:若債務(wù)方向債權(quán)方支付人民幣欠款,債權(quán)方就要向債務(wù)方返還相應(yīng)的信用憑證。
簽發(fā)信用憑證
信用憑證分借入和借出。企業(yè)在借出信用憑證時(欠債),不能超過自己所擁有的的信用憑證總額(借入-借出),以確保企業(yè)不會透支自己的信用。銀行在衡量企業(yè)的信用評級時,不能只看信用憑證凈值,因為信用憑證為 0 時不代表企業(yè)不欠錢,企業(yè)信用在未來的一段時間內(nèi),可能會因為信用憑證的逾期,導(dǎo)致信用為負(fù)。因此銀行在評估企業(yè)信用時,需要查詢企業(yè)的所有交易信息。
融資
信用憑證的產(chǎn)生和轉(zhuǎn)移都是一樣的,只不過信用憑證的產(chǎn)生是從金融機(jī)構(gòu)到企業(yè),而轉(zhuǎn)移是企業(yè)和企業(yè)間的轉(zhuǎn)移。企業(yè)還可以向銀行融資(借入人民幣),操作不太一樣,企業(yè)需要將自己的信用憑證轉(zhuǎn)移給銀行,銀行向企業(yè)提供人民幣貸款。到期時企業(yè)向銀行還款,銀行向企業(yè)返還信用憑證。
賬戶體系
本合約將用戶分為以下幾種
央行
合約的管理員賬戶(部署合約時傳入)由央行控制,允許央行審核、管理金融機(jī)構(gòu)和政府的賬號。審核機(jī)制允許央行審查賬戶的真實性,避免賬戶被冒名頂替。
央行可以通過調(diào)用合約更新自己的信用憑證總量,和增發(fā)貨幣一樣,該機(jī)制允許央行調(diào)節(jié)合約內(nèi)的信用憑證總量,以便進(jìn)行宏觀調(diào)控。
央行可以通過合約向銀行派發(fā)信用憑證,并設(shè)置有效期。這種方式類似央行的逆回購操作,是允許央行調(diào)節(jié)市場中信用憑證總量的另一個手段。通過審查金融機(jī)構(gòu)的擔(dān)保能力和信譽(yù),央行可以借此機(jī)制精準(zhǔn)調(diào)控每個金融機(jī)構(gòu)能派發(fā)的信用憑證總量。避免金融機(jī)構(gòu)過量擔(dān)保,產(chǎn)生造成經(jīng)濟(jì)不穩(wěn)定的因素。
央行具有合約數(shù)據(jù)庫的管理權(quán)限,央行可以直接修改合約數(shù)據(jù)庫,以便執(zhí)行合約未提供的高級操作。通過 FISCO-BCOS 提供的 CRUD 合約來查詢合約數(shù)據(jù)庫的數(shù)據(jù)、對某個賬號的交易進(jìn)行管理。
政府
政府賬戶只負(fù)責(zé)審核企業(yè)。由于企業(yè)比較多,管理員一般沒有足夠精力管理這么多賬戶,因此開設(shè)新的一個層級來管理企業(yè)。政府可以審核企業(yè)資質(zhì),準(zhǔn)許企業(yè)進(jìn)入?yún)^(qū)塊鏈,也可以剝奪企業(yè)的區(qū)塊鏈賬戶。
政府賬戶也是一個普通的賬戶,可以接受和轉(zhuǎn)移信用憑證,地方政府可以通過其區(qū)塊鏈賬戶來進(jìn)行融資操作。
金融機(jī)構(gòu)
金融機(jī)構(gòu)可以從央行獲得信用憑證,代表央行對金融機(jī)構(gòu)的信用評級,允許金融機(jī)構(gòu)最多擔(dān)保多少款項。金融機(jī)構(gòu)若遇到企業(yè)希望融資,可以查詢企業(yè)的相關(guān)信息:企業(yè)的借入借出憑證總額、企業(yè)的借入借出交易細(xì)表。以便金融機(jī)構(gòu)結(jié)合企業(yè)的實際情況和區(qū)塊鏈內(nèi)的信用派生情況,對企業(yè)的再盈利能力進(jìn)行評估。
金融機(jī)構(gòu)在為企業(yè)融資時,可能需要再次驗證企業(yè)的還款能力。金融機(jī)構(gòu)可以查詢區(qū)塊鏈內(nèi)所有企業(yè)的交易信息,因此金融機(jī)構(gòu)可以沿信用憑證轉(zhuǎn)移鏈查詢到信用憑證來源,也就是查詢到供應(yīng)鏈上游企業(yè)是向哪個金融機(jī)構(gòu)獲取信用憑證的。通過認(rèn)可供應(yīng)鏈上游企業(yè)依賴的金融機(jī)構(gòu)的信譽(yù),這個金融機(jī)構(gòu)便可以向該下游企業(yè)提供貸款。
企業(yè)
企業(yè)可以查詢自己的借入借出憑證,允許向其他企業(yè)轉(zhuǎn)移信用憑證,前提是雙方都要確認(rèn)交易。這樣供應(yīng)鏈下游企業(yè)就可以借助供應(yīng)鏈上游企業(yè)的信譽(yù),融到人民幣。
本文轉(zhuǎn)載自:http://www.biyezuopin.vip/onews.asp?id=16517
三、合約核心功能
合約事件
該合約會創(chuàng)建一些事件,以便其他合約能參與到信用憑證的轉(zhuǎn)移中來,提升合約的可擴(kuò)展性。文章來源:http://www.zghlxwxcb.cn/news/detail-489158.html
// 公司注冊事件event CompanyRegistration(address addr, string name);// 銀行注冊事件event BankRegistration(address addr, string name);// 政府注冊事件event GovernmentRegistration(address addr, string name);
// 信用憑證交易發(fā)起事件event TransactionBegin(address debtor, address debtee, int receiptId, int256 amount);// 信用憑證交易接受事件event TransactionEnd(address debtor, address debtee, int receiptId);
// 信用憑證銷毀發(fā)起事件event ReturnBegin(address debtor, address debtee, int receiptId, int amount);// 信用憑證銷毀接受事件event ReturnEnd(address debtor, address debtee, int receiptId, int amount);
金融機(jī)構(gòu)和政府機(jī)構(gòu)注冊
根據(jù)設(shè)計,金融機(jī)構(gòu)注冊需要央行確認(rèn)。通過在管理控制臺注冊時,管理控制臺會提交注冊信息給央行賬戶,央行賬戶確認(rèn)后將注冊信息提交到區(qū)塊鏈上。政府機(jī)構(gòu)賬號同理。區(qū)塊鏈合約注冊函數(shù)的代碼如下:
// 央行將指定賬戶設(shè)置為金融機(jī)構(gòu),信用額度function registerBank(address addr, string name) public {
require(msg.sender == adminAddr, "Only the Central Bank is allowed to banks registration");
insertCompany(addr, name, true, false, 0, 0);
emit BankRegistration(addr, name);}
// 政府賬號調(diào)用本函數(shù)將賬戶注冊為公司// 每個賬號只能注冊一次function registerGovernment(address addr, string name) public {
require(msg.sender == adminAddr, "Only the Central Bank is allowed to governments registration");
insertCompany(addr, name, false, true, 0, 0);
emit GovernmentRegistration(addr, name);}
區(qū)塊鏈合約保證只有央行賬戶可以調(diào)用該合約,將指定的金融機(jī)構(gòu)賬戶設(shè)置為金融機(jī)構(gòu)。
企業(yè)注冊
企業(yè)注冊和其他不同,企業(yè)注冊需要政府審核,因此檢查 msg.sender 是否是政府而不是央行。和銀行注冊類似,企業(yè)在管理控制臺注冊時,需要提供政府賬號,將注冊信息提交給政府審核。
// 政府賬號調(diào)用本函數(shù)將賬戶注冊為公司// 每個賬號只能注冊一次function registerCompany(address addr, string name) public {
findCompany(msg.sender);
require(company.gov, "Only governments are allowed to companies registration");
insertCompany(addr, name, false, false, 0, 0);
emit CompanyRegistration(addr, name);}
轉(zhuǎn)賬
轉(zhuǎn)賬分為提交轉(zhuǎn)賬和確認(rèn)轉(zhuǎn)賬兩個步驟。合約首先將轉(zhuǎn)賬提交到數(shù)據(jù)庫中記錄,允許債權(quán)人確認(rèn)接受轉(zhuǎn)賬和拒絕轉(zhuǎn)賬。轉(zhuǎn)賬為等待接受、接受、拒絕的狀態(tài)將被記錄到數(shù)據(jù)庫中。被拒絕的轉(zhuǎn)賬記錄會保留。
其中,提交轉(zhuǎn)賬不會改變雙方的賬款,只有債權(quán)方接受了轉(zhuǎn)賬后才會改變雙方的賬款。
// 由第三方金融機(jī)構(gòu)賬戶調(diào)用本函數(shù),表示 debtor 公司向 debtee 公司轉(zhuǎn)移信用憑證,// 或者 debtor 公司向 debtee 銀行借款(將 debtor 的信用轉(zhuǎn)移給銀行表示融資)// 或者 debtor 銀行向 debtee 公司提供信用憑證// debtor=msg.senderfunction transferCredit(address debtee, int amount, int deadline) public {
require(amount > 0, "You must transfer credits non negative");
int debtorIn; int debtorOut; (debtorIn, debtorOut) = findCompanyBalance(msg.sender); // 債務(wù)人 int debteeIn; int debteeOut; (debteeIn, debteeOut) = findCompanyBalance(debtee); // 債權(quán)人 require(debtorIn - debtorOut >= amount, "Debtor does not have enough balance");
nextReceiptId++;
insertReceipt("t_in_receipt", toString(debtee), msg.sender, debtee, nextReceiptId, amount, deadline, 0);
insertReceipt("t_out_receipt", toString(msg.sender), msg.sender, debtee, nextReceiptId, amount, deadline, 0);
emit TransactionBegin(msg.sender, debtee, nextReceiptId, amount);}
// 由債權(quán)人調(diào)用,表示接受債務(wù)人轉(zhuǎn)移的信用憑證// valid = 1 表示接受轉(zhuǎn)移,valid = 2 表示拒絕轉(zhuǎn)移function acceptTransferCredit(int receiptId, int valid) public {
require(valid == 1 || valid == 2, "Only accepting or declining are allowed");
findReceipt("t_in_receipt", toString(msg.sender), receiptId);
require(receipt.valid == 0, "Receipt to be accepted should be pending");
if (valid == 1) {
int debtorIn; int debtorOut; (debtorIn, debtorOut) = findCompanyBalance(msg.sender); // 債務(wù)人 int debteeIn; int debteeOut; (debteeIn, debteeOut) = findCompanyBalance(debtee); // 債權(quán)人 debtorOut += receipt.amount;
debteeIn += receipt.amount;
updateCompanyBalance(msg.sender, debtorIn, debtorOut);
updateCompanyBalance(debtee, debteeIn, debteeOut);
}
updateReceiptInt("t_in_receipt", toString(receipt.debtee), receiptId, "valid", valid, false);
updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "valid", valid, false);
emit TransactionEnd(receipt.debtor, receipt.debtee, receiptId);}
還款
還款分為提交還款和確認(rèn)還款兩個步驟。合約首先將還款提交到數(shù)據(jù)庫中記錄(通過更新轉(zhuǎn)賬數(shù)據(jù)庫實現(xiàn)),允許債務(wù)人確認(rèn)接受還款和拒絕還款。還款為等待接受、接受、拒絕的狀態(tài)將被記錄到數(shù)據(jù)庫中。被拒絕的還款記錄不像被拒絕的轉(zhuǎn)賬記錄,不會被保留。
和轉(zhuǎn)賬一樣,還款未被確認(rèn)前不會改變雙方的賬款,只有債務(wù)方接受了還款后才會改變雙方的賬款。
// 由債權(quán)人調(diào)用,表示返還信用憑證// debtee 公司向 debtor 公司返還信用憑證(表示 debtor 公司向 debtee 公司支付貨款)// debtee 公司向 debtor 銀行返還信用憑證(表示期限前撤銷信用憑證)// debtee 銀行向 debtor 公司返還信用憑證(公司完成融資還款)function returnCredit(int receiptId, int amount) public {
findReceipt("t_in_receipt", toString(msg.sender), receiptId);
int debtorIn; int debtorOut; (debtorIn, debtorOut) = findCompanyBalance(receipt.debtor); // 債務(wù)人 int debteeIn; int debteeOut; (debteeIn, debteeOut) = findCompanyBalance(receipt.debtee); // 債權(quán)人
require(amount > 0, "You must return credits non negative");
require(receipt.amount >= amount, "Cannot return credit more than amount transfered at first");
require(receipt.valid == 1, "Receipt should be already accepted");
updateReceiptInt("t_in_receipt", toString(receipt.debtee), receiptId, "valid", 3, false);
updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "valid", 3, false);
// 只更新一方的賬款,用兩側(cè)賬款差表示還款總額 updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "amount", receipt.amount - amount, false);
emit ReturnBegin(receipt.debtor, receipt.debtee, receiptId, amount);}
// 由債務(wù)人調(diào)用,表示接受債權(quán)人返還的信用憑證function acceptReturnCredit(int receiptId, int valid) public {
require(valid == 1 || valid == 2, "Only accepting or declining are allowed");
findReceipt("t_out_receipt", toString(msg.sender), receiptId);
Receipt memory outReceipt = receipt;
findReceipt("t_in_receipt", toString(receipt.debtee), receiptId);
Receipt memory inReceipt = receipt;
require(inReceipt.valid == outReceipt.valid, "Receipt states are nonconsistent");
require(inReceipt.valid == 3, "Only Receipts pending for returning are allowed to accept");
require(outReceipt.amount < inReceipt.amount, "Receipts states are nonconsistent");
int debtorIn; int debtorOut; (debtorIn, debtorOut) = findCompanyBalance(receipt.debtor); // 債務(wù)人 int debteeIn; int debteeOut; (debteeIn, debteeOut) = findCompanyBalance(receipt.debtee); // 債權(quán)人 int amount = inReceipt.amount - outReceipt.amount;
if (valid == 1) { // 接受返還信用憑證 // 同步兩側(cè)賬款 updateReceiptInt("t_in_receipt", toString(receipt.debtee), receiptId, "amount", outReceipt.amount, true);
updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "amount", outReceipt.amount, true);
debtorOut -= amount;
debteeIn -= amount;
updateCompanyBalance(receipt.debtor, debtorIn, debtorOut);
updateCompanyBalance(receipt.debtee, debteeIn, debteeOut);
} else { // 拒絕返還信用憑證,恢復(fù)賬款 // 恢復(fù)單側(cè)賬款 updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "amount", inReceipt.amount, true);
}
// 恢復(fù)賬款到接受狀態(tài) updateReceiptInt("t_in_receipt", toString(receipt.debtee), receiptId, "valid", 1, false);
updateReceiptInt("t_out_receipt", toString(receipt.debtor), receiptId, "valid", 1, false);
emit ReturnEnd(receipt.debtor, receipt.debtee, receiptId, amount);}
文章來源地址http://www.zghlxwxcb.cn/news/detail-489158.html
到了這里,關(guān)于區(qū)塊鏈的供應(yīng)鏈金融系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!