Compare commits

...

119 commits

Author SHA1 Message Date
Christopher Sanborn
219b17a8aa Updated numbering in bsip-1203 to match assigned numbering. 2018-10-17 12:58:47 -04:00
Christopher Sanborn
792c524b2a Work in API Requirements subsection of Specifications 2018-10-10 14:51:35 -04:00
Christopher Sanborn
4772b5a736 Small additions to References and See Also. 2018-10-10 13:46:32 -04:00
Christopher Sanborn
52eafc5a64 Clarity edits in Discussion section. 2018-10-10 13:31:20 -04:00
Christopher Sanborn
43831e0a05 Clarity edits in Specifications section. 2018-10-10 12:53:26 -04:00
Christopher Sanborn
dfb2ca516a Typo 2018-10-08 14:17:26 -04:00
Christopher Sanborn
6b923189cd Clarity edits in Specifications section. 2018-10-08 14:15:10 -04:00
Christopher Sanborn
bd1f839c7f More clarity edits in Rationale section. 2018-10-08 13:47:45 -04:00
Christopher Sanborn
a5d3b0208b More edits for clarity. 2018-10-08 12:05:10 -04:00
Christopher Sanborn
b0b0be9592 bsip1203 minor phrasing fixes 2018-10-05 11:38:11 -04:00
Christopher Sanborn
4383ef74a7 bsip-1203: Detailed deterministic offset computation. 2018-10-03 13:40:22 -04:00
Christopher Sanborn
87525f2496 BSIP-1203: Explanation of address-per-invoice. 2018-10-02 01:04:47 -04:00
Christopher Sanborn
3a053c4828 Added a link to an example transaction in main net showing cTXO output fields. 2018-10-01 10:07:56 -04:00
Christopher Sanborn
b767a530f2 Explication of encrypted memo format 2018-10-01 00:24:12 -04:00
Christopher Sanborn
d489b494bd BSIP-1203: More work in Specification section. Some addition to Shareholder Summary section. 2018-09-30 19:14:48 -04:00
Christopher Sanborn
fb068e7e1c BSIP-1203: Moved Motivation section to Rationale section and wrote a brief Motivation section. 2018-09-30 14:42:36 -04:00
Christopher Sanborn
f3ee7999f7 Rephrasing in the Specifications section. Discussion of some future address extensions in the Discussion section. 2018-09-30 14:13:58 -04:00
Christopher Sanborn
7ebd6ac361
Update bsip-1203.md
Added rudimentary summary in Summary section.
2018-09-30 00:42:51 -04:00
Christopher Sanborn
9445500771
Typo in table markdown 2018-09-30 00:34:53 -04:00
Christopher Sanborn
effbe1bcde Rewriting of Motivation section for clarity and specifics. 2018-09-30 00:32:48 -04:00
Christopher Sanborn
c51a358a2d Added clarification of key roles in Motivation section of 1203. Fixed incorrect bsip numbers in header blocks of 1203, 1204, and 1205. 2018-09-24 11:48:50 -04:00
Christopher Sanborn
00e3c38ebf
Description of possible Address Key attack
Description of possible attack on Address private key if a single commitment private key is leaked
2018-09-19 22:59:19 -04:00
Christopher Sanborn
0d3e68f471 Work on bsip-1203, recognition of incoming transactions. 2018-09-10 22:17:08 -04:00
christophersanborn
88f8af359f
Link to top-level BSIP for Stealth Phase-II 2018-07-18 16:51:01 -04:00
christophersanborn
286e8ac44b
Overview of asset surjection proof. 2018-07-18 11:42:44 -04:00
christophersanborn
75b47a4748
References to Elements Project 2018-07-18 11:31:33 -04:00
christophersanborn
5ab1257b0b
range proof blurb 2018-07-16 22:58:59 -04:00
christophersanborn
59507c2ea3
Minor edits for style and clarity 2018-07-16 13:15:06 -04:00
christophersanborn
d1f7fbdbe4
Surjection question 2018-07-16 11:44:17 -04:00
christophersanborn
52feaa1fc8
subsection Asset Tags and Asset Commitments 2018-07-16 11:09:43 -04:00
christophersanborn
dfffa78782
Update bsip-1201.md 2018-07-15 10:26:36 -04:00
christophersanborn
4bd1dc5638
Op-codes for CA operations, outline. 2018-07-12 18:07:53 -04:00
christophersanborn
fd1c1a368b
Update bsip-1201.md
Additions to Motivation section.
2018-07-06 00:12:29 -04:00
Christopher Sanborn
ba3b9d3255 Added more links and references 2018-03-18 17:42:15 -04:00
Agorise
4ed19a0414
Update bsip-1200.md 2018-03-17 09:23:05 +02:00
Christopher Sanborn
326873130c Fixed heading level of a subheading. 2018-03-16 21:47:20 -04:00
Christopher Sanborn
d039e475b4 Renumbered BSIPs due to removal of old bsip-1203. Updated links. 2018-03-16 21:42:10 -04:00
Christopher Sanborn
07af9adbf6 Removed old bsip-1203.md 'Retrieve Stealth UTXO sets by block-height range'. 2018-03-16 21:32:45 -04:00
Christopher Sanborn
f040dd080f Merging BSIP 1203 content into BSIP 1204, in preparation to remove 1203. 2018-03-16 21:21:31 -04:00
Christopher Sanborn
9599ba8817 Added a table of component BSIPs to bsip-1200 abstract. Renamed two BSIPs to better represent high-level purpose. 2018-03-16 14:36:44 -04:00
Christopher Sanborn
f32a60c08e Addition of draft material for Stealth Development, Phase II, comprising BSIPs 1200 through 1206 (temporary numbers). 2018-03-16 12:15:45 -04:00
Abit
adb233735f
Merge pull request #69 from bitshares/update1
Update worker and status for bsip29-37
2018-03-06 00:09:58 +01:00
abitmore
344156ce36 Update worker and status for bsip29-37 2018-03-05 10:35:32 +00:00
Fabian Schuh
5bf3ddc5f6
Merge pull request #59 from bitshares/bsip35
Add BSIP 35: Mitigate Rounding Issue On Order Matching
2018-02-27 14:08:58 +01:00
abitmore
3831794d4e Merge branch 'master' into bsip35 2018-02-26 11:21:13 +00:00
Abit
e3e8bd79b3
Merge pull request #65 from bitshares/oxarbitrage-patch-5
change title
2018-02-26 12:15:49 +01:00
Abit
a57b3aa159
Merge pull request #66 from bitshares/oxarbitrage-patch-6
change title
2018-02-26 12:15:30 +01:00
Abit
dac2335aa4
Merge pull request #64 from bitshares/oxarbitrage-patch-4
change bsip 36 and 37 titles
2018-02-26 12:15:09 +01:00
oxarbitrage
b5d70d616f
change title 2018-02-25 19:45:17 -03:00
oxarbitrage
e56ccde022
change title 2018-02-25 19:43:54 -03:00
oxarbitrage
90c7abb725
change bsip 36 and 37 titles 2018-02-25 19:42:30 -03:00
abitmore
2587dc7d49 bsip35: add link in motivation section. 2018-02-25 22:37:15 +00:00
oxarbitrage
623a6f9b8e
Merge pull request #63 from bitshares/oxarbitrage-patch-3
add bsip 36 and 37 to readme
2018-02-25 19:27:27 -03:00
abitmore
dbb42ea8fb bsip35: add core issue 342 to discussion link 2018-02-25 22:13:46 +00:00
abitmore
e22fe0e2d3 bsip35: rounding rules when call bigger than limit 2018-02-25 22:07:57 +00:00
abitmore
d6c7fdc785 bsip35: overall solution for rounding issues 2018-02-25 21:24:21 +00:00
oxarbitrage
a1b438c7e0
add bsip 36 and 37 to readme 2018-02-25 13:42:35 -03:00
Abit
e82288f370
Merge pull request #62 from bitshares/oxarbitrage-patch-2
Add BSIP 37: Extend created asset names
2018-02-25 15:07:32 +01:00
Abit
e8204f3a70
Merge pull request #61 from bitshares/oxarbitrage-patch-1
Add BSIP 36: Remove expired feeds
2018-02-25 15:04:46 +01:00
abitmore
485df5cd4f bsip35: more settling rules after globally settled
Add description for the old total supply rule (no change).
2018-02-23 19:16:38 +00:00
abitmore
8a06150338 bsip35: handle settling after globally settled 2018-02-23 18:56:36 +00:00
oxarbitrage
52a530fd8e
change discussion link 2018-02-23 15:01:50 -03:00
oxarbitrage
e3914d5f03
change discussion link 2018-02-23 14:58:48 -03:00
oxarbitrage
c4d424aa57
change rationale 2018-02-23 14:56:02 -03:00
oxarbitrage
2bd11aedac
Create bsip-0037.md 2018-02-23 11:43:57 -03:00
oxarbitrage
cd459ee9d4
Create bsip-0036.md 2018-02-23 11:00:07 -03:00
abitmore
b00e7f33ab bsip35: wording change 2018-02-22 15:36:43 +00:00
abitmore
259fbe05ac bsip35: add definition of smaller order 2018-02-22 14:35:23 +00:00
abitmore
58e11a7397 Update Readme to include bsip35 2018-02-22 11:34:12 +00:00
abitmore
a52ca3919f Merge branch 'master' into bsip35 2018-02-22 11:32:44 +00:00
Abit
2bbe6f836f
Merge pull request #60 from bitshares/update-readme
Update Readme
2018-02-22 12:31:09 +01:00
Fabian Schuh
ece1658e00 Update Readme 2018-02-22 12:22:59 +01:00
Fabian Schuh
72c63d9ef6
Merge pull request #56 from bitshares/bsip32
Add BSIP 32: Always Match Orders At Maker Price
2018-02-22 12:08:09 +01:00
Fabian Schuh
e12c618a3f
Merge pull request #57 from bitshares/bsip33
Add BSIP 33: Maker Orders With Better Prices Take Precedence
2018-02-22 12:07:53 +01:00
Fabian Schuh
2f45346aac
Merge pull request #58 from bitshares/bsip34
Add BSIP 34: Always Trigger Margin Call When Call Price Above Or At Price Feed
2018-02-22 12:07:36 +01:00
abitmore
590a296fb6 bsip35: correct specification about settle order 2018-02-20 19:03:04 +00:00
abitmore
9a841385bc bsip35: update specification with more details 2018-02-20 18:53:45 +00:00
abitmore
1cf3cf894d bsip35: adjust mechanism handling settle order 2018-02-20 18:16:48 +00:00
abitmore
dceedb9d43 bsip35: update logic of matching limit and call 2018-02-19 20:35:00 +00:00
abitmore
27e1975b28 bsip33: text reorganization 2018-02-19 10:53:41 +00:00
abitmore
5fabc12f16 Add BSIP 35 2018-02-19 00:19:59 +00:00
abitmore
f220846900 bsip34: wording change and text reorganization 2018-02-18 21:56:55 +00:00
abitmore
21f3d15cbc bsip32: text reorganization 2018-02-18 21:19:57 +00:00
abitmore
b5e469742a Update README.md for BSIP 32 2018-02-18 20:12:46 +00:00
abitmore
4819d6be64 Merge branch 'master' into bsip32 2018-02-18 20:11:29 +00:00
Abit
1f91ed3c9a
Merge pull request #55 from bitshares/bsip31
Add BSIP 31: Update Short Position's Margin Call Price After Partially Called Or Settled
2018-02-18 21:11:08 +01:00
abitmore
219b3089b4 Update readme for BSIP 31 2018-02-18 19:28:56 +00:00
abitmore
2474ee2fd2 Merge branch 'master' into bsip31 2018-02-18 19:27:28 +00:00
Abit
2260bab020
Merge pull request #54 from bitshares/bsip30
Add BSIP 30: Always Allow Increasing Collateral Ratio If Debt Not Increased
2018-02-18 20:26:22 +01:00
abitmore
f086fdfd37 Add BSIP 34 2018-02-18 15:17:25 +00:00
abitmore
09a6529d66 bsip33: fix typo 2018-02-18 13:24:32 +00:00
abitmore
dcaa2e8891 bsip32: fix typo 2018-02-18 13:23:39 +00:00
abitmore
f350d86af9 bsip31: fix typo 2018-02-18 13:23:02 +00:00
abitmore
2255360034 bsip30: fix typo 2018-02-18 13:22:19 +00:00
abitmore
c8be764e1f bsip32: minor wording change 2018-02-18 12:45:22 +00:00
abitmore
6579c464c2 bsip33: minor wording change 2018-02-18 12:43:43 +00:00
abitmore
b57ab21399 bsip33: minor wording change 2018-02-18 11:03:20 +00:00
abitmore
6878d6461f bsip33: add link to bitshares-core issue No. 453 2018-02-18 10:22:35 +00:00
abitmore
97ed075555 bsip33: add text about processing taker call order 2018-02-18 10:20:12 +00:00
Abit
7480447b88
bsip32: wording change about MSSP and 100CRP 2018-02-17 22:35:53 +01:00
abitmore
c6dbe1880e Add BSIP 33 2018-02-17 00:33:15 +00:00
abitmore
7f291d9b06 bsip32: minor wording change. 2018-02-17 00:02:11 +00:00
abitmore
2723cc73b6 bsip32: add when to check for black swan event 2018-02-16 23:41:39 +00:00
abitmore
8bc2a40e46 Add BSIP 32 2018-02-16 22:48:21 +00:00
abitmore
a38836001c Add BSIP 31 2018-02-16 22:01:13 +00:00
abitmore
69ac9dc067 Add BSIP 30 2018-02-16 09:51:51 +00:00
Fabian Schuh
3a526a4109 worker added 2018-01-30 09:20:42 +01:00
Fabian Schuh
6c89183bc3 typo 2018-01-30 09:15:43 +01:00
Fabian Schuh
54c1644310 New BSIP 29 2018-01-30 09:15:22 +01:00
abitmore
30477cb3ff Update status of BSIP 26 and 27 to accepted 2018-01-27 20:31:36 +00:00
Abit
ed658d5c94
Update bsip26 status to approved 2018-01-27 21:27:01 +01:00
Abit
fdbd098dd4
Change bsip27 status to approved. 2018-01-27 21:26:27 +01:00
Fabian Schuh
eba090850f Updates to #27 to reflect the code 2018-01-24 14:55:08 +01:00
Abit
e062a351c2
Change bsip 18 status to installed 2017-12-12 14:52:34 +01:00
Abit
2b214b2ffc
bsip18: update status -> installed 2017-12-12 14:50:47 +01:00
Fabian Schuh
1281d05215 Deferr 19 & 20 2017-11-30 09:06:50 +01:00
Abit
25e935586e
bsip27: update worker id 2017-11-23 20:33:16 +01:00
Abit
0045b5da94
bsip26: update worker id 2017-11-23 20:32:47 +01:00
Abit
cf781275af
Merge pull request #41 from bitshares/oxarbitrage-patch-1
update proposed changes
2017-11-18 22:21:43 +01:00
22 changed files with 2047 additions and 18 deletions

View file

@ -25,14 +25,29 @@ Number | Title |
[15](bsip-0015.md) | Disable negative voting on workers | Daniel Larimer | Protocol | Installed
[16](bsip-0016.md) | Optimization to Force Settlement Parameters of BitCNY | Jerry Liu | Protocol | Installed
[17](bsip-0017.md) | Revive BitAsset after Global Settlement | Peter Conrad | Protocol | Draft
[18](bsip-0018.md) | Revive BitAsset through buying Settlement Pool | Fabian Schuh | Protocol | Implemented
[19](bsip-0019.md) | Introducing profit sharing/dividends to Bitshares (MPA only) | Customminer | Protocol | Rejected
[20](bsip-0020.md) | Introducing profit sharing/dividends to Bitshares (UIA only) | Customminer | Protocol | Rejected
[18](bsip-0018.md) | Revive BitAsset through buying Settlement Pool | Fabian Schuh | Protocol | Installed
[19](bsip-0019.md) | Introducing profit sharing/dividends to Bitshares (MPA only) | Customminer | Protocol | Deferred
[20](bsip-0020.md) | Introducing profit sharing/dividends to Bitshares (UIA only) | Customminer | Protocol | Deferred
[21](bsip-0021.md) | Introducing the 'Coin-Age' statistic to Bitshares assets | Customminer | Protocol | Draft
[22](bsip-0022.md) | Introducing expiring votes for Witnesses, Committie members & Proxies within the Bitshares network | Customminer | Protocol | Draft
[23](bsip-0023.md) | Sharedropping an UIA against an external cryptocurrency distribution snapshot | Customminer | Protocol | Draft
[24](bsip-0024.md) | Locking Bitshares away as 'Bitshares Influence' for voting privileges on the BTS DEX | Customminer | Protocol | Draft
[25](bsip-0025.md) | Transaction Flat-Rates with Weighted Rate-Limitation | Fabian Schuh | Protocol | Draft
[26](bsip-0026.md) | Refund Order Creation Fee in Originally Paid Asset on Cancel | Abit More | Protocol | Draft
[27](bsip-0027.md) | Asset Issuer Reclaim Fee Pool Funds | Abit More | Protocol | Draft
[26](bsip-0026.md) | Refund Order Creation Fee in Originally Paid Asset on Cancel | Abit More | Protocol | Accepted
[27](bsip-0027.md) | Asset Issuer Reclaim Fee Pool Funds | Abit More | Protocol | Accepted
[28](bsip-0028.md) | Worker Proposal Improvements | Bill Butler | Protocol | Draft
[29](bsip-0029.md) | Asset issue change to require owner authority | Fabian Schuh | Protocol | Accepted
[30](bsip-0030.md) | Always Allow Increasing Collateral Ratio If Debt Not Increased | Abit More | Protocol | Accepted
[31](bsip-0031.md) | Update Short Position's Margin Call Price After Partially Called Or Settled | Abit More | Protocol | Accepted
[32](bsip-0032.md) | Always Match Orders At Maker Price | Abit More | Protocol | Accepted
[33](bsip-0033.md) | Maker Orders With Better Prices Take Precedence | Abit More | Protocol | Accepted
[34](bsip-0034.md) | Always Trigger Margin Call When Call Price Above Or At Price Feed | Abit More | Protocol | Accepted
[35](bsip-0035.md) | Mitigate Rounding Issue On Order Matching | Abit More | Protocol | Accepted
[36](bsip-0036.md) | Remove expired price feeds on maintenance interval | oxarbitrage | Protocol | Accepted
[37](bsip-0037.md) | Allow new asset name to end with a number | oxarbitrage | Protocol | Accepted
[1200](bsip-1200.md) | Stealth development, Phase II | Chris Sanborn | Informational | Draft
[1201](bsip-1201.md) | New operations for Confidential Asset (CA) transactions | Chris Sanborn | Protocol | Draft
[1202](bsip-1202.md) | Ring signatures for untraceability of Stealth transactions | Chris Sanborn | Protocol | Draft
[1203](bsip-1203.md) | Blockchain scanning for inbound Stealth transactions | Chris Sanborn | Protocol | Draft
[1204](bsip-1204.md) | Deterministic addresses for Stealth wallets | Chris Sanborn | Informational | Draft
[1205](bsip-1205.md) | Metadata hiding via Garlic Routing and other means | Chris Sanborn | Informational | Draft

View file

@ -1,7 +1,7 @@
BSIP: 00018
BSIP: 0018
Title: Revive BitAsset through buying Settlement Pool
Authors: Fabian Schuh, Peter Conrad
Status: Implemented
Status: Installed
Type: Protocol
Created: 2017-06-05
Discussion: https://bitsharestalk.org/index.php/topic,24322.0.html

View file

@ -2,7 +2,7 @@
BSIP: #019
Title: Introducing profit-sharing/dividends to Bitshares (MPA only)
Authors: [Customminer](https://steemit.com/@cm-steem/)
Status: Rejected
Status: Deferred
Type: Protocol
Created: 2017-06-18
Primary Discussion: https://bitsharestalk.org/index.php/topic,23981.0.html

View file

@ -1,7 +1,7 @@
BSIP: #020
Title: Introducing profit-sharing/dividends to Bitshares (UIA only)
Authors: [Customminer](https://steemit.com/@cm-steem/)
Status: Rejected
Status: Deferred
Type: Protocol
Created: 2017-06-26
Primary Discussion: https://bitsharestalk.org/index.php/topic,23981.0.html

175
bsip-0025.md Normal file
View file

@ -0,0 +1,175 @@
BSIP: 00025
Title: Transaction Flat-Rates with Weighted Rate-Limitation
Authors: Fabian Schuh <Fabian.Schuh@blockchainprojectsbv.com>
Status: Draft
Type: Protocol
Created: 2017-10-16
Worker: T.B.D.
# Abstract
Blockchain technology currently depends upon transaction fees to prevent
spam. These fees suffer all of the known problems with
micro-transactions and prevent blockchains from being used for low-value
transactions, massive trading and high-rate market making. Truly
decentralized applications must offer users the *appearance* of free
transactions if they wish to compete with their centralized
alternatives.
This document proposes a protocol upgrade to BitShares to introduce
rate-limitations for *fee-free* transactions. Since the BitShares
blockchain is entitled to be a profitable decentralized autonomous
company (DAC), making use of *fee-free* transactions comes at a
*monthly* fixed cost as well as the option to lock shares away in a
vesting balance in order to increase the standard rate at which users
may interact with the blockchain.
# Motivation
Blockchains are decentralized networks where all transactions are
broadcast to all peers. Every so often a block is produced that includes
some or all of the pending transactions. All blockchains must find a
solution to prevent malicious users from consuming all of the available
network capacity with worthless transactions. These worthless
transactions can prevent other valuable transactions from being
processed and ultimately destroy the network.
The solution adopted by most blockchains thus far is to charge a minimum
transaction fee. A fee worth just a few cents is enough to make
attacking the network expensive and unprofitable. While this approach
solves the spam problem, it introduces new problems.
Market making as well as micro-transactions are a highly competitive
market. Being *decentralized* and *trust-less* alone, does not make the
BitShares blockchain a good competitor when compared to centralized
services.
Despite blockchain transactions being cheaper *technically*, the fee
that is attached to each and every transaction on BitShares results in
some crucial businesses to be unviable, such as **market making** at
scale, where dozens of orders are created (and canceled) continuously,
in order to provide liquidity to the markets.
# Rational
In this proposal, we extend the BitShares fee model to allow
transactions made by accounts to go through without paying a fee. We
require accounts to be lifetime members to harness a **transaction
flat-rate** with certain limits that can be raised by additionally
providing BTS (units of the core asset) in a vesting balance that is
locked away for a certain amount of time, only do be made liquid in
weekly chunks over the whole period.
## Full Reserve vs Fractional Reserve
Let's view a blockchain like an Internet Service Provider (ISP) co-op
which owns all of the cables in the town and can process a maximum
amount of data transmission on those cables at any time. This is called
*the capacity* of the transmission lines. People living in the town can
buy shares in the ISP and obtain the right to utilize a portion of the
available capacity.
The ISP has two choices and can either run a **full reserve** or
**fractional reserve** system.
* Under a full reserve system each user is only allowed a fraction of
the capacity proportional to her shares. Because not everyone uses
the Internet at the same time, the town's network would be significantly
underutilized.
* Under a fractional reserve system the individual users could utilize
more date rate than they are entitled to at any given point in time so
long as not everyone uses the Internet at the same time.
The problem with operating a fractional reserve is that congestion
occurs anytime too many people wish to use the network at the same time.
The ISP needs a way to prioritize transmissions during congested
periods. In the most extreme case, a fully congested network must revert
to a full reserve system.
The challenge is setting the proper fractional reserve ratio or
implement a **dynamic fractional reserve ratio**. Under this model the
blockchain will
automatically adjust the reserve ratio for the network during times of
congestion. The blockchain will set a target utilization that leaves
enough headroom for short term surges in demand. Any time the surges
are sustained the blockchain reduces the maximum rate-per-share.
When a surge is over and there is surplus capacity the blockchain can
slowly increase the rate-per-share.
If the time window for this control cycle is stretched too far then the
reserve ratio will not adjust fast enough to respond to short-term
surges, if the window is too short then clustering usage will have too
big of an impact on normal users.
In our estimate it should be sufficient to measure the average weekly
transaction rate usage of users. This parameter will be changeable by
the BitShares committee. The advantage with this approach is, that the
BitShares committee can define whether they prefer a dynamic fractional
reserve, where occasional uses may transact more often within a very
short period of time, or a simple and static method, where professional
users get an easy picture of how many transactions they may produce in a
certain amount of time.
## Flat-Rate Model
In recent years, ISP providers have seen a shift in their own economics
leaving the *pay-per-use* (e.g. per minute) service domain where users
paid for a duration they occupied a land-line to go for a
*pay-per-serice* flat-rate model where users paid a fixed fee to enable
a specific service to be used for free within certain conditions (e.g.
data volume). With the improvements in communications technology, land
lines got replaced by fiber which can carry significantly more load.
Thus the flat-rate model makes sense from business perspective.
The same holds true for blockchain technologies. The Graphene framework
is capable of incomparable transaction loads and thus, the individual
transaction may not be tagged with a fee for the profit alone, but
merely to prevent spam. A full reserve system gives value to a
transaction processing capabilities of the blockchain which everyone can
own a share of to prevent spam.
## Flat-Rate with Weighted Rate-Limitation
That said, we here propose a combination of the flat-rate model with a
stake-weighted limitation of transaction rates.
* **Flat-Rate**: A new feature is added to the blockchain that enables
the flat-rate model with a basic transaction rate that can be defined
by the BitShares committee (e.g. 10 transactions per day). This
operation costs a fee and lasts for a committee-parameterized amount
of time (e.g. 30 days). These rates are the same for every single user
that has bought the flat-rate subscription.
* **Stake-Weighting**: Since some users may need more than the basic
amount of transactions per day, power users can increase the
implicitly assumed weight of 1x to a higher value by providing BTS
core tokens in a vesting balance locks them away for as long as the
subscription lasts.
This ultimately gives the option to
* pay a fee for every transaction (current system)
* pay for a flat-rate to transaction for fee within certain conditions
* powerup your account with core tokens to increase fee transaction
rate
# Specifications
* Do not refund order creation fee!
* Replace Annual Fee operation?
# Discussion
Todo
# Summary for Shareholders
Todo
# Copyright
This document is placed in the public domain.
# See Also
1. [Steem Whitepaper](https://steem.io/SteemWhitePaper.pdf)

View file

@ -1,12 +1,12 @@
BSIP: 0026
Title: Refund Order Creation Fee in Originally Paid Asset on Cancel
Authors: Abit More <https://github.com/abitmore>
Status: Draft
Status: Accepted
Type: Protocol
Created: 2017-10-16
Discussion: https://bitsharestalk.org/index.php/topic,25153.0.html
Replaces: 0002
Worker: TBD
Worker: 1.14.69
# Abstract

View file

@ -2,11 +2,11 @@
Title: Asset Issuer Reclaim Fee Pool Funds
Authors: Abit More <https://github.com/abitmore>
Fabian Schuh <Fabian@BitShares.eu>
Status: Draft
Status: Accepted
Type: Protocol
Created: 2017-11-02
Discussion: https://github.com/bitshares/bitshares-core/issues/188
Worker: TBD
Worker: 1.14.70
# Abstract
@ -40,17 +40,28 @@ The `amount` in the structure can only be positive, which means the `from_accoun
## Proposed Changes
* Allow `amount` to be negative;
* When `amount` is negative, `from_account` can only be the issuer;
* When `amount` is negative, deduct the absolute amount from the asset's fee pool and add it to the issuer's balance.
We propose to add a new operation `asset_claim_pool_operation` that allows to claim CORE asset (BTS) from the fee pool.
```
struct asset_claim_pool_operation : public base_operation
{
asset fee;
account_id_type issuer;
asset_id_type asset_id; /// fee.asset_id must != asset_id
asset amount_to_claim; /// core asset
extensions_type extensions;
};
```
We've decided to add a new operation in order to no modify existing behavior.
# Discussion
The operation fee for `asset_fund_fee_pool_operation ` should be no less than `transfer_operation`.
The operation fee for `asset_claim_pool_operation ` should be no less than `transfer_operation`.
# Summary for Shareholders
[to be added]
We here propose the addition of a new operation that allows to claim fees from the fee pool. Since the fee pools are pre-filled with an initial amount from the asset creation fee, this feature is useful for those that do not desire to use the fee pool.
# Copyright

97
bsip-0029.md Normal file
View file

@ -0,0 +1,97 @@
BSIP: 0029
Title: Asset issue change to require owner authority
Authors: Fabian Schuh <Fabian.Schuh@blockchainprojectsbv.com>
Status: Accepted
Type: Protocol
Created: 2018-01-28
Discussion: https://github.com/bitshares/bitshares-core/issues/199
Worker: 1.14.81
# Abstract
With the current design, the issuer of an asset can be changed with the
*active authority* alone. However, this authority is also required for
issuing new units of an asset/token. If this process wants to be
automated, an active key needs to be stored on an internet-connected
device. If compromised, an attacker can easily move the asset under his
control with no way to back.
This proposal comes with two changes to the protocol:
1. The current behavior of changing an assets' parameters will no longer
allow to change the issuer.
2. A new operation is introduced that allows to change the issuer of an
asset but requires the owner authority of the issuer to sign that
transaction.
# Motivation
Improve asset security.
# Rational
Assets should not be at risk while automating issuing of new units.
# Specifications
## Current Design and Implementation
Currently, any asset can be updated with `asset_update_operation`. This
operation contains an optional `new_issuer` that changes the issuer of
the asset.
## Proposed Changes
# `asset_update_operation`
The existing `asset_update_operation` will be modified in such that it
no longer allows the user of `new_issuer` after a hard fork.
# `asset_update_issuer_operation`
A new operation is added with the following construction
```
struct asset_update_issuer_operation : public base_operation
{
struct fee_parameters_type {uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
account_id_type issuer;
asset_id_type asset_to_update;
account_id_type new_issuer;
extensions_type extensions;
account_id_type fee_payer()const { return issuer; }
void validate()const;
void get_required_owner_authorities( flat_set<account_id_type>& a )const
{ a.insert( issuer ); }
void get_required_active_authorities( flat_set<account_id_type>& a )const
{ }
};
```
This new operation merely allows to change the issuer of an asset and
requires the owner authority (of the issuer account) to sign the
transaction.
# Summary for Shareholders
We here propose the addition of a new operation that improves security
of assets with respect to updating the issuer. This closes a long
existing problem that makes running automated issuing of units a
security issue since an attacker that obtains the keys can obtain full
control of an asset indefinitely. This proposal changes this behavior
and requires the owner to sign such change of issuer.
# Copyright
This document is placed in the public domain.
# Sponsoring
This worker proposal is proudly presented and sponsored by [Blockchain Projects BV](http://blockchainprojectsbv.com).

71
bsip-0030.md Normal file
View file

@ -0,0 +1,71 @@
BSIP: 0030
Title: Always Allow Increasing Collateral Ratio If Debt Not Increased
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/583,
https://github.com/bitshares/bitshares-core/issues/672
Replaces: -
Worker: 1.14.91
# Abstract
Currently, when a short position's collateral ratio is below MCR (a parameter
in price feed: `maintenance_collateral_ratio`) but is not completely filled
immediately due to a lack of enough volume on the opposite side of the market,
it will hang in the market and be waiting for being margin called.
The owner then can adjust the order's collateral ratio **only if**
* to close the position, or
* the new collateral ratio is above MCR, or
* the call order get completely filled (margin called) immediately.
While this prevents shorters from maliciously reducing collateral ratio (to
increase possibility of black swan event), it also prevents shorters from
slightly increasing collateral ratio (to decrease possibility of black swan
event).
This BSIP proposes a mechanism to improve this situation.
# Motivation
Make the exchange system more user-friendly.
# Rationale
The ecosystem would get benefit if shorters are allowed to reduce risks to
themselves while reducing risks to the system at same time.
Current rules are a bit too strict, which can be loosed to:
A shorter can adjust the position's collateral ratio **only if**
* to close the position, or
* the new collateral ratio is above MCR, or
* the call order get completely filled (margin called) immediately, or
* **the new ratio is higher than old ratio and debt is not increased**
# Specifications
In `do_apply()` function of `call_order_update_evaluator` class, if
finally found the call order still in margin call territory,
* don't throw an exception if `call_obj->collateralization()` is reduced, and
* require `delta_debt` of `call_order_update_operation` to be non-positive.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/583
* https://github.com/bitshares/bitshares-core/issues/672
* https://bitsharestalk.org/index.php?topic=25926.0

65
bsip-0031.md Normal file
View file

@ -0,0 +1,65 @@
BSIP: 0031
Title: Update Short Position's Margin Call Price After Partially Called Or Settled
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/343,
https://github.com/bitshares/bitshares-core/issues/649
Replaces: -
Worker: 1.14.92
# Abstract
Currently, when a short position get partially called or settled, the call
price won't change, that said, even if its actual collateral ratio is higher
than others, higher than minimum required, it will still be selling collateral
at a low price, taking precedence over other short positions.
This behavior is causing several issues:
* it's somehow unfair, thus brought bad experience to shorters, and
* it prevents black swan event from being triggered in time when needed,
because the collateral ratio of the 2nd even overall short positions may
be too low but not being checked, thus risks the pegging system.
This BSIP proposes a mechanism to improve this situation.
# Motivation
Make the exchange system more user-friendly.
# Rationale
To attract more users, the system should be fair, should be well balanced.
It's common sense that short positions with least collateral ratio should
get margin called first. This can be achieved if always update the margin
call price after every fill.
# Specifications
In `fill_order( const call_order_object& ...)` function of `database` class,
update `call_price` field of `call_order_object` after debt or collateral
changed to a non-zero value.
In addtion, after `call_price` get updated, the iterators initialized with
`by_price` index may be invalidated, so need to review / revise involved code,
E.G. `check_call_orders(...)` function of `database` class.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/343
* https://github.com/bitshares/bitshares-core/issues/649
* https://bitsharestalk.org/index.php?topic=25926.0

104
bsip-0032.md Normal file
View file

@ -0,0 +1,104 @@
BSIP: 0032
Title: Always Match Orders At Maker Price
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/338
Replaces: -
Worker: 1.14.93
# Abstract
Currently, under most circumstances, when matching two orders, the maker price
will be used to calculate how much each order will pay and receive.
However, when matching a taker limit order with a maker margin call order,
the taker price is being used.
This BSIP proposes a principle: always match orders at maker price.
# Motivation
Generally, the order that is placed earlier (the maker) sets a price,
another order that is placed later (the taker) accepts the price, thus a match,
two orders pay to each other at that price.
Take the pure limit order matching mechanism in BitShares as an example:
If one person (A) placed a limit
order to sell 100 BTS at 0.1 USD per BTS, another person (B) then placed a new
limit order to buy 100 BTS at 0.105 USD per BTS, the two orders will match at
0.1 USD per BTS, so A will pay 100 BTS and get 10 USD, B will pay 10 USD and
get 100 BTS.
However, in BitShares, when matching a taker limit order with a maker margin
call order, the taker price is being used.
For example, if trader A's margin call order is
selling 100 BTS at no less than 0.1 USD per BTS, then trader B placed an order
that buys 100 BTS at 0.105 USD per BTS, the two order will match at 0.105 USD
per BTS, so A will pay 100 BTS and get 10.5 USD, B will pay 10.5 USD and get
100 BTS.
While not strictly a bug, this behavior is unexpected and irritating for users.
# Rationale
Matching orders at the maker price, with margin calls being inlined in the
order book, is an easy to understand rule and matches user expectations,
see [bitshares-core
issue #338](https://github.com/bitshares/bitshares-core/issues/338).
There is a parameter in price feed named MSSR, which stands for "maximum short
squeeze ratio". Maker price of margin call orders is MSSP, which stands for
"maximum short squeeze price", is calculated as `feed_price / MSSR`.
Note: `feed_price` here is in terms of debt/collateral, aka "how much debt per
collateral".
Currently a black swan event will occur when the call order with least
collateral ratio is going to be matched below 100% collateral ratio price
(name it `100CRP`). Because the call order will be matched with incoming limit
order at limit order's price (taker price),
which can be higher or lower than 100CRP, so even if MSSP is below 100CRP,
an incoming taker limit order may or may not trigger a black swan.
So it makes sense to check if a black swan event will occur every time when a
limit order is created.
After the behavior changed to always match at maker price, when MSSP is below
100CRP, an incoming taker limit order will always trigger a black swan event.
So it makes sense to trigger the black swan event when MSSP is below 100CRP
rather than waiting for an incoming limit order. That means it's no longer
needed to check for black swan event when a limit order is created.
Since checking for black swan event is somehow expensive, we'll gain a side
benefit on performance with the change.
# Specifications
Matching between a limit order and a call order is done in
`check_call_orders(...)` function of `database` class, price of limit order
is always used. It need to be changed to use MSSP when the call order is maker.
When triggering a black swan event when MSSP is below 100CRP,
sometimes the short
position with least collateral ratio may still have more than 100% collateral
ratio. In this case, the global settlement price is 100CRP but not the actual
collateral ratio of the short position with least collateral ratio.
This is current behavior, it's fair, no need to change.
# Discussion
It might seem unfair on the shorter to match at MSSP even if the incoming order
specifies a better price. However, in a rationally acting market users will not,
in the presence of margin calls, create limit orders below the MSSP.
Effectively the new rule doesn't change this situation.
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/338
* https://bitsharestalk.org/index.php?topic=25926.0

136
bsip-0033.md Normal file
View file

@ -0,0 +1,136 @@
BSIP: 0033
Title: Maker Orders With Better Prices Take Precedence
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-17
Discussion: https://github.com/bitshares/bitshares-core/issues/625,
https://github.com/bitshares/bitshares-core/issues/453
Replaces: -
Worker: 1.14.94
# Abstract
Currently, in BitShares, under certian circumstances, a taker order may be
matched with a maker order which is not "on the top" of the order book.
This behavior is unexpected and irritating for users.
This BSIP proposes a principle: always match taker orders with maker orders
with the best prices (aka on the top of the order book) first.
# Motivation
As expected, when matching taker limit orders with maker limit orders, the maker
limit orders with better prices will always be matched first.
For example, if trader A has a limit order selling 100 BTS at
0.1 USD per BTS, trader B has a limit order selling 100 BTS at 0.09 USD per BTS,
which means B's limit order has a better price for the opposite side to buy.
Now if trader C placed an order that buys 10 BTS at 0.105 USD per BTS, B's
limit order will take precedence, A's limit order won't be matched.
However, when there are (maker) margin call orders in the market which have met
the requirements that to be matched (able to be margin called), they always
take precedence over the (maker) limit orders on the same side, no matter
whether the limit orders provided better price.
For example, if trader A's margin call order is selling 100 BTS at no less than
0.1 USD per BTS, trader B has a limit order selling 100 BTS at 0.09 USD per BTS,
which means B's limit order has a better price for the opposite side to buy.
Now if trader C placed an order that buys 10 BTS at 0.105 USD per BTS, A's
margin call order will take precedence, B's limit order won't be matched. That
means C is forced to "buy high" when have chance to "buy low", which is
unexpected.
Users have been confused by this behavior, as discussed in [bitshares-core
issue #625](https://github.com/bitshares/bitshares-core/issues/625) and other
threads.
Another scenario is described in [Bitshares-core
issue #453](https://github.com/bitshares/bitshares-core/issues/453)
that sometimes a taker margin call order may be matched with a maker limit order
which is not on the top of the order book. This can be seen as a bug.
# Rationale
Always matching taker order (e.g. a buy) with a maker order which offered best
price (aka lowest ask), is a simpler rule which most users would understand
easily.
There is a parameter in price feed named MSSR, which stands for "maximum short
squeeze ratio". Maker price of margin call orders is MSSP, which stands for
"maximum short squeeze price", is calculated as `feed_price / MSSR`.
Note: `feed_price` here is in terms of debt/collateral, aka "how much debt per
collateral".
That said, the price that margin call orders are offering is MSSP. The prices
those limit orders are offering are the limit prices.
When placing a limit (e.g. buy) order with a price beyond the lowest sell,
the order is expected to "walk the book", matching each order on the opposite
side in turn, at that order's price, until the new limit order is completely
filled, or there is no more sell order matching its price.
To meet the expectation,
* firstly, we need to match the limit buy order with the limit sell orders
whose prices are lower than MSSP and prices can match the new order;
* then, if the new limit buy order hasn't been completely filled, match it with
the margin calls if MSSP can match the new order's price;
* then, if the new limit buy order still hasn't been completely filled, match it
with the rest sell orders until it's completely filled or no more sell order
matching its price
# Specifications
## Matching a taker limit order
New limit order is being processed in `apply_order(...)` function of `database`
class.
Currently, in the function, firstly call orders will be checked and matched.
After that, limit orders on the opposite side will be checked and matched.
Need to change the logic to:
1. firstly, sort the limit orders on the opposite by `price`, best price first,
end at MSSP; check them one by one, calls `match(...)` function until the
return value is not `2` which means the new order is completely filled;
2. if reach the end (MSSP), which means the new order is still unfilled,
call `check_call_orders(..)` function or an equivalent;
3. check if `new_order_object` still exist, if yes, redo step one but set the
maximum possible price of the market as end price.
## Matching taker margin call orders
For [bitshares-core
issue #453](https://github.com/bitshares/bitshares-core/issues/453),
in `check_call_orders(...)` function of `database` class,
iterator `limit_itr` will move forward when variable `filled_limit` is `true`.
`filled_limit` will be set to `true` when a limit order get completely filled.
However, since `filled_limit` is declared out of the `while` block,
it doesn't get reset to `false` after `limit_itr` moved forward. That means
after the first limit order get completedly filled, `filled_limit` will always
be `true`, so `limit_itr` will always move forward no matter whether *current*
limit order got completedly filled, so a taker call order may match
with a limit order that is not on the top of the order book.
To fix this, need to change the code to make sure `limit_itr` always references
the limit order on the top of the order book when dereferencing.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/625
* https://github.com/bitshares/bitshares-core/issues/453
* https://bitsharestalk.org/index.php?topic=25926.0

104
bsip-0034.md Normal file
View file

@ -0,0 +1,104 @@
BSIP: 0034
Title: Always Trigger Margin Call When Call Price Above Or At Price Feed
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-18
Discussion: https://github.com/bitshares/bitshares-core/issues/606
Replaces: -
Worker: 1.14.95
# Abstract
Currently, in BitShares, a short position may be margin called only when both
two requirements are met:
* call price is above or equal to median price feed
* no limit order on the book is buying collateral with price higher than the
short position's call price
This behavior has led to certain confusion and anger among market participants.
This BSIP proposes a new behavior to improve the situation: drop the second
requirement, trigger margin call when the first requirement is met.
# Motivation
To avoid ambiguity, in this article, all prices are in terms of
`debt asset / collateral asset`, aka how much debt asset per collateral
asset. A bid is an order to buy collateral asset with debt asset.
Generally, a short position may be margin called when its collateral ratio is
below or equal to maintenance collateral ratio (MCR).
However, to calculate collateral ratio, a fair collateral price is needed.
In BitShares, there are two data sources can be used to decide the fair
collateral price:
* the internal market
* the price feeds
Currently, both data sources are used. Specifically, collateral price is decided
as the higher one between the highest bid price on the internal market and the
median price feed. That said, when a short position's collateral ratio has
fallen to below or equal to MCR according to median price feed (in this case,
call price of the short position is above or equal to median price feed), if
there is a bid on the market with high price, the short position won't be margin
called.
This mechanism has led to certain confusion and anger among market participants.
* there are often orders with overlapping price on the book but didn't fill
* there are often short positions selling collaterals with low prices, but
traders are unable to buy at those prices
* it often causes borrowers to sell collaterals at a low price when have chances
to sell at higher price
* market manipulators / arbitrage traders have more chances to force borrowers
to sell collaterals at lower price
This BSIP effectively proposes a new behavior: derive the fair collateral price
only from price feeds.
# Rationale
Since price feeds are provided by a set of chosen producers, the median price
feed is usually considered trustworthy. On the other hand, instant market
price is not as reliable, especially for the markets with poor depth, so it's
a rather limited supplement for calculating collateral price.
At this moment, changing the rule to only use median price feed will clear away
the confusion the end users may have, while still keeping the derived collateral
price fair to an extent.
After this change is done, placing a new limit order will no longer trigger a
margin call, cancelling a limit order or expiring a limit order will no longer
trigger a margin call as well, that means we don't need to check for new margin
calls nor black swan events in those scenarios, so we'll gain a side benefit on
performance.
# Specifications
In `check_call_orders(...)` function of `database` class, when matching a call
order with a limit order, there is a check:
`if( match_price > ~call_itr->call_price )`, when the result is `true`,
processing will be ended and `margin_called` will be returned.
Need to skip the check and the following `return` action.
In `do_apply(...)` function of `limit_order_cancel_evaluator` class, and
similar code blocks after a limit order object is removed, no longer need to
call `check_call_orders(...)` function of `database` class.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/606
* https://bitsharestalk.org/index.php?topic=25926.0

488
bsip-0035.md Normal file
View file

@ -0,0 +1,488 @@
BSIP: 0035
Title: Mitigate Rounding Issue On Order Matching
Author: Abit More <https://github.com/abitmore>
Status: Accepted
Type: Protocol
Created: 2018-02-19
Discussion: https://github.com/bitshares/bitshares-core/issues/132,
https://github.com/bitshares/bitshares-core/issues/184,
https://github.com/bitshares/bitshares-core/issues/342
Replaces: -
Worker: 1.14.96
# Abstract
Under some circumstances, when two orders get matched, due to rounding,
one order may be paying more than enough, even paying something but receiving
nothing. This looks unfair.
This BSIP proposes an overall mechanism to mitigate rounding issue when matching
orders and avoid something-for-nothing issue completely.
This BSIP also sets two principles for order matching:
* never pay more than enough, and
* something-for-nothing shouldn't happen.
# Motivation
There are mechanisms in the system to try to avoid something-for-nothing issue,
however, not all scenarios are well-handled, see [bitshares-core
issue #184](https://github.com/bitshares/bitshares-core/issues/184) for example.
Other than that, rounding issue occurs frequently and has led to a lot of
confusion among market participants, see [bitshares-core
issue #342](https://github.com/bitshares/bitshares-core/issues/342) for example.
# Rationale
## Amounts, Prices and Rounding
Amounts in the system are integers with per-asset fixed precisions.
The minimum positive amount of an asset is called one Satoshi.
Prices in the system are rational numbers, which are expressed as
`base_amount / quote_amount` (precisions are omitted here).
To calculate how much amount of asset B is equivalent to some amount of
asset A, need to calculate `amount_of_a * a_to_b_price` which is
`amount_of_a * b_amount_in_price / a_amount_in_price`. The accurate result
of this formula is a rational number. To convert it to the final result which
is an amount, which is an integer, may need to round.
## Order Matching
An order means someone is willing to give out some amount of asset X expecting
to get some amount of asset Y. The ratio between the two assets is the price of
the order. The price can be expressed as either `x_amount / y_amount` or
`y_amount / x_amount`, when we know which amount in the price is of which asset,
the two expressions are equivalent. The amount of asset X is known and fixed.
In a market, E.G. the X:Y market, some people are selling X for Y, some people
are selling Y for X (or say buying X with Y). Orders are classified by type
(buy or sell), then ordered by price. For each type, the order offering the
best price is on the top. So, in every market there may be a top buy order and
a top sell order, name them highest bid and lowest ask, so there is
a highest bid price (in terms of `asset X amount / asset Y amount`),
and a lowest ask price (in terms of `asset X amount / asset Y amount` as well).
When the highest bid price is higher or equal to the lowest ask price, the two
top orders can be matched with each other.
## The Match Price
In a continuous trading market, orders are placed one by one, when comparing
every two orders, it's deterministic that one order is placed earlier than the
other.
In BitShares, it doesn't mean that the transaction that contains the first
order is signed before the transaction contains the second, but means that
the first order is processed earlier than the second in the witness node that
produced the block that contains the second order.
When two orders get matched, the one placed earlier is maker, the other one
is taker. Say, the maker provides an offer, the taker accept the offer.
So, when calculating who will get how much, we use the maker order's price,
aka maker price, as the match price.
## The Need for Compromise
When matching two orders, due to rounding, usually we're unable to completely
satisfy both parties.
Here is an example mentioned in the 4th comment of [bitshares-core
issue #132](https://github.com/bitshares/bitshares-core/issues/132):
Alice's order: Sell CORE at $3 / 8, balance 1000000 CORE
Bob's order: Buy CORE at $19 / 50, balance $10
Both assets have precision of 1, i.e. the order balances are
1000000 CORE-satoshis and 10 USD-satoshis repectively.
Alice is selling at $3/8 CORE = $0.375 / CORE and Bob is buying at
$19 / 50 CORE = $0.38, so based on the price, Alice and Bob should match.
Bob's $10 / $0.38 ~ 26.3. So 26.3 is the fewest CORE he is willing to accept
(assuming that the meaning of "price" is "the least favorable exchange rate
a party is willing to accept in trade"). Combined with the design restriction
that satoshis are indivisible, in practice this means Bob will only accept 27
or more CORE for his $10.
But $10 / 27 gives a price smaller than $0.370 and $0.371, which is smaller
than Alice's sale price of $0.375. So neither party can fill this offer.
We need to come to a compromise.
## The Possible Solutions
There are some possible solutions listed in the 5th comment of [bitshares-core
issue #132](https://github.com/bitshares/bitshares-core/issues/132):
- (a) Fill someone at a less favorable exchange rate than the price they
specified in their order. Downside: This violates the above definition of
price; i.e. if a user enters a price intending the system to never sell below
that price in any circumstance, the system will not always behave in a way
which fulfills that user intent.
- (b) Keep both orders on the books. Downside: This complicates the matching
algorithm, as now Alice might be able to match an order behind Bob's order.
Naive implementation would have potentially unbounded matching complexity;
a more clever implementation might be possible but would require substantial
design and testing effort.
- (c) Cancel an order. This is complicated by the fact that an order such as
a margin call cannot be cancelled. Downside: When there are margin calls
happening, it seems perverse to delete a large order that's willing to fill
them just because the lead margin call happens to fall in a narrow window
which causes a rounding issue. Also, orders cancelled by this mechanism
cannot be refunded. Otherwise an attacker who wants to consume
a lot of memory on all nodes could create a large number of orders, then
trigger this case to cancel them all, getting their investment in deferred
cancellation fees back without paying the cancel op's per-order fee as
intended.
- (d) Require all orders to use the same denominator. Altcoin exchanges and
many real-world markets like the stock market solve this problem by specifying
one asset as the denominator asset, specifying a "tick" which is the smallest
unit of price precision, and requiring all prices to conform.
Downside: Complicates the implementation of flipped market UI, may require
re-working part of market GUI, reduces user flexibility, new asset fields
required to specify precision, if `n` assets exist then `O(n^2)` markets
could exist and we need to figure out how to determine the precision
requirement for all of them.
## The Chosen Solution
Current code actually implemented (a) in the first place: when matching two
orders, if there is a rounding issue, the order with smaller volume will be
filled at a less favorable price. It's the least bad compromise since it has
the most efficiency (highest traded volume while not hard to implement) among
the solutions.
The algorithm can be described as follows (sample code is
[here](https://github.com/bitshares/bitshares-core/blob/2.0.171105a/libraries/chain/db_market.cpp#L311-L324)):
Assuming the maker order is selling amount `X` of asset A, with price
`maker_price = maker_b_amount / maker_a_amount`; assuming the taker is buying
asset A with amount `Y` of asset B, with price
`taker_price = taker_b_amount / taker_a_amount`. Anyway, since the two orders
will be matched at maker price, the taker price doesn't matter here as long
as it's higher than or equal to maker price. Note: currently all limit orders
are implemented as sell limit orders, so in the example, the taker order can
only specify amount of asset B but not amount of asset A.
Now compare `X * maker_price` with `Y`. To be accurate (avoid rounding),
compare `X' = X * maker_b_amount` with `Y' = Y * maker_a_amount`.
* The best scenario is when `X' == Y'`, which means both orders can be
completely filled at `maker_price`.
* If `X' < Y'`, it means the maker order can be completely filled but the
taker order can't, aka the maker order is smaller.
In this case, maker pay amount `X` of asset A to taker, taker pay amount
`Y" = round_down( X' / maker_a_amount )` of asset B to maker.
Note: due to rounded down, it's possible that `Y"` is smaller than the
rational number
`X * maker_price`, which means `Y" / X` may be lower than `maker_price`,
that said, the maker order may has been filled at a less favorable price.
* If `X' > Y'`, it means the taker order can be completely filled but the
maker order can't, aka the taker order is smaller.
In this case, taker pay amount `Y` of asset B to maker, maker pay amount
`X" = round_down( Y' / maker_b_amount )` of asset A to taker.
Note: due to rounded down, it's possible that `X"` is smaller than the
rational number
`Y / taker_price`, which means `Y / X"` may be higher than `taker_price`,
that said, the taker order may has been filled at a less favorable price.
## Issues With The Chosen Solution
### The Something-for-nothing Issue
When filling a small order at a less favorable price, the receiving
amount is often rounded down to zero, thus causes the something-for-nothing
issue. Current code tried to solve the issue by cancelling the smaller order
when it would receive nothing, but only applied this rule in a few senarios
(the processed parties won't be paying something for nothing):
* when matching two limit orders, processed the maker
* when matching a limit order with a call order, processed the call order
* when matching a settle order with a call order, processed the call order
* when globally settling, processed the call order
Other senarios that need to be processed as well (these to-be-processed parties
may be paying something for nothing in current system):
* when matching two limit orders, process the taker
* when matching a limit order with a call order, process the limit order
* when matching a force settle order with a call order, process the settle order
* when globally settling, process the settlement fund
* when force settling after an asset has been globally settled, paying the force
settle order from global settlement fund, process the settle order
### The Broader Rounding Issue
Something-for-nothing is only a subset of rounding issues, it's the most extreme
one. There are much more scenarios that one of the matched parties would be
paying more than enough, although they're not paying something for nothing
overall. Some scenarios are discussed in [bitshares-core
issue #342](https://github.com/bitshares/bitshares-core/issues/342).
Take a scenario similar to the one described in the 4th comment of
[bitshare-core
issue #132](https://github.com/bitshares/bitshares-core/issues/132) as an
example:
* Alice's order: Sell CORE at `$3 / 80 = $0.0375`, balance `50 CORE`
* Bob's order: Buy CORE at `$19 / 500 = $0.038`, balance `$100`
Current system would process them as follows:
* If Alice's order is maker, use `$3 / 80` as match price; since Alice's order
is smaller, round in favor of Bob's order, so Alice will pay the whole `50
CORE` and get `round_down(50 CORE * $3 / 80 CORE) = round_down($1.6) = $1`,
the effective price would be `$1 / 50 = $0.02`;
* If Bob's order is maker, use `$19 / 500` as match price; since Alice's order
is smaller, round in favor of Bob's order, so Alice will pay the whole `50
CORE` and get `round_down(50 CORE * $19 / 500 CORE = round_down($1.9) = $1`,
the effective price would still be `$1 / 50 = $0.02`.
Both results are far from Alice's desired price `$0.0375`. Actually, according
to Bob's desired price, paying `round_up($1 * 500 CORE / $19) = 27 CORE` would
be enough, then the effective price would be `$1 / 27 = $0.037`, which is
still below Alice's desired price `$0.0375`, but much closer than `$0.02`.
## The Improved Solution Proposed By This BSIP
The detailed rules proposed by this BSIP with new rules highlighted:
* match in favor of taker, or say, match at maker price;
* round the receiving amounts according to rules below.
* When matching two limit orders, round down the receiving amount of the
smaller order,
* **if the smaller order would get nothing, cancel it;**
* **otherwise, calculate the amount that the smaller order would pay as
`round_up(receiving_amount * match_price)`.**
* **After filled both orders, for each remaining order (with a positive
amount remaining), check the remaining amount, if the amount is too small
so the order would receive nothing on next match, cancel the order.**
* When matching a limit order with a call order,
* **if the call order is receiving the whole debt amount, which means it's
smaller and the short position will be closed after the match, round up its
paying amount; otherwise,** round down its paying amount.
* **In the latter case,**
* **if the limit order would receive nothing, cancel it (it's smaller,
so safe to cancel);**
* **otherwise, calculate the amount that the limit order would pay as
`round_up(receiving_amount * match_price)`. After filled both orders,
if the limit order still exists, the remaining amount might be too small,
so cancel it.**
* When matching a settle order with a call order,
* **if the call order is receiving the whole debt amount, which means it's
smaller and the short position will be closed after the match, round up its
paying amount; otherwise,** round down its paying amount.
* **In the latter case,**
* **if the settle order would receive nothing,**
* **if the settle order would be completely filled, cancel it;**
* **otherwise, it means both orders won't be completely filled, which
may due to hitting `maximum_force_settlement_volume`, in this case,
don't fill any of the two orders, and stop matching for this asset at
this block;**
* **otherwise (if the settle order would not receive nothing), calculate
the amount that the settle order would pay as
`round_up(receiving_amount * match_price)`. After filled both orders,
if the settle order still exists,
match the settle order with the call order again. In the new match, either
the settle order will be cancelled due to too small, or we will stop
matching due to hitting `maximum_force_settlement_volume`.**
* **That said, only round up the collateral amount paid by the call order
when it is completely filled, so if the call order still exist after the
match, its collateral ratio won't be lower than before, which means we won't
trigger a black swan event, nor need to check whether a black swan event
would be triggered.**
* When globally settling, **in favor of global settlement fund, round up
collateral amount.**
* When paying a settle order from global settlement fund, for predition
markets, there would be no rounding issue, also no need to deal with
something-for-nothing issue; for other assets, apply rules below:
* if the settling amount is equal to total supply of that asset, pay the
whole remaining settlement fund to the settle order;
* otherwise, in favor of global settlement fund since its volume is bigger,
round down collateral amount. **If the settle order would receive nothing,
raise an exception (aka let the operation fail). Otherwise, calculate the
amount that the settle order would pay as
`round_up(receiving_amount * match_price)`; after filled the order, if there
is still some amount remaining in the order, return it to the owner.**
## Examples Of The Improved Solution
### Example 1
Take the example mentioned in the 4th comment of [bitshares-core
issue #132](https://github.com/bitshares/bitshares-core/issues/132):
* Alice's order: Sell CORE at `$3 / 8 = $0.375`, balance `1000000 CORE`
* Bob's order: Buy CORE at `$19 / 50 = $0.38`, balance `$10`
Process:
* If both orders are limit orders
* If Alice's order is maker, use `$3 / 8` as match price;
since Bob's order is smaller, round in favor of Alice's order,
so Bob will get
`round_down($10 * 8 CORE / $3) = round_down(26.67 CORE) = 26 CORE`,
and Alice will get
`round_up(26 CORE * $3 / 8 CORE) = round_up($9.75) = $10`,
the effective price would be `$10 / 26 CORE = $0.3846`.
* If Bob's order is maker, use `$19 / 50` as match price; since Bob's
order is smaller, round in favor of Alice's order, so Bob will get
`round_down($10 * 50 CORE / $19 = round_down(26.32 CORE) = 26 CORE`,
and Alice will get
`round_up(26 CORE * $19 / 50 CORE) = round_up($9.88) = $10`,
the effective price would still be `$10 / 26 CORE = $0.3846`.
* If Alice's order is a call order, since it's bigger, round in favor of it,
we will get same results.
### Example 2
If we change the example to this:
* Alice's order: Buy CORE at `3 CORE / $8 = 0.375`, balance `$1000000`
* Bob's order: Sell CORE at `19 CORE / $50 = 0.38`, balance `10 CORE`
Process:
* If both orders are limit orders, we get similar results as above.
* If Bob's order is a call order, it should have a debt amount which is an
integer, for example `$26`, then
* Alice would get
* `round_up(26 * 3 / 8) = round_up(9.75) = 10 CORE` as a maker, or
* `round_up(26 * 19 / 50) = round_up(9.88) = 10 CORE` as a taker.
* Bob would get the full debt amount which is `$26`.
* If Bob's order is a call order, but the debt amount is a bit high,
for example `$27`, then Alice would get
* `round_up(27 * 3 / 8) = round_up(10.125) = 11 CORE` as a maker, or
* `round_up(27 * 19 / 50) = round_up(10.26) = 11 CORE` as a taker.
However, since the collateral is only `10 CORE`, this match will fail and
trigger a black swan event.
### Example 3
If we change the example to that one used above:
* Alice's order: Sell CORE at `$3 / 80 = $0.0375`, balance `50 CORE`
* Bob's order: Buy CORE at `$19 / 500 = $0.038`, balance `$100`
Assuming both orders are limit orders, they'll be processed as follows:
* If Alice's order is maker, use `$3 / 80` as match price; since Alice's order
is smaller, round in favor of Bob's order, so Alice will get
`round_down(50 CORE * $3 / 80 CORE) = round_down($1.6) = $1`,
and Bob will get `round_up($1 * 80 CORE / $3) = round_up($26.67) = $27`,
the effective price would be `$1 / 27 = $0.037`;
* If Bob's order is maker, use `$19 / 500` as match price; since Alice's order
is smaller, round in favor of Bob's order, so Alice will get
`round_down(50 CORE * $19 / 500 CORE = round_down($1.9) = $1`,
and Bob will get `round_up($1 * 500 CORE / $19) = round_up($26.3) = $27`,
the effective price would also be `$1 / 27 = $0.037`.
# Specifications
## When Matching Two Limit Orders
### Handling Something-For-Nothing Issue
In `match( const limit_order_object&, OrderType ... )` function of `database`
class, after calculated `usd_receives` which is for the taker,
check if it is zero.
If the answer is `true`, skip filling and see the order is filled, return `1`,
so the order will be cancelled later.
### Handling Rounding Issue
In `match( const limit_order_object&, OrderType ... )` function of `database`
class, after calculated `receives` for the smaller order, if it isn't zero,
calculate `pays` for it as `round_up(receives * match_price)`.
If the smaller order is taker, after filled, even if there is still some amount
remaining in the order, see it as completely filled and set the lowest bit of
return value to `1`.
If the smaller order is maker, since it will be culled when filling,
no need to change the logic.
## When Matching A Limit Order With A Call Order
In `check_call_orders(...)` function of `database` class,
if the call order is smaller, round up `order_receives`,
otherwise round down `order_receives`.
In the latter case,
* if `order_receives` is zero, skip filling and cancel the limit order.
* otherwise, calculate `order_pays` as
`round_up(order_receives * match_price)`, then the limit order will be
either completely filled, or culled due to too small after partially filled.
## When Matching A Settle Order With A Call Order
In `match( const call_order_object&, ... )` function of `database` class,
if the call order is smaller, round up `call_pays`,
otherwise round down `call_pays`.
In the latter case, check if `call_pays` is zero.
* If the answer is `true`,
* if `call_receives` is equal to `settle.balance`,
call `cancel_order(...)` with parameter set to `settle`,
then return a zero-amount collateral asset object;
* otherwise, return a zero-amount collateral asset object directly.
* Otherwise, calculate `call_receives` as `round_up(call_pays * match_price)`,
then fill both orders normally. If the settle order still exists after the
match, it will be processed again later but with different condition.
After returned, need to check the amount of returned asset at where calling the
`match(...)` function, specifically, `clear_expired_orders()` function of
`database` class. If the returned amount is `0`, break out of the `while` loop.
If the settle order is still there and the returned amount is `0`,
label that processing of this asset has completed. Also, in the outer loop,
need to check the label, if found it's completed, process next asset.
## When Globally Settling
In `global_settle_asset(...)` function of `database` class, round up `pays`.
## When Paying A Settle Order From Global Settlement Fund
In `do_apply(...)` function of `asset_settle_evaluator` class,
after calculated `settled_amount` and adjusted it according to the "total
supply" rule, check if it's zero.
If the answer is `true`, and the asset is not a prediction market,
throw a `fc::exception`.
If the answer is `false`, and the asset is not a prediction market,
and `op.amount.amount` is not equal to `mia_dyn.current_supply`,
calculate `pays` as `round_up(settled_amount * bitasset.settlement_price)`,
then, only deduct `pays` from total supply, and refund
`op.amount.amount - pays` to the user.
# Discussion
There is an argument suggests when matching call orders, we should always
round in favour of the call. If a settlement receives 0 collateral as a result,
that's acceptable, because the settlement price is unknown at the time when
settlement is requested, so no guarantee is violated (within the range of
rounding errors). This should keep the collateral > 0 as long as there is
outstanding debt. A counter-argument supports rounding up to 1 Satoshi since
rounding down to zero may break the promise of "every smart coin is backed
by something".
There is an argument says breaking the `min_to_receive` limit is a no-go,
because that's why it's called a "limit order". A counter-argument says
slightly breaking the limit is the least bad compromise.
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/132
* https://github.com/bitshares/bitshares-core/issues/184
* https://github.com/bitshares/bitshares-core/issues/342

73
bsip-0036.md Normal file
View file

@ -0,0 +1,73 @@
BSIP: 0036
Title: Remove expired price feeds on maintenance interval
Author: oxarbitrage <https://github.com/oxarbitrage>
Status: Accepted
Type: Protocol
Created: 2018-02-22
Discussion: https://bitsharestalk.org/index.php?topic=25996.0
Replaces: -
Worker: 1.14.97
# Abstract
Currently, expired bitasset feeds remain in the blockchain forever. The only way to get them erased is if operation `update_feed_producers` is called with new publishers on the asset. At this call, and only at this case, old publisher feeds will be deleted from the blockchain. If this operation never occurs or if it occurs maintaining some or all of the same publishers feeds will not be removed.
Some examples of this are the followings, where we can see feeds from 2015:
- http://open-explorer.io/#/objects/2.4.9 - HKD
- http://open-explorer.io/#/objects/2.4.21 - USD
- http://open-explorer.io/#/objects/2.4.10 - RUB
- etc.
This BSIP proposes a protocol change to remove expired feeds at maintenance time.
# Motivation
Improve performance of the bitshares-core.
# Rationale
The proposed change only affects the feed price when the feed expiration time is increased. This rarely happens, if ever, so in practice the effect on pricing is negligible. The savings in performance however, is not.
# Specifications
As mentioned in the abstract feeds stay in the blockchain forever unless `asset_update_feed_producers_evaluator::do_apply` is called.
The BSIP proposes to remove expired feeds at maintenance time by adding feed cleanup code at `db_main.cpp`.
Solution is not that simple, `asset_update_bitasset_operation` can change `feed_expiration_time` and `minimum_feeds` required for the asset.
If a feed is expired and the `feed_expiration_time` changes, expired feeds may became valid, similar if `minimum_feeds` (required to calculate the median) is increased, older feeds may became valid and used by the core market engine if available.
This scenario actually happened in the past and that is the reason the change will fail unless a hardfork protection is added.
## The proposed solution
Goal is to remove expired feeds in a safe manner. To do this we need to keep current behavior before hardfork date and only remove feeds at maintenance intervals after the hardfork. This will allow the chain to synchronize and start the cleanup at a point where all the feeds are valid, safely being able to remove them an continue clean from that time on.
This a permanent hardfork, code before hardfork date will work one way(current behavior) and after date new code will work different making the feed cleanup at maintenance times.
Feed cleanup code will only be executed after proposed hardfork date, at the first maintenance interval after date old feeds will be removed, node will not be able to use them anymore as they will not be available in the database.
If `asset_update_bitasset_operation` is called before hardfork operation will be normal as it is currently is now.
If `asset_update_bitasset_operation` is called after hardfork and increases the `minimum_feeds` while they are not enough feeds `update_median_feeds()` will set a null feed. This is current `asset_update_bitasset_operation`, no need to make any change in the operation.
# Discussion
https://bitsharestalk.org/index.php?topic=25996.0
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/518
* https://github.com/bitshares/bitshares-core/pull/598

64
bsip-0037.md Normal file
View file

@ -0,0 +1,64 @@
BSIP: 0037
Title: Allow new asset name to end with a number
Author: oxarbitrage <https://github.com/oxarbitrage>
Status: Accepted
Type: Protocol
Created: 2018-02-23
Discussion: https://bitsharestalk.org/index.php?topic=25997.0
Replaces: -
Worker: 1.14.98
# Abstract
Currently, the bitshares-core do not allow asset creation that start or end with a numerical character. Creation of index style assets like `CRYPTO500` are not possible.
This BSIP proposes a protocol change to allow number characters at the end of the created asset name.
# Motivation
Economical, enable more asset names to be created in the exchange.
# Rationale
No valid reason was found until now about why this is not allowed. The creation of index style assets will bring new business to the exchange.
# Specifications
Restriction in asset names are detailed in `asset_ops.cpp`:
```
/**
* Valid symbols can contain [A-Z0-9], and '.'
* They must start with [A, Z]
* They must end with [A, Z]
* They can contain a maximum of one '.'
*/
```
BSIP proposes to change third rule to:
`They must end with [A, Z0-9]`
As file where the changes are needed(`asset_ops.cpp`) do not have access to the database, we are unable to use `head_block_time()` to create the hardfork guard.
The process is more complicated and it is described as follows:(quote from @abit in github ticker: https://github.com/bitshares/bitshares-core/issues/620#issuecomment-364803143):
"To make the change, need to loose the validation code in `asset_ops.cpp`, add a hard fork guard code with original rule to asset_evaluator to make sure no rule change before the hard fork, add corresponding hard fork guard code in proposal_evaluator. After hard fork, those hard fork guard code can be safely removed."
# Discussion
https://bitsharestalk.org/index.php?topic=25997.0
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/620
* https://github.com/bitshares/bsips/issues/52

89
bsip-1200.md Normal file
View file

@ -0,0 +1,89 @@
BSIP: 1200 (unassigned)
Title: Stealth development, Phase II
Authors: Christopher J. Sanborn <...>
Agorise, Ltd. <Agorise@protonmail.ch>
Status: Draft
Type: Informational
Created: 2018-01-29
Discussion: <https://t.me/Agorise>
## Abstract
To discuss the continued development of Stealth functionality and provide an overview of the following BSIPs which define components of that development.
Component BSIPs: _(Works in progress!!)_
Number | Title | Type | Status
:-----------------:|--------------------------------------------------------------|---------------|--------
[1200](bsip-1200.md) | Stealth development, Phase II — _(this document)_ | Informational | Draft
[1201](bsip-1201.md) | New operations for Confidential Asset (CA) transactions | Protocol | Draft
[1202](bsip-1202.md) | Ring signatures for untraceability of Stealth transactions | Protocol | Draft
[1203](bsip-1203.md) | Blockchain scanning for inbound Stealth transactions | Protocol | Draft
[1204](bsip-1204.md) | Deterministic addresses for Stealth wallets | Informational | Draft
[1205](bsip-1205.md) | Metadata hiding via Garlic Routing and other means | Informational | Draft
## Motivation
The initial phase of Stealth development was proposed and implemented in [BSIP-0008](bsip-0008.md), and is live on the BitShares network. Support for this first round of confidentiality features has been implemented in the CLI wallet, and has also been demonstrated in the UI wallet by Agorise, Ltd., in a code fork not yet integrated into the mainline UI-Wallet code. Utilization of the privacy features remains low, for two reasons: (1) the difficulty of using the CLI wallet for day-to-day activities, and (2) the Stealth feature set thus far, while valuable, does not yet provide a comprehensive privacy solution.
Phase One of Stealth development consisted of the implementation of Confidential Transactions (CT) [[1]](#see-also), which was initially proposed for the Bitcoin network in a paper by Greg Maxwell. CT provides two key features: **value-blinding**, and **stealth addresses**. Value-blinding means that the value amounts of transactions are unknowable except to the parties of the transaction (provided the transaction is sufficiently removed from the operation that initially converted a public balance to a blind balance). Stealth addresses are an address format that the sender can use to derive a "shared secret" public key for which only the recipient can derive a private key, without revealing publicly that the stealth address and the public key used to transmit the funds are related. The use of stealth addresses helps to anonymize transactions, however it creates a burden of communication between the sender and the recipient, who must be made aware of the existence of an inbound transaction.
Stealth addresses also provide partial **unlinkability**, or the inability to "link" balance elements (we'll call them UTXOs for Unspent Transaction Outputs) together to see that they are controlled by the same party. However, wallet implementations may, in order to facilitate discovery by the receiving party, publicly embed the stealth address of the receiving party into the transaction, thus breaking unlinkability and threatening anonymity. Heretofore, no privacy-preserving method has been proposed on this network to enable discovery, other than the sender and receiver being in direct communication off of the blockchain (e.g. sending **transaction receipts**). Furthermore, CT transactions are **traceable**, meaning that a transaction reveals which UTXOs are consumed in the creation of new UTXOs. This has two implications: (1) a transaction history can be constructed, and it may be possible to establish a vary narrow set of originating users who initally "blinded" a previously public balance, thus potentially establishing to a high degree of probability *who* is involved and *how much* value is involved in a particular sequence of transactions, and (2) a user spending a balance consisting of more than one UTXO will of necessity reveal that those UTXOs are controlled by the same party, or "linked," thus again breaking unlinkability.
In what follows we propose methods of enhancing the confidential abilities offered by the BitShares network by integrating specific solutions to achieve unlinkability, untraceability, and automated transaction discovery by the receiving party. Additionally, since BitShares is a multi-asset blockchain, we propse to adopt Confidential Assets (CA). CA is an extension to CT that hides not just the values of a transaction, but also the assets involved. Further, we propose various convenience and user-experience enhancements to ease the backup burden placed on users and reduce the chances of lost funds. Lastly, we propose an ongoing effort to harden wallets and p2p nodes against metadata leaks.
## Rationale
We view "Stealth" as a constellation of features providing robust privacy and "grandma-friendly" usability and reliability. A user of Stealth transactions should be reasonably assured that their privacy is complete, and not underminable by easy-to-make procedural mistakes.
### "Blinded" vs. "Stealth"
To facilitate an orderly, confusion-free upgrade, and to differentiate between Phase One and Phase Two functionality, we have adopted the convention of referring to the existing CT transactions that only blind transaction amounts as **Blind Transfers**, and the proposed more fully-private transaction features as **Stealth Transfers**. The names convey that Stealth Transfers will be more private than Blind Transfers (although some user education will be needed on this). Upon maturity of the Stealth feature set, the utilization of Blind transfers should be retired.
### Specific features and enhancements
Specific features and enhancments proposed by this and associated BSIPs are as follows:
#### Asset Hiding
Confidential Assets (CA) [[2]](#see-also) extends Confidential Transactions (CT) to include asset hiding. Existing CT functionality can hide the value amount of a transaction, but the asset being transfered is publically visible in the transaction format. Since BitShares is a multi-asset blockchain, it would be of value to hide not just the value but also the identity of the asset involved. CA provides a method to do this. The proposal to implement CA on the BitShares network is in [BSIP-1201](bsip-1201.md).
#### Unlinkability and Untraceability
While BitShares is an account-based blockchain, similar e.g. to Ethereum and others, Stealth operations on the BitShares network follow a UTXO model, similar to BitCoin and related blockchains. UTXOs (Unspent Transaction Outputs) are discrete balances held in the "outputs" of transactions. A user's total balance is composed of the sum total of all UTXOs that fall under their control. A Stealth transaction consists of the destruction of one or more existing UTXOs and the creation of one or more new UTXOs. CT guarantees that the values of the outputs are unknowable (except for deductions that can be made if one happens to know, precisely or approximately, the values of the inputs). However, the current implementation of CT provides no privacy regarding *which* UTXOs are used as inputs to the transaction. Because of this, current CT transactions are fundamentally *traceable* and *linkable*. **Traceable** means that a history of prior inputs can be constructed, "tracing" where an output came from, and if the history is short enough (refering to how many prior UTXOs one must traverse before finding an operation where a public balance was converted to a blind balance) then it may be possible to reveal involved parties and estimate transaction values. **Linkability** refers to the ability to show that a set of UTXOs are controlled by the same party, or that a set of disparate transactions were conducted by the same party. Although the latter is well protected due to non-reuse of public keys, the former is implicated by CT. A CT transaction consuming multiple inputs necessarily reveals that all inputs are controlled by the same party, and if anonymity has been compromised for one input UTXO, then it is effectively compromised for all of them.
To solve the problems of linkability and traceability, we propose to take a page from the Monero project. The Monero network uses a system of **ring signatures** to create a high degree of plausible-deniability as regards who exectuted any particular transaction [[3]](#see-also). A ring signature is an *n* of *m* signature scheme wherein the set of inputs to a transaction is much larger than the set of inputs actually consumed by the transaction, and the signature provided guarantees that the correct party signed the transaction, but makes it impossible to know *which* party is the signer. With a Monero-like ring signature scheme, it is no longer possible to determine *which* UTXOs are "spent" vs. "unspent" (a mechanism to prevent double-spends does exist, of course). This means that it is no longer possible to construct an exclusive directed graph if inputs to outputs, thus providing untraceability and unlinkability. (More specifically, the set of inputs that *might* be in the history of a particular output rapidly becomes so large that it is no longer possible to say with significant probability that any particular party was involved.)
We propose and discuss the implementation of ring signatures for Stealth transactions in [BSIP-1202](bsip-1202.md).
#### Scanning for Inbound Stealth Transactions
The current implementation of CT requires that a sender must communicate to the recipient a "transaction receipt" that contains, in encrypted form, data that the recipient needs in order to take possession of a transaction output. This is burdensome, and implies a high risk of lost funds as a result of lost or uncommunicated receipts.
We propose automated, privacy-preserving methods of scanning for inbound transactions in [BSIP-1203](bsip-1203.md).
#### Backups of Stealth Balances
In [BSIP-1204](bsip-1204.md) we propose standardized derivation of Stealth addresses to enable backup seeds or brainkeys to be used to securely back up a Stealth account prior to first use, enabling recovery in the event of a lost or corrupted hot wallet.
#### Metadata Hiding
Lastly, in [BSIP-1205](bsip-1205.md), we propose methods of hardening wallets against eavesdropping and timing attacks, so that usage patterns and the method used to communicate with the peer-to-peer network do not compromise user privacy. (As an example, a naive wallet might check a users balance by querying the status of a set UTXOs under the user's control, revealing immediately to the network that a given set of UTXOs are "of interest" to a single party.)
## Specifications
## Discussion
## Summary for Shareholders
## Copyright
This document is placed in the public domain.
## See Also
* Phase One of Stealth development: [BSIP-0008](bsip-0008.md)
[1] Confidential Transactions (Greg Maxwell) - https://people.xiph.org/~greg/confidential_values.txt
[2] Confidential Assets (Poelstra, et. al.) - https://blockstream.com/bitcoin17-final41.pdf
[3] Ring Confidential Transactions (Shen Noether) - https://eprint.iacr.org/2015/1098

106
bsip-1201.md Normal file
View file

@ -0,0 +1,106 @@
BSIP: 1201 (unassigned)
Title: New operations for Confidential Asset (CA) transactions
Authors: Christopher J. Sanborn
Status: Draft
Type: Protocol
Created: 2018-01-29
Discussion: <url>
## Abstract
Confidential Assets (CA) [[2]](#see-also) extends Confidential Transactions (CT) [[1]](#see-also) to include asset hiding. The BitShares network already understands and validates CT transactions, but is not yet capable of validating CA transactions. The transaction format will need minor to moderate updating and the validation routines will likewise need updating. We propose to either (a) update op-code 39, 49, and 41 to be CA capable, or (b) define new opcodes for CA stealth operations. The latter option probably affords a cleaner upgrade path. The old opcodes should then be disfavored for user wallet use.
Confidential Assets is a new, but not un-tested, technology. The Elements Project [[3]](#see-also) maintains an experimental implementation [[4]](#see-also) of CA as a Bitcoin side chain. The code for that project is MIT-licensed and can help guide the implementation of CA in the BitShares ecosystem.
_This BSIP is one of several describing_ [Stealth development, Phase II](bsip-1200.md).
## Motivation
A user maintains value-blinded balances on the BitShares blockchain as a collection of Pedersen commitments, which are EC curve points that obscure their committed values by adding a secret blinding factor times a generator point. By keeping the blinding factor secret, the user keeps their balance secret. Meanwhile, balances can be transferred, subdivided, or combined, provided the sum of blinding factors for all inputs to a transaction are equal to the sum of blinding factors of all outputs of a transaction. A user wishing to un-blind and "claim" a balance contained in a Pedersen commitment may do so by revealing the blinding factor for that commitment, which then allows the network to verify the committed amount and credit it to a public balance.
A commitment C is given mathematically by _C = value * H + blinding_factor * G_, where H and G are separate curve point generators with no known divisor between them. Because there is no known multiple _m_ solving _H = m*G_, the _value_ and _blinding_factor_ quantities are effectively independent, which makes _C_ a firm commitment to _value_.
BitShares is a multi-asset chain. The Pedersen commitments implemented in _Stealth Phase I_ commit only to a value amount, and nothing more. For the network to understand *which* asset is represented by a commitment, a plaintext metadata field is associated with the Graphene object for the commitment, containing the asset ID of the blinded asset. This means that the asset type of an individual blinded balance is publicly knowable.
Confidential Assets (CA) introduces a method for using a commitment to a hash of the asset description as a confounding factor similar to the blinding factor, such that, unless one already knows the asset represented by a particular Pedersen commitment, one cannot determine the asset from inspection alone. Furthermore, amounts of differing assets can be combined in a single transaction, so that the asset IDs of the outputs are not individually knowable. Thus, even by tracing the history of a given commitment, one cannot simply divine the asset type by back-tracing to the point where a public asset was blinded, as the history may implicate multiple asset types. When a user wishes to un-blind an asset, he may do so by providing both the value blinding factors and the asset blinding factors for the commitment, so that the network can confirm the contents thereof.
By allowing commitments of differing assets to be mixed together, we achieve two points for privacy: (1) we increase the available mix-in set for diffusion of transaction history, and (2) we make it more difficult for blockchain analysis to determine which assets are being operated on in any given transaction (the more assets involved in the history of a particular commitment, the greater the uncertainty of what the commitment contains).
## Rationale
### _Asset Tags_ and _Asset Commitments_
The existing value-blinded CT transaction capability includes an explicit **asset ID** in the transaction format, and unspent commitments are associated with an explicit clear-text asset ID in the database. For example, querying the blockchain for commitment "024449...8073" returns a structure containing three defining fields:
Field: | Data (Meaning)
:----------:|----------
commitment: | "0244492ceafc9c3d6fab34b4e2912b360a3276560651451580325f754705758073" |
asset_id: | "1.3.0" (Core asset, BTS)
owner: | (Authority struct specifying public key that must sign)
Under CA, the `asset_id` field would be replaced by `asset_commit` which is a commitment to an **asset tag**. The asset tag, denoted *H<sub>A</sub>*, is a curve point produced by a hashing procedure of some defining description of the asset (for example the `asset_id`, "1.3.0", etc.). The asset commitment, denoted *H*, is the sum of *H<sub>A</sub>* and a blind point, e.g., _H = H<sub>A</sub> + r*G_. Under this scheme, a CA commitment in the database would look similar to:
Field: | Data (Meaning)
:------------:|----------
commitment: | "0244492ceafc9c3d6fab34b4e2912b360a3276560651451580325f754705758073"
asset_commit: | "022b607af588386028a97d6bc4be5caddb432340329bc808ba587c0b92ffb1087c"
owner: | (Authority struct specifying public key that must sign)
As can be seen, casual inspection of the blockchain does not reveal the underlying asset, nor even asset tag, since it is commingled with a blinding factor. The only way to know the asset id would be if the commitment were a direct descendent of an asset-issuance transaction (where a public balance was blinded into a value-asset blind CA commitment). However, once a commitment is involved in a transaction involving inputs of multiple asset types, then uncertainty is introduced in the descendent commitments: the asset type will be _one_ of the parent asset types, but which one is unknowable except to parties that know the blinding factors.
_(TODO: QUESTION: How is it ensured that H<sub>A</sub> is a valid curve point? There must be some kind of nonce increment in the hash procedure to reject non-curve points. Find out.)_
### _Range Proofs_ and _Surjection Proofs_
Since the committed values in the Pedersen commitments are unknowable to parties not privy to the blinding factors, there exists the possibility for a transaction resulting in two or more outputs to encode a negative value in one output and an excess positive value in the others, resulting in inflated (i.e., counterfeit) asset supply. To prevent this, transactions with more than a single output are required to provide a **range proof** for each output, which is a zero-knowledge proof that the committed value is in a finite range between zero and an upper bound that won't risk overflow into negative values. (Values are encoded as 256-bit unsigned integers such that very-large integers "wrap around" and behave as negatives. Range proofs typically prove that a committed amount can be represented in 64-bits or less, affording no risk of overflow.) Under CA, the requirement to provide a range proof remains the same as under CT.
A new requirement in CA is the **asset surjection proof**. Similar to range proofs, ASPs prove that a validity contstraint is met on the blinded asset commitments of the transaction outputs. Specifically, it proves that the asset tags of the outputs match the asset tags of the inputs, without revealing what those tags are or which outputs correspond to which inputs. (TODO: preceding is imprecise.)
(TODO: discuss space requirments of ASPs, since they do add to transaction size. Compared to range proofs already included in CT transactions, however, they are comparatively small, except perhaps in the case of a large number of inputs and outputs in a single transaction.)
## Specifications
We propose to add the following three CA operations to the set of valid operations declared in graphene::chain::operation (chain/protocol/operations.hpp). The new CA operations are shown here side by side with their CT equivalents:
Op-Code | Description | Op-Code | Description
:------:|-------------------------------|------------------|----------------------------------
39 | transfer_to_blind_operation | 49 (placeholder) | transfer_to_ca_blind_operation
40 | blind_transfer_operation | 50 (placeholder) | ca_blind_transfer_operation
41 | transfer_from_blind_operation | 51 (placeholder) | transfer_from_ca_blind_operation
| | | 52 (placeholder) | ct_to_ca_blind_transfer_operation
On the left are CT operations, whose outputs are value-blinded commitments. On the right are the corresponding CA operations, whose outputs are value-and-asset-blinded commitments. Of special note is op 52, which takes value-blinded CT inputs and outputs value-and-asset-blinded outputs. (As an alternative, op 50 could be made flexible enough to accept either CT or CA inputs, if this proves feasible.) As CA is seen as an upgrade to CT, no op-code is here proposed for transferring from CA back to CT, however in the event of market demand such an operation could be coded.
#### Proposed operation: transfer_to_ca_blind_operation (Public to Blind)
#### Proposed operation: ca_blind_transfer_operation (Blinded to Blind)
#### Proposed operation: transfer_from_ca_blind_operation (Blind to Public)
## Discussion
### Compatibility with ring-signature scheme
The Op-Code additions and specifications provided in this document do not conflict with or depend on the details of the ring-signature proposals in [BSIP-1202](bsip-1202.md), as they effect different substructures of the Transaction structure, and therefore both proposals can be implemented independently. This document specifies structures within the Operations vector within a Transaction structure, whereas the ring signature scheme would change the Signatures vector.
(TODO: Check whether preceding is true, i.e. that the operation structure is independent of signature method. If it is not true, include here a discussion of what else might need to be included in the structure, so that a decision can be made as to whether the two features would be best developed in parallel, or whether ring-sigs could be implemented subsequently as an "upgrade" to CA.)
#### Asset surjection and compatibility
TODO: Question: Are Asset-Surjection Proofs compatible with a Ring-Sig scheme? I.e., can a prover who is "accusing" unrelated inputs produce the proof even not knowing the blind factors and asset tags of the unrelated inputs?
## Summary for Shareholders
## Copyright
This document is placed in the public domain.
## See Also
[1] Confidential Transactions (Greg Maxwell) - https://people.xiph.org/~greg/confidential_values.txt
[2] Confidential Assets (Poelstra, et. al.) - https://blockstream.com/bitcoin17-final41.pdf
[3] Elements Project - https://elementsproject.org
[4] Elements Project on GitHub - https://github.com/ElementsProject/elements

103
bsip-1202.md Normal file
View file

@ -0,0 +1,103 @@
BSIP: 1202 (unassigned)
Title: Ring signatures for untraceability of Stealth transactions
Authors: Christopher J. Sanborn
Status: Draft
Type: Protocol
Created: 2018-01-29
Discussion: <url>
## Abstract
Confidential Transactions (CT) [[1]](#see-also), (as implemented by [Phase I](bsip-0008.md) of Stealth development), solves the linkability and value-hiding problems, but not the traceability problem. CT transfers are traceable on the blockchain, meaning that for any given transaction, a history of prior transactions can be determined. If the set of antecedents is large, then there is a great degree of plausible-deniability regarding the origins of the hidden assets. However, if the set is small, it is possible to determine with increasing probability where the assets originated from. A solution to this is to “mix” transaction inputs with unrelated users so as to increase the traceability set. Some privacy blockchains rely on a mechanical mixing or “tumbling” process to increase the traceability set, however this approach has drawbacks. Monero has a very clever scheme of using ring signatures to automatically and randomly mix in unrelated inputs on every transaction, guaranteeing that even newly blinded funds are mixed with with inputs having a rich history. It is proposed, as a component of [Stealth development Phase II](bsip-1200.md), to implement a similar mechanism for BitShares.
## Motivation
Stealth can be thought of as a constellation of privacy-preserving features implemented on (or planned for) the BitShares blockchain. "Privacy" here is a set of specific goals:
* Untraceability
* Unlinkability
* Value/Asset hiding
* Anonymity
Although Confidential Transactions (CT) provides good solutions to unlinkability and value hiding, (which together help but do not fully solve anonymity), the transactions currently supported on the network are fully traceable. This means it is possible generate a history all prior transactions leading up to a particular transaction output, including a set of originating transactions wherein public balances were blinded. For outputs which are "close" to their originating transactions, it may be possible possible to identify a small set of non-anonymous originating actors, and to make estimates of the possible maximum value amount of an output (by assuming it can be no larger than the sum of all originating transactions in its history).
What we seek is a method to make it unknowable *which* prior transaction outputs were consumed in the generation of a new transaction output. Although it seems a tall order (how can a node validate that a sum of inputs balances a set of outputs when it is unknown which inputs are involved?), a solution actually comes in the form of a ring signature protocol developed for the Monero project. <!-- TODO: check specific heritage of this protocol -->
The ring signature strategy in Monero has gone through two major developmental stages. In the first stage, transaction amounts were not blinded (although pseudo-blinding was achieved by composing value transfers from an aggregate of round-number individual transactions). In the second stage, the ring signature authorization protocol was combined with Confidential Transactions to form the RingCT protocol [[2]](#see-also), in which transfers are both value-blinded and untraceable. Since BitShares already implements CT, the adoption of RingCT into BitShares Stealth operations can be seen as an improvement upon an existing feature.
## Rationale
Although BitShares is an account-based blockchain, in which value-transfer operations are a simple transfer of balance from one account to another, Stealth operations on the BitShares blockchain instead follow a **UTXO model**. Stealth transactions produce "**transaction outputs**" (TXOs) which represent individual balance amounts under the control of someone possessing the appropriate secret key. These TXOs are "unspent" (UTXOs) until they are involved in a downstream transaction, at which point they are considered destroyed and no longer spendable. (To partially spend a UTXO, a transaction consuming it would need to produce two outputs: one to the intended recipient, and one back to the sender as "change.")
A transaction in a UTXO-based blockchain is simply a list of inputs (UTXOs which will be destroyed) and a list of outputs (newly-generated UTXOs). Validating such a transaction involves confirming that the value sum of inputs equals the value sum of outputs plus fees, and that appropriate authorization is provided for all inputs.
Because the list of inputs is part of the transaction, all UTXOs have a traceable history.
Ring signatures are a signature scheme in which, for a given set of credentials, a signature is provided proving that at least *one* of the credentials authorized the transaction, but it cannot be determined by a third party *which* credential it was that signed it. Thus ring signatures provide **plausible deniability**. All involved credentialed parties can mutually point fingers at each other, saying, "it wasn't me." <!-- CITE -->
Ring signatures can provide untraceability in Stealth transactions in the following way: For a given transaction, a set of inputs is collected which is *larger* than the set needed to cover the the intended transaction outputs. The additional inputs should include inputs for which the spender does not have authorizaton to spend. A signature is provided proving that at minimum *enough* inputs are authorized to cover the outputs, however an external observer cannot determine which inputs are thereby consumed. Double-spending of inputs is prevented by the provision of a "**key image**" for each actually-spent input. A key image is a piece of data that uniquly derives from the consumed input, but which cannot be matched to it. A subsequent spend of the same input would produce the same key image, alerting the network to the attempt at a double spend. Now, the set of inputs to any transaction includes not only the actually-consumed inputs, but also a large set of "red herring" inputs, which achieve two important aims for untraceability:
1. A degree of plausible-deniability for the authorizer of any individual transaction, and
2. An enormously larger set of prior transactions that form the "history" of the transaction, implicating a *much* larger set of originating transactions than is actually involved in the true history of the transaction.
It should be noted that one drowback of this scheme is that it is no longer possible to determine which UTXOs are spent vs. unspent, and this has implications for database pruning. However, the Monero chain has been functioning with this limitation for several years now without hitting a performance bottleneck. Additionally, the Monero team has projected that performance growth will keep pace with database size, even absent pruning of spent TXOs. (CITE). (A review of this projection and discussion of its implication for the BitShares chain is in the Discussion section.)
## Specifications
(Detailed description of RingCT with annotations for how it would be adapted to BitShares Stealth transactions.) [[2]](#see-also)
## Discussion
### Overview of alternative untraceability solutions
(Compare/contrast with other schemes for providing untraceability, including ZeroCoin accumulators, master-node facilitated tumbling, MimbleWimble, etc.)
#### Mimblewimble
* PRO: Supports a sort of automated, non-interactive aggregate signature scheme (end result similar to CoinJoin), facilitating untraceability at the blockchain level (although not necessarily at the network-snooping level).
* CON: Requires communication between sender and recipient.
* [[Jed2016]](#see-also), [[PoelMW]](#see-also)
#### CoinJoin, CoinSwap, etc.
* In [1], Maxwell states "[CT is] compatible with CoinJoin and CoinSwap, allowing for transaction graph privacy as well while simultaneously fixing the most severe limitation of these approaches to privacy (that transaction amounts compromise their privacy)."
* ((This still needs to be researched by this author but I believe these protocols involve mixing with contemporaneous participants, many of whom may be nefarious actors. RingCT allows mixing with historical transactions, and reuse of historical transactions, greatly broadening the set of available mix-in transactions. TODO: confirm this disadvantage.))
* Dash (http://dash.org) uses a system of "master nodes" to coordinate an opt-in mechanism of "pre-washing" coins via several rounds of mixing with other participants where each round of washing is a CoinJoin-like process. (https://dashpay.atlassian.net/wiki/spaces/DOC/pages/1146924/PrivateSend)
#### Accumulator Schemes, e.g. ZeroCoin
* Spending a coin into the accumulator produces receipt that can be used to withdraw a coin from the accumulator later. The withdraw operation cannot be linked to the orignal deposit operation. Untraceability os provided by the fact that the "plausible deniability set" of users who might be responsible for the coin is the set of all users who have deposited coins into the accumulators. This can be a very large set.
* Pros:
* Large deniability set
* Conceptully simple mechanism
* Possible to audit supply
* Cons:
* Depends on a **trusted setup**, which, if compromised, could allow theft or counterfeit of coins
* (NOTE: Announcement by ZCoin team of an upgrade that eliminates need for trusted setup) (CITE)
* [[Yap2017]](#see-also), [[GrothSigma]](#see-also)
* Mechanism to transfer coins between users while the coins are *inside* the accumulator is unclear/unknown (to this author) or impossible. Thus an accumulator may be a good way to wash or hide your own funds, but is not a good solution for creating a balance that one easily use in cash-like user-to-user transactions.
### Scaling challenges in a Ring-Sig scheme
(Discussion of the implications of not pruning spent TXOs.)
## Summary for Shareholders
## Copyright
This document is placed in the public domain.
## See Also
[1] Confidential Transactions (Greg Maxwell) - https://people.xiph.org/~greg/confidential_values.txt
[2] Ring Confidential Transactions (Shen Noether) - https://eprint.iacr.org/2015/1098
[Jed2016] Mimblewimble (Tom Elvis Jedusor) - https://scalingbitcoin.org/papers/mimblewimble.txt
[Poel2016MW] Mimblewimble (Andrew Poelstra) - https://download.wpsoftware.net/bitcoin/wizardry/mimblewimble.pdf
[Yap2017] Zcoin moving beyond trusted setup in Zerocoin (Reuben Yap) - https://zcoin.io/zcoin-moving-beyond-trusted-setup-in-zerocoin/
[GrothSigma] - One-out-of-Many Proofs: Or How to Leak a Secret and Spend a Coin (Jens Groth and Markulf Kohlweiss) - https://eprint.iacr.org/2014/764.pdf

264
bsip-1203.md Normal file
View file

@ -0,0 +1,264 @@
BSIP: 0053
Title: Blockchain scanning for inbound Stealth transactions
Authors: Christopher J. Sanborn
Status: Draft
Type: Protocol
Created: 2018-01-29
Discussion: https://github.com/bitshares/bsips/issues/91
## Abstract
The existing Stealth implementation ([BSIP-0008](bsip-0008.md)) requires the sender to manually communicate *transaction receipts* to the recipients of each transaction to alert them to the presence of an inbound balance transfer, creating a danger of lost funds due to miscommunicated or lost receipts. This BSIP explores options for automated discovery of inbound transactions while still preserving fundamental privacy features of unlinkability and anonymity.
## Motivation
"Stealth addresses" are a method of providing _unlinkability_ to blockchain transactions. Unlinkability is a major component of the Privacy Triad: _unlinkability_, _confidentiality_, and _untraceability_. Using a stealth address, a sending wallet is able to compute a child public key that derives from a public key encoded in the address, but which cannot be correlated, or "linked", to the address public key, unless you are either the sender or the receiver. This child key becomes the authorization key for transaction outputs (TXOs) intended for the receiver. As such, third party observers cannot link TXOs to addresses, nor even link together independent TXOs which are destined to the same address.
Although this is a great benefit to privacy, it complicates the matter of detecting inbound transactions, since a wallet cannot simply scan for transactions which explicitly identify the destination address.
Existing [Stealth Phase I](bsip-0008.md) functionality already includes the use of stealth addresses, but does not include a solution for detection of inbound transactions. As a result of which, user adoption of the Stealth feature has been very minimal. We propose below a solution to inbound transaction detection as well as some additional enhancements to the stealth addressing scheme, including a proposed new address format that allows for watch-only wallets.
## Rationale
A confidential transaction (cTX) does not identify the recipient. As such, there is no direct way for a wallet to use only its Stealth address to query the p2p network for inbound transactions. In the current "phase one" implementation of Stealth ([BSIP-0008](bsip-0008.md)), inbound discovery is a manual process requiring the sender to communicate "transaction receipts" to the intended recipients of each transaction output in order to alert each recipient of their incoming balance. Transaction receipts are encrypted data structures that embed the Pedersen commitment of the transaction output and the value and blinding factor that the recipient needs to "open" the commitment. Additionally, the receipt records the one-time public key which the recipient must use to derive the private key offset needed to spend the incoming coin, via a shared-secret procedure between the one-time key and the recipient's address key. The need to communicate transaction receipts is burdensome and introduces substantial risk of lost funds due to failure to communicate or retain receipts.
_Keys involved in a cTX output (cTXO):_
* **One-Time Key (OTK)** — The sender generates this key (public and private) from randomness and uses it to generate a shared-secret between the OTK and the recipient's Address ViewKey. The OTK PubKey will be clear-text encoded in the Tx receipt, and optionally also recorded in the transaction output to enable automated discovery.
* **Address Keys (ViewKey and SpendKey)** — These are public keys encoded in the recipient's stealth address. The goal of a stealth address scheme is to _not_ identify these public keys in any transaction output. A long-form address encodes _two_ public keys, referred to as ViewKey and SpendKey. The SpendKey serves as a base point from which individual Tx output AuthKeys are computed as an offset, and the ViewKey is used with the OTK to compute that offset. A short-form address encodes only a single public key, which serves as both the ViewKey and SpendKey.
* **Tx Output Authorization Key (AuthKey)** — This public key will be recorded in the confidential transaction output (cTXO) as the key which is authorized to spend the commitment. This key is offset from the address SpendKey by a secret offset that only the sender and recipient can calculate (from the shared secret between OTK and ViewKey). The sender can only know the offset, but not the full secret key to the AuthKey. The recipient, knowing the private key behind the SpendKey, can compute the private key to AuthKey and therefore can spend the commitment.
Automated discovery could be enabled if the receipt were embedded within the transaction data structure and if an aspect of that data structure supported a challenge condition which the recipient could recognize.
Current network rules allow for a receipt to be embedded in each Tx output via a `stealth_memo` field which is formatted in a similar way as the encrypted memos that may accompany regular (non-Stealth) transfer operations. These memos are composed of a header specifying the OTK PubKey and the "message PubKey" for which the recipient holds the corresponding private key, followed by cipher text which is AES encrypted with a shared-secret key between the OTK and the message PubKey. For this `stealth_memo` field, the current behavior of the CLI reference wallet is to use the recipient's Address PubKey as the message PubKey. Although this is a reasonable choice for encrypting message text generally, it has the severe downside of identifying the recipient's Address PubKey in the memo header, and therefore breaks anonymity and negates the unlinkability provided by using a stealth address scheme. For this reason, the CLI reference wallet currently does _NOT_ actually embed the memo in the Tx ouput but instead Base58 encodes it and prints it to the screen, calling it a "transaction receipt." The sender must manually, and secretly, transmit this to the recipient via a side channel.
**Stealth Memo structure: (Stealth I)**
<span></span> | <span></span>
-----: | :---
**One-time PubKey:** | Chosen from randomness by sender &nbsp; **_(33 bytes)_**
**Message PubKey:** | Public key controlled by recipient. &nbsp; **_(33 bytes)_**<br>
**Cipher Text:** | AES encrypted message, using _key &leftarrow; Shared(OTK,MPK)_
_Current Stealth I behavior is to use the Address PubKey as the message PubKey, which reveals intended recipient!!_
A very simple solution would be to change the behavior of embedding the Address PubKey in the message PubKey field, and to instead record the Tx output AuthKey in this slot. Because the recipient is also able to derive this AuthKey through knowledge of her own address private keys (in combination with the OTK recorded in the header), the recipient would simply need to test the OTK against each of their own Address Keys to see if the resulting AuthKey matches the one in the header. If it does, then the output is recognized as destined to the recipient, even though the recipient's Address PubKeys are not identified in the memo header. The computational cost of this is one Diffie Hellman round, a hash operation, and a child key derivation. It should be noted that the AES encryption key should still be computed from the shared secret between the OTK and the address ViewKey, however, as this will allow view-only wallets which cannot compute the private key behind the AuthKey to decrypt the memo and tally the incoming transaction.
**Stealth Memo structure: (Proposed: Stealth II)**
<span></span> | <span></span>
-----: | :---
**One-time PubKey:** | Chosen from randomness by sender &nbsp; **_(33 bytes)_**
**cTXO AuthKey:** | Child public key of the stealth address and the OTK. &nbsp; **_(33 bytes)_**<br>
**Cipher Text:** | AES encrypted message, using _key &leftarrow; Shared(OTK,ViewKey)_
_Proposed Stealth II behavior is to embed the AuthKey in the second slot, while still encrypting the message data with a shared key between the OTK and the Address key (specifically, the ViewKey so that watch-only wallets can read the commitment data)._
To support this strategy, a wallet will need to inspect all cTX activity on the network and test the challenge conditions on each transaction. This could be achieved if API nodes are extended to provide an API call to retrieve `stealth_memo` fields from all cTXOs appearing in a specified block range. The wallet could simply download the memos, test the challenge on each one, and identify and decrypt the ones that are destined to the wallet. No need would remain to manually transmit transaction receipts. The receipts would be embedded, compactly and unlinkably, in the Tx outputs.
## Specifications
We specify two protocols. In the first subsection, [_Wallet procedure..._](#wallet-procedure-for-recognizing-own-commitments), we specify the recognition protocol by detailing wallet behaviors for:
* Creating transaction outputs that can be recognized by their recipients, and,
* Recognizing transaction outputs that are destined to the wallet.
And in the second subsection, [_API requirements..._](#api-requirements-to-allow-detection-of-inbound-commitments), we propose a new API call for querying nodes for transaction outputs to be scanned for recognizable markers. This is an added feature for API nodes and does not involve any consensus changes.
### Wallet procedure for recognizing own commitments
Assumptions:
1. Wallet has access to a set of private keys corresponding to stealth addresses which may own commitments on the blockchain. These private keys are needed to "recognize" incoming transactions. If the wallet is a watch-only wallet for a particular address, then it is assumed to have the private and public ViewKey, but only the public SpendKey.
2. Wallet can query an API node for commitments occurring between specified block heights, to obtain sets of embedded receipts to scan for owned commitments. ([See below](#api-requirements-to-allow-detection-of-inbound-commitments) for this process.)
We detail procedures for stealth address formats which encode either a single public key, or two distinct public keys in which one key is the ViewKey and the other the SpendKey. The single-key format is already in use on the BitShares network and is borrowed from the original Confidential Transactions specification. The dual-key format allows for additional wallet features and is borrowed from CryptoNote-based coins such as Monero. No changes to the network nodes are required for wallets to support dual-key address formats. In fact, the single-key format can be thought of as a special case of the dual-key format in which the same key is used as the ViewKey and the SpendKey.
**Address Formats:**
&nbsp; | Format:
:------:|--------
**CT-style:** | Single public key and checksum. Public key _A_ serves both viewing and spending roles.<br><br> Format: `BTSaaaaaaaaaaaaaaaaaaaacccc`
**CryptoNote-style:** | Two public keys plus a checksum. Public key _A_ serves the viewing role and public key _B_ serves the spending role.<br><br> Format: `BTSaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbcccc`
**Invoice Nonce:** | This one encodes a single PubKey serving both the viewing and spending role, but also includes a 64-bit "nonce" or "tag" that the spending wallet is to include in the encrypted memo part of the cTXO, allowing the receiver to interpret payment as being applied to a specific invoice. <br><br> Format: `BTSaaaaaaaaaaaaaaaaaaaannnnnnnncccc`
_(In the address formats above we consider the part following the "BTS" identifier to be Base58 encodings of the concatenated byte buffer representations of public keys and checksum bytes. C.f. [Base58Check](https://en.bitcoin.it/wiki/Base58Check_encoding) encoding.)_
The dual-key format separates the duties of spending a commitment from those of reading the commitment, such that a person in possession of only the "viewing key" (the private key corresponding to the additional pubkey in the address) can discover, interpret, and tally incoming transactions, but _cannot_ spend them. The "spending key" (private key corresponding to the primary pubkey in the address) is needed to authorize the spending of a commitment. The dual-key address format and signing procedures are described in detail in [[vS13]](#references) and reviewed below.
#### Procedure for single-key stealth addresses (CT-style)
Recognizability depends on there being a deterministic relationship between the AuthKey that authorizes expenditure of a particular cTXO, the one-time key (OTK) that the sender generated randomly for the cTXO, and the recipient's Address key (or keys).
We assume that the stealth address encodes public keys corresponding to two purposes: discovery, and expenditure. When an address encodes only one public key, that key is used for both purposes. We refer to the key for discovery as the "view" key, and denote the private, public pair as _(v, ViewKey)_. For spending, we denote the key pair as _(s, SpendKey)_.
The AuthKey for a cTXO is an EC point summation of the address's SpendKey and an EC point "offset," which, for present purposes we will denote by the private, public pair _(o, Offset)_, with _Offset = o*G_, where _G_ is the generator point for the curve.
&nbsp; _AuthKey &nbsp;=&nbsp; SpendKey &nbsp;+&nbsp; Offset_
Anonymity is preserved so long as only the sender and the receiver are able to compute _o_ and _Offset_. The algorithm for computing _Offset_ is a deterministic function of the OTK and ViewKey only, (and not the SpendKey). This allows the the recipient to recover the SpendKey by simple subtraction of _Offset_ from the AuthKey. The recipient's wallet then compares the computed SpendKey against the address SpendKey. The wallet may even compare against a whole list of SpendKeys that the wallet may have used to generate an address family with a common ViewKey, allowing for differentiable invoices, without sacrificing efficiency of scanning. (See _[address-per-invoice](#utility-of-dual-key-addresses)_ below.)
Algorithm | Description / Specification
:---:|:---------------------------
_Shared(a,B)&nbsp;&rarr;&nbsp;secret <br> Shared(A,b) &rarr; secret_ | This yields a "shared secret" between public keys _A_ and _B_ computable only by parties possessing at least one of the private keys _a_ and _b_.<br><br>&nbsp; _secret = SHA512(P<sub>X</sub>)_; &nbsp; &nbsp; _P = aB = Ab_<br><br>For BitShares Stealth, the secret is a byte buffer (64 bytes) computed from the SHA512 hash of the encoded _X_ coordinate (32 bytes) of EC point _P_. (c.f. [EC Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic-curve_DiffieHellman).)
_ChildOffset(B,index)&nbsp;&rarr;&nbsp;offset_ | This yields an integer-valued private key _offset_ that generates the keypair _(offset, Offset = offset*G)_. The offset is considered to be a "child" of key _B_, and the parameter _index_ is a byte buffer.<br><br>&nbsp; _child = BigInteger(SHA256(Compressed(B)_ &vert;&vert; _index))_<br><br>_Compressed(B)_ refers to the SEC1 "compressed" representation of public key _B_. The &vert;&vert; symbol refers to concatenation.
**Sending:**
The sender's procedure for computing the offset and generating the AuthKey for the cTXO is detailed as follows:
<ol>
<li> Compute a "shared secret" between between the sender and receiver:
_secret = Shared(otk, ViewKey)_
The sender must be careful to leak neither the shared shared secret nor the private _otk_ key.
</li>
<li> Compute the OffsetKey as a child of the ViewKey, using a SHA256 hash of the shared secret as a child index:
_childindex = SHA256(secret)_<br>
_offset = ChildOffset(ViewKey,childindex)_<br>
_OffsetKey = offset*G_
</li>
<li> Compute the AuthKey by summing SpendKey and OffsetKey:
_AuthKey = SpendKey + OffsetKey_
</li>
</ol>
**Receiving:**
The receiver, having acquired a list of cTXO metadata that includes _OTK_ and _AuthKey_, goes through the following process to test for ownership:
<ol>
<li> Compute a "shared secret" between between the sender and receiver:
_secret = Shared(OTK, viewpriv)_
</li>
<li> Compute the OffsetKey as a child of the ViewKey, using a SHA256 hash of the shared secret as a child index:
_childindex = SHA256(secret)_<br>
_offset = ChildOffset(ViewKey,childindex)_<br>
_OffsetKey = offset*G_
</li>
<li> Recover the public SpendKey by subtracting OffsetKey from AuthKey:
_SpendKey = AuthKey - OffsetKey_
</li>
<li> Compare the recovered SpendKey against all wallet SpendKeys that may have been used with the ViewKey to generate an address. If one matches, then the cTXO is "recognized." To later spend the cTXO, the wallet computes the private authorization key as:
_authpriv = spendpriv + offset_
</li>
</ol>
Thus, a wallet may undertake to periodically download and scan the metadata for Stealth transactions and test for outputs that can recover a wallet's public SpendKey from knowledge of the private ViewKey.
##### Embedding recognizability data in the transaction
For the recipient to have the practical ability to recognize a cTXO as their own, the cTXO, as recorded on the blockchain, must include the following two items: 1.) The one-time PubKey (OTK) that the sender generated for shared-secret generation, and, 2.) the authorization PubKey (AuthKey) of the cTXO. Because the AuthKey is computed deterministically from _Shared(OTK,AddrKey)_, it stands that if the recipient can generate the same AuthKey, then the cTXO belongs to them.
The structure of a cTXO is as follows:
_Field_ | _Purpose_
-------:|:-------
**`commitment`:** | Blinded value commitment &nbsp; _(EC curve point, 33 bytes)_
**`range_proof`:** | Proof data supporting transaction validity &nbsp; _(0 to ~5 KiB)_
**`owner`:** | BitShares owner structure specifying weighted list of keys or accounts that may spend this commitment. (Typically lists just one public key, the "AuthKey" for the cTXO.)
**`stealth_memo`:** | Also known as the "transaction receipt" when transmitted off-chain.<br><br> **`one_time_key`:** &nbsp; _(EC curve point, 33 bytes)_<br> **`to`:** &nbsp; Use the AuthKey here! _(EC curve point, 33 bytes)_<br> **`encrypted_memo`:** &nbsp; Data that recipient needs to "open" the commitment.<br><br> _The stealth memo is optional as far as the network is concerned, but essential if you want the recipient to be able to detect the incoming transaction without sending a "receipt."_
_(An example transaction showing all these fields can be seen in [block 22157273](https://cryptofresh.com/tx/8182e9d78cbce7df281bc252a9e6d87566ca0622). In this Tx, the stealth_memo '`to`' field unwisely names the recipient's address key, rather than the cTXO Auth key, and thus breaks unlinkability.)_
Since the `stealth_memo` field can be used to record both the OTK and the AuthKey, all the wallet needs to do to scan for incoming transactions is to download batches of stealth memos and, for each one, test whether the combination of the OTK and the wallet's Address key yields the AuthKey. If it does, then derive the AES decryption key from _Shared(OTK,ViewKey)_ and use that to read the additional data in `encrypted_memo`.
Structure of `encrypted_memo`:
_Field_ | _Purpose_
-------:|:-------
**`from_key`:** | Original use:<br><br><ul>Identifies address key of sender **(optional)**. &nbsp; _(EC curve point, 33 bytes)_</ul>Alternate possible uses:<br><br> <ul><li>Instead of ID'ing the 'from' address, could use this field to embed an _invoice nonce_ to allow receiver to correlate payment to an invoice.</li></ul>
**`amount`:** | Value of commitment. &nbsp; _(Integer, 32 bytes)_
**`blinding_factor`:** | Blinding factor. &nbsp; _(Integer, 32 bytes)_<br><br>_Note: Except when a blind_sum is needed, the blinding factor is deterministic from a hash of the shared secret, meaning this field can potentially be repurposed or omitted. To guarantee that the blinding factor can always be deterministic, transactions can be padded with a commitment to zero to absorb the blind_sum._
**`commitment`:** | The Pedersen commitment. &nbsp; _(EC curve point, 33 bytes)_<br><br> _Note: This field is redundant, since the commitment is determined by_ C = amnt * H + blind * G, _and could potentially be omitted._
**`check`:** | Checksum to confirm correct decryption. &nbsp; _(4 bytes)_
_(TODO: How is this serialized? Do omitted fields "take up space"? Can fields be chosen a la carte? How hard will it be to extend this memo format, for, say, multiple assets in the case of CA? See fc::raw::pack.)_
### API Requirements to Allow Detection of Inbound Commitments
To monitor for incoming transactions to a particular wallet, a wallet need only download sets of `stealth_memo` structures to test for recognition. The full cTXO (including Pedersen commitment, owner structure, range proof, etc.) need not be downloaded. Because the encrypted data inside the memo indicates the Pedersen commitment, the wallet will know which cTXO it has recognized. (Witness nodes index cTXO's by Pedersen commitment.)
(Discuss here a proposed API call for retrieving stealth_memos by block height range)
To know whether a cTXO is still unspent (e.g. by another instance of the wallet), a wallet could attempt to retrieve the corresponding commitment object from an API node. An empty result indicates the commitment has been spent. However, this procedure indicates our interest in a specific set of commitments, and the network traffic generated runs the risk of revealing that those commitments are "linked".
To prevent this, we propose instead that, in like manner to the downloading of bulk `stealth_memo` structures, that an API call for downloading bulk lists of consumed commitments be implemented, with the download again being over specified block height ranges. A wallet then needs only to test that its own commitments are not on the list of spent commitments.
In the event that ring signatures are implemented for transaction inputs (see [BSIP-0052](bsip-0052.md)), then instead of downloading a list of consumed commitments, we would instead download a list of used key images, which would serve the same purpose.
Because a wallet downloads `stealth_memo` structures in bulk over block height ranges, the wallet never reveals to the network its interest in any specific cTXOs. Thus network interaction for monitoring purposes does not undermine privacy.
NOTE: It is currently possible to retrieve all needed info to support recognition of incoming transactions via Elastic Search queries. This implies: (1) functional wallet behavior can be implemented right away, even if new API calls take longer to implement, and (2) it may be possible to avoid adding new API calls altogether, if the Elastic Search infrastructure is deemed performant enough to support queries from Stealth wallets. (Although intuitively it seems to me an API method would result in a better user experience).
## Discussion
### Utility of dual-key addresses
Utilization of the dual-key address format has numerous interesting use cases, including:
* The ability to maintain **watch-only wallets**. By entrusting only the View Key to a view-only node, it is possible for this node to monitor for activity to an address without granting spending access to the same node. This allows for such things as: opt-in transparency; cash register monitoring; organizational internal auditing, etc.
* The ability to use **address-per-invoice** without introducing substantial additional scanning overhead. To use this, one keeps the same viewing PubKey and iterates the Spending PubKey part of the address, generating a distinct address per invoice. When scanning the blockchain, the _Child Offset_ is a function of the shared-secret between OTK and ViewKey, such that _AuthKey = SpendKey + Offset_. To obtain the public SpendKey, a watching wallet can subtract the Offset from the AuthKey to obtain the SpendKey, and simply compare against a list of per-invoice SpendKeys that were used to generate addresses. Adding additional SpendKeys to scan for does not incur any additional EC group operations, merely additional byte-wise comparisons, which are trivial. _(Note that while the invoice addresses generated in this manner are distinct, they are not unlinkably distinct, since they share the viewing component. If a business wants individual invoices to be mutually unlinkable, then this scheme will not be sufficient. However, this is a consideration for a business's off-chain security practices, as the addresses themselves never appear on-chain or in a transaction. An alternate solution which allows even the ViewKey to vary, while still allowing for efficient scanning, is presented in [MRL-0006](https://lab.getmonero.org/pubs/MRL-0006.pdf), however this introduces a change in how the deterministic offsets are generated, which would need to be signaled by a flag in the address format and supported by wallets.)_
### Possible future extensions
#### Additional address formats
The two stealth address formats described above provide for single key and dual key addresses, where the latter allows for separation of transaction monitoring from the ability to spend, allowing for view-only wallets.
There may be use cases for additional address formats allowing for more complex situations.
One would be a multi-sig situation in which the address format encodes multiple spending keys and a weighting requirement. Although, this would make the resulting address very lengthy, it would also add an interesting use-case. And, since BitShares authority structures already allow for a vector of authorizing keys and weights, it should be possible to implement the feature on the wallet side, without needing any changes to consensus or API. This idea is not explored further here but merely suggested for future exploration if there is a desire for the feature.
Another use case for an extended address format would be... (TODO: Discuss including an "invoice nonce" in the address format for correlating incoming transactions to a particular invoice. C.f. Bitcoin where using an address-per-transaction serves both unlinkability as well as invoicing. With Stealth addresses, there is no need to increment addresses for unlinkability, and doing so to facilitate invoicing only increases the scanning overhead by introducing the need to test against additional private keys. But by including an invoice nonce in the address format, which the spending wallet would carry over into the encrypted part of the `stealth_memo`, the recipient can correlate payments to invoices while using only a single address key. This strategy would be similar to the "Integrated addresses" that can be used on the Monero platform. Note, however, that this scheme is largely obsoleted by the simple ability to iterate the SpendKey through a HD address family while keeping the same ViewKey in a dual-key address format.)
### Pitfalls and Cautions
#### Specific risks and remedies
##### Sender leaks private _otk_ or private _shared secret_:
TODO: analyze
#### An attack on address key from leak of a transaction private key
A confidential output will have associated with it an "Output PubKey," or AuthKey. He who can provide a signature from the AuthKey is authorized to spend the commitment. Automated detection of inbound commitments depends on the deterministic computation of an offset between the One-time PubKey (OTK) and the Address SpendKey, which is computed from the shared secret between the sender and receiver. Because only the offset is deterministic, the sender cannot compute the private key to the AuthKey. Only the receiver can do this (by knowing both the offset and the address's private spending key).
Because AuthKeys are only used once, wallet software designers may be led to believe that the security of the AuthKey private keys are only important up until the commitment is spent. (What would it matter, to leak that private key, when the commitment it authorizes is no longer spendable?) This would be a mistake, however, because anyone who can compute the additive offset can subtract it from the private AuthKey to reveal the address's private spending key. Although the general public is not expected to be privy to that offset, the _sender_ of the output is in possession of the offset (and the ability to compute it due to knowing the random _k_ behind the One-time PubKey). This means the sender would be enabled to compute the address's private key, in the event that the recipient leaks the private AuthKey.
Thus, wallet designers should be advised to treat the private TXO AuthKeys handled by their wallets with at least as much care as the address private keys, even long after the commitments they authorize have been spent. A leak of a single commitment's PrivKey is tantamount to a leak of the PrivKey for the entire wallet.
(A similar risk of revealing a parent PrivKey from leak of a child PrivKey and parent XPUB when using non-hardened derivation is noted in the Bitcoin BIP-32 protocol for Hierarchical Deterministic Wallets.)
## Summary for Shareholders
Although the goal of this BSIP is to support the long-range vision of [Stealth Phase II](bsip-0050.md), the implementation of this BSIP would provide value _right now_, as it would enable the utilization of even the Phase I _Confidential Transactions_ operations without the reliance on burdensome transaction receipts, which are the primary end-user stumbling block to routine Stealth use.
We have detailed in this document procedures for producing recipient-recognizable transaction outputs from stealth addresses. Specifically, we have detailed the procedure for _two_ distinct stealth address formats: a single-key address format which is identical to that which is already in use, and a new dual-key address format which separates the duties of monitoring from spending, and thus allows for watch-only Stealth wallets. Support for the dual-key address format would require no network or consensus changes. It requires only wallet support.
Most of the work needed to implement this BSIP is in the wallet, namely the correct production of recognizable cTXOs and the process of scanning for owned cTXOs. The only network-level change is the addition of two API calls: one to return batches of `stealth_memo` fields included in a block range, and one to return batches of consumed commitments (in the case of CT transactions) or used key-images (in the case of RingCT transactions). These API calls would need to be available on wallet-serving API nodes, but would not be needed on block-producing witness nodes. There are no consensus changes proposed in this document.
## Copyright
This document is placed in the public domain.
## References
[vS13] - Nicolas van Saberhagen, _Cryptonote v 2.0_, 2013 - https://cryptonote.org/whitepaper.pdf
[NG17] - Sarang Noether and Brandon Goodell, _An efficient implementation of Monero subaddresses_, 2017 - https://lab.getmonero.org/pubs/MRL-0006.pdf
## See Also
* Overview of _Stealth Phase II_ - [BSIP-0052](bsip-0052.md)
* [bitshares-stealth-k](https://github.com/Agorise/bitshares-stealth-k) - A Kotlin library for Stealth support in BitShares (in _very_ early development stage)

34
bsip-1204.md Normal file
View file

@ -0,0 +1,34 @@
BSIP: 1204 (unassigned)
Title: Deterministic addresses for Stealth wallets
Authors: Christopher J. Sanborn
Status: Draft
Type: Informational
Created: 2018-01-29
Discussion: <url>
## Abstract
To simplify a wallet owner's backup burden by documenting and standardizing key derivation for Stealth balances from the same backup seeds used to generate the user's regular account keys.
## Motivation
Current wallet implementations (e.g. the CLI wallet and Agorise's extensions to the UI wallet) generate a new Brain Key for each Stealth "account" (defined as a confidential balance under the control of a single private key). Since creating a confidential account is a purely client-side activity, (in contrast with a regular account which is registered on the blockchain), there is no automatic association between a confidential balance and a regular account that ostensibly "owns" it, and a backup burden is created for each new confidential balance.
It would be desireable to give the user the ability to maintain all of her accounts and balances under the control of a single backup key seed or brain key, so that the backup burden can be satisfied just once, at the creation of the user's first regular account. The derivation schemes defined under Bitcoin's BIP-44 provide a natural mechanism for this, and Satoshi Lab's SLIP-48 already define derivation paths for owner, active, and memo keys on BitShares and similar networks.
We propose here:
(1) To define additional derivation paths for Stealth accounts, and,
(2) For backwards compatibility with existing accounts secured by Brain Key, to standardise and document a distinct procedure for deriving Stealth keys from Brain Keys so that the same Brain Key that secures a user's regular account can also be used to secure their confidential balances, if the user desires.
## Rationale
## Specifications
## Discussion
## Summary for Shareholders
## Copyright
This document is placed in the public domain.
## See Also

30
bsip-1205.md Normal file
View file

@ -0,0 +1,30 @@
BSIP: 1205 (unassigned)
Title: Metadata hiding via Garlic Routing and other means
Authors: Christopher J. Sanborn
Status: Draft
Type: Informational
Created: 2018-01-29
Discussion: <url>
## Abstract
To provide an overview of strategies that can be used by wallets to prevent leaking of sensitive metadata, e.g. your interest in particular balances on the blockchain, to third parties that may be monitoring network traffic, or to potentially compromised nodes on the BitShares p2p network.
## Motivation
Querying a p2p node to check your confidential balances reveals your interest in particular commitments and threatens anonymity by establishing a link between an IP address and a commitment set. New anonymity technologies such as Garlic routing and i2p can be used to ensure that neither network monitoring nor a compromised p2p node can determine the origin of a request regarding a particular set of commitments, thus protecting anonymity.
Additionally, querying a discrete set of commitments undermines confidential unlinkability. Unlinkability is the inability to determine that multiple independent commitments are controlled by the same party. Although not perfect, a partial solution to this is to use Bloom filters to query a superset of commitments, so that the p2p node will return a mix of linked commitments as well as random commitments, making it difficult for an external observer to establish which commitments are actually of interest to the querying party and which are included by the filter serendipitously.
There may also exist other strategies of merit to protect unlinkability and privacy generally.
## Rationale
## Specifications
## Discussion
## Summary for Shareholders
## Copyright
This document is placed in the public domain.
## See Also