diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/JWT.md | 18 | ||||
-rw-r--r-- | content/_index.md | 14 | ||||
-rw-r--r-- | content/block_docs.md | 33 | ||||
-rw-r--r-- | content/misc_docs.md | 4 | ||||
-rw-r--r-- | content/register_docs.md | 21 | ||||
-rw-r--r-- | content/transaction_docs.md | 35 |
6 files changed, 64 insertions, 61 deletions
diff --git a/content/JWT.md b/content/JWT.md index 46da1a2..e77457f 100644 --- a/content/JWT.md +++ b/content/JWT.md | |||
@@ -7,15 +7,15 @@ weight = 4 | |||
7 | > JSON Web Tokens are representations of claims, or authorization proofs that fit into the `Header` of HTTP requests. | 7 | > JSON Web Tokens are representations of claims, or authorization proofs that fit into the `Header` of HTTP requests. |
8 | 8 | ||
9 | # How? | 9 | # How? |
10 | 10 | JWTs are used as the [MAC](https://en.wikipedia.org/wiki/Message_authentication_code) of operations that require authorization. | |
11 | JWTs are used as the [MAC](https://en.wikipedia.org/wiki/Message_authentication_code) of operations that require authorization: | 11 | Gradecoin has 2 such operations: |
12 | - block proposal | 12 | - block proposal |
13 | - transaction proposal. | 13 | - transaction proposal. |
14 | 14 | ||
15 | They are send alongside the JSON request body in the `Header`; | 15 | They are sent alongside the JSON request body in the `Header`; |
16 | 16 | ||
17 | ```html | 17 | ``` |
18 | Authorization: Bearer aaaaaa.bbbbbb.ccccc | 18 | Authorization: Bearer <JWT Token here> |
19 | ``` | 19 | ``` |
20 | 20 | ||
21 | Gradecoin uses 3 fields for the JWTs; | 21 | Gradecoin uses 3 fields for the JWTs; |
@@ -29,11 +29,13 @@ Gradecoin uses 3 fields for the JWTs; | |||
29 | ``` | 29 | ``` |
30 | 30 | ||
31 | - `tha` is explained in [blocks](@/block_docs.md) and [transactions](@/transaction_docs.md) documentations. | 31 | - `tha` is explained in [blocks](@/block_docs.md) and [transactions](@/transaction_docs.md) documentations. |
32 | - `iat` when the JWT was created in [Unix Time](https://en.wikipedia.org/wiki/Unix_time) format | 32 | - `iat` when the JWT was created in [Unix Time](https://en.wikipedia.org/wiki/Unix_time) format. |
33 | - `exp` when the JWT will expire & be rejected in [Unix Time](https://en.wikipedia.org/wiki/Unix_time) | 33 | - `exp` when the JWT will expire & be rejected in [Unix Time](https://en.wikipedia.org/wiki/Unix_time). |
34 | 34 | ||
35 | # Algorithm | 35 | # Algorithm |
36 | We are using [RS256](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1), `RSASSA-PKCS1-v1_5 using SHA-256`. The JWTs you encode with your private RSA key will be decoded using the public key you have authenticated with. You can see how the process works [here](https://jwt.io/). | 36 | We are using [RS256](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1), `RSASSA-PKCS1-v1_5 using SHA-256`. |
37 | The JWTs you encode with your private RSA key will be decoded using the public key you have authenticated with. | ||
38 | You can see how the process works and create ad hoc tokens [here](https://jwt.io/). | ||
37 | 39 | ||
38 | # References | 40 | # References |
39 | - [RFC, the ultimate reference](https://tools.ietf.org/html/rfc7519) | 41 | - [RFC, the ultimate reference](https://tools.ietf.org/html/rfc7519) |
diff --git a/content/_index.md b/content/_index.md index d0be673..3522122 100644 --- a/content/_index.md +++ b/content/_index.md | |||
@@ -4,7 +4,6 @@ sort_by = "weight" | |||
4 | +++ | 4 | +++ |
5 | 5 | ||
6 | # Welcome to Gradecoin! | 6 | # Welcome to Gradecoin! |
7 | |||
8 | Blockchains are incredibly simple yet can appear very complicated, we will see how they work and practice programming _production_ cryptography code. | 7 | Blockchains are incredibly simple yet can appear very complicated, we will see how they work and practice programming _production_ cryptography code. |
9 | 8 | ||
10 | This server is the sandbox for the PA1, it's currently running the Gradecoin application. Gradecoin is the faux currency we will use to simulate a blockchain network. At the end of the simulation, the amount of Gradecoin you hold will be your PA1 grade. | 9 | This server is the sandbox for the PA1, it's currently running the Gradecoin application. Gradecoin is the faux currency we will use to simulate a blockchain network. At the end of the simulation, the amount of Gradecoin you hold will be your PA1 grade. |
@@ -17,7 +16,7 @@ Blocks need to be _mined_ beforehand using Proof-of-work, or brute force. | |||
17 | Gradecoin offers 3 endpoints at [/register](/register), [/block](/block) and [/transaction](/transaction). You can only send GET requests to /block and /transaction without authorization. | 16 | Gradecoin offers 3 endpoints at [/register](/register), [/block](/block) and [/transaction](/transaction). You can only send GET requests to /block and /transaction without authorization. |
18 | The server is programmed in [RESTful](https://www.service-architecture.com/articles/web-services/representational_state_transfer_rest.html) architecture, there are no `DELETE`, `PUT` or `UPDATE` operations, though. | 17 | The server is programmed in [RESTful](https://www.service-architecture.com/articles/web-services/representational_state_transfer_rest.html) architecture, there are no `DELETE`, `PUT` or `UPDATE` operations, though. |
19 | 18 | ||
20 | Gradecoin uses a Proof-of-work block accepting mechanism. It uses single round [Blake2s](https://www.blake2.net/) hashing which produces 256-bit (64 hexadecimal characters) output. The [target](https://wiki.bitcoinsv.io/index.php/Target) hash is _24 bits_ or _6 hexadecimal characters_ of 0. During testing, I could mine a block on average around 4-6 minutes. | 19 | Gradecoin uses a Proof-of-work block accepting mechanism. It uses single round [Blake2s](https://www.blake2.net/) hashing which produces 256-bit (64 hexadecimal characters) output. The [target](https://wiki.bitcoinsv.io/index.php/Target) hash is _24 bits_ or _6 hexadecimal characters_ of 0. |
21 | 20 | ||
22 | > We're expecting you to use existing tools and implementations. Standards are hard. [Don't roll your own crypto](https://www.reddit.com/r/crypto/comments/2coqsy/dont_roll_your_own/). Feel free to ask questions. Collaborate. | 21 | > We're expecting you to use existing tools and implementations. Standards are hard. [Don't roll your own crypto](https://www.reddit.com/r/crypto/comments/2coqsy/dont_roll_your_own/). Feel free to ask questions. Collaborate. |
23 | 22 | ||
@@ -25,7 +24,8 @@ You might ask, | |||
25 | 24 | ||
26 | > But if nobody has any Gradecoin then how do we have transactions? | 25 | > But if nobody has any Gradecoin then how do we have transactions? |
27 | 26 | ||
28 | There is a bank! Their public key is `31415926535897932384626433832795028841971693993751058209749445923` and they have some amount of Gradecoin preloaded. It's also the only account that you can send transactions requests _to_ yourself. | 27 | You get rewarded for your hard work during the authentication with some Gradecoin to start with! |
28 | Then you can earn block rewards by proposing blocks, create some Gradecoins by generating traffic on the system, or transact with our new highly trained AI bots! | ||
29 | 29 | ||
30 | # Coinbase | 30 | # Coinbase |
31 | The first transactions of a block is called the `coinbase`. They are the **author** of the block proposal and if the block is accepted then they get compensated for their efforts with some Gradecoin. | 31 | The first transactions of a block is called the `coinbase`. They are the **author** of the block proposal and if the block is accepted then they get compensated for their efforts with some Gradecoin. |
@@ -39,6 +39,7 @@ Gradecoin uses 2048 bit RSA keypairs. | |||
39 | - Download `Gradecoin`'s Public Key from [Moodle](https://odtuclass.metu.edu.tr/my/) | 39 | - Download `Gradecoin`'s Public Key from [Moodle](https://odtuclass.metu.edu.tr/my/) |
40 | - Encrypt your [JSON](https://www.json.org/json-en.html) wrapped `Public Key`, `Student ID` and one time `passwd` using Gradecoin's Public Key | 40 | - Encrypt your [JSON](https://www.json.org/json-en.html) wrapped `Public Key`, `Student ID` and one time `passwd` using Gradecoin's Public Key |
41 | - Your public key is now in our database and can be used to sign your JWT's during requests | 41 | - Your public key is now in our database and can be used to sign your JWT's during requests |
42 | - **Don't forget your Public Key** | ||
42 | - For more information, check the [register](@/register_docs.md) page | 43 | - For more information, check the [register](@/register_docs.md) page |
43 | 44 | ||
44 | ## /transaction | 45 | ## /transaction |
@@ -55,10 +56,10 @@ Gradecoin uses 2048 bit RSA keypairs. | |||
55 | - Fetch the last accepted `Block` with a GET request | 56 | - Fetch the last accepted `Block` with a GET request |
56 | - For more information, check our [block](@/block_docs.md) page | 57 | - For more information, check our [block](@/block_docs.md) page |
57 | 58 | ||
58 | `Authorization`: The request header should have Bearer JWT.Token signed with Student Public Key | 59 | > `Authorization`: The request header should have Bearer JWT.Token signed with Student Public Key |
59 | 60 | ||
60 | ## /user | 61 | ## /user |
61 | - Meant to be used in the browser, you can see the current list of users and their balance here | 62 | - Looking for people to conduct business with? Everyone is listed here! 🤖👋 are bots who are very eager to transact with you. I've trained them personally. |
62 | 63 | ||
63 | # Questions | 64 | # Questions |
64 | ## This all sound complicated! | 65 | ## This all sound complicated! |
@@ -87,12 +88,13 @@ At the end of the _simulation_, your Gradecoin balance will be your grade. I wil | |||
87 | - perl | 88 | - perl |
88 | - rust | 89 | - rust |
89 | - python | 90 | - python |
91 | - dart/typescript | ||
90 | - random assortment of bash scripts | 92 | - random assortment of bash scripts |
91 | 93 | ||
92 | If your favourite programming language is missing please let me know 🤷? | 94 | If your favourite programming language is missing please let me know 🤷? |
93 | 95 | ||
94 | ## Can my friends play? | 96 | ## Can my friends play? |
95 | Sadly, no. Student's who are enrolled to the class will receive one-time-passwords for authentication. | 97 | Probably not at this point. I've allowed a couple of people during the testnet phase but don't intend to any more. |
96 | 98 | ||
97 | ## How and or Why? | 99 | ## How and or Why? |
98 | - [Built](https://xkcd.com/2314/), [with](https://lofi.cafe/) [Rust](https://xkcd.com/2418/) | 100 | - [Built](https://xkcd.com/2314/), [with](https://lofi.cafe/) [Rust](https://xkcd.com/2418/) |
diff --git a/content/block_docs.md b/content/block_docs.md index 92880b6..05bf8ee 100644 --- a/content/block_docs.md +++ b/content/block_docs.md | |||
@@ -4,11 +4,19 @@ description = "Block Documentation" | |||
4 | weight = 10 | 4 | weight = 10 |
5 | +++ | 5 | +++ |
6 | 6 | ||
7 | A block that was proposed to commit Transactions in `transaction_list` to the | 7 | > Blocks commit proposed transactions into the ledger. |
8 | ledger with a nonce that made `hash` valid; 6 zeroes at the left hand side of the | 8 | > A transaction that do not appear on a valid block is not accepted by the network. |
9 | hash (24 bytes). | ||
10 | 9 | ||
11 | We are _mining_ using [blake2s](https://www.blake2.net/) algorithm, which produces 256 bit hashes. Hash/second is roughly {{ exp(num="20x10", exponent="3") }} on my machine, a new block can be mined in around 4-6 minutes. | 10 | Blocks in Gradecoin are proposed to commit [Transactions](@/transaction_docs.md) that were proposed previously to the system. |
11 | `transaction_list` of the Block should be filled with valid transactions to be committed. | ||
12 | Blocks are valid when they are proposed with a `nonce` that produces a `hash` value with 6 zeroes (24 bits) at the left hand side. | ||
13 | |||
14 | We are _mining_ using [blake2s](https://www.blake2.net/) algorithm, which produces 256 bit hashes. | ||
15 | Hash/second is roughly {{ exp(num="20x10", exponent="3") }} on my machine, a new block can be mined in around 4-6 minutes. | ||
16 | |||
17 | {% tidbit() %} | ||
18 | We have seen blocks that came in within a minute during the testnet phase! | ||
19 | {% end %} | ||
12 | 20 | ||
13 | # Requests | 21 | # Requests |
14 | 22 | ||
@@ -16,14 +24,13 @@ We are _mining_ using [blake2s](https://www.blake2.net/) algorithm, which produc | |||
16 | A HTTP `GET` request to [/block](/block) endpoint will return the latest mined block. | 24 | A HTTP `GET` request to [/block](/block) endpoint will return the latest mined block. |
17 | 25 | ||
18 | ## POST | 26 | ## POST |
19 | 27 | A HTTP `POST` request with Authorization using [JWT](@/JWT.md) will allow you to propose your own blocks. | |
20 | A HTTP `POST` request with Authorization using JWT will allow you to propose your own blocks. | ||
21 | 28 | ||
22 | # Fields | 29 | # Fields |
23 | ``` | 30 | ``` |
24 | transaction_list: [array of Fingerprints] | 31 | transaction_list: [array of Transaction IDs] |
25 | nonce: unsigned 32-bit integer | 32 | nonce: unsigned 32-bit integer |
26 | timestamp: ISO 8601 <date>T<time> | 33 | timestamp: ISO 8601 Timestamp (<date>T<time>) |
27 | hash: String | 34 | hash: String |
28 | ``` | 35 | ``` |
29 | 36 | ||
@@ -36,8 +43,12 @@ The _mining_ process for the hash involves; | |||
36 | If the resulting hash is valid, then you can create a `Block` JSON object with the found `nonce` and `hash`. | 43 | If the resulting hash is valid, then you can create a `Block` JSON object with the found `nonce` and `hash`. |
37 | 44 | ||
38 | # Hash | 45 | # Hash |
46 | `tha` field in [jwt documentation](@/JWT.md) stands for "The Hash" in the context of blocks. | ||
47 | Fill this with the `hash` value you found during the mining process. | ||
39 | 48 | ||
40 | ```tha``` field in [jwt documentation](/jwt) in fact stands for "The Hash", in the case of a post request for a block, you need to use hash field of the block. | 49 | # Block Rules |
41 | 50 | - Blocks should include some minimum number of transactions. | |
51 | - Blocks cannot have duplicate transactions. | ||
42 | 52 | ||
43 | [ISO 8601 Reference](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) | 53 | # References |
54 | - [ISO 8601 Reference](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) | ||
diff --git a/content/misc_docs.md b/content/misc_docs.md index 90ea514..695119b 100644 --- a/content/misc_docs.md +++ b/content/misc_docs.md | |||
@@ -4,14 +4,10 @@ description = "Documentation about everything else" | |||
4 | weight = 10 | 4 | weight = 10 |
5 | +++ | 5 | +++ |
6 | 6 | ||
7 | We thought it might be good to explain some concepts you might have questions about. | ||
8 | |||
9 | # Fingerprint | 7 | # Fingerprint |
10 | |||
11 | ## Definition | 8 | ## Definition |
12 | 9 | ||
13 | A fingerprint is a 256 bit 64 character hexadecimal user identifier for users. Fingerprints are used in defining users in [transactions](@/transaction_docs.md) and [blocks](@/block_docs.md). | 10 | A fingerprint is a 256 bit 64 character hexadecimal user identifier for users. Fingerprints are used in defining users in [transactions](@/transaction_docs.md) and [blocks](@/block_docs.md). |
14 | 11 | ||
15 | ## Fingerprint Generation | 12 | ## Fingerprint Generation |
16 | |||
17 | A user's finger print is generated via applying SHA256 sum of the user's public RSA key. | 13 | A user's finger print is generated via applying SHA256 sum of the user's public RSA key. |
diff --git a/content/register_docs.md b/content/register_docs.md index 7c405b8..4fde05f 100644 --- a/content/register_docs.md +++ b/content/register_docs.md | |||
@@ -4,15 +4,12 @@ description = "Register Documentation" | |||
4 | weight = 3 | 4 | weight = 3 |
5 | +++ | 5 | +++ |
6 | 6 | ||
7 | POST request to `/register` endpoint | 7 | Here you can authenticate yourself with the system. |
8 | 8 | Only people who are enrolled to the class can open Gradecoin accounts, with some exceptions for people who asked nicely. | |
9 | Lets a user to authenticate themselves to the system. | 9 | This is enforced with your Student ID (e123456) and a one time password you received with your complementary *Welcome to Gradecoin* email. |
10 | Only people who are enrolled to the class can open Gradecoin accounts. | ||
11 | This is enforced with your Student ID (e123456) and a one time password you will receive. | ||
12 | 10 | ||
13 | # Authentication Process | 11 | # Authentication Process |
14 | 12 | > The cryptographic outputs you are sending over the network are all Base64 Encoded | |
15 | > The bytes you are sending over the network are all Base64 Encoded | ||
16 | 13 | ||
17 | - Gradecoin's Public Key (`gradecoin_public_key`) is listed on our Moodle page and [here](/gradecoin.pub). Download and load it it to your client. | 14 | - Gradecoin's Public Key (`gradecoin_public_key`) is listed on our Moodle page and [here](/gradecoin.pub). Download and load it it to your client. |
18 | - Create a JSON object (`P_AR`) with your `metu_id` ("e"+`6 chars`) and `public key` in base64 (PEM) format (`S_PK`) [reference](https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem) | 15 | - Create a JSON object (`P_AR`) with your `metu_id` ("e"+`6 chars`) and `public key` in base64 (PEM) format (`S_PK`) [reference](https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem) |
@@ -25,11 +22,10 @@ This is enforced with your Student ID (e123456) and a one time password you will | |||
25 | ``` | 22 | ``` |
26 | 23 | ||
27 | ## Cipher Initialization | 24 | ## Cipher Initialization |
28 | |||
29 | > Since we are working with AES-128, both key and IV should be 128 bits (or 32 hexadecimal characters) | 25 | > Since we are working with AES-128, both key and IV should be 128 bits (or 32 hexadecimal characters) |
30 | 26 | ||
31 | - Pick a short temporary key (`k_temp`) | 27 | - Pick a short temporary key (`k_temp`) |
32 | - Pick a random IV [1](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV)) [2](https://en.wikipedia.org/wiki/Initialization_vector) (`iv`). | 28 | - Pick a random IV ([1](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV))) ([2](https://en.wikipedia.org/wiki/Initialization_vector) (`iv`)). |
33 | 29 | ||
34 | ## Encryption | 30 | ## Encryption |
35 | - Encrypt the serialized string of `P_AR` with 128 bit block [AES](https://en.wikipedia.org/wiki/Initialization_vector) in [CBC](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode with [Pkcs7 padding](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Padding) using the temporary key (`k_temp`), the result is `C_AR`. Encode this with base64. | 31 | - Encrypt the serialized string of `P_AR` with 128 bit block [AES](https://en.wikipedia.org/wiki/Initialization_vector) in [CBC](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode with [Pkcs7 padding](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Padding) using the temporary key (`k_temp`), the result is `C_AR`. Encode this with base64. |
@@ -51,4 +47,11 @@ The available tools and libraries might warn you about how using the primitives | |||
51 | ``` | 47 | ``` |
52 | 48 | ||
53 | If your authentication process was valid, you will be given access and your public key fingerprint that is your address. | 49 | If your authentication process was valid, you will be given access and your public key fingerprint that is your address. |
50 | Please note it down. | ||
54 | You can now sign [JWTs](@/JWT.md) to send authorized transaction requests. | 51 | You can now sign [JWTs](@/JWT.md) to send authorized transaction requests. |
52 | After all this, you might want to bask in the glory of having successfully managing your way through a home-made cryptographic system. | ||
53 | Maybe the Gradecoin you got given as the registration reward will help. | ||
54 | |||
55 | {% tidbit() %} | ||
56 | Seriously, congratulations | ||
57 | {% end %} | ||
diff --git a/content/transaction_docs.md b/content/transaction_docs.md index 05c1534..f9e8947 100644 --- a/content/transaction_docs.md +++ b/content/transaction_docs.md | |||
@@ -7,17 +7,14 @@ weight = 6 | |||
7 | A transaction request between `source` and `target` to move `amount` Gradecoin. | 7 | A transaction request between `source` and `target` to move `amount` Gradecoin. |
8 | 8 | ||
9 | # Requests | 9 | # Requests |
10 | |||
11 | ## GET | 10 | ## GET |
12 | A HTTP `GET` request to [/transaction](/transaction) endpoint will return the current list of pending transactions. | 11 | A HTTP `GET` request to [/transaction](/transaction) endpoint will return the current list of pending transactions. |
13 | 12 | ||
14 | ## POST | 13 | ## POST |
15 | 14 | A HTTP `POST` request with Authorization using [JWT](@/JWT.md) to [/transaction](/transaction) will allow you to propose your own transactions. | |
16 | A HTTP `POST` request with Authorization using JWT to [/transaction](/transactions) will allow you to propose your own transactions. | ||
17 | 15 | ||
18 | # Fields | 16 | # Fields |
19 | ``` | 17 | ``` |
20 | by: Fingerprint | ||
21 | source: Fingerprint | 18 | source: Fingerprint |
22 | target: Fingerprint | 19 | target: Fingerprint |
23 | amount: unsigned 16 bit integer | 20 | amount: unsigned 16 bit integer |
@@ -25,28 +22,20 @@ timestamp: ISO 8601 <date>T<time> | |||
25 | ``` | 22 | ``` |
26 | 23 | ||
27 | # Hash | 24 | # Hash |
28 | 25 | `tha` field in [jwt documentation](@/JWT.md) in fact stands for "The Hash". | |
29 | `tha` field in [jwt documentation](@/JWT.md) in fact stands for "The Hash", in the case of a post request for a transaction, you need the Md5 hash of the serialized JSON representation of transaction. The resulting JSON string should look something like; | 26 | In the context of a transaction proposal, you need the [Md5](https://en.wikipedia.org/wiki/MD5) hash of the serialized JSON representation of transaction. |
27 | Serializing in this context is a simple JSON to string conversion with key, value pairs enclosed with quotation marks ("). | ||
28 | The resulting JSON string should look something like; | ||
30 | 29 | ||
31 | ``` | 30 | ``` |
32 | {"by":"foo","source":"bar","target":"baz","amount":2,"timestamp":"2021-04-18T21:49:00"} | 31 | {"source":"bar","target":"baz","amount":2,"timestamp":"2021-04-18T21:49:00"} |
33 | ``` | 32 | ``` |
34 | 33 | ||
35 | Or; without any whitespace, separated with `:` and `,`. | 34 | Or; without any whitespace, separated with `:` and `,`. |
36 | 35 | ||
37 | # Bank | 36 | # Transaction Rules |
38 | 37 | - Transactions should be sent from your account (`source`) to any other account (`target`). | |
39 | There is a `bank` account with Fingerprint `31415926535897932384626433832795028841971693993751058209749445923` | 38 | - Transactions generate traffic which is something we desperately need in Gradecoin, so for every transaction you send, some Gradecoin will be generated out of thin air and will appear on the target. |
40 | 39 | - Don't worry if your transaction goes unaccepted! Transactions do not disappear until they are committed into the ledger with a block. | |
41 | {% tidbit() %} | 40 | - Every transaction has a unique ID generated from the `source` and `target` fields. No two transaction with the same ID can appear on the pending transaction list [/transactions](/transaction) |
42 | First 64 digits of Pi | 41 | - Transactions have an upper amount limit. |
43 | {% end %} | ||
44 | |||
45 | This is the only account that will let you _withdraw_ from them. | ||
46 | |||
47 | ``` | ||
48 | by: this has to be your Fingerprint | ||
49 | source: this can be either you or the bank | ||
50 | target: this can be a valid fingerprint or yourself if source is the bank | ||
51 | ... | ||
52 | ``` | ||