🔏
PexpA
  • Home
  • Knowledge
    • Design Pattern
    • RxJS
    • Computer Graphics
      • Phép biến đổi hình học
    • Javascript
      • Generator function và Yield trong javascript
      • Asynchronous và Synchronous
    • GraphQL
      • Core Concepts
      • Xây dựng GraphQL sử dụng NodeJS
    • Analysis and System Design
    • SEO
    • Database
      • NoSQL
        • MongoDB
      • SQL
    • ReactJS
      • React Fragment
      • Lifecycle trong component
      • HOCs
      • What is Ref ?
      • Context API
      • React Hooks
        • useState Hook
        • useEffect Hook
        • useLayoutEffect Hook
        • Khi nào dùng useLayoutEffect và useEffect
        • useContext Hook
        • useReducer Hook
        • useCallback Hook
        • useMemo Hook
        • useRef Hook
        • Building Your Own Hooks
      • Redux
    • React Native
      • Animations
    • Angular
    • Python
      • Object Oriented Programming
      • Decorator
      • Multi Threading
      • Generators
      • Iterators
    • Java
    • Blockchain
      • Ethereum Development Overview
      • Solidity Document
      • JSON RPC Protocol
  • Package
    • React Router V4
    • API Documentation
      • API Blueprint
      • Swagger
    • Lazyload image
    • React Helmet
    • React Spring
    • React Apollo
    • ImmerJS
    • Styled components
  • Experience
    • Sử dụng Latex trên VSCode
    • Linked List in C++
    • How to using Date, Time, TimeStamp for Java to connect Database
    • Pass props to a component rendered by React Router v4
    • Forking Workflow
  • Deploy
    • Heroku
      • How to deploy React App with Express
      • How to deploy React App with Python
      • How to deploy React App with Java
  • About me
Powered by GitBook
On this page
  • Các ví dụ cơ bản
  • Storage Example
  • Subcurrency Example
  • Cấu trúc Solidity source file
  • SPDX License Identifier
  • Structure of a Contract
  • State Variables
  • Function
  • Function Modifiers
  • Events
  • Struct Types
  • Enum Types

Was this helpful?

  1. Knowledge
  2. Blockchain

Solidity Document

Chúng ta sẽ đến với những ví dụ cơ bản trước khi đi sâu vào chi tiết của ngôn ngữ Solidity

Các ví dụ cơ bản

Storage Example

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

Dòng số 2 chúng ta có thể thấy đây là phiên bản solidity sử dụng để viết smart contract, điều này đảm bảo rằng hợp đồng không thể biên dịch với phiên bản nhỏ hơn0.4.16 và lớn hơn hoặc bằng phiên bản0.9.0

Hợp đồng trong solidity về cơ bản là một tập hợp các mã (các chức năng của nó) và dữ liệu (các trạng thái của nó) được nằm tại những địa chỉ cụ thể trên Ethereum Blockchain. Dòng uint storedData;khai báo biến trạng thái storedDatacó kiểu uint( unsigned integer of 256 bits)

Để truy cập vào biến trạng thái bạn cần sử dụng tiền tố this.

Bất kỳ ai cũng có thể ghi đè giá trị storedData của bạn bằng cách thực hiện hàm setnhưng giá trị cũ của bạn vẫn được lưu trữ trong lịch sử của blockchain. Trong những ví dụ tiếp, bạn sẽ có thể cài đặt các giới hạn truy cập mà chỉ có bạn mới có thể thay đổi giá trị storedData

Hãy cẩn thận khi sử dụng văn bản Unicode, các ký tự trông giống nhau (hoặc giống hệt nhau) có thể có các code points khác nhau và như vậy khi mã hóa sẽ thành một mảng byte khác nhau

Tất cả các định danh (contract names, function names and variable names) đều bị hạn chế bởi bộ ASCII. Nó có thể lưu trữ dữ liệu được mã hóa dưới dạng UTF-8 trong biến string

Subcurrency Example

Ví dụ sau sẽ tạo ra một form triển khai hợp đồng thông minh của tiền điện tử. Hợp đồng này chỉ cho phép người dùng tạo ra đồng tiền mới. Bất kỳ ai cũng có thể gửi tiền cho nhau mà không cần đăng ký với tên người dùng và mật khẩu từ trước. Tất cả những gì bạn cần là Ethereum keypair.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Coin {
    // The keyword "public" makes variables
    // accessible from other contracts
    address public minter;
    mapping (address => uint) public balances;

    // Events allow clients to react to specific
    // contract changes you declare
    event Sent(address from, address to, uint amount);

    // Constructor code is only run when the contract
    // is created
    constructor() {
        minter = msg.sender;
    }

    // Sends an amount of newly created coins to an address
    // Can only be called by the contract creator
    function mint(address receiver, uint amount) public {
        require(msg.sender == minter);
        require(amount < 1e60);
        balances[receiver] += amount;
    }

    // Sends an amount of existing coins
    // from any caller to an address
    function send(address receiver, uint amount) public {
        require(amount <= balances[msg.sender], "Insufficient balance.");
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }
}

The line address public minter; khai báo biến có kiểu address. address là giá trị 160 bit không cho phép bất kỳ phép toán số học nào. Nó phù hợp để lưu trữ địa chỉ của hợp đồng, hoặc public key của keypair thuộc về tài khoản bên ngoài.

public tự động sinh ra một function cho phép bạn truy cập vào giá trị hiện tại của biến trạng thái từ bên ngoài hợp đồng. Nếu không có từ khóa này, các hợp đồng khác không có cách nào có thể truy cập được vào biến. Mã của từ khóa public sau khi được biên dịch tương đương với

function minter() external view returns (address) { return minter; }

Tiếp theo đến mapping (address => uint) public balances;cũng tạo ra một public state variable, nhưng có kiểu dữ liệu phức tạp hơn, nó sẽ ánh xạ từ address đến uint

Mappings có thể trông như một bảng hash được khởi tạo sao cho mỗi khóa sẽ ánh xạ tới một giá trị có kiểu byte là tất cả các số 0. Tuy nhiên, không thể lấy danh sách tất cả các khóa của ánh xạ, cũng như danh sách tất cả các giá trị. Nó chỉ ghi lại những gì bạn thêm vào

Hàm getter (hàm này được tạo tự động trong trình biên dịch) được tạo bởi từ khóa public phức tạp hơn trong trường hợp mapping. Nó trông giống như sau:

function balances(address _account) external view returns (uint) {
    return balances[_account];
}

Bạn có thể sử dụng chức năng này để truy vấn số dư của một tài khoản.

The line event Sent(address from, address to, uint amount); declares an "event", which is emitted in the last line of the function send .Các ứng dụng Ethereum client như ứng dụng web có thể lắng nghe các sự kiện này được emitted trên blockchain mà không tốn nhiều chi phí. Ngay sau khi nó được emitted, bên máy client sẽ nhận các tham số from, to, amount điều này giúp bạn theo dõi các giao dịch.

Để lắng nghe các sự kiện, bên phía client, chúng ta sử dụng web3.js. Trước tiên, chúng ta tạo Coin contract object trong web3.js và bất kỳ giao diện người dùng nào cũng gọi balances function được tạo tự động từ bên trên:

Coin.Sent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer: " + result.args.amount +
            " coins were sent from " + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balances now:\n" +
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
})

The functions that make up the contract, and that users and contracts can call are mint and send.

The send function can be used by anyone (who already has some of these coins) to send coins to anyone else. If the sender does not have enough coins to send, the require call fails and provides the sender with an appropriate error message string.

If you use this contract to send coins to an address, you will not see anything when you look at that address on a blockchain explorer, because the record that you sent coins and the changed balances are only stored in the data storage of this particular coin contract. By using events, you can create a “blockchain explorer” that tracks transactions and balances of your new coin, but you have to inspect the coin contract address and not the addresses of the coin owners.

Cấu trúc Solidity source file

Các mã nguồn có thể chứa một số lượng tùy ý các định nghĩa hợp đồng, chỉ thị nhập, chỉ thị pragma và các định nghĩa cấu trúc, enum, hàm và biến hằng số.

SPDX License Identifier

Ví dụ: // SPDX-License-Identifier: MIT

Trình biên dịch sẽ không xác nhận giấy phép là một phần trong tập danh sách được cấp phép bởi SPDX, nhưng nó bao gồm chuỗi được cung cấp trong bytecode metadata. Nếu bạn không muốn chỉ định giấy phép hoặc nếu mã nguồn không phải là mã nguồn mở, vui lòng sử dụng giá trị đặc biệt UNLICENSED. Pragmas Từ khóa pragma được sử dụng để kích hoạt các tính năng hoặc kiểm tra trình biên dịch nhất định. Một chỉ thị pragma luôn là cục bộ cho một tệp nguồn, vì vậy bạn phải thêm pragma vào tất cả các tệp của mình nếu bạn muốn kích hoạt nó trong toàn bộ dự án của mình.

Structure of a Contract

Hợp đồng trong Solidity giống với classes trong ngôn ngữ hướng đối tượng. Trong mỗi hợp đồng có thể được khai báo: State Variables, Functions, Function modifiers, Events, Struct Types và Enum Type. Hơn nữa các hợp đồng có thể thừa kế các hợp đồng khác. Có 2 loại hợp đồng đặc biệt đó là: Libraries và Interfaces.

State Variables

State Variables là các biến có giá trị được lưu trữ vĩnh viễn trong bộ lưu trữ hợp đồng.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

contract SimpleStorage {
    uint storedData; // State variable
    // ...
}

Function

Các hàm là các đơn vị mã có thể thực thi được. Các chức năng thường được xác định bên trong hợp đồng, nhưng chúng cũng có thể được định nghĩa bên ngoài hợp đồng.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0 <0.9.0;

contract SimpleAuction {
    function bid() public payable { // Function
        // ...
    }
}

// Helper function defined outside of a contract
function helper(uint x) pure returns (uint) {
    return x * 2;
}

Function calls có thể xảy ra bên trong hoặc bên ngoài và có các mức độ hiển thị khác nhau đối với các hợp đồng khác.

Function Modifiers

Function Modifiers có thể được sử dụng để sửa đổi ngữ nghĩa của các hàm theo cách khai báo

Giống như các hàm, modifiers có thể overriden.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;

contract Purchase {
    address public seller;

    modifier onlySeller() { // Modifier
        require(
            msg.sender == seller,
            "Only seller can call this."
        );
        _;
    }

    function abort() public view onlySeller { // Modifier usage
        // ...
    }
}

Events

Events are convenience interfaces with the EVM logging facilities.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.21 <0.9.0;

contract SimpleAuction {
    event HighestBidIncreased(address bidder, uint amount); // Event

    function bid() public payable {
        // ...
        emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
    }
}

Struct Types

Structs are custom defined types that can group several variables.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

contract Ballot {
    struct Voter { // Struct
        uint weight;
        bool voted;
        address delegate;
        uint vote;
    }
}

Enum Types

Enums can be used to create custom types with a finite set of ‘constant values’.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

contract Purchase {
    enum State { Created, Locked, Inactive } // Enum
}

PreviousEthereum Development OverviewNextJSON RPC Protocol

Last updated 4 years ago

Was this helpful?

The mint function có chức năng gửi số tiền mới được tạo đến một tài khoản khác. The function call defines conditions that reverts all changes if not met. In this example, require(msg.sender == minter); ensures that only the creator of the contract can call mint(quan sát hàm constractor ta có thể thấy minter = msg.sender tức là khi bắt đầu người dùng tạo hợp đồng (sender) thì giá trị minter chỉ thuộc về duy nhất 1 người. Do đó nếu không có điều kiện msg.sender == minter thì chỉ cần một ai đó mạo danh senderbất kỳ thì hàm mint sẽ được chạy ), and require(amount < 1e60); ensures a maximum amount of tokens. This ensures that there are no overflow errors in the future.

Trust in smart contract can be better established if their source code is available. Since making source code available always touches on legal problems with regards to copyright, the Solidity compiler encourages the use of machine-readable . Every source file should start with a comment indicating its license:

require
SPDX license identifiers