목차
- 솔리디티 언어란?
- 컴파일러?
- EOA, CA 차이
- 스마트 컨트랙트 구현을 위한 코드작성
솔리디티 언어란?
What is Solidity?
솔리디티는 기존에 있던 언어가 아닌 이더리움의 스마트 컨트랙트를 구현하기 위해서 만들어진 이더리움 전용 언어입니다. 솔리디티는 Python, C++, Javascript같은 널리 알려진 언어와 사용법이 유사하며, EVM(Ethereum Virtual Machine)에서 구동되어 집니다.
이더리움은 기본적으로 무작정 솔리디티 코드를 짜는 것보다는 검증된 모범사례를 참고해서 작성되는 것을 권유하고 있습니다. 코인이 전달되는 코드이기 때문에, 잘못 짠 소스는 악의적인 해커(Hacker)들의 먹잇감이 될 수 있기 때문에 검증된 모범사례(Best Practice)의 코드가 아니라면 상당 기간의 코드리뷰(code review), 테스팅(testing), 감사(audit), 정확성증명(correctness proofs) 작업이 들어가야 할 것입니다.
출처: https://needjarvis.tistory.com/250 [자비스가 필요해:티스토리]
컴파일러?
컴파일러를 엄밀히 말하자면, 어떤 프로그래밍 언어로 쓰여진 소스 파일을 다른 프로그래밍 언어로 바꾸어주는 번역기인 셈이다. 어떤 언어 A를 B로 바꾸면 그게 컴파일러다.
아래에서 스마트 컨트랙트를 구현하면서, 솔리디티 언어로 짜여진 코드를 컴퓨터 언어(이진수) Bytecode와 abi(Application Binary Interface)로 컴파일러 해줄 것이다.
EOA, CA 차이
외부 소유 계정(Externally Owned Accounts)
공개 이더리움 주소와 개인키 조합을 의미하는데 쉽게 말해 지갑 주소라고 보면 된다.
이것을 이용하여 다른 계정과 이더리움을 송수신하고 스마트 컨트랙트에 트랜잭션을 보낼 수 있다.
메타마스크, 카이카스에서 만든 계정이 EOA라고 보면 된다.
컨트랙트 계정(Contract Accounts)
컨트랙트 계정은 외부 소유 계정과 다르게 개인키가 존재하지 않고, 스마트 컨트랙트를 블록체인에 배포할 때 생성된다.
컨트랙트 계정 대신 컨트랙트로만 표시하기도 한다.
이 컨트랙트 계정은 다른 계정과 이더를 송수신하는 기능을 하며, 이것은 EOA와 동일하다.
또 이 컨트랙트 계정에는 코드를 담고 있는데 흔히 스마트 컨트랙트라고 한다.
EOA나 다른 컨트랙트의 호출을 받아서 트랜잭션을 발생시키며, 스스로 동작하지는 않는다.
스마트 컨트랙트에 접근하기 위한 주소가 곧 컨트랙트 계정을 의미한다.
출처: https://progdev.tistory.com/49 [플머의 개발 연구소:티스토리]
스마트 컨트랙트 구현을 위한 코드 작성
참고용 디렉토리
1) 일단
HelloWorld.sol 파일에 스마트컨트랙트에 사용할 코드를 넣어준다.
Contract/HelloWorld.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
contract HelloWorld{
string text; // 상태 변수
constructor(){
text = "Hello World";
}
function getText() public view returns(string memory){
return text;
}
function setText(string memory value) public{ //타입스크립트 void 타입.
text = value; //상태변수를 바꾸는거임.
}
}
이 솔리디티 언어로 짠 코드를 geth와 컴퓨터가 인식할 수 있도록 컴파일을 해주어야한다.
이때 컴파일에 필요한 모듈을 깔아준다.
npm init -y
npm install solc
다 깔리면
npx solc [디렉토리/파일명]
디렉토리까지 cd로 접근한 후에,
npx solc --bin --abi ./Contracts/HelloWorld.sol
을 입력해주면 컴파일이 된다(시간 조금 걸리는 듯)
그러면
이런 파일 두 개가 생기는데 하나는 bin파일(컴퓨터언어), 하나는 abi파일(사용자와 상호작용할 수 있는 언어(컴퓨터와 사용자를 연결해주는 OS같은 존재))이 생성된다.
들어가보면?
bin은 알아보지 못할 긴 숫자로 써져있고, abi는 그래도 읽을 수는 있을 정도로 써져있다.
2) 이제 geth를 실행해주겠다.
새 터미널을 열어 node와, genesis block 파일이 있는 디렉토리로 이동한 후(아직 없다면 전글-private 네트워크 글- 참고), geth를 실행해준다.
geth --datadir node --http --http.addr "0.0.0.0" --http.port 9000 --http.corsdomain "*" --http.api "admin,eth,debug,miner,net,txpool,personal,web3" --syncmode full --ipcpath "~/.ethereum/geth.ipc" --networkid 4756 --port 30300 --ws --ws.addr "0.0.0.0" --ws.port 9005 --ws.origins "*" --ws.api "miner,eth,net,web3" --allow-insecure-unlock --unlock "0,1" --password "./node/password"
geth --datadir node --http --http.addr "0.0.0.0" --http.port 9000 --http.corsdomain "*" --http.api "admin,eth,debug,miner,net,txpool,personal,web3" --syncmode full --ipcpath "~/.ethereum/geth.ipc" --networkid 4756 --port 30300 --ws --ws.addr "0.0.0.0" --ws.port 9005 --ws.origins "*" --ws.api "miner,eth,net,web3" --allow-insecure-unlock --unlock "0,1" --password "./node/password"
networkid는 본인 마음이다. password는 계정을 생성할 때(newAccount) 설정한 비밀번호이며, 필자는 password라는파일안에 보관하였기 때문에 경로를 작성해주었다.
다른 터미널 하나 더 열고,
geth attach http://127.0.0.1:9000
외부 네트워크로 접근해주었다.
3) 실행되었다면?
이런 게 뜰 것이고, 여기에 우리는 명령어를 입력해줄 것이다.
> username = "podo" ##마음대로 작성
> bytecode = "0x [bytecode]"
아까 컴파일을 통해 얻은 bin 파일을 전부복사 (ctrl + a, ctrl + c)해서 0x뒤에 붙여 넣고 엔터
> abi = [abi복사]
마찬가지로 abi파일을 그대로 복사. 추가해줄 것은 없음. 역시 엔터
이렇게 뜨면 성공
> txObject = {
from:eth.coinbase,
data:bytecode
}
를 복사해서 넣어준다.
data라는 key값에 bytecode(컴퓨터 언어)가 들어가는 것이고, from이라는 key값엔 코인베이스(은행으로 치면 주거래 계좌)가 들어가는 것이다.
4)
트랜잭션을 발동 시켜보자.
> eth.sendTransaction(txObject)
> txpool을 입력해보면 pending에 1이 늘어난 것을 볼 수 있다.
트랜잭션이 발생하였기 때문에 블럭이 생성되지 않으면 반영되지 않는다.
그러므로
miner.start(8)
miner.stop()
을 대충해서 마이닝을 해주면 트랜잭션이 반영된다.
> eth.sendTransaction(txObject)
를 했을 때 출력 된 트랜잭션 해시를 복붙해서 잘 가지고 있자.
아니면 blockNumber를 복붙해도 된다.
> eth.getTransactionReceipt("복붙한 트랜잭션 해시")
blockNumber를 복붙했다면
>eth.getBlock(blockNumber)
필자는 트랜잭션을 사용했다.
입력을 해주고 엔터를 쳐보면 해당 트랜잭션에 대한 정보를 확인할 수 있다.
여기서 그냥 Private network로 geth를 실행했을 때와 다른점은 CA(contractAddress) 라는 계좌가 생성되었단 것이다.
> eth.getTransaction("트랜잭션 해시")
를 해도 input이라는 값이 생성되었음이 확인가능하다.
CA도 잘 복붙해서 보관해놓자.
5)
> contract = eth.contract(abi)
해보자.
eth객체에 abi 속성값을 추가해준것이다.(우리가 솔리디티로 적은 코드. 즉 사용자 지정함수라고 볼 수 있음)
> instance = contract.at("CA")
아까 복사해놓은 CA를 넣어주자.
우리가 아까 넣은 함수가 들어갔음을 확인할 수 있다.
> instance.getText.call()
치면 우리가 솔리디티 언어로 작성한 text값을 가져옴.
instance.setText('asdf')
하면 그 text값을 asdf로 바꿔줌.
> instance.setText('바꿀 text', {from:eth.coinbase})
객체에 from이라는 정보를 싣고, text를 변경할 수 있다.
변경 사항은
> instance.getText.call()
로 확인가능하다.
솔리디티 코드에서,
getText(코드 단순 불러오는 것)은 돈(이더)이 들지 않는다.
그러나 setText는 돈이 든다.왜냐면 트랜잭션을 발생시키기 때문....
또한 용량도 중요하다. .sol에서 용량도 지정해줄 수 있는데, 효율적인 용량 크기를 지정해주어야한다.
uint 인가? uint256 이렇게 용량을 지정해줘야함. 용량이 바뀔때마다 역시 이더가 든다.
16비트인데 256비트로 용량 설정하면? 돈이 과하게 나가게 되는 것이다.
사실
위에서 노가다로 친 내용을 쉽게 해주는 프레임 워크가 있다.
sol코드만 작성하면 끝이다 ㅋㅋ
'블록체인 > 스마트 컨트랙트' 카테고리의 다른 글
[스마트 컨트랙트] 투표 dApp 만들어 보기 (0) | 2022.07.18 |
---|---|
[truffle, 스마트 컨트랙트] 토큰 생성해보기 (0) | 2022.07.15 |
[ truffle, 스마트 컨트랙트 ] 솔리디티 event 사용해서 dApp 간단하게 구현해보기 (0) | 2022.07.14 |
[truffle, 스마트 컨트랙트] d App 간단하게 만들어보기 (0) | 2022.07.13 |
[truffle] 트러플 사용 방법 알아보기. (0) | 2022.07.12 |