class: center, middle, inverse, title-slide # DSBA 20598 – FinTech and Blockchains ## Lab 8 & Lab 9: Writing Smart Contracts ### Prof. Silvio Petriconi ### Department of Finance, Bocconi University ### 2019-11-11 (updated: 2019-11-12) --- # Today's lab Today we'll start with practical smart contract development using the Solidity language. Tomorrow we'll learn about the deployment of smart contracts: * on an Ethereum public testnet * on a private Ethereum testnet What you'll need: * just the browser for today --- # Why you (still) have to learn Solidity [Solidity](https://solidity.readthedocs.io/en/) is the __by far__ most frequently used language for Ethereum smart contracts. * if you know Java / C++ / Golang, it will feel rather familiar. * upside: powerful; downside: complexity can be high (inheritance, operator overloading, modifiers etc). Contracts are hard to audit. * prone to security holes due to design imperfections. [Vyper](https://vyper.readthedocs.io/en/) is a very promising new language for the EVM: * it is extremely close to Python 3 syntax * things are nice, readable, and better safeguards against the worst kind of errors are in place. Some things like infinite loops simply aren't implementable in Vyper. Rumors have it that Vyper is __the__ EVM language of the future. Unfortunately, Vyper is at its current stage still not mature enough for production use, and there's not much of a community around it (yet) that can help you if you get stuck. --- # The Remix IDE There's an excellent in-browser integrated editor for Solidity: [Remix](https://remix.ethereum.org) [](https://remix.ethereum.org) --- # The Remix IDE (cont.) With the Remix IDE, you get not just an in-browser editor to write your code: * You also get a Solidity compiler plus an in-browser Javascript emulation of the Ethereum VM such that you can test and debug your contracts! * Beware though that the in-browser Ethereum VM emulation deviates from Ethereum VM in important aspects, e.g. no delay for writing to the chain. * Contracts should eventually always be tested on a public or private Ethereum testnet before being deployed to production use. --- class:center,middle,inverse # Solidity: The type system --- # Basic types | Built-In Type | Description | | --------------------- | ------------------------------------------------------------ | | `int8` ... `int256` | signed integer, n bits (256 bit if width not specified) | | `uint8` ... `uint256` | unsigned integer, n bits (256 bit if with not specified) | | `bool` | boolean (only true or false) | | `string` | UTF-8 encoded string, internally represented as array of uint8 | | `fixed`/`ufixed` | Fixed point type (e.g. 3.141592), implementation incomplete, try not using it | `address` | an Ethereum address; from 0.5.0 onwards any address that gets paid to should be declared an `address payable` | --- # Basic Types: Initialization ```c // variable declarations with initialization uint counter = 2; // constant declarations uint constant MAX_VALUES = 4; // declare as constant, immutable bool constant canExecute = false; // ... some code ... then, counter += 5; // no problem, increment counter by 5 *MAX_VALUES = 42; // WON'T WORK, ASSIGNING TO CONST ``` --- # The World of Typed Programming When you're used to Python, some things in the typed programming world need more attention than what you're used to: * _every_ variable that you work with must be declared (and thereby its type defined) before you work with it * Solidity initializes each variable to an initial value of zero, unless you assign a different initial value * Once the type has been declared, any assignment of a different type will produce a compilation error, e.g. ```c int A = 42; // declare as int * A = "Hello, world!"; // COMPILE ERROR!!!! ``` * Discipline with types is good, in principle. Whenever you are missing flexibility with types (e.g. have a mix of types in one and the same array), it's in 99% of cases caused by poor code design choices rather than a genuine need for such flexibility. --- # Arrays ```c int[5] quizPoints; // this declares an array // of fixed size 5, type int uint[] dynArray; // declaring an array of dynamic size, // mind it must still be allocated, // and its size should always be // controlled by contract, not by // unvalidated contract parameters! // here's how to create a constant array: int[3] constant constantArray = [4,3,2]; // Using arrays: int y = constantArray[1]; // this will set y = 3 dynArray = new uint[](y); // reserve space for 3 elements dynArray.push(42); dynArray.push(0); // dynArray contains now [42, 0]. int z = dynArray.length; // z=2 ``` --- # Mappings If you're looking for something similar to Python's dict(), mappings are for you, though their syntax is more clumsy: ```c // declare a mapping mapping(address => int) balance; // use it balance[msg.sender] = 10; ``` --- # Structs ```c struct point { int x; int y; } A = point({x:1, y:1}); point[] curve; curve.push(A); ``` Structs "bundle together" several variables (a bit like namedtuple in Python, but unlike namedtuple they're mutable). --- #Memory vs. Storage In Solidity, variables reside either in storage (i.e. written to blockchain, expensive and slow), in memory (fast and low cost but not persistent), or on the stack (almost free, but limited capacity). Item | Default location --------|---------------------- state variables | always in storage function arguments | always in memory local variables of struct, array or mapping type reference | storage by default local variables of value type (not array, struct, mapping) | stored on the stack Location can be modified with modifiers memory and storage e.g. like this: .small[ ```solidity struct coordinate{ uint x; uint y; } coordinate memory cursor = coordinate({x : 10, y : 5}); ``` ] --- class:inverse,middle,center #Contracts --- # Contract declarations Contracts in Solidity are somewhat like objects in Python. Each contract provides a constructor, and there are additional functions that can be called. .small[ ```solidity contract temperatureReading { string public location; int public time; int public tempCelsius; constructor(string location) { itsLocation = location; setTemperature(24); } function setTemperature(int degrees) public { tempCelsius = degrees; time = now; } function getTemperature() public constant { return tempCelsius; } } ``` ] --- # Contract declarations, cont. Unlike Python, Solidity enforces access modes for each contract function: ```solidity function (<parameter types>) {internal|external|public|private} [pure|view|payable] [(modifiers)] [returns (<return types>)] ``` * __internal__ functions can only be called by the contract itself internally, or from contracts that derive from this contract * __private__ functions can only be called by the contract's functions internally (but not by derived contracts' functions) * __external__ functions can only be called from outside Solidity in a transaction * __pure__ functions can't access any of the data of the contract * __view__ functions can only read-access its data * __payable__ functions require ether payment along the function call --- # The global msg object Each function can access the global msg object which contains the parameters of the blockchain transaction in whose context it was called: | Parameter | Description | | ------------ | ------------------------------------------------------------ | | `msg.data` | Data field from the call or transaction data linked to the current transaction | | `msg.gas` | Amount of gas that the function has available | | `msg.sender` | Address of the party invoking the contract / transaction | | `msg.value` | Amount of wei sent along with the invocation of the function | --- # Control flow: if ```c // For all that follows, we will assume the following are defined: int a; int input1 = 1; // assume input1 is set to some value ``` The if statement lets you do conditional execution. Mind the round braces. ```c if(input1 == 2) { a = 1; } else { a = 0; } ``` --- # Control flow: for ```c for(uint i=0; i<=50; i++) { a++; if(a == 4) break; } ``` Note that `for(exp1;exp2;exp3)` comes with three arguments: the first is code that is executed at loop initialization. The second is a function that will, as long as it is true, lead to continuation of the loop. The third is a function that will be executed to prepare the next step. Here, `i++` is just a short notation for `i = i + 1`. --- # Control flow: while ```c while(input1 >= 0){ if(input1 == 5) continue; input1 = input1 - 1; a++; } ``` Loops (for, while etc) can be resumed immediately in the next iteration with the continue keyword. --- #Events Contract logic can also emit special events that leave traces in the chain to trigger further code to be executed outside the blockchain. Example: .small[ ```solidity contract Test { event Deposit(address indexed _from, bytes32 indexed _id, uint _value); function deposit(bytes32 _id) public payable { emit Deposit(msg.sender, _id, msg.value); } } ``` ] --- class: center, middle # Thanks! For questions, comments and suggestions regarding these slides please contact the author, [`silvio.petriconi@unibocconi.it`](mailto:silvio.petriconi@unibocconi.it). <br></br> [](http://creativecommons.org/licenses/by-nc-sa/4.0/) <br></br> This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).