やさしい初心者向けガイド(第2部)


これは継続です.Ethereum、Solility、Ethereum Virtual Machine、Smart Contactのような主要な話題を見て、私たちは深く完全に固辞に飛び込んだ.
私たちは、この記事の中でより高度なコンセプトを求めます.

関数


私たちはパート1の機能を見ました、しかし、我々はそれにより深い観察をします.
様々な種類の機能があります
  • パブリック関数
  • 個人関数
  • 内部関数
  • 外部関数
  • パブリック関数-これらの関数は、任意のコントラクトによって呼び出すことができる関数です.これは、関数の呼び出しの結果として値を変更する場合は特に、あなたの関数を公開します.それはあなたの契約を攻撃に公開します.パブリックキーワードは関数パラメータの後に追加されます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       function createCar(uint _amount, string memory _name) public pure returns (Car memory _car) {    
            Car memory newCar = Car(_amount,_name);
            return newCar;     
        }
    }
    
    
    上記の関数のように、関数が返すデータの戻り値を指定する必要があります.
    プライベート関数-これらは、契約内でのみ呼び出すことができる関数です.外部関数にアクセスできません.親指の良いルールは、デフォルトであなたの契約を非公開にすることです.
    プライベートキーワードは、関数パラメータの後に追加されます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       function createCar(uint _amount, string memory _name) private pure returns (Car memory _car) {   
            Car memory newCar = Car(_amount,_name);
            return newCar;     
        }
    }
    
    
    内部関数-これらはプライベート関数ですが、契約から継承する契約にアクセスできます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       function createCar(uint _amount, string memory _name) internal pure returns (Car memory _car) {  
            Car memory newCar = Car(_amount,_name);
            return newCar;     
        }
    }
    
    
    外部関数-これらは、あなたの契約の外でのみアクセス可能な関数です.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       function createCar(uint _amount, string memory _name) external pure returns (Car memory _car) {  
            Car memory newCar = Car(_amount,_name);
            return newCar;     
        }
    }
    
    

    複数の値を返す


    ほとんどの場合、関数は値を返します、そして、返される値は1以上でありえます.前の例では、1つの値を返す方法について、複数の値を返す方法の例を見てみましょう.すべての戻り値のデータ型も、1つ以上の値を返すときに指定する必要があります
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
    function createCar(uint _amount, string memory _name) external pure returns (uint amount, string memory name, Car memory _car) {   
            Car memory newCar = Car(_amount,_name);
            return (_amount, _name, newCar );   
        }
    }
    
    
    

    条件文とループ


    if
    文が真か偽かをチェックするのに使われる条件文であるならば、Sollianceでのその使用法は他の言語
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       uint newAmount = 1000;
    
       function createCar(uint _amount, string memory _name) external returns (Car memory _car) {  
             if (_amount > 1000){
                 newAmount = _amount;
             }
            Car memory newCar = Car(newAmount,_name);
            return newCar;   
        }
    }
    
    
    上記のロジックは、金額が1000より大きいかどうかチェックします、それがtrueであるならば、それはnew量変数を関数に渡される量に変えます.
    ループ用
    ループの場合、条件に基づいて複数回ステートメントを実行できます.Soluityのループは他の言語
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
    
        struct Car { 
            uint amout; 
            string name; 
        }    
    
        string[] carNamesList = ["BMW","Toyota","Honda"];
        uint[]  carAmountList = [1000,2000,2000];
        Car[] allCars;
    
        function loopCars() public {
            for (uint i = 0; i < carNamesList.length; i += 1) { 
            Car memory newCar = Car(carAmountList[i], carNamesList[i]);
            allCars.push(newCar);
            }
        }
    
    
    
    }
    
    
    私たちはCarNamListとCaramountList配列を作成しました.そして、それは自動車名と自動車量のリストを含みます、そして、我々は配列を通過して、新しい車をつくって、Allcar配列にそれを加えました.
    必要
    requireはif文と似ていますが、文が真か偽ならば評価します.文がtrueの場合、require文の下の行は評価されます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
       uint newAmount = 1000;
    
       function createCar(uint _amount, string memory _name) external view returns (Car memory _car) {  
            require(_amount > newAmount);
            Car memory newCar = Car(newAmount,_name);
            return newCar;   
        }
    }
    
    
    
    上記のロジックは、金額がNew量変数で設定された量より大きいかどうかチェックします、それが本当であるならば、以下の線は実行します、それがfalseであるならば、それはエラーを投げます.

    乱数の生成


    乱数を生成するには、KECCAK 256として知られているEthereumハッシュ関数が必要です.このハッシュ関数は256ビットの16進数を返し、ハッシュ関数はバイトの単一パラメータを期待しています.
    それを使用するために、我々はABIを使用している関数に渡すストリングをコード化する必要があります.この関数は文字列を型バイトに変換します.
    アクションでそれを見ることができます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
    
     bytes32 variable = keccak256(abi.encodePacked("aaaab"));
    //6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5
    
    }
    
    

    輸入


    私たちが異なるファイルで我々の契約をして、我々がもう一つのファイルで彼らを使いたいとき、我々は輸入を使います.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    // NFT contract to inherit from.
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    
    contract MyNFT is ERC721 {
    
    }
    
    
    我々は、以下のコードでNFTトークンを作成するために使用することができます上記の契約をインポートします.
    OpenZeppelinはオープンソースのOpenZeppelin契約を提供します.OpenZeppelin契約はESPERベースのトークンのためのERC規格を使用します.Ethereumまたは他のBlockchainの上で安全なスマート契約を構築することに関連しているサイバーリスクを最小にするために、OpenZeppelin契約は絶えず監査されて、テストされます.

    遺産


    これは、オブジェクト指向プログラミングにおいて、クラスが別のクラスのプロパティを継承する概念です.Solility契約は他の契約から継承することができます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract Hello {
      function HelloWorld() public pure returns (string memory) {
        return "Hello World";
      }
    }
    
    contract HelloWord is Hello {
      function AnotherHelloWorld() public pure returns (string memory) {
        return "Another Hello World";
      }
    }
    
    
    
    第1の契約はHelloWorld機能だけにアクセスします、第2の契約はHelloWorld機能とAnotherHelloWord機能の両方にアクセスします.
    isは継承のためのキーワードです.

    イベント


    イベントは、アプリケーションのクライアント側またはフロントエンドにブロックチェーンで起こっていることを伝えるための媒体です.フロントエンドがブロックの変化が起こったときに知ることが出来ます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        struct Car { 
            uint amout; 
            string name; 
        }
    
        event CarCreated(uint _amount, string  _name, Car _car); 
    
        function createCar(uint _amount, string memory _name) internal returns (Car memory) {  
             Car memory newCar = Car(_amount,_name);
             emit CarCreated(_amount,_name, newCar);
             return newCar;     
      }
    
    
    }
    
    
    }
    
    
    イベントを作成してイベントを作成しました.
    createCar関数では、生成されたイベントを生成します.クライアント側はイベントを取得し、何かを行います.
    // The frontend implementation
    YourContract.CarCreated(function(error, result) {
       // do something when car is created
    }) 
    

    アドレス


    Ethereumのブロックチェーンはアカウントで構成され、これらのアカウントは銀行口座と同様に動作します.アカウントはエーテル(Ethereum Blockchainの上で使用される通貨)のバランスを持ちます、そして、あなたはエーテル支払いを他の口座に送って、受け取ることができます.
    各アカウントには、銀行口座番号のように考えることができるアドレスがあります.このアカウントを指すユニークな識別子で、以下のようになります.
    これが私のアドレスです.前もってお礼を申し上げます.
    アドレスは、ブロックチェーン( Ethereum Blockchain )のユーザIDです.

    マッピング


    アドレスは我々がEthereumブロックチェーンに我々のデータを写像する最も重要なもののうちの1つです.そして、我々は我々のアドレスにブロックチェーンで我々に属している口座残高(NFL)、NGs、ユーザーIDと他のもののようなものを地図化することができます.
    たとえば、我々の口座残高に我々のアドレスと一致するために、我々はこれをすることができます
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
    
        mapping(address => uint) public accountBalance;
    
    }
    
    
    上で作成したマッピングの名前はAccountTbalanceです.マッピングのキーワードを使用してアドレスをUINTにマッピングします.アドレスはUINTと同じようにデータ型です.

    MSG送付者


    我々のアドレスへのアクセスを得るために、私たちはアクセスMSGを必要とします.送付者、すべての関数、msgに利用可能なグローバル変数です.送付者はユーザのアドレスを出力します.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
        uint amount = 5000;
        mapping(address => uint256) public accountBalance;
    
    
        accountBalance(msg.sender) = amount;
        // mapping is done, now we can access the account balance 
        // from the accountBalance mapping when we need it
    
    }
    
    
    我々は、金額を我々のアドレスに割り当てました、そして、我々はMSGから我々のアドレスを得ました.送付者.

    コンストラクタ


    それは、契約と同じ名前を持つ任意の特別な機能です.それは、契約が最初に作成される1回だけ実行されます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
       constructor(
            string[] memory carList,
        )
    
      //Do other things
    
    }
    
    
    carlist配列は、契約が作成された最初に作成されます.

    関数修飾子


    それらは他の関数を変更するのに使用される半分の関数の一種であり、関数を実行する前にほとんどの要件をチェックするために使用されます.
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract HelloWorld {
       address private  _owner;
       constructor(
             _owner = msg.sender;
        )
    
       // modifier function
       modifier onlyOwner() {
        require(msg.sender == _owner);
        _;
      }
    
      function doSomething() public onlyOwner {
          // This function only runs when the onlyOwner 
          //  modifier question evaluates as true
      }
    
    }
    
    
    私たちは、アドレスデータ型を持つCount所有者と呼ばれるプライベート変数を作成しました.私たちは、コンストラクタの変数にアドレスを割り当てました.
    修飾子キーワードを使用して、onlyownerという修飾子関数を作成しました.修飾子関数では、アドレスが最初に格納されたアドレスに一致するかどうかを確認します.
    私たちは修飾子関数をdothing関数に割り当てました、これは、それにアクセスしようとしている人が契約の所有者であるならば、機能が走るだけであることを意味します.
    この記事のパート3では、NFT契約とフロントエンドアプリケーションを構築するために、これらすべてのコンセプトを使用します.
    このチュートリアルが役に立つと思います.
    お読みありがとうございます.
    参考文献
  • Solidity Docs
  • Crypto Zombies
  • Tutorial Point