鏈下資產發行
發行數字資產是區塊鏈的一大應用。同質化的火幣發行目前大多數基于以太坊的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公司獎勵線上參與者提供訓練模型,可以通過發行這種不需要立即上鏈的資產
- 基于對某個具體個人的信任,他也可以向其他人發行線下資產,資產價值的波動本身蘊含在周圍的人對他的信任的基礎上。
- 眾籌項目,當項目尚未完成,需要對參與眾籌的用戶提供一個購買憑據。
- 一些臨時的應用場景,比如禮物卡
- 當人們在網絡較差的環境下工作時,可以先在無網絡狀態下進行簽名,等有網環境下再去兌現。
爭論
- 是否應當設置總量上限。
- 好處:接收資產方能基本確定自己的資產的價值(假設總估值不變),不會因為過度發行資產導致通貨膨脹
- 壞處:當發行資產數量到達上限后,發行方繼續發行的有效資產,將無法在合約里兌付。