# Getting Started With Solidity Part 1
In this guide we'll create an ERC-20 token!
## Environment
Install the Solidity [plugin](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) for VSCode (or your choice of code editor) — it's a huge help. Next, install [Foundry](https://book.getfoundry.sh/). Foundry is the newest of Solidity toolkits, and the best. I recommend you read the entire Foundry book but for this guide, all that's necessary is you install it! Follow the [installation instructions](https://book.getfoundry.sh/getting-started/installation).
## Libraries
Security is a big deal in blockchain development. Due to the nature of blockchains — decentralization at the expense of the virtually free compute of web2, non-custodial ownership where users own assets without any megacorp intermediary, and the open source ethos — most things stored in the database are relatively high value & anyone can see the code. This is ripe ground for hackers.
Libraries offer audited, battle-tested contracts that your contracts can inherit from. The two most popular are [OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/) & [Solmate](https://github.com/transmissions11/solmate). OpenZeppelin is the most widely used while Solmate offers a minimal, more gas*-effecient alternative (written by child prodigy and gas opimizooor [Transmissions11](https://twitter.com/transmissions11)).
###### * [Gas](https://ethereum.org/en/developers/docs/gas/) is the metric of compute in blockchains & it costs a lot more money than a web2 databse. Currently 18 gas units costs 1 [gwei](https://coinmarketcap.com/alexandria/glossary/gwei) or $00.00000151 for ETH @ $1,290. ETH has 18 decimal places. The 18th decimal place (lowest unit of ETH) is called a wei. The 9th decimal place is a called a gigawei, or gwei.
## ERC-20 Example
In the terminal, run `forge init token`. You may need to add ` --no-commit` to the end if you get aan error. This creates & initializes your directory. The way to install libraries in your Foundry directory is `forge install <github_usernamename>/<github_reponame> --no-commit`. In the directory, run `forge install transmissions11/solmate --no-commit` to install [Solmate](https://github.com/transmissions11/solmate).
Once installed, you can find Solmate in the 'lib' folder. At lib/solmate/src/tokens/ERC20.sol you'll find an abstract contract for an [ERC-20 token](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/). This is the most common token standard and it's used for fungible (interchangable) tokens.
Because Ethereum is decentralized, the ecosystem is held together with stanards like these, as specified in Ethereum Improvement Proposals (EIP's). Here is [EIP-20](https://eips.ethereum.org/EIPS/eip-20) which is the proposal for the token spec — EIP's are numbered sequentially from the first to the latest, so this was the 20th improvement proposal.
Let's go through Solmate's ERC-20 implementation.

• **License Identifier**: At the very top you'll find a license identifier. The compiler while actually give you a warning if you don't include one. This contract uses a [GNU Affero General Public License ](https://spdx.org/licenses/AGPL-3.0-only.html).
• **Pragma**: Right under that you'll see the [pragma](https://docs.soliditylang.org/en/develop/layout-of-source-files.html#pragmas) keyword, used to tell the compiler which version of solidity you're using for the following code.
• **NatSpec**: Below that you'll see NatSpec [tags](https://docs.soliditylang.org/en/v0.8.16/natspec-format.html#tags). Solidity uses the 'Ethereum Natural Language Specification Format' ([NatSpec Format](https://docs.soliditylang.org/en/v0.8.16/natspec-format.html)) for inline documentation. The meaning of the tags are pretty self explanatory.
• **Contract Definition**: This is an [abstract contract](https://docs.soliditylang.org/en/v0.6.2/contracts.html#abstract-contracts), meaning at least one of the functions aren't implemented (and are meant to be implemented in the contracts that inherit from this contract). In this case though, while all of the functions are implemented, if you were to deploy this contract there would be no tokens & no way to mint them. While this contract would compile without being defined as abstract, choosing to define it as abstract seems to be a styling choice from Transmissions11.

• **Events**: Logs in solidity are defined as [events](https://docs.soliditylang.org/en/develop/contracts.html#events). This allows front-ends to listen to the contract for certain actions. Defining an event is structured as `event <event_name> (<parameter_type> <indexed_?> <parameter_name>);` The indexed keyword is used to define parameters that can be filtered from, these are called 'topics'. An event has a max of 3 topics. You generally want to index things like addresses and not things like amounts, but it's up to you.
• **Metadata Storage**: Stored here is the name of the token (e.g. My Token), it's symbol (e.g. TOKEN), and how many decimal places it has. These parameters are defined in EIP-20. Solidity can't hold floating numbers (e.g. 5.5) so you define how many decimal places it has (e.g. 1), use a whole number in your code (e.g. 55), and front ends / wallets do the rest.
• **Defining Variables**: Variables are defined as `<variable_type> <public_or_private_?> <constant_or_immutable_?> <variable_name>`. You'll notice a uint8 in the code above which is a number from 0 - 255. This can seem confusing but for now you can safely just define your numbers with type uint which = uint256 (a very high number).
If a variable is defined as private, then it isn't supposed to be accessed from a front end (though it's easily possible to do so) & your contract functions will save some gas. The gas saving is because [getter functions](https://docs.soliditylang.org/en/v0.8.17/contracts.html#visibility-and-getters) will automatically be created for public variables (we'll get into how they work later) & ultimately the more functions you have, the more gas they cost to use. If you don't define public / private then it will be private by default. Lastly there is the constant & immutable modifiers, which are similar in that they can't be changed & are much more gas-efficient. Constant variables must be initialized when defining them & immutable variables need to be assigned at contract construction (we'll see this later).
• **ERC20 Storage**: Here we have the totalSupply which is the counter of total tokens, and our introduction to the [mapping](https://docs.soliditylang.org/en/v0.8.17/style-guide.html?highlight=mapping#mappings) keyword, which defines the parameters of a key => value pair and stores it in a variable. The `allowance` variable is an instance of a nested mapping representing <token_owner_address> => <address_that's_allowed_to_spend_on_behalf_of_owner> => <amount_they're_allowed_to_spend>.
*Note that Solidity has default values for variables, and the default for a uint256 is 0*.

• **EIP-2616**: [EIP-2616](https://eips.ethereum.org/EIPS/eip-2612) is an ERC-20 extention that exposes a `permit` function, allowing a user to give an allowance for another address to move their tokens with a signature. I've honestly never used EIP-2616 and it doesn't really matter for this tutorial. But notice the *internal* access modifier, which we haven't come across. This is similar to private, except it also allows derived contracts (i.e. contracts that inherit from another contract) to view and manipulate the variable, wheras private variables can only be manipulated within the base contract.
• **Constructor**: This is a special function that only runs once: at deployment. It's here that immutable variables must be implemented. The parameters here are the name of the token, symbol, and the number of decimals. Each of these are assigned to their corresponding state variables. The [block](https://docs.soliditylang.org/en/latest/units-and-global-variables.html#block-and-transaction-properties) variable is a special global variable that represnts the block that operation belongs to. It's typically helpful for grabbing timestamps with `block.timestamp`.

### ERC20 Logic
This is the core logic that users will call when interfacing with an ERC-20
• **approve**: This allows a user Bob to approve another user Alice to spend some amount of their tokens. The first line shows how to use a nested mapping. msg.sender is the account that made the function call, spender is the account of the person allowed to spend the tokens, and it sets the allowance to the amount argument. After that, it emits an event log that was defined earlier.
• **trasnfer**: This function transfers tokens (amount) to another account (to). First it decreases the balance of the sender by amount, then increases the balance of the receiving address by the same before emitting another event log.
• **unchecked**: Solidity 0.8 introduced [overflow / underflow](https://ethereum.stackexchange.com/questions/83226/integer-underflow-overflow) checks. This comes at the cost of some extra gas (which is real money), and you can use the [unchecked](https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic) block to skip needless checks
• **transferFrom**: This function allows Alice to move the tokens she was approved to move by Bob. The first line in the code block is an illustration of a very important gas-saving technique. Variables defined outside of functions are saved to storage & variables defined inside of functions are saved to memory. Memory reads/writes are *much* cheaper than their storage counterparts. In this case, saving the allowance to memory saves 1 storage read.
An approval set to `type(uint256).max` (the max unit256 value) is treated as an unlimited approval. The if statement checks if the approval is meant to be unlimited. If not, then it decreases the allowance by the amount spent. The function then decreases the balance of the token owner's account by amount, and increases the balance of the receiving address by the same. It then emits an event log.

### Internal Mint / Burn Logic
I still don't understand EIP-2616, so I skipped that code. If you look at it though, you'll see `assembly` blocks. Solidity has an assembly language called [Yul](https://docs.soliditylang.org/en/latest/yul.html), which is mainly used for gas-optimizing. It's not necessary and you can ignore it until you're ready to learn
• **\_mint**: This function mints new tokens (amount) to an account (to). The modifer of this function is internal, which is similar to private, except it can also be used by contracts that inherit from this contract — meaning it can't be used outside of your ERC-20 contract.
First the function increasses to total supply by `amount`. It then increases the balance of `to` by `amount` before emiting an event log.
• **\_burn**: This function burns tokens (amount) from an account (from). It does the inverse of mint. Burning is the complete deletion of tokens.