这是一篇对实现一个加密货币支付平台的技术方案的基础的思考和调研,思考之所以排在调研前是因为先想到了加密货币实现在线支付的场景,然后通过调研验证了自己的想法。
写这篇文章的起源是,是想给自己规划的个人项目加在线支付的场景,比如微信支付、支付宝、Paypal等,但个人非公司主体在如何简单快速实现支付的对接时让我有了一些思考,既然链上的账本交易是公开的,是不是可以实现加密货币的支付系统呢?细想来链路是通的实现并不复杂。然后又扩展想到如何实现一个加密货币聚合支付的平台服务商,带着这个疑问梳理出了下文的内容。
又是偶然的机会在 TradingView 的付费流程里看到了加密支付的选项,顺着又发现了 Coinbase 提供的支付商户服务 Coinbase Commerce,通过简单的体验了流程基本上验证了我的想法,当然类似的服务还有 BitPay。
关键词:#加密货币 #聚合支付 #支付商户服务平台 #支付服务商
名词解释:用户、商户、支付服务商(下文会围绕这三者展开,即用户在商户电商系统通过支付服务商发起加密货币支付)
USDT
对应TRX
转账网络)
CREATE2
预生成)USDT
充值地址USDT
对应TRX
网络发起转账USDT
币种增加余额selfdestruct
销毁合约)Alipay/Paypal
)的做法是在交易信息中增加「商户订单号」的形式来确权的ERC20
网络的USDT
)涉及到两个话题,一个是资金安全,另一个是商户的提现流程如何设计,这两个话题之所以一起描述是因为有很紧密的关系
收款账户的地址可以选择外部账户(Externally-owned account
) 和合约账户(Contract account
), 我们对比一下选出最优的
显然,方案2从资金安全考虑是最优的,但为每一笔交易都部署合约显然是昂贵的,所以最优的方式是通过CREATE2
操作码预计算出合约地址,通过此地址先进行收款,等需要转移资金时再部署合约
前文提到为每一笔交易预创建一个合约地址收的资金,会有两个流向:商户的钱包(入账)、服务商的钱包(分佣),下面讲解如何将合约钱包中的数字货币进行转移的
selfdestruct
),这将退还部署智能合约部分的Gas
费此时资金已经成功入账和分佣,但是这种方式安全吗?我们会在合约的构造方法里加上入账方的地址参数,这样确保了接受者始终是我们预期的,这样无论如何攻击者都无法使用任何收款来获取资金的控制权。
一笔交易完成后,在很短的时间里会通过智能合约进行资金转移,即资金会入账到商户自己的钱包里,如何保障钱包的安全至关重要
Coinbase Commerce
提供的将加密版本的私钥存储到Google Drive
的方式)这里部署在以太坊测试网上的合约地址为 :0x4d3e2C755aCCeDb752878b2E025Bdfa2cFE7116C
CREATE2 定义了新的账户生成方式:keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
(其中 Account a = new Account{salt: _salt}(_to);
是 Solidity 0.6.2
加入的支持 CREATE2
的语法糖)。
Wallet
合约的 create
方法来创建 Account
合约:https://rinkeby.etherscan.io/address/0x4d3e2C755aCCeDb752878b2E025Bdfa2cFE7116C#writeContractAccount
合约创建后在构造方法中直接实现了资金的转移,无需显示调用,验证合约的资金流向:https://rinkeby.etherscan.io/address/0xdebedc5e19376c4c2c8b365d47cf7dc031cd7a7a#internaltx最后,其实还有很多细节问题没有涉及到,比如小额支付时的佣金无法覆盖创建合约和转账的Gas成本、用户多支付的退款流程、用户商户侧主动发起退款流程、在支付服务中币价波动风险及应对策略等的思考,以后有机会再和大家分享。
感谢阅读!如果有问题交流,可以关注并私信我:微信(jingwentian)、Twitter(@0xDaotian)、微信公众号(北极之野)、Substack邮件订阅(文叔白话WEB3)。