Overview
Augur is a decentralized prediction market platform that runs on Ethereum.
The stable Augur application is built and hosted at augur.net. If you want to use or help test Augur, you do not need to download or install anything! Just go to augur.net and start using it. (If you want to use our cutting-edge development client, this is maintained at augur-dev.firebaseapp.com – warning, we push changes to augur-dev pretty rapidly, so it can be a bit buggy!)
If you want to help develop Augur, you will need to build the client from source. To do this, first install Node.js, then execute the following commands to build the client:
$ git clone https://github.com/AugurProject/augur.git
$ cd augur
$ npm install
$ npm run build
(If you’re going to be developing and want the build to update automatically when you make changes, use npm run watch instead of npm run build!) Next, start the static web server:
$ npm start
Finally, go to http://localhost:8080 in your web browser. You should be greeted by Augur’s markets interface. Congratulations, you’re ready to start hacking!
Architecture
Local node
If you are running a local Ethereum node, sending RPC requests to your local node is the best (fastest) way to use Augur. To do this, you can either download and run the Augur app locally, or simply visit http://local.augur.net, which is configured to automatically talk to your local node, if present.
Because geth’s RPC server uses regular (unencrypted) HTTP, in order for the Augur app to communicate with your local geth node, it must be served over HTTP. The static file served when you visit augur.net is presently hosted on Firebase, which is HTTPS-only, and therefore you can’t interact with your local geth node from this URL! As a short-term workaround (until we set up on a more flexible CDN), we set up local.augur.net on one of our Linode servers. It’s configured for both HTTP and HTTPS, so it will work with your local node.
Hosted node
Understandably, many users will not want to go to the trouble of running a full Ethereum node solely for the purpose of using Augur. Augur maintains a public Ethereum node at https://eth3.augur.net, which is used automatically by augur.net (and by local.augur.net if a local Ethereum node is not detected). Augur’s node is on the Morden testnet.
API
// After installing, just require augur.js to use it.
var augur = require("augur.js");
// Attempt to connect to a local Ethereum node
augur.connect({http: "http://127.0.0.1:8545"});
// Connect to Augur's public node with websocket support
augur.connect({http: "https://eth3.augur.net", ws: "wss://ws.augur.net"});
// Connect to a local Ethereum node with websocket and IPC support
augur.connect({
http: "http://127.0.0.1:8545",
ws: "ws://127.0.0.1:8546",
ipc: process.env.HOME + "/.ethereum/geth.ipc"
});
The Augur API is a set of JavaScript bindings for the methods encoded in Augur’s smart contracts. The API method name, as well as its parameters, are generally identical to those of the underlying smart contract method.
Augur’s core contracts exist on Ethereum’s decentralized network. The various serialization, networking, and formatting tasks required to communicate with the Augur contracts from a web application are carried out by Augur’s sprawling middleware.
augur.js includes the Augur JavaScript API, and is the user-facing component of the middleware. If you want to interact with the Augur contracts from a custom application, augur.js is the recommended way to do so. The easiest way to install augur.js is using npm:
$ npm install augur.js
To use the Augur API, augur.js can connect to an Ethereum node, which can be either remote (hosted) or local. To specify the connection endpoint, pass your RPC/IPC connection info to augur.connect.
Market making
var marketID = "0x34e104a15ab3eb2a0c26f1138c278416424ef7f8425799a76127e9b427fac74d";
var params = {
market: marketID,
liquidity: 9012,
startingQuantity: 501,
bestStartingQuantity: 500,
priceWidth: "0.08697536855694898",
initialFairPrices: [ "0.661837082683109", "0.5132635487227519" ]
};
augur.generateOrderBook(params, {
onBuyCompleteSets: function (res) { /* ... */ },
onSetupOutcome: function (outcome) { /* ... */ },
onSetupOrder: function (order) { /* ... */ },
onSuccess: function (orderBook) { /* ... */ },
onFailed: function (err) { /* ... */ }
});
params.isSimulation = true;
augur.generateOrderBook(params, {
onSimulate: function (simulation) { /* ... */ }
})
// example:
simulation = {
shares: "4007",
numBuyOrders: [ 10, 7 ],
numSellOrders: [ 4, 7 ],
buyPrices:
[ [ "0.61834939840463451",
"0.55853753243153362626",
"0.49872566645843274252",
"0.43891380048533185878",
"0.37910193451223097504",
"0.3192900685391300913",
"0.25947820256602920756",
"0.19966633659292832382",
"0.13985447061982744008",
"0.08004260464672655634" ],
[ "0.46977586444427741",
"0.40996399847117652626",
"0.35015213249807564252",
"0.29034026652497475878",
"0.23052840055187387504",
"0.1707165345787729913",
"0.11090466860567210756" ] ],
sellPrices:
[ [ "0.70532476696158349",
"0.76513663293468437374",
"0.82494849890778525748",
"0.88476036488088614122" ],
[ "0.55675123300122639",
"0.61656309897432727374",
"0.67637496494742815748",
"0.73618683092052904122",
"0.79599869689362992496",
"0.8558105628667308087",
"0.91562242883983169244" ] ],
numTransactions: 34,
priceDepth: "0.05981186597310088374"
}
augur.generateOrderBook is a convenience method for generating an initial order book for a newly created market. generateOrderBook calculates the number of orders to create, as well as the spacing between orders, using the augur.calculatePriceDepth method.
generateOrderBook(params, callbacks)
params is an object containing the input parameters (see example code). liquidity is the total amount of liquidity to add to the market. initialFairPrice is the center of the bid-ask spread. startingQuantity is the number of shares available at each price point. bestStartingQuantity can optionally be specified separately, and is the number of shares available at the best price point (those closest to the spread). priceWidth is the price difference between the best bid and best ask orders.
augur.calculatePriceDepth accepts arguments liquidity, startingQuantity, bestStartingQuantity, halfPriceWidth, minValue, and maxValue. All arguments to calculatePriceDepth are expected to be in BigNumber format. The order book generated by generateOrderBook is “flat”, in the sense that there is the same size order created at each price point (except for the best bid/offer). A typical generated order book (for a single outcome) might look like:
This calculation is done as follows. Let \(p_\mathrm{max}\) and \(p_\mathrm{min}\) be the maximum and minimum allowed prices, \(I\) be the initial fair price for the outcome under consideration, \(q\) be the starting quantity (size of each order), \(q_0\) be the size of the best order, and \(w\) be the price width (the size of the bid-ask spread). The liquidity available on the buy and sell order books is given by:
$$ L_{\mathrm{buy}} = q_0 + \frac{q}{\delta} \left( p_\mathrm{min} + I - \frac{w}{2} \right) $$
$$ L_{\mathrm{sell}} = q_0 + \frac{q}{\delta} \left( p_\mathrm{max} - I - \frac{w}{2} \right) $$
where \(\delta\) is the “price depth”, the distance between orders on the same side of the book. The total liquidity \(L = L_{\mathrm{buy}} + L_{\mathrm{sell}}\) is an input parameter, so the only unknown is the price depth \(\delta\), which can now be calculated:
$$ \delta = \frac{\left( p_\mathrm{min} + p_\mathrm{max} - w \right) q}{L - 2q_0} $$
The initial order book is now fully specified.
augur.generateOrderBook also accepts an optional parameter, isSimulation, which if set to true, returns information about what the method will do (see code example). shares is the number of complete sets of shares to purchased, numBuyOrders is the number of buy orders that will be created, numSellOrders is the number of sell orders that will be created, and numTransactions is the total number of Ethereum transactions needed to set up the order book.
Trading
Traders submit bids and asks. Orders are executed if another trader will match/offer better terms. Orders executed first come first served. UI offers users the best prices first, in case another trader has already picked up those orders by broadcasting their transaction first (UI can also check this in the transaction pool). The UI includes multiple backup/fallback orders in their transactions that the user would still be willing to trade (provided they’re within her limit parameters). Orders are never executed at worse prices than their limit prices (but can be better). Orders can be partially filled.
How to trade
- To go long, buy on exchange via bid or buy a complete set of all outcomes and sell everything else
- To go short buy a whole set and sell the one you don’t like (or call the
short_sellfunction) - Spreads still stay tight due to super easy arbitrage from buy/sell complete sets
- To sell shares held buy the other outcomes and turn in a complete set or sell directly via asks. Whichever is cheaper should be done first.
When someone enters an order in the UI the following happens:
- Find all orders on the book that can fill that order, so price is <= if buying and >= if selling
- Call
trade(max_value, max_amount, trade_ids:arr)which will return the amount of money that still isn’t filled at the end of trading - If it returns 0 for the max value and amounts the UI is done
- If it returns a positive number, place a buy or sell order on the book for the amount it returns using
buy(amount, price, market_id, outcome)orsell(amount, price, market_id, outcome) - This will then
log(type=log_add_tx, $market_id, msg.sender, $type, $price, $amount, $outcome, trade_id)where type is eitherBIDorASK, rest is self explanatory - The UI calls
get_trade_ids(market_id)to get a list of all open orders on the book - Then to populate the order books for each outcome in the UI:
get_trade(id) - If
> maxor< mindon’t show order
Pending transactions and what orders have already been picked up in pending broadcasted transactions are shown in the book. These orders are removed if the other side has already been taken in the transaction pool (those orders get executed first on Ethereum anyway based on time precedence and default gas price). If not processed / taken up, those orders are placed back on the book. If two orders at same price are placed on the book, the one placed first is executed first.
Initial market loading
# Each market's ID is a hash of the following information:
marketinfo = string(8*32 + len(description))
marketinfo[0] = tradingPeriod
marketinfo[1] = tradingFee
marketinfo[2] = block.timestamp # market creation timestamp
marketinfo[3] = tag1
marketinfo[4] = tag2
marketinfo[5] = tag3
marketinfo[6] = expirationDate
marketinfo[7] = len(description)
mcopy(marketinfo + 8*32, description, chars=len(description))
marketID = sha3(marketinfo, chars=len(marketinfo))
# Then for the next market, do sha3 of its marketID plus the previous:
# (marketID2 is the same calculation as above, for the second market)
compositeMarketsHash = sha3(marketID + marketID2)
# Then continue this process until you've included all markets in the
# composite hash; for example, if there were 4 total markets:
compositeMarketsHash = sha3(compositeMarketsHash + marketID3)
compositeMarketsHash = sha3(compositeMarketsHash + marketID4)
To load the basic market info for all markets, first call augur.getMarketsInfo({branch, offset, numMarketsToLoad, callback}). You will likely need to chunk the results so that the request does not time out. More detailed market info (including prices) for each market in each chunk (page) is then loaded using augur.getMarketInfo(marketID). getMarketInfo does not return the full order book; to get the order book for a market, call augur.getOrderBook(marketID).
Reporting outcomes
Yes or no (binary)
- no:
2**64 - yes:
2*2**64 - indeterminate:
3*2**63 - exactly in the middle but not indeterminate:
2**63 + 1
Multiple choice (categorical)
- min:
1 - max:
2**64 - indeterminate:
2**63 - exactly in the middle but not indeterminate:
2**63 + 1
Numerical (scalar)
- min:
1 - max:
2**64 - indeterminate:
2**63 - exactly in the middle but not indeterminate:
2**63 + 1
Simplified API
var branchId = 1010101;
var marketId = "0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519";
augur.getOrderBook(marketId, function (orderBook) { /* ... */ });
// example output:
{ sell:
[ { id: '-0xc764b37f2eebb389040025b33668470bf017ce00e3d7c3725d2c33da04cc0bc5',
type: 'sell',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '0.25',
price: '0.51999999999999999998',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8457,
outcome: '1' },
{ id: '-0x66f53e64d4547120bd1962168f4acedc58d93efb63e62ad675ef55d19743e66c',
type: 'sell',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '1',
price: '0.5',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8452,
outcome: '1' },
{ id: '-0x6d354a545d040ee85ef3b59f96cf20227f7f9385c510c87a5b43970043e36ed5',
type: 'sell',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '0.25',
price: '0.51999999999999999998',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8379,
outcome: '1' },
{ id: '-0x7f79fc1e36e703f9a0f7b8776d9a1899d6e9ce121f68b3bce7161b9f394b942e',
type: 'sell',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '1',
price: '0.5',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8375,
outcome: '1' } ],
buy:
[ { id: '-0x753a368b0cd164302041448c61c57a868dccf8fceb538fb2e0a60356f793d720',
type: 'buy',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '0.25',
price: '0.51999999999999999998',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8448,
outcome: '1' },
{ id: '-0x9bae4959ded1d5426da64870b39a1465a39491d47e5071c6e4889d739c994c0d',
type: 'buy',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '1',
price: '0.5',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8446,
outcome: '1' },
{ id: '-0xadd0854ba0ebba7ac915929988cb01e7b2ca8b6cca9cf9f88b235d654ce6666c',
type: 'buy',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '0.25',
price: '0.51999999999999999998',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8391,
outcome: '1' },
{ id: '-0x1116dd2bd3aa1db9d14591c42f8eaac9a6a57ea2aad5654c5ada3245f7a52a7b',
type: 'buy',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '1',
price: '0.5',
owner: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
block: 8389,
outcome: '1' } ] }
augur.getMarketInfo(marketId, function (marketInfo) { /* ... */ })
// example output:
{ network: '2',
traderCount: 2,
traderIndex: 5e-20,
numOutcomes: 2,
tradingPeriod: 107304960000,
makerFee: '0.01246155619866478799995356402249700352',
takerFee: '0.07910419330000878000004643597750299648',
tradingFee: '0.061043832999115712',
branchId: '0xf69b5',
numEvents: 1,
cumulativeScale: '14999',
creationTime: 1463784466,
volume: '1.25',
creationFee: '5.14285714285714266327',
author: '0x7c0d52faab596c08f484e3478aebc6205f3f5d8c',
tags: [ 'spaceflight', 'LEO', 'economics' ],
type: 'scalar',
endDate: 1609574400000,
winningOutcomes: [ '0', '0', '0', '0', '0', '0', '0', '0' ],
description: 'How much will it cost (in USD) to move a pound of inert cargo from Earth\'s surface to Low Earth Orbit by January 1, 2021?',
outcomes:
[ { shares: {},
id: 1,
outstandingShares: '0.5',
price: '0.51999999999999999998' },
{ shares: {}, id: 2, outstandingShares: '0.5', price: '0' } ],
events:
[ { id: '-0x9d869b3088e7c963e21d295bec13b57342aa70510252fa97388ded77df03d483',
endDate: 1609574400000,
outcome: '0',
minValue: '1',
maxValue: '15000',
numOutcomes: 2,
type: 'scalar' } ],
_id: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519' }
All of the methods in the Simplified API are getter methods that use an eth_call RPC request; for transactional requests (eth_sendTransaction), see the Full API section below. This API is simplified in the sense that single requests to this API can be used to fetch a large amount of data, without the need for complicated RPC batch queries.
getOrderBook(marketId[, callback])
Retrieves the full order book for marketId. The order book’s format is an object with fields buy and sell containing arrays of buy and sell orders. The structure of the orders is shown in the example code.
getMarketInfo(marketId[, callback])
Reads all information about a market that is stored on-contract. It also determines the type of the market, which can be binary (two outcomes; i.e., Yes or No), categorical (more than two outcomes, i.e., Multiple Choice), scalar (answer can be any of a range of values; i.e., Numerical), or combinatorial (for combined wagers on multiple events). If the market is a combinatorial market, getMarketInfo also makes separate RPC request for the individual event descriptions.
var marketIDs = [
'0xf41e2f1827142a95cc14b5333f3d3493588342ef8bc9214e96e0c894dff27fc5',
'0x9b8e45cdf9d35ab66b939d5eb5b48bf10de3c39b7f6fa2d38fe518a869502e8'
];
augur.batchGetMarketInfo(marketIDs, function (info) { /* ... */ });
// example output:
info = {
"0xf41e2f1827142a95cc14b5333f3d3493588342ef8bc9214e96e0c894dff27fc5": {
"network": "2",
"traderCount": 0,
"makerFee": "0.01246155619866478799995356402249700352",
"takerFee": "0.07910419330000878000004643597750299648",
"tradingFee": "0.061043832999115712",
"traderIndex": 0,
"numOutcomes": 3,
"tradingPeriod": 206104,
"branchId": "0xf69b5",
"numEvents": 1,
"cumulativeScale": "1",
"creationTime": 1464642365,
"volume": "0",
"creationFee": "8.99999999999999967469",
"author": "0x7c0d52faab596c08f484e3478aebc6205f3f5d8c",
"tags": ["weather", "temperature", "climate change"],
"type": "categorical",
"endDate": 1483948800,
"winningOutcomes": ["0", "0", "0", "0", "0", "0", "0", "0"],
"description": "Will the average temperature on Earth in 2016 be Higher, Lower, or Unchanged from the average temperature on Earth in 2015? Choices: Higher, Lower, Unchanged",
"outcomes": [
{
"shares": {},
"id": 1,
"outstandingShares": "0",
"price": "0"
},
{
"shares": {},
"id": 2,
"outstandingShares": "0",
"price": "0"
},
{
"shares": {},
"id": 3,
"outstandingShares": "0",
"price": "0"
}
],
"events": [
{
"id": "0x808bd49d2a16214bed80a6249302b55a87282a7d6ecc74a0381b7453b1ed9101",
"endDate": 1483948800,
"outcome": "0",
"minValue": "1",
"maxValue": "2",
"numOutcomes": 3,
"type": "categorical"
}
],
"_id": "0xf41e2f1827142a95cc14b5333f3d3493588342ef8bc9214e96e0c894dff27fc5",
"sortOrder": 0
},
"0x9b8e45cdf9d35ab66b939d5eb5b48bf10de3c39b7f6fa2d38fe518a869502e8": {
"network": "2",
"traderCount": 0,
"makerFee": "0.01246155619866478799995356402249700352",
"takerFee": "0.07910419330000878000004643597750299648",
"tradingFee": "0.061043832999115712",
"traderIndex": 0,
"numOutcomes": 3,
"tradingPeriod": 206104,
"branchId": "0xf69b5",
"numEvents": 1,
"cumulativeScale": "1",
"creationTime": 1464642450,
"volume": "0",
"creationFee": "8.99999999999999967469",
"author": "0x7c0d52faab596c08f484e3478aebc6205f3f5d8c",
"tags": ["quotes", "严肃", "蝙蝠侠"],
"type": "categorical",
"endDate": 1483948800,
"winningOutcomes": ["0", "0", "0", "0", "0", "0", "0", "0"],
"description": "为什么有这么严重吗?",
"outcomes": [
{
"shares": {},
"id": 1,
"outstandingShares": "0",
"price": "0"
},
{
"shares": {},
"id": 2,
"outstandingShares": "0",
"price": "0"
},
{
"shares": {},
"id": 3,
"outstandingShares": "0",
"price": "0"
}
],
"events": [
{
"id": "0xe2b0453641b305c4aa96b3bd473d93b0b5062a7c0fc62d6e158c133859fcdcb3",
"endDate": 1483948800,
"outcome": "0",
"minValue": "1",
"maxValue": "2",
"numOutcomes": 3,
"type": "categorical"
}
],
"_id": "0x9b8e45cdf9d35ab66b939d5eb5b48bf10de3c39b7f6fa2d38fe518a869502e8",
"sortOrder": 1
}
}
var options = {
branch: 1010101, // branch ID (default: 1010101)
offset: 10, // which markets to start (default: 0)
numMarketsToLoad: 2 // numMarkets
};
augur.getMarketsInfo(options, function (marketsInfo) { /* ... */ })
// example output:
{ '0xf41e2f1827142a95cc14b5333f3d3493588342ef8bc9214e96e0c894dff27fc5':
{ _id: '0xf41e2f1827142a95cc14b5333f3d3493588342ef8bc9214e96e0c894dff27fc5',
sortOrder: 0,
tradingPeriod: 206104,
tradingFee: '0.01999999999999999998',
creationTime: 1464642365,
volume: '0',
tags: [ 'weather', 'temperature', 'climate change' ],
endDate: 1483948800,
description: 'Will the average temperature on Earth in 2016 be Higher, Lower, or Unchanged from the average temperature on Earth in 2015? Choices: Higher, Lower, Unchanged' },
'0x9b8e45cdf9d35ab66b939d5eb5b48bf10de3c39b7f6fa2d38fe518a869502e8':
{ _id: '0x9b8e45cdf9d35ab66b939d5eb5b48bf10de3c39b7f6fa2d38fe518a869502e8',
sortOrder: 1,
tradingPeriod: 206104,
tradingFee: '0.01999999999999999998',
creationTime: 1464642450,
volume: '0',
tags: [ 'quotes', '严肃', '蝙蝠侠' ],
endDate: 1483948800,
description: '为什么有这么严重吗?' } }
batchGetMarketInfo(marketIDs[, callback])
Retrieve a marketInfo object for the market IDs in array marketIDs. The marketInfo objects (see above for example) are collected into a single object and indexed by market ID.
getMarketsInfo(options[, callback])
Gets basic info about markets the specified branch, and returns an object with market info indexed by market ID. The options parameter is an object which specifies the branch ID (branch). There are also two fields (offset and numMarketsToLoad) used to split up the getMarketsInfo query into multiple requests. This is useful if the number of markets on the branch is too large for a single RPC request (which is typical).
Call API
Augur’s Call API is made up of “getter” methods that retrieve information from the blockchain (using Ethereum’s eth_call RPC) but do not write information to the blockchain.
// cash contract
var address = "0x639b41c4d3d399894f2a57894278e1653e7cd24c";
augur.getCashBalance(address, function (cashBalance) { /* ... */ });
// example output:
cashBalance = "93016.83621687256922549981"
cash contract
getCashBalance(address[, callback])
Gets the play money (CASH) balance of the user account address.
// info contract
var marketId = "0x9368ff3e9ce1c0459b309fac6dd4e69229b91a42d736197278acab402980fd4";
augur.getCreator(marketId, function (creator) { /* ... */ });
// example output:
creator = "0x639b41c4d3d399894f2a57894278e1653e7cd24c"
augur.getCreationFee(marketId, function (creationFee) { /* ... */ });
// example output:
creationFee = "16"
augur.getDescription(marketId, function (description) { /* ... */ });
// example output:
description = "Will the Sun turn into a red giant and engulf the Earth by the end of 2016?"
info contract
getCreator(id[, callback])
Gets the address of the account that created id (a market or event ID).
getCreationFee(id[, callback])
Gets the fee paid by the creator of id (a market or event ID).
getDescription(item[, callback])
Gets the plaintext (UTF-8) description of item (a market or event ID).
// branches contract
var branchId = augur.branches.dev;
augur.getNumBranches(function (numBranches) { /* ... */ });
// example output:
augur.getBranches(function (branches) { /* ... */ });
// example output:
branches = ["0xf69b5"]
augur.getMarkets(branchId, function (markets) { /* ... */ })
// example output:
markets = ["-0x519bcdaa60e7259143402153efb9825fc37a5c3d8eee0445b987453d2a23919c",
"-0xacfe5fbc7654fee0b8873e2db464f5c189a1fa9e6e0ea5f5fa44bf6a08832f7a",
"-0xb73f41b31a160852d059c870d1c4d205da9b72db6c53588d4426ffe261ccc745",
"-0x40189b8366a578e807f1381088de10bb4660505ff37d9cfa4be8d2a4eb39c74a",
"-0x5a2d3e163636f0f35ff25bfe9a87d62185228c970acaae71eb1a469132631406",
"-0xd7850ae02e616824cfaa2dfbe6129303752e31a7fdbd559f6c4466ec1594f7c6",
"-0xb52debd79c5baaeec50ef7fa85e9f7b7fca6ddecba38810b070aa4bb8ef06952",
"-0x5680dadb064bd5942e827dc70b389d2d24a63bd186279c0bea6e2ab46444c4a",
"-0x98e1eb72b4c1a5973ab2a443ad2ca0b7a90107c2dc2594c33daea307ec39aa1c",
"0x9368ff3e9ce1c0459b309fac6dd4e69229b91a42d736197278acab402980fd4",
"-0x679b4b3112994a7c034ae7f6fb4b5e7bcb4a6923e969c24696ee823fbe4e5524"]
augur.getPeriodLength(branchId, function (periodLength) { /* ... */ })
// example output:
periodLength = "1800"
augur.getVotePeriod(branchId, function (reportPeriod) { /* ... */ })
// example output:
reportPeriod = "397"
augur.getNumMarkets(branchId, function (numMarkets) { /* ... */ })
// example output:
numMarkets = "45"
augur.getMinTradingFee(branchId, function (minTradingFee) { /* ... */ })
// example output:
minTradingFee = "0.0078125"
augur.getBranchByNum(0, function (branch) { /* ... */ })
// example output:
branch = "0xf69b5"
branches contract
augur.getNumBranches([callback])
Looks up the total number of branches that exist on the current network.
augur.getBranches([callback])
Gets an array of all branch IDs on the current network.
augur.getMarkets(branch[, callback])
Gets an array of all markets on the specified branch ID branch.
augur.getPeriodLength(branch[, callback])
Gets the period length for the specified branch ID branch.
augur.getVotePeriod(branch[, callback])
Looks up the number of the current vote period on the specified branch ID branch.
augur.getNumMarkets(branch[, callback])
Gets the number of markets on the specified branch ID branch.
augur.getMinTradingFee(branch[, callback])
Gets the minimum trading fee allowed on the specified branch ID branch.
augur.getBranchByNum(branchNumber[, callback])
Gets branch ID for the branch with index branchNumber. (Branches are stored as an “array” on-contract; branchNumber is the index of the branch within this array.)
// events contract
var eventId = "-0x5fa67764c533d97e33ef2cbdc37cd11eb5f187b47c89c88d3d81250ba834cb3";
augur.getEventInfo(eventId, function (eventInfo) { /* ... */ });
// example output:
eventInfo = ["0xf69b5", "13801186", "0", "1", "2", "2"]
augur.getEventBranch(eventId, function (eventBranch) { /* ... */ });
// example output:
eventBranch = "0xf69b5"
augur.getExpiration(eventId, function (expiration) { /* ... */ });
// example output:
expiration = "13801186"
augur.getOutcome(eventId, function (outcome) { /* ... */ });
// example output:
outcome = "0"
augur.getMinValue(eventId, function (minValue) { /* ... */ });
// example output:
minValue = "1"
augur.getMaxValue(eventId, function (maxValue) { /* ... */ });
// example output:
maxValue = "2"
augur.getNumOutcomes(eventId, function (numOutcomes) { /* ... */ });
// example output:
numOutcomes = "2"
events contract
getEventInfo(eventId[, callback])
Fetches an array of basic information about event eventId: branch ID, expiration block number, outcome ("0" if not yet resolved), minimum value, maximum value, and number of outcomes.
getEventBranch(eventId[, callback])
Gets the branch ID of event eventId.
getExpiration(eventId[, callback])
Gets the expiration block number of event eventId.
getOutcome(eventId[, callback])
Gets the outcome ("0" if the event is not yet resolved) of event eventId.
getMinValue(eventId[, callback])
The minimum possible value for event eventId. For binary (yes/no) events, the minimum value is 1.
getMaxValue(eventId[, callback])
The minimum possible value for event eventId. For binary (yes/no) events, the maximum value is 2.
getNumOutcomes(eventId[, callback])
The total number of outcomes for this event. Binary (yes/no) and scalar (numerical) events always have 2 outcomes; categorical events have more than 2 outcomes.
// expiringEvents contract
var branchId = augur.branches.dev;
var reportPeriod = 397;
augur.getEvents(branchId, reportPeriod, function (events) { /* ... */ });
// example output:
events = ["-0xc6481ca18bec443c7831578e5f2de02594041041e0abbf0e8ecafd70197fd1a5",
"-0xea03728786ca7ddcb91ec3303723ac794b7bcbcb9b3ad48943e797885c6d05ab",
"-0xdb633b6cdbfbd00c85ca1f093764dcb2b2f0b5284c2324baa6008a3d73e0a1c",
"-0xd0dbd235c8de8cccd7d8ef96b460c7dc2d19539fb45778f7897c412d4c0a3683",
"-0x16fe3cb92062b9f43ef9988eb871f346960ff23b5c16222c1ebe5a5e2fc908c6",
"-0x72162079f64916bccf580430cc1788d9b0873fd1e7de633d118c2d1e931eb47b",
"-0x80da06cc9b94b559880aab761a40c88f1cc9c9eae7124301eaa246688ed8eee6",
"-0x8e33043e75d6b8bc9ba5b60edaa159e25f0c84172730026d7c875e35377da13c",
"-0x2e78a12ce25c171d32d649498babc011152b6509d5880568d77009826c6660e3",
"-0xd5cbab9a85c1dd2ae692b87f98faa1e4841933d604d78622bb6dbe03d8acde36",
"-0x7a2c24bec3f16f5edfa06ed6941569f9de70cbe33c768b02617ed89b16be8d8f",
"-0x399c15976085e8dcf8cb57317c1001013ce8ee5472868b1faa8657edcd1336bd" ]
augur.getNumberEvents(branchId, reportPeriod, function (numberEvents) { /* ... */ });
// example output:
numberEvents = "12"
var eventIndex = 3;
augur.getEvent(branchId, reportPeriod, eventIndex, function (event) { /* ... */ });
// example output:
event = "-0xd0dbd235c8de8cccd7d8ef96b460c7dc2d19539fb45778f7897c412d4c0a3683"
augur.getTotalRepReported(branchId, reportPeriod, function (totalRepReported) { /* ... */ });
// example output:
totalRepReported = "76"
augur.getReporterBallot(branchId, reportPeriod, reporterID, function (reporterBallot) { /* ... */ });
// example output:
reporterBallot = ["1", "2", "1", "1.5", "1", "1.5", "2", "1", "1", "1.5", "1", "1"]
var reportNum = "0";
augur.getReport(branchId, reportPeriod, reporter, reportNum, function (report) { /* ... */ });
// example output:
report = "1"
augur.getReportHash(branchId, reportPeriod, reporter, function (reportHash) { /* ... */ });
// example output:
reportHash = "-0x4480ed40f94e2cb2ca244eb862df2d350300904a96039eb53cba0e34b8ace90a"
augur.getTotalReputation(branchId, reportPeriod, function (totalReputation) { /* ... */ });
// example output:
totalReputation = "282"
expiringEvents contract
getEvents(branch, reportPeriod[, callback])
Fetches an array of event IDs that are scheduled to be reported on during reportPeriod.
getNumberEvents(branch, reportPeriod[, callback])
The total number of events scheduled to be reported on during reportPeriod.
getEvent(branch, reportPeriod, eventIndex[, callback])
Looks up the event ID that has index eventIndex.
getTotalRepReported(branch, reportPeriod[, callback])
Gets the total amount of Reputation reporting during reportPeriod.
getReporterBallot(branch, reportPeriod, reporterID[, callback])
Fetches the ballot submitted for reportPeriod by address reporterID.
getReport(branch, reportPeriod, reporter, reportNum[, callback])
The report for reporting event number reportNum submitted for reportPeriod by address reporter.
getReportHash(branch, reportPeriod, reporter[, callback])
The report hash submitted for reportPeriod by address reporter.
getTotalReputation(branch, reportPeriod[, callback])
Gets the total amount of Reputation issued on branch branch by reportPeriod. (In the live release Reputation is neither created nor destroyed, so this will be a constant value of 11000000.)
// trades contract
var trade_id = "-0x22daf7fdff22ff716fd8108c011d1c0e69a7ab4a2b087f65dda2fc77ea044ba1";
augur.get_trade(trade_id, function (trade) { /* ... */ });
// example output:
trade = {
id: '-0x22daf7fdff22ff716fd8108c011d1c0e69a7ab4a2b087f65dda2fc77ea044ba1',
type: 'sell',
market: '0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519',
amount: '1',
price: '0.5',
owner: '0x15f6400a88fb320822b689607d425272bea2175f',
block: 920945,
outcome: '1'
}
trades contract
get_trade(trade_id[, callback])
Gets the details of trade trade_id. (To get the trade_ids for a given market, call augur.get_trade_ids(market).)
// markets contract
var marketId = "0x45c545745a80121b14c879bf9542dd838559f7acc90f1e1774f4268c332a519";
augur.get_trade_ids(marketId, function(trade_ids) { /* ... */ });
// example output:
trade_ids = [
'-0xd2cbbef4aa237c97c7c412885b283a0fa517cc7a58f37e981f0cc2e01338bbbf',
'-0xec12b8e92e92b83534ba5948c0ea22752f6975e5eef96b46e4f6d558314347a7',
'-0xef272ceaabdc90b0c99248caaf34198e2d88d973e30a485118ab30598a95097e',
'-0x22daf7fdff22ff716fd8108c011d1c0e69a7ab4a2b087f65dda2fc77ea044ba1'
]
var outcomeId = 5; // 8-outcome categorical market
var amount = 4;
augur.getMarketEvents(marketId, function (marketEvents) { /* ... */ });
// example output:
marketEvents = ["-0xa65427afe1fc912e973d8dac2a83487aea5f5707a74c3168afb56e5a95b760ea"]
augur.getNumEvents(marketId, function (numEvents) { /* ... */ });
// example output:
numEvents = "1"
augur.getBranchID(marketId, function (branchID) { /* ... */ });
// example output:
branchID = "0xf69b5"
augur.getCurrentParticipantNumber(marketId, function (currentParticipantNumber) { /* ... */ });
// example output:
currentParticipantNumber = "1"
augur.getMarketNumOutcomes(marketId, function (marketNumOutcomes) { /* ... */ });
// example output:
marketNumOutcomes = "9"
var participantNumber = "0";
augur.getParticipantSharesPurchased(marketId, participantNumber, outcomeId, function (participantSharesPurchased) { /* ... */ });
// example output:
participantSharesPurchased = "4"
augur.getSharesPurchased(marketId, outcomeId, function (sharesPurchased) { /* ... */ });
// example output:
sharesPurchased = "32.24854252438022522758"
augur.getWinningOutcomes(marketId, function (winningOutcomes) { /* ... */ });
// example output:
winningOutcomes = ["0", "0", "0", "0", "0", "0", "0", "0", "0"]
var address = "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b";
augur.getParticipantNumber(marketId, address, function (participantNumber) { /* ... */ });
// example output:
participantNumber = "0"
augur.getParticipantID(marketId, participantNumber, function (participantID) { /* ... */ });
// example output:
participantID = "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b"
augur.getCumScale(marketId, function (cumScale) { /* ... */ });
// example output:
cumScale = "0.00000000000000000005"
augur.getTradingPeriod(marketId, function (tradingPeriod) { /* ... */ });
// example output:
tradingPeriod = "1075"
augur.getTradingFee(marketId, function (tradingFee) { /* ... */ });
// example output:
tradingFee = "0.00999999999999999999"
markets contract
get_trade_ids(market[, callback])
Gets an array of trade IDs. Each trade ID represents a buy or sell order that is sitting on market’s order book (i.e., has not yet been matched). To get detailed information about the trade, call augur.get_trade(trade_id).
getMarketEvents(market[, callback])
Gets an array of event IDs included in market. (Note: only combinatorial markets have more than one event.)
getNumEvents(market[, callback])
Get the number of events included in market. (Note: only combinatorial markets have more than one event.)
getBranchID(market[, callback])
Gets the branch ID of market.
getCurrentParticipantNumber(market[, callback])
Gets the current number of participants (traders) in market, starting from 0. (i.e., if there is a single trader, then he is assigned participant number 0, and the “current participant number” is 1.)
getMarketNumOutcomes(market[, callback])
Gets the total number of outcomes for market. For binary and scalar markets, this is 2. For categorical markets, this is equal to the number of categories (choices). For combinatorial markets, this is the number of possible outcome combinations.
getParticipantSharesPurchased(market, participantNumber, outcome[, callback])
The number of shares of outcome in market purchased by trader number participantNumber. (Note: you can look up participantNumber using augur.getParticipantNumber.)
getSharesPurchased(market, outcome[, callback])
The total number of shares purchased (by all traders) of outcome in market.
getWinningOutcomes(market[, callback])
Gets an array of outcomes showing the winning/correct outcome, or an array of all zeros if market has not yet been resolved.
getParticipantNumber(market, address[, callback])
Looks up the participant number for account address.
getParticipantID(market, participantNumber[, callback])
Looks up the account address for participantNumber.
getCumScale(market[, callback])
Gets the cumulative scale for market.
getTradingPeriod(market[, callback])
Gets the trading period for market.
getTradingFee(market[, callback])
Gets the trading fee for market, expressed as a proportion.
// reporting contract
var branchId = augur.branches.dev;
var address = "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b"
augur.getRepBalance(branchId, address, function (repBalance) { /* ... */ });
// example output:
repBalance = "47"
var repIndex = 0;
augur.getRepByIndex(branchId, repIndex, function (rep) { /* ... */ });
// example output:
rep = "47"
augur.getReporterID(branchId, repIndex, function (reporterID) { /* ... */ });
// example output:
reporterID = "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b"
augur.getNumberReporters(branchId, function (numberReporters) { /* ... */ });
// example output:
numberReporters = "38"
augur.repIDToIndex(branchId, address, function (repIndex) { /* ... */ });
// example output:
repIndex = "0"
augur.getTotalRep(branchId, function (totalRep) { /* ... */ });
// example output:
totalRep = "1796"
var ballot = ["1", "2", "1", "1.5", "1", "1.5", "2", "1", "1", "1.5", "1", "1"];
var salt = "0xbd352b6e2858ba27d8b7639afd2e34954803338e0e54cae7dcdf93f97f315225";
hashReport(ballot, salt, function (reportHash) { /* ... */ });
// example output:
reportHash = "-0x4480ed40f94e2cb2ca244eb862df2d350300904a96039eb53cba0e34b8ace90a"
reporting contract
getRepBalance(branch, address[, callback])
The Reputation balance on branch of account address.
getRepByIndex(branch, repIndex[, callback])
The Reputation balance on branch of reporter number repIndex.
getReporterID(branch, index[, callback])
Looks up a reporter’s ID (address) by reporter number index.
getNumberReporters(branch[, callback])
The total number of reporters on branch.
repIDToIndex(branch, repID[, callback])
Looks up a reporter’s number (index) by address repID.
getTotalRep(branch[, callback])
The total amount of Reputation on branch.
// makeReports contract
var branchId = augur.branches.dev;
var report = ["1", "2", "1", "1.5", "1", "1.5", "2", "1", "1", "1.5", "1", "1"];
var reportPeriod = 397;
augur.checkReportValidity(branchId, report, reportPeriod, function (isValid) { /* ... */ });
// example output:
isValid = "1"
makeReports contract
checkReportValidity(branch, report, reportPeriod[, callback])
Validates report made on branch for reportPeriod. A valid report is the correct length, is made before 2 reporting periods have elapsed, and is created by a valid reporting address. Returns 1 if valid, -1 if invalid because the report is the wrong length (i.e., doesn’t match the number of events being reported on), or -2 if invalid for another reason.
Transaction API
Augur’s Transaction API is made up of “setter” methods that can both read from and write to the blockchain using Ethereum’s eth_sendTransaction RPC. Under the hood, the API uses augur.js’s convenience wrapper for eth_sendTransaction, augur.transact.
Callbacks
All Transaction API methods accept three callback functions:
onSent(sentResponse)
Fires when the initial eth_sendTransaction response is received. If the transaction was broadcast to the network without problems, sentResponse will have two fields: txHash (the transaction hash as a hex string) and callReturn (the value returned by the invoked contract method). The optional returns field in the tx object sent to augur.transact can be used to specify the format of the callReturn value.
onSuccess(successResponse)
Fires when the transaction is successfully incorporated into a block and added to the blockchain, as indicated by a nonzero blockHash value. successResponse is structured the same way as eth_getTransactionByHash responses (see code example for details), with the addition of a callReturn field which contains the contract method’s return value.
onFailed(failedResponse)
Fires if the transaction is unsuccessful. failedResponse has error (error code) and message (error description) fields, describing the way in which the transaction failed.
No callbacks are required; if none are supplied, then the transaction hash (or error) will simply be returned. In this case, the transaction has been broadcast to the Ethereum network, but further confirmation of the transaction and/or lookups of its return value will need to be done manually. If an onSent but not an onSuccess callback is provided, the transaction will be broadcast, and onSent will be passed an sentResponse object containing txHash and callReturn fields, but augur.rpc will not poll the network repeatedly to check on the status of the transaction.
Arguments
All Transaction API methods accept either positional or object arguments. Examples are shown using object arguments (to make the field names clear). The arguments are displayed in order from left-to-right (top-to-bottom if multiple lines are needed). For positional arguments, onSent, onSuccess, and onFailed should always be the last three arguments, in that order.
// transaction object (generated by the buyShares method)
var tx = {
"to": "0x2e5a882aa53805f1a9da3cf18f73673bca98fa0f",
"method": "buyShares",
"signature": "iiiiii",
"from": "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b",
"params": [
"0xf69b5",
"-0x130158e01e01cc67d3d8803f88493b8aadc6654be759fbf2d40105506b41daa3",
1,
"0x199999999999999a",
"0",
0
],
"returns": "unfix",
"send": true
};
// onSent callback fires when the initial eth_sendTransaction response
// is received
var onSent = function (sentResponse) {
console.log("transaction sent:", sentResponse);
};
// onSuccess callback fires
var onSuccess = function (successResponse) {
console.log("transaction successful:", successResponse);
};
// onFailed callback fires when the transaction is malformed, fails to confirm,
// or an object with an error field is received
var onFailed = function (failedResponse) {
console.error("transaction failed:", failedResponse);
};
augur.transact(tx, onSent, onSuccess, onFailed);
// example outputs:
sentResponse = {
txHash: '0xdf096e249638df143118f562868e90285579819e59b09f0784b95fa5fd920413',
callReturn: '0.05959702938270431576'
}
successResponse = {
nonce: '0x4e1',
blockHash: '0xb8e4e78c9cf949729bbb7b94e942d8d63e67e9f48b394f3208cf0d2928e44bad',
blockNumber: '0x6a5f',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0x2e5a882aa53805f1a9da3cf18f73673bca98fa0f',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x7d9e764100000000000000000000000000000000000000000000000000000000000f69b5ecfea71fe1fe33982c277fc077b6c47552399ab418a6040d2bfefaaf94be255d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000199999999999999a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
callReturn: '0.05959702938270431576',
txHash: '0xdf096e249638df143118f562868e90285579819e59b09f0784b95fa5fd920413'
}
failedResponse = {
error: 501,
message: 'polled network but could not confirm transaction'
}
transact(tx[, onSent, onSuccess, onFailed])
augur.transact carries out the following “send-call-confirm” sequence:
augur.transactsends aneth_sendTransactionRPC request (oreth_sendRawTransactionfor transactions which are already signed), which broadcasts the transaction to the Ethereum network. If an error is received, then the error is passed toonFailedandaugur.transactterminates. If a transaction hash is received, then this transaction is added to theaugur.rpc.txsobject (which is indexed by transaction hash, e.g.augur.rpc.txs[txHash]) and assigned astatusof"pending".augur.rpc.confirmTxuseseth_getTransactionByHashto look up the transaction’s exact ABI-encoded inputs. It then sends aneth_callRPC using these inputs to get the invoked method’s return value (if any). If the return value is an error, then the error is passed toonFailedandaugur.transactterminates. Otherwise,augur.rpc.encodeResultencodes the return value (as specified in thereturnsfield of thetxinput), and an object withtxHashandcallReturnfields is passed toonSent.Every
augur.rpc.TX_POLL_INTERVALmilliseconds,augur.rpc.txNotifylooks up the transaction usingeth_getTransactionByHash. Ifaugur.rpc.txNotifyreceives anullresponse,augur.rpc.txs[txHash].statusis set to"failed". A null response indicates that the transaction has been (silently) removed from geth’s transaction pool. This can happen if the transaction is a duplicate of another transaction that has not yet cleared the transaction pool (and therefore geth does not fire a duplicate transaction error), or if the transaction’s nonce (but not its other fields) is a duplicate. In the former case, the duplicate transaction is assumed to be an accidental submission, aTRANSACTION_NOT_FOUNDerror is passed toonFailed, and theaugur.transactsequence terminates. The latter case arises when the transaction was signed client-side – and therefore its nonce was also generated client-side – then submitted usingeth_sendRawTransaction(instead ofeth_sendTransaction). Network latency, client-side errors, and other factors can result in duplicate raw transaction nonces. In this case,augur.rpc.txs[txHash].statusis set to"resubmitted", the transaction’s nonce is incremented, andaugur.transactis executed with the new transaction.If
augur.rpc.txNotifyreceives a non-null transaction object, thenaugur.rpc.checkBlockHashchecks to see if the transaction’sblockHashfield is a nonzero value, indicating that it has been successfully incorporated into a block and attached to the blockchain. IfblockHashis zero, then afteraugur.rpc.TX_POLL_INTERVALelapses,augur.rpc.txNotifyagain looks up the transaction; this step repeats at mostaugur.rpc.TX_POLL_MAXtimes, after whichaugur.rpc.txs[txHash].statusis set to"unconfirmed", theTRANSACTION_NOT_CONFIRMEDerror is passed toonFailed, and the sequence terminates. IfblockHashis non-zero, thenaugur.rpc.txs[txHash].statusis set to"confirmed". AcallReturnfield is added to the transaction object, which is then passed toonSuccess, completing the sequence.
The first argument to augur.transact is a “transaction object”.
// faucets contract
var branch = augur.branches.dev;
augur.reputationFaucet({
branch: branch,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x7aeeacf586d3afa89dc7ca41a4df52307d1a91c33b8726552d3f84b041b5850e',
callReturn: '1'
}
successResponse = {
nonce: '0x4e4',
blockHash: '0x1fb89b98f59e8a1803556e99c6e2772992ad9bd199e638ccf5e9bff9aa595ffe',
blockNumber: '0x6ab8',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0x509592c96eee7e19f6a34772fd8783cb072ca3c6',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x988445fe00000000000000000000000000000000000000000000000000000000000f69b5',
callReturn: '1',
txHash: '0x7aeeacf586d3afa89dc7ca41a4df52307d1a91c33b8726552d3f84b041b5850e'
}
faucets contract
reputationFaucet(branch[, onSent, onSuccess, onFailed])
Sets the Reputation balance of the sending account to 47. (Only available during testing, of course!)
// cash contract
augur.sendCash({
to: "0x639b41c4d3d399894f2a57894278e1653e7cd24c",
value: 1,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0xff5ad9bdfc9e1ffce3f1014ead5feea6ce4ff15b4a4aaa8734ef4e18338a7bfb',
callReturn: '1'
}
successResponse = {
nonce: '0x4e6',
blockHash: '0xc1fd7a7897560f153cd37053389ac079942661c11f6b9296928481188e4b2b5d',
blockNumber: '0x6ade',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xe4714fcbdcdba49629bc408183ef40d120700b8d',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x693200ce000000000000000000000000639b41c4d3d399894f2a57894278e1653e7cd24c0000000000000000000000000000000000000000000000010000000000000000',
callReturn: '1',
txHash: '0xff5ad9bdfc9e1ffce3f1014ead5feea6ce4ff15b4a4aaa8734ef4e18338a7bfb'
}
augur.sendCashFrom({
to: to,
value: value,
from: from,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0xb2dc04cb4b5f3bb4b0a1dec50d539f31cf048918f62da6bfd202a0a546a32b62',
callReturn: '1'
}
successResponse = {
nonce: '0x4e7',
blockHash: '0x220870218f6e62037139c4d86ba21fad96497ec8bcc3735999dc81e0bc099b21',
blockNumber: '0x6ae4',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xe4714fcbdcdba49629bc408183ef40d120700b8d',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x80b97fc0000000000000000000000000639b41c4d3d399894f2a57894278e1653e7cd24c000000000000000000000000000000000000000000000001000000000000000000000000000000000000000005ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
callReturn: '1',
txHash: '0xb2dc04cb4b5f3bb4b0a1dec50d539f31cf048918f62da6bfd202a0a546a32b62'
}
augur.depositEther({
value: 2,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x2cb4c0f6796b102fb6b1dead8cb85d91f2af330057eb69a6f6f9814617d04a56',
callReturn: '2000000000000000000'
}
successResponse = {
nonce: '0x4e8',
blockHash: '0x81cfb01f897dd7df9ca898f4fd232f5c0957f59596a35b1ef552e37516cdfc38',
blockNumber: '0x6af0',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xe4714fcbdcdba49629bc408183ef40d120700b8d',
value: '0x1bc16d674ec80000',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x98ea5fca',
callReturn: '2000000000000000000',
txHash: '0x2cb4c0f6796b102fb6b1dead8cb85d91f2af330057eb69a6f6f9814617d04a56'
}
augur.withdrawEther({
to: "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b,
value: 2,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x3f44c75513667dee7dcf0a5f08e7be32751fbc2c5c52a8a29018682941ee4895',
callReturn: '1'
}
successResponse = {
nonce: '0x4e9',
blockHash: '0xde4deb916d67631e63e8aed4fefec7839a09be9b3cd8b3914fe48d9751a159a4',
blockNumber: '0x6af3',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xe4714fcbdcdba49629bc408183ef40d120700b8d',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x698f6e9d00000000000000000000000005ae1d0ca6206c6168b42efcd1fbe0ed144e821b0000000000000000000000000000000000000000000000001bc16d674ec80000',
callReturn: '1',
txHash: '0x3f44c75513667dee7dcf0a5f08e7be32751fbc2c5c52a8a29018682941ee4895'
}
cash contract
sendCash(to, value[, onSent, onSuccess, onFailed])
Sends value units of CASH to address to. Returns the value sent if successful.
sendCashFrom(to, value, from[, onSent, onSuccess, onFailed])
Sends value units of CASH to address to from address from. Returns the value sent if successful.
depositEther(value[, onSent, onSuccess, onFailed])
Exchange value units of Ether for an equivalent number of CASH tokens. Returns the amount sent (in Wei).
withdrawEther(to, value[, onSent, onSuccess, onFailed])
Exchange value CASH tokens for an equivalent number of Ether tokens. The withdrawn CASH is sent to address to. Returns 1 if successful, 0 otherwise.
// buy&sellShares contract
var marketId = "-0xb196c4ce182399271e6ed434eb3f2210ae5e427c8ac0604c2cb2261694951d9";
var outcome = 1;
var amount = "0.1";
var price = "0.5";
augur.sell({
amount: amount,
price: price,
market: marketId,
outcome: outcome,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x24fa2a803f42253bbaa900af9badd32d75a728299e66ce9a0dce6a2a264307ca',
callReturn: '-0xb33524aac9866c6cfb74305e92958b150e0a1c1849dbcf606f18d861c4362467'
}
successResponse = {
blockHash: '0x0cde35b78f6102a59c07c0c4279166864e34518fd6672af988cd9224acdfc9c6',
blockNumber: '0xe0ddb',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0x24cd95b300000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000f4e693b31e7dc66d8e1912bcb14c0ddef51a1bd83753f9fb3d34dd9e96b6ae270000000000000000000000000000000000000000000000000000000000000001',
nonce: '0x1006ff',
to: '0xa16ced61576483990d0d821a5fc344a3429ba755',
transactionIndex: '0x0',
value: '0x0',
callReturn: '-0xb33524aac9866c6cfb74305e92958b150e0a1c1849dbcf606f18d861c4362467',
txHash: '0x24fa2a803f42253bbaa900af9badd32d75a728299e66ce9a0dce6a2a264307ca'
}
augur.buy({
amount: amount,
price: price,
market: marketId,
outcome: outcome,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0xbeacc3547fd07d7cd0bde16d404f3554eb4515561fb21bc6a5231459238085c0',
callReturn: '-0x5c354ef67fc3306a984bd1e8722fa3342b02fe6ba690b2d7aecc766c927891f'
}
successResponse = {
blockHash: '0x7f940ad92362787b0f788c8c092e12791f8c588edc10de43091cf989bf5dd615',
blockNumber: '0xe0e4d',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0x3651cae40000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000851eb851eb851eb8f4e693b31e7dc66d8e1912bcb14c0ddef51a1bd83753f9fb3d34dd9e96b6ae270000000000000000000000000000000000000000000000000000000000000001',
nonce: '0x100701',
to: '0xa16ced61576483990d0d821a5fc344a3429ba755',
transactionIndex: '0x0',
value: '0x0',
callReturn: '-0x5c354ef67fc3306a984bd1e8722fa3342b02fe6ba690b2d7aecc766c927891f',
txHash: '0xbeacc3547fd07d7cd0bde16d404f3554eb4515561fb21bc6a5231459238085c0'
}
buy&sellShares contract
buy(amount, price, market, outcome[, onSent, onSuccess, onFailed])
Buy amount shares of outcome in market.
sell(amount, price, market, outcome[, onSent, onSuccess, onFailed])
Sell amount shares of outcome in market.
// check the maximum number of orders per trade
var blockNumber = augur.rpc.blockNumber();
var gasLimit = parseInt(augur.rpc.getBlock(blockNumber).gasLimit, 16);
var maxOrdersPerTrade = augur.maxOrdersPerTrade("buy", gasLimit);
// verify that a trade combination does not exceed the gas limit
var proposedTrades = ["buy", "buy", "sell", "buy", "sell"];
assert(augur.isUnderGasLimit(proposedTrades, gasLimit));
// trade contract
augur.trade({
max_value: 1,
max_amount: 0,
trade_ids: ["-0x22daf7fdff22ff716fd8108c011d1c0e69a7ab4a2b087f65dda2fc77ea044ba1"],
onTradeHash: function (tradeHash) { /* ... */ },
onCommitSent: function (sentResponse) { /* ... */ },
onCommitSuccess: function (successResponse) { /* ... */ },
onCommitFailed: function (failedResponse) { /* ... */ },
onNextBlock: function (blockNumber) { /* ... */ },
onTradeSent: function (sentResponse) { /* ... */ },
onTradeSuccess: function (successResponse) { /* ... */ },
onTradeFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x1437c2e44379169076db42d12fb4f0fab1d330f84ab152900a703ee13f814bf7',
callReturn: '0'
}
successResponse = {
blockHash: '0x3f19ec7209de63043cf5031bb4a38df4bcf6e610f6874dfac87e7ad42e830708',
blockNumber: '0xe10e0',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0xf5c3624f0000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001c630a59f0e14a6695e8078027b13184f00c79e72e606390eab9bd395bdfa1a83',
nonce: '0x10074f',
to: '0xb44cd937904ba0e309204ffc1413e094f2a84ee5',
transactionIndex: '0x0',
value: '0x0',
callReturn: '0',
txHash: '0x1437c2e44379169076db42d12fb4f0fab1d330f84ab152900a703ee13f814bf7'
}
trade contract
trade(max_value, max_amount, trade_ids[, onSent, onSuccess, onFailed])
Matches orders (specified with the array parameter trade_ids) already on the books. max_value is the maximum amount to spend buying shares (including fees). max_amount is the maximum number of shares to sell. The maximum number of trade IDs that can be included in a trade depends on the current gas limit as well as whether the trades are bid or ask orders.
maxOrdersPerTrade(type, gasLimit)
Calculates the maximum number of orders (trade_ids) of type ("buy" or "sell") that can be included in a single augur.trade without exceeding the block gasLimit: max_num_tradeids = 1 + (gas_limit - first_tradeid_gas_cost) \ next_tradeid_gas_cost, where \ is integer division. These costs are determined empirically: for asks, first_tradeid_gas_cost = 756374, next_tradeid_gas_cost = 615817, and for bids, first_tradeid_gas_cost = 787421, next_tradeid_gas_cost = 661894.
isUnderGasLimit(proposedTrades[, gasLimit, callback])
Verifies that the sequence of trades in the array proposedTrades does not exceed the gas limit. If gasLimit is not specified, this function will get the gas limit of the most recent block. (If gasLimit is not specified, isUnderGasLimit should be run asynchronously.) Returns true if the proposed trades are under the gas limit, false otherwise.
// completeSets contract
var marketId = "-0xb196c4ce182399271e6ed434eb3f2210ae5e427c8ac0604c2cb2261694951d9";
var outcome = 1;
var amount = "0.1";
augur.buyCompleteSets({
marketId: marketId,
amount: amount,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x536411add36fc39a8bb8cf310d4f26468f78fde7901721e0aea5b392f59661fe',
callReturn: '1'
}
successResponse = {
blockHash: '0x45498bd80813e9711b86f5ca8ff1ceec0a306a2e1f9d9e884094c78eb24c00bd',
blockNumber: '0xe0e60',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0xbefa1c86f4e693b31e7dc66d8e1912bcb14c0ddef51a1bd83753f9fb3d34dd9e96b6ae27000000000000000000000000000000000000000000000000199999999999999a',
nonce: '0x100704',
to: '0x3eb691ebc786d06eb97954d84e6528f72c4be74a',
transactionIndex: '0x1',
value: '0x0',
callReturn: '1',
txHash: '0x536411add36fc39a8bb8cf310d4f26468f78fde7901721e0aea5b392f59661fe'
}
augur.sellCompleteSets({
marketId: marketId,
amount: amount,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x60ce607ee24c62a60c42837f2ee2a0833fff68c1be23a3805e0271763e04c1b3',
callReturn: '1'
}
successResponse = {
blockHash: '0x326d77dc3891132df8b74cfcf6f27f589e13557c2db40abeae17eae33f026a96',
blockNumber: '0xe0e63',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0xe30d0ad7f4e693b31e7dc66d8e1912bcb14c0ddef51a1bd83753f9fb3d34dd9e96b6ae270000000000000000000000000000000000000000000000010000000000000000',
nonce: '0x100706',
to: '0x3eb691ebc786d06eb97954d84e6528f72c4be74a',
transactionIndex: '0x1',
value: '0x0',
callReturn: '1',
txHash: '0x60ce607ee24c62a60c42837f2ee2a0833fff68c1be23a3805e0271763e04c1b3'
}
completeSets contract
buyCompleteSets(marketId, amount[, limit, onSent, onSuccess, onFailed])
Buy amount shares of all outcomes of marketId from the automated market maker.
sellCompleteSets(marketId, amount[, limit, onSent, onSuccess, onFailed])
Sell amount shares of all outcomes of marketId from the automated market maker.
// createBranch contract
augur.createSubbranch({
description: "Ground0:Party at Ground Zero",
periodLength: 25,
parent: augur.branches.dev,
tradingFee: "0.02",
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x29b169c0bd087aefd2f2dcd7b54c6ac08a3d8d78c6030a18980d059650f39117',
callReturn: '-0xab9869bbaf19cc580a5c6d4571cd7eac02e98ed6ef127c69478bfb43762d4d13'
}
successResponse = {
nonce: '0x4f0',
blockHash: '0xe521198ffbbd9c53bbe7e773502a08482ebe3cdebbb0053a1bf44487b834d43a',
blockNumber: '0x6b7f',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0x5f67ab9ff79be97b27ac8f26ef9f4b429b82e2df',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x5c5c65010000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000f69b5000000000000000000000000000000000000000000000000051eb851eb851eb8000000000000000000000000000000000000000000000000000000000000001c47726f756e64303a50617274792061742047726f756e64205a65726f00000000',
callReturn: '-0xab9869bbaf19cc580a5c6d4571cd7eac02e98ed6ef127c69478bfb43762d4d13',
txHash: '0x29b169c0bd087aefd2f2dcd7b54c6ac08a3d8d78c6030a18980d059650f39117'
}
createBranch contract
createSubbranch(description, periodLength, parent, tradingFee[, onSent, onSuccess, onFailed])
Creates a new sub-branch of branch parent. The description format is branchName:description. periodLength is given in blocks. Returns the new branch’s ID if successful. Otherwise, returns -1 if there is a bad input or the parent doesn’t exist, -2 if there is insufficient funds to create the branch or if the branch already exists.
// sendReputation contract
augur.sendReputation({
branchId: augur.branches.dev,
to: "0x0da70d5a92d6cfcd4c12e2a83950676fdf4c95f9",
value: 10,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x1460b261654f24bf0bbb436f1766b68a94f476c57d4998e26da75114f56cc5a8',
callReturn: '10'
}
successResponse = {
nonce: '0x4f1',
blockHash: '0x2ad3f1071758d9efcb4d2458236128fdaa76585c3c4d551f50c26d2a50a2e38f',
blockNumber: '0x6b97',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0x35152caa07026203a1add680771afb690d872d7d',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0xa677135c00000000000000000000000000000000000000000000000000000000000f69b50000000000000000000000000da70d5a92d6cfcd4c12e2a83950676fdf4c95f900000000000000000000000000000000000000000000000a0000000000000000',
callReturn: '10',
txHash: '0x1460b261654f24bf0bbb436f1766b68a94f476c57d4998e26da75114f56cc5a8'
}
sendReputation contract
sendReputation(branchId, to, value[, onSent, onSuccess, onFailed])
Sends value Reputation tokens on branch branchId to address to. Returns the value sent if successful.
// makeReports contract
var branchId = augur.branches.dev;
var report = ["1", "2", "1", "1.5", "1", "1.5", "2", "1", "1", "1.5", "1", "1"];
var reportPeriod = 397;
var salt = "0xb3017088d3de23f9611dbf5d23773b5ad38621bab84aa79a0621c8800aeb4c33";
augur.report({
branchId: branchId,
report: report,
reportPeriod: reportPeriod,
salt: salt,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse =
augur.submitReportHash({
branchId: branchId,
reportHash: reportHash,
reportPeriod: reportPeriod,
salt: salt,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse =
augur.slashRep({
branchId: branchId,
reportPeriod: reportPeriod,
salt: salt,
report: report,
reporter: "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b",
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse =
makeReports contract
report(branchId, report, reportPeriod, salt[, onSent, onSuccess, onFailed])
Submits an array of reports report for report period reportPeriod on branch branchId.
submitReportHash(branchId, reportHash, reportPeriod[, onSent, onSuccess, onFailed])
Submits the SHA256 hash of the reports array reportHash for report period reportPeriod on branch branchId.
slashRep(branchId, reportPeriod, salt, report, reporter[, onSent, onSuccess, onFailed])
Slashes the Reputation of address reporter for report on branch branchId.
// createEvent contract
var description = "What will the high temperature (in degrees Fahrenheit) be in San Francisco, California, on July 1, 2016?";
augur.createEvent({
branchId: augur.branches.dev,
description: description,
expDate: new Date("7/2/2016").getTime(),
minValue: 0,
maxValue: 120,
numOutcomes: 2,
resolution: "www.weather.com",
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0xc9b92f0224fee5f28c35f49c8b3015e5a09a4876ebb819c1abb5c08ba47c01c6',
callReturn: '0xce75eb6f37b92fa80df3240ea8528f7c4b70c8553a536275e26f36a87f02518'
}
successResponse = {
blockHash: '0x30782f7d4dda3be6e9823deb64a926556b9a508bbef76f4d7bb0e69a4940e59f',
blockNumber: '0xe287e',
from: '0x15f6400a88fb320822b689607d425272bea2175f',
gas: '0x2fd618',
gasPrice: '0x4a817c800',
input: '0x3c1f6f6300000000000000000000000000000000000000000000000000000000000f69b500000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000155aa68258000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000068576861742077696c6c2074686520686967682074656d70657261747572652028696e20646567726565732046616872656e686569742920626520696e2053616e204672616e636973636f2c2043616c69666f726e69612c206f6e204a756c7920312c20323031363f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f7777772e776561746865722e636f6d0000000000000000000000000000000000',
nonce: '0x100751',
to: '0x24b051c19bd981a59f6c459c128a285bcd8d66bc',
transactionIndex: '0x1',
value: '0x0',
callReturn: '0xce75eb6f37b92fa80df3240ea8528f7c4b70c8553a536275e26f36a87f02518',
txHash: '0xc9b92f0224fee5f28c35f49c8b3015e5a09a4876ebb819c1abb5c08ba47c01c6'
}
createEvent contract
createEvent(branchId, description, expDate, minValue, maxValue, numOutcomes, resolution[, onSent, onSuccess, onFailed])
Creates an event on branch branchId with description, expiration date (in epoch time) of expDate, minimum value minValue, maximum value maxValue, numOutcomes possible outcomes, and resolution source for resolution data (e.g., resolution might be set to https://www.wunderground.com/history for a weather-related event).
// createMarket contract
augur.createMarket({
branchId: augur.branches.dev,
description: description,
takerFee: "0.02",
makerFee: "0.01",
tags: ["example tag", "other example tag", "nonsense"],
extraInfo: "An even longer description / link to more info!",
events: ["-0x90fb310e94df790eaab7266034ae3807b147696bcf57a72f71db338f86718875"],
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sendResponse = {
txHash: '0x643462835b9899318ead8f47a1c43232b04a1dfeda8fba213e8c3d8a0c4651e0',
callReturn: '-0x3bb8d91f2481d886fe94acd4d1ffe3339ec60524aeb55ceb5a6c6c8631a796c2'
}
successResponse = {
nonce: '0x535',
blockHash: '0x60a299bc290af601300f2a17686947159073537884aa71fc18fe3628735c5f24',
blockNumber: '0x72e7',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0x448c01a2e1fd6c2ef133402c403d2f48c99993e7',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x08d19b3f00000000000000000000000000000000000000000000000000000000000f69b500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000205bc01a36e2eb200000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000051eb851eb851eb800000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000068576861742077696c6c2074686520686967682074656d70657261747572652028696e20646567726565732046616872656e686569742920626520696e2053616e204672616e636973636f2c2043616c69666f726e69612c206f6e204a756c7920312c20323031363f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f04cef16b2086f15548d99fcb51c7f84eb8969430a858d08e24cc70798e778b',
callReturn: '-0x3bb8d91f2481d886fe94acd4d1ffe3339ec60524aeb55ceb5a6c6c8631a796c2',
txHash: '0x643462835b9899318ead8f47a1c43232b04a1dfeda8fba213e8c3d8a0c4651e0'
}
createMarket contract
createMarket(branchId, description, takerFee, events, tags, makerFee, extraInfo, onSent, onSuccess, onFailed)
Creates a market on branch branchId with description, trading fees paid by the taker of a trade (as a proportion) takerFee, maker fees (fees paid by the order creator, as opposed to the person matching the order) makerFee, topics/categories tags, and more detailed description and/or link to more info extraInfo, and containing event IDs supplied in an array events. Regular (non-combinatorial) markets always have a single event; combinatorial markets allow up to 3 events.
// closeMarket contract
var marketId = "-0x3bb8d91f2481d886fe94acd4d1ffe3339ec60524aeb55ceb5a6c6c8631a796c2";
augur.closeMarket({
branchId: augur.branches.dev,
marketId: marketId,
onSent: function (sentResponse) { /* ... */ },
onSuccess: function (successResponse) { /* ... */ },
onFailed: function (failedResponse) { /* ... */ }
});
// example outputs:
sentResponse = {
txHash: '0x2b48ff35e52c9963503d573c15b559c53e6b34e2ba8f1be3d4d63709239bd8f2',
callReturn: '0'
}
successResponse = {
nonce: '0x536',
blockHash: '0x107c03ea39f081c462db612b7acbb8c6e3abfbdeb16fb7f2e27a680590092f9e',
blockNumber: '0x7301',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xcece47d6c0a6a1c90521f38ec5bf7550df983804',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0xba43b7400',
input: '0x60aea93e00000000000000000000000000000000000000000000000000000000000f69b5c44726e0db7e2779016b532b2e001ccc6139fadb514aa314a5939379ce58693e',
callReturn: '0',
txHash: '0x2b48ff35e52c9963503d573c15b559c53e6b34e2ba8f1be3d4d63709239bd8f2'
}
closeMarket contract
closeMarket(branchId, marketId[, onSent, onSuccess, onFailed])
Closes market with ID marketId on branch branchId.
Invoke
In some cases, you may need more flexibility beyond simply mix-and-matching the Augur API methods. To do this, use ethrpc’s lower-level invoke method (augur.rpc.invoke). First, build a transaction object manually, then execute it using invoke. The invoke method executes a method in a contract already on the network. It can broadcast transactions to the network and/or capture return values by calling the contract method(s) locally.
javascript
// The method called here doubles its input argument.
augur.rpc.invoke({
to: "0x5204f18c652d1c31c6a5968cb65e011915285a50",
method: "double",
signature: "i",
params: 22121, // parameter value(s)
send: false,
returns: "number"
});
// this returns:
44242
Transaction fields are as follows:
Required:
- to:
<contract address> (hexstring) - method:
<function name> (string) - signature:
<function signature, e.g. "iia"> (string) - params:
<parameters passed to the function>
Optional:
- send:
<true to sendTransaction, false to call (default)> - from:
<sender's address> (hexstring; defaults to the coinbase account) - returns:
<"array", "int", "BigNumber", or "string" (default)>
The params and signature fields are required if your function accepts parameters; otherwise, these fields can be excluded. The returns field is used only to format the output, and does not affect the actual RPC request.
Accounts
/**
* Create an account using the augur.web.register method.
*/
var username = "tinybike";
var password = "tinypassword";
augur.web.register(username, password, function (account) {
console.log("Account:", account);
});
// output
Account: {
handle: "tinybike",
privateKey: <Buffer ...>,
address: "0x09129dcde8e0f510ffb2a715709b69f5c4a42361",
nonce: 0
}
/**
* The user is automatically logged in after registering. When logged in,
* the user's data is kept in the the augur.web.account object. Logging out
* unsets the augur.web.account object.
*/
augur.web.logout();
console.log("Account:", augur.web.account);
// output
{}
/* Logging in both sets and returns the augur.web.account object: */
augur.web.login(username, password, function (account) {
console.log(augur.web.account);
});
// output
{
handle: "tinybike",
privateKey: <Buffer ...>,
address: "0x09129dcde8e0f510ffb2a715709b69f5c4a42361",
nonce: 0
}
augur.js includes a trustless account management system. The purpose of the accounts system is to allow people to use Augur without needing to run an Ethereum node themselves, as running a full Ethereum node can be resource-intensive.
To use the account system, the user specifies a username and password. Everything else is done automatically for the user. The only requirement for the password is that it be at least 6 characters long.
A private key (+ derived public key and address) is automatically generated for the user. A secret key derived from the password using PBKDF2, along with a random 128-bit initialization vector, is used to encrypt the private key (using AES-256). The username, encrypted private key, and initialization vector are stored in the browser’s localStorage.
Transaction signing and serialization is entirely carried out in the browser using ethereumjs-tx and the eth_sendRawTransaction RPC; the plaintext private key never touches our servers at any time.
Invoking contract methods is unchanged from normal use (from the client’s perspective). The Augur API functions can simply be called in the usual way (e.g., augur.reputationFaucet), and augur.js will default to client-side transactions if the user is logged in.
Callbacks
/**
* Check account 0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b's cash balance.
*/
var address = "0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b";
// Synchronous
var showMeTheMoney = augur.getCashBalance(address);
// '98855.99999999999999994145'
// Asynchronous
augur.getCashBalance(address, function (showMeTheMoney) {
console.log(showMeTheMoney);
});
// prints 98855.99999999999999994145
/**
* Send 50 cash to 0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b. Because this
* submits a transaction to the network, it can only be done asynchronously.
*/
var amountToSend = 50;
var cb = {
onSent: function (res) { console.log("Sent:", res); },
onSuccess: function (res) { console.log("Success!", res); },
onFailed: function (res) { console.log("Failed:", res); }
};
augur.sendCash(address, amountToSend, cb.onSent, cb.onSuccess, cb.onFailed);
// Printed almost immediately; the callReturn field is the sendCash method's
// return value. If the transaction was sent successfully, callReturn will
// be the amount of cash sent. txHash (the transaction hash) uniquely
// identifies this transaction, and can be used to look it up.
Sent: {
txHash: '0xd5743b5b3bfdec989692b69d68fd8c979120e82cd199fdd80cff36dba42befbe',
callReturn: '50'
}
// Printed after about 12 seconds, when the transaction is detected to have a
// non-null blockHash value.
Success! {
nonce: '0x6f',
blockHash: '0x2f10d8cdb8b2746a5ed24f4021caffae3f25abca297622984c2baa69db0ac50f',
blockNumber: '0x2c58',
transactionIndex: '0x0',
from: '0x05ae1d0ca6206c6168b42efcd1fbe0ed144e821b',
to: '0xe4714fcbdcdba49629bc408183ef40d120700b8d',
value: '0x0',
gas: '0x2fd618',
gasPrice: '0x11102181f5e',
input: '0x693200ce00000000000000000000000005ae1d0ca6206c6168b42efcd1fbe0ed144e821b0000000000000000000000000000000000000000000000320000000000000000',
callReturn: '50',
txHash: '0xd5743b5b3bfdec989692b69d68fd8c979120e82cd199fdd80cff36dba42befbe'
}
Augur API methods that submit transactions to the network (using the eth_sendTransaction RPC) take three callbacks, in the following order:
- onSent: fires when the transaction has been broadcast to the network.
- onSuccess: fires when the transaction has been successfully incorporated into a block.
- onFailed: fires if the RPC request returns an error.
The onSent callback is required; onSuccess and onFailed are both optional. If the onSuccess callback is supplied, augur.js will poll the network every 12 seconds with eth_getTransaction, until the transaction record contains a non-null blockHash value, or a maximum of 12 requests have been made.
Augur API methods that perform RPC requests that do not submit transactions to the network (using the eth_call RPC) take a single optional callback as their last parameter. Unlike transaction RPCs, call RPCs can be synchronous. If a callback is supplied, the RPC request will be asynchronous; otherwise, it will be synchronous.
Numbers
There are three acceptable ways to pass numerical inputs to the Augur API:
primitive JS numbers (e.g.,
1010101): ok for integers, but use strings for floating point numbers (see below)stringified numbers (e.g.,
"1010101")hexadecimal strings (e.g.,
"0xf69b5")
Floating-point (decimal) values should be passed to augur.js as strings (e.g., instead of 0.07, use "0.07"), for reasons described in enormous detail elsewhere.
JSON-RPC
augur.js communicates with the Ethereum network using the ethrpc module, which implements Etherum’s generic JSON-RPC interface. In addition to being the building blocks for the Augur API’s higher-level methods, ethrpc methods are available directly via augur.rpc.
Basic RPC
The raw method allows you to send in raw commands (similar to sending in via cURL):
> augur.rpc.raw("net_peerCount")
"0x10"
> augur.rpc.eth("gasPrice")
"0x015f90"
Many of the commonly used functions have named wrappers. For example, blockNumber fetches the current block number:
> augur.rpc.blockNumber()
217153
Contract upload and download
publish broadcasts (uploads) a compiled contract to the network, and returns the contract’s address:
> augur.rpc.publish("0x603980600b6000396044567c01000000000000000000000000000000000000000000000000000000006000350463643ceff9811415603757600a60405260206040f35b505b6000f3")
"0xf4549459f9ef8c8898c054a7fc37c286831c2ced"
read downloads code from a contract already on the Ethereum network:
> augur.rpc.read("0x5204f18c652d1c31c6a5968cb65e011915285a50")
"0x7c010000000000000000000000000000000000000000000000000000000060003504636ffa1caa81141560415760043560405260026040510260605260206060f35b50"
Filters
// Start filtering
augur.filters.listen({
block: function (blockHash) {
console.log("new block:", blockHash);
},
contracts: function (augurTx) {
console.log("augur transaction:", augurTx);
},
creation: function (newMarket) {
console.log("new market created:", newMarket.marketId);
},
price: function (updatedPrice) {
console.log("updated price:", updatedPrice);
}
});
// Stop filtering
augur.filters.ignore();
// Stop filtering and uninstall filters
augur.filters.ignore(true);
/**
* Example filter results
*/
// block
blockHash = "0x999553c632fa10f3eb2af9a2be9ab612726372721680e3f76441f75f7c879a2f"
// contracts (topics and data fields vary by contract and method)
augurTx = {
address: "0xc1c4e2f32e4b84a60b8b7983b6356af4269aab79",
topics: [
"0x1a653a04916ffd3d6f74d5966492bda358e560be296ecf5307c2e2c2fdedd35a",
"0x00000000000000000000000005ae1d0ca6206c6168b42efcd1fbe0ed144e821b",
"0x3557ce85d2ac4bcd36be7f3a6e0f63cfa6b18d34908b810ed41e44aafb399b44",
"0x0000000000000000000000000000000000000000000000000000000000000001"
],
data: [
"0x000000000000000000000000000000000000000000000001000000000000d330",
"0xfffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffa3"
],
blockNumber: "0x110d",
logIndex: "0x0",
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
transactionHash: "0x8481c76a1f88a203191c1cd1942963ff9f1ea31b1db02f752771fef30133798e",
transactionIndex: "0x0"
}
// creation
newMarket = {
marketId: "-0xcaa8317a2d53b432c94180c591f09c30594e72cb6f747ef12be1bb5504c664bc",
blockNumber: "4689"
}
// price
updatedPrice = {
user: "0x00000000000000000000000005ae1d0ca6206c6168b42efcd1fbe0ed144e821b",
marketId: "-0xcaa8317a2d53b432c94180c591f09c30594e72cb6f747ef12be1bb5504c664bc",
outcome: "1",
price: "1.00000000000000002255",
cost: "-1.00000000000000008137",
blockNumber: "4722"
}
augur.js binds the RPC commands associated with Ethereum’s blockchain (transaction/block) filters, as well as whisper filters. Messages “caught” by filters are retrieved by polling the Ethereum node; the filtering “heartbeat” checks for new messages every 5 seconds. The three primary types of blockchain filters augur.js uses are:
| Filter | Message contents |
|---|---|
| block | new blockhashes |
| contracts | transactions involving any Augur contract |
| creation | new market’s ID and creation blocknumber |
| price | market price updates |
Passing callback functions for block, contracts, creation and/or price to the augur.filters.listen method will start polling the block, contracts, creation and price filters, respectively.
Batching
/**
* Batch RPC request that gets the cash and reputation balances for account
* 0x63524e3fe4791aefce1e932bbfb3fdf375bfad89.
*/
var myAccount = "0x63524e3fe4791aefce1e932bbfb3fdf375bfad89";
var batch = augur.createBatch();
batch.add("getCashBalance", [myAccount], callback);
batch.add("getRepBalance", [augur.branches.dev, myAccount], callback);
batch.execute();
// Manual batching
var txlist = [{
to: "0x3caf506cf3d5bb16ba2c8f89a6591c5160d69cf3",
method: "ten"
}, {
to: "0x5204f18c652d1c31c6a5968cb65e011915285a50",
method: "double",
signature: "i",
params: 3
}];
augur.rpc.batch(txlist);
// returns: ['10', '6']
augur.js implements batch RPC, which can help reduce overhead if you’re making several API calls that can be run in parallel (i.e., do not depend on each other’s results).
For finer-grained control over the batched commands, you can also use ethrpc’s lower-level batch method directly, which is attached to augur.rpc. augur.rpc.batch accepts a list of manually constructed transaction objects.
Geth
// After installing, require geth.js to use it
var geth = require("geth");
// The same flags as the geth command line client!
var options = {
networkid: "10101",
port: 30303,
rpcport: 8545,
mine: null
};
geth.start(options, function (err, proc) {
if (err) return console.error(err);
// get your geth on!
});
// When you and geth have had enough lively times, geth.stop kills
// the geth child process:
geth.stop(function () { /* no more lively times :( */ });
// The `stdout`, `stderr`, and `close` listeners can be initially set
// by passing them to `geth.start`.
var listeners = {
stdout: function (data) {
process.stdout.write("I got a message!! " + data.toString());
},
stderr: function (data) {
if (data.toString().indexOf("Protocol Versions") > -1) {
geth.trigger(null, geth.proc);
}
},
close: function (code) {
console.log("It's game over, man! Game over!");
}
};
geth.start(options, listeners, function (err, proc) { /* <3 geth */ });
// Swap out or add listeners after the initial startup:
geth.listen("stdout", "data", function (data) { /* ... */ });
geth.js is a Node.js module that allows you to start, stop, and monitor geth programmatically. These methods are a bit lower-level than what consumers of Augur’s API will require.
geth.js can be installed using npm:
$ npm install geth
geth’s start method accepts a configuration object, which uses the same flags as the geth command line client. Here, the flags are organized into an object. Flags that are not accompanied by a value on the command line (for example, --mine) should be passed in as { flag: null }.
The callback for geth.start fires after geth has successfully started. Specifically, it looks for "IPC service started" in geth’s stderr stream. If you want to change the start callback trigger to something else, this can be done by replacing geth’s default listeners.
geth.trigger is the callback passed to geth.start: its callback is stored so that the startup trigger can be changed if needed.
Tests
augur.js includes unit tests. Tests are run using Mocha.
$ npm install -g mocha
There are two test suites – the first only runs tests which do not require sending transactions to the Ethereum network, and the second runs a full complement of tests, including tests that create events, markets, buy and sell shares, etc. Generally, it is recommended to only run the full test suite on a private chain.
To run the test suite without transactional tests:
$ npm run testnet
To set up a private chain to run the full test suite, run the included setup.js script. This script requires a local installation of geth, and creates a fresh blockchain (with network ID 10101) in data directory ~/.augur-test. It does not create Ethereum accounts for you; you must set these up yourself prior to running setup.js. The script assumes that your account password is in a file in the new data directory called .password.
The setup script also will upload the Augur contracts to the new blockchain. You must have a local clone of the augur-core repository on your machine for this to work. The setup script can be run with npm:
$ npm run setup -- --augur /path/to/augur-core
After the setup script finishes, you can run the full test suite using npm:
$ npm test -- --gospel
Errors
{
"error": 412,
"message": "transaction validation failed"
}
In addition to the error codes generated by the Augur API, there is a separate set of error codes used by Augur’s smart contracts. To avoid confusion, API error codes are positive integers, while contract error codes are integers less than or equal to zero.
API and contract errors are returned as objects that contain an error field (the integer error code) and a message field (a description of the error).
API Errors
| Error Code | Meaning |
|---|---|
| 40 | Gas Limit Exceeded: trade exceeds the current block gas limit |
| 41 | Wrong Number of Outcomes: the number of initial fair prices does not match this market’s number of outcomes |
| 42 | Insufficient Liquidity: insufficient liquidity to generate order book |
| 43 | Initial Price Out-of-Bounds: one or more initial fair prices are out-of-bounds |
| 44 | Price Width Out-of-Bounds: price width is too large for one or more initial fair prices |
| 97 | Database Delete Failed |
| 98 | Database Write Failed |
| 99 | Database Read Failed |
| 400 | Invalid Contract Parameter: cannot send parameter to contract |
| 401 | Not Logged In |
| 402 | Incorrect number of parameters |
| 403 | Bad Credentials: incorrect handle or password |
| 404 | Transaction Not Found |
| 405 | Password Too Short: password must be at least 6 characters long |
| 406 | Null Call Return: expected contract call to return value, received null |
| 407 | Null Response: expected transaction hash from Ethereum node, received null |
| 408 | No Response |
| 409 | Invalid Response: could not parse response from Ethereum node |
| 410 | Local Node Failure: RPC request to local Ethereum node failed |
| 411 | Hosted Node Failure: RPC request to hosted nodes failed |
| 412 | Transaction Invalid: transaction validation failed |
| 422 | Handle Taken: handle already taken |
| 450 | Filter could not be created |
| 500 | Transaction Failed |
| 501 | Transaction Not Confirmed: polled network but could not confirm transaction |
| 502 | Duplicate Transaction |
| 503 | Raw Transaction Error: error sending client-side transaction |
| 504 | RLP Encoding Error (geth error -32603) |
| 505 | Transaction receipt not found |
| 599 | RPC Timeout: timed out while waiting for Ethereum network response |
| 650 | Loopback Not Found: loopback interface required for synchronous local commands |
| 651 | Ethereum Not Found: no active Ethereum node(s) found |
| 710 | Check Order Book Failed: could not check order book using current prices |
| 711 | Trade Failed: instead of success value (1), received [actual value received] |
| 712 | Trade Not Found |
Contract Errors
| Contract Method | Error | Meaning |
|---|---|---|
| buy | 0 | Market doesn’t exist |
| buy | -1 | Amount/price bad |
| buy | -2 | Oracle-only branch |
| buy | -4 | Not enough money or shares |
| buy | 21 | Trade already exists |
| buyCompleteSets | 0 | market not found |
| buyCompleteSets | -1 | oracle-only branch |
| buyCompleteSets | -3 | not enough cash |
| cashFaucet | -1 | Hey, you’re not broke! |
| claimProceeds | 0 | reporting not done |
| claimProceeds | -1 | trader doesn’t exist |
| claimProceeds | -8 | invalid branch |
| closeMarket | 0 | fail/trading not over yet/event not expired or closed already |
| closeMarket | -1 | Market has no cash anyway / already closed |
| closeMarket | -2 | 0 outcome / not reported on yet |
| closeMarket | -3 | not final round 2 event |
| closeMarket | -5 | Event forked and not final yet |
| closeMarket | -6 | bonded pushed forward market not ready to be resolved |
| closeMarket | -7 | event not reportable >.99 |
| closeMarket | -8 | market isn’t in branch |
| collectFees | -2 | needs to be second half of reporting period to claim rep (1st half is when redistribution is done) |
| createEvent | -1 | we’re either already past that date, branch doesn’t exist, or description is bad |
| createEvent | 0 | not enough money to pay fees or event already exists |
| createEvent | -2 | max value < min value |
| createEvent | -9 | would expire during non-reporting fork period |
| createMarket | -1 | bad input or parent doesn’t exist |
| createMarket | -2 | too many events |
| createMarket | -3 | too many outcomes |
| createMarket | -4 | not enough money |
| createMarket | -5 | fee too low |
| createMarket | -6 | duplicate events |
| createMarket | -7 | event already expired |
| createMarket | -8 | market already exists |
| createMarket | -9 | would expire during non-reporting fork period |
| penalizationCatchup | -1 | not in first half of reporting period |
| penalizationCatchup | -2 | doesn’t need to be penalized/caught up |
| penalizationCatchup | -3 | user isn’t behind or reported in the last period (and should thus use the penalization functions in consensus.se) |
| penalizeOnForkedEvent | -2 | already past first half of new period and needed to penalize before then |
| penalizeOnForkedEvent | -4 | fork event isn’t resolved yet |
| penalizeOnForkedEvent | -5 | already done for all events in this period |
| penalizeRoundTwoWrong | 0 | event is a fork event |
| penalizeRoundTwoWrong | -1 | need to penalize in round 2 penalize function |
| penalizeRoundTwoWrong | -2 | already past first half of new period and needed to penalize before then |
| penalizeRoundTwoWrong | -4 | in fork period only thing that rbcr is done on is the round 2 event in the original branch via round 2 penalize |
| penalizeRoundTwoWrong | -5 | already done for all events in this period |
| penalizeRoundTwoWrong | -6 | forked events should be penalized using the fork penalization function |
| penalizeWrong | 0 | event is a fork event |
| penalizeWrong | -1 | need to penalize in round 2 penalize function |
| penalizeWrong | -2 | already past first half of new period and needed to penalize before then |
| penalizeWrong | -4 | in fork period only thing that rbcr is done on is the round 2 event in the original branch via round 2 penalize |
| penalizeWrong | -5 | already done for all events in this period |
| penalizeWrong | -6 | forked events should be penalized using the fork penalization function |
| penalizeWrong | -7 | no outcome |
| proveReporterDidntReportEnough | -1 | already done |
| proveReporterDidntReportEnough | -2 | not in right part of period |
| pushMarketForward | -1 | fork period cannot be the current or previous period |
| pushMarketForward | -2 | market is already closed or pushed forward |
| pushMarketForward | -3 | not enough cash to post early resolution bond |
| pushMarketForward | -4 | early resolution already attempted or outcome already exists |
| sell | 0 | Market doesn’t exist |
| sell | -1 | Amount/price bad |
| sell | -2 | Oracle-only branch |
| sell | -3 | Bad outcome to trade |
| sell | -4 | Not enough money or shares |
| sell | 21 | Trade already exists |
| sellCompleteSets | -1 | oracle-only branch |
| sellCompleteSets | -2 | not a participant in this market |
| sellCompleteSets | -3 | not enough shares |
| sendReputation | 0 | Not enough Reputation |
| sendReputation | -1 | Your Reputation account was just created! Earn some Reputation before you can send to others. |
| sendReputation | -2 | Receiving address doesn’t exist |
| short_sell | -1 | trade doesn’t exist |
| short_sell | -2 | invalid trade hash/commitment |
| short_sell | -3 | must be a bid, not an ask |
| short_sell | -4 | market is already resolved |
| short_sell | -5 | can’t pickup your own trade |
| short_sell | -6 | can’t trade on oracle only branch |
| short_sell | -7 | not a large enough trade |
| short_sell | 10 | insufficient balance |
| short_sell | 22 | trade in same block prohibited |
| slashRep | 0 | Not a valid claim |
| slashRep | -2 | Reporter doesn’t exist |
| submitReportHash | -1 | invalid event |
| submitReportHash | -2 | not in first half of period (commit phase) |
| submitReport | 0 | reporter doesn’t exist or has <1 rep |
| submitReport | -1 | has already reported |
| submitReport | -2 | not in second half of period [reveal part] |
| submitReport | -3 | hash doesn’t match |
| submitReport | -4 | bad report |
| submitReport | -5 | invalid event |
| submitReport | -6 | already resolved |
| submitReport | -7 | <48 hr left in period, too late to report, able to put up readj. bonds though", |
| submitReport | -8 | fees couldn’t be collected |
| submitReport | -9 | need to pay not reporting bond |
| trade | -1 | oracle only branch |
| trade | -2 | bad trade hash |
| trade | -3 | trader doesn’t exist / own shares in this market |
| trade | -4 | must trade at least 0.00000001 in value |
| trade | -5 | can’t pick up your own trade |
| trade | 10 | insufficient balance |
| trade | 22 | trade in same block prohibited |
| updateTradingFee | -1 | invalid trading fee: either fee is below the minimum trading fee or you are trying to raise the trading fee (trading fees can be lowered, but not raised) |
| updateTradingFee | -4 | sender’s address does not match the market creator’s address |
Contributing
We think Augur and Ethereum are pretty awesome, and believe that they’re going to change the world. We’d love it if you want to be a part of this – as a user, tester, or developer!
We use Github issues as our bug tracker and to-do list. If you want to put your shoulder to the wheel, just pick an issue you want to work on, comment on it to let us know you want to tackle it, and we’ll help you get it done.
Most of our day-to-day conversation happens in our Slack. (We also have an IRC gateway in #augur on Freenode that is connected to our Slack chat!) Our Slack is totally open. If you’d like to join the conversation, just go to Hamsterpad and sign up.