使用在线Remix IDE开始在Vyper中编写智能合约的是最简单的工具。
由于它是一个在线IDE,因此无需安装或开发环境设置,您可以打开该站点并开始使用!
Remix提供在线环境中进行调试,静态分析和部署的工具。要将Remix与Vyper一起使用,首先需要从插件管理器选项卡启用Vyper插件。
1. 在dapp中允许任何用户使用eth发放赏金
2. 当满足一定要求时,任何拥有以太坊帐户的用户都可以在ETH中发放赏金
3. 任何用户都可以提交一份赏金的履行情况和证明
4. 赏金发行人接受履行支付
我们首先清除编辑器的内容,并将文件命名为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)此函数取消赏金,如果尚未被接受,则将资金发回给发行人