Solidity Basics
End of this post you can get basic knowledge on Solidity Language. If you have any programming experience before, this post will boost your knowledge up to developing a complete Ethereum software solution.
To test Solidity codes which you write in this session, you can use online tool called Remix . Remix is a online Solidity Compiler and Testing Environment which uses your browser folder and your machine resources to save data.
Here i mentioned basic and most usable data types. With the time i will update this content.
bool - true, false
string - ""
int / uint - int8 (0 - 255) & int256 (0 - 2 power 256)
address - store Ethereum address
(keep in your mind, apart from the string all the other data types are passed by reference. string is pass by value.)
private - can access inside this contract only
internal - can access inside this contract as well as contracts derived from this
external - disallow accessing internally. Only allow external access
constant - earlier days this is used to indicate that the relevant function won't change the storage state. But later they have introduced more specific access modifiers as replace for constant. they are,
view - tells it never change the storage state (Use for Getters)
&
pure - tells it won't even read the storage state (Functions which do not read/write storage. Just imagine a function which only work with input parameters)
Custom modifiers - solidity allows you to create your own modifiers according to your requirement.
Example :- Let's imagine the relevant function should execute by only the owner(your instance only, outside address are not allowed)
Let's we look at how to debug in solidity.
I think now you are much familiar with Remix online IDE. So let me explain how to read and understand the following sections.
Now we study actually how they calculate ActualTransactionCost for a method, Ex:- getGrade() that i demonstrated in Debugging video.
Execution Cost is calculated in the same manner. Finally they add both ExecutionCost and ActualTransactionCost and if it is a new creation of a Contract(deployment) then they add the ContractCreationCost as well for getting Transaction Cost.
I said that you can't return a Struct. But you can do above hack if you really need to return, using the special functionality of Solidity called return multiple values as i shown above example (getMyDataSet function).
Restriction of returning string :- This is a limitation of Solidity, and the reason is that
But you can fix this if you know the max length of the string:-
(if you really want to work with Standard Time, you have to use a time library. There are some Git repositories for Solidity Standard Time)
Okay fellows this is the end of my short and sweet Ethereum Solidity Theory Tutorials and let's we meet with another new practical tutorial.
Cheers π«π«π«.
My Next Post : Create Complete Solidity based Blockchain Application
To test Solidity codes which you write in this session, you can use online tool called Remix . Remix is a online Solidity Compiler and Testing Environment which uses your browser folder and your machine resources to save data.
What is Solidity?
Solidity is Contract Oriented, Object Oriented, High Level Language for writing Smart Contract aiming the Ethereum Virtual Machine. Solidity is influenced by C++, Python and Java Script.What are the Basic Data Types in Solidity ?
Here i mentioned basic and most usable data types. With the time i will update this content.
bool - true, falsestring - ""
int / uint - int8 (0 - 255) & int256 (0 - 2 power 256)
address - store Ethereum address
(keep in your mind, apart from the string all the other data types are passed by reference. string is pass by value.)
What are the Access Modifiers in Block Chain?
public - can access everywhereprivate - can access inside this contract only
internal - can access inside this contract as well as contracts derived from this
external - disallow accessing internally. Only allow external access
constant - earlier days this is used to indicate that the relevant function won't change the storage state. But later they have introduced more specific access modifiers as replace for constant. they are,
view - tells it never change the storage state (Use for Getters)
&
pure - tells it won't even read the storage state (Functions which do not read/write storage. Just imagine a function which only work with input parameters)
Custom modifiers - solidity allows you to create your own modifiers according to your requirement.
Example :- Let's imagine the relevant function should execute by only the owner(your instance only, outside address are not allowed)
Other modifiers - actually solidity has some modifiers which is not used to control the access level but it control the Ether Transferring mechanism. For an example we can use payable modifier for the fallback function(in future i will explain fallback functions) in order to mark the contract which is capable of accepting incoming Ether into the contract.
Sample structure of a Solidity Contract
if you see carefully the above solidity example,- in variable declaration - access modifier come after the data type and finally declare the name of the variable
- in function declaration - access modifier come after the name of the function and if it return a value that return type is defined last.
Let's we look at how to debug in solidity.
I think now you are much familiar with Remix online IDE. So let me explain how to read and understand the following sections.
Now we study actually how they calculate ActualTransactionCost for a method, Ex:- getGrade() that i demonstrated in Debugging video.
Execution Cost is calculated in the same manner. Finally they add both ExecutionCost and ActualTransactionCost and if it is a new creation of a Contract(deployment) then they add the ContractCreationCost as well for getting Transaction Cost.
Advanced data types in solidity with examples.
Now i believe you have a good understanding on Remix IDE. So Following video which explain the Advanced Data Types was developed on Remix.- Array - Collection of data but same Type. Three ways of initializing an array in solidity.
- Struct - collection of data but different Types. We can't create objects using a Struct. It is a loose bag of Variables. So you can not return a Struct by a function.
I said that you can't return a Struct. But you can do above hack if you really need to return, using the special functionality of Solidity called return multiple values as i shown above example (getMyDataSet function).
Restriction of returning string :- This is a limitation of Solidity, and the reason is that
string
is basically an arbitrary-length byte array (i.e. byte[]
), and so string[]
is a two-dimensional byte array (i.e. byte[][]
). According to Solidity references, two-dimensional arrays as parameters are not yet supported.But you can fix this if you know the max length of the string:-
function setStrings(byte[MAX_LENGTH][] row) {...}
Keep in your mind you can store a Struct inside another Struct.- Enum - List of finite set of values.
- Address - Hold a 20 byte value (Ethereum Address).
- Mapping - kind of a hash table, dynamically sized array.
Verification in Solidity (require and assert).
If you see carefully you will see though relevant validation failed but if it was "require" then it will refund the remaining Gas and reverting all changes.
But if we use "assert" it won't refund remaining Gas. It will use remaining Gas and reverting all changes.
So require is mostly use for input validations and assert is used to catch run time errors.
Besides that we have throw and revert.
throw - simply revert all the changes but consumes all the Gas. It is used to check that something owner should do.
revert - it will refund all the remaining Gas to the caller and allows to return a value.
Import and Inheritance in Solidity
This video describes how to do inheritance in solidity and make Parent and Child relationship between two Contracts.
Event in Solidity
Event is basically designed for listening to a particular occurrence. Also it enable logging facility in Solidity but it is not the major duty of Events. Actually events are inheritable members of Contracts. It's mean if B is A and A has an event then B can call that event. When you call an event it stores its arguments in the transaction's log related to the address of the Contract which called the Event. This log exists until the Block is accessible.
simple Event Program
As you can see now execution details consist new section called logs.
Now i am going to show you an interesting thing that how to access this backend by a simple front end UI and how to use this Event to give notification on the UI.
Interface, Library : write upgradeable Ethereum contracts in Solidity
I guess you remember that once we deploy our Contract into the Blockchain it can not be changed (Immutable). I mentioned this in one of my previous tutorial when i am describing the Ethereum concepts. But you can use interfaces and Library for creating upgradeable Ethereum contracts.
Write upgradeable contract using Interfaces.
Actually storing data is expensive. So if you upgrade contract which contain large storage variables then it might exceed your transaction Gas Limit because it copy your existing data to the newer version of the contract (the purpose of the Gas Limit is to prevent vulnerable behavior of Contract). So the best thing we can do is isolating the storage variables from the Logic Contract.
In order to do that we have to keep our our variables in a separate contract called storage contract. Then we can upgrade our logic part without affecting to the storage.
Write upgradeable contract using Library.
Actually library is a different type of Contract. Library doesn't have any storage. It means if library function is called then that particular caller Contract's context is used for executing the Library function. So memory of the particular Contract can be accessed by the Library function.
Libraries are deployed only once at a specific address. Then we can reuse the Library code using the DELEGATE feature of EVM. That is why i mentioned that Library function use the memory of calling Contract.
(Before you learn what is a DELEGATE Call, you should learn what is a Message Call. Message Calls have many similarities to transactions, such as having a
target, a source, data payload, gas, Ether and return data. Contract can call other Contracts using Message Calls.)
Actually DELEGATE call is a kind of Message Call but it variant from Message Call by the way how DELEGATE Call uses memory and use Balance.
Call | Memory | Balance |
Message Call | Use memory of Callee | Use Balance(Gas) of Callee |
Delegate Call | Use memory of Caller | Use Balance(Gas) of Caller |
So now you know Libraries are singleton and it is not allowed for any storage variables.So we can use Libraries to encapsulate business logic(logic that frequently change) and it costs only upgrading one. Obviously it prevent upgrading many Contracts if we need a business logic change.
So this diagram is for you if you didn't get this solution πΌπΌπΌ describing how to write upgradeable contracts.
Let me dig into this again. You know Upgrading is impossible when we talking about the Contracts with storage variables. Because to update a Contract with variable is take a high cost(we have to rewrite the storage if we do a change for a existing Contract with variable) and probably it exceeds the Gas Limit.
But what if we isolate the storage variables in a separate contract called Storage Contract which is inherited to a Interface and isolate the business logic in a Library. Now we can simply maintain a Contract(Usage Contract) for handling user calls and we can import the Interface and Library on top of the Usage Contract. Inside the functions in Usage Contract we can call the services written in the library and same time we can pass variables into Library Services taking from the Interface.
Now think we have a situation like change the business logic. Now we can simply update only the Library Contract services without touching the Storage Contracts. It is very cheap and it make possible to update the Contract.
Now let's imagine we have a requirement to change the Storage variables. Now we can simply get rid of the Old Storage Contract and we can inherit a New Storage Contract to the Interface and we can now access the Storage using that interface inside the Usage Contract.
Globally Available Variables & functions
- All Ether Units are available globally -
wei,
finney,
szabo,
ether
- so you can write these equations, ex:
4 ether == 4000 finney
- These time units are available globally -
seconds
,minutes
,hours
,days
,weeks,
years
- so you can write this way, ex:
120 seconds == 2 minutes
Special functions -
block.blockhash(uint blockNumber) returns (bytes32)
: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced byblockhash(uint blockNumber)
.block.coinbase
(address
): current block miner’s addressblock.difficulty
(uint
): current block difficultyblock.gaslimit
(uint
): current block gaslimitblock.number
(uint
): current block numberblock.timestamp
(uint
): current block timestamp as seconds since unix epochgasleft() returns (uint256)
: remaining gasmsg.data
(bytes
): complete calldatamsg.gas
(uint
): remaining gas - deprecated in version 0.4.21 and to be replaced bygasleft()
msg.sender
(address
): sender of the message (current call)msg.sig
(bytes4
): first four bytes of the calldata (i.e. function identifier)msg.value
(uint
): number of wei sent with the messagenow
(uint
): current block timestamp (alias forblock.timestamp
)tx.gasprice
(uint
): gas price of the transactiontx.origin
(address
): sender of the transaction (full call chain)
msg.sender,
msg.value
)Okay fellows this is the end of my short and sweet Ethereum Solidity Theory Tutorials and let's we meet with another new practical tutorial.
Cheers π«π«π«.
My Next Post : Create Complete Solidity based Blockchain Application
Comments
Post a Comment