diff options
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | config.toml | 28 | ||||
-rw-r--r-- | content/JWT.md | 41 | ||||
-rw-r--r-- | content/_index.md | 98 | ||||
-rw-r--r-- | content/block_docs.md | 43 | ||||
-rw-r--r-- | content/misc_docs.md | 17 | ||||
-rw-r--r-- | content/register_docs.md | 54 | ||||
-rw-r--r-- | content/transaction_docs.md | 52 | ||||
-rw-r--r-- | static/android-chrome-192x192.png | bin | 0 -> 26249 bytes | |||
-rw-r--r-- | static/android-chrome-512x512.png | bin | 0 -> 80376 bytes | |||
-rw-r--r-- | static/apple-touch-icon.png | bin | 0 -> 24023 bytes | |||
-rw-r--r-- | static/favicon-16x16.png | bin | 0 -> 878 bytes | |||
-rw-r--r-- | static/favicon-32x32.png | bin | 0 -> 2463 bytes | |||
-rw-r--r-- | static/favicon.ico | bin | 0 -> 15406 bytes | |||
-rw-r--r-- | static/gradecoin.png | bin | 0 -> 197656 bytes | |||
-rw-r--r-- | static/gradecoin.pub | 9 | ||||
-rw-r--r-- | static/site.css | 57 | ||||
-rw-r--r-- | templates/_variables.html | 15 | ||||
-rw-r--r-- | templates/index.html | 68 | ||||
-rw-r--r-- | templates/shortcodes/exp.html | 1 | ||||
-rw-r--r-- | templates/shortcodes/tidbit.html | 5 |
21 files changed, 498 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..a4415af --- /dev/null +++ b/README.md | |||
@@ -0,0 +1,10 @@ | |||
1 | # Gradecoin Site | ||
2 | URL: https://gradecoin.xyz/ | ||
3 | |||
4 | Uses [Zola](http://getzola.org/). | ||
5 | |||
6 | ```bash | ||
7 | zola serve --open # for local building & testing | ||
8 | zola build | ||
9 | ``` | ||
10 | |||
diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..070b762 --- /dev/null +++ b/config.toml | |||
@@ -0,0 +1,28 @@ | |||
1 | # The URL the site will be built for | ||
2 | base_url = "https://gradecoin.xyz" | ||
3 | |||
4 | theme = "juice" | ||
5 | |||
6 | title = "Gradecoin" | ||
7 | description = "Mine Your Grades" | ||
8 | |||
9 | # Whether to automatically compile all Sass files in the sass directory | ||
10 | compile_sass = true | ||
11 | |||
12 | # Whether to build a search index to be used later on by a JavaScript library | ||
13 | build_search_index = true | ||
14 | |||
15 | [markdown] | ||
16 | # Whether to do syntax highlighting | ||
17 | # Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola | ||
18 | highlight_code = true | ||
19 | highlight_theme = "subway-moscow" | ||
20 | |||
21 | [extra] | ||
22 | # Put all your custom variables here | ||
23 | juice_logo_name = "Gradecoin" | ||
24 | juice_logo_path = "gradecoin.png" | ||
25 | juice_extra_menu = [ | ||
26 | { title = "why?", link = "https://github.com/zhuowei/nft_ptr#why"} | ||
27 | ] | ||
28 | |||
diff --git a/content/JWT.md b/content/JWT.md new file mode 100644 index 0000000..46da1a2 --- /dev/null +++ b/content/JWT.md | |||
@@ -0,0 +1,41 @@ | |||
1 | +++ | ||
2 | title = "JWT" | ||
3 | description = "JSON Web Token Documentation" | ||
4 | weight = 4 | ||
5 | +++ | ||
6 | |||
7 | > JSON Web Tokens are representations of claims, or authorization proofs that fit into the `Header` of HTTP requests. | ||
8 | |||
9 | # How? | ||
10 | |||
11 | JWTs are used as the [MAC](https://en.wikipedia.org/wiki/Message_authentication_code) of operations that require authorization: | ||
12 | - block proposal | ||
13 | - transaction proposal. | ||
14 | |||
15 | They are send alongside the JSON request body in the `Header`; | ||
16 | |||
17 | ```html | ||
18 | Authorization: Bearer aaaaaa.bbbbbb.ccccc | ||
19 | ``` | ||
20 | |||
21 | Gradecoin uses 3 fields for the JWTs; | ||
22 | |||
23 | ```json | ||
24 | { | ||
25 | "tha": "Hash of the payload, check invididual references", | ||
26 | "iat": "Issued At, Unix Time", | ||
27 | "exp": "Expiration Time, epoch" | ||
28 | } | ||
29 | ``` | ||
30 | |||
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 | ||
33 | - `exp` when the JWT will expire & be rejected in [Unix Time](https://en.wikipedia.org/wiki/Unix_time) | ||
34 | |||
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/). | ||
37 | |||
38 | # References | ||
39 | - [RFC, the ultimate reference](https://tools.ietf.org/html/rfc7519) | ||
40 | - [JWT Debugger](https://jwt.io/) | ||
41 | |||
diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..d0be673 --- /dev/null +++ b/content/_index.md | |||
@@ -0,0 +1,98 @@ | |||
1 | +++ | ||
2 | title = "Gradecoin" | ||
3 | sort_by = "weight" | ||
4 | +++ | ||
5 | |||
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. | ||
9 | |||
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. | ||
11 | |||
12 | **A quick summary**: authenticate yourself to the system using public key encryption. | ||
13 | Craft [Transaction](@/transaction_docs.md) proposals and tag them using [JWTs](@/JWT.md). | ||
14 | When there are enough transactions then you can propose [Blocks](@/block_docs.md) in the same way. | ||
15 | Blocks need to be _mined_ beforehand using Proof-of-work, or brute force. | ||
16 | |||
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. | ||
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. | ||
19 | |||
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. | ||
21 | |||
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. | ||
23 | |||
24 | You might ask, | ||
25 | |||
26 | > But if nobody has any Gradecoin then how do we have transactions? | ||
27 | |||
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. | ||
29 | |||
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. | ||
32 | |||
33 | # Public Key Signatures | ||
34 | Gradecoin uses 2048 bit RSA keypairs. | ||
35 | |||
36 | # Services | ||
37 | ## /register | ||
38 | - Create your own 2048 bit RSA `keypair` | ||
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 | ||
41 | - Your public key is now in our database and can be used to sign your JWT's during requests | ||
42 | - For more information, check the [register](@/register_docs.md) page | ||
43 | |||
44 | ## /transaction | ||
45 | - You can offer a [Transaction](@/transaction_docs.md) with a POST request | ||
46 | - The request should have `Authorization` | ||
47 | - The request header should be signed by the Public Key of the `by` field in the transaction | ||
48 | - Fetch the list of `Transaction`s with a GET request | ||
49 | - For more information, check our [transaction](@/transaction_docs.md) page | ||
50 | |||
51 | ## /block | ||
52 | - Offer a [Block](@/block_docs.md) with a POST request | ||
53 | - The request should have `Authorization` | ||
54 | - The `transaction_list` of the block should be a subset of pending transactions, available on [/transaction](/transaction) | ||
55 | - Fetch the last accepted `Block` with a GET request | ||
56 | - For more information, check our [block](@/block_docs.md) page | ||
57 | |||
58 | `Authorization`: The request header should have Bearer JWT.Token signed with Student Public Key | ||
59 | |||
60 | ## /user | ||
61 | - Meant to be used in the browser, you can see the current list of users and their balance here | ||
62 | |||
63 | # Questions | ||
64 | ## This all sound complicated! | ||
65 | - I've drawn inspiration from [actual Bitcoin transactions](https://explorer.bitcoin.com/btc) and [warp](https://github.com/seanmonstar/warp/blob/master/examples/todos.rs). The simplicity of the system is how little interfaces it has. | ||
66 | - Don't know where to start? Gradecoin uses RESTful API; simple `curl` commands or even your browser will work! [This website can help as well](https://curl.trillworks.com/). | ||
67 | - [JWT Debugger](https://jwt.io) and the corresponding [RFC](https://tools.ietf.org/html/rfc7519). | ||
68 | - Remember that you are absolutely encouraged to grab off-the-shelf implementations for every cryptography primitive you will use. You can start by finding a code snippet to generate a RSA keypair? | ||
69 | - Check out [misc](@/misc_docs.md) for everything else you might be curious about. | ||
70 | |||
71 | ## How do you actually earn Gradecoin? | ||
72 | - Register yourself to at [/register](@/register_docs.md) | ||
73 | - Create transactions at [/transaction](@/transaction_docs.md) | ||
74 | - Create blocks to commit transactions at [/block](@/block_docs.md) | ||
75 | - See how everyone is doing and find people to trade with at [/user](/user) | ||
76 | |||
77 | ## I found a bug! | ||
78 | Thank you! Please [let me know](mailto:yigit@ceng.metu.edu.tr) so we can solve it. | ||
79 | |||
80 | ## I hacked the server! | ||
81 | That wasn't supposed to happen :( I did not place any intentional vulnerabilities to the system so if you cracked something, it was not intended. Please don't abuse it and let me know so I can patch it. | ||
82 | |||
83 | ## Submission? | ||
84 | At the end of the _simulation_, your Gradecoin balance will be your grade. I will also expect a unique client programmed in either; | ||
85 | - c | ||
86 | - c++ | ||
87 | - perl | ||
88 | - rust | ||
89 | - python | ||
90 | - random assortment of bash scripts | ||
91 | |||
92 | If your favourite programming language is missing please let me know 🤷? | ||
93 | |||
94 | ## Can my friends play? | ||
95 | Sadly, no. Student's who are enrolled to the class will receive one-time-passwords for authentication. | ||
96 | |||
97 | ## How and or Why? | ||
98 | - [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 new file mode 100644 index 0000000..92880b6 --- /dev/null +++ b/content/block_docs.md | |||
@@ -0,0 +1,43 @@ | |||
1 | +++ | ||
2 | title = "Blocks" | ||
3 | description = "Block Documentation" | ||
4 | weight = 10 | ||
5 | +++ | ||
6 | |||
7 | A block that was proposed to commit Transactions in `transaction_list` to the | ||
8 | ledger with a nonce that made `hash` valid; 6 zeroes at the left hand side of the | ||
9 | hash (24 bytes). | ||
10 | |||
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. | ||
12 | |||
13 | # Requests | ||
14 | |||
15 | ## GET | ||
16 | A HTTP `GET` request to [/block](/block) endpoint will return the latest mined block. | ||
17 | |||
18 | ## POST | ||
19 | |||
20 | A HTTP `POST` request with Authorization using JWT will allow you to propose your own blocks. | ||
21 | |||
22 | # Fields | ||
23 | ``` | ||
24 | transaction_list: [array of Fingerprints] | ||
25 | nonce: unsigned 32-bit integer | ||
26 | timestamp: ISO 8601 <date>T<time> | ||
27 | hash: String | ||
28 | ``` | ||
29 | |||
30 | # Mining | ||
31 | The _mining_ process for the hash involves; | ||
32 | - Creating a temporary JSON object with `transaction_list`, `timestamp` and `nonce` values | ||
33 | - Serializing it | ||
34 | - Calculating blake2s hash of the serialized string | ||
35 | |||
36 | If the resulting hash is valid, then you can create a `Block` JSON object with the found `nonce` and `hash`. | ||
37 | |||
38 | # Hash | ||
39 | |||
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. | ||
41 | |||
42 | |||
43 | [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 new file mode 100644 index 0000000..90ea514 --- /dev/null +++ b/content/misc_docs.md | |||
@@ -0,0 +1,17 @@ | |||
1 | +++ | ||
2 | title = "Misc" | ||
3 | description = "Documentation about everything else" | ||
4 | weight = 10 | ||
5 | +++ | ||
6 | |||
7 | We thought it might be good to explain some concepts you might have questions about. | ||
8 | |||
9 | # Fingerprint | ||
10 | |||
11 | ## Definition | ||
12 | |||
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). | ||
14 | |||
15 | ## Fingerprint Generation | ||
16 | |||
17 | 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 new file mode 100644 index 0000000..974fe37 --- /dev/null +++ b/content/register_docs.md | |||
@@ -0,0 +1,54 @@ | |||
1 | +++ | ||
2 | title = "Register" | ||
3 | description = "Register Documentation" | ||
4 | weight = 3 | ||
5 | +++ | ||
6 | |||
7 | POST request to `/register` endpoint | ||
8 | |||
9 | Lets a user to authenticate themselves to the system. | ||
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 | |||
13 | # Authentication Process | ||
14 | |||
15 | > The bytes you are sending over the network are all Base64 Encoded | ||
16 | |||
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. | ||
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) | ||
19 | ```json | ||
20 | { | ||
21 | "student_id": "e123456", | ||
22 | "passwd": "15 char secret", | ||
23 | "public_key": "---BEGIN PUBLIC KEY..." | ||
24 | } | ||
25 | ``` | ||
26 | |||
27 | ## Cipher Initialization | ||
28 | |||
29 | > Since we are working with AES-128, both key and IV should be 128 bits (or 16 hexadecimal characters) | ||
30 | |||
31 | - 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`). | ||
33 | |||
34 | ## 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. | ||
36 | - The temporary key you have picked `k_temp` is encrypted using RSA with [OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding) padding scheme using SHA-256 with `gradecoin_public_key`, giving us `key_ciphertext`. Encode this with base64. | ||
37 | - Base64 encode the IV (`iv`) as well. | ||
38 | |||
39 | {% tidbit() %} | ||
40 | The available tools and libraries might warn you about how using the primitives given above are "hazardous". They are, crypto is hard. | ||
41 | {% end %} | ||
42 | |||
43 | - The payload JSON object (`auth_request`) can be serialized now: | ||
44 | |||
45 | ```json | ||
46 | { | ||
47 | "c": "C_AR", | ||
48 | "iv": "iv", | ||
49 | "key": "key_ciphertext" | ||
50 | } | ||
51 | ``` | ||
52 | |||
53 | If your authentication process was valid, you will be given access and your public key fingerprint that is your address. | ||
54 | You can now sign [JWTs](@/JWT.md) to send authorized transaction requests. | ||
diff --git a/content/transaction_docs.md b/content/transaction_docs.md new file mode 100644 index 0000000..05c1534 --- /dev/null +++ b/content/transaction_docs.md | |||
@@ -0,0 +1,52 @@ | |||
1 | +++ | ||
2 | title = "Transactions" | ||
3 | description = "Transaction documentation" | ||
4 | weight = 6 | ||
5 | +++ | ||
6 | |||
7 | A transaction request between `source` and `target` to move `amount` Gradecoin. | ||
8 | |||
9 | # Requests | ||
10 | |||
11 | ## GET | ||
12 | A HTTP `GET` request to [/transaction](/transaction) endpoint will return the current list of pending transactions. | ||
13 | |||
14 | ## POST | ||
15 | |||
16 | A HTTP `POST` request with Authorization using JWT to [/transaction](/transactions) will allow you to propose your own transactions. | ||
17 | |||
18 | # Fields | ||
19 | ``` | ||
20 | by: Fingerprint | ||
21 | source: Fingerprint | ||
22 | target: Fingerprint | ||
23 | amount: unsigned 16 bit integer | ||
24 | timestamp: ISO 8601 <date>T<time> | ||
25 | ``` | ||
26 | |||
27 | # Hash | ||
28 | |||
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; | ||
30 | |||
31 | ``` | ||
32 | {"by":"foo","source":"bar","target":"baz","amount":2,"timestamp":"2021-04-18T21:49:00"} | ||
33 | ``` | ||
34 | |||
35 | Or; without any whitespace, separated with `:` and `,`. | ||
36 | |||
37 | # Bank | ||
38 | |||
39 | There is a `bank` account with Fingerprint `31415926535897932384626433832795028841971693993751058209749445923` | ||
40 | |||
41 | {% tidbit() %} | ||
42 | First 64 digits of Pi | ||
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 | ``` | ||
diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png new file mode 100644 index 0000000..023ddbd --- /dev/null +++ b/static/android-chrome-192x192.png | |||
Binary files differ | |||
diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png new file mode 100644 index 0000000..4251933 --- /dev/null +++ b/static/android-chrome-512x512.png | |||
Binary files differ | |||
diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png new file mode 100644 index 0000000..cd8e4c8 --- /dev/null +++ b/static/apple-touch-icon.png | |||
Binary files differ | |||
diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png new file mode 100644 index 0000000..bd63d34 --- /dev/null +++ b/static/favicon-16x16.png | |||
Binary files differ | |||
diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png new file mode 100644 index 0000000..e343587 --- /dev/null +++ b/static/favicon-32x32.png | |||
Binary files differ | |||
diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..45d8bfe --- /dev/null +++ b/static/favicon.ico | |||
Binary files differ | |||
diff --git a/static/gradecoin.png b/static/gradecoin.png new file mode 100644 index 0000000..eeb670c --- /dev/null +++ b/static/gradecoin.png | |||
Binary files differ | |||
diff --git a/static/gradecoin.pub b/static/gradecoin.pub new file mode 100644 index 0000000..ffe2f12 --- /dev/null +++ b/static/gradecoin.pub | |||
@@ -0,0 +1,9 @@ | |||
1 | -----BEGIN PUBLIC KEY----- | ||
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGuqiCPGcguy+Y9TH7Bl | ||
3 | 7XlEsalyqb9bYlzpbV0dnqZ3lPkEPkuOhkN+GcuiV6iXtSwyh7nB+xTRXKJFRUBO | ||
4 | /jbN8jfcxVwBu0JxjF3v1YRBxbOHhz2A295mbKD9xHQCKxkfYBNkUXxj8gd+GaDv | ||
5 | QiSW5NdrX/lEkvqfGtdEX1m2+HdcG0+3YW24Xg0znhCwLr+sorLuJaDy9Xa0Uo+D | ||
6 | PWGC5s001U/BxkCIWJ+eJQCb7Bv+9vXb8BGRK/ecMb/fb6h5O+8fgB64RCHMgcc2 | ||
7 | v+Q/dPt8kHX1OJdMuYUrUJGACppMQY3W6e1HdlRIBcZKL2LMZ2CrIB/2D5LiJhPT | ||
8 | hQIDAQAB | ||
9 | -----END PUBLIC KEY----- | ||
diff --git a/static/site.css b/static/site.css new file mode 100644 index 0000000..6c79aa9 --- /dev/null +++ b/static/site.css | |||
@@ -0,0 +1,57 @@ | |||
1 | .content blockquote { | ||
2 | border-left: #689d6a 8px solid; | ||
3 | |||
4 | } | ||
5 | .content blockquote.tidbit { | ||
6 | border-left: #928f74 8px solid; | ||
7 | font-size: 12px; | ||
8 | color: #282828; | ||
9 | } | ||
10 | |||
11 | li p { | ||
12 | margin: 2px; | ||
13 | } | ||
14 | |||
15 | /* OUTER CONTAINER */ | ||
16 | .tcontainer { | ||
17 | width: 100%; | ||
18 | overflow: hidden; /* Hide scroll bar */ | ||
19 | } | ||
20 | |||
21 | /* MIDDLE CONTAINER */ | ||
22 | .ticker-wrap { | ||
23 | width: 100%; | ||
24 | padding-left: 100%; /* Push contents to right side of screen */ | ||
25 | background-color: #eee; | ||
26 | } | ||
27 | |||
28 | /* INNER CONTAINER */ | ||
29 | @keyframes ticker { | ||
30 | 0% { transform: translate3d(0, 0, 0); } | ||
31 | 100% { transform: translate3d(-100%, 0, 0); } | ||
32 | } | ||
33 | |||
34 | .ticker-move { | ||
35 | /* Basically move items from right side of screen to left in infinite loop */ | ||
36 | display: inline-block; | ||
37 | white-space: nowrap; | ||
38 | padding-right: 100%; | ||
39 | animation-iteration-count: infinite; | ||
40 | animation-timing-function: linear; | ||
41 | animation-name: ticker; | ||
42 | animation-duration: 30s; | ||
43 | } | ||
44 | |||
45 | .ticker-move:hover{ | ||
46 | animation-play-state: paused; /* Pause scroll on mouse hover */ | ||
47 | } | ||
48 | |||
49 | /* ITEMS */ | ||
50 | .ticker-item { | ||
51 | display: inline-block; /* Lay items in a horizontal line */ | ||
52 | padding: 0 5px; | ||
53 | } | ||
54 | |||
55 | .ticker-item::before { | ||
56 | content: " ✑ "; | ||
57 | } | ||
diff --git a/templates/_variables.html b/templates/_variables.html new file mode 100644 index 0000000..3fd05b4 --- /dev/null +++ b/templates/_variables.html | |||
@@ -0,0 +1,15 @@ | |||
1 | <style> | ||
2 | :root { | ||
3 | /* Primary theme color */ | ||
4 | --primary-color: #F8D12F; | ||
5 | /* Primary theme text color */ | ||
6 | --primary-text-color: #1E2329; | ||
7 | /* Primary theme link color */ | ||
8 | --primary-link-color: #2F57F7; | ||
9 | /* Secondary color: the background body color */ | ||
10 | --secondary-color: #FAFAFA; | ||
11 | --secondary-text-color: #303030; | ||
12 | /* Highlight text color of table of content */ | ||
13 | --toc-highlight-text-color: #d46e13; | ||
14 | } | ||
15 | </style> | ||
diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..08e3c8a --- /dev/null +++ b/templates/index.html | |||
@@ -0,0 +1,68 @@ | |||
1 | {% extends "juice/templates/index.html" %} | ||
2 | |||
3 | {% block head %} | ||
4 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" /> | ||
5 | <link rel="stylesheet" href="/site.css" /> | ||
6 | {% endblock head %} | ||
7 | |||
8 | {% block hero %} | ||
9 | |||
10 | <section class="text-center"> | ||
11 | <h1 class="heading-text animate__animated animate__jackInTheBox" style="font-size: 50px"> | ||
12 | Mine your own grades | ||
13 | </h1> | ||
14 | <h3 class="title-text"> | ||
15 | <b>Gradecoin</b> is the latest cutting edge blockchain technology agile grading framework that drives organic engagement and other buzzwords, with big data mining search engine optimization | ||
16 | </h3> | ||
17 | <div> | ||
18 | </div> | ||
19 | </section> | ||
20 | <img class="hero-image" style="width: 40%" src="{{ get_url(path="gradecoin.png") }}"> | ||
21 | |||
22 | <div class="explore-more text" | ||
23 | onclick="document.getElementById('features').scrollIntoView({behavior: 'smooth'})"> | ||
24 | ⇩ Learn How ⇩ | ||
25 | </div> | ||
26 | |||
27 | <style> | ||
28 | |||
29 | .hero section { | ||
30 | padding: 0 5rem; | ||
31 | } | ||
32 | |||
33 | @media screen and (max-width: 768px) { | ||
34 | .hero section { | ||
35 | padding: 0 2rem; | ||
36 | } | ||
37 | |||
38 | .hero-image { | ||
39 | display: none | ||
40 | } | ||
41 | |||
42 | } | ||
43 | footer { | ||
44 | color: #8b8b8b; | ||
45 | } | ||
46 | </style> | ||
47 | {% endblock hero %} | ||
48 | |||
49 | {% block content %} | ||
50 | <div class="tcontainer" id="features"> | ||
51 | <div class="ticker-wrap"> | ||
52 | <div class="ticker-move"> | ||
53 | <div class="ticker-item"><b>News:</b></div> | ||
54 | <div class="ticker-item">Gradecoin is in testnet mode, API is not stable, everything might reset at any time.</div> | ||
55 | <div class="ticker-item">Transactions are now unique according to their "by" field, sorry for the trouble</div> | ||
56 | <div class="ticker-item">Blocks now require 5 transactions in them, during testnet phase</div> | ||
57 | <div class="ticker-item">It was possible (and hilarious) to mine a new block with just 1 transaction, it is now fixed</div> | ||
58 | </div> | ||
59 | </div> | ||
60 | </div> | ||
61 | {{ section.content | safe }} | ||
62 | {% endblock content %} | ||
63 | |||
64 | {% block footer %} | ||
65 | <footer> | ||
66 | Built For ⁂ CENG489 ⁂ Introduction to Computer Security | ||
67 | </footer> | ||
68 | {% endblock footer %} | ||
diff --git a/templates/shortcodes/exp.html b/templates/shortcodes/exp.html new file mode 100644 index 0000000..5a37a39 --- /dev/null +++ b/templates/shortcodes/exp.html | |||
@@ -0,0 +1 @@ | |||
{{ num }}<sup>{{ exponent }}</sup> | |||
diff --git a/templates/shortcodes/tidbit.html b/templates/shortcodes/tidbit.html new file mode 100644 index 0000000..7023578 --- /dev/null +++ b/templates/shortcodes/tidbit.html | |||
@@ -0,0 +1,5 @@ | |||
1 | <blockquote class="tidbit"> | ||
2 | <p> | ||
3 | {{ body }} | ||
4 | </p> | ||
5 | </blockquote> | ||