中心化交易所:钱包系统设计-以太坊

由于现工作项目是设计一款中心化交易所产品,鉴于网上相关的产品设计资料较少,现在开始自己写一些文章分享一下,时间原因,文章不能一次性更新完整,修修补补的有空的时间每天写一点,也没有目录,先从“以太坊钱包”入手。欢迎交流区块链相关项目 

I ETH基本概念

矿工费:即发起转账的手续费,手续费等于Gas Limit * Gwei

ERC20代币:ERC20是ETH的代币(举个例子:黄金有纯金、有K金、千足金等不同标准的金。),ERC20转账与ETH转账的手续费一般是不一样的,ETH转账会便宜一些,而代币转账扣取的手续费是ETH,非代币。

区块确认:以太坊区块确认一般以12个区块确认为确认完成,实际大多数场景下1个区块确认便可以。

确认状态:转账确认状态有“等待处理”“处理中”"失败"“确认中”

Nonce:可以理解为ID,Nonce由钱包发起转账时设置,以太坊转账需要严格遵循排序进行转账,当前Nonce为1,则下一笔转账设置Nonce为3是不可能成功转账,必须发起一笔Nonce为2且完成转账才会继续进行Nonce为3一笔的转账,要不然Nonce为3的会一致处于等待处理状态。


I 了解ETH钱包转账的一些隐藏的坑

Nonce覆盖型做法:

覆盖型方法既在钱包中存在一笔待区块确认的转账,若再发起一笔转账则后一笔转账会覆盖掉前一笔发起的转账,即Nonce一样,后一笔覆盖前一笔。这样做法一般在类似imtoken的这种以太坊钱包中使用比较多,这种做法的好处在于用户发起一笔转账后,由于各种原因堵塞在网络中,希望取消转账重新拉高邮费转账,只需要拉高邮费再转一笔即可把前一笔覆盖,也不会出现重复转账的问题。

Nonce阻塞型做法:

阻塞型方法既在钱包中发起多笔转账,Nonce是按序列发送到网络中等待打包,等待前一笔Nonce完成自动执行下一笔。这种做法一般用在去中心化交易所中,去中心化交易中由于用户代币在自己钱包中,完成撮合代币会自动转账到成交人手中,所以如果这里使用覆盖型做法,则无法完成多笔撮合,应为当多笔撮合时会导致前一笔覆盖后一笔,所以在去中心化交易所中多为使用阻塞型做法。阻塞型做法是在发起转账时,获取以太网络中的最新Nonce以及本地钱包队列条数进行比较+1处 理。

举例:第一目前该地址最新区块接收的转账Nonce为5,第二本地钱包有2条记录正在排队等待转账(即发起了两笔账还没转出),这时再发起一笔转账,那么现在这笔转账的Nonce应该是5+2+1=8

这里还有隐形的坑:

这种做法会经常出现跳Nonce的问题,既应该是8的跳到了9,那么如果不把8的补进去,这笔9的转账是永远排在那里无法转账,也无法取消。好了,这是什么原因导致呢?原因是本地节点同步不够及时通知队列数量存在异常导致。用以上例子,有2条记录正在排队,其中一条记录已经被区块开始确认,但是节点未同步及时,这时候再发起一笔转账,正确的Nonce应该是6+1+1=8,错误的Nonce情况6+2+1=9。因为原网络最新Nonce是5,排队中有2,其中一条已经开始确认,那么区块最新Nonce成6,排队中有1。可是节点同步有问题,钱包获取区块最新Nonce是6,但节点未及时同步队列中已经确认的数量,依然以2返回给钱包,则就会出现跳Nonce问题。

中心化交易所ETH提币方法建议:

在中心化交易所里面,热钱包的提币转账是一个非常高频的操作,肯定是不能使用Nonce覆盖型做法,Nonce阻塞型做法也不能用,应为阻塞型做法跳Nonce问题出现会可能导致多转的问题。中心化做法建议是使用本地队列排队的方法,本地记录待提币记录数,不把记录发送到网上上。获取区块最新确认Nonce,进行下一条转账发送,接收到成功确认记录再进行下一条记录发送。

(注意:只能单点操作,多点操作会出现跳Nonce问题)

(问题又来了,那为什么上面说的去中心化交易不能这么做呢,应为现在很多去中心化交易都是钱包加交易公用的,交易同时可以执行转账,如果采用本地队列,那转账跟交易同时存在时怎么处理呢?只能用阻塞型Nonce做法来中和了。 当然最好的办法就是不给转账功能,只能交易。暂时没有想到完美的办法,去中心化交易所的坑还是很多)

归集资金需往用户地址打入矿工费:

别忘了,以太坊的代币转账是扣以太坊作为油费的,那么交易所分配给用户充值的地址是不是都要给用户的地址准备一些以太坊存放着用于资金归集用呢?答案:即是又否,当然是有条件的,不可能每一个注册用户分发的地址都给充值以太坊,这样成本太高,需要过滤垃圾账号,只针对有充值资金的账号进行油费打款进行资金归集,具体视每个交易所项目产品经理如何设计了,这里没有对错,下面会简单说下我们的初步设计方案。


I 交易所钱包组成结构


  数字货币交易所钱包组成结构分为冷钱包、热钱包、账户钱包,冷热钱包一般设计有多个热钱包A、热钱包B、热钱包C、冷钱包A、冷钱包B、冷钱包C等等,冷热钱包的设计个数需要根据自身业务规模来恒定。

账户钱包:每个注册用户分配单独的充值地址。交易所中每一个注册用户的充值地址都不一样,每注册一个用户将分配一个地址,所有用户的地址跟私钥由交易所集中保管。

热钱包:热钱包可以理解为常用钱包,一般交易所中用户进行提现,资金是通过交易所的热钱包执行转账。

冷钱包:由于热钱包经常需要使用,经常需要私钥进行签名,所以存在一定的安全性,资金如果全部保存在热钱包中对交易所来说是十分不安全的,万一资金被盗交易所就要倒闭。所以一般大部分不常用资金会存放在一个离线的冷钱包中。

业务流程:大体的业务流程上图已经很清晰,用户通过充值代币到交易所分配的账户地址中,交易所监听账户地址的资金变动,若发生资金转入,则同步数据在用户账户中添加余额记录。(注意账户地址只监听转入结果)。当然,每个用户分配了不同地址,钱如果都放在地址就会出现一个问题就是“资金分散“的问题难以管理。所以监听地址存在转入后,交易所需要把地址中的资金归集到交易所官方的热钱包中集中管理。热钱包由于经常使用资金不能过于集中,所以会把部分不动资金存放在安全的冷钱包中。


I 交易所充提业务流程设计


上图是比较完整的钱包业务流程图,涉及内容包括:生成用户充值地址、监听充值入账代币、资金归集、归集矿工费转入、热钱包资金分配至冷钱包、提现转账。

生成用户地址:

当账户注册完成,需要对应的创建一个钱包信息,给账号分配充值地址,充值地址暴露给用户,私钥由系统保存,用于资金归集。


https://www.jianshu.com/p/84c7dcf3098a

之前有写过一篇关于以太钱包的内容,可以看一下

监听充值入账代币:

第二步,当用户充值后,我们需要监听钱包入账的区块确认数,一般设计为12个区块,okex设计为1个区块,币安设计为24个区块,我们参考了币安使用24个区块确认完成后才定义为成功充值,当成功充值完成,需要判断入账的代币类型,若在系统中存在入账代币的合约地址,则在账户余额添加对应代币余额。


资金归集:


判断代币: 资金归集前,先要判断代币类型是ETH还是代币,如果是ETH则判断地址中资金是否大于0.1ETH,若不大于0.1ETH就进行归集,我们的成本会增加,所以对于低于0.1ETH的地址可先不触发归集状态,若大于则直接归集。如果是代币,则需要先判断该地址中是否存在足够的ETH作为矿工费,比对推荐矿工费与当前地址ETH余额,若足够则直接归集。

判断网络状态: 由于以太坊网络经常出现拥堵状态,当出现拥堵状态则转账成本会非常高,而且不一定成功,当以太坊网络推荐邮费大于100Gwei时,则是较为拥堵状态,这种状态下我们没必要增加成本来归集资金,选择等待。在归集前需要先进行推荐矿工费判断,避免资源浪费。

矿工费转入: 如果代币归集地址中ETH不足支付转账费用,则需把缺乏邮费的地址进行记录,次日早上10:00使用智能合约批量转入0.01EHT矿工费进行资金归集。

(为什么要早上10:00?/早上处于便于技术进行监控,防止出现异常问题导致多转。)

(为什么要转入0.01ETH?/鉴于以往经验,最高矿工费一般在0.00X,所以转入0.01ETH较为合      理,多出的余额可以作为下一次归集所用。)

(为什么要集中使用智能合约转?/因为智能合约批量集中转账可以大大降低矿工费,降低成本。)


I 热钱包资金安全转移


资金分配:资金存储比例设计为冷钱包储存80%,热钱包存储20%。对于目前数字货币钱包的使用门槛,大部分玩家几乎都是把资金存放在交易所中,热钱包20%流动资金是足够支撑用户的提币需求。

资金划转:什么时候进行资金划转呢,这个问题视乎自身业务量而定,我们设计一周分配一次,每周一的下午2:00进行资金划转。划转前需要对有效资金进行统计,因为数字货币钱包中经常出现空投币,如果对垃圾空投币进行分配,则是无用的,所以需要先筛选钱包中有效的代币进行转移,有效代币为平台提供充提的代币合约。筛选出代币进行总资产计算“热钱包地址资金/(热钱包资金+冷钱包资金)%”

特殊处理:并不是热钱包资金一定大于20%,当然会存在集中提现的情况,导致资金小于20%,这时候需要给热钱包注入资金,注入资金应当从冷钱包或其他渠道注入,但是冷钱包如果利用系统自动注入则需要把私钥放到系统,这是很不安全的,所以这种情况建议线下人工处理。


I 提币矿工费


这里说的提币矿工费不是平台收取用户多少提币手续费,是提币转账要设置多少手续费转出才更加容易成功,答案是获取区块网络当前推荐的手续费再往上加一点,110%最为合适。

(完结)

风控设计-暂时搁置

微信交流:JonTimfire

你可能感兴趣的:(中心化交易所:钱包系统设计-以太坊)