跳转至

为银行构建支付解决方案

今天,银行和其他金融科技公司开发了许多应用和服务,让我们可以发送和接受支付。但我们没有一款应用程序能让收发钱像收发短信一样简单。尽管比特币和其他加密货币使得在世界各地发送和接收支付变得非常容易,但由于波动性和监管问题,它们现在无法成为主流。在本章中,我们将构建一个 P2P 支付系统,使发送和接收银行间支付变得非常容易,也使银行间的清算和结算变得近乎实时和简单。在构建解决方案时,我们还将学习各种银行和金融概念。

在本章中,我们将学习以下内容:

  • 对于国内和国际银行间电子转账,银行之间如何进行清算和结算
  • 环球银行金融电信协会系统和银行间的国际资金转移是如何工作的
  • 区块链法定货币的数字化及其解决的问题
  • 如何在仲裁中实现网络许可
  • 如何构建使用手机号码转账的解决方案

支付系统概述

在本章中,我们将构建一个集成到移动银行应用程序中的支付解决方案。这一解决方案将允许客户使用手机号码进行支付。只用一个手机号码向世界上的任何人付款将是最友好的付款方式。

我们的解决方案将使用数字化法定货币进行银行间转账的结算和清算。为了理解我们为什么选择使用数字化法定货币作为结算媒介,让我们了解一下银行间转账及其问题的结算和清算是如何进行的。

银行间转账的结算和清算

我们先来了解一下国内跨行转账是怎么操作的。每个县的中央银行都有一个以上不同类型的中央电子资金转账系统。比如印度的即时支付服务 ( IMPS )、美国的自动清算中心 ( ACH )、加拿大的电子资金转账 ( EFT )。该国的银行利用这些系统相互发送信息,以便于向客户转移资金。传递的只是信息,不是真钱。最终结算通过结算账户进行。每家银行在中央银行都有一个结算账户,每当有转账信息时,资金就被记入这些账户的贷方或借方。为了更清楚地理解这一点,我们来看一个例子。

假设银行 A 在中央银行有一个结算账户,账户中有 50,000 美元。类似地,假设银行 B 在中央银行有一个包含 100,000 美元的结算账户。现在,假设 X 是银行 A 的客户,而 Y 是银行 B 的客户。当 X 想给 Y 汇 100 美元时,银行 A 通过资金转账系统向银行 B 发送消息,表明它已经从 X 的账户借记了 100 美元,并将 100 美元贷记到 Y 在银行 B 的账户。在看到这条消息后,银行 B 继续向 Y 的账户存入 100 美元。为了结算该支付,中央银行从银行 A 的结算账户中借记 100 美元,因此新的余额为 49,900 美元,并将 100 美元贷记到银行 B 的结算账户中,因此新的余额为 100,100 美元。

中央银行通常每天在特定时间进行一次最终结算。消息传输接近实时。这一过程运作良好,因为参与的两家银行都信任央行。

让我们看看国际银行间转账是如何进行的。在这种情况下,涉及两个不同国家的两家银行,国际支付的工作方式不同于国内转账。在国际支付的情况下,银行使用 SWIFT 系统发送信息。SWIFT 是一个报文传送网络,金融机构使用它通过标准化的代码系统安全地传输信息和指令。SWIFT 为每个金融机构分配一个 8 或 11 个字符的唯一代码。该代码可互换地称为银行识别码(【BIC】)、SWIFT 代码、SWIFT ID 或 ISO 9362 代码。

要了解更多有关 SWIFT 的信息,请访问https://www . investopedia . com/articles/personal-finance/050515/how-SWIFT-system-works . ASP

在这种情况下,他们不是在特定的中央银行有结算账户,而是在彼此之间有结算账户。为了进一步理解这一点,让我们举一个例子。假设 A 银行是一家美国银行,B 银行是一家印度银行。 X 是银行 A 的客户, Y 是银行 B 的客户。为了使 X 能够向 Y 转账,反之亦然,银行 A 和银行 B 相互持有结算账户。因此,银行 A 可能具有银行 B 的账户,其中₹300,000 被记入贷方,而银行 B 将具有银行 A 的结算账户,其中 100,000 美元被记入贷方。现在,当 XY 发送一笔价值 100 美元的款项时,银行 B 将从其处理的银行a结算账户中借记₹6909.50(在撰写本书时 1 美元= 69.10 印度卢比)。x 的账户将被借记 100 美元,y 的账户将被贷记₹6909.50.

通常需要五到七天的时间才能将信用反映到 Y 的帐户中。这是由于许多必要的流程、检查和问题,例如:

  • 由于国外汇款助长了洗钱行业,银行必须进行某种背景调查,以确定您使用的资金不是从非法来源获得的。
  • 汇款人的银行搜索其系统,以检查其是否与收款人账户所在的银行有直接合作关系(持有结算账户)。通常不太可能。因此,汇款人的银行与他们有合作关系的银行联系,并且知道收款人的银行也是他们的合作伙伴。所以本质上它变成了一个链条。有时,这个链条可能会增长到中间的三至四家银行,这取决于你所在国家的银行基础设施和经济开放程度。
  • 大多数情况下,这些 SWIFT 报文仅由汇款人银行的一个指定办理国外汇款的分支机构发送。此外,发件人的分支机构将需要更多的时间将消息发送到主分支机构,并从那里继续前进。
  • 在许多国家,与法规和合规性相关的检查是手动完成的,因此增加了完成转移的时间。

A Nostro 账户是银行 A 用来指代我们在银行 B 的账户。 A vostro 成就账户是银行 B 使用的术语,银行 A 的钱被存入该账户。

数字化法定货币

我们看到了银行间转账是如何运作的。在国内转账的情况下,中央银行必须负责管理和更新结算账户,而在国际转账的情况下,各银行必须努力更新结算账户。在国际转账的情况下,还存在其他问题,如需要更多的对账工作,因为没有可信任的第三方,以及通过多个中间银行进行支付。

区块链让我们能够将法定货币数字化,让银行可以直接向世界上任何一家银行转账;它通过提供单一的真相来源,在很大程度上减少了和解的努力。

让我们看看区块链法定货币数字化的过程和流程:

  • 只有央行有权在区块链发行各自的数字化法定货币。
  • 我们可以为每种法定货币建立一个独立的网络,而不是使用单一的网络来分配流量和提高可扩展性。
  • 银行要将法定货币转换成数字化形式,必须将法定货币存入中央银行的现金托管账户。等量的数字化法定货币将由区块链中央银行发放给各银行。
  • 银行可以通过销毁区块链上的法定货币,随时将数字化的法定货币转换回纸币。
  • 为了实现匿名,银行可以使用多个地址。因此,其他银行将很难预测谁拥有多少数字化法定货币。

使用手机号码作为身份

我们的支付应用程序将基于使用手机号码作为接收者的身份。让我们看看使用手机号码作为使用区块链支付的标识符的整个过程:

  • 区块链将作为与银行代码关联的手机号码的共享和安全存储。
  • 每个 ISD 电码都有自己的网络。这样做是出于可伸缩性的原因。
  • 每个手机号码都可以关联到一家或多家银行。如果有一家以上的银行,汇款人可以选择向哪个银行账户汇款。
  • 对于使用手机号码接收付款的收款人,应使用收款人所在银行的手机银行应用程序在区块链上注册手机号码。
  • 如果收款人的银行账户被暂停,应在区块链上更新状态,以通知其他人不接受该手机号码的付款。

构建网络

在我们开始编写智能合约之前,让我们为+1 ISD 代码创建美元货币的法定网络。我们将确保使用节点 id 来许可和保护这些网络。

到目前为止,我们在本书中创建的所有网络都假设它们受到白名单 IP 的保护。但是 Quorum 提供了一种将节点 id 列入白名单的方法。您可以将相同的实践应用于本书中构建的其他网络。手机号码不应该泄露到网络之外,因此不惜一切代价保护网络非常重要。

仲裁中的网络许可

通过在节点启动期间添加--permissioned标志作为命令行参数,可以在单个节点级别启用网络许可。添加标志后,节点会在节点的数据目录文件夹中查找名为permissioned-nodes.json的文件。

permissioned-nodes.json文件包含一个节点标识符(enode://nodeID@ip:port)列表,该特定节点将从该列表接受传入连接,并向其发出连接。

如果设置了--permissioned标志,但是permissioned-nodes.json文件为空,或者根本不在节点的数据目录文件夹中,则节点将启动,但是它既不会连接到任何其他节点,也不会接受来自其他节点的任何传入连接请求。

例如,在我们的案例中,我们最少需要一个三节点网络,即银行 A ,银行 B 和中央银行。假设银行 A 的节点 ID 为480cd6ab5c7910af0e413e17135d494d9a6b74c9d67692b0611e4eefea1cd082adbdaa4c22467c583fb881e30fda415f0f84cfea7ddd7df45e1e7499ad3c680c,银行 B 的节点 ID 为60998b26d4a1ecbb29eff66c428c73f02e2b8a2936c4bbb46581ef59b2678b7023d300a31b899a7d82cae3cbb6f394de80d07820e0689b505c99920803d5029a,央行的节点 ID 为e03f30b25c1739d203dd85e2dcc0ad79d53fa776034074134ec2bf128e609a0521f35ed341edd12e43e436f08620ea68d39c05f63281772b4cce15b21d27941e

所以银行 A 节点上的permissioned-nodes.json文件会有如下内容:

[
  "enode://60998b26d4a1ecbb29eff66c428c73f02e2b8a2936c4bbb46581ef59b2678b7023d300a31b899a7d82cae3cbb6f394de80d07820e0689b505c99920803d5029a@[::]:23001?discport=0",
  "enode://e03f30b25c1739d203dd85e2dcc0ad79d53fa776034074134ec2bf128e609a0521f35ed341edd12e43e436f08620ea68d39c05f63281772b4cce15b21d27941e@[::]:23002?discport=0"
]

类似地,银行 B 将银行 A 和央行列入白名单,而央行将银行 A 和银行 B 列入白名单。

当发出后续的传入/传出请求时,服务器将动态拾取对permissioned-nodes.json文件的任何添加。为了使更改生效,不需要重新启动节点,但是从permissioned-nodes.json文件中删除现有的连接节点不会立即删除那些现有的连接节点。但是,如果由于某种原因连接被删除,并且从删除的节点 id 发出后续的连接请求,它将作为新请求的一部分被拒绝。

建造 DApp

让我们为数字化法定货币和存储与银行账户相关的手机号码写下智能合同。以下是法定货币数字化的智能合约:

pragma solidity ^0.4.18;

contract USD {
    address centralBank;

    mapping (address => uint256) balances;
    uint256 totalDestroyed;
    uint256 totalIssued;

    event usdIssued(uint256 amount, address to);
    event usdDestroyed(uint256 amount, address from);
    event usdTransferred(uint256 amount, address from, address to,
      string description);

    function USD() {
        centralBank = msg.sender;
    }

    function issueUSD(uint256 amount, address to) {
        if(msg.sender == centralBank) {
            balances[to] += amount; 
            totalIssued += amount;
            usdIssued(amount, to);
        }
    }

    function destroyUSD(uint256 amount) {
        balances[msg.sender] -= amount;
        totalDestroyed += amount;
        usdDestroyed(amount, msg.sender);
    }

    function transferUSD(uint256 amount, address to, string 
      description) {
        if(balances[msg.sender] >= amount) {
            balances[msg.sender] -= amount;
            balances[to] += amount;
            usdTransferred(amount, msg.sender, to, description);
        }
    }

    function getBalance(address account) returns (uint256 balance) {
        return balances[account];
    }

    function getTotal() returns (uint256 totalDestroyed, uint256 
      totalIssued) {
        return (totalDestroyed, totalIssued);
    }
}

前面的代码是这样工作的:

  • 我们假设央行部署了智能合约。
  • 我们有发放、转移和销毁的方法。这些方法不言自明。转账方法还有一个描述,其中可以包含交易目的或接收客户详细信息等信息。
  • 我们有方法来检索一个帐户的余额,以及曾经发出和销毁的总数。

以下是持有手机号码及其各自银行的智能合约:

pragma solidity ^0.4.18;

contract MobileNumbers {
    address centralBank;

    struct BankDetails {
        string name;
        bool authorization;
    }

    mapping (address => BankDetails) banks;
    mapping (uint256 => address[]) mobileNumbers;

    event bankAdded(address bankAddress, string bankName);
    event bankRemoved(address bankAddress);
    event mobileNumberAdded(address bankAddress, uint256 mobileNumber);

    function MobileNumbers() {
        centralBank = msg.sender; 
    }

    function addBank(address bank, string bankName) {
        if(centralBank == msg.sender) {
            banks[bank] = BankDetails(bankName, true);
            bankAdded(bank, bankName);
        }
    }

    function removeBank(address bank) {
        if(centralBank == msg.sender) {
            banks[bank].authorization = false;
            bankRemoved(bank);
        } 
    }

    function getBankDetails(address bank) view returns (string 
      bankName, bool authorization) {
        return (banks[bank].name, banks[bank].authorization);
    }

    function addMobileNumber(uint256 mobileNumber) {
        if(banks[msg.sender].authorization == true) {
            for(uint256 count = 0; count < 
              mobileNumbers[mobileNumber].length; count++) {
                if(mobileNumbers[mobileNumber][count] == msg.sender) {
                    return;
                }
            }

            mobileNumbers[mobileNumber].push(msg.sender);
            mobileNumberAdded(msg.sender, mobileNumber);
        }
    }

    function removeMobileNumber(uint256 mobileNumber) {
        if(banks[msg.sender].authorization == true) {
            for(uint256 count = 0; count < 
              mobileNumbers[mobileNumber].length; count++) {
                if(mobileNumbers[mobileNumber][count] == msg.sender) {
                    delete mobileNumbers[mobileNumber][count];

                    //fill the gap caused by delete
                    for (uint i = count; i < 
                      mobileNumbers[mobileNumber].length - 1; i++){
                        mobileNumbers[mobileNumber][i] = 
                          mobileNumbers[mobileNumber][i+1];
                    }
                    mobileNumbers[mobileNumber].length--;

                    break;
                }
            }
        }
    }

    function getMobileNumberBanks(uint256 mobileNumber) view returns
     (address[] banks) {
        return mobileNumbers[mobileNumber];
    }
}

以下是上述代码的工作原理:

  • 我们假设中央银行展开合约。
  • 然后,中央银行可以在网络中添加或删除银行。每家银行在区块链都有账户。我们不能用任何账户写手机号码,因为这将让银行实施欺诈——即使他们不拥有与手机号码相关的账户,他们仍然会添加它,而不会被抓住。一个预定义的帐户将启用可听度,以便银行不会接受他们不持有的手机号码的付款。
  • 那么我们就有了一个添加手机号的方法。每个手机号码都与这个人有账户的许多银行相关联。在发送付款时,发送者可以选择这些账户中的一个。
  • 然后,我们有一种方法,银行可以用这种方法将自己从手机号码中删除。这在银行账户被暂停或关闭时很有用。
  • 最后,我们有一个函数来获取与手机号码相关的银行账户列表。

现在让我们看看用户支付和结算的整个流程:

  • 假设 X 在银行 A 有账户,而 Y 在银行 B 有账户。两个银行都在两个网络上注册,并且两个银行在USD网络上都有足够数量的USD
  • 为了让 Y 使用手机号码接收付款, Y 必须使用银行 B 的手机号码在MobileNumbers网络上注册其号码。银行 B 将调用addMobileNumber方法在网络上注册 Y 的银行账户。
  • 为了让 XY 付款, X 必须将 Y 的手机号码输入银行 A 的手机银行 app。之后,银行 A 将调用getMobileNumberBanks方法来获取 Y 拥有账户的银行列表。银行 B 肯定会被列出,所以 X 可以选择它并点击Send Payment按钮。
  • 一旦点击了Send Payment按钮,银行 A 将调用transferUSD方法,并在描述中提供 Y 的手机号码,指示将资金存入的银行账户。transferUSD中的to地址将是getMobileNumberBanks方法返回的地址。

摘要

在本章中,我们学习了一些银行业务的基本概念,以及银行间转账是如何结算和清算的。我们还了解了 SWIFT 及其工作原理。然后我们进入了 Quorum 中的高级网络许可,并了解了--permissioned标志。

最后,我们建立了一种新型的资金转移系统,它使用数字化的法定货币和一个用于识别客户身份的手机号码来结算支付。我们在区块链的基础上构建了整个解决方案,最大限度地减少了协调工作,解决了许多以前不可能解决的问题。


我们一直在努力

apachecn/AiLearning

【布客】中文翻译组