solidity代碼

 

 

 

http://www.tryblockchain.org/javascript

教你如何舒服的看solidity代碼

最近智能合約隨着區塊鏈技術的發展愈加收到廣大技術人員的重視!html

其中最被看好的以太坊就是一個提供智能合約開發的平臺,它擁有比其餘區塊鏈更圖靈完備的技術 -- 以太坊虛擬機(EVM)。。您無需去了解區塊鏈底層技術(點對點網絡、數字加密技術等)只要擁有基本的編程知識和javascript基礎,就能夠在區塊鏈上開發一款本身的去中心化應用。java

以太坊開發了一套近似於javascript語言--solidity。node

歡迎加入QQ羣:325411816 和有眼光的人共同進步!c++

雖然它和javascript很相近,可是當咱們下載了一些Demo來學習它時,卻發現不少編譯器對他的支持不是很友好,致使咱們很難將註釋和代碼區分開來,以下圖:git

雖然近期傳出微軟Visual Studio開始支持solidity,可是筆者還何嘗試。(好像是今天的消息。)github

值得一提的是以太坊官方開發了本身的編譯器--Mix,可是因爲是測試版本常常會崩潰。web


今天我給你們推薦一個編譯器能讓你們舒服的看代碼--Atom!算法

相信你們不少人都據說過這個,而且使用過它。由於它是大名鼎鼎的Github開發的。chrome

你們只用下載一個叫作 language-ethereum 的插件就能夠舒舒服服的看代碼了。以下圖:

是否是很贊?

若是您正在學習Solidity不妨一試。

加入QQ羣:325411816 咱們共同進步!

 

 

 

 

Solidity番外篇(一)Solidity在線or插件使用

標籤: 區塊鏈solidity以太坊插件
 分類:
 

目錄(?)[+]

 

在學習以太坊合約的過程當中會須要本身編寫智能合約,官方提供了幾種方式供你們使用。下面分別簡單介紹一下,若是有錯誤的地方,還留言指正補充。

DAPP IDE

說實話,這個版本IDE我尚未使用過,只提供一個鏈接地址供你們參考。 
The-DApp-IDE 
此鏈接中有具體的使用描述。

在線編程

Solidity支持在線編程,在線編程網址爲:

https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.4+commit.4633f3de.js
  • 1
  • 1

直接在瀏覽器中輸入此鏈接便可進入。

瀏覽器插件

進入chrome擴展程序,找到chrome網上應用,搜索「Solidity」,選擇Sol那個插件安裝。安裝以後在瀏覽器右上角會出現對應插件的圖標,點擊進入與在線編程操做界面基本相同。 
這裏寫圖片描述

使用簡介

在線編程和瀏覽器插件頁面初始化時已經提供了一個投票的合約,能夠具體閱讀如下代碼。 
也能夠經過左上角的按鈕新建本身的合約。在編寫代碼的過程當中兩個插件都會進行自動的錯誤提示。不一樣的是,在線版本的須要制定solidity的版本。

頁面的其餘功能你們就慢慢摸索吧。 
這裏寫圖片描述

 
 

 

 

 

 

 

 

安裝Solidity

基於瀏覽器的Solidity

若是你只是想嘗試一個使用Solidity的小合約,你不須要安裝任何東西,只要訪問基於瀏覽器的Solidity

若是你想離線使用,你能夠保存頁面到本地,或者從 http://github.com/chriseth/browser-solidity 克隆一個。

NPM / node.js

這可能安裝Solidity到本地最輕便最省事的方法。

在基於瀏覽器的Solidity上,Emscripten提供了一個跨平臺JavaScript庫,把C++源碼編譯爲javascript,同時也提供NPM安裝包。

去安裝它就能夠簡單使用。

npm install solc
  • 1
  • 1

如何使用nodejs包的詳細信息能夠在代碼庫中找到。

二進制安裝包

包括Mix IDE的二進制Solidity安裝包在Ethereum網站C++ bundle中下載。

從源碼構建

在MacOS X、Ubuntu和其它類Unix系統中編譯安裝Solidity很是類似。這個指南開始講解如何在每一個平臺下安裝相關的依賴軟件,而後構建Solidity。 
MacOS X

MACOS X系統 
系統需求: 
- OS X Yosemite (10.10.5) 
- Homebrew 
- Xcode 
安裝Homebrew:

brew update
    brew install boost --c++11 # 這須要等待一段時間 brew install cmake cryptopp miniupnpc leveldb gmp libmicrohttpd libjson-rpc-cpp # 僅僅安裝Mix IDE和Alethzero brew install xz d-bus brew install llvm --HEAD --with-clang brew install qt5 --with-d-bus # 若是長時間的等待讓你發瘋,那麼添加--verbose輸出信息會讓你感受更好。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Ubuntu系統

下面是在最新版Ubuntu系統上編譯安裝Solidity的指南。最佳的支持平臺是2014年11月發佈的64位Ubuntu 14.04,至少須要2GB內存。咱們全部的測試都是基於此版本,固然咱們也歡迎其它版本的測試貢獻者。

安裝依賴軟件:

在你從源碼編譯以前,你須要準備一些工具和依賴軟件。

首先,升級你的代碼庫。Ubuntu主代碼庫不提供全部的包,你須要從Ethereum PPA和LLVM獲取。

注意Ubuntu 14.04的用戶須要使用:sudo apt-add-repository ppa:george-edison55/cmake-3.x獲取最新版本的cmake。

如今加入其它的包:

sudo apt-get -y update sudo apt-get -y install language-pack-en-base sudo dpkg-reconfigure locales sudo apt-get -y install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo add-apt-repository -y ppa:ethereum/ethereum-dev sudo apt-get -y update sudo apt-get -y upgrade
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

對於Ubbuntu 15.04(Vivid Vervet)或者更老版本,使用下面的命令獲取開發相關的包:

sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjson-rpc-cpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
  • 1
  • 1

對於Ubbuntu 15.10(Wily Werewolf)或者更新版本,使用下面的命令獲取開發相關的包:

sudo apt-get -y install build-essential git cmake libboost-all-dev libgmp-dev libleveldb-dev libminiupnpc-dev libreadline-dev libncurses5-dev libcurl4-openssl-dev libcryptopp-dev libjsonrpccpp-dev libmicrohttpd-dev libjsoncpp-dev libedit-dev libz-dev
  • 1
  • 1

不一樣版本使用不一樣獲取命令的緣由是,libjsonrpccpp-dev已經在最新版的Ubuntu的通用代碼倉庫中。

編譯

若是你只准備安裝solidity,忽略末尾Alethzero和Mix的錯誤。

git clone --recursive https://github.com/ethereum/webthree-umbrella.git cd webthree-umbrella ./webthree-helpers/scripts/ethupdate.sh --no-push --simple-pull --project solidity # 更新Solidity庫 ./webthree-helpers/scripts/ethbuild.sh --no-git --project solidity --all --cores 4 -DEVMJIT=0 # 編譯Solidity及其它 # 在OS X系統加上DEVMJIT將不能編譯,在Linux系統上則沒問題
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

若是你選擇安裝Alethzero和Mix:

git clone --recursive https://github.com/ethereum/webthree-umbrella.git cd webthree-umbrella && mkdir -p build && cd build cmake ..
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

若是你想幫助Solidity的開發,你須要分支(fork)Solidity並添加到你的私人遠端分支: 
注意webthree-umbrella使用子模塊,因此solidity是其本身的Git代碼庫,可是他的設置不是保存在 .git/config, 而是在webthree-umbrella/.git/modules/solidity/config


原文:https://solidity.readthedocs.org/en/latest/installing-solidity.html

譯者: @abao

校對: @shaoping

 

 

Solidity 文檔--第三章:Solidity 編程實例

標籤: solidity區塊鏈文檔實例
 分類:
 

目錄(?)[+]

 

Solidity 編程實例

Voting 投票

接下來的合約很是複雜,但展現了不少Solidity的特性。它實現了一個投票合約。固然,電子選舉的主要問題是如何賦予投票權給準確的人,並防止操縱。咱們不能解決全部的問題,但至少咱們會展現如何委託投票能夠同時作到投票統計是自動和徹底透明。

思路是爲每張選票建立一個合約,每一個投票選項提供一個短名稱。合約建立者做爲會長將會給每一個投票參與人各自的地址投票權。

地址後面的人們能夠選擇本身投票或者委託信任的表明人替他們投票。在投票結束後,winningProposal()將會返回得到票數最多的提案。

/// @title Voting with delegation. /// @title 受權投票 contract Ballot { // 這裏聲明瞭複雜類型 // 將會在被後面的參數使用 // 表明一個獨立的投票人。 struct Voter { uint weight; // 累積的權重。 bool voted; // 若是爲真,則表示該投票人已經投票。 address delegate; // 委託的投票表明 uint vote; // 投票選擇的提案索引號 } // 這是一個獨立提案的類型 struct Proposal { bytes32 name; // 短名稱(32字節) uint voteCount; // 累計得到的票數 } address public chairperson; //這裏聲明一個狀態變量,保存每一個獨立地址的`Voter` 結構 mapping(address => Voter) public voters; //一個存儲`Proposal`結構的動態數組 Proposal[] public proposals; // 建立一個新的投票用於選出一個提案名`proposalNames`. function Ballot(bytes32[] proposalNames) { chairperson = msg.sender; voters[chairperson].weight = 1; //對提供的每個提案名稱,建立一個新的提案 //對象添加到數組末尾 for (uint i = 0; i < proposalNames.length; i++) //`Proposal({...})` 建立了一個臨時的提案對象, //`proposal.push(...)`添加到了提案數組`proposals`末尾。 proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 })); } //給投票人`voter`參加投票的投票權, //只能由投票主持人`chairperson`調用。 function giveRightToVote(address voter) { if (msg.sender != chairperson || voters[voter].voted) //`throw`會終止和撤銷全部的狀態和以太改變。 //若是函數調用無效,這一般是一個好的選擇。 //可是須要注意,這會消耗提供的全部gas。 throw; voters[voter].weight = 1; } // 委託你的投票權到一個投票表明 `to`。 function delegate(address to) { // 指定引用 Voter sender = voters[msg.sender]; if (sender.voted) throw; //當投票表明`to`也委託給別人時,尋找到最終的投票表明 while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) to = voters[to].delegate; // 當最終投票表明等於調用者,是不被容許的。 if (to == msg.sender) throw; //由於`sender`是一個引用, //這裏實際修改了`voters[msg.sender].voted` sender.voted = true; sender.delegate = to; Voter delegate = voters[to]; if (delegate.voted) //若是委託的投票表明已經投票了,直接修改票數 proposals[delegate.vote].voteCount += sender.weight; else //若是投票表明尚未投票,則修改其投票權重。 delegate.weight += sender.weight; } ///投出你的選票(包括委託給你的選票) ///給 `proposals[proposal].name`。 function vote(uint proposal) { Voter sender = voters[msg.sender]; if (sender.voted) throw; sender.voted = true; sender.vote = proposal; //若是`proposal`索引超出了給定的提案數組範圍 //將會自動拋出異常,並撤銷全部的改變。 proposals[proposal].voteCount += sender.weight; } ///@dev 根據當前全部的投票計算出當前的勝出提案 function winningProposal() constant returns (uint winningProposal) { uint winningVoteCount = 0; for (uint p = 0; p < proposals.length; p++) { if (proposals[p].voteCount > winningVoteCount) { winningVoteCount = proposals[p].voteCount; winningProposal = p; } } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

可能的改進

如今,指派投票權到全部的投票參加者須要許多的交易。你能想出更好的方法麼?

盲拍

這一節,咱們將展現在以太上建立一個完整的盲拍合約是多麼簡單。咱們從一個全部人都能看到出價的公開拍賣開始,接着擴展合約成爲一個在拍賣結束之前不能看到實際出價的盲拍。

簡單的公開拍賣

一般簡單的公開拍賣合約,是每一個人能夠在拍賣期間發送他們的競拍出價。爲了實現綁定競拍人的到他們的拍賣,競拍包括髮送金額/ether。若是產生了新的最高競拍價,前一個最高價競拍人將會拿回他的錢。在競拍階段結束後,受益人人須要手動調用合約收取他的錢 — — 合約不會激活本身。

contract SimpleAuction {
    // 拍賣的參數。 // 時間要麼爲unix絕對時間戳(自1970-01-01以來的秒數), // 或者是以秒爲單位的出塊時間 address public beneficiary; uint public auctionStart; uint public biddingTime; //當前的拍賣狀態 address public highestBidder; uint public highestBid; //在結束時設置爲true來拒絕任何改變 bool ended; //當改變時將會觸發的Event event HighestBidIncreased(address bidder, uint amount); event AuctionEnded(address winner, uint amount); //下面是一個叫作natspec的特殊註釋, //由3個連續的斜槓標記,當詢問用戶確認交易事務時將顯示。 ///建立一個簡單的合約使用`_biddingTime`表示的競拍時間, /// 地址`_beneficiary`.表明實際的拍賣者 function SimpleAuction(uint _biddingTime, address _beneficiary) { beneficiary = _beneficiary; auctionStart = now; biddingTime = _biddingTime; } ///對拍賣的競拍保證金會隨着交易事務一塊兒發送, ///只有在競拍失敗的時候纔會退回 function bid() { //不須要任何參數,全部的信息已是交易事務的一部分 if (now > auctionStart + biddingTime) //當競拍結束時撤銷此調用 throw; if (msg.value <= highestBid) //若是出價不是最高的,發回競拍保證金。 throw; if (highestBidder != 0) highestBidder.send(highestBid); highestBidder = msg.sender; highestBid = msg.value; HighestBidIncreased(msg.sender, msg.value); } ///拍賣結束後發送最高的競價到拍賣人 function auctionEnd() { if (now <= auctionStart + biddingTime) throw; //拍賣尚未結束 if (ended) throw; //這個收款函數已經被調用了 AuctionEnded(highestBidder, highestBid); //發送合約擁有全部的錢,由於有一些保證金可能退回失敗了。 beneficiary.send(this.balance); ended = true; } function () { //這個函數將會在發送到合約的交易事務包含無效數據 //或無數據的時執行,這裏撤銷全部的發送, //因此沒有人會在使用合約時由於意外而丟錢。 throw; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

Blind Auction 盲拍

接下來擴展前面的公開拍賣成爲一個盲拍。盲拍的特色是拍賣結束之前沒有時間壓力。在一個透明的計算平臺上建立盲拍系統聽起來可能有些矛盾,可是加密算法能讓你脫離困境。

在拍賣階段, 競拍人不須要發送實際的出價,僅僅只須要發送一個它的散列值。由於目前幾乎不可能找到兩個值(足夠長)的散列值相等,競拍者提交他們的出價散列值。在拍賣結束後,競拍人從新發送未加密的競拍出價,合約將檢查其散列值是否和拍賣階段發送的同樣。 另外一個挑戰是如何讓拍賣同時實現綁定和致盲 :防止競拍人競拍成功後不付錢的惟一的辦法是,在競拍出價的同時發送保證金。可是在Ethereum上發送保證金是沒法致盲,全部人都能看到保證金。下面的合約經過接受任何儘可能大的出價來解決這個問題。固然這能夠在最後的揭拍階段進行復核,一些競拍出價多是無效的,這樣作的目的是(它提供一個顯式的標誌指出是無效的競拍,同時包含高額保證金):競拍人能夠經過放置幾個無效的高價和低價競拍來混淆競爭對手。

contract BlindAuction
{
    struct Bid { bytes32 blindedBid; uint deposit; } address public beneficiary; uint public auctionStart; uint public biddingEnd; uint public revealEnd; bool public ended; mapping(address => Bid[]) public bids; address public highestBidder; uint public highestBid; event AuctionEnded(address winner, uint highestBid); ///修飾器(Modifier)是一個簡便的途徑用來驗證函數輸入的有效性。 ///`onlyBefore` 應用於下面的 `bid`函數,其舊的函數體替換修飾器主體中 `_`後就是其新的函數體 modifier onlyBefore(uint _time) { if (now >= _time) throw; _ } modifier onlyAfter(uint _time) { if (now <= _time) throw; _ } function BlindAuction(uint _biddingTime, uint _revealTime, address _beneficiary) { beneficiary = _beneficiary; auctionStart = now; biddingEnd = now + _biddingTime; revealEnd = biddingEnd + _revealTime; } ///放置一個盲拍出價使用`_blindedBid`=sha3(value,fake,secret). ///僅僅在競拍結束正常揭拍後退還發送的以太。當隨同發送的以太至少 ///等於 "value"指定的保證金而且 "fake"不爲true的時候纔是有效的競拍 ///出價。設置 "fake"爲true或發送不合適的金額將會掩沒真正的競拍出 ///價,可是仍然須要抵押保證金。同一個地址能夠放置多個競拍。 function bid(bytes32 _blindedBid) onlyBefore(biddingEnd) { bids[msg.sender].push(Bid({ blindedBid: _blindedBid, deposit: msg.value })); } ///揭開你的盲拍競價。你將會拿回除了最高出價外的全部競拍保證金 ///以及正常的無效盲拍保證金。 function reveal(uint[] _values, bool[] _fake, bytes32[] _secret) onlyAfter(biddingEnd) onlyBefore(revealEnd) { uint length = bids[msg.sender].length; if (_values.length != length || _fake.length != length || _secret.length != length) throw; uint refund; for (uint i = 0; i < length; i++) { var bid = bids[msg.sender][i]; var (value, fake, secret) = (_values[i], _fake[i], _secret[i]); if (bid.blindedBid != sha3(value, fake, secret)) //出價未被正常揭拍,不能取回保證金。 continue; refund += bid.deposit; if (!fake && bid.deposit >= value) if (placeBid(msg.sender, value)) refund -= value; //保證發送者毫不可能重複取回保證金 bid.blindedBid = 0; } msg.sender.send(refund); } //這是一個內部 (internal)函數, //意味着僅僅只有合約(或者從其繼承的合約)能夠調用 function placeBid(address bidder, uint value) internal returns (bool success) { if (value <= highestBid) return false; if (highestBidder != 0) //退還前一個最高競拍出價 highestBidder.send(highestBid); highestBid = value; highestBidder = bidder; return true; } ///競拍結束後發送最高出價到競拍人 function auctionEnd() onlyAfter(revealEnd) { if (ended) throw; AuctionEnded(highestBidder, highestBid); //發送合約擁有全部的錢,由於有一些保證金退回可能失敗了。 beneficiary.send(this.balance); ended = true; } function () { throw; } } Safe Remote Purchase 安全的遠程購物 contract Purchase { uint public value; address public seller; address public buyer; enum State { Created, Locked, Inactive } State public state; function Purchase() { seller = msg.sender; value = msg.value / 2; if (2 * value != msg.value) throw; } modifier require(bool _condition) { if (!_condition) throw; _ } modifier onlyBuyer() { if (msg.sender != buyer) throw; _ } modifier onlySeller() { if (msg.sender != seller) throw; _ } modifier inState(State _state) { if (state != _state) throw; _ } event aborted(); event purchaseConfirmed(); event itemReceived(); ///終止購物並收回以太。僅僅能夠在合約未鎖定時被賣家調用。 function abort() onlySeller inState(State.Created) { aborted(); seller.send(this.balance); state = State.Inactive; } ///買家確認購買。交易包含兩倍價值的(`2 * value`)以太。 ///這些以太會一直鎖定到收貨確認(confirmReceived)被調用。 function confirmPurchase() inState(State.Created) require(msg.value == 2 * value) { purchaseConfirmed(); buyer = msg.sender; state = State.Locked; } ///確認你(買家)收到了貨物,這將釋放鎖定的以太。 function confirmReceived() onlyBuyer inState(State.Locked) { itemReceived(); buyer.send(value);//咱們有意忽略了返回值。 seller.send(this.balance); state = State.Inactive; } function() { throw; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179

小額支付通道

相關文章
相關標籤/搜索