# Writing Your First Smart Contract Nick Szabo first ideated and defined "smart contracts" as "A set of **promises**, specified in **digital form**, including **protocols**, within which the parties perform on these **promises**." Ethereum is a decentralized platform that enables developers to build and deploy smart contracts - or... a bunch of promises, in digital form, that run on the Ethereum protocol rules. ### Vending Machines: The Ancestor of Smart Contracts Nick Szabo also writes: “A canonical real-life example, which we might consider to be the primitive ancestor of smart contracts, is the humble **vending machine**.” Similar to how a vending machine operates in the real world based on a set of programmed rules, a smart contract functions in the digital world of blockchain according to its predefined protocols (ie, consensus mechanism, public key cryptography, etc). ![ven](https://hackmd.io/_uploads/SkxUwbLvh.png) When you set up a vending machine, you will most likely set it up with pre-defined rules such as: - When a consumer selects a soda item, the machine will display that soda item's price. If the consumer "inputs" the minimum payment, the machine should dispense a soda. This can all be neatly put into a formula: `soda_selection + price_of_soda_selected_inputted = soda_dispensed_to_consumer` When writing smart contracts, you are just writing the pre-defined rules that "consumers" of your smart contract will have to interact with when you deploy it onto a live blockchain. Think of a smart contract deployment as actually setting up a vending machine in its final place - once you set it up, consumers can see and start interacting with it. Just like with vending machines and you accidentally setting a soda price *too low*, if you **code** the wrong set of pre-defined rules in a smart contract, consumers might be prone to abuse the gap in rules. ## Writing a Vending Machine Smart Contract 🤖 Ok, you get it - vending machines are pretty alike to smart contracts! In order to fully drive this analogy home, let's write our own implementation of a vending machine... but in smart contract form! 🤯 ### Step 1: Set Up Remix 1. Go to https://remix.ethereum.org/ (if this is your first time visiting the site, please follow along the user interface tour and get to know the sidebar tabs!) > 🧙‍♂️ Recommended: In the left-hand side navigation bar, go to the `Solidity compiler` tab and enable `Auto compile` - this will help give you a live status indicator of whether the code you write is syntactically correct or not - very helpful! ![v1](https://hackmd.io/_uploads/SyWOJMIv3.png) 2. In the left-hand side tab, under `File Explorer`, select `Create a new file` and name it `MyVendingMachine.sol` > Why name the file with a `.sol` extension? 🤔 Because we will write this smart contract using [Solidity](https://soliditylang.org/), a very popular programming language specifically created and used to write smart contracts. At this point, your Remix should look something like this: ![remix](remix) ⚠️ Please note: the `MySmartContract.sol` file should be outside of any of the folders that Remix includes for your by default! Feel free to delete or ignore those folders and other files, they won't be needed. ### Step 2: Write Some Solidity! 👩‍💻 Now that we have a blank file, let's run through all of the steps needed for this smart contract to work. #### Add the Smart Contract License 1. On `Line 1` (note, Remix shows line numbers!), add in the following *commented* line: ```solidity // SPDX-License-Identifier: MIT ``` This first line is a comment in the code (it is a comment because it is pre-fixed with `//`) that you will see across 99% of Ethereum smart contracts, and it is nothing more than the software license. The MIT license is a popular license that basically means: "The code you're about to see can be freely used, shared, or modified. But if you do use it, you need to acknowledge that it was originally licensed under the MIT license." #### Add the Smart Contract Version 2. On `Line 2` of your smart contract, add in the following: ```solidity pragma solidity 0.8.17; ``` This line indicates what version of the Solidity compiler will be used to compile your smart contract. In this case, we are saying: "When this smart contract is compiled, please use version `0.8.17` of the Solidity compiler." #### Set up Smart Contract Name and Scope We've now gotten the boring boilerplate stuff out of the way (specifying license and compiler version), now let's actually write the first part of our smart contract! 3. Add a new line or two after the pragma directive from above! 4. Add the following to your file: ```solidity contract MyVendingMachine() { } ``` Boom! You've just outlined your very first smart contract! Every part of the rest of the code you will write will live in between the `contracct MyVendingMachine { // all your code will live here! }` bracket scope you just outlined. The smart contract is a little boring and doesn't really do anything at the moment, let's give it some functionality. #### Add State Variables! In Solidity, a **state variable** is a variable that is permanently stored in contract storage. They represent the "state" of the smart contract on the blockchain and will persist even after the function execution ends. Just like when you save a video game, the state of your character is also saved for when you come back! Within the `contract` brackets, let's add a state variable: ```solidity uint public numSodas; address public owner; ``` In this smart contract, we will keep track of two items: - **`numSodas`**: How many sodas does a vending machine smart contract hold? - **`owner`**: Who owns the vending machine smart contract? The syntax to declare state variables is as follows: ```solidity variable_type variable_visibility variable_name; ``` Above, we declared two variables: - `numSodas`: a variable of type `uint` (Solidity's version of integers) with a `public` visibility (meaning anyone can easily see the value of this variable). - `owner`: a variable of type `address` (keeps track of an Ethereum address!), also of `public` visibility. #### Add a Constructor Now that we've added state variables, let's initialize them with actual values. 5. *Within* the brackets of the previous step, add the following: ```solidity constructor(uint _numSodas) { numSodas = _numSodas; owner = msg.sender; } ``` A **constructor** in a Solidity smart contract is similar to that initial setup process for your phone. It sets up the contract with the initial settings it needs to function properly, and it only runs once, when the contract is first created. The constructor you just added to your contract will accept one `uint` number as a parameter and set the contract's deployer as the owner. In other words, this constructor is saying: "When this smart contract deploys, set `numSodas` to `200` and set the Ethereum address paying for this deployment to be the `owner`." #### Add a Function to Purchase a Soda 🥤 Now let's add some **functions** to enable some functionality and make this smart contract act like a real-world vending machine would! 6. A line or two under the `constructor` function, add the following: ```solidity function purchaseSoda() public payable { require(numSodas > 0, "Not enough sodas in the machine!"); require(msg.value >= 1000 gwei, "Minimum payment is 1000 gwei!"); numSodas--; } ``` This function is what our users will actually call when they use our smart contract! It does a couple of things: - **requires** that there are more than 1 sodas still in the machine to dispense - **requires** that the user sends a minimum payment of 1000 gwei - if the two conditions above are met, the function will subtract one soda from the overall `numSodas` balance The syntax to declare a function are as follows: `function nameOfFunction() function_visibility` **Do you notice how these are the pre-defined set of rules we are peppering into our vending machine smart contract? 👀** We just enabled our vending machine with a price-per-soda and more! ### Add More Functions!! We have an `owner` variable that we can also use for some cool stuff! This one will look a little more advanced but just sound it out and you'll notice Solidity is very understandable! 7. Add the following function to your smart contract: ```solidity function withdrawProfits() public { require(msg.sender == owner, "Only the owner can call this function!"); (bool sent, ) = owner.call{value: address(this).balance}(""); require(sent); } ``` Just like a real-life vending machine, the owner must be able to withdraw profits right? The function above accomplishes just that. It: - **requires** that whoever calls it, **must** be the address currently stored in the `owner` state variable - if the above condition is met, send the owner the profits! ### Conclusion You just wrote a whole smart contract end-to-end, nice!! Can you think of ways you can keep riffing and more functionality that you can potentially add? Here are some ideas: - a function to `changeOwner` so that, just like a real life vending machine, an owner can transfer ownership of the smart contract to another Ethereum address - a way to keep track of how many sodas a user has purchased, as currently our simplistic implementation just subtracts from the `numSodas` value without assigning the soda to the consumer - a way to refill the sodas! If the sodas run out, the machine will never work again! Do you see how a smart contract is very similar to a real-life vending machine? The possibilities are endless in smart contracts and not bound by physical constraints like real machine are - this is the flexibility that has enabled applications like Aave and Uniswap to become pilars of web3 innovation!