728x90

https://cryptozombies.io/ko/lesson

 

#1 Solidity Tutorial & Ethereum Blockchain Programming Course | CryptoZombies

CryptoZombies is The Most Popular, Interactive Solidity Tutorial That Will Help You Learn Blockchain Programming on Ethereum by Building Your Own Fun Game with Zombies — Master Blockchain Development with Web3, Infura, Metamask & Ethereum Smart Contracts

cryptozombies.io

내가 볼라고 적는거임

다들 클립토좀비 들어가서 공부해

 

레슨 1의

챕터 2: 컨트랙트

 

솔리디티 코드는 컨트랙트안에 싸여있음

 

솔리디티 소스 코드는 

버전선언으로 시작해야함!

 

pragma solidity ^0.4.19; //1. 여기에 솔리디티 버전 적기

//2. 여기에 컨트랙트 생성
contract ZombieFactory{
    
}

 

컨트랙트를 위한 뼈대 갖추기 완성!

 

챕터 3: 상태 변수 & 정수

상태변수는 컨트랙트 저장소에 영구적으로 저장돼!

즉 이더리움 블록체인에 기록된다는 것.

 

contract Example {
//이 변수가 블록체인에 영구적으로 저장됨
uint myUnsignedUnteger = 100;
}

 

챕터 4: 수학 연산

  • 덧셈: x + y
  • 뺄셈: x - y,
  • 곱셈: x * y
  • 나눗셈: x / y
  • 모듈로 / 나머지: x % y (이를테면, 13 % 5는 3이다. 왜냐면 13을 5로 나누면 나머지가 3이기 때문이다)

솔리디티는 지수 연산도 지원하지 (즉, "x의 y승", x^y이지):

uint x = 5 ** 2; // 즉, 5^2 = 25

챕터 5: 구조체

복잡한 자료형을 필요로 할 때 솔리디티로는 구조체를 쓰면 됨

struct Person {
uint age;
string name;
}

구조체를 통해 여러 특성가진 보다 복잡한 자료형을 생성할 수 있지.

 

 

컨트랙트 안에 구조체 있는 모습

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

}

챕터 6: 배열

어떤 것의 모음집이 필요할 때 

배열을 사용할 수 있지

 

솔리디티에도 정적배열, 동적배열  두 종류배열 있어. 

//2개의 원소를 담을 수 있는 고정길이의 배열;
uint[2] fixedArray;

//고정길이의 배열, 5개의 스트링을 담을 수 있다.
string[5] stringArray;

//동적배열은 고정된 크기가 없으며 계속 크기가 커질 수 있다.
uint[] dynamicArray;

 

구조체의 배열을 생성할 수 있다!

아까 우리가 sturct Person {uint age; string name;} 이렇게 만들었던 구조체를 이용하면 

Person[] people; // 이는 동적 배열로, 원소를 계속 추가할 수 있다.

상태변수가 블록체인에 영구적으로 저장할 수 있는 것처럼 구조체의 동적배열을 생성하면 

마치 데이터베이스처럼 컨트랙트에 구조화된 데이터를 저장하는데 유용하다. 

 

Public 배열

public으로 배열을 선언할 수 있음 솔리디티는 이런 배열을 위해 getter메소드를 자동적으로 생성한다. 

Person[] public people;

다른 컨트랙트들은 이 배열을 읽을 수는 있게되지만 쓸 수는 없다.

이는 컨트랙트에 공개데이터를 저장할 때 유용한 패턴이다.

 

 

 

 

지금까지 한 코드

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    // 좀비들을 다른 앱에 자랑하고 싶어서 좀비 군대 저장소를public으로 함.
    //Zombie구조체의 public배열을 생성하고 이름을 zombies로 한다.


    Zombie[] public zombies;

}

 

챕터 7: 함수 선언

솔리디티에서 함수 선언

function eatHam(string _name, uint _amount){
}

(함수의 인자명을 _로 시작하는 건 전역변수랑 구별하려고 하는 관례때문임~)

 

이 함수를 오출 할때는 이렇게 할 수 있겠지

eatHam("jun",100);

챕터 8: 구조체와 배열 활용하기

새로운 구조체를 생성하기 

 

전에 만들어 놓은 Person구조체를 사용할거야.

//구조체 Person 틀
struct Person {
  uint age;
  string name;
}
//Person배열을 peole로 이름지음
Person[] public people;

그 틀로 새로운 Person satoshi을 찍어낼거야. 

//Person틀쓸거고 변수명은 satoshi임  // age, name
Person satoshi = Person(172,"Satoshi");
//people배열에 이 사람을 추가한다.
peole.push(satoshi);

이 두 줄을 한 줄로 표현하면 이거임

people.push(Person(16,"Jun"));

 

 

챕터 9: Private / Public 함수

솔리디티에서 함수는 기본적으로 public으로 선언된다. 

누구나 또는 다른 어느 컨트랙트가 우리의 컨트랙트의 함수를 호출하고 코드를 실행할 수 있다는 의미다.

하지만 이건 공격에 취약해질 수 있는 가능성이 있어서 

기본적으로 함수는 private로 선언하고 공개할 함수만 public으로 선언하는 게 좋다

 

private함수를 선언하는 방법

unit[] numbers;
function _addToArray(uint _number) private {
numbers.push(_number);
}

private는 컨트랙트 내의 다른 함수들만이 이 함수를 호출해서 numbers 배열로 무언가를 추가할 수 있다걸 의미.

함수 인자명과 마찬가지로 private함수명도 언더바_로 시작하는 것이 관례임.

 

 

챕터 10: 함수 더 알아보기

함수의 반환값, 함수의 제어자

 

반환값

함수에서 어떤 값을 반환받으려면 다음과같이 선언해야함.

 

string greeting = "what's up dog";
function sayHello() public returns (string) {
//솔리디티에서 함수 선언은 반환값 종류를 포함한다. 지금은 string이야. 
return greeting;
}

함수제어자

위에 함수는 솔리디티에서 어떤값을 변경하거나 무언가를 쓰는등 상태를 변화시키지 않는다. 

이렇게 함수가 데이터를 보기만 하고 변경하지 않는 건 view함수로 선언한다.

function sayHello() public view returns (string) {
}

 

728x90
728x90

https://github.com/jsoyun/naivecoin-chapter6.git

 

GitHub - jsoyun/naivecoin-chapter6

Contribute to jsoyun/naivecoin-chapter6 development by creating an account on GitHub.

github.com

순서는 이렇게 됨

1. 채굴을 해서 coinbase를 만들어 보상금 50받아 (잔고balance에 50쌓이는 걸 볼 수 있음)

2. 보낼 금액 양  /  보낼 지갑 주소 

적어서 sendTx 트랜잭션풀에 보낸다.

3. 채굴 누르면 트랜잭션풀에 있던 애들을 블록으로 넣어줌 채굴됨 (이때도 채굴한 사람은 보상금 50받을거임)

4. 난이도 올라가는 걸 보려면  (코드에서 넣어놓은 이전에 만들어진 블록과 최신블록 차이많이나면 안되는 제한 걸어놔서 서버 다시 돌리고 하는 게 좋음)

10이상 채굴했을 때 난이도 올라가고 넌스도 올라가는 걸 볼 수 있음

 

노드를 하나만 해서 보내는 테스트할 때는

공개키 지갑주소 04~ 에 숫자만 바꿔서 해봤음.

 

내 지갑 주소고.

 

 

현재 잔고는 0

거래하게 코인베이스 채굴할게

처음 제네시스 블록, 그리고 그다음에 코인베이스 50담겨서 들어옴.

잔고 눌렀을 때도 보임

 

 

 

이제 보낼 금액이랑 보낼 주소 해서 

트랜잭션 풀에 넣어보겠음 

트랜잭션 풀을 보면(얘는 시각화안함...json형태로 띄워져있음) 잘들어온게 보임

그럼 이제 채굴을 눌러서 block에 넣고 화면에 띄우면

트랜잭션이 블록에 들어간걸 볼 수 있음

 

 

 

그리고 잔고를 확인했을 때도 채굴을 한번더 해서 보상받아서 100으로 늘어난걸 볼 수 있음

 

 

사실 지금까지는 보내는 주소를 그냥 자기 자신한테 해서 효과없는거라 채굴해서 보상받은 금액만 올라갔는데

주소를 해시값 갯수 지키고 앞에 04 지킨 상태에서 숫자만 하나 바꿔서 보내봄

 

99를 다른 노드에 보내고 

채굴해서 

잔돈 1에 50 생겨서 51됨

 

 

 

728x90
728x90

 


 


 

728x90
728x90

값이 undefined라서 찾을 수 없을 때 많이 뜸

값이 타입이 달라서 가져올 수 없다거나.

배열이라서 가져올라면 map함수를 써야한다거나

[]를 묶어줘야하거나 빼줘야하거나. 등의 이유..

 

 

 

 

나는 기존의 server갈아엎고 naivecoin6의 서버 코드를 쓰고 있어서 

block header없고 block만 있어서 a.header.index가 인식 못하는 것!

 

 

 

이렇게 해서 블록의 정보들은 뜨게 되었는데

 

 

트랜잭션은 안보임

 

 

 

블록체인 구조를 보면 

설명해준 학우분 짱.

이렇게 생겼단 말임

그래서 data부터는 배열로 안에 들어간 값이라 보여줄라면 map함수를 써야함!

채굴된 Block으로 보면 이러함.

 

 

 

 

 

해결한 코드

  {chainBlocks &&
        chainBlocks.map((a) => (
          <div style={marginBottom} key={a.index}>
            {/* <div>바디 : {a.body}</div> */}
            {a.data.map((b) => (
              <>
                <div>txId : {b.id}</div>

                {b.txIns.map((c) => (
                  <>
                    <div>signature : {c.signature}</div>
                    <div>txOutId: {c.txOutId}</div>
                    <div>txOutIndex: {c.txOutIndex}</div>
                  </>
                ))}
                {b.txOuts.map((c) => (
                  <>
                    <div>address : {c.address}</div>
                    <div>amount: {c.amount}</div>
                  </>
                ))}
              </>
            ))}

            <div>인덱스 : {a.index}</div>
            <div>넌스 : {a.nonce}</div>
            {/* <div>버전 : {a.version}</div> */}
            <div>시간 : {a.timestamp}</div>
            <div>난이도 : {a.difficulty}</div>
            {/* <div>머클 루트 : {a.merkleRoot}</div> */}
            <div>이전 해쉬 : {a.previousHash}</div>
          </div>
        ))}

728x90
728x90

cors에러 경우

CORS(Cross-Origin Resource Sharing)

자기가 속하지 않은 포트로 정보 보내려고 할 때 주소가 달라서 보안상 안된다고 하는것

 

얘는 별도처리 없이
모두에게 허용하는 방법임!!

const cors = require("cors");

하고 

구동되는 함수에 

app.use(cors());

이렇게 하면 해결된다. 

 

 

 

 

특정 도메인에만 허용하고 싶으면 변수에 특정 도메인 주소만 넣으면 됨.

let corsOptions = {
    origin: 'https://www.domain.com',
    credentials: true
}

app.use(cors(corsOptions));

 

 

 

 

 

 


 

특정 도메인을 허용할 때 사용!

Access-Control-Allow-Origin response 헤더를 추가하는 방법도 있음.

app.get('/', (req,res) => {
  res.header("Access-Control-Allow-Origin", "*");
  ...
}

 

미들웨어 서버 이용하기
proxy


proxy를 쓰는 경우 밑에 유튜브 영상처럼

/api 설정을 해줘야함.!

 

client에 

setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:3001',
      changeOrigin: true
    })
  );
};

서버

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

출처:

https://surprisecomputer.tistory.com/32

 

[Node.js] express cors 사용하기

1. 서론 리버스 프록시 서버로 NGINX를 두고 한 워크스테이션에서 Swagger와 node.js 서버를 함께 구동한 적이 있다. Swagger의 포트를 8085로 지정하고 node.js 서버는 443번으로 지정했는 데, CORS 에러가 발

surprisecomputer.tistory.com

https://firework-ham.tistory.com/70

 

 

 

https://www.youtube.com/watch?v=BHSJw8PDwj0&list=PL9a7QRYt5fqkZC9jc7jntD1WuAogjo_9T&index=22 

 

728x90
728x90

스마트컨트랙트

 

 

객체지향언어의 class와 비슷하다

 

멤버 필드하나

생성자 하나

단일 클래스 만들어서 샐행하고 사용해보자

 

 

코드자동 컴파일

 

 

 

 

pragma solidity ^0.4.0;
contract SimpleCoin {
    //멤버 필드
    //public int num
    //map 변수 타입
    mapping (address => uint256) public coinBalance ;
    //mapping(string => addresss) public tenDatabase;
   // 생성자

    constructor() public {
        coinBalance
        [msg.sender] = 10000; //멤버필드 초기화
    }

    //메서드
    //해당주소에 얼마만큼 보내겟다
    function transfer(address _to, uint256 _amount) public {
        coinBalance[msg.sender] -= _amount;
        coinBalance[_to] += _amount;
    }
}

 

 


좀비 클립토에 있던 내용

솔리디티는 지수 연산도 지원하지 (즉, "x의 y승", x^y이지):

uint x = 5 ** 2; // 즉, 5^2 = 25

 

 

 

728x90

+ Recent posts