├── .github ├── actions │ └── generate-resources │ │ ├── .gitignore │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── __tests__ │ │ └── main.test.js │ │ ├── action.yml │ │ ├── init.js │ │ ├── main.js │ │ └── package.json └── workflows │ └── refresh.yml ├── CONTRIBUTING.md ├── GLOSSARY.md ├── README.md └── RESOURCES.md /.github/actions/generate-resources/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.lock -------------------------------------------------------------------------------- /.github/actions/generate-resources/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "proseWrap": "always" 9 | } 10 | -------------------------------------------------------------------------------- /.github/actions/generate-resources/README.md: -------------------------------------------------------------------------------- 1 | # Generate RESOURCES.md Action 2 | 3 | This action reads data from the Developer DAO Airtable and puts its content into RESOURCES.md. 4 | 5 | ## Authors 6 | 7 | - [@gjsyme](https://github.com/gjsyme) 8 | - [@codingwithmanny](https://github.com/codingwithmanny) 9 | 10 | ## Requirements 11 | 12 | - NVM or Node `v16.13.0` 13 | 14 | ## Setup 15 | 16 | ```bash 17 | yarn install; 18 | ``` 19 | 20 | ## Tests 21 | 22 | ```bash 23 | yarn test; 24 | ``` 25 | 26 | ## How To Run Locally 27 | 28 | **NOTE:** `DO NOT` run this from within the `actions/generate-resources` folder, it will overwrite this `RESOURCES.md`. 29 | 30 | **NOTE:** You need to have the [nektos/act](https://github.com/nektos/act) cli on your system for this to work as it has been developed 31 | Once installed, you can call the below command. 32 | 33 | **NOTE:** You need to create the github token for yourself in order to test on your local machine. As it is your github token, you will only be able to push to repos you have write access to. 34 | 35 | ```bash 36 | act -v -s GITHUB_TOKEN=YOUR_USER_TOKEN -j refresh 37 | ``` 38 | 39 | ## Example GitHub Action Usage 40 | 41 | ```yaml 42 | jobs: 43 | refresh: 44 | name: Scheduling 45 | runs-on: ubuntu-latest 46 | steps: 47 | - name: Checkout 48 | uses: actions/checkout@v2 49 | 50 | - name: Enable node 51 | uses: actions/setup-node@v2 52 | with: 53 | node-version: 16.x 54 | 55 | - name: Install Yarn 56 | run: npm i -g yarn 57 | 58 | # hack given that we don't have top-level dependencies 59 | # go into the directory and install (resets dir before next command is run) 60 | - name: Install dependencies 61 | run: cd ./.github/actions/generate-resources && yarn install --frozen-lockfile 62 | 63 | - name: Run action 64 | uses: ./.github/actions/generate-resources 65 | 66 | - name: Prettier clean up 67 | run: ./.github/actions/generate-resources/node_modules/.bin/prettier RESOURCES.md --write 68 | 69 | # note the harcode of the repo name. this could be done better if we wanted to use this repeatedly, but seems like a one-off 70 | # if you're testing, make sure that the repo organization and repo name (gjsyme and resources, respectively, here) are replaced by something 71 | # that something needs to be writable by a user with your permissions (from your GH token) 72 | - name: Commit changes 73 | run: | 74 | git add RESOURCES.md 75 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/gjsyme/resources 76 | git -c user.name="D_D RESOURCE BOT" -c user.email="resource_bot@users.noreply.github.com" commit -m 'Refresh RESOURCES.md from Airtable' || echo 'No changes to commit' 77 | git push origin || echo 'No changes to commit' 78 | ``` -------------------------------------------------------------------------------- /.github/actions/generate-resources/__tests__/main.test.js: -------------------------------------------------------------------------------- 1 | // Mocks 2 | // **NOTE:** Mocks needs to be init before main is imported 3 | // ex: ReferenceError: Cannot access 'mockAirtableBase' before initialization 4 | // ======================================================== 5 | // To suppress the console.error 6 | global.console = { 7 | ...jest.requireActual('console'), 8 | error: jest.fn(), 9 | }; 10 | 11 | /** 12 | * 13 | */ 14 | const mockAirtableEachPageNextPage = jest.fn(); 15 | 16 | /** 17 | * 18 | */ 19 | const mockAirtableEachPage = jest.fn(); 20 | 21 | /** 22 | * 23 | */ 24 | const mockAirtableSelect = jest.fn(() => ({ 25 | eachPage: mockAirtableEachPage, 26 | })); 27 | 28 | /** 29 | * 30 | */ 31 | const mockAirtableBase = jest.fn(() => { 32 | return () => ({ 33 | select: mockAirtableSelect, 34 | }); 35 | }); 36 | 37 | /** 38 | * 39 | */ 40 | jest.mock('airtable', () => { 41 | return jest.fn().mockImplementation(() => ({ 42 | base: mockAirtableBase, 43 | })); 44 | }); 45 | 46 | /** 47 | * 48 | */ 49 | const mockWriteFileSync = jest.fn(); 50 | 51 | /** 52 | * 53 | */ 54 | jest.mock('fs', () => { 55 | return { 56 | writeFileSync: mockWriteFileSync, 57 | }; 58 | }); 59 | 60 | /** 61 | * 62 | */ 63 | afterEach(() => { 64 | jest.clearAllMocks(); 65 | }); 66 | 67 | // Imports 68 | // ======================================================== 69 | const main = require('../main'); 70 | 71 | // Tests 72 | // ======================================================== 73 | /** 74 | * Failure - fetchAirtableData 75 | */ 76 | test('[Failure]: fetchAirtableData handles errors and returns empty array', async () => { 77 | // Setup 78 | 79 | // Pre Expectations 80 | expect(mockAirtableBase).not.toHaveBeenCalled(); 81 | 82 | // Init 83 | const result = await main.fetchAirtableData(); 84 | 85 | // Post Expectatations 86 | expect(mockAirtableBase).not.toHaveBeenCalled(); 87 | expect(result).toEqual([]); 88 | }); 89 | 90 | /** 91 | * Success - fetchAirtableData 92 | */ 93 | test('[Success]: fetchAirtableData returns array', async () => { 94 | // Setup 95 | mockAirtableEachPage.mockImplementation((callback) => { 96 | callback( 97 | [ 98 | { 99 | _rawJson: 'entry1', 100 | }, 101 | { 102 | _rawJson: 'entry2', 103 | }, 104 | ], 105 | mockAirtableEachPageNextPage, 106 | ); 107 | }); 108 | 109 | // Pre Expectations 110 | expect(mockAirtableBase).not.toHaveBeenCalled(); 111 | 112 | // Init 113 | const result = await main.fetchAirtableData('random'); 114 | 115 | // Post Expectatations 116 | expect(mockAirtableBase).toHaveBeenCalledWith(main.AIRTABLE_RESOURCE_BASE); 117 | expect(mockAirtableBase).toHaveBeenCalled(); 118 | expect(mockAirtableSelect).toHaveBeenCalled(); 119 | expect(mockAirtableEachPage).toHaveBeenCalled(); 120 | expect(mockAirtableEachPageNextPage).toHaveBeenCalled(); 121 | expect(result).toEqual(['entry1', 'entry2']); 122 | }); 123 | 124 | /** 125 | * Failure - init 126 | */ 127 | test('[Failure]: init returns a default README.md', async () => { 128 | // Setup 129 | const airTableResourceData = [ 130 | { 131 | _rawJson: { 132 | fields: { 133 | Title: 'Title1', 134 | Source: 'Source1', 135 | Author: ['unknownAuthorId1'], 136 | Summary: 'Summary1', 137 | }, 138 | }, 139 | }, 140 | ]; 141 | mockAirtableEachPage.mockImplementation((callback) => { 142 | callback(airTableResourceData, mockAirtableEachPageNextPage); 143 | }); 144 | const README_RESOURCE_BODY = airTableResourceData.map( 145 | (item) => 146 | `- [${item?._rawJson?.fields?.Title}](${ 147 | item?._rawJson?.fields?.Source 148 | })\n\n Author${ 149 | item?._rawJson?.fields?.Author?.length > 1 ? 's' : '' 150 | }: ${item?._rawJson?.fields?.Author?.map(() => '')}${ 151 | item?._rawJson?.fields?.Summary 152 | ? '\n' + item?._rawJson?.fields?.Summary 153 | : '' 154 | }`, 155 | ); 156 | 157 | // Pre Expectatations 158 | expect(mockAirtableBase).not.toHaveBeenCalled(); 159 | 160 | // Init 161 | await main.init(); 162 | 163 | // Post Expectatations 164 | expect(mockAirtableBase).toHaveBeenCalled(); 165 | expect(mockWriteFileSync).toHaveBeenCalled(); 166 | expect(mockWriteFileSync).toHaveBeenCalledWith( 167 | './README.md', 168 | `${main.README_RESOURCE_HEADER}${README_RESOURCE_BODY}`, 169 | ); 170 | }); 171 | 172 | /** 173 | * Success - init 174 | */ 175 | test('[Success]: init returns full README.md', async () => { 176 | // Setup 177 | const airTableAuthorData = [ 178 | { 179 | _rawJson: { 180 | id: 'unknownAuthorId1', 181 | fields: { 182 | Name: 'AuthorName1', 183 | }, 184 | }, 185 | }, 186 | { 187 | _rawJson: { 188 | id: 'unknownAuthorId2', 189 | fields: { 190 | Name: 'AuthorName2', 191 | }, 192 | }, 193 | }, 194 | { 195 | _rawJson: { 196 | id: 'unknownAuthorId3', 197 | fields: { 198 | Name: '', 199 | }, 200 | }, 201 | }, 202 | ]; 203 | const airTableResourceData = [ 204 | { 205 | _rawJson: { 206 | fields: { 207 | Title: 'Title1', 208 | Source: 'Source1', 209 | Author: ['unknownAuthorId1', 'unknownAuthorId2', 'unknownAuthorId3'], 210 | Summary: 'Summary1', 211 | }, 212 | }, 213 | }, 214 | ]; 215 | 216 | mockAirtableBase.mockImplementation(() => { 217 | return (tableName) => { 218 | if (tableName === 'Author') { 219 | return { 220 | select: () => ({ 221 | eachPage: (callback) => { 222 | callback(airTableAuthorData, mockAirtableEachPageNextPage); 223 | }, 224 | }), 225 | }; 226 | } 227 | return { 228 | select: () => ({ 229 | eachPage: (callback) => { 230 | callback(airTableResourceData, mockAirtableEachPageNextPage); 231 | }, 232 | }), 233 | }; 234 | }; 235 | }); 236 | 237 | const authorMap = {}; 238 | airTableAuthorData.forEach((item) => { 239 | if (item?._rawJson?.id && item?._rawJson?.fields) { 240 | authorMap[item?._rawJson?.id] = item?._rawJson?.fields; 241 | } 242 | }); 243 | 244 | const README_RESOURCE_BODY = airTableResourceData.map( 245 | (item) => 246 | `- [${item?._rawJson?.fields?.Title}](${ 247 | item?._rawJson?.fields?.Source 248 | })\n\n Author${ 249 | item?._rawJson?.fields?.Author?.length > 1 ? 's' : '' 250 | }: ${item?._rawJson?.fields?.Author?.map( 251 | (authorId) => authorMap[authorId]?.Name ?? '', 252 | )}${ 253 | item?._rawJson?.fields?.Summary 254 | ? '\n' + item?._rawJson?.fields?.Summary 255 | : '' 256 | }`, 257 | ); 258 | 259 | // Pre Expectatations 260 | expect(mockAirtableBase).not.toHaveBeenCalled(); 261 | 262 | // Init 263 | await main.init(); 264 | 265 | // Post Expectatations 266 | expect(mockAirtableBase).toHaveBeenCalled(); 267 | expect(mockWriteFileSync).toHaveBeenCalledWith( 268 | './README.md', 269 | `${main.README_RESOURCE_HEADER}${README_RESOURCE_BODY}`, 270 | ); 271 | }); 272 | -------------------------------------------------------------------------------- /.github/actions/generate-resources/action.yml: -------------------------------------------------------------------------------- 1 | name: 'generate resources' 2 | description: 'Read Developer DAO Airtable and generate README.md' 3 | runs: 4 | using: 'node12' 5 | main: 'init.js' -------------------------------------------------------------------------------- /.github/actions/generate-resources/init.js: -------------------------------------------------------------------------------- 1 | // Imports 2 | // ======================================================== 3 | const main = require('./main'); 4 | 5 | /** 6 | * 7 | */ 8 | main.init(); -------------------------------------------------------------------------------- /.github/actions/generate-resources/main.js: -------------------------------------------------------------------------------- 1 | // Imports 2 | // ======================================================== 3 | const Airtable = require('airtable'); 4 | const fs = require('fs'); 5 | 6 | // Constants 7 | // ======================================================== 8 | // airtable resources managed by @kempsterrrr 9 | // these should be replaced by secrets other than these values 10 | const AIRTABLE_READONLY_KEY = 'keyDaaDlZelNrerXQ'; 11 | const AIRTABLE_RESOURCE_BASE = 'appPP6MpO5hrfQwqI'; 12 | const RESOURCE_HEADER = `# Resources\n\n`; 13 | 14 | // Config 15 | // ======================================================== 16 | const airtable = new Airtable({ apiKey: AIRTABLE_READONLY_KEY }); 17 | 18 | // Functions 19 | // ======================================================== 20 | /** 21 | * 22 | * @param {*} tableName 23 | * @returns 24 | */ 25 | const fetchAirtableData = async (tableName) => { 26 | let DATA = []; 27 | try { 28 | if (!tableName) throw new Error('Invalid name.'); 29 | 30 | await airtable 31 | .base(AIRTABLE_RESOURCE_BASE)(tableName) 32 | .select() 33 | .eachPage((records, fetchNextPage) => { 34 | DATA = records 35 | ? [...DATA, ...records.map((item) => item ? item._rawJson || '' : '')] 36 | : DATA; 37 | fetchNextPage(); 38 | }); 39 | } catch (error) { 40 | console.error(`ERROR: Fetching '${tableName}''`, { error }); 41 | } 42 | 43 | return DATA; 44 | }; 45 | 46 | /** 47 | * 48 | * @param {*} authorTwitter a string containing the twitter handle possibly with other undesired content 49 | * @returns the string twitter handler from the input 50 | */ 51 | const cleanTwitterString = (authorTwitter) => { 52 | if (!authorTwitter) return; 53 | // prevent casing weirdness and ensure lowercasae for checking 54 | const compare = authorTwitter.toLowerCase(); 55 | // lazy, ifs for the common distortions 56 | // either the '.com/' construct or starting with @ 57 | if (compare.indexOf('twitter.com') > -1) { 58 | const comIndex = compare.indexOf('.com/') + 5; 59 | return authorTwitter.substring(comIndex, authorTwitter.length); 60 | } 61 | if (compare.startsWith('@')) { 62 | return authorTwitter.substring(1, authorTwitter.length); 63 | } 64 | return authorTwitter; 65 | }; 66 | 67 | /** 68 | * 69 | */ 70 | const init = async () => { 71 | // Retrieve airtable data 72 | const resourcesData = await fetchAirtableData('Resource'); 73 | const authorsData = await fetchAirtableData('Author'); 74 | console.log( 75 | `received ${resourcesData.length} resources and ${authorsData.length} authors`, 76 | ); 77 | 78 | // ids used with resources 79 | const authorMap = {}; 80 | authorsData.filter(item => item).forEach((item) => { 81 | if (item.id && item.fields) { 82 | authorMap[item.id] = { 83 | ...item.fields, 84 | Twitter: cleanTwitterString(item.fields.Twitter) 85 | } 86 | } 87 | }); 88 | 89 | /** 90 | * 91 | * @param {Author} author the airtable author, notably included Name and optional Twitter value 92 | * returns the string (markdown) value for the author 93 | */ 94 | const buildAuthorText = (author) => { 95 | if(author.Twitter){ 96 | return `[${author.Name ? author.Name : 'No name given'}](https://twitter.com/${author.Twitter})`; 97 | } 98 | return author.Name ? author.Name : ''; 99 | } 100 | 101 | const buildSection = (title, resourceList) => { 102 | let resource_string = `## ${title}\n\n`; 103 | return resource_string.concat( 104 | // filter to make up for old node not supporting attribute.?otherAttribute syntax 105 | resourceList.filter(item => (item && item.fields && item.fields.Author)).map( 106 | (item) => ( 107 | `- [${item.fields.Title}](${item.fields.Source})\n\n Author${ 108 | item.fields.Author.length > 1 ? 's' : '' 109 | }: ${item.fields.Author.map((authorId) => buildAuthorText(authorMap[authorId]))}${ 110 | item.fields.Summary ? '\n\n ' + item.fields.Summary : '' 111 | }` 112 | ) 113 | ) 114 | .join('\n\n') 115 | ); 116 | } 117 | 118 | const RESOURCE_BODY = 119 | buildSection('Beginner', resourcesData.filter((item) => (item.fields && item.fields.Level==='Beginner')))+'\n\n' 120 | + buildSection('Intermediate', resourcesData.filter((item) => (item.fields && item.fields.Level==='Intermediate')))+'\n\n' 121 | + buildSection('Advanced', resourcesData.filter((item) => (item.fields && item.fields.Level==='Advanced')))+'\n\n'; 122 | console.log( 123 | 'writing to ./RESOURCES.md', 124 | RESOURCE_HEADER, 125 | RESOURCE_BODY, 126 | ); 127 | 128 | // Write RESOURCES.md file 129 | fs.writeFileSync( 130 | './RESOURCES.md', 131 | `${RESOURCE_HEADER}${RESOURCE_BODY}`, 132 | ); 133 | }; 134 | 135 | // Exports 136 | // ======================================================== 137 | module.exports = { 138 | fetchAirtableData, 139 | init, 140 | AIRTABLE_READONLY_KEY, 141 | AIRTABLE_RESOURCE_BASE, 142 | RESOURCE_HEADER, 143 | }; 144 | -------------------------------------------------------------------------------- /.github/actions/generate-resources/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-resources", 3 | "version": "0.2.0", 4 | "description": "An action to read Developer DAO Airtable and generate README.md", 5 | "main": "main.js", 6 | "author": "@gjsyme", 7 | "license": "MIT", 8 | "private": false, 9 | "scripts": { 10 | "start": "node main.js && ./node_modules/.bin/prettier README.md --write", 11 | "test": "jest", 12 | "prettier": "./node_modules/.bin/prettier . --write" 13 | }, 14 | "dependencies": { 15 | "airtable": "^0.11.1", 16 | "prettier": "^2.4.1" 17 | }, 18 | "devDependencies": { 19 | "jest": "^27.3.1" 20 | } 21 | } -------------------------------------------------------------------------------- /.github/workflows/refresh.yml: -------------------------------------------------------------------------------- 1 | name: Populate Markdown 2 | 3 | on: 4 | # actual valid github configuration that would get called 5 | schedule: 6 | - cron: '0 0 * * *' 7 | 8 | jobs: 9 | refresh: 10 | name: Scheduling 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | 16 | - name: Enable node 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: 16.x 20 | 21 | - name: Install Yarn 22 | run: npm i -g yarn 23 | 24 | # hack given that we don't have top-level dependencies 25 | # go into the directory and install (resets dir before next command is run) 26 | - name: Install dependencies 27 | run: cd ./.github/actions/generate-resources && yarn install --frozen-lockfile 28 | 29 | - name: Run action 30 | uses: ./.github/actions/generate-resources 31 | 32 | - name: Prettier clean up 33 | run: ./.github/actions/generate-resources/node_modules/.bin/prettier RESOURCES.md --write 34 | 35 | # note the harcode of the repo name. this could be done better if we wanted to use this repeatedly, but seems like a one-off 36 | - name: Commit changes 37 | run: | 38 | git add RESOURCES.md 39 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} 40 | git -c user.name="D_D RESOURCE BOT" -c user.email="resource_bot@users.noreply.github.com" commit -m 'Refresh RESOURCES.md from Airtable' || echo 'No changes to commit' 41 | git push origin || echo 'No changes to commit' -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for taking the time to contribute to our knowledge base. 4 | 5 | We'd love for you to contribute directly by creating a pull request. If this is not possible, and you have new links or information to add, create an issue. We'll review and add it into the repo as needed. 6 | 7 | ## Guidelines 8 | - TBD 9 | 10 | ## Pull Request Tips 11 | - Fork the repo and clone it locally 12 | - Follow contributing guidelines above 13 | - For more information: 14 | - [Creating a pull request from a fork](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) -------------------------------------------------------------------------------- /GLOSSARY.md: -------------------------------------------------------------------------------- 1 | 2 | # 📓 Glossary 3 | 4 | ## B 5 | - What is a Blockchain? 6 | > A blockchain is a public database that is updated and shared across many computers in a network. 7 | 8 | > "Block" refers to data and state being stored in consecutive groups known as "blocks". If you send ETH to someone else, the transaction data needs to be added to a block to be successful. 9 | 10 | > "Chain" refers to the fact that each block cryptographically references its parent. In other words, blocks get chained together. The data in a block cannot change without changing all subsequent blocks, which would require the consensus of the entire network. 11 | 12 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/intro-to-ethereum/) 13 | 14 | ## D 15 | - What is a dapp? 16 | > A decentralized application (dapp) is an application built on a decentralized network that combines a smart contract and a frontend user interface. Note: in Ethereum, smart-contracts are accessible and transparent – like open APIs – so your dapp can even include a smart contract that someone else has written. 17 | 18 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/dapps/) 19 | 20 | - What is Defi? 21 | > DeFi is a collective term for financial products and services that are accessible to anyone who can use Ethereum – anyone with an internet connection. With DeFi, the markets are always open and there are no centralized authorities who can block payments or deny you access to anything. Services that were previously slow and at risk of human error are automatic and safer now that they're handled by code that anyone can inspect and scrutinize. 22 | 23 | [Learn more about DeFi from here](https://ethereum.org/en/defi/) 24 | 25 | ## E 26 | - What are ERC Tokens? 27 | > ERCs (Ethereum Request for Comments) are technical documents used by smart contract developers at Ethereum. They define a set of rules required to implement tokens for the Ethereum ecosystem. These documents are usually created by developers, and they include information about protocol specifications and contract descriptions. Before becoming an standard, an ERC must be revised, commented and accepted by the community through an EIP (Ethereum Improvement Proposal). 28 | 29 | [Learn more from EthHub Docs](https://docs.ethhub.io/built-on-ethereum/erc-token-standards/what-are-erc-tokens/) 30 | 31 | - What is ERC-20? 32 | > The ERC-20 introduces a standard for Fungible Tokens, in other words, they have a property that makes each Token be exactly the same (in type and value) of another Token. For example, an ERC-20 Token acts just like the ETH, meaning that 1 Token is and will always be equal to all the other Tokens. 33 | 34 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) 35 | 36 | - What is ERC-721? 37 | > The ERC-721 introduces a standard for NFT, in other words, this type of Token is unique and can have different value than another Token from the same Smart Contract, maybe due to its age, rarity or even something else like its visual. 38 | 39 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) 40 | 41 | - What is Ether? 42 | > Ether (ETH) is the cryptocurrency used to pay for computing services on the Ethereum blockchain. 43 | 44 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/intro-to-ether/) 45 | 46 | - What is Ethereum? 47 | > Ethereum is a blockchain platform with its own cryptocurrency, called Ether (ETH) or Ethereum, and its own programming language, called Solidity. 48 | 49 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/intro-to-ethereum/) 50 | 51 | - What is Ethereum Virtual Machine (EVM)? 52 | > The Ethereum protocol itself exists solely for the purpose of keeping the continuous, uninterrupted, and immutable operation of this special state machine; It's the environment in which all Ethereum accounts and smart contracts live. At any given block in the chain, Ethereum has one and only one 'canonical' state, and the EVM is what defines the rules for computing a new valid state from block to block. 53 | 54 | [Learn more from EVM Docs](https://ethereum.org/en/developers/docs/evm/) 55 | 56 | - What is Ether.js? 57 | > A complete Ethereum wallet implementation and utilities in JavaScript (and TypeScript). 58 | [Learn more from ether Docs](https://docs.ethers.io/v5/) 59 | 60 | 61 | ## F 62 | - What is a Fungible Token? 63 | > The ERC-20 introduces a standard for Fungible Tokens, in other words, they have a property that makes each Token be exactly the same (in type and value) of another Token. For example, an ERC-20 Token acts just like the ETH, meaning that 1 Token is and will always be equal to all the other Tokens. 64 | 65 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) 66 | 67 | ## G 68 | - What is Gas? 69 | > Gas is essential to the Ethereum network. It is the fuel that allows it to operate, in the same way that a car needs gasoline to run. 70 | 71 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/gas/) 72 | - What is Ganache? 73 | > Ganache is a test network for Ethereum. It is a blockchain simulator client or virtual blockchain that runs on your computer. It is a free service that allows you to test your smart contracts and Ethereum smart contracts. blockchain simulator client. You can think of it as similar to a localhost server, it's a private blockchain that only runs on your computer. 74 | 75 | [Learn more from Ganache Docs](https://trufflesuite.com/ganache/) 76 | 77 | ## H 78 | - What is Hardhat? 79 | > Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software. It helps developers manage and automate the recurring tasks that are inherent to the process of building smart contracts and dApps, as well as easily introducing more functionality around this workflow. This means compiling, running and testing smart contracts at the very core. 80 | 81 | [Learn more from Hardhat Docs](https://hardhat.org/getting-started/) 82 | 83 | ## L 84 | 85 | - What is Layer 2? 86 | > Layer 2 is a collective term for solutions designed to help scale your application by handling transactions off the Ethereum Mainnet (Layer 1) while taking advantage of the robust decentralized security model of Mainnet. 87 | 88 | [Learn more from ethereum.org](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/) 89 | 90 | ## M 91 | - What is Metamask? 92 | 93 | > Metamask is a crypto wallet- it allows you to store and transact Ethereum or any other Ethereum-based (ERC- 20) tokens. 94 | 95 | [Learn more from Metamask Docs](https://docs.metamask.io/guide/) 96 | ## N 97 | - What is a Non-Fungible Token? 98 | > A Non-Fungible Token (NFT) is used to identify something or someone in a unique way. This type of Token is perfect to be used on platforms that offer collectible items, access keys, lottery tickets, numbered seats for concerts and sports matches, etc. This special type of Token has amazing possibilities so it deserves a proper Standard, the ERC-721 came to solve that! 99 | 100 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) 101 | 102 | - What is Nonce? 103 | > a counter that indicates the number of transactions sent from the account. This ensures transactions are only processed once. In a contract account, this number represents the number of contracts created by the ac 104 | 105 | ## R 106 | - What is Remix IDE? 107 | > Remix IDE is an open source web and desktop application. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the entire journey of contract development with Solidity language in as well as being a playground for learning and teaching Ethereum. you can switch to remixid on your browser from here [here](https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js) 108 | 109 | [Learn more from Remix IDE docs](https://remix-ide.readthedocs.io/en/latest/#) 110 | ## S 111 | - What is a Smart Contract? 112 | > A "smart contract" is simply a program that runs on the Ethereum blockchain. It's a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain. 113 | 114 | [Learn more from Ethereum Docs](https://ethereum.org/en/developers/docs/smart-contracts/) 115 | 116 | - What is Solana? 117 | > Solana is an open source project implementing a new, high-performance, permissionless blockchain. 118 | 119 | [Learn more from Solana Docs](https://docs.solana.com/introduction) 120 | 121 | - What is Solidity? 122 | > Solidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs which govern the behaviour of accounts within the Ethereum state. 123 | 124 | > Solidity is a curly-bracket language. It is influenced by C++, Python and JavaScript, and is designed to target the Ethereum Virtual Machine (EVM). 125 | 126 | [Learn more from Solidity Docs](https://docs.soliditylang.org/en/v0.8.8/) 127 | ## T 128 | - What is a Transaction? 129 | >An Ethereum transaction refers to an action initiated by an externally-owned account, in other words an account managed by a human, not a contract. For example, if Bob sends Alice 1 ETH, Bob's account must be debited and Alice's must be credited. This state-changing action takes place within a transaction. 130 | 131 | - What is Truffle ? 132 | > Truffle is a world-class development environment, testing framework and asset pipeline for blockchains using the Ethereum Virtual Machine (EVM), aiming to make life as a developer easier. 133 | 134 | [Learn more from Truffle Docs](https://www.trufflesuite.com/docs/truffle/overview) 135 | 136 | ## W 137 | - What is Web3.Js? 138 | > It is a JavaScript library that allows you to interact with the Ethereum (local or remote) blockchain using HTTP, IPC or WebSocket. It acts as the middleman between your frontend and your smart contracts. 139 | 140 | [Learn more from Web3 Docs](https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html) 141 | 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | Welcome to the [DeveloperDAO](https://github.com/Developer-DAO/developer-dao) **Knowledge Base**. 4 | 5 | The community has created this knowledge base to help you **learn** and **grow** in your Web3 journey, whether you want to start learning about Web3, or you're building your first dApp, or you're deep into the world of solidity. 6 | 7 | ## Terminology 8 | 9 | - Visit the [Glossary](GLOSSARY.md) to understand more about a specific term. 10 | 11 | ## Getting Started with Web3 Development 12 | 13 | ### 💡 Learning about Web3 14 | 15 | - [What is Web3? The Decentralized Internet of the Future Explained](https://www.freecodecamp.org/news/what-is-web3/) 16 | - [How to Break into Ethereum, Crypto, and Web3 as a Developer](https://www.freecodecamp.org/news/breaking-into-ethereum-crypto-web3-as-a-developer/) 17 | 18 | ### 📄 Tutorials 19 | 20 | - [The Complete Guide to Full Stack Ethereum Development](https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13) 21 | 22 | This guide by [Nader Dabit](https://github.com/dabit3) is especially useful for Web2 devs and provides a basic understanding of building a full stack dApp from end-to-end using technologies including Hardhat, Solidity, Ethers.js, The Graph, and React. 23 | 24 | - [How to write your first decentralized app - scaffold-eth Challenge 1: Staking dApp](https://dev.to/stermi/scaffold-eth-challenge-1-staking-dapp-4ofb) 25 | 26 | This guide by [Emanuele Ricci](https://twitter.com/StErMi) will cover in depth the first speed run challenge from scaffold-eth. Inside you will find web3/solidity concepts, explanations and detailed code review. 27 | 28 | - [How to create an ERC20 Token and a Solidity Vendor Contract to sell/buy your own token](https://dev.to/stermi/how-to-create-an-erc20-token-and-a-solidity-vendor-contract-to-sell-buy-your-own-token-4j1m) 29 | 30 | This guide by [Emanuele Ricci](https://twitter.com/StErMi) will cover in depth the second speed run challenge from scaffold-eth. Inside you will find web3/solidity concepts, explanations and detailed code review. 31 | 32 | - [How to deploy your first smart contract on Ethereum with Solidity and Hardhat](https://dev.to/stermi/how-to-deploy-your-first-smart-contract-on-ethereum-with-solidity-and-hardhat-5efc) 33 | 34 | This guide by [Emanuele Ricci](https://twitter.com/StErMi) will cover how to configure Hardhat to compile, deploy test and debug a Solidity project. You will learn to create a smart contract, test it with Waffle, deploy it on Rinkeby and get it verified by Etherscan. 35 | 36 | - [How to deploy your first NFT contract on Ethereum](https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft) 37 | 38 | This guide could tell you how to write and deploy NFT contract, also it could help you to run front-end about minting your deployed contract. Could choose Truffle or Hardhat. And this tutorial could teach you how to mint NFT by script. 39 | 40 | ### 📺 Content Creator Channels 41 | 42 | - [Nader Dabit on YouTube](https://www.youtube.com/c/naderdabit) 43 | - [Austin Griffith on YouTube](https://www.youtube.com/channel/UC_HI2i2peo1A-STdG22GFsA) 44 | - [Patrick Collins on YouTube](https://www.youtube.com/channel/UCn-3f8tw_E1jZvhuHatROwA) 45 | - [Whiteboard Crypto on YouTube](https://www.youtube.com/channel/UCsYYksPHiGqXHPoHI-fm5sg) 46 | - [EatTheBlock on YouTube](https://www.youtube.com/c/EatTheBlocks) 47 | 48 | ### 📚 Docs 49 | 50 | - [Ethereum Development Documentation](https://ethereum.org/en/developers/docs/) 51 | - [Solidity Documentation](https://docs.soliditylang.org/en/v0.8.8/index.html) 52 | - [Solidity By Example](https://docs.soliditylang.org/en/v0.8.8/solidity-by-example.html) 53 | 54 | ### 📖 Books 55 | 56 | - [Mastering Ethereum](https://github.com/ethereumbook/ethereumbook), open source book by Andreas M. Antonopoulos and Gavin Wood 57 | - [Hands-On Smart Contract Development with Solidity and Ethereum](https://www.oreilly.com/library/view/hands-on-smart-contract/9781492045250/), by Kevin Solorio, Randall Kanna, and David H. Hoover 58 | 59 | ### 🤯 More Resource Lists 60 | 61 | - [Solidity cheatsheet and best practices](https://github.com/manojpramesh/solidity-cheatsheet) 62 | - [Solidity gotchas, pitfalls, limitations, and idiosyncrasies](https://github.com/miguelmota/solidity-idiosyncrasies) 63 | - [Awesome Solidity](https://github.com/bkrem/awesome-solidity) 64 | - [Awesome Smart Contracts](https://github.com/transmute-industries/awesome-smart-contracts) 65 | - [Not So Smart Contracts](https://github.com/crytic/not-so-smart-contracts) 66 | - [useWeb3](https://www.useweb3.xyz/) 67 | - [Open source web3 develop tutorial](https://github.com/ConsenSys-Academy/Blockchain-Developer-Bootcamp) 68 | 69 | ### 🎮 Interactive Game Tutorials 70 | 71 | - [CryptoZombies](https://cryptozombies.io/en/solidity) 72 | - [Capture the Ether](https://capturetheether.com/) 73 | 74 | ### 🔨 Tools 75 | 76 | - [Remix IDE](https://remix.ethereum.org/) 77 | - [ETH.Build](https://eth.build/) 78 | - [Etherscan](https://etherscan.io/) 79 | - [scaffold-eth](https://github.com/scaffold-eth/scaffold-eth) - 🏗 forkable Ethereum dev stack focused on fast product iterations 80 | - [eth-hooks](https://github.com/scaffold-eth/eth-hooks) - Commonly used Ethereum hooks to create a web3 application 81 | - [eth-components](https://github.com/scaffold-eth/eth-components) - React library of commonly used Ethereum components to kickstart your next web3 react app 82 | - [useDApp](https://usedapp.io/) - Framework for rapid Dapp development. Simple. Robust. Extendable. Testable 83 | 84 | ## Technologies 85 | 86 | ### Ethereum 87 | 88 | - [Ethereum Development Documentation](https://ethereum.org/en/developers/docs/) 89 | - [Hardhat Documentation](https://hardhat.org/getting-started/) 90 | - [Solidity Documentation](https://docs.soliditylang.org/en/v0.8.8/index.html) 91 | - [Truffle Suite Documentation](https://www.trufflesuite.com/docs) 92 | 93 | ## Dorage (Decentralized Storage) 94 | 95 | - [IPFS](https://ipfs.io/) 96 | - [Arweave](https://www.arweave.org/) 97 | - [Filecoin](https://filecoin.io/) 98 | 99 | ### Solana 100 | 101 | - [Solana Developer Resources](https://github.com/CristinaSolana/solana-developer-resources) 102 | 103 | ### Layer 2 Rollups 104 | 105 | Layer 2 rollups provide a path to scaling Ethereum in a way that preserves the security guarantees of mainnet while increasing the transaction throughput and affordability of using Ethereum. Two main types of solutions exist, Optimistic Rollups and Zero-Knowledge Rollups. Below are some resources for learning more and getting started. 106 | 107 | - [Rollups Overview](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/) 108 | - [Optimism Developer Documentation](https://community.optimism.io/docs/) 109 | - [Truffle Optimism Box](https://github.com/truffle-box/optimism-box) 110 | - [Arbitrum Developer Documentation](https://developer.offchainlabs.com/docs/developer_quickstart) 111 | - [Truffle Arbitrum Box](https://github.com/truffle-box/arbitrum-box) 112 | - [Starknet](https://starkware.co/starknet/) 113 | - [Tutorial Using Starknet with Nile](https://medium.com/coinmonks/starknet-tutorial-for-beginners-using-nile-6af9c2270c15) 114 | - [zkSync Developer Documentation](https://zksync.io/dev/) 115 | 116 | ## Use Cases 117 | 118 | ### DeFi 119 | 120 | - Examples: 121 | - [UniSwap](https://uniswap.org/) 122 | 123 | ### NFT Marketplaces 124 | 125 | - Examples: 126 | - [OpenSea](https://opensea.io/) 127 | - Tutorials: 128 | - [Building a Full Stack NFT Marketplace on Ethereum with Polygon](https://dev.to/dabit3/building-scalable-full-stack-apps-on-ethereum-with-polygon-2cfb) 129 | 130 | ### Games 131 | 132 | - Examples: 133 | - [CryptoKitties](https://www.cryptokitties.co/) 134 | - [LootWars](https://lootwars.xyz/) 135 | 136 | ## Courses 137 | 138 | ### Free Courses 139 | 140 | - [Buildspace](https://buildspace.so) 141 | 142 | Action-oriented and community-driven course platform. Learn how to build a simple dApp or mint your own NFTs in just hours. (More courses later) 143 | 144 | - [Solidity by Example](https://solidity-by-example.org/) 145 | 146 | Summary and examples of most common Solidity functions, use-cases, real smart contracts, and more. 147 | 148 | - [ProtoSchool](https://proto.school/) 149 | 150 | Interactive tutorials on decentralized web protocols 151 | 152 | - [Questbook](https://questbook.notion.site/Questbook-Learn-Web3-a5f4be8b107f4647a91fe84e6aa7e722) 153 | 154 | Questbook is a Decentralized University where learning web3 is always free 155 | 156 | - [FreeCodeCamp's Solidity Tutorial](https://www.youtube.com/embed/M576WGiDBdQ) 157 | 158 | Comprehensive introduction to main Solidity concepts (+blockchain/smart contracts) everyone needs to start writing their own ERC720 and ERC20 tokens, dApps, and more. 159 | 160 | ### Paid Courses 161 | 162 | - [Ethereum and Solidity: The Complete Developer's Guide](https://www.udemy.com/course/ethereum-and-solidity-the-complete-developers-guide/) (Udemy) 163 | - [Smart Contracts con Solidity de la A a la Z](https://www.udemy.com/course/solidity-a-z/learn/lecture/26791510?start=0#overview) (Udemy) (Spanish) 164 | - [Smart Contract Engineer](https://www.smartcontract.engineer/) 165 | - [SuperHi Crypto + Web 3 for Creatives](https://www.superhi.com/courses/crypto-and-web3-for-creatives) 166 | 167 | ## 🔒 Security 168 | 169 | - [Awesome Ethereum Security](https://github.com/crytic/awesome-ethereum-security) contains curated resources to learn about Ethereum security, and also several useful tools 170 | - [Not so Smart Contracts](https://github.com/crytic/not-so-smart-contracts) contains examples of common smart contract vulnerabilities, including code from real smart contracts 171 | - [Smart Contract Security Audits](https://github.com/chainsulting/Smart-Contract-Security-Audits) performed and published by Chainsulting, with all audit reports included 172 | - [Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/) is the wargame to learn offensive security of DeFi smart contracts 173 | 174 | ## Meetups 175 | 176 | - [Blockchain 101](https://blockchain101.com/) is a meetup group from NYC that runs a lot of virtual meetups every month, open to everyone remotely! 177 | 178 | ## Other helpful resources 179 | 180 | - [OpenZeppelin](https://openzeppelin.com/contracts/) 181 | 182 | Security standards and tools to build safe smart contracts on Solidity. Free for anyone to use. 183 | 184 | ## Contributing 185 | 186 | Thanks for showing interest in contributing to DeveloperDAO's Resources page. 187 | 188 | Before submitting any changes please review our contributing gudielines in [CONTRIBUTING.md](./CONTRIBUTING.md). 189 | -------------------------------------------------------------------------------- /RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | ## Beginner 4 | 5 | ## Intermediate 6 | 7 | ## Advanced 8 | --------------------------------------------------------------------------------