반응형
solidity02_helloworld

Solidity 02

  • solidity 버전 표시
pragma solidity ^0.4.25;    // 정확히 이 버전만 지원
pragma solidity >=0.4.0 <0.6.0;  // 지원 범위

  • 파일 import
import "filename";
import "filename" as symbolName ;
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

github에 있는 소스도 사용할 수 있다.

  • 주석은 c 형식 사용. /**/ // 등
  • public 함수나 변수는 외부에 노출
  • 반대는 internal로 표시한다. 내부에서만 호출 가능.
  • 파리미터에 memory는 라이프사이클이 함수내.
  • 파리미터에 storage로 주면 참조 형식으로 값이 변할 수 있다.
  • 함수에 view를 주면 storage 변수에 읽기 접근만 가능하다. 이벤트 발생 안된다.
  • 함수에 pure를 주면 storage 변수에 접근이 안된다.
  • view, pure를 귀찮게 왜 쓰나? gas 비용 절감과 보안측면 이다.

구버전

pragma solidity ^0.4.25 ;
contract HelloWorld {
	string public greeting ;
	function HelloWorld(string _g) public {
		greeting = _g ;
	}
	function setGreeting(string _g) public {
		greeting = _g ;
	}
	function say() public constant returns (string) {
		return greeting ;
	}
}

위는 0.4대 버전, 아래는 0.5대 버전이다. 문법이 약간 달라졌다.
- constructor가 클래스명에서 명시적으로 constructor로 변경.
- 파라미터, 리턴 변수앞에 저장소 지정을 명시적으로. (엄격해짐)
- constant가 없어짐. view로 대체.
  • public/internal 의 위치가 타입 뒤에 가는 것이 특징. (cpp, java와 다르다.)
  • 함수 리턴 타입을 지정하는 부분이 마지막에 들어간다.

신버전

pragma solidity >0.5.0;

contract HelloWorld {
	string public greeting ;
	
	constructor(string memory g) public {
		greeting = g;
	}
	
	function setGreeting(string memory g) public {
		greeting = g;
	}
	function say() public view returns (string memory) {
		return greeting ;
	}
}

image

  • deploy시 remix에서 펼쳐서 이름을 입력해줘야 인코딩에러가 안난다.
  • setGreeting시도에 펼쳐서 값을 넣어줘야 작동되었다.

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#3 변수와 타입  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10
반응형
solidity01_version

Solidity

Truffle

npm install -g truffle

작업 폴더를 만들고, 들어가서 프로젝트 초기화

truffle init

컴파일

solc source.sol --abi --bin (컴파일 변환 결과를 출력)

전체출력을 JSON 형태로 출력 (뒤에 받을 정보를 기록)
solc source.sol --combined-json abi, asm, bin

truffle을 사용한다면 truffle compile
배포는 truffle migrate로 한다.

문법

cpp처럼 ;으로 끝난다.
주석도 cpp처럼 한다. //, /* 등

pragma solidity >= 0.4.22 <0.6.0 ;
지원하는 버전을 표시한다. 0.4.22이상 0.6 미만.
특정 버전을 지칭할 경우는 ^0.4.22 이렇게 한다.

import ‘a.sol’;
다른 파일을 include 한다.
다른 사용 방식은
import * as cs from “filename”;
import “filename” as shortname;

contract 계약명 {
}
cpp 클래스처럼 정의한다.

mapping (address => uint) balances ;

버전 4와 5와 차이

solidity는 4, 5의 버전 차이가 심하다. 그것을 알아야 빌드를 할 수 있다.

  • Low-Level 함수 호출
    • callcode 삭제
    • staticcall 추가
    • 입력 파라미터가 bytes로 통일
    • 리턴값 지원
  • 지역변수 scope
    • C처럼 scope을 사용한다.
  • 배열에 pop 메소드 추가
  • 중요한 변화
  • address payable 타입 추가
    • 기존에 address 타입에 있던 send, transfer 메소드 삭제
    • 주소를 address payable 타입으로 변환해야 사용 가능하다.
    • send, transfer는 같은 기능인데 send는 low-level함수로 예외처리가 가능하다. transfer는 트랜잭션으로 처리.
    • 주소 타입을 payable로 변환하려면,
(0x...).transfer(1 ether); // 주소 상수 뒤에 바로 사용 OK
address to = 0x...;  
address(to).transfer(1 ether); // 에러!  
address(uint160(to)).transfer(1 ether); // 두번 변환은 OK
address payable x = address(uint160(to)); // 저장할 때도 두번 변환해야 OK
- msg.sender는 address payble 타입으로 변함
- msg.value는 payable, internal 함수에서만 접근 가능
- 다른 곳에서 사용하고 싶으면, 
function msgvalue() internal returns (uint256) {  
return msg.value;  
}
  • 변수 선언을 먼저 확실하게 해주어야 함. (C code)
  • 함수의 visibility (external/public/internal) 명시.
    • (v0.4는 default public)
  • 데이터로케이션(storage(상태변수참조)/memory(함수내)/calldata(함수파라미터)) 명시.
    • (v0.4는 default로 함수파라미터는 memory/calldata, 지역변수는 storage로 자동)
  • contract 타입을 address 타입으로 형변환하여 사용.
    • 0.4에서는 contract 타입이 기본적으로 address 타입과 혼용하여 사용가능했지만 transfer, balance 등을 사용하려면 명시적으로 형변환을 해줘야 한다.
  • Contract 타입간 형변환은 상속관계만 가능.
    • 상속관계가 아닌 contract로 변환하려면 형변환을 두 번하면 가능하다. A(address(b))
  • bytesX, uintX는 사이즈가 같은 경우만 형변환이 가능
    • bytes1 c=1 ;
    • bytes2 d = bytes2( c) ; // 0x0100 (오른쪽에 0이 추가)
    • bytes1 e = bytes1(d); // 0x01 (오른쪽을 제거)
    • bytes1 a = bytes1(0x100); // 0.5.0 부터는 error
    • bytes1 b = bytes1(uint8(0x100)); // 결과는 0
    • bytes1 c = bytes1(bytes2(0x100)); // 결과는 1
  • constant 키워드 삭제. 대신 view로 사용해야 함.
  • var 타입 삭제. 명시적 필요
  • suicide 함수 삭제. selfdestruct로 대체
  • sha3 함수 삭제. keccak256로 대체
  • throw 삭제. revert, require, assert 사용
  • contract명과 동일한 이름의 함수 construct 사용 불가. constructor키워드로 대체
  • 16진수표현은 0X는 삭제. 0x만 지원

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#3 변수와 타입  (0) 2019.12.06
Solidity#2 HelloWorld  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10
반응형
Ether01getset

smart contract / solidity 맛보기

온라인 solidity 개발 테스트 사이트에 접속한다.
https://remix.ethereum.org/

  • 코드를 작성한다.
    단순하게 integer값을 set하고 get하는 API 2개가 있다.
    image

  • 컴파일 한다.
    image

  • Deploy를 한다.
    image

  • 생성된 contract에서 각각의 메소드를 테스트해 볼 수 있다. 위에서는 100을 set하고 get으로 100이 나오는 것을 확인하였다.

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#2 HelloWorld  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
이더리움개발 환경 준비  (1) 2019.11.10
반응형
Ethe00_Setup

Etherium

이더리움 주소

  1. 개인키 생성
  2. 개인키에서 공개키 생성
  3. keccak256으로 공개키의 해시값 생성
  4. 해시값에서 뒤쪽 20바이트를 이더리움 주소로 사용한다.

계정

  1. 외부 소유계정 (EOA)
    다른 계정과 이더 송수신 및 컨트랙트에 트랜잭션 전송도 가능

  2. 컨트랙트 계정
    개인키가 없다. 스마트계약을 블록체인에 배포시 생성됨.
    다른 계정과 이더 송수신 가능.
    코드를 감고 있다.
    EOA나 다른 컨트랙트의 영향으로 트랜잭션을 발생시킬 수 있다.

지갑

이더리움 계정을 저장하고 관리
여러 계정을 관리하고 트랜잭션에 서명, 잔고 추적 등.

가스

스마트 계약 배포, 트랜잭션 실행등에 비용이 소모된다. 채굴자에게 이더를 지불해야한다. 트랜잭션에 얼마나 많은 단위연산이 포함되는지에 따라 비용이 결정됨. 연산의 단위를 가스라고 한다.

가스 가격

트랜잭션 생성자가 원하는 가스 가격을 정할 수 있다. 가스당 3wei 처럼 설정한다. 설정한 가스가격이 높을 수록 트랜잭션 처리 속도가 빠르다. 채굴자들이 높은 가격순으로 처리하기 때문.

가스 한도

트랜잭션 수행 최대 금액을 지정할 수 있다. 블록가스 한도와 다르다.

바이트 코드

스마트 계약 코드는 solidity 언어로 작성 EVM 바이트코드로 컴파일하여 EVM(이더리움 VM)에서 실행된다.

게스(Geth)/패리티(Parity) 클라이언트

geth는 이더리움재단에서 제공하는 공식 클라이언트. (Go로 개발). geth는 블록체인의 복사본을 최신 상태로 유지하고 위해 계속 통신한다. 블록을 채굴하고, 블록체인에 트랜잭션을 추가하고 검증하고 실행한다. API를 제공하기도 한다.

Web3JS

이더리움과 상호작용하는 javascript library.

가나슈. 메모리블록체인 개발테스트
https://www.trufflesuite.com/ganache

지갑관리
https://metamask.io/

메인넷 모니터링
https://etherscan.io/

https://www.etherstudy.net/geth.html

geth 다운로드 설치

https://geth.ethereum.org/downloads/

> geth --dev console
> eth.blockNumber

가나슈설치

Ganache
https://www.trufflesuite.com/ganache
또는
https://github.com/trufflesuite/ganache/releases

온라인 solidity 개발

https://remix.ethereum.org/#optimize=false&evmVersion=null

윈도우/linux solidity compiler

https://github.com/ethereum/solidity/releases

https://github.com/ethereum/solidity/releases/download/v0.5.12/solidity-windows.zip

가나슈가 개발 테스트시에는 빠르다. 추천! (단, 키스토어가 없다. 개인키 접근이 필요하면 복호화된 스트링을 복사해서 사용한다. UI에 열쇠모양 클릭.)

geth는 메모리를 많이 먹어서 느림. 대신 키스토어에 개인키 저장.

py-solc 모듈이 solidity 여러가지 버전에 대해서 잘 지원이 안되는 듯함. python내에서 source compile시도시 에러발생.
커맨드로 빌드하여 output을 파일에 생성하고, 그 파일을 파이썬에서 읽어서 설정하는 방식으로 해야 할 듯 하다.

solc 컴파일러는 버전에 따라 다르니 주의가 필요하다. ubuntu에서 구버전 solc 를 설치하려면?

우분투에서 apt-get 으로 설치하면 최신버전의 solc가 설치된다.
구버전을 사용하려면 위 사이트에서 구버전 soliidity-ubuntu-trusty-clang.zip을 받아서 설치한다.
실행시 libz3 에러가 발생?? 하면 아래와 같이 라이브러리를 설치해 준다. 그 외에도 여러가지 개발툴들을 설치한다.
apt-get -y install build-essential cmake g++ gcc git unzip
apt-get install libz3-dev
solc --version

강좌

https://www.ethereum.org/ko/developers/#%EC%8B%9C%EC%9E%91%ED%95%98%EB%A9%B4%EC%84%9C

https://solidity-kr.readthedocs.io/ko/latest/

https://winterj.me/smart-contract-with-python/


실습

  • geth 설치
sudo add-apt-respository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
sudo apt install golang-go

확인
geth version
1.9.6-stable
go version
1.10.4
  • genesis 블록 설정
    genesis.json 파일 생성
$ cat genesis.json 
{
    "config": {
        "chainId": 16,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0
        },
    "nonce": "0x0000000000654123",
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x00",
    "gasLimit": "0x2db7579a600",
    "difficulty": "0x20",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "alloc": {}
}
  • difficulty 값은 채굴난이도로 낮을수록 빨리캔다. 위의 설정에서는 32가 된다.
  • geth 접속 후, eth.getBlock(0) 으로 확인할 수 있다.

초기화

현재 폴더에서 chain-data 폴더가 만들어진다. 데이터는 다 그곳에 저장됨. (geth, keystore 등)

geth init genesis.json --datadir chain-data
geth --datadir chain-data console

구동

접속을 쉽게하려면 rpc를 만들어 놓자. 아래와 같은 start.sh 스크립트를 만들어 저장해 두고 실행하자. 기본 포트는 8545인데, 여기서는 8485로 변경하였다. (주의!)
원격에서 계정 unlock을 허용하려면 --allow-insecure-unlock 옵션을 추가한다.

just running...
> geth --datadir ./chain-data console
> 최초 계정을 만들어 주어야 한다. 없으면 마이닝 모드 구동시 
> ether base가 없다고 에러가 남.
> 
> personal.newAccount('pass')
> 파라미터가 암호임. 반복하여 여러개의 계정을 임시로 만들어 본다.
> exit

start with options...
> cat start.sh
geth --rpc --rpcport 8485 --rpccorsdomain "*" --datadir "./chain-data" --port 30303 --nodiscover --rpcapi "db,eth,net,web3" --networkid 15 console
다른예) 위와 같이 실행해서 계정을 만든 다음 다음부터 아래처럼 실행
geth --rpc --rpcport 8545 --rpccorsdomain "*" --datadir "./chain-data" --port 30303 --nodiscover --mine --minerthreads 1 --allow-insecure-unlock --rpcapi "admin,personal,miner,db,eth,net,web3" --networkid 15 console
> ./start.sh
실행하면 메시지와 함께 콘솔이 뜬다.

내가 쓰는 구동 스크립트

> cat start3.sh
> geth --rpc --rpcport 8485 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --datadir "./chain-data" --port 30303 \
--allow-insecure-unlock --mine --minerthreads 5 --identity private_chain \
--rpcapi "personal,miner,admin,db,eth,net,web3" --networkid 15 console
  • 윈도우에서 구동시 CPU100% 먹길래 "minerthreads 1"을 삭제해주니까 CPU가 정상적으로 떨어졌다. (참고) 또는 5나 10정도로 설정한다.
  • 구동해 놓으면 coinbase 계정으로 이더가 알아서 쌓이기 시작한다.
  • 마이닝이 안되면 miner.start(5) 이렇게 쓰레드를 지정해서 시작해 보자.
  • 그래도 마이닝이 계속 안되면, 작업관리자를 띄워서 메모리를 살펴보자. 메모리가 점점 증가하다가 1기가 좀 넘어서 기다리면 그 때 부터 CPU를 막 잡아먹기 시작하면서 마이닝을 할 것이다. 컴퓨터 성능에 따라 마이닝 하는데 시간이 좀 걸릴 수 있으니 기다려라.

로컬의 다른 쉘에서 geth 연결하기

geth 구동시 datadir에 설정된 경로에 geth.ipc라는 파일이 생기는데 그것으로 연결한다.

$ geth attach ./chain-data/geth.ipc
or
$ geth attach http://localhost:8485 (rpc:http://... 이렇게도 가능)
일부 작업이 제한될 수 있다. geth 시작시 옵션 설정이 필요.
  • 간단한 명령어
    eth.accounts : 계정 목록
    eth.blockNumber : 현재 채쿨된 블록 번호
    eth.hashrate
    eth.coinbase : 채굴 보상받을 계정. 디폴트는 eth.accounts[0]
    eth.mining : 마이닝 상태 on/off
    eth.getBalance(account) : 잔고
    eth.getTransaction(tx) : TX 정보
    miner.start() : 함수를 호출하여 마이닝 시작. 파라미터 1,2등 thread개수옵션
    miner.stop() : 마이닝 중지
    miner.setEtherbase() : 채굴 보상 계정 설정
    personal.newAccount(password) : 계정 생성
    personal.unlockAccount(account, password) : 계정 잠금 해제 (송금등 TX발생시 사전필요작업임)

  • 콘솔 연결 후 작업

personal.newAccount('pass')
personal.newAccount('pass')
personal.newAccount('pass')
personal.newAccount('pass')
위와 같이 테스트 계정들을 만들어 준다. 암호는 일단 다 pass로 하였음.
eth.mining : 마이닝 상태 확인. 
miner.start() : 마이닝이 멈춰있으면 마이닝을 시작한다.
잠시 후,첫번째 계정 잔고를확인한다.
eth.blockNumber
eth.getBalance( eth.accounts[0] ) : 0번 사용자 잔고 확인.

계정의 키는 데이터 루트 폴더(chain-data)안에 keystore 폴더에 계정별로 저장되어 있다.

  • 방화벽
    아까 rpc port로 설정했던 포트를 연다.
    ufw allow 8485

  • remix연결
    Env. web3provider
    http://172.16.100.88:8485
    원격 주소로는 접속이 안되는 것인지??? 계속 실패하였음.
    그래서 ssh로 포트 터널링하여 로컬로 연결함. (참고로 서버 ssh포트는 2222로 변경된 상태)
    접속 실패 원인을 찾아보니, rpcaddr을 안 줘서 그런 거였다.

ssh -L 8545:localhost:8485 blockchain@172.16.100.88
   -p 2222

위와 같이 로컬 8545를 원격의 8485로 연결해 놓고, remix에서 web3 provider에 주소를 로컬 주소를 주었다.
http://localhost:8545

  • smart contract deploy (배포)

계정 unlock을 해 주어야 한다 (unlock을 해주지 않으면 deploy나 set이 안된다.)
한 번 해두면 일정시간만 허용되는 것 같고, 시간이 지나면 자동으로 잠긴다.
personal.unlockAccount(eth.accounts[0])
위 커맨드가 작동하지 않는다면, geth 구동 스크립트에 옵션을 추가해 주어야 한다. –allow-insecure-unlock

remix로 contract를 deploy 시도 및 API 테스트를 했는데, 계속 가스 초과 에러가 발생하였다.
여러가지 시도 끝에, solidity compiler 버전을 0.4.23으로 낮추고 deploy를 하니 정상적으로 작동하였다. 계속 삽질을 했다는…
또 어디서는 genesis에 chainId가 0이면 그런 증상이 발생해서 42정도로 설정하여 해결했다는 얘기도 있다. 나의 경우는 chainId 설정을 하지 않았는데( config 필드가 empty) 위와 같이 해결하였음.
잘 안되면 남들하는 버전을 보고 연관되어 돌아가는 버전을 모두 맞춰 시도해보는 것도 좋다.

참고
원격 접속용 geth 구동

$ nohup geth --networkid 4649 --nodiscover --maxpeers 0 --datadir ~/Blockchain/data_testnet --mine --minerthreads 1 --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --unlock 0,1 --password ~/Blockchain/data_testnet/passwd --verbosity 6 2>> ~/Blockchain/data_testnet/geth.log &

rpc ; http-rpc 활성화
rpcaddr : 접속 가능한 주소 0.0.0.0는 any 허용. 127.0.0.1을 입력하면 로컬호스트에서만 접속 가능. 자신의 IP 주소를 주면 그 IP로 접근이 허용된다.
rpcapi : rpc에서 허용가능한 모듈을 지정. 여기에 miner, personal 등이 들어가면 사용 가능.
unlock : 계정 잠금 해제. geth에서 해당 계정에 암호없이 접근 가능.

많이 쓰는 명령어

잔고 조회
eth.getBalance(eth.accounts[0])

전송 : 10이더를 해당 사용자에게 전송
personal.unlockAccount(eth.accounts[0])
패스워드(pass) 입력

eth.sendTransaction( {from: eth.accounts[0], 
   to:"0xc8cafbebb42f522f040d5690b1b220c3a9aed8f1", 
   value:web3.toWei(10,"ether")})

eth.getBalance("0xc8cafbebb42f522f040d5690b1b220c3a9aed8f1")

마이닝
eth.mining  : 현재 마이닝 상태
miner.start(1)
miner.stop()

계정
eth.accounts : 계정 목록 조회
personal.newAccount('password') : 계정 생성
personal.unlockAccount(eth.accounts[0]) : 잠금해제

SubLimeText 에서 solidity code intelligence 지원

Ctrl+Shift+P를 누르고 install 을 치고 install package 실행
잠시 기다리면, 입력창이 뜸.
ethereum을 입력. Ethereum을 설치
다시 한 번 반복하고 이번엔 EthereumSoliditySnippets를 설치
다시 시작하면 적용 완료.

강좌

https://www.ethereum.org/ko/developers/#%EC%8B%9C%EC%9E%91%ED%95%98%EB%A9%B4%EC%84%9C

https://solidity-kr.readthedocs.io/ko/latest/

https://winterj.me/smart-contract-with-python/

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#2 HelloWorld  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10

+ Recent posts