https://docs.soliditylang.org/en/v0.8.10/introduction-to-smart-contracts.html
A Solidity Contract is a collection of code and data that resides at a specific address on the Ethereum blockchain. It is essentially a location of data on the blockchain that contains functionality to read or update the contents.
The contract is broken up into several components.
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
contract Token {
// The keyword "public" makes variables
// accessible from other contracts
address public minter;
mapping (address => uint) public balances;
// Events allow clients to react to specific
// contract changes you declare
event Sent(address from, address to, uint amount);
// Constructor code is only run when the contract
// is created
constructor() {
minter = msg.sender;
}
// Sends an amount of newly created coins to an address
// Can only be called by the contract creator
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
balances[receiver] += amount;
}
// Errors allow you to provide information about
// why an operation failed. They are returned
// to the caller of the function.
error InsufficientBalance(uint requested, uint available);
// Sends an amount of existing coins
// from any caller to an address
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);
}
}
The first line of code in a solidity program is the compiler version. It tells the the compiler which version(s) the code should be compiled in. This is important as syntax is constantly changing. One piece of code may work in one version, but may be obsolete in another.
pragma solidity ^0.8.4;
The above code tells the compiler that the compiler version (that the code is meant for) should be version 0.8.4
or higher.
Contract
The contract is essentially a class that defines how the contact is constructed and accessed. In an object-oriented sense, it is a constructable object that contains data. The contact can have any name and may contain methods to get or set information, create events or errors, and even instructions to for minting .
contract Token {
// Smart Contract code
}
https://docs.soliditylang.org/en/v0.8.10/contracts.html#events
Events allow clients to react to specific contract changes that you declare. When you run blockchain transactions, events log information. They are a “One Way Logging of Transactions”. Examples of event types are Sent
, Transfer
, and Allow
, but they only log the information,they do not conduct the event.
Arguments are inputs that allow the function to dynamically change its output depending on its conditions. Events have three preconditioned arguments: from
, to
, and amount
.
contract Token {
event Sent(address from, address to, uint amount);
function send(address reciever, uint amount) public {
emit Sent(msg.sender, reciever, amount);
}
}
The first step in any event is to set it up and the second step is to emit it.
https://docs.soliditylang.org/en/v0.8.10/types.html#mapping-types
Mapping acts like a dictionary to store data. It assigns shorter key to longer value. In terms of addresses, a uint
key can be mapped to an address
value. Mapping is nearly identical to hash maps in Java.
contract Token {
mapping (address => uint) public balances;
}
In this example, a public map takes the key of an address and maps it to the value of an integer called balances
.
https://docs.soliditylang.org/en/v0.8.10/contracts.html#constructor
A constructor is a special type of function that gets called immediately upon deployment. It is used to create an instance of the contract object. The constructor can only be called one time.
contract Token {
constructor( /* arguments */ ) {
minter = msg.sender;
}
}
In this example, the constructor runs the code minter = msg.sender
when the contract is deployed. This code assigns the minter variable, the address of the caller (the person creating the contract).
Functions in Solidity are very similar to functions or methods in any other language. They are self contained modules of code the perform a specific task. A minting function is syntactically the same as any other function expression, but in this example, is used to create “Tokens”.
contract Token {
function mint(address reciever, uint amount) public {
require(msg.sender == minter);
balances[receiver] += amount;
}
}
require(msg.sender == minter)
ensures that only the person who can mint tokens is the owner of the contract. It evaluates the truthiness within its parenthesis and if it is false, it breaks out of the parent function.balances[reciever] += amount
adds data to the balances
map. Specifically, it modifies the receiver
key and adds amount
to its existing value. (The value of balances[reciever]
equals balances[reciever]
plus amount
).https://docs.soliditylang.org/en/v0.8.10/contracts.html#errors
Errors allow you to provide information to the caller about why a condition or operation failed. To emit an error, you use a revert statement. The revert statement breaks out of the function that it is in, reverts all changes, and provides the name of the error with additional data that will be supplied to the caller. It is very similar to a Java exception.
error InsufficientBalance(uint requested, uint available);
uint amount = 7;
revert InsufficientBalance({
requested: amount,
available: balances[msg.sender]
});
The send function is used to transfer something to someone else. In this case, we are sending tokens to the receiver.
function send(address reciever, uint amount) public {
if (amount > balances[msg.sender]) {
revert InsufficientBalance({
requested: amount,
available: balances[msg.sender]
});
}
balances[msg.sender] -= amount;
balances[reciever] -= amount;
emit Sent(msg.sender, reciever, amount);
}
The send function is a public function that:
InsufficientBalance
error