Trọn series Lập trình smart contracts ethereum

Phần 1 — Lời mở đầu


Công nghệ thay đổi rất nhiều thứ, kể cả nhận thức của chúng ta, công nghệ mới thay thế công nghệ cũ. Blockchain cũng vậy, tuy không phải là công nghệ mới nhưng nó là sự kế thừa và đặt nền tảng để ta hiện thực những ý tưởng mà trước đây là không thể. Smart contracts một khái niệm không còn mới mẽ nhưng với Ethereum - lần đầu tiên nó được hiện thực hóa nó bằng cách ứng dụng công nghệ blockchain.

Nếu các chính phủ chấp nhận giá trị pháp lý của các smart contracts nó sẽ mở ra những triển vọng rất lớn và sự chuyển dịch trong khối hành chính sự nghiệp cũng như khối doanh nghiệp. Smart contracts và digital signature hoàn toàn có thể thay thế hoàn toàn các hợp đồng dân sự và điều này sẽ tiết kiệm hàng tấn tiền để in các hợp đồng, xét xử, kiện cáo…

Và điều này cũng có nghĩa lập trình smart contracts sẽ trở thành một kỹ năng cần thiết trong cuộc sống. Thế giới đầy những điều không tưởng xảy ra, và nếu không chuẩn bị ta có thể trở thành những kẻ thất bại của xã hội.

Những platform nào thực thi smart contracts?

Ethereum không phải là platform duy nhất cho phép thực hiện smart contracts, có rất nhiều và hằng hà sa số các platform hướng tới việc lập trình smart contract và xây dựng các decentralized applications. Tiêu biểu là:

LSK: https://docs.lisk.io/docs/the-lisk-protocol

RSK: http://www.rsk.co/

Tại sao Ethereum và Solidity?

Ethereum và solidity là platform và ngôn ngữ phổ biến và dễ học nhất, bạn sẽ không mất quá nhiều công sức để xây dựng tất cả mọi thứ.

Những bước làm quen với smart contracts

Nắm vững những hạn chế của Ethereum
  • Thời gian confirm một transaction (10–13s)
  • Gas limit của một block (4,000,000–6,000,000)
  • Gas estimate cho mỗi transaction (nếu không đủ gas thì toàn bộ estimate gas của bạn sẽ bị consume hết và EVM throw INVAILD out of gas)
  • Cách điều chỉnh gas price
  • Các BIP liên quan tới HD wallet (BIP32), và mnemonic words (BIP39)
Hiểu biết về platform là lợi thế chính yếu
  • Sử dụng thành thạo NodeJS & GNU Toolchain
  • Rất nhiều thư viện như EthereumJS được viết trên JavaScript. Bạn sẽ không mất công làm lại
  • Sử dụng các GNU toolchain cũng cần thiết, nó sẽ giúp các bạn khi biên dịch cách packages được thuận lợi
Sử dụng thành thạo command line
  • Bạn phải làm việc với command line khá nhiều nếu không muốn nói là 24/7
  • Nếu bạn dùng GNU/Linux hoặc macOS thì thuận tiện hơn rất nhiều so với Windows.
  • Dùng được truffle thì điều kiện tiên quyết là rành command line
Học solidity

Phần 2 — Viết smart contracts đầu tiên


Smart contracts sinh ra nhằm mục đích giải quyết bài toán tin tưởng trong một môi trường thiếu tin tưởng như Internet. Và smart contract không phải là điều gì quá ghê gớm, nó sinh ra để giải quyết các bài toán thực tế, chẳng hạn như: trả lương, bảo hiểm, thừa kế, trao đổi, mua bán…. Gần đây chúng ta nghe nhiều về Decentralized Exchange, ICO… mọi người nói về nó thực sự rất ghê gớm. Đôi khi người ta thổi phồng sự việc lên một cách không cần thiết nhằm đạt mục đích PR. Nhưng trong kỹ thuật mọi thứ đều tiệm cận tới θ.

ERC20 Token

Trong hệ thống của Ethereum thì ETH đóng vai trò là native token, transaction fee sẽ được tính trên token này. Ethereum platform còn cho phép người dùng định nghĩa token riêng và để chuẩn hóa các token này, ERC20 ra đời. Tùy mục đích của người sáng lập mà một ecosystem có thể có hoặc không có token.

Viết một token đơn giản 

Một token đơn giản nhất sẽ bao gồm các thành phần sau:

  • totalSupply: Tổng số token 
  • balanceOf(): Hiển thị balance của một owner 
  • transfer(): Chuyển token từ người sở hữu này sang cho người khác 

Đầu tiên ta phải định nghĩa một mapping để lưu trữ thông tin của token đóng vai trò như một ledger:

mapping (address => uint256) balances;

Với mỗi address sẽ mapping tới một số uint256 (unsigned integer 256 bits). Ta có thể tương tác thông qua toán tử [] để access các phần tử.

Tiếp theo để đọc dữ liệu từ mapping ta tạo ra method balanceOf():

function balanceOf(address _owner) constant public returns(uint256){
       return balances[_owner];
}

Method này cho phép ta đọc thông tin của bất cứ owner nào và biết họ có bao nhiêu token.

Ta định nghĩa method transfer() để có thể chuyển đổi token giữa các owner

function transfer(address _to, uint256 _value) public returns(bool){
 balances[msg.sender] -= _value;
 balances[_to] += _value;
 return true;
}

Và kết hợp tất cả ta có smart contract của AmazingToken

pragma solidity ^0.4.11;

contract AmazingToken{
  
    uint256 public totalSupply;
  
    mapping (address => uint256) balances;
  
    function balanceOf(address _owner)
    constant public returns(uint256){
        return balances[_owner];
    }
  
    function transfer(address _to, uint256 _value)
    public returns(bool){
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        return true;
    }
  
}

Bảo mật cho AmazingToken:
Trong smart contract nói trên ta sẽ thấy các vấn đề của method transfer() đó là:

Nếu _to = 0x00 thì token sẽ biến mất, giống như ta stream data vào /dev/null vậy
Transfer vẫn thực thi cho dù msg.sender không có đủ balance
Giờ ta viết lại smart contract của amazing token kèm theo việc check các conditions này.

pragma solidity ^0.4.11;
contract AmazingToken{
  
    uint256 public totalSupply;
  
    mapping (address => uint256) balances;
  
    modifier onlyValidAddress(address _to){
        require(_to != address(0x00));
        _;
    }
  
    modifier onlyValidValue(address _from,uint256 _value){
        require(_value <= balances[_from]);
        _;
    }
  
    function balanceOf(address _owner)
    constant public returns(uint256){
        return balances[_owner];
    }
  
    function transfer(address _to, uint256 _value)
    onlyValidAddress(_to) onlyValidValue(msg.sender,_value)
    public returns(bool){
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        return true;
    }
  
}

Việc thêm hai modifier này làm cho contract của chúng ta an toàn hơn rất nhiều. Sau khi lập trình xong token thì điều mọi người nghĩ tới cách thức để phát hành token.

Định nghĩa phương thức phát hành token

Ta định nghĩa method nhằm bán AmazingToken mỗi khi có ai đó gửi Ethereum tới sẽ nhận lại AmazingToken theo tỉ lệ 1:100.

function () public payable {
    uint256 _issued = (msg.value*100)/10**18;
    totalSupply += _issued;
    balances[msg.sender] = _issued;
}

Biến global msg.value chứa giá trị eth theo đơn vị wei (1 eth = 10¹⁸ wei).

Smart contract của AmazingToken sẽ như sau

pragma solidity ^0.4.11;
contract AmazingToken{
  
    uint256 public totalSupply;
  
    mapping (address => uint256) balances;
  
    modifier onlyValidAddress(address _to){
        require(_to != address(0x00));
        _;
    }
  
    modifier onlyValidValue(address _from,uint256 _value){
        require(_value <= balances[_from]);
        _;
    }
  
    function () public payable {
        uint256 _issued = (msg.value*100)/10**18;
        totalSupply += _issued;
        balances[msg.sender] = _issued;
    }
  
    function balanceOf(address _owner) constant public
    returns(uint256){
        return balances[_owner];
    }
  
    function transfer(address _to, uint256 _value)
    onlyValidAddress(_to) onlyValidValue(msg.sender,_value) public
    returns(bool){
        balances[msg.sender] -= _value;
        balances[_to] += _value;
        return true;
    }
  
}

Decentralized exchange 

Bây giờ mình sẽ viết một smart contract đóng vai trò như một Decentralized Exchange, điều mình mong muốn là có thể rao bán AmazingToken mà mình đang sở hữu nếu có ai đó chấp nhận mua nó bằng Ethereum.

pragma solidity ^0.4.11;
contract AmazingTokenInterface{
    uint256 public totalSupply;
    function () public payable;
    function balanceOf(address _owner)
    constant public returns(uint256);
    function transfer(address _to, uint256 _value)
    public returns(bool);
}

contract AmazingDex {
    AmazingTokenInterface AmazingToken;
    address ChiroWallet = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
  
    uint256 public rate = 100;
    modifier onlyValidAddress(address _to){
        require(_to != address(0x00));
        _;
    }
  
    modifier onlyChiro(){
        require(msg.sender == ChiroWallet);
        _;
    }
  
    function setRate(uint256 _rate)
    onlyChiro public returns(uint256){
        rate = _rate;
        return rate;
    }
  
    function AmazingDex(address _amazingTokenAddress)
    onlyValidAddress(_amazingTokenAddress) public {
        AmazingToken = AmazingTokenInterface(_amazingTokenAddress);
    }

    function buyToken()
    onlyValidAddress(msg.sender) public payable {
        uint256 _value = (msg.value*rate)/10**18;
        assert(AmazingToken.transfer(msg.sender, _value));
        ChiroWallet.transfer(msg.value);
    }
}

Smart contract này thực hiện một điều rất đơn giản, khi có bất kỳ ai gọi method buyToken() thì mình sẽ trả token cho họ theo như rate đã được mình cung cấp, còn Ethereum sẽ ngay lập tức về ví của mình.

Tất nhiên AmazingToken sẽ do AmazingDex contract này nắm giữ.

Phần 3: — Xây dựng một dAPP

Sự ra đời của Ethereum ngoài việc hiện thực hóa các smart contracts còn cung cấp cho chúng ta các phương tiện để xây dựng các decentralized applications (dApps).

Decentralized Applications

Nói nôm na dApps là ứng dụng nhưng thay vì phụ thuộc vào một central point như các ứng dụng truyền thống vẫn tồn tại. Thì back-end của nó sẽ được thay thế bằng smart contracts hoặc programmable transactions.

Cấu trúc của dApp

F1. Decentralized Application

Các dApp thường cấu thành bởi cách thành phần:
  • Front-end: Đóng vai trò là GUI (Graphical User Interface), phần này sẽ có nhiệm vụ là hiển thị và xử lý các input. Bạn có thể build front end từ bất cứ thứ gì miễn là nó thuận tiện và có thể tái sử dụng. Điểm khác biệt so với front-end của web app hay mobile app là các xử lý quan trọng nhất sẽ nằm ở phía client-side. Front-end của bạn có thể sẽ giữ và mã hóa private key, sign các transactions hoặc phải có khả năng tương tác vời các third party extension như metamask, trezor.
  • Transport: Front-end bản thân nó sẽ không có khả năng tương tác trực tiếp vào smart contracts mà luôn cần cầu nối tới các full-node, nơi cung cấp các API để làm việc với smart contracts/blockchain. Anonymous network layer, distributed file system cũng được dùng nhằm giảm thiểu việc tin tưởng các third parties hay single point of failure.
  • Services: Cung cấp các methods để front-end có thể làm việc và tương tác với smart contracts. Các bạn phải lựa chọn giữa xây dựng các services hoặc sử dụng API của TTP như https://etherscan.io, điều này tùy thuộc vào mức độ quan trọng của dApp.
  • Back-end: Các smart contracts sau khi được viết, trải qua quá trình biên dịch sẽ là các OPCODE (Operation Code) và sẽ được deploy tại một địa chỉ lý thuyết (logical address) trong blockchain của Ethereum. Các smart contracts hoàn toàn thụ động và không có khả năng thực thi các lệnh hoặc duy trì các timer. Giải quyết vấn đề như: trigger theo thời gian, lấy các thông tin từ internet… sẽ cần tới dịch vụ của third party như https://www.oraclize.it/.
Điểm mạnh của dApp
  1. Không tiêu tốn nhiều chi phí bảo mật
  2. Không tiêu tốn chi phí vận hành
  3. Không gặp vấn đề single point of failure
  4. Minh bạch và có thể kiểm chứng kết quả
  5. Tính mở cao không giới hạn quyền truy cập
  6. Người dùng tương tác với dApp, không cần cung cấp danh tín
Diểm yếu
  1. Chi phí vận hành sẽ do users trả (hay còn được biết là gas cost)
  2. Không có khả năng tương tác realtime
  3. Kiểm thử thường sẽ phức tạp hơn so với applications thông thường
  4. Phụ thuộc vào platform (e.g Ethereum)

Kết luận

Hiện tại định nghĩa decentralized application vẫn đang được hình thành, các platform vẫn đang chạy đua với nhau để giành vị trí quán quân trong việc trở thành một chuẩn chung cho dApp. Sự phát triển của blockchain, smart contracts trong những năm gần đây và việc bùng nổ các dApp sẽ thay đổi cách chúng ta viết các ứng dụng trong tương lai.

Các bài viết tiếp tiếp theo mình mong muốn đưa ra một ví dụ cụ thể và triển khai nó để chúng ta cùng quan sát quá trình phát triển một dApp từ những gì sơ khai nhất.

Nguồn: Dũng Trần
DMCA.com Protection Status
Mystown author image
| | | | | | | | |

NHÓM TÁC GIẢ MYSTOWN

"Bí mật là những gì chúng ta trao cho người khác nhờ giữ hộ"

Mọi thứ đều chứa đựng điều bí ẩn, thậm chí cả bóng tối và sự câm lặng, tôi học được rằng cho dù tôi ở trạng thái nào, tôi cũng có thể yên bình.

- Chúng tôi không đi ngược lại quy luật của tự nhiên
- Chúng tôi không làm trái lẽ sống của xã hội
- Chúng tôi không tiếp tay cho cái sai
- Chúng tôi cung cấp những SỰ THẬT bị che giấu

Bình luận

  • MysTown Beta Version II | Copyright © 2017