Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KIP-0006: Standard Token Transfer Process #11

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions kip-0006.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
KIP: KIP-0006
Title: transfer standard
Author: Doug Beardsley doug@kadena.io
Status: Draft
Type: Standard
Category: API
Created: 2020-08-12
---

## Abstract

Define a standard process / algorithm for handling Kadena token transfers that
facilitates smooth interoperability between various tools, services, and
ecosystem participants.

## Motivation

Kadena users have discovered that various parts of the Kadena ecosystem
(exchanges, wallets, etc) don't always interoperate seamlessly. Here are some
real problems that we have encountered:

1. Transfers from one entity to another fail because because the receiving
account already existed and the sending entity used `transfer-create` with a
keyset that didn't match the one already defined for the account.
2. Transfers from one entity to another fail because the sending entity only
supported the `transfer` function but the user didn't have an existing
account or any coins by which to create one.
3. One tool or entity exports an address format not supported by other entities.

## Rationale

The Kadena ecosystem has several features that make this task complex: native
support for multi-sig (enabled by what we call "keysets"), an account model (as
opposed to a UTXO model) with stable account names and the ability to rotate
keysets, and multiple chains which unavoidably increase complexity for certain
types of transfers.

Kadena tokens can be sent using one of three methods: `transfer`,
`transfer-create`, or `transfer-crosschain`. KIP-0002 [1] and KIP-0005 [2] are
the relevant KIPs where these functions are specified. The actual code used by
Chainweb for this can be found at [3].

### Requirements

In order to fully support token transfers in the Kadena ecosystem, the following
requirements must be satisfied:

1. SHOULD Use a single recipient input field
2. MUST support transfers to recipient account that doesn't exist
3. MUST support transfers to any recipient account that does exist and not fail
unnecessarily
4. SHOULD Warn about key mismatch
5. MUST support all of the following recipient formats: TxBuilder, single public
key, account name

#### High Level Transfer Flow Chart

[Flow Chart](kip-0006/transfer-flow-chart.png)

#### Single Recipient Input Field

Fully specifying a Kadena account can require quite a bit of data. Nice UIs for
specifying all of it as multiple input fields are complex to specify and build.
To keep the user experience simple, we recommend having a single input field
where the recipient information can be pasted.

#### Transfer to New Accounts

Systems that support Kadena token transfers MUST include support for
transferring to accounts that haven't been created yet. This is crucial for
onboarding new users who don't already hold KDA.

#### Transfer to Any Existing Account

It should be possible to transfer to ANY account that already exists on the
Kadena blockchain. We have seen some systems fail to do this because they used
`transfer-create` with a default keyset predicate. This will fail if the
predicate doesn't match the one already associated with the account. The only
potential exception to this is key mismatch, our next section...

#### Warn About Key Mismatch

Since Kadena account names have to be unique, it is often desireable to make the
account name be the same as the public key. Since public keys are randomly
generated and have 2^256 possible values, using the public key as the account
name is an easy way to guarantee uniqueness. However, if the account name is one
public key and the keyset has a different public key, users could end up
transferring tokens to an account that is not controlled by the person they
think it's controlled by.

Kadena transfer systems should detect when an account name is a public key and
warn the user if the account's keyset is anything other than a single key keyset
with the same public key.

#### Recipient Formats

One of at least three formats should be accepted in the recipients field:
TxBuilder, public key, and account name. This can be implemented easily by first
attempting to parse the recipient as a TxBuilder. The TxBuilder data structure
contains all the information necessary to specify a recipient, so if the
recipient is a valid TxBuilder, the transfer can be done immediately. It is
possible that the transfer could fail, but that is unavoidable user error.

If the recipient data is not a valid TxBuilder, the next step is to check if it
is a valid public key. In many other blockchains public keys define an account,
so this is important for making the Kadena ecosystem more accessible to
newcomers.

TODO add more detail about proper handling of the public key case

Finally, if the recipient data is not a valid public key, then we assume it is
an account name. In this case, we can do a `transfer` to that account name. If
possible, it is desireable to call the `details` function with that account name
to get balance and key information to show the user so they can sanity check
that the account is indeed controlled by the key(s) they expect.

## Backwards Compatibility

N/A

## Specification

### TxBuilder

A TxBuilder is a JSON representation of all the information needed to specify
the recipient of a token transfer. Here is an example:

```
{
"account": "my-test-account",
"chain": "00",
"keyset": {
"keys": [
"b7d76b10eaff025a8c3307b8eb8804b1d4f68976176cd297e8da1c603a190ecb",
"e0fe8143702c6b706a8a2b18a675abcf517f26a43f12a4f375479974c394a305"
],
"pred": "keys-any"
}
}
```

The `account` and `chain` fields are mandatory. They `keyset` field is optional.
Both the `transfer-create` and `transfer-crosschain` functions require a keyset,
so omitting the `keyset` field usually suggests the use of the `transfer`
function.

The `keys` field specifies a list of keys that control this account. Currently
these are always 64-character hex strings that represent ED25519 public keys. In
the future more key types will be supported and the key representation will
include information about what signature algorithm is being used.

The `pred` field specifies the keyset predicate that determines how many
signatures are required to sign transactions for this account. There are three
built-in predicates: `keys-all`, `keys-any`, and `keys-2`. Other user-specified
predicates are supported but that topic is out of scope for this document.

## References

[1] https://github.com/kadena-io/KIPs/blob/master/kip-0002.md
[2] https://github.com/kadena-io/KIPs/blob/master/kip-0005.md
[3] https://github.com/kadena-io/chainweb-node/tree/master/pact/coin-contract

Binary file added kip-0006/transfer-flow-chart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.