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 doesn`t 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節省了大量的交易費!
一個支付合約就寫完了
附:
ecrecover函式是由以太坊提供的一個全域性函式,用於簽名資料的校驗。與上面所陳述的方式略有不同的是,這個函式返回的是簽名者的公匙地址。如果返回結果是簽名者的公匙地址,那麼說明資料是正確的。
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)
ecrecover
函式需要四個引數,需要被簽名資料的雜湊結果值,r,s,v三個值。通過前面的說明,我們知道r,s,v是分別來自簽名結果串。
r = signature[0:64]
s = signature[64:128]
v = signature[128:130]
其中v取出來的值或者是00
或01
。要使用時,我們先要將其轉為整型,再加上27,所以我們將得到27或28。在呼叫函式時v將填入27或28。
如果你使用以太坊的客戶端進行簽名時,它們會在你要簽名的資料前增加字首x19Ethereum Signed Message:
。
eth_sign
The sign method calculates an Ethereum specific signature with: sign(keccak256(“x19Ethereum Signed Message:
” + len(message) + message))).
相關文章
- 以太坊概率微支付
- 以太坊官方 Token 程式碼詳解
- 如何學習以太坊的程式碼
- 以太坊原始碼分析(5)accounts程式碼分析原始碼
- 以太坊原始碼分析(37)eth以太坊協議分析原始碼協議
- 以太坊原始碼分析(18)以太坊交易執行分析原始碼
- 以太坊原始碼分析(52)以太坊fast sync演算法原始碼AST演算法
- 以太坊原始碼分析(54)以太坊隨機數生成方式原始碼隨機
- 以太坊原始碼分析(3)以太坊交易手續費明細原始碼
- 以太坊交易池原始碼分析原始碼
- 以太坊交易池原始碼解析原始碼
- 以太坊的程式設計介面程式設計
- 以太坊的工作原理 程式篇
- 以太坊原始碼分析(15)node包建立多重協議以太坊節點原始碼協議
- 以太坊是什麼?以太坊交易可靠嗎?
- 以太坊連載(一):以太坊是什麼?
- 以太坊原始碼分析(53)以太坊測試網路Clique_PoA介紹原始碼
- 5.1 以太坊原始碼詳解1原始碼
- 5.2 以太坊原始碼詳解2原始碼
- 5.3 以太坊原始碼詳解3原始碼
- 5.4 以太坊原始碼詳解4原始碼
- 5.5 以太坊原始碼詳解5原始碼
- 5.6 以太坊原始碼詳解6原始碼
- 5.7 以太坊原始碼詳解7原始碼
- 以太坊原始碼分析(13)RPC分析原始碼RPC
- 以太坊Solidity程式語言開發框架————10、外部指令碼Solid框架指令碼
- 以太坊原始碼分析(36)ethdb原始碼分析原始碼
- 以太坊原始碼分析(38)event原始碼分析原始碼
- 以太坊原始碼分析(41)hashimoto原始碼分析原始碼
- 以太坊原始碼分析(43)node原始碼分析原始碼
- 以太坊原始碼分析(51)rpc原始碼分析原始碼RPC
- 以太坊原始碼分析(52)trie原始碼分析原始碼
- 以太坊學習筆記————1、以太坊是什麼?筆記
- 以太坊學習筆記————7、以太坊賬戶管理筆記
- 用 PHP 開發一個簡單的以太坊支付系統PHP
- 以太坊啟動過程原始碼解析原始碼
- 死磕以太坊原始碼分析之state原始碼
- 死磕以太坊原始碼分析之txpool原始碼