50行代碼寫就以太坊支付
狀態通道(State Channel)是非常流行的擴容方案。比特幣線下支付通道有閃電(lightning),以太坊有雷電(Raiden) 本文演示如何立刻用合約寫以太坊支付.
源代碼在這裡
假設在Alice和Bob之間發生的微支付場景: Bob僱傭Alice為他的推特的水軍,定期在Bob的推特上發推,回帖。為此BOB答應Alice,每發一個推(tweet),Bob支付0.001個ETH。這種微支付交易通過公鏈來做的話,20%的Alice的收入都會被以交易費的方式吃掉。
一方面,Alice不想每發100條推特後才信任Bob會付總額0.001ETH*100=0.1ETH。因為BOB有可能賴賬。另一方面,Bob不想一次性付Alice發100個推特的錢,因為Alice完全有可能拿了錢,人間蒸發而不幹活。
這時候,我們就需要一個支付通道,Bob預先打100*0.001 = 0.1 ETH 到通道的智能合約,按照合約的規則,合約里的錢可能給Alice,也可能退回給BOB. 構造函數如下:
contract Channel { address public channelSender; address public channelRecipient; uint public startDate; uint public channelTimeout; mapping (bytes32 => address) signatures; function Channel(address to, uint timeout) payable { channelRecipient = to; channelSender = msg.sender; startDate = now; channelTimeout = timeout; }
假設Bob送了0.1 ETH給這個合約,而且設定Timeout為1天。如果timeout發生,Bob可以撤銷這個合約,從而獲得被退回的餘額.
Alice看到支付通道合約里有錢被鎖定了,Alice就放心的開始工作:發推特。每發一個tweet, Bob就用私鑰簽名一個(contract_address, value)產生的哈希值,並送給 Alice. 所以,Alice發第一個tweet, Bob 就簽(0x123…, 0.001 ETH), 發第二個推特,Bob簽(0x123, 0.002 ETH), etc…
每次Alice收到Bob簽名的信息,Alice也簽名,但是並不送到公鏈。任何時候Alice決定終止這分工作時,alice需要發一個多人簽名(Bob和Alice)的消息給合約。合約就會送給Alice事先約定好的酬勞 (say, 0.05 ETH=發了50個推特*0.001ETH) 並把合約里剩餘的資金返回給Bob.
function CloseChannel(bytes32 h, uint8 v, bytes32 r, bytes32 s, uint value){ address signer; bytes32 proof; // get signer from signature signer = ecrecover(h, v, r, s); // signature is invalid, throw if (signer != channelSender && signer != channelRecipient) throw; proof = sha3(this, value); // signature is valid but doesnt match the data provided if (proof != h) throw; if (signatures[proof] == 0) signatures[proof] = signer; else if (signatures[proof] != signer){ // channel completed, both signatures provided if (!channelRecipient.send(value)) throw; selfdestruct(channelSender); }}
Alice可以調用這個函數中止通道。因為調用此函數需要Bob和Alice的簽名,Bob不能單方面的關閉合約(從而不付Alice她應得的報酬)
因為此函數需要Bob和Alice兩個人的簽名才能執行,Bob和Alice都不能單方面的從合約里提錢。
如果Alice是惡意的,而且希望欺騙Bob:讓Bob把錢鎖進合約,但是Alice不幹任何事,並且偽造一個交易(讓合約送給Alice一半的錢)這種情況下,ChannelTimeout函數可以保護Bob:Bob可以等一天,然後調用, 把合約銷毀,並把合約里所有的資金返回給Bob.
function ChannelTimeout(){ if (startDate + channelTimeout > now) throw; selfdestruct(channelSender);}
Timeout 函數保證Bob 免受勒索
同時,在Bob和Alice的簽名提交到公鏈之前,Bob沒有Alice的簽名。Bob不能單方面關閉通道從而免付Alice應得的報酬。如果Alice覺察到Bob沒有付錢了,Alice可以關閉通道從而拿到她應得的報酬。唯一的損失是Alice可能損失她發最後一個推特的錢。同時Bob和Alice節省了大量的交易費!
一個支付合約就寫完了
參照
推薦閱讀:
※如何做一個真正去中心化的EOS Blockchain?
※有沒有玩比特幣山寨幣穩賺不賠的方法論?
※?ENS競標到底是什麼鬼!
※別人貪婪時我賺錢,別人恐懼時我賺錢。