这几日看了有关于去中心化的支付系统Stellar,将自己的理解写成一篇文章.好不好供大家观阅.
在网上有很多的去中心化交易平台.例如:比特股,AirSwap,Bancor Protocol ,Stellar distributed Exchange等等.
Stellar 架构
我们可以使用Stellar 网络构建移动端的手机钱包,在线的银行系统以及支付服务,整个网络其实由两个组件构成,一个用于与Stellar网络交互的API服务Horizon;另一个是网络的骨干,也就是Stellar Core.
网络中的所有的Horizon服务都会链接到Stellar core 上,由它通过共识算法负责交易的验证和处理工作,当我们谈到Stellar网络时,往往说的都是Stellar Core的集合,我们可以将Stellar core 理解为Bitcoin 中的节点,网络中相互连接的全部节点构成整个网络,而Horizon 就是用于与节点对话的HTTP服务了.
由于Stellar 在设计的目的就是为了结合现有的金融系统和区块链技术,所以让第三方通过网络发行货币或者代币其实是Stellar 中非常重要的功能,与Ethereum(运行智能合约的分布式平台)的设计目标不同,Stellar为使用者提供了内置的发币功能,不需要类似ERC20等协议额外约束.
为了达到其设计的目的,Stellar引入了包括账户,资产,分布式交易所,通货膨胀以及锚等概念,构建了一个比较丰富的金融体系.
锚(Anchor)
在Stellar中,锚(Anchor)
是一个非常重要并且有意思的概念,它们是帮助用户保留存款并且向Stellar网络中发行信用的可信实体,也可以理解为全世界各国银行的中央银行.
所有网络中交易的资产都是Anchor
发行的信用,例如:银行,储蓄机构,农业合作社,中央银行或者汇款公司.作为Anchor
,一般需要维护最少两个账户:
发行账户只能用于发行和销毁资产,而基础账户用户用来处理与其他Stellar账户的业务,其中保存了所有发行账户发行的资产.
为了履行作为Anchor
职责,基础设施需要支持两个核心的功能,付款和收款,在Stellar官方文档Architecture中对这两个核心功能的数据流进行了详细的介绍.
付款流程
- 客户使用
Anchor
提供的客户端或者网页发出一笔付款;Anchor
的内部服务通过桥接服务(Bridge)
发出一笔付款;- 桥接服务决定是否需要进行合规检查并将交易的相关信息发给合规服务;
- 合规服务通过查找联合抵制决定收款的账户ID;
- 合规服务调用
Anchor
的接口获取客户的相关信息并发送给付款组织的合规服务;- 如果通过了相关组织的合规验证,那么桥接服务就会创建并签发一笔交易,发送到Stellar 网络中;
- 当交易被网络确认时,桥接服务收到消息最终更新客户的账户余额;
收款流程
当其他人向我们发送一笔转账时,整个数据流相比付款时就有一些不同了:
-发送者通过查找Stellar 账户ID根据客户的联合抵制发送一笔付款;
- 发送者将付款信息与付款方的账户信息发送给收款方的合规服务;
- 合规服务联系三个不同的服务;
1.一个用于判断发送者是否允许的支付客户的制裁回调(Sanction Callback
);
2.如果发送者想要得到客户的信息,需要由回调来决定是否提供当前的客户信息;
3.如果决定提供客户信息,通过回调的方式进行提供;- 发送方将交易发送到Stellar网络中;
- 桥接服务监控Stellar网络中的这笔交易并确认是否是3.1中已经同意的付款;
- 桥接服务通知我们的服务当前交易已经确定,可更新用户的账户余额.
从Stellar 网络为我们提供的首付款功能的执行流程来看,很多架构的设计都是为了资产的发型方能够更好地控制自己的发型资产,使得整个账户转账和付款流程更加合规,这一点对于大型的金融机构十分重要.
概念
账户
账户是Stellar中的核心数据结构,它是被存储在账本中的公钥标记的,账户中其他的数据结构都是属于某一个账户的,我们其中最熟悉的交易Transaction也是由账户创建的,每一笔交易都需要由当前账户的四哟啊签名才能生效.
AccountEntry
在Stellar 中其实就是一个C语言的结构体,其中包含了与当前账户相关的很多字段:
struct AccountEntry { AccountID accountID;
int64 balance;
SequenceNumber seqNum;
uint32 numSubEntries;
AccountID * inflationDest;
uint32 flags;
string32 homeDomain;
Thresholds thresholds;
Singer singers<20>;
};
- 在结构体重,
accountID
是当前账户的唯一标识符,在默认情况下都是账户对应的私钥; -
balance
就是当前账户持有的XLM
余额; -
seqNum
标识当前账户的最新交易的序列号,也就是所有的交易的签发都是线性的; -
numSubEntries
标识当前账户包含的条目数,例如:信任线,订单,数据等; -
inflationDest
标识当前账户接受通货膨胀的目标地址;
每一个Stellar账户都对应着唯一的AccountEntry
以及多个TrustLineEntry
,OfferEntry
,DataEntry
.
以TrustLineEntry
为例,信任线(TrustLine
)其实就是Stellar中的某个账户接受另一个账户发型的资产,可以理解为一个关系表,其中存储着新人的asset以及资产的余额.
struct TrustLineEntry {
AccountID accountID;
Asset asset;
int64 balance;
int64 limit;
uint32 flags;
};
除此之外,Stellar中的DataEntry
可以保存一些与账户相关的数据:
struct DataEntry {
AccountID accountID;
string64 dataName;
DataValue dataValue;
};
数据条目其实就是与账户相关的键值对数据,这允许账户可以在其上附加任意的数据,包括存储一些应用特定的数据,提供了很好的扩展能力.
交易
Stellar的账本作为一个状态机,想要改变其状态的唯一方式就是通过交易(Transaction
),交易有非常多的功能,可以通过交易发起付款,在分布式交易所中创建订单,改变账户的设置等等;总而言之,账本如果可以被当做是数据库的话,交易就是SQL命令.
struct Transaction {
AccountID sourceAccount;
uint32 fee;
SequenceNumber seqNum;
TimeBounds* timeBounds;
Memo memo;
Operation operations<100>;
};
上述结构体就是Stellar中交易的架构,其中包含了如下的属性,sourceAccount
也就是发出交易的源地址,该交易必须被发出交易的原地址签名;seqNum对于每一个交易和账户必须都是唯一并且但单调递增的,它与Ethereum的nonce非常的相似;最后的operations就是一个操作的数组,其中包含了这一次交易需要执行的全部操作.
每一个Transaction都是由一组Operation构成的,可用的Operation包括CreateAccount,Payment,PathPayment,ManagerOffer 等等,以发出付款为例,可以向指定的账户发送特定数量的某资产;
Parameters Type | |
---|---|
Destination | AccountID |
Asset | Asset |
Amount | Integer |
以上的三个参数能够决定当前账户向另一账户发送付款需要的全部消息.我们可以通过以下的命令得到一个交易中的全部内容;
▶ curl -X GET 'https://horizon-testnet.stellar.org/accounts/GA5IQGCHGT6FWTCWJHWQW5A2PIGNC2AQDN2VDE3Y6PHPTRJZSPXCCMFR/transactions'
{
// ...
"_embedded": {
"records": [
{
"_links": {
"operations": {
"href": "https://horizon-testnet.stellar.org/transactions/d629907411f368ed7cdd2fff5658a43ac134544da116447b687255998f7ec32c/operations{?cursor,limit,order}",
"templated": true
},
// ...
},
"id": "d629907411f368ed7cdd2fff5658a43ac134544da116447b687255998f7ec32c",
"paging_token": "40591997907513344",
"hash": "d629907411f368ed7cdd2fff5658a43ac134544da116447b687255998f7ec32c",
"ledger": 9451061,
"created_at": "2018-06-12T00:05:04Z",
"source_account": "GAIH3ULLFQ4DGSECF2AR555KZ4KNDGEKN4AFI4SU2M7B43MGK3QJZNSR",
"source_account_sequence": "27797951757828075",
"fee_paid": 100,
"operation_count": 1,
"envelope_xdr": "AAAAABB90WssODNIgi6BHveqzxTRmIpvAFRyVNM+Hm2GVuCcAAAAZABiwhcAAj/rAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAOogYRzT8W0xWSe0LdBp6DNFoEBt1UZN48875xTmT7iEAAAAXSHboAAAAAAAAAAABhlbgnAAAAECTzE0kuVPLsjGyke+J2sjMvUxRIjivmlxIS3UTRp4zlWO29T+pK24/JBgbZUmUzG6goHYa4kLCqFwYCMBQeVUI",
"result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA=",
"result_meta_xdr": "AAAAAAAAAAEAAAADAAAAAACQNjUAAAAAAAAAADqIGEc0/FtMVkntC3QaegzRaBAbdVGTePPO+cU5k+4hAAAAF0h26AAAkDY1AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAwCQNjUAAAAAAAAAABB90WssODNIgi6BHveqzxTRmIpvAFRyVNM+Hm2GVuCcAAM2cVDdj8MAYsIXAAI/6wAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAQCQNjUAAAAAAAAAABB90WssODNIgi6BHveqzxTRmIpvAFRyVNM+Hm2GVuCcAAM2Wghmp8MAYsIXAAI/6wAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA",
"fee_meta_xdr": "AAAAAgAAAAMAkDSbAAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAADNnFQ3ZAnAGLCFwACP+oAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAkDY1AAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAADNnFQ3Y/DAGLCFwACP+sAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==",
"memo_type": "none",
"signatures": [
"k8xNJLlTy7IxspHvidrIzL1MUSI4r5pcSEt1E0aeM5VjtvU/qStuPyQYG2VJlMxuoKB2GuJCwqhcGAjAUHlVCA=="
]
}
]
}
}
通过上述JSON格式的Transaction,我们可以看到当前交易的源地址,手续费以及序列号等字段,可以在通过这个命令访问当前的交易中所有的Operation:
$ curl -X GET 'https://horizon-testnet.stellar.org/transactions/d629907411f368ed7cdd2fff5658a43ac134544da116447b687255998f7ec32c/operations'
{
// ...
"_embedded": {
"records": [
{
// ...
"id": "40591997907513345",
"paging_token": "40591997907513345",
"source_account": "GAIH3ULLFQ4DGSECF2AR555KZ4KNDGEKN4AFI4SU2M7B43MGK3QJZNSR",
"type": "create_account",
"type_i": 0,
"created_at": "2018-06-12T00:05:04Z",
"transaction_hash": "d629907411f368ed7cdd2fff5658a43ac134544da116447b687255998f7ec32c",
"starting_balance": "10000.0000000",
"funder": "GAIH3ULLFQ4DGSECF2AR555KZ4KNDGEKN4AFI4SU2M7B43MGK3QJZNSR",
"account": "GA5IQGCHGT6FWTCWJHWQW5A2PIGNC2AQDN2VDE3Y6PHPTRJZSPXCCMFR"
}
]
}
}
上述Transaction是只包含一个Operation交易,该交易中的操作只用来创建新的账户并为当前账户添加一些用于转账手续费的初始余额10,000XLM.
每一个Transaction其实都是由一系列Operation组成的,这些Operation组成的交易就类似一个数据库中的事务,所有的操作要么执行成功,要么执行失败,Stellar 会保证一个交易的原子性
资产
与现有的大部分公链一样,资产是区块链生态系统中不可缺少的一部分,与原生的资产Lumens不同,所有的资产都有发行人和资产类型组成.
持有Stellar中的资产时,其实是持有特定发行人的信誉,我们相信资产的发行人能够将Stellar中的资产兑换成货币,昂贵金属以及其他在网络中不存在的资源.但是当我们想要持有某一个发行人的发行的资产时,需要创建一个信任线(TrustLine)
,这些数据会存储在Stellar的账本中,也就是上面提到的TrustLineEntry:
struct TrustLineEntry {
AccountID accountID;
Asset asset;
int64 balance;
int64 limit;
uint32 flags;
};
资产的发行人在发型资产时,需要提供遵循 ISO 4217 或者ISIN的资产编码.
当用户想要持有或者交易某一种资产时,它会创建一个等待发型人审批的信任线,发行人授权该信任线之后,用户 才可以接受或者发出资产;当发行人想要冻结用户访问资产的权限时,也可以随时取消用户的授权,在这之后用户就无法在发送或者接受该资产了.
发布式交易所
为了增加Stellar 网络中资产的流动性,它还提供了去中心化的分布式交易所用于资产的交易,任意的两种资产之间都会存在一个市场,我们可以通过ManagerOrder操作箱订单薄插入一个新的订单,它与传统交易所中限价单的行为基本相同.
通过膨胀
很多币或者Token其实从发型的第一天起数量就是固定的,但是世界上绝大多数的法币实际上都是以每年百分之几的速度通货膨胀的,通货膨胀并不是一件绝对不好的事情,适当的通货膨胀能够增加市场的流动性,而Stellar也引入了通货膨胀的特性,网络中的XLM会以每年1%的速度增加,所有的代币会发放给票数占网络超过0.05%的账户
原文链接:去中心化支付系统Stellar 面向信仰编程