License
// SPDX-License-Identifier: GPL-3.0
This line means this code is licensed under the GPL (for open source, use MIT)
Pragma
pragma solidity >=0.4.16 <0.9.0
Solidity needs compiling and this language is always updated fast.
By clarifying version of code, it prevents code from behaving differently
contract
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
A contract is a collection which resides at a specific address on Ethereum blockchain world. Ignore the functionalities now.
Solidity is an Object-oriented programming language, but doesn't use this.
(It is just solidity style. You can directly access a member of current contract by calling their name.)
contract name is 'Coin'
'address public minter' is a declaration of state variable named 'minter' with 'address' type as public variable (address type is suitable for storing addresses of contracts or hash of the public key of external accounts)
'public' keyword enables you to access the current value in this contract from outside of contract
'mapping' is also one of solidity types. Its declaration maps addresses to unsigned intergers. It is neither possible to obtain a list of all keys and a list of all values.
'event' can be regarded as a user interaction event in javascript.
'event' and 'emit' is one pair. After you set event (from, to, amount in below example), you emit the event in a function and then the listener receives the arguments 'from, to and amount' which makes it possible to track transactions.
'constructor' is a special function that is executed during the creation of the contract. In below example, it permanently store 'msg.sender' in 'minter' variable.
'msg' (additonally, 'tx' and 'block') is also special built-in global variable. It contains properties which allow access to the blockchain.
'msg.sender' is always address where the current function call came from.
mint function add coin into balances with address and send function send coint to receiver in here
You can check another built-in function 'require'.
require takes an conditional argument and if that condition is not met, it reverts all changes. (It seems like try and catch block in javascript )
'Error' allow you to provide more information why a condition or operation failed. Check this its usage in 'send' function. This error handling is so useful for client side of application.
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
contract Coin {
address public minter;
mapping (address => uint) public balances;
event Sent(address from, address to, uint amount);
constructor() {
minter = msg.sender;
}
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
balances[receiver] += amount;
}
error InsufficientBalance(uint requested, uint available);
function send(address receiver, uint amount) public {
if (amount > balances[msg.sender])
revert InsufficientBalance({
requested: amount,
available: balances[msg.sender]
});
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}