StandardBounties/docs/documentation.md

531 lines
20 KiB
Markdown
Raw Permalink Normal View History

2017-08-07 19:35:40 +00:00
# StandardBounties Complete Documentation
2017-07-04 20:23:27 +00:00
2017-10-09 16:11:01 +00:00
`Version 1.0.0`
2017-07-04 20:23:27 +00:00
## Summary
2017-10-02 16:45:17 +00:00
A bounty is a simple mechanism for individuals or groups to pay out for the completion of tasks. The issuer of the bounty begins by deploying a new bounty contract, during which time any of the storage variables (like bounty requirements or the payout amount) can be altered. Once sufficient funds have been deposited into the contract, the issuer may activate the bounty, allowing bounty hunters to submit fulfillments for the bounty task. The issuer can then approve the submitted work, releasing the payout funds to the bounty hunter in question.
2017-07-04 20:23:27 +00:00
2017-08-07 19:35:40 +00:00
## Contract Details
2017-08-08 16:23:25 +00:00
### Storage
2017-10-02 16:45:17 +00:00
`address issuer`
2017-08-28 20:25:04 +00:00
The issuer is the creator of the bounty, and has full control over administering its rewards.
2017-08-08 16:23:25 +00:00
2017-10-02 16:45:17 +00:00
`uint deadline`
A bounty can only be contributed to, activated, or fulfilled before the given deadline, however fulfillments can be accepted even after the deadline has passed. This deadline can be moved forward or backwards in the draft stage, but once the bounty is activated it can only be extended. This helps maintain the contractual nature of the relationship, where issuers cannot move deadlines forward arbitrarily while individuals are fulfilling the tasks.
`string public data`
2017-10-09 16:11:01 +00:00
All data representing the requirements are stored off-chain on IPFS, and their hash is updated here. Requirements and auxiliary data are mutable while the bounty is in the `Draft` stage, but becomes immutable when the bounty is activated, thereby "locking in" the terms of the contract, the requirements for acceptance for each milestone. These should be as rich as possible from the outset, to avoid conflicts stemming from task fulfillers believing they merited the bounty reward.
The schema for the bounty data field is:
```
{
title: // A string representing the title of the bounty
description: // A string representing the description of the bounty, including all requirements
sourceFileName: // A string representing the name of the file
sourceFileHash: // The IPFS hash of the file associated with the bounty
contact: // A string representing the preferred contact method of the issuer of the bounty
categories: // an array of strings, representing the categories of tasks which are being requested
2017-11-15 16:12:10 +00:00
githubLink: // The link to the relevant repository
2017-10-09 16:11:01 +00:00
}
```
2017-10-02 16:45:17 +00:00
The current set of categories in use is:
```
['Code', 'Bugs', 'Questions', 'Graphic Design', 'Social Media', 'Content Creation', 'Translations', 'Surveys']
```
If you would like to add or amend fields in the data schema presented, please open a github issue and they will be added.
2017-10-02 16:45:17 +00:00
`uint public fulfillmentAmount`
The number of units which the bounty pays out for successful completion, either in wei or in token units for the relevant contract.
`address arbiter`
2017-08-28 20:25:04 +00:00
The arbiter is an individual or contract who is able to accept fulfillments on the issuer's behalf. The arbiter is also disallowed from fulfilling the bounty.
2017-08-08 16:23:25 +00:00
2017-10-02 16:45:17 +00:00
`bool paysTokens`
A representation of whether the given bounty pays in ERC20 tokens or in ETH. When it is `true`, the bounty cannot accept ETH deposits, and vice versa when it is false, it will not transfer tokens to the contract.
`BountyStages bountyStage`
2017-08-28 20:25:04 +00:00
Bounties are formed in the `Draft` stage, a period during which the issuer can edit any of the bounty's state variables, and attain sufficient funding. In the draft stage, no fulfillments can be submitted, and no funds can be paid out.
2017-10-02 16:45:17 +00:00
Once the bounty state variables are finalized, and the bounty contract holds sufficient funds to pay out each milestone at least once, it can be transitioned to the `Active` stage by only the issuer. During the active stage, the requirements or payout amount cannot be altered, however the deadline may be extended. Fulfillments can only be submitted in the `Active` stage before the deadline, although they may be accepted by the issuer or arbiter even after the deadline has passed.
2017-08-28 20:25:04 +00:00
At any point, the issuer can kill the bounty returning all funds to them (less the amount due for already accepted but unpaid submissions), transitioning the bounty into the `Dead` stage. However, this behaviour is highly discouraged and should be avoided at all costs.
2017-08-08 16:23:25 +00:00
2017-10-02 16:45:17 +00:00
`uint balance`
The number of units of tokens or ETH which the bounty has under its control. The balance must always be greater than or equal to the owedAmount for a given bounty.
2017-08-08 16:23:25 +00:00
2017-08-09 14:17:17 +00:00
`mapping(uint=>Fulfillment[]) public fulfillments`
2017-10-02 16:45:17 +00:00
Work is submitted and a hash is stored on-chain, allowing any deliverable to be submitted for the same bounty. Fulfillments for a given `_bountyId` are added to the array of fulfillments at that same `_bountyId`.
2017-08-08 16:23:25 +00:00
2017-08-09 14:17:17 +00:00
`mapping(uint=>uint) public numAccepted`
2017-10-02 16:45:17 +00:00
The number of submissions which have been accepted for each bounty
2017-08-08 16:23:25 +00:00
2017-08-07 19:35:40 +00:00
### External functions
2017-10-02 16:45:17 +00:00
#### StandardBounties()
Constructs the StandardBounties registry and instantiates it's owner as given
```
function StandardBounties(address _owner)
public
{
owner = _owner;
}
```
#### issueBounty()
Issues the bounty and instantiates state variables, initializing it in the draft stage. The bounty deadline must be after the time of issuance (contract deployment), and none of the milestones can pay out 0 tokens.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function issueBounty(
address _issuer,
2017-08-08 16:23:25 +00:00
uint _deadline,
string _data,
2017-10-02 16:45:17 +00:00
uint256 _fulfillmentAmount,
address _arbiter,
bool _paysTokens,
address _tokenContract
2017-08-08 16:23:25 +00:00
)
2017-10-02 16:45:17 +00:00
public
2017-08-08 16:23:25 +00:00
validateDeadline(_deadline)
2017-10-02 16:45:17 +00:00
amountIsNotZero(_fulfillmentAmount)
2017-10-05 16:14:46 +00:00
validateNotTooManyBounties
2017-10-02 16:45:17 +00:00
returns (uint)
2017-08-08 16:23:25 +00:00
{
bounties.push(Bounty(_issuer, _deadline, _data, _fulfillmentAmount, _arbiter, _paysTokens, BountyStages.Draft, 0));
2017-10-02 16:45:17 +00:00
if (_paysTokens){
tokenContracts[bounties.length - 1] = HumanStandardToken(_tokenContract);
}
BountyIssued(bounties.length - 1);
return (bounties.length - 1);
}
```
#### issueAndActivateBounty()
Issues the bounty and instantiates state variables, initializing it in the active stage. The bounty deadline must be after the time of issuance (contract deployment), and none of the milestones can pay out 0 tokens. The issuer must specify their initial deposit amount, which is checked against the deposited tokens or ETH. This new amount is the initial balance of the bounty.
```
function issueAndActivateBounty(
address _issuer,
uint _deadline,
string _data,
uint256 _fulfillmentAmount,
address _arbiter,
bool _paysTokens,
address _tokenContract,
uint256 _value
)
public
payable
validateDeadline(_deadline)
amountIsNotZero(_fulfillmentAmount)
2017-10-02 18:41:59 +00:00
validateNotTooManyBounties
2017-10-02 16:45:17 +00:00
returns (uint)
{
require (_value >= _fulfillmentAmount);
if (_paysTokens){
require(msg.value == 0);
2017-10-02 16:45:17 +00:00
tokenContracts[bounties.length] = HumanStandardToken(_tokenContract);
require(tokenContracts[bounties.length].transferFrom(msg.sender, this, _value));
} else {
require((_value * 1 wei) == msg.value);
}
bounties.push(Bounty(_issuer,
_deadline,
_data,
_fulfillmentAmount,
_arbiter,
_paysTokens,
BountyStages.Active,
_value));
BountyIssued(bounties.length - 1);
2017-10-02 18:41:59 +00:00
ContributionAdded(bounties.length - 1, msg.sender, _value);
BountyActivated(bounties.length - 1, msg.sender);
2017-10-02 16:45:17 +00:00
return (bounties.length - 1);
2017-08-08 16:23:25 +00:00
}
```
#### Contribute()
2017-08-28 20:25:04 +00:00
This allows a bounty to receive 3rd party contributions from the crowd. This functionality is only available before the deadline has passed, and while the bounty is not in the `Dead` stage. The Ether (or tokens) which are deposited are at the mercy of the issuer, who can at any point call `killBounty()` to drain remaining funds.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function contribute (uint _bountyId, uint _value)
2017-08-08 16:23:25 +00:00
payable
2017-10-02 16:45:17 +00:00
public
validateBountyArrayIndex(_bountyId)
2017-10-02 16:45:17 +00:00
isBeforeDeadline(_bountyId)
isNotDead(_bountyId)
amountIsNotZero(_value)
transferredAmountEqualsValue(_bountyId, _value)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
bounties[_bountyId].balance += _value;
ContributionAdded(_bountyId, msg.sender, _value);
2017-08-08 16:23:25 +00:00
}
```
#### ActivateBounty()
2017-10-02 16:45:17 +00:00
If the bounty has sufficient funds to pay out at least once, it can be activated, allowing individuals to add submissions. Only the issuer is allowed to activate their bounty.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function activateBounty(uint _bountyId, uint _value)
2017-08-08 16:23:25 +00:00
payable
public
validateBountyArrayIndex(_bountyId)
2017-10-02 16:45:17 +00:00
isBeforeDeadline(_bountyId)
onlyIssuer(_bountyId)
transferredAmountEqualsValue(_bountyId, _value)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
bounties[_bountyId].balance += _value;
require (bounties[_bountyId].balance >= bounties[_bountyId].fulfillmentAmount);
2017-10-02 16:45:17 +00:00
transitionToState(_bountyId, BountyStages.Active);
2017-08-08 16:23:25 +00:00
2017-10-02 18:41:59 +00:00
ContributionAdded(_bountyId, msg.sender, _value);
2017-10-02 16:45:17 +00:00
BountyActivated(_bountyId, msg.sender);
2017-08-08 16:23:25 +00:00
}
```
#### FulfillBounty()
2017-10-02 16:45:17 +00:00
Once the bounty is active, anyone can fulfill it and submit the necessary deliverables (as long as the deadline has not passed). Anyone can fulfill the bounty, except for the issuer and arbiter, who are disallowed from doing so.
2017-08-28 20:25:04 +00:00
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function fulfillBounty(uint _bountyId, string _data)
2017-08-08 16:23:25 +00:00
public
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
2017-10-05 16:14:46 +00:00
validateNotTooManyFulfillments(_bountyId)
2017-10-02 16:45:17 +00:00
isAtStage(_bountyId, BountyStages.Active)
isBeforeDeadline(_bountyId)
notIssuerOrArbiter(_bountyId)
2017-08-08 16:23:25 +00:00
{
fulfillments[_bountyId].push(Fulfillment(false, msg.sender, _data));
2017-08-08 16:23:25 +00:00
2017-10-02 16:45:17 +00:00
BountyFulfilled(_bountyId, msg.sender, (fulfillments[_bountyId].length - 1));
2017-08-08 16:23:25 +00:00
}
```
2017-08-28 20:25:04 +00:00
#### updateFulfillment()
After a bounty has been fulfilled, the data representing the fulfillment deliverables can be changed or updated by the fulfiller, but only before the bounty has been accepted or paid. Individuals may only update the fulfillments which they personally submitted.
```
2017-10-02 16:45:17 +00:00
function updateFulfillment(uint _bountyId, uint _fulfillmentId, string _data)
public
validateBountyArrayIndex(_bountyId)
validateFulfillmentArrayIndex(_bountyId, _fulfillmentId)
onlyFulfiller(_bountyId, _fulfillmentId)
notYetAccepted(_bountyId, _fulfillmentId)
{
2017-10-02 16:45:17 +00:00
fulfillments[_bountyId][_fulfillmentId].data = _data;
2017-10-05 16:14:46 +00:00
FulfillmentUpdated(_bountyId, _fulfillmentId);
}
```
2017-08-08 16:23:25 +00:00
#### AcceptFulfillment()
Submissions can be accepted by the issuer while the bounty is active, and the contract has sufficient funds to pay out all previously accepted submissions. Arbiters also have the ability to accept work, but should only do so after mediating between the issuer and fulfiller to resolve the conflict.
2017-08-28 20:25:04 +00:00
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function acceptFulfillment(uint _bountyId, uint _fulfillmentId)
2017-08-08 16:23:25 +00:00
public
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
validateFulfillmentArrayIndex(_bountyId, _fulfillmentId)
2017-10-02 16:45:17 +00:00
onlyIssuerOrArbiter(_bountyId)
isAtStage(_bountyId, BountyStages.Active)
fulfillmentNotYetAccepted(_bountyId, _fulfillmentId)
enoughFundsToPay(_bountyId)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
fulfillments[_bountyId][_fulfillmentId].accepted = true;
numAccepted[_bountyId]++;
bounties[_bountyId].balance -= bounties[_bountyId].fulfillmentAmount;
if (bounties[_bountyId].paysTokens){
require(tokenContracts[_bountyId].transfer(fulfillments[_bountyId][_fulfillmentId].fulfiller, bounties[_bountyId].fulfillmentAmount));
2017-10-02 16:45:17 +00:00
} else {
fulfillments[_bountyId][_fulfillmentId].fulfiller.transfer(bounties[_bountyId].fulfillmentAmount);
}
FulfillmentAccepted(_bountyId, msg.sender, _fulfillmentId);
2017-08-08 16:23:25 +00:00
}
```
2017-08-28 20:25:04 +00:00
2017-08-08 16:23:25 +00:00
#### KillBounty()
2017-10-02 16:45:17 +00:00
The issuer of the bounty can transition it into the `Dead` stage at any point in time, draining the bounty of all remaining funds (less the amount still due for successful fulfillments which are yet unpaid).
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function killBounty(uint _bountyId)
2017-08-08 16:23:25 +00:00
public
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
transitionToState(_bountyId, BountyStages.Dead);
uint oldBalance = bounties[_bountyId].balance;
bounties[_bountyId].balance = 0;
if (oldBalance > 0){
if (bounties[_bountyId].paysTokens){
require(tokenContracts[_bountyId].transfer(bounties[_bountyId].issuer, oldBalance));
} else {
bounties[_bountyId].issuer.transfer(oldBalance);
}
2017-10-02 16:45:17 +00:00
}
BountyKilled(_bountyId, msg.sender);
2017-08-08 16:23:25 +00:00
}
```
#### ExtendDeadline()
The issuer of the bounty can extend the deadline at any time, allowing more time for submissions to be fulfilled.
```
2017-10-02 16:45:17 +00:00
function extendDeadline(uint _bountyId, uint _newDeadline)
2017-08-08 16:23:25 +00:00
public
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
newDeadlineIsValid(_bountyId, _newDeadline)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
bounties[_bountyId].deadline = _newDeadline;
2017-08-08 16:23:25 +00:00
2017-10-02 16:45:17 +00:00
DeadlineExtended(_bountyId, _newDeadline);
2017-08-08 16:23:25 +00:00
}
```
#### transferIssuer()
2017-08-28 20:25:04 +00:00
At any point, the issuer can transfer ownership of the bounty to a new address that they supply. This gives full power and authority to the new issuer address, and releases the old issuer address from the ability to administer the bounty.
```
2017-10-02 16:45:17 +00:00
function transferIssuer(uint _bountyId, address _newIssuer)
public
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
{
2017-10-02 16:45:17 +00:00
bounties[_bountyId].issuer = _newIssuer;
2017-10-05 16:14:46 +00:00
IssuerTransferred(_bountyId, _newIssuer);
}
```
2017-10-02 16:45:17 +00:00
#### changeBountyDeadline()
The issuer of the bounty can change the deadline while the bounty is in the `Draft` stage. This is not allowed when the bounty is in the `Active` or `Dead` stage.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function changeBountyDeadline(uint _bountyId, uint _newDeadline)
2017-08-08 16:23:25 +00:00
public
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
2017-08-08 16:23:25 +00:00
validateDeadline(_newDeadline)
2017-10-02 16:45:17 +00:00
isAtStage(_bountyId, BountyStages.Draft)
{
bounties[_bountyId].deadline = _newDeadline;
BountyChanged(_bountyId);
}
```
#### changeBountyData()
The issuer of the bounty can change the data while the bounty is in the `Draft` stage. This is not allowed when the bounty is in the `Active` or `Dead` stage.
```
function changeBountyData(uint _bountyId, string _newData)
public
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
isAtStage(_bountyId, BountyStages.Draft)
{
bounties[_bountyId].data = _newData;
BountyChanged(_bountyId);
}
```
#### changeBountyFulfillmentAmount()
The issuer of the bounty can change the fulfillment amount while the bounty is in the `Draft` stage. This is not allowed when the bounty is in the `Active` or `Dead` stage.
```
function changeBountyFulfillmentAmount(uint _bountyId, uint _newFulfillmentAmount)
public
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
isAtStage(_bountyId, BountyStages.Draft)
{
bounties[_bountyId].fulfillmentAmount = _newFulfillmentAmount;
BountyChanged(_bountyId);
}
```
#### changeBountyArbiter()
The issuer of the bounty can change the arbiter while the bounty is in the `Draft` stage. This is not allowed when the bounty is in the `Active` or `Dead` stage.
```
function changeBountyArbiter(uint _bountyId, address _newArbiter)
public
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
isAtStage(_bountyId, BountyStages.Draft)
{
bounties[_bountyId].arbiter = _newArbiter;
BountyChanged(_bountyId);
}
```
#### changeBountyPaysTokens()
The issuer of the bounty can change whether the bounty pays in tokens or ETH, or change the token contract, while the bounty is in the `Draft` stage. This is not allowed when the bounty is in the `Active` or `Dead` stage. If the balance of the contract is non-zero, it will return all contributed funds to the issuer.
```
function changeBountyPaysTokens(uint _bountyId, bool _newPaysTokens, address _newTokenContract)
public
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
isAtStage(_bountyId, BountyStages.Draft)
2017-08-08 16:23:25 +00:00
{
HumanStandardToken oldToken = tokenContracts[_bountyId];
bool oldPaysTokens = bounties[_bountyId].paysTokens;
bounties[_bountyId].paysTokens = _newPaysTokens;
tokenContracts[_bountyId] = HumanStandardToken(_newTokenContract);
2017-10-02 16:45:17 +00:00
if (bounties[_bountyId].balance > 0){
2017-10-05 16:14:46 +00:00
uint oldBalance = bounties[_bountyId].balance;
bounties[_bountyId].balance = 0;
if (oldPaysTokens){
require(oldToken.transfer(bounties[_bountyId].issuer, oldBalance));
2017-10-02 16:45:17 +00:00
} else {
2017-10-05 16:14:46 +00:00
bounties[_bountyId].issuer.transfer(oldBalance);
2017-10-02 16:45:17 +00:00
}
}
BountyChanged(_bountyId);
}
```
#### increasePayout()
The issuer of the bounty can increase the payout of the bounty even in the `Active` stage, as long as the balance of their bounty is sufficient to pay out any accepted fulfillments.
```
2017-10-02 18:41:59 +00:00
function increasePayout(uint _bountyId, uint _newFulfillmentAmount, uint _value)
2017-10-02 16:45:17 +00:00
public
2017-10-02 18:41:59 +00:00
payable
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
onlyIssuer(_bountyId)
newFulfillmentAmountIsIncrease(_bountyId, _newFulfillmentAmount)
2017-10-02 18:41:59 +00:00
transferredAmountEqualsValue(_bountyId, _value)
2017-10-02 16:45:17 +00:00
{
2017-10-02 18:41:59 +00:00
bounties[_bountyId].balance += _value;
require(bounties[_bountyId].balance >= _newFulfillmentAmount);
2017-10-02 16:45:17 +00:00
bounties[_bountyId].fulfillmentAmount = _newFulfillmentAmount;
2017-10-02 18:41:59 +00:00
PayoutIncreased(_bountyId, _newFulfillmentAmount);
2017-08-08 16:23:25 +00:00
}
```
#### getFulfillment()
2017-10-02 16:45:17 +00:00
Returns all of the information describing a given fulfillment for a given bounty.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function getFulfillment(uint _bountyId, uint _fulfillmentId)
2017-08-08 16:23:25 +00:00
public
constant
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
validateFulfillmentArrayIndex(_bountyId, _fulfillmentId)
returns (bool, address, string)
2017-08-08 16:23:25 +00:00
{
return (fulfillments[_bountyId][_fulfillmentId].accepted,
2017-10-02 16:45:17 +00:00
fulfillments[_bountyId][_fulfillmentId].fulfiller,
fulfillments[_bountyId][_fulfillmentId].data);
2017-08-08 16:23:25 +00:00
}
```
2017-10-02 16:45:17 +00:00
2017-08-08 16:23:25 +00:00
#### getBounty()
2017-10-02 16:45:17 +00:00
Returns a tuple of the variables describing the bounty, except for the arbiter, data, or token contract.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function getBounty(uint _bountyId)
2017-08-08 16:23:25 +00:00
public
constant
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
returns (address, uint, uint, bool, uint, uint)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
return (bounties[_bountyId].issuer,
bounties[_bountyId].deadline,
bounties[_bountyId].fulfillmentAmount,
bounties[_bountyId].paysTokens,
uint(bounties[_bountyId].bountyStage),
bounties[_bountyId].balance);
2017-08-08 16:23:25 +00:00
}
```
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
#### getBountyArbiter()
Returns an address of the arbiter for the given bounty.
2017-08-08 16:23:25 +00:00
```
2017-10-02 16:45:17 +00:00
function getBountyArbiter(uint _bountyId)
2017-08-08 16:23:25 +00:00
public
constant
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
returns (address)
2017-08-08 16:23:25 +00:00
{
2017-10-02 16:45:17 +00:00
return (bounties[_bountyId].arbiter);
2017-08-08 16:23:25 +00:00
}
```
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
#### getBountyData()
Returns a string of the data for the given bounty.
```
2017-10-02 16:45:17 +00:00
function getBountyData(uint _bountyId)
public
constant
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
returns (string)
{
2017-10-02 16:45:17 +00:00
return (bounties[_bountyId].data);
}
```
2017-10-02 16:45:17 +00:00
#### getBountyToken()
Returns an address of the token for the given bounty.
```
2017-10-02 16:45:17 +00:00
function getBountyToken(uint _bountyId)
public
constant
2017-10-02 16:45:17 +00:00
validateBountyArrayIndex(_bountyId)
returns (address)
{
2017-10-02 16:45:17 +00:00
return (tokenContracts[_bountyId]);
}
```
2017-10-05 16:14:46 +00:00
#### getNumBounties()
Returns the number of bounties which exist on the registry
```
function getNumBounties()
public
constant
returns (uint)
{
return bounties.length;
}
```
2017-10-02 16:45:17 +00:00
#### getNumFulfillments()
Returns the number of fulfillments which have been submitted for a given bounty
```
function getNumFulfillments(uint _bountyId)
public
constant
validateBountyArrayIndex(_bountyId)
returns (uint)
{
return fulfillments[_bountyId].length;
}
```
2017-08-07 19:35:40 +00:00
### Events
2017-10-02 16:45:17 +00:00
```event BountyIssued(uint bountyId);```
This is emitted when a new bounty is issued on the StandardBounties registry
```event BountyActivated(uint bountyId, address issuer);```
2017-08-07 19:35:40 +00:00
This is emitted when the bounty gets activated by the issuer
2017-10-02 16:45:17 +00:00
```event BountyFulfilled(uint bountyId, address indexed fulfiller, uint256 indexed _fulfillmentId);```
This is emitted when a given bounty is fulfilled
```event FulfillmentUpdated(uint _bountyId, uint _fulfillmentId);```
This is emitted when a given fulfillment is altered
```event FulfillmentAccepted(uint bountyId, address indexed fulfiller, uint256 indexed _fulfillmentId);```
This is emitted when a given fulfillment for a given bounty is accepted and paid
2017-10-02 16:45:17 +00:00
```event BountyKilled(uint bountyId);```
This is emitted when a given bounty is killed
```event ContributionAdded(uint bountyId, address indexed contributor, uint256 value);```
This is emitted when an individual contributes to a given bounty
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
```event DeadlineExtended(uint bountyId, uint newDeadline);```
This is emitted when the deadline of the bounty has been extended
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
```event BountyChanged(uint bountyId);```
This is emitted when the bounty has been changed (in the draft stage)
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
```event IssuerTransferred(uint _bountyId, address indexed _newIssuer);```
This is emitted when the issuer of a bounty transfers the ownership of the bounty to a new issuer.
2017-08-07 19:35:40 +00:00
2017-10-02 16:45:17 +00:00
```event PayoutIncreased(uint _bountyId, uint _newFulfillmentAmount);```
This is emitted when the issuer of a bounty increases the payout amount