├── README.md ├── tsconfig.json ├── package.json ├── .gitignore ├── src └── index.ts └── yarn.lock /README.md: -------------------------------------------------------------------------------- 1 | # Typechain 2 | 3 | Learning Typescript by making a Blockchain with it 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2015", 5 | "sourceMap": true, 6 | "outDir": "dist" 7 | }, 8 | "include": ["src/**/*"], 9 | "exclude": ["node_modules"] 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typechain", 3 | "version": "1.0.0", 4 | "description": "Learning Typescript by making a Blockchain with it", 5 | "main": "index.js", 6 | "repository": "https://github.com/nomadcoders/typechain", 7 | "author": "Nicolás Serrano Arévalo ", 8 | "license": "MIT", 9 | "scripts": { 10 | "start": "tsc-watch --onSuccess \" node dist/index.js\" " 11 | }, 12 | "devDependencies": { 13 | "tsc-watch": "^1.0.17" 14 | }, 15 | "dependencies": { 16 | "crypto-js": "^3.1.9-1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | dist -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as CryptoJS from "crypto-js"; 2 | 3 | class Block { 4 | static calculateBlockHash = ( 5 | index: number, 6 | previousHash: string, 7 | timestamp: number, 8 | data: string 9 | ): string => 10 | CryptoJS.SHA256(index + previousHash + timestamp + data).toString(); 11 | 12 | static validateStructure = (aBlock: Block): boolean => 13 | typeof aBlock.index === "number" && 14 | typeof aBlock.hash === "string" && 15 | typeof aBlock.previousHash === "string" && 16 | typeof aBlock.timestamp === "number" && 17 | typeof aBlock.data === "string"; 18 | 19 | public index: number; 20 | public hash: string; 21 | public previousHash: string; 22 | public data: string; 23 | public timestamp: number; 24 | 25 | constructor( 26 | index: number, 27 | hash: string, 28 | previousHash: string, 29 | data: string, 30 | timestamp: number 31 | ) { 32 | this.index = index; 33 | this.hash = hash; 34 | this.previousHash = previousHash; 35 | this.data = data; 36 | this.timestamp = timestamp; 37 | } 38 | } 39 | 40 | const genesisBlock: Block = new Block(0, "2020202020202", "", "Hello", 123456); 41 | 42 | let blockchain: Block[] = [genesisBlock]; 43 | 44 | const getBlockchain = (): Block[] => blockchain; 45 | 46 | const getLatestBlock = (): Block => blockchain[blockchain.length - 1]; 47 | 48 | const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000); 49 | 50 | const createNewBlock = (data: string): Block => { 51 | const previousBlock: Block = getLatestBlock(); 52 | const newIndex: number = previousBlock.index + 1; 53 | const newTimestamp: number = getNewTimeStamp(); 54 | const newHash: string = Block.calculateBlockHash( 55 | newIndex, 56 | previousBlock.hash, 57 | newTimestamp, 58 | data 59 | ); 60 | const newBlock: Block = new Block( 61 | newIndex, 62 | newHash, 63 | previousBlock.hash, 64 | data, 65 | newTimestamp 66 | ); 67 | addBlock(newBlock); 68 | return newBlock; 69 | }; 70 | 71 | const getHashforBlock = (aBlock: Block): string => 72 | Block.calculateBlockHash( 73 | aBlock.index, 74 | aBlock.previousHash, 75 | aBlock.timestamp, 76 | aBlock.data 77 | ); 78 | 79 | const isBlockValid = (candidateBlock: Block, previousBlock: Block): boolean => { 80 | if (!Block.validateStructure(candidateBlock)) { 81 | return false; 82 | } else if (previousBlock.index + 1 !== candidateBlock.index) { 83 | return false; 84 | } else if (previousBlock.hash !== candidateBlock.previousHash) { 85 | return false; 86 | } else if (getHashforBlock(candidateBlock) !== candidateBlock.hash) { 87 | return false; 88 | } else { 89 | return true; 90 | } 91 | }; 92 | 93 | const addBlock = (candidateBlock: Block): void => { 94 | if (isBlockValid(candidateBlock, getLatestBlock())) { 95 | blockchain.push(candidateBlock); 96 | } 97 | }; 98 | 99 | createNewBlock("second block"); 100 | createNewBlock("third block"); 101 | createNewBlock("fourth block"); 102 | 103 | console.log(blockchain); 104 | 105 | export {}; 106 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.2.1: 6 | version "3.2.1" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | chalk@^2.3.0: 12 | version "2.3.2" 13 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" 14 | dependencies: 15 | ansi-styles "^3.2.1" 16 | escape-string-regexp "^1.0.5" 17 | supports-color "^5.3.0" 18 | 19 | color-convert@^1.9.0: 20 | version "1.9.1" 21 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 22 | dependencies: 23 | color-name "^1.1.1" 24 | 25 | color-name@^1.1.1: 26 | version "1.1.3" 27 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 28 | 29 | cross-spawn@^5.1.0: 30 | version "5.1.0" 31 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 32 | dependencies: 33 | lru-cache "^4.0.1" 34 | shebang-command "^1.2.0" 35 | which "^1.2.9" 36 | 37 | crypto-js@^3.1.9-1: 38 | version "3.1.9-1" 39 | resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" 40 | 41 | duplexer@~0.1.1: 42 | version "0.1.1" 43 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" 44 | 45 | escape-string-regexp@^1.0.5: 46 | version "1.0.5" 47 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 48 | 49 | event-stream@~3.3.0: 50 | version "3.3.4" 51 | resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" 52 | dependencies: 53 | duplexer "~0.1.1" 54 | from "~0" 55 | map-stream "~0.1.0" 56 | pause-stream "0.0.11" 57 | split "0.3" 58 | stream-combiner "~0.0.4" 59 | through "~2.3.1" 60 | 61 | from@~0: 62 | version "0.1.7" 63 | resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" 64 | 65 | has-flag@^3.0.0: 66 | version "3.0.0" 67 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 68 | 69 | isexe@^2.0.0: 70 | version "2.0.0" 71 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 72 | 73 | lru-cache@^4.0.1: 74 | version "4.1.2" 75 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" 76 | dependencies: 77 | pseudomap "^1.0.2" 78 | yallist "^2.1.2" 79 | 80 | map-stream@~0.1.0: 81 | version "0.1.0" 82 | resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" 83 | 84 | pause-stream@0.0.11: 85 | version "0.0.11" 86 | resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" 87 | dependencies: 88 | through "~2.3" 89 | 90 | ps-tree@^1.1.0: 91 | version "1.1.0" 92 | resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" 93 | dependencies: 94 | event-stream "~3.3.0" 95 | 96 | pseudomap@^1.0.2: 97 | version "1.0.2" 98 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 99 | 100 | shebang-command@^1.2.0: 101 | version "1.2.0" 102 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 103 | dependencies: 104 | shebang-regex "^1.0.0" 105 | 106 | shebang-regex@^1.0.0: 107 | version "1.0.0" 108 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 109 | 110 | split@0.3: 111 | version "0.3.3" 112 | resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" 113 | dependencies: 114 | through "2" 115 | 116 | stream-combiner@~0.0.4: 117 | version "0.0.4" 118 | resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" 119 | dependencies: 120 | duplexer "~0.1.1" 121 | 122 | supports-color@^5.3.0: 123 | version "5.3.0" 124 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" 125 | dependencies: 126 | has-flag "^3.0.0" 127 | 128 | through@2, through@~2.3, through@~2.3.1: 129 | version "2.3.8" 130 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 131 | 132 | tsc-watch@^1.0.17: 133 | version "1.0.17" 134 | resolved "https://registry.yarnpkg.com/tsc-watch/-/tsc-watch-1.0.17.tgz#c33e564aba93617823b17996f2dd999cefb7a0b9" 135 | dependencies: 136 | chalk "^2.3.0" 137 | cross-spawn "^5.1.0" 138 | ps-tree "^1.1.0" 139 | typescript "*" 140 | 141 | typescript@*: 142 | version "2.7.2" 143 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" 144 | 145 | which@^1.2.9: 146 | version "1.3.0" 147 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 148 | dependencies: 149 | isexe "^2.0.0" 150 | 151 | yallist@^2.1.2: 152 | version "2.1.2" 153 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 154 | --------------------------------------------------------------------------------