1
0
mirror of https://github.com/bigchaindb/site.git synced 2024-11-22 17:50:07 +01:00
site/_src/_guide/tutorial-token-launch.md

186 lines
9.9 KiB
Markdown
Raw Normal View History

2017-11-19 18:57:39 +01:00
---
layout: guide
2017-11-22 21:05:09 +01:00
title: "Tutorial: How to launch your own token on BigchainDB"
2017-12-29 13:17:01 +01:00
tagline: Learn how to use divisible assets in BigchainDB for token generating events
2017-11-19 18:57:39 +01:00
header: header-token.jpg
2017-11-23 13:27:25 +01:00
order: 3
2017-11-19 18:57:39 +01:00
2017-11-20 11:04:08 +01:00
learn: >
- How to use divisible assets on BigchainDB
2017-11-22 21:05:09 +01:00
- How assets in BigchainDB can represent tokens
2017-11-22 21:05:09 +01:00
- How tokens can be distributed to participants using TRANSFER transactions
2018-01-12 13:55:28 +01:00
- How various BigchainDB transactions can be combined together
2017-11-20 11:04:08 +01:00
---
2017-11-19 18:57:39 +01:00
2017-11-24 11:13:01 +01:00
Hi there! Welcome to our next tutorial about divisible assets. For this tutorial, we assume that you are familiar with the BigchainDB primitives (assets, inputs, outputs, transactions etc.). If you are not, familiarize yourself with the [Key concepts of BigchainDB](../key-concepts-of-bigchaindb/). We also assume that you have completed our [first tutorial](../tutorial-car-telemetry-app/).
2017-11-22 21:05:09 +01:00
2017-12-29 13:17:01 +01:00
# About token generating events
2017-11-22 21:05:09 +01:00
2017-12-29 13:17:01 +01:00
In the last 12 months we have witnessed exponential growth in token generating events. Many of them have been launched on Ethereum. Since we are experiencing rising interest in potential token launches on BigchainDB, this tutorial aims at showing a very simple approach on how to launch your own token on BigchainDB.
2017-11-20 13:19:16 +01:00
2017-12-29 13:17:01 +01:00
This tutorial just aims at illustrating the usage of one building block, namely divisible assets. An actual token launch is much more complex and requires other components which are not discussed here. Furthermore, BigchainDB is currently not yet ERC20 compatible.
2017-11-20 13:19:16 +01:00
{% include_relative _setup.md %}
2017-11-19 18:57:39 +01:00
2017-11-22 21:05:09 +01:00
# Usage of divisible assets to create tokens
2017-11-20 10:18:32 +01:00
2017-11-24 11:13:01 +01:00
In BigchainDB, a token generation can be represented as a divisible asset. A divisible asset is an asset that has a fixed number of sub-assets linked to it. This means that the create transaction contains more than that asset. The linked fixed sub-assets represent your tokens. When creating a divisible asset in BigchainDB, the number of the sub-assets (tokens) that you want to create needs to be specified in the beginning. That number represents your fixed total supply of tokens.
2017-11-23 11:07:10 +01:00
The code below illustrates how to create a divisible asset with 10 000 tokens associated to it.
2017-11-20 13:19:16 +01:00
2017-11-19 18:57:39 +01:00
```js
const nTokens = 10000
let tokensLeft
2018-01-09 14:22:47 +01:00
const tokenCreator = new BigchainDB
.Ed25519Keypair(bip39.mnemonicToSeed('seedPhrase').slice(0,32))
2017-11-19 18:57:39 +01:00
function tokenLaunch() {
2017-11-24 11:13:01 +01:00
// Construct a transaction payload
2017-11-19 18:57:39 +01:00
const tx = BigchainDB.Transaction.makeCreateTransaction({
2017-12-06 10:28:05 +01:00
token: 'TT (Tutorial Tokens)',
2017-11-19 18:57:39 +01:00
number_tokens: nTokens
2017-11-24 11:13:01 +01:00
},
// Metadata field, contains information about the transaction itself
// (can be `null` if not needed)
{
2017-11-19 18:57:39 +01:00
datetime: new Date().toString()
2017-11-24 11:13:01 +01:00
},
2017-12-29 13:19:11 +01:00
// Output: Divisible asset, include nTokens as parameter
2017-12-18 11:25:40 +01:00
[BigchainDB.Transaction.makeOutput(BigchainDB.Transaction
.makeEd25519Condition(tokenCreator.publicKey), nTokens.toString())],
2017-11-19 18:57:39 +01:00
tokenCreator.publicKey
)
2017-12-18 11:25:40 +01:00
// Sign the transaction with the private key of the token creator
const txSigned = BigchainDB.Transaction
.signTransaction(tx, tokenCreator.privateKey)
2017-11-19 18:57:39 +01:00
2017-12-18 11:25:40 +01:00
// Send the transaction off to BigchainDB
2018-04-06 14:05:11 +02:00
conn.postTransactionCommit(txSigned)
2017-11-19 18:57:39 +01:00
.then(res => {
tokensLeft = nTokens
2017-11-24 11:13:01 +01:00
document.body.innerHTML ='<h3>Transaction created</h3>';
// txSigned.id corresponds to the asset id of the tokens
document.body.innerHTML +=txSigned.id
2017-11-19 18:57:39 +01:00
})
}
```
2017-12-29 13:17:01 +01:00
With these commands, you have minted 10000 tokens. For that, give an extra parameter to the `makeOutput()` function. Pay attention to give the function a string instead of a plain number. With the `tokenCreator` keypair you indicate who will be the owner of the tokens. This could for instance be the foundation issuing the tokens. Once this transaction is accepted by BigchainDB, you update the value of the tokens left in the possession of the creator. Right now, all the tokens created are associated with the public key of the creator (`tokenCreater.publicKey`).
2017-11-19 18:57:39 +01:00
2017-11-24 11:13:01 +01:00
Now that the tokens have been minted, you can start distributing them to the owners.
2017-11-19 18:57:39 +01:00
2018-01-12 14:24:27 +01:00
# Distribution of tokens
2017-11-20 10:18:32 +01:00
2017-11-24 11:13:01 +01:00
Tokens can be transferred to an unlimited number of participants. In this example, you are now going to make a transfer transaction to transfer 200 tokens to a new user called John. For that, you first need to create a new user and then do the transfer. The code below shows that.
2017-11-23 14:26:33 +01:00
2017-11-19 18:57:39 +01:00
```js
const amountToSend = 200
2018-01-09 14:22:47 +01:00
const newUser = new BigchainDB
.Ed25519Keypair(bip39.mnemonicToSeed('newUserseedPhrase')
.slice(0, 32))
2017-11-19 18:57:39 +01:00
function transferTokens() {
2017-12-29 13:17:01 +01:00
// User who will receive the 200 tokens
2017-11-19 18:57:39 +01:00
const newUser = new BigchainDB.Ed25519Keypair()
2017-12-29 13:17:01 +01:00
// Search outputs of the transactions belonging the token creator
// False argument to retrieve unspent outputs
2017-11-19 18:57:39 +01:00
conn.listOutputs(tokenCreator.publicKey, 'false')
.then((txs) => {
2018-01-09 14:22:47 +01:00
// Just one transaction available with outputs not being spent by
// tokenCreator. Therefore, txs[0]
2017-11-24 11:13:01 +01:00
return conn.getTransaction(txs[0].transaction_id)
})
2018-01-09 14:22:47 +01:00
.then((txOutputs) => {
2017-11-24 11:13:01 +01:00
// Create transfer transaction
2018-01-09 14:22:47 +01:00
const createTranfer = BigchainDB.Transaction
.makeTransferTransaction(
[{
tx: txOutputs,
output_index: 0
}],
// Transaction output: Two outputs, because the whole input
// must be spent
[BigchainDB.Transaction.makeOutput(
BigchainDB.Transaction
.makeEd25519Condition(tokenCreator.publicKey),
(tokensLeft - amountToSend).toString()),
BigchainDB.Transaction.makeOutput(
BigchainDB.Transaction
.makeEd25519Condition(newUser.publicKey),
amountToSend)
],
// Metadata (optional)
{
2018-01-12 13:55:28 +01:00
transfer_to: 'john',
2018-01-09 14:22:47 +01:00
tokens_left: tokensLeft
}
)
2017-11-24 11:13:01 +01:00
// Sign the transaction with the tokenCreator key
2017-12-18 11:25:40 +01:00
const signedTransfer = BigchainDB.Transaction
2018-01-09 14:22:47 +01:00
.signTransaction(createTranfer, tokenCreator.privateKey)
2017-11-24 11:13:01 +01:00
2018-04-06 14:05:11 +02:00
return conn.postTransactionCommit(signedTransfer)
2017-11-19 18:57:39 +01:00
})
2017-11-24 11:13:01 +01:00
.then(res => {
// Update tokensLeft
tokensLeft -= amountToSend
2017-12-18 11:25:40 +01:00
document.body.innerHTML += '<h3>Transfer transaction created</h3>'
2017-11-24 11:13:01 +01:00
document.body.innerHTML += res.id
})
2017-11-19 18:57:39 +01:00
}
```
2017-11-23 14:52:51 +01:00
You have now transferred 200 tokens to the user John. You could repeat the same with multiple other users.
2017-12-29 13:17:01 +01:00
With `listOutputs` using `false` as the second argument you retrieved all the outputs belonging to the user `tokenCreator`, that were not spent yet. There will just be one output that fulfills these characteristics, because when you transfer tokens to another user, you are spending this output and giving the ownership to the other user. Then, you queried for that transaction and made a transfer to John with it. Note however, that there is also a transaction back to `tokenCreator.publicKey`, as you need to 'give back change' due to BigchainDB's transaction model. It is designed in a way that all of the inputs have to be spent in a transaction. That means that if you send part of the `tokensLeft` (200 tokens) to John, you have to send the rest (9800 tokens) back to the `tokenCreator` to preserve that amount.
2017-11-23 14:26:33 +01:00
2018-01-12 14:24:27 +01:00
# Combination of different BigchainDB transactions
2018-01-09 10:05:10 +01:00
Imagine now that you have received several transactions of tokens and you want to combine all of the balances and transfer them to another user (e.g. your best friend, who keeps some tokens in escrow). In BigchainDB, this is possible as well. The code below illustrates how to do that.
2018-01-02 13:53:40 +01:00
```js
const amountToSend = 200
const bestFriend = new driver.Ed25519Keypair()
function combineTokens(transaction1, outputIndex1, transaction2, outputIndex2,
totalTokens) {
const combineTranfer = BigchainDB.Transaction.makeTransferTransaction(
[{
tx: transaction1,
output_index: outputIndex1
}, {
tx: transaction2,
output_index: outputIndex2
}],
2018-01-09 14:22:47 +01:00
// Output
2018-01-02 13:53:40 +01:00
[BigchainDB.Transaction.makeOutput(
BigchainDB.Transaction.makeEd25519Condition(
bestFriend.publicKey),
2018-01-09 14:22:47 +01:00
(totalTokens).toString())], {
2018-01-02 13:53:40 +01:00
transfer_to: 'my best friend'
}
)
// Sign the transaction with the newUser key
const signedTransfer = BigchainDB.Transaction
.signTransaction(combineTranfer, newUser.privateKey)
2018-04-06 14:05:11 +02:00
return conn.postTransactionCommit(signedTransfer)
2018-01-02 13:53:40 +01:00
}
```
2018-01-09 10:05:10 +01:00
You just made a transfer transaction combining two different transactions into one output. Note that the `totalTokens` quantity is a required variable. It is the sum of the tokens of the two outputs being spent. As you have seen before, if this quantity is not correct, the transaction will fail, as you literally need to spend all of the outputs in a transaction.
2018-01-12 13:55:28 +01:00
`transaction1` and `transaction2` can look like the transaction `createTranfer` that you did before. In that case, the `outputIndex1` and `outputIndex2` would be `0`.
2018-01-02 13:53:40 +01:00
2017-11-23 14:52:51 +01:00
Note that in our example, the supply of your tokens was fixed and cannot be changed anymore after creation. So, you would need to clearly define for yourself, how many tokens you will need. However, BigchainDB does offer the option of refillable, divisible assets that allow for a more dynamic token supply. You can learn more about that [here](https://github.com/bigchaindb/bigchaindb/issues/1741).
2017-11-19 18:57:39 +01:00
2017-11-23 14:52:51 +01:00
That's it! Now you know, how divisible assets in BigchainDB can be used as a potential building block for token launches. Of course, in practice a token distribution event is much more complex and requires other important building blocks like smart contracts etc. But, this tutorial showed you how divisible assets can play a part of that.