Smart Contract Development
The course is part of this learning path
This course provides a deep dive into the Solidity programming language which is used to implement smart contracts on blockchain platforms. This course will give you a practical understanding of Solidity and how to develop your own smart contracts.
In this lecture, I want to talk about some basic variables, some value types, reference types like Booleans, unsigned integers, and addresses which are a special type of variable only specific for smart contracts. And I want to get started with some very, very simple types like booleans. For example, a boolean called MyBool, and booleans as you might know, they can have two values; Is it a true or false. So, when I have boolean and I'm going to make this public, so I automatically have this get to function and I call it myBool. And when I deploy this contract here, let me deploy this here, then I can automatically get the default value of this variable. Now, I've said this before and I want to highlight it here again. Every variable is initialized with its default value and in case of booleans, that's going to be false, in case of integers, it's going to be 0, and so on. So, strings are going to be empty, so I think that's pretty much it if I'm not mistaken here, but that is basically the thing that is slightly different than in other programming languages. I could also say this is false and it deploys here, so it would have the same effect and it doesn't throw any errors or warnings or anything. Now, let's write a function, "setMyBool" and this is going to set the boolean here, mybool, this public function obviously and myBool = _myBool. If I deploy this here, then my boolean is "false" and I can set it to "true" and now it's "true." Okay, this is booleans. Now, let's talk about integers and unsigned integers. I want to start with the unsigned integers. They can range from 8 bit to 256 bits and the 8 bit would be defined as uint8 or int8. I'm going to make this public as well and I say, myUint8 is... and the 8 bit integers, they can have a range from 0 to 255, so this is 2** 8 - 1. And we could -- let me delete this here and redeploy the smart contract and when I get myUint8 and it's 255. Now, very important and I'm going to show you this in an example in a second, when you add 1 here then you will end up with 0 and then you decrement 0 then you will end up with the largest number of the unsigned integers defined. So in case of unsigned integers myUint8, it will be 255. So, 0 -1 = 255. It will just what they call, "Wraparound" and it is very important to keep this in mind when you work with solidity and always check for wraparound values, especially when you work with balances of something like tokens in your smart contracts which we're going to do later. Always keep in mind that wraparounds are without any warnings, without any error, it will just wraparound. And let me give you this example for this, let's write a function called myUintWrapAround, and this is going to be a public function and let's just make this a view function or in this case a pure function. I'm going to talk about pure functions later. Pure functions are functions which are not accessing any storage variables at all. So, not reading, not writing to anything here; They're just -- the scope of the pure functions is inside the function itself. And this is going to return uint8 and let me just show you how this works. I define one uint8, myZeroUint = 0. So, I have one uint8 which is 0 and now I decrement myZeroUint by one. These two - - means decremented which is the same as myZeroUint - 1. So, this is the short form if you've never seen it, and then just return myZeroUint. So, in a normal... I think in Java you would just get an error here because you decrement this... decrement this, decrement the unsigned integer which cannot go below zero but in solidity and I think in C or C++ this also just wrapping around within any warning. So, when you come from a C world it should be fairly familiar and this is 255. If I'm going to change this to unsigned integer 256, which is the largest unsigned integer range that you can have, then you can see here the largest range of unsigned integers that you can have, which is 2**256 -1. Okay, then we have also unsigned integers in any 8 bit increment values. So, we have 16, there is 32, public myUint32 = 2**32-1 and this is unsigned integer 256. It's the same as unsigned integer, it's the largest range, public myUint256 = 2**256-1. So, this would be how unsigned integers are used. Why do you want to use unsigned integers 8 over unsigned integers 256?
Sometimes because the range is not necessary, sometimes because you want to save storage, gas costs. The way the internal EVM works, the Ethereum virtual machine works, is by allocating 256 bit values or storage ranges and when you can stack them together, when you have several unsigned integers 8, and they're getting stacked together to some degree and you can save some gas costs. Now usually, you are very safe if you used the unsigned integer 256 in the first place. All right, then there is one thing... let me define one integer for you just to see how this works. Let's make this public, myint8. This would range from -127, I think, no, -128 to 127. So, this can go from -128. Let me get the unsigned integer, -128 which is the same as -2**4 -1. So, this is the range for integers; They are going to be -- they are using the same space but because of the sign, so they can go into the negative range, they are just shifted for the value they can store. So, instead of going from 0 to 255, they can go from -128 to 127 including the zero obviously. All right, then there's one more important thing which is division. So, if you divide two unsigned or two integers then any decimals will be just truncated. They will be deleted so, it will always round down. This is the effect. Let me show you this. Let's say we divide five by two and this would normally be 2.5 and when you round it in the normal programming language then this would be 3 because 5 will be a round up but because the decimal place here is just truncated, it's just removed or lost, basically, that means it will always be to what was round down. So, let me show you this made an example, myUintDivisionExample() public. Let's make this also a pure function to have some more examples of pure functions uint, this returns a uint8 and let's say you have one uint8 = 5 and I have one uint8, sorry, one uint8 five = 5 and one uint8 2 = 2 and now I return to 5/2. And I do this in this way because if I just do 5/2, that gives you an error because it cannot implicitly convert this type. So, I have to put this into two variables and once I deploy the smart contract and I 'Run' this uint8 division example, then it's 2 and not 2.5 which you would normally expect from programming languages where you can define fixed points or floating point values. Now, talking about floating point values, they are in the documentation mentioned and fixed point values but they are not supported yet by solidity. Solidity is too young and you can just handle unsigned integers, integers and what is usually done is that the decimal point is saved which is then at a specific point in the number. So, if for example, you have a number which is, let's say, 10,000 and you say actually this has three decimal points so here would be the decimal point is actually 10.000, so you would say if the decimal point is at the third place in this number here. So this is how it's done. A practical point of view. Now here comes the more interesting part, which is the addresses, which I want to talk about. There is this type address. And just let me give you an example of an address, address public myaddress, for example. And address comes with a couple of members, which are very, very interesting, because the Ethereum Blockchain which is public permissionless Blockchain, so all the information is public. You can always access how much money is stored on the address. You can't send this money from that address because you would need a private key for that. But you can always look how much money is stored there including your own. Meaning their own address of the smart contract which is running on. Now with your own address you can also send money from your own address to another smart contract. So, that means you can transfer to an address which is stored in this variable. Some money from the address where the smart contract is running on. Let me give you an example of this. First of all, I'm going to set the address here with classical set of functions. So I'm going to write, function, set address, and then I have an address, address, and this is going to be public. And I see my address is _address, for example. But before I run this, I want to have another function which gives me the amount of wei, which is the smallest denomination on the Ethereum Blockchain. We're going to talk about this in a later lecture. From the address which is stored here, so get the balance, for example. And this is a public view function and returns, and unsigned integer, uint256. And this will return, the myaddress.balance. And this member gives you the balance of this address which is stored on the Blockchain. Now that already highlights how powerful a public ledger is because everybody has access to the same information. I don't need to query any API because essentially that information is going to be stored in the Blockchain I have access to. Now, went around this and I hit on get the balance. It's zero because the address here is initialized with its default value, and the default value for an address is the zero address, 0x00000 and so on. Now if I set the address to the address of my account here, so I'm going to copy this here, and I'm going to enter this here, then my address will be now my account here, and I can clear read the balance in Wei, which is ten to the power of 18 ether. So I get back the amount of ether, or Wei that are stored on this address. I can also take the other address, paste it here and then get the balance, which is this one. And when I get this one, and I do it with the other account. So I'm not using up any guess, then I get exactly 100 ether here. Now that is very cool. But you can do a little bit more. First of all, I could send money to this smart contract. So there is actually ether hole, so that the smart contract can hold ether on its own address. And when I then call address.transfer, then I can put an amount of wei into this, as an argument into the transfer function. And I would transfer from the address from a smart contract to this address which is stored in this address variable, the amount of wei which is the argument in the transfer function. So it's very, very powerful. The concept where you have the code, the logic running on the same platform, with the same access to the ether, to the money. And I'm going to demonstrate this now. You can follow along, but you don't have to follow along, because we're talking about this again later when we talk about payable functions, but I just want to give you a quick example of how this looks like. Because, there is another keyword which you have to add in order to actually transfer funds. There's two types of addresses, the one is addresses that are just addresses, they hold 20 Bytes of values, basically 40 Hex characters, which are these addresses, and that's it. You can get the balance, but you cannot transfer any funds. And to make it a little bit more secure, in the latest version of solidity, they introduced this payable keyword. And with the payable keyword, you tell solidity, this address is actually here to receive funds from a smart contract. I also have to make this payable here in order to actually assign this address. Another address here which is then also payable. And then, I can always use address, this to get the address of this instance of the smart contract. So this one address this, would be the address of their own smart contracts, and then I can get the balance here. Now it's a little bit tricky. Obviously this is not what I meant, I meant to transfer the money out. And this is going to be a public function, so it's not going to return anything, it's just going to transfer. This is what I meant. So in this case, I'm getting the address of the smart contract, and I'm getting the balance which is stored in the smart contract. Initially it's zero. But we can send money to the smart contract, and then it will not be zero, and then I can transfer all the money that is stored in the smart contract to the address that is stored here. Now let me demonstrate this, and before I can demonstrate I have to actually make one function payable. Which tells solidity then, if I interact with the function then I can also send ether there. It's just a demonstration for now, to see what you can do with addresses. We're going to talk about this in more detail later. So I have a function, payme, and this is a payable function, public function, and it doesn't do anything, just can receive ether. Let me deploy the smart contract. Let me show you how this works. I have the first account, and now I can use the value here to actually send one ether to my smart contract. And when I hit the payme function, and I look at the transaction, then you can see that the value here is not zero, it's one to the power of 18 weis, or this is like 18 zeros here. Now my smart contract has money in its own address, and this is very cool because now I can use my set address to set the address variable to my let's say third account here, which I just copied. And I'm going to set this to my third account, and now I can hit on transfer the money out. And what happens next is, my address is set to the third account in my account list. So it might be an entirely different person. And it's trying to transfer the balance from the smart contract, which is now one ether, and it will transfer this out. So the smart contract, obviously has only access to its own funds running on its own address, but you can always transfer them somewhere else. So very important is to really make sure you understand how this works. And because this is so important we are going to make another lecture only talking about these things. So I transfer the money out, and I have now 101 ether in my third account, and 98 ether in my first account, which I Just used to transfer one ether into my smart contract. You can find this example obviously, also in our course repository. Check it out, have a look. I was working. And now for the last example that I'm going to give you. And we also have a small tiny coding challenge here. I'm going to show you bytes. And bytes range from bytes one to bytes 32 fixed size byte arrays, and they allow for a couple of operators. And let me just give you a bytes one, that is public, and I call it my bytes one. And this holds one byte or two hex characters. So it's going to be 0xFF for example. And I can have a function which compares bytes, let's say returns a Boolean, where I say, is myBytes smaller than. This should actually work. It is automatically converting this. Okay. My bytes two is 0xFFF. So this is obviously true, but we can still just run this here. My bytes is 0xFFF. And my bytes compare, I just want to compare if this is smaller than this one. And that is true. And then we have a length function. Get my bytes length. So we have a length here. Where is the my bytes length? It's one, so 1 byte. And this one ranges from bytes one to bytes 32. So the coding challenge that I want to do now, just to have a little bit of hands-on, is create a new bytes 32 variable, fill it up completely with the highest value, and then compare it to the bytes one. If you want to do the coding challenge, then do it now, pause the video. And I will just do this in five seconds. All right. It's not too hard. 0xFF. So one byte, two byte, three byte, four byte, 8 byte, 16 byte. 32 byte. And then we compared this. We're here. Run this, and here we go. We have our true. All right. That's it for this lecture. And this was the basic types that I wanted to talk about. Obviously there are a few more types, but for me I think this is the most important things at the moment. And we are going to continue in the next lecture with the global objects and the payable functions. Where we are talking a little bit more about this addresses and how to pay a smart contract.
Tom is a CTO, senior back-end developer, and systems architect with over twenty years of hands-on development experience in a variety of languages and systems. He has a CS master's degree and has been working with Ethereum and blockchain technologies since 2016.