I am working on BitMarket. BitMarket is an open source application, that runs on top of bitmessage and provides an online platform to sell goods and services and is meant to replace the "Market Place" on bitmessage.ch. Please feel free to add any suggestions. Download will be available soon as I already completed about 70% of the work. Below is the readme as it is now. It describes the market and the commands which are currently available. It's quite a mess as it serves as my notepad but should explain how the system works and what are the advantages over a TOR market. ==================================== README.TXT ==================================== // // Warning! This readme is still being modified. // It will become the server and developer readme but currently // also contains informations for end-users. // Content might change in the future. // BitMarket Readme ================ This is the server readme for bitmarket It allows developers to set up their own servers and design BitMarket compatible market systems. Introduction ============ BitMarket is a simple application, allowing you to sell or buy items over the internet securely and anonymously. How does this system differs from other markets? - No requirement for TOR (but possible via proxy setting in PyBitmessage). - No webbrowser or plugin required. - No advertisments. - Buyer and seller communicate over Bitmessage directly. - Market owner cannot steal bitcoins. - Seller is completely free in the way he want to design his offers. - Advanced "PriceMap" system with multiple user-chosen currencies. Confication proof design ======================== Since users can only contact the sellers via their bitmessage address no actual communication gets stored on the server. In case the database gets Confiscated or even hacked, no useful data is stored on it, assuming buyers and sellers use addresses for "market only" purposes. BitMarket can be run in a passive mode on a secondary server. It will receive and process all messages but will not generate any messages. In case the primary server is inaccessible, BitMarket can be switched over to active mode and continues to operate normally. You can have infinite passive mode Markets running on different machines. They all must share the same Bitmessage address and the Database should be set up identically to avoid issues with text lengths. Gettins started =============== BitMarket uses bitmessage as the underlying network infrastructute. Bitmessage is an open-source encrypted communication tool. You can download it from https://bitmessage.org. Compiled and signed Windows binaries can be obtained from http://home.ayra.ch/bitsign After the client has been started at least once, configure the API settings according to https://bitmessage.org/wiki/API Open BitMarket.exe and configure the API settings you just set in Bitmessage. Joining a Market ================ You can join a market via its Bitmessage address. Once joined, it takes a few minutes until it is ready to use. Using the Market ================ You can browse categories and get an overview of the offers in it. If you want to see an offer, you can download it from the market system. After downloading you can read its description, download attached files and contact the seller. Communication with the seller is made directly through Bitmessage itself and fully works, even without the market being online. We recommend using one individual address for each seller, this way he can recognize you as returning customer, but cannot track your interests. Market Broadcasts ================= The Market broadcasts updates to its subscribers. These include: - changed/removed/added categories, files and offers*. - changed Market Settings This keeps a client updated, if he comes online on a regular basis without the need to ask the server for updates. *) Offers marked as "uncategorized" or "private" are not broadcasted. Market Interface ================ The market interface allows you to write your own websites and applications to work with the market. You can fully automate your processes with it. General message format: The message subject contains the command you wish to execute. It is rather short and should be uppercase. Character casing is ignored server side, but uppercase is recommended so users can manually distinguish better between messages in Bitmessage itself. The message body contains payload data (if any) for the command. Payload data is in a 'Name=Value' format for commands that operate on a single item. A Name-Value pair cannot span multiple lines. The "Name" part is case insensitive. Commands for multiple items (especially lists) use a simpler format described for each individual command below. Some commands may also return unspecified "free-form" data. If only one value is returned, it is usually returned as is without a Name-Value format. Commands: MAIN INFO ========= Returns a message with some basic Infromations about the Market. The Text format is free to choose for the Market owner MAIN SETTINGS ============= Returns a message with settings for text fields in the Market. This message might return fields, that cannot be edited by the user. The values do not only tell you how you have to send values, it also tells how values are sent back. Missing values should be assumed to be in RAW format. The settings tell you how a Name-Value pair must be formatted (Maximum Length and format) -1 indicates 'no maximum length'. The Length has to be calculated from the raw data and is in bytes, not in chars. RAW indicates to send the text as-is A85 indicates Ascii85 encoding B64 indicates Base64 encoding Example: FILE.NAME=50,RAW FILE.CONTENT=-1,A85 OFFER.NAME=50,RAW OFFER.FILES=50,RAW OFFER.DESCRIPTION=2000,B64 TRANSACTION.COMMENT=500,B64 MAIN TRANSLIST ============== Returns two name-value pairs with each containing a list of transaction IDs you have generated or received. Example: Sold=23,56,2,16,7,12,19 Bought=1,2,3,4 MAIN CATLIST ============ Returns a list of categories, one category per line. A line contains the category ID, its parent ID (or -1, if no parent), and its name Example: 1,-1,Technology 2,1,Computers 4,-1,Books 3,1,Mobile phones 12,1,Consoles 8,4,Comics 18,4,Novels 33,8,Physical 34,8,Digital 35,18,Physical 36,18,Digital The tree would look as folows: Technology --Computers --Mobile phones --Consoles Books --Novels ----Physical ----Digital --Comics ----Physical ----Digital MAIN OFFERLIST ============== Returns a list of all offers. The list incudes: Offer ID, offer category, stock, price map, offer title Example: 1,12,1,$|1-:50,Used N64 for sale 5,8,3,$|3:1100,Action Comics #1 OFFER GET ============== Returns Details for the given offer ID as Name-Value pairs. Values in the body are as folowing: Title The Title of the offer. Description A more or less detailed description of the offer Address Bitmessage address of the owner. Used to contact him. Only this Address can modify the offer. Category ID of the category the offer is in Special Values: -1 Uncategorized This offer is only listed if you call the MAIN OFFERLIST command. -2 Uncategorized and unlisted This offer is not listed in any way, you have to know its ID Files ID of attached files. Seperated with commas Sellers are free to attach file IDs which they do not own, this can make sense if they partner with another seller and if they share files to save them POW time. Stock Returns two values seperated with a comma. First Number: Number of items to be sold. This can be -1 to indicate an infinite stock. Infinite stocks may be useful if you really can provide infinite items or if it is for virtual goods or for work. Second Number Number of items in stock considering unconfirmed transactions. See the "BUY" command for more informations on this. PriceMap This is the Price map. The price map provides advanced configurations for prices, so you can create discounts for large quantities, or you can define a step value of 5, so an item can only be bought 5 at once (5,10,15,20,etc) If you do not set this at all, the offer is "per request only" so users are forced to contact you and negotiate about the price and quantity. Format is: [:currency[:...]]|amount-min[:step][:amount-max];[:price...]|[next amount-price pair] Description of the parts: [:currency[:...]] A list of currencies you accept in the order you like them most. For example: USD:CHF:BTC This is always the first item in the PriceMap and can only be used once. You can feeely choose if you use the 3 letter code, the full name or the currency symbol and you can mix them together. To show you with the same exaple as used above: $:CHF:Bitcoin amount-min[:step[:amount-max]] This defines the range of items. While the shop does not really cares what you enter here as long as it is mathematically valid you should not create a Price Map with overlapping quantities. A common isssue is a map from 1-10 and one from 10-20, so "10" is actually used twice. In this case the client will always show the first match only. You can define 1,2 or 3 values: 1 value : If the user buys at least this many, he pays the prices you defined after the value. In this case step defaults to 1, and amount-max is unlimited 2 values: Similar to the "1 value" example, but the user can only increase in steps of the second value up to the stock count. 3 values: Similar to the "2 value" example, but the 3rd value defines a maximum of items available to buy. Use the 3-value method to limit a user to a specific amountby setting min and max amount to the same number and step to anything bigger than 0. [:price...] This is simple. It's the price per piece. You must have as many values as you have currencies and you also must have them in the same order. The price is always for a single item, so if the Pricemap is "USD|5:1:8|10" and the user buys 7 items, he pays 7*10=70 USD. If you have additional costs (shipment and packaging fees for example) put them in the description and not the PriceMap. Examples: USD:CHF:BTC|10:1;1:0.95:0.001|1:1:9;1.20:1.15:0.0012 This example sells an item in 3 currencies and offers a discount, if 10 or more are bought at once. 1-9 items: you pay 1.20 USD or 1.15 CHF or 0.0012 BTC 10 or more items: you pay 1 USD or 0.95 CHF or 0.001 BTC USD|10:10:50;20 The user can buy 10,20,30,40 or 50 items for 20 USD per single item USD|10:10:55;20 Same example as above, but it would be rejected by BitMarket, because 55 items cannot be reached with the given Range LastModify This is the Date and Time, when the offer was last modified. Offers disappear after 30 days so if you want to keep it active longer, occasionally execute the SET command. OFFER SET ============== Use this command to create new offers and and modify your existing offers. Supply the Name-Value Pairs you want to define below. Read carefully for each pair if it is optional and what happens if ommited. Set the ID to -1 to create a new offer. Creating and editing returns the offer itself as answer. If you supply invalid arguments you additionally also receive error messages. Ommitting a Name-Value Pair or only sending the "Name=" part is not the same. Ommitting usually leaves the value unchanged, while supplying the Name-Part clears the value (since you set it to nothing). This is not valid for everything, for example the title or the Category. Editing an offer resets its expiration time. An offer is removed after being unchanged for 30 days. When editing an offer all fields are optional. You can basically submit an empty SET message if you want to keep your offer active for another 30 days without changing anything. Title This is required for creating an offer and optional for editing. When not supplied, the current value is kept. Must not be empty Description This is optional. When not supplied, the current value is kept for editing and an empty value is set for creating. Category This is optional. When not supplied, the current value is kept for editing and -1 is set for creating. Must not be empty Special values: -1: this offer is uncategorized -2: This offer is uncategorized and unlisted (not visible via "MAIN OFFERLIST"). You must tell the ID others manually Files This is optional. When not supplied, the current value is kept for editing and an empty value is set for creating. Stock This is optional. When not supplied, the current value is kept for editing and 0 (out of stock) is set for creating. When setting this value, consider the PriceMap, if you have a map that allows users to buy in steps of 5 you should always have multiple of 5 in stock. Must not be empty Special values: -1: Infinite stock PriceMap This is optional. When not supplied, the current value is kept for editing and an empty value is set for creating. OFFER DEL ============== This just removes an offer. You can only use this command from the address, that created the offer. OFFER BUY (buyer side) ============== Buys the item with the specified ID. When you buy the item with this command you will receive a message with a transaction ID in it and nothing more. When you buy an item you can send a message to the seller. If the seller requires you to send in some informations in the offers desctiption you can do so here. This will speed up the negotiation process. You can still contact the seller in bitmessage manually if you prefer. The body of your command message must contain name-value pairs (at least the Amount pair): Amount Required, the number of items you want to buy. Understock Optional, Bitmessage requires time to send messages, so two people can buy the last few items at the same time and one of them wins. You can specify a number between 1 and the Amount of items you bought. Assuming only 6 items are left, because somebody bought 4 just before you could buy all 10. What happens now depends on the understock value. If it is 6 or less, you will buy that many, if it is 7 or more, you will buy none and receive an error message. If you do not specify this value it is internally set to the amount you want to buy. Message optional, a message you want to send to the seller. This can be anything. Read the offer description carefully, sometimes the seller requires informations, for example shipping address or color of the item. OFFER BUY (seller side) ============== You cannot buy your own items (seller and buyer address must differ) but as seller you receive part of the result of this command. When somebody buys an item from you, you automatically receive a message with the command as subject. Since you cannot buy your own items you can determine from the ID, if you are the seller or buyer of an item. The body contains Name-Value Pairs: ID This is the transaction ID, not the offer ID. You need it to approve, reject, comment and rate the transaction. AddressBuyer This is the bitmessage address of the user Amount Two values seperated with a comma. First value is what the user wanted, the second value is what he got (considering your stock count). If he got less than what he wanted you definitely want to check how fast you can restock. Some users are willing to wait a few days. Understock This is the Understock value the user specified. In case your stock count count was too high you can try to convince the user to reduce his amount a little. This value will most likely be the amount he wanted. Message The message, the user entered during the transaction. This might be empty. FILE GET ============= Returns the specific File as Name Value Pair to the sender Name File Name Content File contents FILE SET ============= Saves or modifies a file. A file can only be modified by its owner address. Name This is required for creating a file and optional for editing. When not supplied, the current value is kept. Must not be empty Doesn't needs to be a valid file name but at least should end with a proper file extension (.jpg .png, etc) so the client can properly display it. Content This is required for creating a file and optional for editing. When not supplied, the current value is kept. Must not be empty FILE DEL ============= Deletes a file from the market. This will not remove file references from offers. Can only be executed by the address who owns the file. TRANSACTION GET ==================== Can only be executed by buyer (user who created the transaction) and seller (owner of the offer). Returns Name-Value pairs of the transaction to view its details. AddressBuyer The address which generated the transaction. (Buyer of items) AddressSeller The address of the Offer owner. (Seller of items). The reson this is specified is because the offer may be deleted already. Amount Number of items bought Offer ID of the offer State The state the transaction is in. Possible Values: -3 Both have used the "REJECT" command. This transaction is officially invalid. This can happen if negotiation fails or both agree to abandon the transaction. If rejected, the offer is restocked with the amount of items automatically. If nobody leaves a comment or rating, the transaction might get wiped from the system after it expires. -2 The buyer has rejected the transaction, but the seller has not. In this state, the seller cannot confirm the transaction and if it was confirmed this state is removed. This should be done if the user accidently bought wrong quantities and wants to generate another transaction with the correct amount. -1 Only the seller has rejected the offer. This should be done if the item is out of stock of if negotiation failed and the transaction is abandoned. 0 This is the state of a transaction if nothing has happened yet 1 The seller has confirmed the transaction and is willing to process it. At this state, the Stock count of the item is adjusted. 2 The Buyer has confirmed the transaction and received the item/service in question. The transaction can no longer be rejected ad this state. 3 Both sides left a comment and rating. The transaction can no longer be rejected ad this state. Comments and ratings can no longer be changed at this state. This is set automatically if one of these conditions are set: - Offer has state 2 and comment+rating given by both, seller and buyer - Offer has state 2 and is expired and both parties did not comment/rate 4 Buyer left no comment and transaction expired. When displaying ratings for the buyer in question, the client should warn the user about a bad comment practice. 5 Seller left no comment and transaction expired. When displaying ratings for the seller in question, the client should warn the user about a bad comment practice. BuyerComment The comment, the buyer left. This should describe the reason for the given rating SellerComment The comment, the seller left. This should describe the reason for the given rating BuyerRating Rating, the buyer left. (0-5). SellerRating Rating, the seller left. (0-5). TransactionTime The time the transaction was generated. Buyer and seller should try to complete a transaction within 60 days. After 60 days it is expired and cannot be changed anymore. TRANSACTION CONFIRM ======================== Can be initiated by buyer and seller and has different meanings, depending on who confirms. Both parties receive the full transaction spec (as if the issued the GET command) if something changes. You cannot confirm an expired transaction. Seller: The seller should confirm the transaction if he is willing to process it. He should only do so if he guarantees, that he processes the offer, in other words after negotiation with the buyer is complete and everything is set up. This will adjust the stock count of the item in question. If the amount has changed during negotiation you need to manually edit your offer and adjust the stock count manually. The seller can only confirm in state 0. Buyer: The buyer should confirm the offer, after he received the item. He can only confirm in state 1 (cannot confirm before the seller did). Confirmation just indicates, that the buyer received the item and not that he is happy with it. TRANSACTION REJECT ======================= Can be initiated by buyer and seller as long, as the transaction State is not 3,4 or 5 Rejecting a transaction should be done with caution. Rejecting ultimatively prevents a transaction from being successful and is irreversible. A transaction should only be rejected after negotiation with each other. You cannot reject an expired transaction. There are different reasons for rejecting, including the buyer not paying or the seller not being able to deliver the quantity requested. Rejecting will change the State of the transaction but it will not affect the stock count. If the seller has already confirmed he needs to manually adjust the stock count. Rejecting a transaction also removes the comment the issuer of the command has given. The reason for this is, because you cannot change a comment in a negative transaction state. This allows the issuer to set a comment again just once. If one party rejects, the other should not automatically reject. If the transaction expires it tells who has rejected when users ask for rating. If only the buyer rejects, users know, that the seller was willing to fulfill the transaction but the buyer did not. Since the Market is fully anonymous (ans also trustless) it makes it easier for users to understand the comments if the proper transaction state is maintained. TRANSACTION COMMENT ======================== Adds or changes a comment and a rating in a transaction. You cannot comment on expired transactions You cannot comment in state 3,4 or 5. You cannot comment on transactions in state -1,-2 and -3 if a comment is already present. Before leaving negative feedback, try to resolve the issue with the seller. And always double check in your Bitmessage client, if the message was delivered and is not waiting for ACK. Supply two Name-Value pairs in the body of the message: Rating A whole number from 0-5. 1-2 is considered negative feedback, 3 is neutral, 4-5 is positive feedback. 0 means unrated. In some cases you might want to give a text comment but not a Number rating. This is not very nice and may affect your own rating if a client sees this. Comment This should be a textual representation of the Rating value. RATING
GET ==================== Ratings are important but in a completely anonymous system you might not trust them too much. The command returns a simple list of comments: Transaction state,Address,Rating,Comment Example: 3,BM-Bc7Rspa4zxAPy9PK26vmcyoovftipStp,4,VmVyeSBmYXN0IGRlbGl2ZXJ5LCBkaWQgbm90IGhhZCBldmVyeXRoaW5nIGluIHN0b2Nr This is a comment from a completed transaction. The author is BM-Bc7Rspa4zxAPy9PK26vmcyoovftipStp The Rating is 4 The message is "Very fast delivery, did not had everything in stock" The reason the comment is in Base64 is because the SETTINGS command defined it as such. You always receive text values the way you have to send them. Error Messages ============== Whenever something goes wrong, you receive an error message. Error messages have "ERROR" as the subject and a human readable message as body.