42. What is a Constructor in Solidity
// a constructor is a special type of function
// that gets called immediately upon deployment
// the constructor can only be called one time
// a function is just a set of instructions bundled together
constructor(/*we can add arguments*/){
minter = msg.sender; //msg.sender == global variable == the person who created contract
}
constructor는 contract가 deploy될 때 immediately하게 딱 한 번만 실행되는 function이다.
앞서서 선언했던 minter 변수에 msg.sender를 할당한 후, 다시 deploy를 해보면 minter에 현재 내가 contract를 실행한 address의 주소가 할당된 것을 확인할 수 있다. msg.sender는 contract를 만든(호출한) 사람의 주소이고 global variable이라고 한다.
43. What is Mapping in Solidity
// what if we want to store addresses and then give each address a specific
// number or index? - the solution is mapping
// mapping: acts like a dictionary to store data
// mapping takes a key which maps to a value
// mapping(key => value) public mapName
mapping(address => uint) public balances;
JAVA의 MAP 이나 Python의 Dictionary와 같은 자료구조 형식을 Solidity에서는 Mapping이라고 하는 것 같다.
Key 와 Value 쌍으로 이루어져 있고 위와 같이 선언해서 사용한다.
46. What Are Events in Solidity
// Events allow clients to react to specific contract changes
// tht you declare (one way logging of transactions)
// events take two steps:
// 1. is setting it up 2. emitting the event
// preconditioned arguments (inputs) we should pass
event Sent(address from, address to, uint amount);
event라는 개념에 대해 잘 이해가 가지 않아서 추가적으로 찾아보았다. 무언가를 보내거나 하는 event가 아니라 just logging information 하는 용도라고 한다.
https://www.tutorialspoint.com/solidity/solidity_events.htm
Event is an inheritable member of a contract. An event is emitted, it stores the arguments passed in transaction logs. These logs are stored on blockchain and are accessible using address of the contract till the contract is present on the blockchain. An event generated is not accessible from within contracts, not even the one which have created and emitted them.
47. The Mint Token Function Signature
// Build a minting function to mint tokens
// MORE ON FUNCTIONS
// we give a function a specific set of instructions
// and then we can call that function to execute those instructions
// and that's how we get our code to do things!
// functions are self contained modules of code that perform tasks for us
function mint(address receiver, uint amount) public {
// want to make sure that the only person who can mint
// tokens is the owner of this contract
}
이제 minting하는 function을 만들어 보려고 한다. function을 선언하는 방법은 여타 다른 언어들과 비슷하다.
우리는 contract의 owner만이 token minting을 가능하게 하고 싶은데 그 방법은 solidity의 requirement method를 사용하는 것이라고 한다.
48. Conditional Logic & Error Handling in Solidity
function mint(address receiver, uint amount) public {
// want to make sure that the only person who can mint
// tokens is the owner of this contract
// requirement method in solidity
// require evaluates the truthiness within its paranthesis
require (msg.sender == minter);
}
reqruie은 if 문과 같은 것이다. 괄호 안의 statement가 true인지 false인지 확인하고, true인 경우에만 함수가 실행되도록 한다.
그래서 contract를 deploy한 후에 account를 바꾸고 transact를 실행하면 ERROR가 뜨는 것을 확인할 수 있다.
49. Updating Token Balances & the += Operator
// sets the amount to a specific address
// balances[receiver] = balances[receiver] + amount;
balances[receiver] += amount;
이제 위에서 선언했던 mapping 구조에 값을 할당해보자. Key 값으로 receiver를 넣고, Value 값으로 amount를 넣는다. 이때, 값이 계속 차곡차곡 쌓아져야 하기 때문에 += operator를 이용한다.
그런데 이게 왜 minting의 완성인지 모르겠다. 그냥 mapping안에 값만 저장한 거 아닌가?
50. Exercise - Write A Send Token Function
- Write a public function called send where the signature takes the arguments receiver and amount.
- use our mapping to update the msg.sender balance to decrement by the amount being inputted (argument amount)
- use our mapping to update the receiver balance to increment by the amount being inputted (argument amount)
BONUS write the second step for the event Sent with the according inputs
HINT: use the emit keyward!
51. Solution - Write A Send Token Function
function send(address receiver, uint amount) public {
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
52. Deploy Your First Mintable Token Contract
최종 코드
pragma solidity ^0.8.4;
contract CryptoToken {
mapping(address => uint) public balances;
address public minter;
event Sent(address from, address to, uint amount);
constructor(/*we can add arguments*/){
minter = msg.sender; //msg.sender == global variable == the person who created contract
}
function mint(address receiver, uint amount) public {
require (msg.sender == minter);
balances[receiver] += amount;
}
function send(address receiver, uint amount) public {
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
위의 코드를 Deploy 하고 function을 실행해보면 잘 되는 것을.. 확인할 수 있다..
이때 balances에 남은 balance가 부족한데 send를 하려고 시도하면 에러가 뜰 것이다.
send function을 실행한 후 로그를 보면
[
{
"from": "0xDA0bab807633f07f013f94DD0E6A4F96F8742B53",
"topic": "0x3990db2d31862302a685e8086b5755072a6e2b5b780af1ee81ece35ee3cd3345",
"event": "Sent",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
"2": "5",
"from": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"to": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
"amount": "5"
}
}
]
이렇게 찍혀있는 것도 확인할 수 있다. emit event를 해서 확인할 수 있는 것 같다.
개인적으로는 그냥 변수에 저장만 해놓는 것 같은데, 이게 어떻게 진짜 minting이 되는 건가 생각했는데.. 지금은 실습이니까 그냥 전체적인 구조만 알려주는 것 같다. 아직까지는 따라가기 어렵진 않다😅 영어라서 잠깐만 정신줄을 놓쳐도 저 멀리 날아가 있긴 하지만..