- [Instructor] The most interesting part of ethereum are smart contracts.
You can think of smart contracts like autonomous agents deployed onto the Ethereum block chain.
Smart contracts are made up of some state, or data as well as some code that manipulates that data.
Just like a user account, smart contract accounts also have their own balance, as well as a public address which looks the same as a user account address.
To interact with smart contracts you send transactions to it with some extra data to specify which function you want to invoke, as well as any input parameters for the function.
The transaction will invoke the function and return any possible output once it has been mined.
We're going to be using Remix to write smart contracts, which is an online IDE available for free at remix.ethereum.org.
It comes with a compiler, editor, and debugger for solidity.
The great part is that you don't need to download or install or set up anything.
You just go to this webpage and start writing smart contracts, which is awesome.
The UI is divided into four main sections.
The left part is our file explorer, where we can open Solidity files from our hard drive.
The middle section is our editor, where we can view and write our source code.
At the bottom we have a terminal which prints out important events and transactions.
And the right most section contains some handy tools for compiling, running, and debugging our code.
The first example we'll look at is a smart contract called Hodor.
Let's load up the source code.
You'll notice that Solidity source files end with the .sol extension.
The first line we see at the top uses the pragma directive, this tell the compiler that the contract is written for a solidity compiler version of at least .4.0 or anything newer that doesn't break functionality.
We then have a multi-line comment block briefly describing what this class does.
The next line is where we declare the name of our smart contract using the contract keyword.
We've simply called our class Hodor, because as you'll see, all it does is return a simple greeting.
We also declared two state variables called creator and greeting.
Creator has an address data type, which is used for storing addresses of accounts.
Greeting is a string data type which just stores some text greeting.
We initialize both of these variables in our constructor.
The constructor is declared using the function keyword followed by the name of the class.
The constructor is a special function that is invoked only once when a contract is first deployed to the ethereum block chain.
You can only declare a single constructor for a contract.
We also inject the initial string greeting as a parameter into the constructor and set the greeting variable to that value.
In the second line of the constructor we initialize the creator variable to a value called message.sender, but if you look closely you might wonder where this value came from since it's not being injected into the constructor.
This is because message is a global variable that provides certain information about the message such as the address of the account sending it.
We can get the address of the account creating the contract using message.sender in the constructor.
You may notice that we don't actually use this creator variable anywhere in our contract because this is just a simple example.
We could potentially use this information to implement access control to certain functions.
We'll see an example of this later.
Below the constructor we define two functions for this contract, greet and set greeting.
Invoking greet will simply return the currently saved greeting.
You can see that we declared a return type of string for the function and we used the return keyword to give back the value of greeting.
We also used the constant keyword, which is a way of saying that this function does not modify the contract state, and it doesn't make any rights to the block chain.
Anyone can also change the saved greeting using the set greeting function.
This method doesn't have a return type, but does take a string input parameter as the new greeting.
Now, let's try to actually deploy and interact with this contract.
We can go back to our right most section and take a look at the tools available there.
The first tab is the compile tab, which allows us to compile the code or enable disable auto-compile.
It also prints out any static analysis errors and warnings.
The run tab is where we can actually deploy and execute our code.
We can select from three environments to run the code.
It's convenient but it also means that if you reload the browser it will restart a new node from scratch and you lose the old one.
The other two options rely on nodes running external to the browser.
Injected provider connects to a web three provider like MetaMask, that can inject web three.
And web three provider allows you to connect to a node by specifying the url.
This could also be a locally running node, like TestRPC or Geth.
You can also choose from a list of accounts associated with your current node to be the author of the contract, and specify the amount of gas you want to pay for the deployment transaction as well as any initial ether to provide.
Below we also see an at address and create button with a list of the compiled contracts available.
You can use at address to connect and interact with an already deployed instance of a contract if you know its address, but since we're deploying for the first time, we'll use the create button.
It has a field for the input greeting parameter which we need to specify as a string in quotations.
Otherwise, you'll get an encoding error.
Clicking the create button will deploy the contract to the block chain using a transaction.
We can create as many instances as we like and each deployed instance will be visible at the bottom of the run tab.
We can also see the corresponding transaction logs in the terminal.
Clicking on the details button will give us more info such as the resulting contract address, and the amount of gas used to process the transaction.
We can then interact with the instance, and invoke any of its functions.
If we click the greet button to invoke the greet function on this contract we can see it returns the greeting set from the constructor.
Let's set a different greeting and click the set greeting button.
We see the corresponding transaction in the terminal as well.
And if we now invoke the greet function we should get back the updated greeting.
Let's look at another example, say we wanted to create our own cryptocurrency called DragonStone.
How would we do this?
Let's look at the code.
We declare our DragonStone smart contract using the contract keyword.
We have two state variables, creator and balances.
The address of the account creating the contract is stored in the creator field, like the last example.
We also added the public keyword to the creator field.
The public keyword automatically generates a function that allows contracts to access the current value of the field like this.
Without this keyword other contracts cannot access this field.
The balances field, also publicly accessible, keeps track of who owns how many DragonStones.
The automatically generated function in this case is a bit different, and would have a signature like this, allowing anyone to query the balance of any account.
This is because we have a data type of mapping, which can be thought of as hash table of key value pairs.
The key value data types are defined inside the brackets as address keys mapping to unsigned integer values, representing the amount owned by an address.
We also see a new keyword, the event keyword, events are used to indicate that something of interest has happened.
They're fired from within functions and can be listened to by other applications, either Server Side or Front End.
As soon as the delivered event is fired the listener will receive the from, to, and amount arguments.
This feature of solidity makes it easy to track transactions.
In the constructor we only record the address of the creator.
This information is then used to ensure that only the creator can invoke the create function to issue currency.
The if condition in create verifies that the sender of the message is the same as the creator.
Otherwise, it throws an exception and does not create any currency.
If the sender is the creator then the balance is updated for the receiving account by the specified amount.
Transferring DragonStone can be done by anybody, not just the creator.
The only requirement to transfer an amount is to actually have that amount in your account.
Otherwise, the transfer can't be completed.
We verify the account balance as the first step in the transfer function, returning early if there is an insufficient balance.
The balances for the sender and receiver are then updated by the specified amount to complete the transfer.
A delivered event is then fired to notify listeners of the successful transfer.
And there we have a very basic crypto-currency that the creator can issue out of thin air, and owners of this currency can transfer it to whomever they please.
Note that this class is only four lines longer than the Hodor class, which is pretty cool.
Let's deploy this contract and test it out a bit.
We can try to create some DragonStone as the creator of the contract, and issue ourselves five DragonStone.
If we try to create DragonStone as someone who is not the creator, we'll get back an exception since it won't get past our if condition.
Let's try transferring some DragonStone from an account that doesn't have any.
We should also see an exception since we checked for the sender's balance before transferring.
Now, let's try that again but as the creator, and we can see that the transfer was made successfully.
And there we have a simple introduction to smart contracts.
To learn more about ethereum and solidity check out our online guides and courses at blockgeeks.com.
Thanks for watching and we'll catch you next time.
How To Create An Ethereum Smart Contract
How To Create An Ethereum Smart Contract
The most interesting part of Ethereum are smart contracts. You can think of smart contracts like autonomous agents deployed onto the Ethereum blockchain.