Preamble
Smart contracts to solve problems in a trusting environment like the Internet. And smart contract is not a formidable thing, it is born to solve real problems, such as: pay, insurance, inheritance, exchange, purchase .... Recently we hear a lot about Decentralized Exchange, ICO ... people talk about it really very formidable. Sometimes people exaggerate things unnecessarily to achieve the purpose of PR. But in technology everything is approaching.
ERC20 Token
In the Ethereum system, ETH acts as a native token, and the transaction fee is calculated on the token. Ethereum platform also allows users to define their own tokens and to standardize these tokens, the ERC20 is born. It's up to the founder's goal that an ecosystem may or may not have a token.
The simplest token would include the following components:
- totalSupply
- balanceOf
- transfer
First, we must define a mapping to store the information of the token acting as a ledger:
mapping (address => uint256) balances;
Each address will map to a uint256 number (unsigned integer 256 bits). We can interact through the [] operator to access the elements.
Next to read the data from the mapping we created the balanceOf () method:
function balanceOf(address _owner) constant public returns(uint256){
return balances[_owner];
}
This method allows us to read the information of any owner and know how many tokens they have.
We define the transfer () method to be able to switch tokens between owner:
function transfer(address _to, uint256 _value) public returns(bool){
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
Security for AmazingToken:
In the smart contract above we will see the problem of the transfer () method:
- If to = 0x00 the token will disappear, like me stream data into the /dev/null
- The transfer is still executing even if msg.sender does not have enough balance
Now we rewrite the smart contract of the amazing token with the check of these conditions
pragma solidity ^0.4.11;
contract AmazingToken{
uint256 public totalSupply;
mapping (address => uint256) balances;
modifier onlyValidAddress(address _to){
require(_to != address(0x00));
_;
}
modifier onlyValidValue(address _from,uint256 _value){
require(_value <= balances[_from]);
_;
}
function balanceOf(address _owner)
constant public returns(uint256){
return balances[_owner];
}
function transfer(address _to, uint256 _value)
onlyValidAddress(_to) onlyValidValue(msg.sender,_value)
public returns(bool){
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
}
Adding these two modifiers makes our contract a lot safer. After programming the token, what people think of the way to issue tokens.
Defines a method for issuing tokens
We define the method to sell AmazingToken every time someone sends the Ethereum to receive AmazingToken in a 1: 100 scale.
function () public payable {
uint256 _issued = (msg.value* 100)/10**18;
totalSupply += _issued;
balances[msg.sender] = _issued;
}
The global variable msg.value contains the eth value in units of wei (1 eth = 10μl wei).
Smart contract of AmazingToken will be as follows
pragma solidity ^0.4.11;
contract AmazingToken{
uint256 public totalSupply;
mapping (address => uint256) balances;
modifier onlyValidAddress(address _to){
require(_to != address(0x00));
_;
}
modifier onlyValidValue(address _from,uint256 _value){
require(_value <= balances[_from]);
_;
}
function () public payable {
uint256 _issued = (msg.value*100)/10**18;
totalSupply += _issued;
balances[msg.sender] = _issued;
}
function balanceOf(address _owner) constant public
returns(uint256){
return balances[_owner];
}
function transfer(address _to, uint256 _value)
onlyValidAddress(_to) onlyValidValue(msg.sender,_value) public
returns(bool){
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
}
Decentralized exchange
Now I'm going to write a smart contract that acts as a decentralized exchange, which I would like to be able to sell the AmazingToken that I own if anyone agrees to buy it with Ethereum.
pragma solidity ^0.4.11;
contract AmazingTokenInterface{
uint256 public totalSupply;
function () public payable;
function balanceOf(address _owner)
constant public returns(uint256);
function transfer(address _to, uint256 _value)
public returns(bool);
}
contract AmazingDex {
AmazingTokenInterface AmazingToken;
address ChiroWallet = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
uint256 public rate = 100;
modifier onlyValidAddress(address _to){
require(_to != address(0x00));
_;
}
modifier onlyChiro(){
require(msg.sender == ChiroWallet);
_;
}
function setRate(uint256 _rate)
onlyChiro public returns(uint256){
rate = _rate;
return rate;
}
function AmazingDex(address _amazingTokenAddress)
onlyValidAddress(_amazingTokenAddress) public {
AmazingToken = AmazingTokenInterface(_amazingTokenAddress);
}
function buyToken()
onlyValidAddress(msg.sender) public payable {
uint256 _value = (msg.value*rate)/10**18;
assert(AmazingToken.transfer(msg.sender, _value));
ChiroWallet.transfer(msg.value);
}
}
This smart contract does a very simple job, when anyone calls the buyToken () method, I will pay the token to them according to the rate they have provided, and Ethereum will immediately tell the purse.
Of course AmazingToken will be held by AmazingDex.
End
You see things are not as hard as people want us to believe. If you have any comments, please comment below.
Thank you for watching