Solidity Tutorial : 초보자를위한 Solidity 프로그래밍 소개

Solidity 튜토리얼

Solidity는 이더 리움 블록 체인에서 dApp (분산 애플리케이션)을 개발하기위한 객체 지향 고수준 언어입니다..

블록 체인은 네트워크의 모든 데이터와 코드를 공유하는 노드라고하는 컴퓨터의 피어-투-피어 네트워크입니다..

따라서 블록 체인에 연결된 장치 인 경우 네트워크의 노드이고 네트워크의 다른 모든 컴퓨터 노드와 대화합니다 (이후 자습서에서 로컬 컴퓨터에 이더 리움 노드를 설정하는 방법에 대해 설명합니다)..

이제 블록 체인에 모든 데이터와 코드의 사본이 있습니다. 더 이상 중앙 서버가 필요하지 않습니다..

이더 리움이란??

가장 간단하게 말하면 Ethereum은 개발자가 분산 애플리케이션을 구축하고 배포 할 수 있도록하는 블록 체인 기술을 기반으로하는 개방형 소프트웨어 플랫폼입니다..

비트 코인 블록 체인이 디지털 통화 (비트 코인)의 소유권을 추적하는 데 사용되는 반면, 이더 리움 블록 체인은 분산 애플리케이션의 코드 실행에 중점을 둡니다..

이더 리움 블록 체인에서 채굴 자들은 비트 코인 채굴 대신 네트워크에 연료를 공급하는 암호화 토큰 유형 인 이더를 얻기 위해 노력합니다. 거래 가능한 암호 화폐 외에도 이더는 애플리케이션 개발자가 이더 리움 네트워크에서 거래 수수료 및 서비스 비용을 지불하는 데 사용됩니다..

블록에 거래를 포함하기 위해 채굴 자 수수료를 지불하는 데 사용되는 두 번째 유형의 토큰이 있는데,이를 가스라고하며, 모든 스마트 계약 실행에는 채굴자가 그것을 넣도록 유도하기 위해 일정량의 가스가 함께 전송되어야합니다. 블록 체인.

기본부터 시작

Solidity의 코드는 계약에 캡슐화됩니다..

이더 리움 블록 체인을 사용하면 스마트 계약이라는 것을 통해 블록 체인에서 Ethereum Virtual Machine (EVM)으로 코드를 실행할 수 있습니다..

스마트 계약은 애플리케이션의 모든 비즈니스 로직이있는 곳입니다. 모든 변수와 기능은 계약에 속하며 모든 프로젝트의 시작점이됩니다..

스마트 연락처는 Javascript와 C가 혼합 된 것처럼 보이는 Solidity라는 프로그래밍 언어로 작성됩니다..

IDE 리믹스

Remix는 Solidity 스마트 계약을 작성한 다음 배포하고 실행할 수있는 온라인 도구입니다..

그냥 이동 https://remix.ethereum.org 브라우저에서 코딩을 시작할 수 있습니다..

보시다시피 Solidity와 Vyper 중에서 선택할 수 있습니다. 둘 다 스마트 계약을 작성하기위한 언어이며, Vyper는 파이썬과 비슷하고 Solidity는 자바 스크립트와 유사합니다..

둘 다 Javascript 및 Typescript와 같은 EVM 바이트 코드로 컴파일 할 수 있습니다. 우리는 Solidity를 선택합니다.

왼쪽에는 파일 탐색기가 있습니다. 기본적으로 기본 구문을 데모하기위한 두 개의 .sol 파일이 있습니다 (ballot.sol은 스마트 계약이고 ballot_test.sol은 해당 스마트 계약을 테스트하기위한 스크립트입니다)..

더하기 버튼을 클릭하기 만하면 첫 번째 스마트 계약 코딩을 시작할 수 있습니다..

모든 solidity 소스 코드는 “version pragma”로 시작해야합니다.이 코드는이 코드에서 사용해야하는 Solidity 컴파일러 버전 선언입니다. 이는 코드를 손상시킬 수있는 변경 사항을 잠재적으로 도입하는 향후 컴파일러 버전의 문제를 방지하기위한 것입니다..

다음과 같이 보입니다.

pragma 견고성 ^ 0.4.25;

(0.4.25 이상의 Solidity 버전의 경우)

또는

프라 그마 견고 함 >= 0.5.0 < 0.6.0;

(0.5.0에서 0.6.0 사이의 Solidity 버전의 경우)

그런 다음 예약어를 입력하여 계약을 작성합니다. 계약 .sol 파일의 이름 (계약 이름과 파일 이름이 일치하는 것이 중요합니다. 이유는 나중에 설명하겠습니다). 우리의 경우,

contract MyFirstContract {

}

컴파일 해 봅시다. 왼쪽에있는 컴파일 탭으로 이동하여 큰 컴파일 버튼을 클릭하기 만하면됩니다. 코드에 문제가있는 경우 여기에 오류와 경고가 표시됩니다 (Solidity에 동정심을 나타내십시오. 여전히 “젊은 언어”임).

현재 계약으로는 아무 일도하지 않았기 때문에 모든 것이 괜찮습니다..

이제 여러분에게 무언가를 보여주기 위해 의도적으로 오류를 생성하겠습니다. 드롭 다운 메뉴에서 컴파일러를 수동으로 선택할 수 있습니다..

예를 들어 0.4.26 버전을 선택하겠습니다. 이제 다시 컴파일하십시오. 이제 ‘Compiler not yet loaded’오류가 표시됩니다..

이는 0.5.0 이상의 컴파일러 버전에서 작동하도록 pragma로 지정했기 때문입니다. 컴파일러 버전을 다시 변경하면 오류가 사라집니다..

좋습니다. 이제 코딩 해 보겠습니다.!

간단한 ‘Hello world’코드로 시작하여 구문에 익숙해 지도록 함수를 가져오고 설정합니다..

Solidity의 의미에서 계약은 이더 리움 블록 체인의 특정 주소에 상주하는 코드 (기능) 및 데이터 (상태)의 모음입니다..

먼저, 예를 들어 메시지라는 상태 변수를 정의 해 봅시다. 유형은 문자열이됩니다..

get 함수는 변수 메시지의 값을 반환하고 set 함수는 변수 메시지에 새 값을 할당합니다..

함수 입력 방법?

첫째, 예약어 함수 그런 다음 특정 기능 및 매개 변수의 이름과 그 뒤에 .

function myFunction () returns (bool) {

true를 반환하십시오.

}

기능은 공공의 또는 은밀한. 함수가 공용이면 계약 외부에서 호출 할 수 있습니다. 함수가 비공개 인 경우 범위가 제한되어 있으며 현재 계약에서만 호출 할 수 있습니다 (예 : 다른 함수에서)..

다음은 모든 기능 가시성 지정자 목록입니다.

  • 공공의: 외부 및 내부에서 볼 수 있음 (저장 / 상태 변수에 대한 getter 함수 생성)
  • 은밀한: 현재 계약에서만 볼 수 있습니다.
  • 외부: 외부에서만 볼 수 있습니다 (함수에만 해당) – 즉, this.func를 통해 메시지 호출 만 가능합니다.
  • 내부의: 내부적으로 만 표시

기능은 순수한, 전망, 또는 지불 가능. 함수가 블록 체인에 데이터를 쓰지 않는 경우보기 기능에 가스 비용이 들지 않기 때문에보기를 권장합니다..

다음은 모든 함수 수정 자 목록입니다 (상태 변수, 이벤트 및 이벤트 인수에 대한 수정 자도 있지만 나중에 설명합니다).

  • 순수한: 상태 수정 또는 액세스를 허용하지 않습니다..
  • 전망: 상태 수정 금지.
  • 지불 가능: 통화와 함께 Ether 수신 가능.

함수가 어떤 값을 반환하면 예약어로 지정해야합니다. 보고 그런 다음 일반 괄호 안에 함수가 반환하는 유형을 지정합니다. 우리의 경우에는 문자열이 될 것입니다 (문자열 인 변수 메시지를 반환하기 때문입니다)

함수가 값을 반환하지 않으면 보고 성명서.

상태 변수에 액세스하려면 접두사가 필요하지 않습니다. 이. 다른 언어에서 흔히 볼 수 있듯이.

따라서 일반적인 방법은 밑줄 구문으로 함수 인수를 작성하는 것입니다. (_메시지). 이 규칙은 자바 스크립트에서 비롯되었으며 비공개 메소드와 변수는 _로 시작합니다..

명확하게 말하면 코드는 밑줄없이 잘 작동하지만 더 깔끔합니다..

예약어를 알 수 있습니다. 기억 우리 코드에서. 메모리없이 코드를 작성하고 pragma를 0.5. * 미만의 일부 버전으로 설정하면 정상적으로 작동하지만 컴파일러를 0.5 이상으로 변경하면 EVM이 컴파일 오류를 생성합니다..

왜 이런 일이 발생합니까??

Ethereum Virtual Machine에는 항목을 저장할 수있는 세 가지 영역이 있습니다..

  • 첫 번째는 저장, 모든 계약 상태 변수가있는 곳. 모든 계약에는 자체 저장소가 있으며 함수 호출 사이에 지속적이며 사용 비용이 많이 듭니다..
  • 두 번째는 기억, 임시 값을 유지하는 데 사용됩니다. (외부) 함수 호출 사이에 지워지고 사용 비용이 저렴합니다..
  • 세 번째는 스택, 작은 지역 변수를 보유하는 데 사용됩니다. 거의 무료로 사용할 수 있지만 제한된 값만 보유 할 수 있습니다..

거의 모든 유형의 경우 사용할 때마다 복사되기 때문에 저장 위치를 ​​지정할 수 없습니다..

그러나 배열 또는 구조체로 작업 할 때, 그리고 문자열이있는 최신 버전에서도 컴파일러는 저장 영역을 지정하도록 강제합니다..

따라서 이제 코드는 다음과 같습니다.

pragma 견고성 ^ 0.5.0;

contract MyFirstContract {

문자열 메시지;

function get () public view returns (string memory) {

반환 메시지;

}

function set (string memory _message) public {

메시지 = _message;

}

}

일부 Solidity 개발자는 코드를 깔끔하게 만들기 위해 가시성 지정자를 별도의 줄로 나눕니다. 따라서 get 함수는 다음과 같이 작성할 수 있습니다.

함수 get ()

공공의

전망

반환 (문자열)

{

반환 메시지;

}

함수를 작성하는 방법은 사용자에게 달려 있습니다..

이제 계약을 컴파일하고 테스트 해 보겠습니다..

컴파일하려면 아래 단계를 반복하십시오 (.sol 컴파일 버튼 또는 cmd / ctrl + S 키보드에서 자동으로 다시 컴파일됩니다)

실제로 어떻게 작동하는지 확인하려면 (컴파일이 오류를 생성하지 않는 경우) 계약을 배포해야합니다..

이를 위해 왼쪽에서 배포 탭으로 이동하고 환경에 대해 JavaScriptVM을 선택하고 배포 버튼을 누릅니다..

배포 후 이제 계약에서 메서드를 볼 수 있습니다. 이제 화면의 해당 부분에만 집중하겠습니다..

두 개의 버튼이 있음을 알 수 있습니다 (get & set) 두 가지 공용 기능에 대해 그중 하나라도 비공개라면 여기에서 볼 수 없습니다..

get 버튼을 클릭하면 EVM이 get 함수를 실행합니다..

어떻게 작동하는지 보자.

빈 문자열이 있습니다. 위대하지도 끔찍하지도 않습니다. 하지만 왜? 처음에는 메시지 변수를 초기화하지 않았기 때문에.

한 번만 잠시 멈 춥니 다. 리믹스 터미널을 소개합니다. 코드 편집기 아래에 있으며 여기에서 모든 트랜잭션을 추적하고, 성공적으로 실행되었는지 확인하고, 디버그하고, 세부 정보 (트랜잭션 해시 등)를 볼 수 있습니다..

지금은 두 번의 성공적인 거래가 있습니다. 하나는 Contract Deployment이고 비용이 많이 들지만 걱정하지 마세요. 이제 모든 것이 가상 편집자에 있습니다. 두 번째는 Call of our 전망 함수.

좋습니다. 이제 돌아가겠습니다. 지금 set 함수를 호출하면 어떻게 될까요??

인수 _message (예 : “Hello World”)를 전달하고 트랜잭션 버튼을 눌러 기능을 실행해야합니다. 터미널에서 거래 성공을 추적 할 수 있습니다..

이제 다시 get 함수를 호출하겠습니다. 이제 우리의 메시지를 반환합니다..

코드를 약간 개선해 보겠습니다. 변수 메시지를 초기화하지 않았습니다. 해보자.

contract MyFirstContract {

문자열 메시지 = "안녕하세요 세상!";

function get () public view returns (string memory) {

반환 메시지;

}

function set (string memory _message) public {

메시지 = _message;

}

}

메시지는 이제 “Hello world!”이며 처음으로 get 함수를 호출 할 때 빈 문자열을 반환하지 않습니다..

이를 테스트하려면 컨트랙트 (cmd / ctrl + S)를 컴파일해야합니다..

그런 다음 다시 배포합니다. (변경 사항으로 인해) 새로운 계약 인스턴스를 생성하고이를 블록 체인에 게시해야합니다..

(물론 가상 블록 체인이 아닌) 편집기에서 이전 버전을 삭제하고 배포 버튼을 다시 누르십시오. 이제 get 함수를 호출하겠습니다..

좋은! 이제 set 함수를 호출하겠습니다..

그리고 다시.

멋있는.

이제 우리의 메시지를 일정한.

이제 코드 :

pragma 견고성 ^ 0.5.0;

contract MyFirstContract {

문자열 상수 메시지 = "안녕하세요 세상!";

function get () public view returns (string memory) {

반환 메시지;

}

function set (string memory _message) public {

메시지 = _message;

}

}

컴파일하려고하면 set 함수에 오류가 발생합니다. 상수 값을 변경할 수 없기 때문입니다..

이제 그 상수를 제거하겠습니다..

이와 같은 변수를 초기화하는 것은 오류가 아니지만 생성자에서 수행하는 것이 훨씬 좋습니다. Solidity에서 다음을 사용하여 생성자를 작성할 수 있습니다.

constructor () public {

// 뭔가를하세요…

}

생성자는 스마트 계약을 배포하는 동안 호출되는 또 다른 기능입니다. 코드는 약간 다르게 보이지만 동일하게 작동합니다..

pragma 견고성 ^ 0.5.0;

contract MyFirstContract {

문자열 메시지;

constructor () public {

메시지 = "안녕하세요 세상!";

}

function get () public view returns (string memory) {

반환 메시지;

}

function set (string memory _message) public {

메시지 = _message;

}

}

다시 컴파일하고 원하는 경우 테스트 할 수 있습니다..

마지막으로 상태 변수의 가시성을 변경할 수 있습니다. 상태 변수를 만들면 공공의 즉, 계약 외부에서 가치를 주장 할 수 있습니다..

Solidity는 각 공용 상태 변수에 대해 동일한 이름을 가진 메서드를 만들어 일반 함수로 호출 할 수 있습니다 (getter 함수와 유사 함)..

즉, get 함수를 제거하고 변수 메시지를 다음과 같이 선언하면됩니다. 공공의, 그리고 우리의 코드는 동일하게 작동 할 것이고 훨씬 더 깨끗해질 것이며 하루에 메인 네트워크에 배포하는 데 드는 비용이 더 적게들 것입니다..

코드가 클수록 실행하는 데 더 많은 가스가 필요하고 dApp 실행 비용이 증가합니다..

스마트 계약을 개발할 때 우리는 다음과 같아야합니다.

  • 실력 있는 – 소비되는 가스 율은 낮아야합니다.
  • 정확한 – 일단 스마트 계약을 배포하면 변경할 수 없으며 모든 코드 줄이 24 시간 연중 무휴 공개됩니다 (버그를 발견하고 dApp을 악용 할 수있는 해커를 상상해보십시오)

오늘의 최종 코드는 다음과 같습니다.

pragma 견고성 ^ 0.5.0;

contract MyFirstContract {

문자열 공개 메시지;

constructor () public {

메시지 = "안녕하세요 세상!";

}

function set (string memory _message) public {

메시지 = _message;

}

}

배포하고 테스트 해 보겠습니다..

그 메시지 버튼을 볼 수 있습니다. 상태 변수 메시지가 공개이기 때문에 생성되고 있습니다..

이것을 호출하면 생성자를 통해 초기화되는 값을 반환해야합니다 (즉, “Hello world!”)..

좋은. 지금 테스트 세트 기능.

솔리 디티를 배우는 방법?

솔리 디티 자체는 매우 간단한 언어이지만 훌륭한 솔리 디티 개발자가 되려면 모든 것이 이더 리움에서 어떻게 작동하는지 이해해야합니다..

  • Solidity는 ECMAScript (javascript)와 유사한 구문을 가진 고급 프로그래밍 언어입니다..
  • EVM 바이트 코드로 컴파일됩니다. EVM만이 이해할 수있는 것.
  • 컴파일러는 Solc라고합니다..

이 간단한 계약을 예로 들어 보겠습니다.

pragma 견고성 ^ 0.5.0;

계약 예 {

단위 a = 10 + 5;

}

그렇게 간단합니다. 이제 컴파일 해 보겠습니다. 터미널에서 Contract Details로 가면 많은 정보를 볼 수 있습니다.

이 경우 컴파일 된 코드는 다음과 같습니다.

0x6080604052600f600055348015601457600080fd5b5060358060226000396000f3fe6080604052600080fdfea165627a7a72305820bf75c57b7d8745a79baee513ead21a9eb8b075896f8e4c591c8916574d317c750029

이러한 긴 값은 바이트 코드라고도하는 최종 계약의 16 진수 표현입니다. EVM은 바이트 코드 만 이해합니다..

그러나 무언가 잘못되면 예를 들어 바이트 코드를 디버깅 할 수없는 오류가 발생합니다..

Opcode

바이트 코드 위의 언어는 opcode입니다. Opcode는 저수준 프로그래밍 언어입니다. Solidity 및 Opcode는 예를 들어 C 및 어셈블리 언어와 같습니다..

따라서 실패한 트랜잭션을 디버깅해야 할 때 opcode를 디버깅합니다..

Solidity와 디버깅에 대해 알아야 할 한 가지는 매우 어렵습니다. 하지만 불가능하지는 않습니다..

이것은 예제 계약의 opcode입니다.

0 푸시 1 60

02 PUSH1 40

04 엠 스토어

05 PUSH1 0f

07 PUSH1 00

09 SSTORE

10 CALLVALUE

11 DUP1

12 ISZERO

13 PUSH1 14

15 점피

16 PUSH1 00

18 DUP1

19 리버 트

20 점포

21 팝

22 PUSH1 35

24 DUP1

25 PUSH1 22

27 PUSH1 00

29 복사

30 PUSH1 00

32 반환

33 유효하지 않음

34 PUSH1 80

36 PUSH1 40

38 엠 스토어

39 PUSH1 00

41 DUP1

42 REVERT

43 유효하지 않음

44 로그 1

45 PUSH6 627a7a723058

52 SHA3

53 유효하지 않음

54 PUSH22 c57b7d8745a79baee513ead21a9eb8b075896f8e4c59

77 유효하지 않음

78 DUP10

79 회

80 점피

81 유효하지 않음

82 밸런스

83 PUSH29 750029

Opcode는 사람이 읽을 수있는 낮은 수준의 프로그램 명령입니다. 모든 opcode에는 16 진수 대응 코드가 있습니다. MSTORE 이다 0x52.

EVM은 스택 머신입니다. LIFO 구조 (Last In First Out)를 기반으로합니다. 간단히 말해서, 전자 레인지에 빵 조각을 쌓는다고 상상해보십시오. 마지막에 넣은 조각이 가장 먼저 꺼낸 조각입니다..

일반 산술에서는 다음과 같이 방정식을 작성합니다.

10 + 2 * 2

답은 14입니다. 더하기 전에 곱하기를하기 때문입니다..

스택 머신에서는 LIFO 원리로 작동합니다.

2 2 * 10 +

즉, 스택에 먼저 2를 넣은 다음 다른 2를 넣은 다음 곱셈 작업을 수행합니다. 결과는 스택 맨 위에 4가 있습니다. 이제 4 위에 10을 더하고 결국 2 개의 숫자를 더합니다. 스택의 최종 값은 14가됩니다..

스택에 데이터를 넣는 행위를 PUSH 명령어라고하고 스택에서 데이터를 제거하는 행위를 POP 명령어라고합니다. 위의 예에서 볼 수있는 가장 일반적인 opcode는 1 바이트의 데이터를 스택에 넣는 것을 의미하는 PUSH1이라는 것이 분명합니다..

따라서이 지침 :

PUSH1 0x60

스택에 “0x60″의 1 바이트 값을 넣는 것을 의미합니다. 우연히도 PUSH1의 16 진수 값도 “0x60″이됩니다. 필수가 아닌 “0x”를 제거하면이 논리를 “6060”으로 바이트 코드로 작성할 수 있습니다..

조금 더 가자.

PUSH1 0x60 PUSH1 0x40 MSTORE

MSTORE (0x52)는 2 개의 입력을 받고 출력을 생성하지 않습니다. 위의 opcode는 다음을 의미합니다.

PUSH1 (0x60): 스택에 0x60을 넣습니다..

PUSH1 (0x40): 스택에 0x40 넣어.

MSTORE (0x52): 0x60의 메모리 공간을 할당하고 0x40 위치로 이동.

결과 바이트 코드는 다음과 같습니다.

6060604052

사실, 우리는 솔리 디티 바이트 코드의 시작 부분에서이 매직 넘버 “6060604052”를 항상 볼 수 있습니다..

문제를 더 복잡하게하기 위해 0x40 또는 0x60은 실수 40 또는 60으로 해석 될 수 없습니다. 16 진수이므로 40은 실제로 64 (16¹ x 4)와 같고 60은 십진수로 96 (16¹ x 6)과 같습니다..

간단히 말해서“PUSH1 0x60 PUSH1 0x40 MSTORE”가하는 일은 96 바이트의 메모리를 할당하고 포인터를 64 번째 바이트의 시작 부분으로 이동하는 것입니다. 이제 스크래치 공간에 64 바이트, 임시 메모리 저장에 32 바이트가 있습니다..

EVM에는 데이터를 저장할 3 곳이 있습니다. 첫째, 스택에서. 위의 예에 따라 PUSH opcode를 사용하여 데이터를 저장했습니다..

두 번째는 MSTORE opcode를 사용하는 메모리 (RAM)에 있고 마지막으로 SSTORE를 사용하여 데이터를 저장하는 디스크 저장소에 있습니다. 데이터를 스토리지에 저장하는 데 필요한 가스는 가장 비싸고 데이터를 스택에 저장하는 것이 가장 저렴합니다..

이제이 튜토리얼의 Solidity 코드로 돌아가서 예약어에 대해 배운 내용을 요약 할 때입니다. 기억 컴파일러가 문자열 저장 방법을 지정하도록하는 방법, 예를 들어.

우리는 바이트 코드의 기초와 몇 가지 opcode 만 다루었습니다..

스마트 계약 작성을 시작하기 위해 opcode를 알 필요가 없습니다.!

반면에 EVM 오류 처리는 여전히 매우 원시적이며 일이 잘못 될 때 opcode를 쉽게 볼 수 있습니다..

결론

이 첫 번째 강의는 실제 코딩보다 약간 더 많은 이론을 가지고 있지만 초보자가 Ethereum에서 작동하는 방식을 아는 것은 매우 중요합니다. 다음 튜토리얼에서는 좀 더 흥미로운 코드를 작성하고 Ethereum 블록 체인에 자체 토큰을 배포하는 방법을 배웁니다..

그때까지 &# 128075;