我們首先清除編輯器的內容,並將檔案命名為Bounty.vy。
我們首先定義智慧合約的結構。
結構是自定義型別,可以對多個變數進行分組。
struct Bounty:
issuer: address
deadline: timestamp
data: bytes32
status: uint256
amount: wei_value
struct Fulfillment:
accepted: bool
fulfiller_address: address
data: bytes32
要測試一切是否正常,請單擊“compile”按鈕以編譯合同。
如果一切正常,您應該在Bytecode,Runtime Bytecode和LLL選項卡中看到輸出,這表明編譯成功。
發放賞金
現在我們已經擁有智慧合約的基本框架,我們可以開始新增功能了。首先我們解決允許使用者發放賞金的問題。
宣告狀態變數
就像Solidity一樣,Vyper有狀態變數。狀態變數是永久儲存在合同儲存中的值。
接下來,我們定義合約的事件。Vyper可以記錄在執行時捕獲的事件併為使用者顯示它。
BountyIssued: event({_id: int128, _issuer: indexed(address),
_amount: wei_value, data: bytes32 })
BountyCancelled: event({ _id: int128, _issuer: indexed(address),
_amount: uint256 })
BountyFulfilled: event({ _bountyId: int128, _issuer: indexed(address),
_fulfiller: indexed(address), _fulfillmentId: int128, _amount: uint256})
FulfillmentAccepted: event({ _bountyId: int128, _issuer: indexed(address)
, _fulfiller: indexed(address), _fulfillmentId: int128, _amount: uint256 })
我們有四個不同領域的活動。客戶端可能希望偵聽合約更改的事件。
宣告用於跟蹤賞金狀態的常量值:
CREATED: constant(uint256) = 0
ACCEPTED: constant(uint256) = 1
CANCELLED: constant(uint256) = 2
定義2個陣列,我們儲存有關每個已發放的賞金和履行的資料:
bounties: map(int128, Bounty)
fulfillments: map(int128, Fulfillment)
為每個履行和賞金定義索引。我們需要這個來獲得現有的履行和賞金的當前位置。
nextBountyIndex: int128
nextFulfillmentIndex: int128
注意:如果未能定義索引,則在嘗試測試合約時最終會遇到此錯誤。
Persistent variable undeclared: nextBountyIndex
釋出賞金功能
現在我們已經宣告瞭我們的狀態變數,我們可以新增函式以允許使用者與我們的智慧合約進行互動。
將public decorator新增到函式中,以便外部使用者可以從合約中呼叫它。為了將eth傳送到我們的合約中,我們需要在函式中新增payable關鍵字。如果沒有這個payme關鍵字,合約將拒絕透過此函式向其傳送eth的所有嘗試
@public
@payable
def issueBounty(_data: bytes32, _deadline: timestamp):
assert msg.value > 0
assert _deadline > block.timestamp
bIndex: int128 = self.nextBountyIndex
self.bounties[bIndex] = Bounty({ issuer: msg.sender, deadline:
_deadline, data: _data, status: 0, amount: msg.value })
self.nextBountyIndex = bIndex + 1
log.BountyIssued(bIndex, msg.sender, msg.value, _data)
函式issueBounty接收一個名為_data的bytes32變數和一個timestamp_deadline作為引數。
assert msg.value > 0
assert _deadline > block.timestamp
由於Vyper不支援修飾符,因此我們使用assert關鍵字檢查來確保滿足每個條件。如果不滿足任何條件,該函式將返回錯誤。
bIndex: int128 = self.nextBountyIndex
我們定義一個int128變數來儲存賞金的當前Index位置。這是必要的,因為我們需要使用它來儲存賞金列表中的新賞金。
我們的函式體有兩行:
self.bounties[bIndex] = Bounty({ issuer: msg.sender, deadline: _deadline,
data: _data, status: 0, amount: msg.value })
self.nextBountyIndex = bIndex + 1
首先,我們使用bIndex將新的Bounty插入到我們的bounties陣列中,將BountyStatus設定為CREATED。
在Vyper中,msg.sender自動設定為傳送方的地址,msg.value設定為Wei的數量(1 ETH = 1000000000000000000 Wei)。
我們將msg.sender設定為發行者,將msg.value設定為賞金金額。
log.BountyIssued(bIndex, msg.sender, msg.value, _data)
最後,我們記錄BountyIssued事件供使用者訂閱。
親自嘗試一下
既然您已經瞭解瞭如何新增函式來發放賞金,請嘗試將以下函式新增到Bounties合約中:
1. ulfilBounty(uint _bountyId,string _data)此函式儲存附加到給定賞金的履行記錄。 應將msg.sender記錄為履行者。
2. acceptFulfilment(uint _bountyId,uint _fulfilmentId)此函式接受給定的履行,並且如果存在針對給定賞金的記錄。 然後它應該向履行者支付賞金。
3. function cancelBounty(uint _bountyId)此函式取消賞金,如果尚未被接受,則將資金髮回給發行人