코어 이더리움 프로그래밍 - HiroSung/Study GitHub Wiki
[예제로 배우는 스마트컨트랙트 개발|http://www.etherstudy.net/bloter.html]
- 1234 네트웍에 Node 1개가 붙어 있는 것임.
- personal.newAccount() > Account 생성 (mist 화면에 생성된 계정 확인)
- miner.start() > Main Account의 이더 생성.
- miner.stop() > 이더 생성 종료.
- eth.accounts > Account 정보 조회
- miner > 함수 정보
- miner.setEtherbase("account_id") > 메인 Account를 변경함. (메인 Account의 pharase 잊어 벼렸을 경우 활용 가능)
- admin > enode 주소 알 수 있음.
- eth.blockNumber > 블럭의 개수를 알 수 있음
- enisis block이 같으면 됨. (gethinit.bat 파일)
- 노드를 하나 만들어서 같은 네트웍/제니시스블럭이 같고 ... 어택할 수 있음.
- admin > enode 주소를 보고
- admin.addPeer("enode정보") > 블록 reorg가 일어나면서 한쪽 정보가 사라짐.
- 명령어
- gethinit2 수행 > gethclient2 수행 > gethconsole2 수행
- Mist > 컨트랙트 선택 > 컨트랙트 추가 [솔리더티 컨트랙트 소스 코드] 부분에 코딩함
- Mist > 개발 > Rimix IDE 열고 > [소스다운로드]smartcontract 의 파일들을 연다
- 소스 내용
pragma solidity ^0.4.18;
contract GreeterV2 {
string hello = "Hello";
function sayHello() public view returns (string) {
return hello;
}
function changeHello(string _hello) external {
hello = _hello;
}
}
- pure 가 있는 함수는 Mist 왼쪽에 배치 (Tran이 아님)
- view는 Mist 오른쪽에 배치 (Tran 임) > 그래서 Sign을 해야함. 위의 hello(는 상태변수) Tran에 저장함. 로컬의 정보.
- external : 외부에서 호출시 사용
- private : 상속구조 아래에서 부를 수 있음.
- 모든 complex type은 datalocation 가짐. Gas 값이 다름.
- memory : 함수파라미터,반환값이 저장됨.
- storage : 상태변수는 Local var. storage(blockchain)에 저장됨.
- msg
- 이더리움은 대부분 ERC20 토큰임.
- 이더리움 에코 시스템에서 유동성있고 교환가능한 상품
- transfer : return type은 있지만 바로 오지 않음. miner가 채굴하고 채굴된 block이 전달되는 것임.
- log 영역에 출력할때 사용
- atribute : indexed
- 특정이벤트 모니터링으로 사용
> **eth.getTransaction**("0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485")
{
blockHash: "0x8217375939a8e58d69ba1c92646028e211a1414c16e26acabd774fa72d654ee6",
blockNumber: 792,
from: "0xac42827e828225db0544347d12319e101b041316",
gas: 121000,
gasPrice: 18000000000,
hash: "0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485",
input: "0x",
nonce: 9,
r: "0x85781116f7f15ea400c28c433dc2e7d2bb72903e3d074190f186d77c57ef67b8",
s: "0x399134737852efd2cedb82560c718e1642768c3f0d523fd7e18fe71af640c9e",
to: "0xe4c9884340e6273a6d9a51c7ef5aab91c1991914",
transactionIndex: 0,
v: "0x1b",
value: 2e+21
}
> **eth.getTransactionReceipt**("0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485")
{
blockHash: "0x8217375939a8e58d69ba1c92646028e211a1414c16e26acabd774fa72d654ee6",
blockNumber: 792,
contractAddress: null,
cumulativeGasUsed: 21000,
from: "0xac42827e828225db0544347d12319e101b041316",
gasUsed: 21000,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000",
status: "0x1",
to: "0xe4c9884340e6273a6d9a51c7ef5aab91c1991914",
transactionHash: "0x5680e93d87b6c98d0f3d8369b9139e2de11585949672c1e61e0c5014fbe6a485",
transactionIndex: 0
}
- Decimals 처리 확인 (1000을 입력하고, decimal을 1 입력하면 Total Token은 100,0 으로 표현됨)
- ERC20 Token Standard
# 아래와 같은 I/F 구현해주면 거래소와 동일하게 처리 가능함.
# 토큰간의 거래가 용이함
contract ERC20 {
function totalSupply() constant returns (uint totalSupply);
function balanceOf(address _owner) constant returns (uint balance);
function transfer(address _to, uint _value) returns (bool success);
function transferFrom(address _from, address _to, uint _value) returns (bool success); > 전송
function approve(address _spender, uint _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint remaining); > 전송할 수 있는 권한이 있는지 여부
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
https
- 이더를 투자하면, 토큰을 리워드 하게 함.
- 콘트랙과 토큰이 필요 함.
- CrowdFund.sol
pragma solidity ^0.4.16;
interface token {
function transfer(address receiver, uint amount) external;
}
contract CrowdFund {
address public beneficiary;
uint public fundingGoal;
uint public amountRaised; > 현재까지 모인 이더
uint public deadline;
uint public price; > 리워드 비율. 대부분의 ICO들이 이렇게 처리 함.
token public tokenReward; > 이미 만들어진 contract를 쓰겠다.
mapping(address => uint256) public balanceOf; > 장부
bool public fundingGoalReached = false;
bool public crowdsaleClosed = false;
event GoalReached(address beneficiaryAddress, uint amountRaisedValue);
event FundTransfer(address backer, uint amount, bool isContribution);
function CrowdFund( > 생성자.
address ifSuccessfulSendTo,
uint fundingGoalInEthers, > 100이면. * 1 Eth (100* 100의 18승)
uint durationInMinutes,
uint etherCostOfEachToken,
address addressOfTokenUsedAsReward
) public {
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes; > now 블럭생성타임.
price = etherCostOfEachToken * 1 ether; > 비율
tokenReward = token(addressOfTokenUsedAsReward); > contrat 주소. 주소에 토큰을 전달함
}
function () payable external {
require(!crowdsaleClosed);
uint amount = msg.value;
balanceOf[msg.sender] += amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price); > 메시지콜. 컨트랙트에서 해당 토큰으로 보내려고 할때 보래려고 함. FAIL! 이 수행됨.
emit FundTransfer(msg.sender, amount, true);
}
modifier afterDeadline() {
if (now >= deadline)
_; > 원래함수의 내용을 넣어서 컴파일 하게 됨.
}
function checkGoalReached() external afterDeadline {
if (amountRaised >= fundingGoal){
fundingGoalReached = true;
emit GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
function safeWithdrawal() external afterDeadline {
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
emit FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
emit FundTransfer(beneficiary, amountRaised, false);
} else {
fundingGoalReached = false;
}
}
}
}
- 51% 공격을 위한 조건
- 두 노드이 genesis 블록이 동일해야 함.
- 동일한 genesis.json을 이용해서 genesis 블록을 초기화해야 (% geth --datadir test-data init genesis.json)
- stack 사이즈가 있음.
- Crowd Func 컨트랙트에 이더 전송
- 중복코드를 관리하는 방법
- Address
- transfer 함수가 없는 상태에서 송금이 안되므로, 컨트랙트에서 payable이 있는 함수로 선택하여 송금해야 함.
- call function
- 토큰을 처리 하지 못하는 컨트랙은 입금을 못받도록 제한처리함.
- ERC721 : 캐릭터 처리
- https://etherscan.io
Mist Install
- https://github.com/ethereum/mist/releases (또는 ethereum mist로 검색) 접속해서 Mist-installer-0-11-0.exe 다운로드
블로터
1일차 : 하루만에 끝내는 이더리움 이론 세션1. 코어 이더리움 이론 PDF 세션2. 예제로 배우는 스마트컨트랙트 개발 실습준비 PDF - Window용 스크립트 다운로드 - 맥 OSX용 전체 다운로드 - Window용 전체 다운로드 2일차 : ICO 하루만에 끝내기 세션3. ERC20 토큰 개발 (2시간) 세션4. First DApp 실습 (1시간) 실습하기 세션5. Geth 실습 - 프라이빗 네트워크 구축 (1시간) PDF 실습하기 세션6. DApp 실습 - 클라우드펀딩 개발 (2시간) PDF Github 세션7. P2P 파일 시스템 - IPFS (1시간) PDF * (참고) 맥/윈도우 64bit가 아닌 경우 1.Mist 설치 : 바로가기 2.Geth 설치 : 바로가기 3.IPFS 설치 : 바로가기 4.Node 설치 : 바로가기