本节书摘来自华章计算机《区块链开发指南》一书中的第2章,第2.2节,作者:申屠青春 主编 宋 波 张 鹏 汪晓明 季宙栋 左川民 编著更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.2 Counterparty
合约币Counterparty是以合约币协议运行的全套金融工具,合约币协议建立在比特币块链的基础之上,把比特币块链当成可信的时间戳服务和可信的信息发布证明。
目前合约币已经实现了众多的技术创新点,比如燃烧证明、合约、去中心化XCP与BTC交易所、赌约或期货、资产或股份发行、分红等。Counterparty是建立在比特币协议上的传输层,用于建立和使用去中心化的财务工具协议。简单来说,可以将XCP理解为很多“小的BTC”即XCP=“小的BTC”,但是这些“小的BTC”(XCP)不仅仅具有货币的交易功能,还具有资产发行(例如发行股票)、股息分配及下注的功能。
每个合约币信息都包括以下特性。
有一个源地址。
有一个目的地址。
有一定数量的比特币,从源代码发送到目的地址(如果存在目的地址的话)。
以比特币计的费用,支付给挖到这个交易的矿工。
最多40字节的外带数据,这些数据通过上述的两个外带数据方法嵌入到比特币交易中。
为了方便区分,每个合约币交易的数据区域都以UTF-8格式的CNTRPRTY打头,这个字符串已经足够长,因而很难将合约币的交易与在OP_RETURN区域带有伪随机数的比特币交易搞混。在测试情况下(例如:在任何块链中使用TESTCOIN合约币网络),这个字符串是“XX”。
识别字节串“CNTRPRTY”之后的四个字节说明了目的地址的存在性、比特币交易费用的多少,以及交易的比特币数量(根据合约消息类型的不同而不同)。其他的数据则根据消息类型具有不同的格式,具体请参考源代码。
另外,每个合约币交易都必须有一个明确且唯一的源地址,在含有合约币交易的比特币交易中,所有输入都必须一致。在比特币交易中资金唯一的源地址,就是合约币交易的源地址。
合约币交易的源地址和目的地址,就是比特币地址,任何比特币地址都可以收到任何合约币的资产(如果该地址有资产的话,也可以向外发送资产)。
此外,需要说明的是,所有信息都会按照顺序进行解析,一次一个,并且会忽略区块边界。
2.2.1 Counterparty附生链的实现机制详解
附生链支持构建两种类型的交易:BTC发送和以BTC发送合约币的资产分红,这两种交易不包含数据区,对于后者,能使用多个“目的”输出。除BTC和XCP以外的所有资产均具有如下属性:Asset name、Asset ID、Description、Divisiblity、Callability、Call date(if callable)即赎回日期(如果是可赎回的)、Call price(if callable)即赎回价格(如果是可赎回的)等。
资产名称是大写的ASCII字符串,当编码成十进制整数时,其值大于263,小于或等于2568。所有资产名称,除了“BTC”和“XCP”以外,必须至少有4字节长,而且不能以字符“A”开头。这样处理后,某些13字节的资产名称是有效的,但是14字节的就不行。
资产可以是可分割的或不可分割的,可分割资产可以分成8个十进制的位置。资产可以有描述,也可以随时改变。
资产可以是“可赎回的”,可赎回资产在赎回期之后,可以被现在的发行者,以赎回价格(以XCP为单位)强制“赎回”,赎回价格可以设置成该资产首次发行的价格。
可赎回资产可以在赎回日期之后赎回,该赎回日期是在块链中的一个区块中第一次定义的时间。
赎回价格指定为6个十制数的精度,是XCP与该资产的最小单位的比率。
附生链的交易类型包括:发送(Send)、订单(Order)、BTC支付(BTCPay)、发行(Issue)、广播(Broadcast)、赌约(Bet)、分红(Dividend)、燃烧(Burn)、取消(Cancel)、回调(Callback)等。下面就来一一介绍下。
2.2.2 发送
发送(Send)是指从源地址发送任何合约币资产到目的地址,如果在解析(以交易顺序)该消息时,发送者还没有足够的资产数量,则该发送消息只能部分满足。Counterparty支持发送比特币,这里不使用任何数据输出。
2.2.3 订单
订单(Order)是指给定某种资产的特定数量,要得到另外资产的特定数量。“买单”和“卖单”之间没有本质差别。在订单解析时,被给的资产通常会马上被签订合约。也就是说,如果有人想用1个XCP换2个BTC,一旦他发布了这个订单,那么他的XCP账号马上会减去1个XCP。
当订单在块链中可见时,协议会将它与另一个以前见过的开放订单撮合在一起。两个被撮合成功的订单称为“订单对”,如果订单对中的任何一个订单包含比特币,那么这个订单对会被指定为“待处理”状态,直到必要的BTCPay交易发布;如果订单对中的订单没有包含比特币,那么这个贸易将立即完成,并且以协议自身指定的地址形成新的收支平衡。
所有订单都是定价单,询价指定了一个人想要付出和得到的比率,订单会匹配定价以下的最高价格,订单对就是按照这个价格撮合的。也就是说,如果有个开放订单以0.11XCP/每份资产卖出,第二个卖单以0.12XCP/每份资产卖出,第三个卖单以0.145XCP/每份资产卖出,然后有一个新订单要以0.14XCP/每份资产的价格买入,那么它将会先匹配第二个买单,XCP和BTC将会以0.12XCP/ASST的价格成交。
所有订单允许部分执行,也就是说,订单并非要么完全成交,要么不成交。在前一个例子中,如果购买比特币的一方想买的数量多于第一个卖单的数量,那么买单剩余未成交的数量会由后面的现存卖单来满足。在所有可能的订单对撮合完之后,当前的买单被列为开放订单(如果还有数量未被满足的话),如果存在多个价格相同的开放买单,则订单将按照时间顺序撮合。
用户发布开放订单之后,开放订单会在一定数量的区块后过期,当订单过期时,所有担保的资金都会返回到订单发布的那一方。
等待比特币支付的订单对将在10个区块后过期,其中的订单将会重新发布。一般情况下,不会存在虚假交易,因为每一方提供的资产都存储在担保处。然而,担保比特币是不可能的,因而那些想购买比特币的人会要求只匹配有向比特币矿工支付交易费用的交易。另一方面,当创建订单售出比特币时,用户可以支付他愿意支付的任意费用;如果是部分订单,则仅支付部分费用。
此外,可用支付比特币的方式来关闭那些等待BTCPay消息的订单对。在BTCPay消息的数据区块中,存储着两个Hash串连接而成的字节串,这两个Hash串是由订单对中的两个订单Hash生成的。
2.2.4 发行
资产可以以发行消息类型的方式进行发行(Issue):用户指定名称和数量,协议计入相应的地址。资产名称必须是唯一的,或者以前被相同地址发行过的。如果要重新发行一个资产,也就是说,对已经发行的资产进行增发,那么发行的资产名称、可分割性和发布地址必须匹配。对某个已经存在的资产进行增发,这个权利可以转移给别的地址。资产可以被不可逆地锁定,防止进行增发,以保证资产拥有者免受通胀风险。
2.2.5 广播
广播(Broadcast)用于发布文本或数字信息,并且附带一个时间戳作为系列广播的一部分,这系列广播被称为“反馈”。一个反馈和一个地址相关联:从给定地址过来的任何广播,都是该地址反馈的一部分。一个反馈的时间戳必须是单向增加的。赌注以数字形式在反馈中下注,这个数值可以是货币的价格,或者可以是对未来事件可能的离散输出的一部分描述。例如,有人可能以文本形式这么描述:“US QE on 2014-01-01: dec = 1, const = 2, inc = 3”,并且宣布结果是“US QE on 2014-01-01: decrease!”和数值1,更为复杂的赌约可以以非块链的方式进行发布。
发布内容为文本字符串“LOCK”(大小写不敏感)的单个广播可以锁定反馈,阻止它成为以后的广播源地址,同时也阻止它成为任意新赌约的主题(如果反馈被锁定,但还有开放的或未解决的赌约与之相关,那么,那些赌约或赌约对会无损害地过期)。广播-1的数值会被赌约结算所忽略。反馈以它的发布地址来识别。
2.2.6 赌约
赌约(Bets)是指打赌一个特定反馈会等于(或者不等于)某个特定时间的一个目标值,例如,打赌2020年1月1日12点整比特币的价格是否为$10?000美元。参与赌博的人用他们的赌金进行担保,当到达指定时间,该赌约就会按照反馈结果进行结算,赢者获得赌金。
等于/不等于赌约不能用杠杆。然而,为了让两个赌注能被撮合,它们的杠杆水平、时间期限和目标值都必须相同,否则,它们会以订单的形式撮合,除非赌约的赔率与订单价格是反相关的(赔率=保证金/庄家保证金),如果有可能,每个赌约都会以尽可能高的赔率撮合到开放赌约。
目标值必须非负,赌约对(合约)不受-1的广播值所影响。赌约的最后期限不能晚于它们指定反馈的最后一个广播的时间戳。赌约的过期与订单相同,例如:过了特定的区块数量后就会过期。如果赌约对在2016个区块后,发现一个区块的时间戳在赌约的最后期限之后过期,那么,赌约费用将会是初始保证费用的一定比例,这部分并非赌约收入。
因为区块时间的存在,以及交易在块链中被订单化这种非确定性方式的存在,所有合约必须非增量解决,但是涉及的资金必须马上放入担保契约,而且必须有结算日期。否则,有人看到价格下跌了,就会把要被扣除的资金隐藏起来。