Coder Social home page Coder Social logo

stellar-protocol's Introduction

Stellar
Creating equitable access to the global financial system

Stellar Protocol

Docs: CAPs Docs: SEPs

This repository is home to Core Advancement Proposals (CAPs) and Stellar Ecosystem Proposals (SEPs).

Similar to BIPs and EIPs, CAPs and SEPs are the proposals of standards to improve the Stellar protocol and related client APIs.

CAPs deal with changes to the core protocol of the Stellar network. Please see the process for CAPs.

SEPs deal with changes to the standards, protocols, and methods used in the ecosystem built on top of the Stellar network. Please see the process for SEPs.

Repository structure

The root directory of this repository contains:

  • Templates for creating your own CAP or SEP
  • contents directory with [cap | sep]-xxxx subdirectories that contain all media/script files for a given CAP or SEP document.
  • core directory which contains accepted CAPs (cap-xxxx.md where xxxx is a CAP number with leading zeros, ex. cap-0051.md)
  • ecosystem directory which contains accepted SEPs (sep-xxxx.md where xxxx is a SEP number with leading zeros, ex. sep-0051.md)

Example repository structure:

├── CONTRIBUTING.md
├── README.md
├── cap-template.md
├── contents
│   └── cap-0003
│       └── get_offer_stats.sql
├── core
│   ├── cap-0001.md
│   ├── cap-0002.md
│   ├── cap-0003.md
│   └── README.md
├── ecosystem
│   ├── README.md
│   ├── sep-0001.md
│   ├── sep-0002.md
│   ├── sep-0003.md
└── sep-template.md

Contributing

See CONTRIBUTING to learn how to contribute.

stellar-protocol's People

Contributors

accordeiro avatar bartekn avatar c0x41lch0x41 avatar christian-rogobete avatar dmkozh avatar graydon avatar howardtw avatar ifropc avatar istrau2 avatar jakeurban avatar jayz22 avatar jedmccaleb avatar jeremyrubin avatar jonjove avatar leighmcculloch avatar lijamie98 avatar lydiat avatar marcelosalloum avatar misterticot avatar monsieurnicolas avatar msfeldstein avatar nikhilsaraf avatar orbitlens avatar philipliu avatar rice2000 avatar sisuresh avatar stanford-scs avatar theaeolianmachine avatar tomerweller avatar tomquisel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stellar-protocol's Issues

Proposal for an Accounts and Assets "Link" type

Hi all,

I'd really like to formally link accounts and assets, especially into hierarchies.
Think of something like a Chart of Accounts, Parts List / Bill of Materials, Purchase Order, Paper Portfolio, or Index Fund.

This would be a new object type that links two addresses or assets in the system via a from/to.
The two link fields could done as "trust_lines" (a from line and a to line).
Setting the AssetCode to "" or null would represent an account link, otherwise an asset.

This object has "type" and "name" strings and Managed Data fields for properties of the "relationship".
Using this "Link" object is completely user defined and has no formalized in-system meaning.

The operations I see are of the standard CRUD fare; but a convenience API to also return the linked Accounts (if they are Accounts) would save from a couple trips back to the servers.

Thanks,
Mike

Add the ability to attach key/value pairs to an account

Create a new DataEntry that is just a key/value pair.
These DataEntries are owned by accounts. The key would be a string and the value would be 32bytes.
There would be operations to add and remove DataEntries.

Each DataEntry would increase the storage cost of the account.

Could be used for things like attaching an encryption key to the account. Having the account publicly attest to some fact. If the account needs to provide other meta data about itself.

IPFS support

Motivation

Adding support for natively addressing objects stored within ipfs (https://ipfs.io/) would allow, in my opinion, many novel systems that use the combined power of ipfs's "permanant web" and the Stellar network's "financial web".

Ipfs uses multihash (https://github.com/jbenet/multihash) to address objects and peers, and adding support to the stellar memo union would allow it to natively address objects stored within ipfs.

Detailed Design

  • the MemoType enum would receive two new definitions: MEMO_MULTIHASH and MEMO_MULTIRETURN
  • The Memo union would incorporate these new enum definitions, and the value for each new discriminant would be of type Multihash
  • The Multihash struct would be introduced.

Open Questions

  • Presently, multihash's largest digest size is 64 bytes. Should we incorporate support for a larger digest?

Current Draft Proposals

Accounts that must authorize incoming transactions

Certain institutions like banks are required to approve incoming txs. They are required to know the source of incoming funds. Right now when they get a tx in from stellar they are must check the tx and if it isn't from an approved source or it isn't clear which internal account the funds are for they must return the tx.

A simpler method would be:
Add a flag to Account that says any incoming payment must also be signed by the account.

Then for bank A sending to bank B, bank A would first send the tx along with details of the sender to bank B, Bank B would sign this tx and return the signed tx to A. A would then also sign and submit the now valid tx to the network.

Anonymous transactions with blind signatures

(With the blind signature implementation I have in mind, this doesnt work inside stellar, rather it works as a service from gateways, but I am putting it here, because someone might find a solution)

Blind signatures is a way to anonymously transfer credit from one account to another when both accounts trust the node that has issued the credits.

Stellar needs to implement the blind signature scheme for this to work.

How does a blind signature work?

Let U,Ua, Tu, where U is the user account that trusts Tu and Ua is the anonymous account of the user that trusts Tu.

An anonymous transfer from U to Ua happens in this way:
Ua requests a deposit slip of a sum X from stellar.
The stellar network encrypts a unique random number R and sends it to Ua.
Ua gives it to U.
U multiplies it with a specific type of random number and blinds it.
U sends it to stellar.
The ledger removes X credit from the U account and signs the blind deposit slip.
U knows R.
U gives R to Ua.
Ua gives R to stellar and the stellar ledge adds X credit to the Ua account.

For technical information, look at this: https://en.wikipedia.org/wiki/Anonymous_Internet_banking

How can one perform an anonymous transaction with blind signatures?

Let S, Sa, Ts, where S is the sender account that trusts Ts and Sa is the anonymous account of the sender that trusts Ts.
Let R, Ra, Tr, where R is the receiver account that trusts Tr and Ra is the anonymous account of the sender that trusts Tr.

The sender sends anonymously credit from S to Sa.
The sender uses the stellar network to transfer credit to the Ba account.
The recipient sends anonymously credit from Ba to B.

Standard for additional asset information

We need some standard way for clients to load meta information for assets and tokens in the network.
Things we need:

  • icon
  • name
  • description
  • fine print
  • validators

There are two ways this could be done:
A) Set the home_domain of the issuing account and place a stellar.toml file at the given home_domain. Then add the additional info to the [[currency]] block

B) use manage_data and add an IPFS hash of to the issuing account. This hash points to some JSON file that is stored in IPFS. Like I do here: https://www.stellar.org/blog/tokens-on-stellar/

I think A makes the most sense as it will be the easiest for issuers and clients. Thoughts?

Currency codes should allow more than 3 characters

Currency codes are limited right now to 3 characters. This matches the conventions for talking about real-world currencies, but it seems like an unnecessary and arbitrary limitation when talking about stellar currencies. The restriction should be lifted.

It makes sense to put some limitations on the currency code. I'd suggest something like [a-zA-Z_][a-zA-Z0-9_./-]*. That is, allow alphabetic characters + _ as the first letter, then add in digits, ., /, and - for all remaining letters. I picked ., /, and - merely because they seem like the most likely punctuation someone might want to use when e.g. building some sort of hierarchical currency code. Other punctuation should be avoided unless someone comes up with a good reason to support it.

I'd also say that if you need to restrict the length for some reason (e.g. inserting into a database), I'd suggest a 255 character limit. That's more than large enough for any reasonable purpose, while not being absurdly large.

Pros:

  • Allows for custom currency codes to be created that are unique without having to worry about any UI issues surrounding disambiguating e.g. IOU credit issued by two different accounts.
  • Similarly, allows one account to issue multiple distinct credits that serve the same fundamental purpose (e.g. IOU) while still being distinct (e.g. because they represent different owed assets, or are issued to two different groups of accounts and needs to be prevented from trading between them).
  • Custom currencies can be descriptive, making it much easier to talk about them.

Cons:

  • This might make it easier for someone to try and embed messages into the ledger, via a series of TrustSet transactions for fake currencies. However, I assume it's already possible to encode messages in e.g. destination tags on micro-payments, or perhaps SetRegularKey transactions (depending on what sort of validation the key is given), or even a sequence of offers that cannot possibly be filled (e.g. between currencies with an issuer that is guaranteed to never issue those currencies). Expanding the currency field would only make it easier (and cheaper due to fewer fees), as opposed to enabling something that is otherwise disallowed.

Add a third data item on Managed Data for data sync and encrypted values

I've been working with account data lately which is currently a straight kvp.

It would help tremendously if there was a third field as part of this record to host a "field revision id".
It would aid in syncing with outside third party apps and as part of a field encryption key.

Each time the data field was written to, this value would change. This value is part "field sequence number" and part "data hash".

By comparing this "revision id" value to a value the external systems have stored locally for the field, these external applications would be able to determine (a) if they have the most recent value for a record, or (b) if the data value needs updating from their own local values. Just comparing to see if the two values are different doesn't help in determining which of the two values is the more current value.

Also, because the value changes every update, it can be part of preventing reusing the same encryption key twice by incorporating it as part of the symmetric key value that encrypts the field data.

Thanks,
Mike

Drop the concept of rippling in favor of long lived offers

Rippling and offers sort of serve the same function. It seems cleaner to combine the two concepts.
You can achieve the effect of rippling if you create two offers between two currency pairs.

This would just require a new flag on the offers saying that they never expire and are always offering at the given price as long as the owner has the takerGets currency.

Forced account_merge

This should work like account_merge operation but before merging it'd remove all subentries. Trust lines balances are sent to:

  • destination for shared trust lines.
  • to issuer if destination does not have a trust line.

Use cases:

  • Some projects (ex. Bifrost) may require configuring account (ex. creating trust lines) before displaying secret key to the end user. If something goes bad (network connection, browser crash) account should be merged back to funder. Currently, Bifrost creates 4 recovery transactions but with forced account_merge it would need only one.

Allow other accounts to pay your reserve

Not a fully baked idea but would help people like satoshipay and stronghold that want to allow users to have accounts and trustlines but not worry they will run off with the lumens.

Streamline native stellard currency format

Currency codes are currently formatted in the long formatted like explained in the Ripple wiki: https://wiki.ripple.com/Currency_format#National_currency_.28ISO_codes.29

Streamline native currency format

They could be streamlined into 4 bytes of ascii. This is assuming that we don't add demurrage, which I believe it does not belong here and belongs in here: https://www.stellar.org/api/#api-accountset like how TransferRate is set. The only thing a currency format should store is the currency code itself.

If Stellar is to become a decentralized standardized network, we need to consider the design of small details such as this.

Proposal: BIP32 (Hierarchical Deterministic Wallet) Support

Preamble

SEP: Not assigned
Title: Stellar BIP32 (Hierarchical Deterministic Wallet) Support
Author: zulucrypto
Status: Draft
Created: 2017-11-03

Abstract

Defines a convention for using BIP32 paths to generate Stellar accounts.

This allows users of wallets that follow BIP39 (Mnemonic code for generating deterministic keys)
to use their same wallet for managing their Stellar accounts.

This is especially relevant to hardware wallets such as the Ledger Nano and Trezor.

Specification

BIP44 (https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) defines
a BIP32 path for multiple coin types:

m / purpose' / coin_type' / account' / change / address_index

This specification follows BIP44 to build the initial path:

m/44'/

The coin_type is 148' as defined by Satoshi Labs in SLIP-0044 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md)

m/44'/148'/

This specification now diverges from BIP44 since the remaining fields are not
applicable to Stellar.

Instead, the fields are defined as follows:

m / 44' / 148' / primary_asset' / account'

Primary Asset

This field defaults to 0' for XLM but can be set to one of the following values
for users that wish to store assets in separate addresses.

Using a different value for this field is optional and exists to help users organize
their accounts. Storing all assets in the default account should be supported by
all applications.

BIP32 Index Asset Description
0' XLM Stellar Lumens
1' ZuluCoin Example asset. TODO: assets would need some way of registering their constants here

TODO: It might be better to generate the BIP32 index by hashing the issuing address
somehow? This would also remove the requirement for assets to register themselves
in this document.

Account

A user-defined index for the user to create multiple accounts.

Examples

Simple Example

A brand new user would start with the following path:

m/44'/148'/0'/0'

The key at this path would determine their Stellar public address.

For most users, this would be all they need and multiple Assets could be stored
in this account.

User with multiple Assets

A user desiring to separate their assets into multiple accounts may use a path like:

m/44'/148/1'/0'

This would generate the first account for asset 1' (see Primary Asset section).

Freezing assets

It would be nice if the freezing of IOUs would be back-ported from Ripple to Stellar. I think it will play a crucial role when trying to convince current financial establishments to start using Stellar.

Currently the only way to ensure the ability to freeze funds is for the GW to create authorised accounts and give the user access to the regular key only. It would be fine, until several GWs started using this practice. Having two gateways doing this would mean it would be very hard to trade between IOUs issued by those GWs.

Having the freezing option would mean the GW can just release the IOUs to any Stellar account - knowing they can freeze them whenever there is real need for it.

Add encryption key to the account

This would allow people to send private messages to accounts. We definitely need this ability for a lot of things. For example when banks are exchanging KYC info of their customers it should be encrypted.
The alternative to sticking the encryption keys in the ledger is sticking them in the stellar.toml and as federation results.

The upside of sticking in the ledger is that it is more flexible and requires people to set up less infrastructure outside of the core network. It requires less third parties.
The downside is adding more stuff in the ledger and extra complexity in the core.

Stellar Memo Convention

Motivation

Often you need to include more info with a transaction than will fit into the 32 bytes available for memos in a Stellar transaction. You can do this by including the just the hash of the longer message in the Stellar transaction using MEMO_HASH and then providing some way for recipients to retrieve the preimage of the hash. See message server.

Memos are used for things like:

  • further credit to a given recipient
  • transfer KYC info
  • User and use case specific things

Although you can technically put anything in the hash preimage, these messages are intended to be understood by other clients. Therefore it is helpful to follow the Stellar Memo Convention.

Stellar Memo Convention

Memos are in JSON format. They are parsed in two passes. The first pass decrypts the encrypted parts of the memo. This pass generates a new JSON object that can then be parsed by the application.

First pass

Fields with $str_ are reserved.
encrypt_v1 is https://download.libsodium.org/doc/public-key_cryptography/sealed_boxes.html
Any JSON field can have either a normal JSON value or an encrypted object of this format:

field description
$str_type Currently only encrypt_v1 is supported.
$str_for (optional) hint of what public encryption key can decrypt this message.
$str_value The encrypted message in base64.
{
      "$str_type": "encrypt_v1",
      "$str_for": "G56789",
      "$str_value": "AAAAZ2VsbG8="
}

When an encrypted object is found the $str_value field is decrypted and the JSON is changed to just the decrypted value.

Examples

empty:
  packed: 
    {}
  unpacked: 
    {}

no_blocks:
  packed: 
    {"foo": 1234 }
  unpacked: 
    {"foo": 1234 }

top_encrypted:
  packed: 
    {
       "$str_type": "encrypt_v1",
      "$str_for": "G56789",
      "$str_value": "AAAAZ2VsbG8="
    }
  unpacked: 
    {"foo": 1234 }

child_encrypted:
  packed: 
    {
      "foo": {
          "$str_type": "encrypt_v1",
          "$str_for": "G56789",
          "$str_value": "AAAAZ2VsbG8="
      }
    }
  unpacked: 
    {"foo": 1234 }
arrays:
  packed: 
    {
      "foo": [
        "simple",
        {
         "$str_type": "encrypt_v1",
          "$str_for": "G56789",
          "$str_value": "AAAAZ2VsbG8="
        }
      ]
    }
  unpacked: 
    {"foo": ["simple", 1234] }

Second Pass

After the JSON is decrypted it can be sent to the application for further processing. The following are common fields but applications are free to use their own

field description
operations[] Array of info specific to each operation.
note Arbitrary text attached to this transaction or operation intended to be displayed to the recipient.
sender_info Compliance info for the sender. See below.
route Gateway specific routing info for the recipient. (accountID, or username, etc)

Sender info

field description
name Full name of sender
address Mailing address of sender
stellar Payment address of sender (bob*kraken.com)
DOB Date of Birth

Examples

Simple route with message

{
    "note": "Hey thanks for all the Kelp."
    "route": "6387622"
}

Half-Encrypted message

{ 
    "note" : "You can read this but there is secret stuff below."
    "route": {
            $str_type: "encrypt_v1",
            value: E( "127682" )
        }
}

Transaction with 3 payments that each need route info and two of the routes are encrypted.

{
    operations: [{

            "route": "bob"
        }, {
            "route": "127682"
        }, {
            $str_type: "encrypt_v1",
            value: E("route : 127682")
        }
    }]

}

CDN/hosting javascript libraries

One issue we came up on when we did the signup page for the inflation pool was getting users to trust a page enough to put their private key into a form field.

The signup code itself is only 20-30 lines of code, but since we're hosting js-stellar-sdk ourselves, users will have to make sure our version is not instrumented in any way.

Having SDF host the javascript libraries would be very helpful, since the end-users ultimately have to trust SDF. (If they don't, they're in the wrong place anyway)

Something like this perhaps:
cdn.stellar.org/{version-number}}/stellar-sdk.min.js

If you also publish hashes (together w/ the github tag commit perhaps) that would be extra helpful, as web pages could just add SRI to make sure the files aren't changed on your side.

Time format: seconds after year 2000 vs unix timestamp

The switch to having timestamps as seconds after year 2000 gives only 30 years compared to unix timestamp. This doesn't significantly affect the long term timebomb of a 32-bit epoch. Using a uint32, we will run out of space in 2106 with a unix timestamp and 2136 with the 2000 timestamp.

Timestamp libraries are also complex due to the many edge cases (leap years, leap seconds). This complicates things for developers. It would be easier to be compatible with existing unix timestamp libraries.

I'm thinking that a 64-bit unix time stamp would be a better choice especially if we want to plan for long term success of Stellar.

account_tx should allow DestinationTag to be filterable

The account_tx API call should allow you to enter in a destination tag to view transactions that affect an account with the specified destination tag.

If you are only interested in a specific customers account, this will allow faster lookups since each customer will have a unique destination tag.

Access control flags for regular key?

Imagine a gateway which requires email confirmation to authorise trust lines. For such a gateway implementing the cold & hot wallet pattern would be meaningless as the issuing account private (master or regular) key would still have to be present on the servers to authorise trust-lines.

It would be nice if it was possible to limit the access granted to the regular key. A flag of what the regular key can authorise: payment, trust set, offers, etc.

So if I want the regular key to be able to only authorise trust lines, I can safely have the key on my servers without having to worry about too much damage that could be done should it be stolen.

Identity Protocol

Identity Protocol

Complying with AML laws requires financial institutions (FIs) to know not only who their customers are sending money to but who their customers are receiving money from. In some jurisdictions banks are able to trust the KYC procedures of other licensed banks. In other jurisdictions each bank must do its own sanction checking of both the sender and the receiver.
The Identity protocol handles all these scenarios.

The Identity Protocol is an additional step after federation. In this step the sending FI contacts the receiving FI to get permission to send the transaction. To do this the receiving FI creates an AUTH_SERVER and adds it's location to the stellar.toml of the FI.

AUTH_SERVER

The auth endpoint handles two different request types, Auth request and Check request.

Auth request

HTTP POST to https://AUTH_SERVER?data=<json>&sig=<sender sig of data>

data is a block of JSON that contains the following fields:

Name Description
sender The stellar address of the customer that is initiating the send.
need_info If the caller needs the recipient's KYC info in order to send the payment.
tx The transaction that the sender would like to send in XDR format. This transaction is unsigned.
memo The full text of the memo the hash of this memo is included in the transaction. The memo field follows the Stellar memo convention and should contain at least enough KYC info of the sender to allow the receiving financial institution to do their sanction check.

sig is the signature of the data block made by the sending financial institution. The receiving institution should check that this signature is valid against the public key that is posted in the sending financial institution's stellar.toml.

Reply

The auth request will return a JSON object with the following fields:

Name Description
info_status If this FI is willing to share KYC info or not. {ok, denied, pending}
tx_status If this FI is willing to accept this transaction. {ok, denied, pending}
dest_info (only present if info_status is ok) JSON of the recipient's KYC info. in the Stellar memo convention
pending (only present if info_status or tx_status is pending) Estimated number of seconds till the sender can check back for a change in status. See [check request](#Check request) below.

Reply Example

{
    info_status: "ok",
    tx_status: "pending",
    dest_info: {
        type: "encrypt",
        value: "TGV0IHlvdXIgaG9wZXMsIG5vdCB5b3VyIGh1cnRzLCBzaGFwZSB5b3VyIGZ1dHVyZS4="
    },
    pending: 3600
}

Check request

Check request is used by the sender to follow up if the initial [Auth request](#Auth request) wasn't able to complete in real time, i.e. either info_status or tx_status returned pending.

HTTP GET to https://AUTH_SERVER?checkreq=<tx_id>

checkreq tells the AUTH_SERVER that the caller wants an update on the status of the given tx_id. The tx_id is simply the hash of transaction that was auth requested initially.

Reply

Check request has the same reply format as [auth request](#Auth request). It should update the status or tell the caller to continue to wait.


Example of Flow

In this example, Aldi aldi*bankA.com wants to send to Bogart bogart*bankB.com

1) BankA gets the info needed to interact with BankB

BankA -> fetches bankB.com/.well-known/stellar.toml

from this .toml file it pulls out the following info for BankB:

  • FEDERATION_SERVER
  • AUTH_SERVER
  • ENCRYPTION_KEY
  • Needed KYC fields?

2) BankA gets the routing info for Joe so it can build the transaction

BankA -> https://FEDERATION_SERVER?type=name&q=bogart*bankB.com[&simple_kyc=true]

See Federation for a complete description. The returned fields of interest here are:

  • Stellar AccountID
  • Bogart's routing info
  • Need Auth flag that says whether BankB needs to authorize the transaction or not.
  • kyc_yes only returned if simple_kyc is true

3) BankA makes the Auth Request to BankB

This request will ask BankB for Bogart's KYC info and for permission to send to Bogart.

BankA -> https://AUTH_SERVER?data=<json>&sig=<bankA sig of data>

Example data JSON

{
    sender: "aldi*bankA.com",
    need_info: "true",
    tx: <base64 encoded xdr of the tx>,
    memo: 
    {
        type: "encrypt"
        value: encrypted(
        {
            route: <Bogart's routing info>
            sender_info:
            {
                stellar: aldi*bankA.com
                name: Aldi Dobbs
                address: <blah>
            }
        })
    }
}

4) BankB handles the Auth request

  • BankB -> fetches bankA.com/.well-known/stellar.toml
    From this it gets BankA's ENCRYPTION_KEY and SIGNING_KEY
  • BankB verifies the signature on the Auth Request was signed with BankA's SIGNING_KEY
  • BankB does its sanction check on Aldi. This determines the value of tx_status.
  • BankB makes the decision to reveal the KYC info of Bogart or not based on the following:
    • Bogart has made their info public
    • Bogart has allowed BankA
    • Bogart has allowed Aldi
    • BankB has allowed BankA
  • If none of the above criteria are met, BankB should ask Bogart if he wants to reveal this info to BankA and accept this payment. In this case BankB will return info_status: "pending" in the Auth request reply to give Bogart time to accept the payment or not.
  • If BankB determines it can share the kyc info with BankA, it uses BankA's ENCRYPTION_KEY to encrypt Bogart's info and sends this encrypted dest_info back with the reply.

See [Auth Request](#Auth Request) for potential return values.

5) BankA handles the reply from the Auth request

If the call to the auth request returned pending, BankA must check again after the estimated number of seconds.

BankA -> https://AUTH_SERVER?checkreq=tx_id

6) BankA does the sanction checks

Once BankA has been given the dest_info from BankB, BankA does the sanction check using this KYC info of Bogart. If the sanction check passes, BankA signs and submits the transaction to the Stellar network.

7) BankB handles the incoming payment.

  • It checks the transaction hash against a cache it has or redoes the sanction check on the sender.
  • It credits Bogart's account with the amount sent or sends the transaction back.

Payment protocol (directly talking with merchants for faster tx's)

We may want to consider doing something similar to Bitcoin's BIP70. It gives several benefits to merchants such as a simpler communication method between user and merchant as well as returns.

https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#output
http://blog.bitpay.com/2014/06/09/payment-protocol-for-wallets.html

This would be on the same level as federation: not interacting with the daemon but rather web servers and users.

A standard for more user friendly secret key storage

Right now, the only standard way to generate a secret key is through using a secret key. Thats not very user friendly. It'd be nice to have a standard for either:

  1. Passphrase plus encrypted key file (like in myetherwallet)
  2. Mnemonic passphrase

It would be nice to have something standardized and well thought out and secure.

Parent-child account

Not writing CAP yet, just trying to gauge interest in such feature.

Parent/Funder account creates an account with child flag set to true.
Child account must maintain balance higher or equal than CreateAccountOp.StartingBalance and can only be merged with parent.

Use cases:

  • User accounts. Malicious users can exploit the fact that a company funds users' accounts and merge multiple accounts after creating them.
  • ICOs: companies may want to create accounts for participants but don't want them to use/spend/merge their lumens.

Offers do not affect asset balances.

What I mean by this is that when I create an offer with a selling asset of ABCD, my account's asset balance for ABCD is not diminished (I am referring to the asset balance returned by Horizon for the account, I assume this is the same balance that exists in the db).

This results in an individual being able to create multiple offers that sum to a greater balance than is in their account.

I tested this on the test network as follows:

  1. Create an account and fund with 5000 XLM (actually, get 10000 XLM from friendbot and burn 5000 of them).
  2. Create two offers:
    a. Bid 4000 XLM for 50 BTC (price of 80 XLM/BTC)
    b. Bid 4050 XLM for 50 BTC (price of 81 XLM/BTC)
    As mentioned above, because the offers do not affect the account balance, offers can be created with a higher total value that is in the account.
  3. I accepted the offers from another account (with 100 BTC). What happened is that only 4960 XLM worth of BTC was executed and an ask offer created for the rest of the BTC.

I think this behavior is buggy for several reasons:

  1. It is VERY not intuitive for a user to see offers for 100 BTC, accept the offer, and have it only partially execute because some of the offers were vapor offers. Which leads me to point number 2)…
  2. This allows users to manipulate markets. A user can create fake buy or sell walls (and even pop them themselves later) without the funds necessary by simply repeatedly creating offers with a value that is less than their account balance.

I think that an effect of manageOffer should be an adjustment to the account's asset balance.

make it less likely for accounts to get stuck

Right now the clients have to jump through a lot of hoops to prevent accounts from getting stuck:
stellarterm/stellarterm#76
After stuck it is a really bad user experience to get the account usable again.

This mainly results from selling XLM for some other asset.

The proposal is to leave enough lumens in your account to pay the fee for 1000txs when:

  • an offer of yours selling XLM crosses.
  • you send lumens

This way the only way an account can get stuck is if they send/sell all the lumens they can and then do 1000 more txs.

Indivisible Asset type

Certain asset types aren't divisible. For those it doesn't make sense to be able to have fractional amounts.

For example for stocks you really only want to hold and trade integer amounts.

This could be done by creating a new Asset type:
Indivisible Alpha 12 character

Clients would interpret amounts of this asset as integers rather than moving over 7 decimal places.

API to get the count of failed login attempts for a stellar account ID

Need an API to get the count of login attempts failure for a stellar account ID. This API should retrive the data collected by the function loginFailureTracker.record(req.ip).
This will be a good alternative similar to the feature offered by web based email providers who notify us when there are failed login attempts. This is a must have feature until 2FA is implemented.

function actuallyLogin() {
wallet.get(id).then(function(wallet) {
if(typeof wallet === "undefined") {
//TODO: confirm this works well behind cloudflare
loginFailureTracker.record(req.ip);
fail();
} else {
res.send({
"status" : "success",
"data" : _.omit(wallet, ['recoveryId', 'recoveryData'])
});
}
});
}

Drop transaction meta

Transaction Meta takes up a huge amount of disk space and it doesn't seem to provide much more than can be figured out from looking at the ledger before and after. The only use I can see for it is to easily give clients their balance after each tx. But some other client serving server could figure it all out from the raw tx if need be. It doesn't really need to be stellards job.

Thoughts?

New operation proposal: Bump Sequence

Description

Bump sequence allows to bump forward the sequence number of the source account of the operation.

If the specified bumpTo sequence number is greater than the source account's sequence number,
the account's sequence number is updated with that value, otherwise it's not modified.

Threshold: Low

Note:
This operation only allows bumping the sequence number up to (current_ledger_number<<32) - 1.

Return values

BUMP_SEQUENCE_SUCCESS

The source account's sequence number was successfully updated.

BUMP_SEQUENCE_TOO_FAR

The specified bumpTo parameter is greater than the maximum allowed, see note above.

XDR

struct BumpSequenceOp
{
    SequenceNumber bumpTo;
};

/******* BumpSequence Result ********/

enum BumpSequenceResultCode
{
    // codes considered as "success" for the operation
    BUMP_SEQUENCE_SUCCESS = 0,
    // codes considered as "failure" for the operation
    BUMP_SEQUENCE_TOO_FAR = -1 // operation would bump past the maximum sequence number allowed
};

union BumpSequenceResult switch (BumpSequenceResultCode code)
{
case BUMP_SEQUENCE_SUCCESS:
    void;
default:
    void;
};

Implementation considerations on how transaction sets are applied to ledgers

Some background

Currently a transaction set is processed in two phases:

  1. fees and sequence numbers are collected globally
  2. transactions (and their operations) are applied

The problem with this approach is that with the introduction of an operation like BumpSequenceOp,
we have some inconsistencies in the way transactions are processed:
if a transaction bumps the sequence number of an account used in a later transaction, the second
transaction is expected to fail but with the current implementation, it won't (as sequence number
checks are performed while collecting fees).
One the reasons that BumpSequenceOp is introduced is to invalidate ranges of transactions, and
with the current behavior it would make it difficult to reason about the correctness of sequence
of transactions.

Proposed update

Only process fees first:

  1. fees are collected globally
  2. transactions are applied, before applying individual transactions:
    • sequence numbers are checked for validity
    • if the sequence number was valid, update the account's sequence number

We would not change the logic to construct or validate a transaction set:
a transaction set would still be built with transactions that have consecutive sequence numbers.

The difference is that in the event that a transaction is invalidated by an operation from
a different transaction, it would fail (collecting fees), which allows for transactions that make use of BumpSequenceOp to be able to make clean assumptions for any operations scheduled for after the bump.

Example usage

A typical use for this is to allow invalidating large ranges of transactions that were pre-shared with others when implementing complex multi-party transactions that form workflows.

This example has two such workflows:

  • first one is the main path
  • second one is a dispute path, which itself may involve complex dependencies between transactions

Notation

(sequence number, tx source account)[operation1... operation b]

Transactions prepared

main workflow

(1, A)[...], ... , (99, A)[...]

Some transactions may have the same transaction number, as they are logically equivalent to branches:

  • regular flow
    • (5,A)(payment B->C)
    • (6,A)(payment B->E)
  • abort current workflow and enable jumping to the "dispute workflow"
    • (5,A)(bumpSeq 199)
      • when executed, it will invalidate any transactions numbered 6...199

dispute workflow

(200,A)(...), ..., (250, A)(...)

Move stellar.txt => stellar.json before adoption gets to large?

Any reason for not attempting to migrate stellar.txt to JSON (or really any other format) before the gateway / wallet community grows to large to switch?

As far as I understand this is not used by StellarD directly, and would only require community adoption.

Since the TXT format isn't a standard that is widely adopted, this will lead to many people building custom parsers, this could lead to people using slightly incorrect results as more uses are built into the stellar.txt file, that weren't accommodated for in their version of Parser.

TXT Version:

[federation_url]
https://api.stellar.org/federation

[reverse_federation_url]
https://api.stellar.org/reverseFederation

[accounts]
gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F
gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F

[validators]
nakuKsirzNq66iejBfxKxt8Rw4t7kP5ZWSrvWzVKEVSHSkJKYd1   SDF1
n3gVwaSDBtVi4Xd2XBh7rvcwis4uBabu5aNn7WKtEqazJbLHR9n   SDF2
nfozTPzMytTKuuHBJrPB9DVxPccKeNVh8vsEomUAwNWuWrNxwDB   SDF3
naSBAykwFkmw6JLKqPG7HPFMK1GZqu1rdnwbhtTxyTmVX1b6b8z   SDF4
nf3yCmpieMFvAbv5r5jBhGeXheuhc3boAkdmBbpXb6HC7HDkf13   SDF5

[currencies]
USD gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F
SCT gDSSa75HPagWcvQmwH7D51dT5DPmvsKL4q

JSON Version:

{
  "federation_url": "https://api.stellar.org/federation",
  "reverse_federation_url": "https://api.stellar.org/reverseFederation",
  "accounts": [
    "gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F",
    "gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F"
  ],
  "validators": {
    "nakuKsirzNq66iejBfxKxt8Rw4t7kP5ZWSrvWzVKEVSHSkJKYd1": "SDF1",
    "n3gVwaSDBtVi4Xd2XBh7rvcwis4uBabu5aNn7WKtEqazJbLHR9n": "SDF2",
    "nfozTPzMytTKuuHBJrPB9DVxPccKeNVh8vsEomUAwNWuWrNxwDB": "SDF3",
    "naSBAykwFkmw6JLKqPG7HPFMK1GZqu1rdnwbhtTxyTmVX1b6b8z": "SDF4",
    "nf3yCmpieMFvAbv5r5jBhGeXheuhc3boAkdmBbpXb6HC7HDkf13": "SDF5"
  },
  "currencies": {
    "USD": "gJGPgbCnaP3vypwoxtXWEn9tyoARywPE7F",
    "SCT": "gDSSa75HPagWcvQmwH7D51dT5DPmvsKL4q"
  }
}

Proposal: Standardize "amount" representation in client libraries and api

The time is come for us to resolve one of the niggling issues left in the new stellar network: How the API and client libraries deal with numbers that represent an "amount" in a transaction. Example amounts:

  • How much of a given asset will be sent in a payment
  • How much of a given asset will be offered for trade
  • How much of a given asset held by an account

Presently, stellar-core represents these amount as a 64-bit unsigned integer and interprets the number in no other way: It's always using integer math.

However, by convention we say that uint64 is actually a fixed-place decimal number with 7 digits of precision. I'm proposing that we bake this convention into horizon and the client libraries.

To do this, and to gain the most compatibility between language-specific representations and the json representation communicated by horizon, I propose that we should encode amounts as a string containing a decimal number. Some example side effects of this change:

  1. Amounts in horizon would go from being json numbers to strings:
{
                "amount": 50000000.0,
                "asset_type": "native",
}

would become:

{
                "amount": "5",
                "asset_type": "native",
}
  1. The ruby client library would assume the 7 fixed-place decimal representation of any numbers passed into it from user code:
tx = Stellar::Transaction.create_account({
  account:     master,
  destination: destination,
  sequence:    1,
  starting_balance:  50 * Stellar::ONE
})

Would become:

tx = Stellar::Transaction.create_account({
  account:     master,
  destination: destination,
  sequence:    1,
  starting_balance:  50  # or '50' or BigDecimal.new(50)
})

Update threshold range from 0-255 to 1-255

The intention of this issue is to start a conversation around this topic; see conversation from a PR about a change in the docs for multi-sig: stellar-deprecated/docs#237 (comment)

Background:
A threshold of 0 and 1 are effectively the same since we need at least 1 key with a non-zero weight to sign a transaction. By allowing a threshold of 0, we are creating an exception case for the logical condition sum_key_weights >= threshold to make it more like (sum_key_weights >= threshold && threshold > 0) || (sum_key_weights > threshold && threshold == 0) where we treat a 0-threshold differently from a non-0 threshold to account for signing transactions with a key that is weighted at 0.

Proposed solution:
If it's possible to limit the minimum threshold to be 1, we can simplify the condition to be the former, sum_key_weights >= threshold for all cases and more importantly, this will make it simpler for users to understand.
The tricky part here would be dealing with existing accounts and having to update all of them to use this new range (change all 0 thresholds to a 1). There may be other approaches that could make this easier.

Reconsider txINTERNAL_ERROR result of transaction

One of results of executing transaction in stellar protocol is txINTERNAL_ERROR - this means that server has encountered an internal bug that it could not handle (possibly an implementation error). This result is stored in history and is part of input of given ledger hash.

Current stellar protocol has only one implementation - stellar-core by stellar.org, so this is not a big issue. But in future we expect more implementations of protocol. It is hard to expect that they will have the same internal bugs and will return txINTERNAL_ERROR in the same conditions. So it will be possible that some servers will handle given transaction just right and some will return txINTERNAL_ERROR. It will result with different ledger hashes and some nodes will get desynchronized and became unusable.

Finally, these servers will have to get fixed and their history redownloaded to get in sync with other.

I think it would be better to just crash in this case (with lots of logged info, of course). In that case only internal bugs will have to get fixed, no history re-downloading will have to be done. And, what is most important, other servers will not have to reimplement that bug in case when servers returning txINTERNAL_ERROR will be a majority.

Demurrage imposed by an issuer of a credit

The idea of Stellar credits is great since credits since you can track almost anything using the concept of credits. Not only can we send each other currency such as USD but we can also send each other t-shirt credits or rubber ducky credits.

Tracking precious metals as credits

It would be awesome to have precious metals (such as gold and silver) tracked as credits in the Stellar system. Current systems that hold precious metals on the behalf of a customer (like what would happen in a Stellar gateway) currently require a fee that is charged over time for holding the precious metal. In the current system of our world, it costs about 0.5-1% the value of gold per year (source: http://www.bloomberg.com/consumer-spending/2012-05-30/the-real-cost-of-owning-gold.html#slide4)

Demurrage

Because of what was described above, for a gateway to impose fees on ownership of gold credits, demurrage would have to be implemented in the Stellar system.

Supporting "Securitized Assets" (like Mutual Funds, Derivatives, and real world objects)

To summarize this post, I'm describing a system where we use "Accounts as Objects" to store metadata about Assets, to show a hierarchy of links between Assets, to track "service records" for real objects, and otherwise announce and distribute public information generally and encrypted information privately between parties regarding assets they have a shared interest in.

This does not require much, if any, software change, it's mostly a convention for how to use passphrases.


An Asset Holding entry in an account is typically representative of some other thing. Shares of IBM for example represent some portion of distributions from the company IBM; and an Index Fund/Mutual Fund represents holding some percentage of a "collection" of other things.

I'm proposing/have begun to use accounts to describe what's in the collection for that Asset.

For example, "The Vanguard Group" issues their "Vanguard 500 Index Fund" (NASDAQ ticker VFIAX).

Assuming I owned some of that, I'd look in my wallet and I'd see a balance, say 50 units, on a line with, most likely, its ISIN based on current practices as the asset identifier (even though ISIN isn't globally unique enough to represent the same share class from a company, nor is it technically legal to distribute through public channels (because of the SEDOL/CUSIP that are embedded within it); but that's a different discussion entirely ;) ).

But the question is what's actually in that Mutual Fund? What does that mutual fund asset actually hold?
In other words: http://www.marketwatch.com/investing/fund/VFIAX/holdings

Here's a WIP (work in progress) proposal:
Concatenate "/ + [issuer id] + "/" + [Asset identifier] + ":Asset" and hash that to get a keypair.
Use that keypair to access an account, controlled by the issuer, representing the holdings for that asset.

Each asset balance record (including XLM) has an issuer and an asset identifier. This is using only that information (plus the keyword ":Asset") to look up that "Asset Object" in the ledger database. (It's just called an "Account" at the moment.)

To look up the Asset Object for XLM (because the issuer is null) would be the passphrase "//XLM:Asset"
The passphrase for the Vanguard example above "/[somepublicaccountid]/US9229087104:Asset"

By retrieving the balances from that account I can see what that account holds. By looking at the KVP store I can see the set of issued metadata about the Asset Object.

If that account holds another mutual fund (like 401ks do); then I can recursively look that up again. A wallet can navigate my entire tree of holdings this way (and yes it needs to look out for cycles, which it can do by keeping a hash table of the asset passphrases it's processed so far).


Let's look at a derivative, like a group of mortgages; it's notoriously difficult to figure out exactly who owns your bank loan if you have a mortgage (sure your bank is collecting the checks, but they sold the loan off and are now just "servicing the account" for the actual owner(s)).

Each mortgage loan would be identified on the system by its own asset id issued by the original issuer, a collection of those assets would get bundled into another asset and sold as a group, those groups can even be bundled again and sold off as an investment fund or outright ownership transfer.

Using this scheme, the system could store metadata about, and the contents of, each asset and asset collection. Through the derived public account address, it's a well-known location every interested party can look.
Again it'd just be hashing the passphrase: "/[assetissueraddress]/[assetidentifier]:Asset"

Your wallet could dig through the derivatives and, at least to the degree public information has been populated/updated by the issuer, see what's in there (and hopefully derive better info).

I could easily see "automated services" which collect monthly/quarterly published information and files and then associate it with an asset object using the KVPs; using some appropriate key_name, and then some IPFS (or similar) address as the value. Assuming the Stellar node was also running IPFS, it could even retrieve the data if requested/required.


Lastly, let's look at real world objects; specifically manufactured ones with a Serial Number and a Product Code.

Imagine a laptop manufacturer creates a new Account to hold metadata about their new Product.
passphrase: "/" + [manufacturersaccountid] + "/Laptops/" + [ProductCode] + ":Asset"
It now has a shiny new account at address: [ManufacturersProductAccount]

Further, everytime a new laptop rolls off the production line it makes another asset account
passphrase: "/" + [ManufacturersProductAccount] + "/" + [LaptopSerialNumber] + ":Asset"
The manufacturer now controls another account: [SpecificLaptopInstanceAccount]

Inside that account are holdings of all the specific serial numbers for each part that went into making that laptop. This specific laptop instance can now be sold, bundled into a pallet account with a bunch of other laptops for shipping, and theoretically tracked from manufacturer all the way to third hand owner.

This same concept can be applied to cars and VIN numbers, books and ISBN numbers, and UPC codes.
Stellar has the framework for globally and publicly creating and tracking each "instance" of an asset or the asset as a total collection.

A manufacturer can make an "Announcement" about the product line, like a recall, a product manual or product manual update, upcoming press release, software updates, or communicate about the product line in general by attaching new KVP entries to the Product Line issuer account. The "value" of the KVP in these cases would be a pointer to where the actual data can be retrieved (limit of 64 bytes) presumably something like an IPFS address (or other suitable OOB address) .

Now let's say I bought one and registered that specific laptop in one of my Asset Accounts.
I could have some local software that periodically checked the Product Line account and SpecificLaptopAccount for any updates posted by the manufacturer and let me know.

Finally, using the "encrypted data" proposal from issue #26, when I take my laptop in to Best Buy to get serviced; they have a mechanism for creating an account with the combined "BestBuy" + "MikeFair" +"SpecificLaptopSerialNumber" accounts passphrase.

Now BestBuy and I have a "Service Record Account" where we can share information about services performed, problems encountered, replacement parts used, and in general any other useful information about our combined interest in this latop (perhaps even using the account to track an invoice request and a payment txn?). Further because the [SpecificLaptopSerialNumber] account is also part of the trio, there's potential there for directly looping in the manufacturer on the case if required (like perhaps tracking a ticket number or something similar).

Making well-known pre-approved transactions useful

The ability to authorize certain transactions by approving their hash under the account signers is quite a powerful concept. It also has the potential to cater for a certain subset of smart contracts, if used creatively. A state machine can be constructed with the prepared transactions that make up a chain of valid actions that can be executed.

For example, a near-zero-trust escrow account contract could be constructed using those principles. In an escrow smart contract we need 3 parties: the sender, the recipient and the 3rd party dispute resolver. The contract needs to support the following state flows:

  1. consumer [sender] deposits funds -> consumer [sender] releases funds once the goods have been received
  2. consumer [sender] deposits funds -> merchant [recipient] returns funds to consumer as they were unable to hold up their end of the bargain
  3. consumer [sender] deposits funds -> merchant [recipient] starts a dispute because the goods were delivered but the consumer didn't release funds -> dispute resolver examines the facts and determines which party gets the escrowed funds
  4. consumer [sender] deposits funds -> merchant [recipient] has not responded in 30 days, the escrow account will be unlocked and funds returned to consumer [sender]

This can be achieved by preparing the following transactions:

  1. completeEscrow: sender releases funds to the recipient
  2. refundEscrow: recipient releases funds back to sender
  3. beginDispute: recipient adds 2 dispute resolution transaction hashes (completeDisputedEscrow, refund_disputed_escrow) to the account
  4. unlockExpiredEscrow: sender unlocks the account to transfer funds back to themselves (time locked)
  5. completeDisputedEscrow: dispute resolver releases funds to recipient subtracting dispute handling fee from the funds
  6. refundDisputedEscrow: dispute resolver releases funds back to sender subtracting dispute handling fee from the funds

In order for all parties to trust the contract, the transactions which produce the pre-authorized hashes need to be known by all parties. In effect those transactions can be considered well-known and public knowledge.

In order to setup the transactions in that way we need to rely on couple of assumptions:

  • Transactions follow ACID
    • Transactions are constructed to expect certain amount of assets to be available on the escrow account and will fail if there aren't, in a waythat they could be repeated later when there are enough funds
    • Transactions need the ability to limit who can execute them and in case the wrong signer tries to execute them they need to fail, only to be later succeeded when signed by the correct signer
  • Account sequence number is used to lock out a set of transactions once one of them has been executed

My first attempt at limiting transactions to certain signers was to add the signer and increasing the required weights at the start of the transaction and remove them at the end. But apparently the transaction signature validation happens too early for this kind of approach to work (stellar/stellar-core#1329). My second attempt at this was to add the signers to the account and remove the disallowed signers at the beginning of the transaction which results in the transaction failing for wrong users, which by transaction ACID promises made by documentation should work fine. See below for example code of constructing the transactions.

But in reality even the failed transaction manages to increase the account sequence number according to stellar/stellar-core#1330 . Which basically makes well-known public transactions useless as anyone can try to execute them and make them invalid for the future. For example, in our previous escrow example the sender could take the transaction meant for the recipient, submit it with the wrong signatures and the recipient wouldn't ever be able to use that transaction themselves.

In stellar/stellar-core#1330 vogel suggested proposing changes to the protocol that would allow transactions with flexible sequence number to be preauthorized. However, I personally feel that the whole sequence number incremented when the actual transaction failed to apply makes more sense to "fix".

Though, of course, I'm not that versed in the nitty-gritty of the protocol to know why this kind of design decision was made in the first place. Maybe it's for a good reason (protecting against spammy behaviour or some such). Though in that case claiming that the transaction are ACID is somewhat false and the actual usecases for the pre-authorized transaction hashes drops significantly.

I would like to start a discussion around how to make such contracts possible on the Stellar network. And if such usecase is even something that the core team considers worthwhile?

JS code example of constructing an escrow account contract

function prepareEscrowTransactions(escrowKeypair, escrowSequence, escrowExpires, senderSignKeypair, recipientSignKeypair) {
  var escrowSequence = new BigNumber(escrowSequence);

  var completeEscrowTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(1).toString()), {
      timebounds: {
        minTime: 0,
        maxTime: escrowExpires,
      },
    })
    // Remove keys that aren't allowed to perform this transaction
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        ed25519PublicKey: recipientSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    // Complete escrow payment
    .addOperation(StellarSdk.Operation.payment({
      destination: recipientKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: escrowAmount.toString(),
    }))
    .addOperation(StellarSdk.Operation.payment({
      destination: providerKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: providerFeeAmount.toString(),
    }))
    // Hand over account access back to the provider
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 1,
      medThreshold: 1,
      highThreshold: 1,
      signer: {
        ed25519PublicKey: senderSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    .build();

  var refundEscrowTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(1).toString()), {
      timebounds: {
        minTime: 0,
        maxTime: escrowExpires,
      }
    })
    // Remove keys that aren't allowed to perform this transaction
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        ed25519PublicKey: senderSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    // Cancel the escrow payment
    .addOperation(StellarSdk.Operation.payment({
      destination: senderKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: escrowAmount.toString(),
    }))
    .addOperation(StellarSdk.Operation.payment({
      destination: providerKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: providerFeeAmount.toString(),
    }))
    // Hand over account access back to the provider
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 1,
      medThreshold: 1,
      highThreshold: 1,
      signer: {
        ed25519PublicKey: recipientSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    .build();

  var completeDisputedEscrowTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(2).toString()))
    .addOperation(StellarSdk.Operation.payment({
      destination: recipientKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: (escrowAmount - disputeFeeAmount).toString(),
    }))
    .addOperation(StellarSdk.Operation.payment({
      destination: providerKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: (providerFeeAmount + disputeFeeAmount).toString(),
    }))
    // Hand over account access back to the provider
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 1,
      medThreshold: 1,
      highThreshold: 1,
    }))
    .build();

  var refundDisputedEscrowTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(2).toString()))
    .addOperation(StellarSdk.Operation.payment({
      destination: senderKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: (escrowAmount - disputeFeeAmount).toString(),
    }))
    .addOperation(StellarSdk.Operation.payment({
      destination: providerKeypair.publicKey(),
      asset: StellarSdk.Asset.native(),
      amount: (providerFeeAmount + disputeFeeAmount).toString(),
    }))
    // Hand over account access back to the provider
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 1,
      medThreshold: 1,
      highThreshold: 1,
    }))
    .build();

  var beginDisputeTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(1).toString()), {
      timebounds: {
        minTime: 0,
        maxTime: escrowExpires,
      },
    })
    // Remove keys that aren't allowed to perform this transaction
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        ed25519PublicKey: senderSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    // Prepare the dispute transactions
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        preAuthTx: completeDisputedEscrowTx.hash(),
        weight: 2,
      },
    }))
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        preAuthTx: refundDisputedEscrowTx.hash(),
        weight: 2,
      },
    }))
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 3,
      medThreshold: 3,
      highThreshold: 3,
      signer: {
        ed25519PublicKey: recipientSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    .build();

  var unlockExpiredEscrowTx = new StellarSdk.TransactionBuilder(new StellarSdk.Account(escrowKeypair.publicKey(), escrowSequence.add(1).toString()), {
      timebounds: {
        minTime: escrowExpires,
        maxTime: 0,
      }
    })
    // Hand over account access back to the provider
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        ed25519PublicKey: senderSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    .addOperation(StellarSdk.Operation.setOptions({
      signer: {
        ed25519PublicKey: recipientSignKeypair.publicKey(),
        weight: 0,
      },
    }))
    .addOperation(StellarSdk.Operation.setOptions({
      masterWeight: 1,
      lowThreshold: 1,
      medThreshold: 1,
      highThreshold: 1,
    }))
    .build();

  return {
    completeEscrow: completeEscrowTx,
    refundEscrow: refundEscrowTx,
    beginDispute: beginDisputeTx,
    completeDisputedEscrow: completeDisputedEscrowTx,
    refundDisputedEscrow: refundDisputedEscrowTx,
    unlockExpiredEscrow: unlockExpiredEscrowTx,
  }
}

var txs = prepareEscrowTransactions(escrowKeypair, escrowSequence, escrowExpires, senderSignKeypair, recipientSignKeypair);

var tx = new StellarSdk.TransactionBuilder(escrowAccount)
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      ed25519PublicKey: senderSignKeypair.publicKey(),
      weight: 1,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      ed25519PublicKey: recipientSignKeypair.publicKey(),
      weight: 1,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      preAuthTx: txs.completeEscrow.hash(),
      weight: 2,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      preAuthTx: txs.refundEscrow.hash(),
      weight: 2,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      preAuthTx: txs.beginDispute.hash(),
      weight: 2,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    signer: {
      preAuthTx: txs.unlockExpiredEscrow.hash(),
      weight: 2,
    },
  }))
  .addOperation(StellarSdk.Operation.setOptions({
    masterWeight: 0,
    lowThreshold: 3,
    medThreshold: 3,
    highThreshold: 3,
  }))
  .build();

tx.sign(escrowKeypair);
server.submitTransaction(tx);

`forward` request parameters in stellar.toml (SEP-0001)

From Federation doc:

Your stellar.toml file should specify what parameters you expect in a forward federation request

We need to add information about it in stellar.toml doc. Probably something like:

FORWARD_FEDERATION_PARAMS=[
"forward_type", # One of "bank_account", "mobile_number"
"swift", # Bank account SWIFT code, forward_type=bank_account
"acct", # Bank account number, forward_type=bank_account
"mobile_number" # Mobile number, forward_type=mobile
]

CC: @jedmccaleb

account_lines ledger bloat and API inefficiencies

Looking at account_lines and they way they are use by the official client, wouldn't is make more sense NOT to extend trust to EVERY issued currency for an issuer?

Taking justcoin as an example, there's 7318 trust lines right now. How many of those are ever going to be used? There's somewhere around 100 people actually holding currency.

If you, like me, think the stellar.txt approach is a rather weird design decision, then my only option today is to download the whole thing and parse it.

  1. From a ledger bloat perspective, let the user decide what currencies to trust, and don't just default to "*"

  2. From a client perspective, how about adding an "issued"-stanza to account_currencies?

Destination tags should be 64-bit

Destination tags, as I understand them, are unsigned 32-bit integers. That seems like an unnecessary limitation. They should be 64-bit integers. JavaScript can use strings to represent them if that's a concern (as JavaScript can only represent integers up to 52 bits).

A few points in favor:

  1. In the theoretical future world where Stellar takes off and is used everywhere, one recipient might actually need to distinguish payments to more than 4 billion different accounts. Using multiple destination addresses isn't a great solution, because people will expect to be using something like [email protected]. As an example of who might need more than 4 billion tags, a gateway that converts between STR and BTC (assuming BTC also is ubiquitous) might, as BTC addresses are free to create and therefore you could have tens or hundreds of addresses per user.
  2. Proving ownership of an address is easiest done by sending a payment of a specified tiny amount to an address with a unique destination tag. 4 billion tags is a lot, but it's still not enough to really be totally secure. With a 10 stroop fee, and assuming a 1 stroop payment (because the payment amount is irrelevant), you can run through all the tags with just over 47k STR. With the current value on stellarvalue.org (I'm not sure how accurate it is, but it's ballpark at least), that's less than $300. Bumping the destination tags up to 64-bit obviously makes this attack impossible.

I can't think of any good reason against this change. 64-bit integers are easy to handle in modern software, have no real performance penalty to speak of, and as I said before, JavaScript clients can treat it as a string, they have no need to actually represent it as a number

Proposal: Use federation for additional asset information

Federation is currently used for account related stuff. Maybe expand this with information about an asset that may be useful for wallets. Using the homedomain of the issuer's account it can query the federation server using the assetcode and address. After an initial request it can cache it for some time to not flood the federation server as the values probably won't change that much.

A wallet can use this metadata to show an asset as it is meant to be shown by the issuer. This can allow different wallets to have an uniform representation of the same asset.

Request:

https://api.stellar.org/federation?q=EUR*[issuers_address]&type=asset

Response:

status: 200
{
    code: "EUR",
    issuer: "[address]",
    name: "Euro's",
    symbol: "€",
    ui_decimals: 2,
    ui_step_increment: 0.25,
    ... : ?
}

Merge ledger_index and ledger_hash params

A bunch of API methods accept optional ledger_index or ledger_hash parameters. They fulfill the same role and since it's easy to distinguish between "current", "validated", an integer or a hash string, I think they can be merged into a single ledger parameter which would accept any of those values.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.