链下资产发行
发行数字资产是区块链的一大应用。同质化的火币发行目前大多数基于以太坊的ERC20协议,这种协议在创建智能合约时,便规定了整个资产的数量。由于智能合约的公开透明和资产的上限约束,来取信用户对资产本身以及未来价值的信任。
然而,在某些场景下,资产是由某些业务的官方机构发行的,比如在线游戏内的资产,这些资产不必及时上链兑现,可以链下发行,当累积到一定程度时再同步到链上。这种场景类似于支付货款时,支付方提供支票,收款方随后拿着支票到银行兑现现金。那么,如何能够保证链下发行的资产能在链上兑现呢?
资产发行一般需要指明接收方,金额,兑现期限等,用数据结构表示如下:
struct IssuanceMessage {
address recipient;
uint amount;
uint issuanceBlock; // could also use time stamp
}
限定区块序号和限定时间戳主要是用来限定在某个区块或者某个时间戳以后,该消息才被视作有效消息,可以来领取资产。
为了防止重放,这里每次授权的amount变量实际上是累计的,系统始终维护一个授予每个人的铸币权的总量,而每次签名,用户得到的是当前签名的amount减去上一次授权的amount的差。由于这个值是个递增值,用户无法拿过去作废的签名来获得资产发行权。
具体的资产兑付的伪码如下:
contract OffchainIssuableToken is MintableToken {
mapping (address => uint) latestWithdrawBlock;
struct IssuanceMessage {
address recipient;
uint amount;
uint issuanceBlock;
}
function redeemPromisedTokens(bytes payload, uint8 v, bytes32 r, bytes32 s) public returns (bool) {
assert(verify(payload, v, r, s));
IssuanceMessage memory msg = parse(payload, v, r, s);
// Ensure user submits the latest message they have
// to prevent replay attacks:
assert(msg.issuanceBlock > latestWithdrawBlock[msg.sender]);
latestWithdrawBlock[msg.sender] = this.blockNumber;
mint(msg.recipient, msg.amount);
}
}
这里的parse函数并未详细设计,实际上需要验证payload和签名信息的对应关系,并且解析出地址,是否和合约的owner一致。
应用场景
- AI公司奖励线上参与者提供训练模型,可以通过发行这种不需要立即上链的资产
- 基于对某个具体个人的信任,他也可以向其他人发行线下资产,资产价值的波动本身蕴含在周围的人对他的信任的基础上。
- 众筹项目,当项目尚未完成,需要对参与众筹的用户提供一个购买凭据。
- 一些临时的应用场景,比如礼物卡
- 当人们在网络较差的环境下工作时,可以先在无网络状态下进行签名,等有网环境下再去兑现。
争论
- 是否应当设置总量上限。
- 好处:接收资产方能基本确定自己的资产的价值(假设总估值不变),不会因为过度发行资产导致通货膨胀
- 坏处:当发行资产数量到达上限后,发行方继续发行的有效资产,将无法在合约里兑付。