[Solidity]Libraries

18479 ワード

Solidity Contracts間でコードを共有する必要がある場合は、Libraryを使用します.
ライブラリを使用します.多くのインテリジェントな会議に汎用機能を格納できます.ライブラリ関数は、再利用可能な関数からプロトコル・モードと権限まで、すべて揃っています.
ライブラリを使用する理由は次のとおりです.

エラーとエラーの可能性を制限する新しいコードを削減


新しいコードを書く必要がなく、開発時間を節約


良好なコードと既存のベストプラクティス保護契約の作成


構築されたコードを使用してエネルギーを節約


ガス代の節約は倉庫の使い方にかかっている.ライブラリはプロトコルのように自分で配置したり、プロトコルバイトコードに直接コンパイルしたりすることができます.

UINT LIBRARY


倉庫は田舎とかなり似ている.どちらも同じ構文(contract C{}とlibrary C{})として定義されています.両方には、同じプロパティ、タイプ、構文を持つ関数が含まれています.同じグローバル変数と演算コードにもアクセスできます.
では、どんな違いがありますか.
ライブラリと契約の主な違いは、ライブラリにstateがないことです.ステータス変数を宣言しようとすると、ライブラリはコンパイルされません.
また、ライブラリはethersを受信、継承、受信、または破棄することはできません.
ライブラリの目的はコードを共有することです.
ライブラリには、基本的に再利用可能なアルゴリズムの関数が含まれています.これは開発者が車輪の再発明を停止するのに役立ちます!
良いライブラリは厳格なテストと検証を受けています.そのため、これらのライブラリを使用すると、エラーが発生する可能性を低減し、契約の締結に役立ちます.
Open Zeppelinは、この分野でセキュリティ企業をリードして検証された優れたSolidityライブラリを提供します.

Library Functions


ライブラリ機能は主に請負業者が使用します.ライブラリ自体にステータスはありません.
したがって,ライブラリ関数の多くは純粋な関数であり,読み取り/書き込み状態を表さない.
ライブラリ関数がpureまたはviewとして表示されている場合にのみ、直接呼び出すことができます.テストでは、JavaScriptからライブラリ関数を直接呼び出すことがわかります.これは、関数がステータスを変更しないことを示す場合にのみ役立ちます.
この関数がステータスを変更しないことを保証しないと、ライブラリのABIにコンパイルされません.これは、テストまたはABI検証でアクセスできないことを意味します.
では、ライブラリを直接呼び出す代替案は何でしょうか.
ライブラリ関数は、牽引/メッセージデータを使用して、牽引上のステータス変数にアクセスできる牽引コンテキストで実行できます.この場合、ライブラリはステータスを変更できます.
pragma solidity ^0.8.4;

library UIntFunctions {
    
function isEven(uint x) public pure returns(bool) {
		return x % 2 == 0;
	} 
    
}
この場合、関数は純粋またはview形式でなければなりません.

USING LIBRARY


ライブラリの使用
ライブラリは、さっきのテストコードのように直接呼び出すことができます.しかし、それらは一般的に契約として輸入されています.

Library Compilation & Communication


インポート・ライブラリには2つのケースがあります.
1.契約の内部に表示されるライブラリ機能を使用すると、関数の内部コードが契約そのものにコピーされ、契約とともにコンパイルされます.
2.契約で外部または共通タグのライブラリ機能を使用する場合、ライブラリは自身のアドレスで配布する必要があります.では、契約書は図書庫の住所にリンクされます.実行時、ContractはDELEGATECALL(an EVM opcode)を使用してメッセージを生成し、ライブラリ関数にアクセスします.
ライブラリをインポートすると、プロトコルコードと同じコンテキストでコードが実行されます.ライブラリがバイトコードにコンパイルされると、コードは実際には契約内部で実行されます.ライブラリが接続されている場合、DELEGATECALLオペレーティングコードはコンテキストを維持しながらライブラリを呼び出します.
ライブラリを独自に配置する必要がある場合、エンティティコンパイラはcontractバイトコードにプレースホルダを挿入します.
608060405234801561001057600080fd5b5073__$ba528da1e2dc9d528a3d6faf88239359ae$__633ef7df506040518163ffffffff1660e01b815260040160206040518083038186803b15801561005557600080fd5b505af4158015610069573d6000803e3d6000fd5b505050506040513d602081101561007f57600080fd5b81019080805190602001909291905050506000819055506085806100a46000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80630c55699c14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea264697066735822122086180a06d1da4b2b704e3d89f6c825310e78b0304df1d268790893e24b9f206164736f6c63430006020033
上のba 528 da 1 e 2 dc 9 d 528 a 3 d 6 faf 882359 aeba 528 da 1 e 2 dc 9 d 528 a 3 d 6 faf 882359 af 88358 da 1 e 2 dc 9 d 528 a 3 d 6 faf 882359 aeはlinkプレースホルダです.
コンパイラはまた、バイトコード内のプレースホルダの位置を参照します.
"linkReferences": {
    "contracts/Library.sol": {
        "Library": [
            {
                "length": 20,
                "start": 19
            }
        ]
    }
}
これはLibraryですsolを表す条件は38個の16進数文字(19バイト)から始まり、長さは40文字である.
ライブラリを配備すると、プレースホルダはブロックチェーンのライブラリアドレスに変換できます.
プレースホルダを配置している場合は、Contractバイトコードを配置する準備ができています.
EVMからライブラリ関数を呼び出す必要がある場合、ContractはDEARGCALLを使用して、ライブラリのアドレスで関数を実行するメッセージを生成します.
最後に作成したコードライブラリを見積例として使用します.
2つの使い方があります.一つ目は.
import "./UIntFunctions.sol";
contract Example {
    function isEven(uint x) public pure returns(bool) {
        return UIntFunctions.isEven(x);
    }
}
ここではUINTFunctionsライブラリをインポートし、関数isEvenを呼び出すことができます.
もう1つの方法は、
import "./UIntFunctions.sol";
contract Example {
    using UIntFunctions for uint;
    function isEven(uint x) public pure returns(bool) {
        return x.isEven();
    }
}
この例では、UITFunctionsライブラリをuintデータ型に適用します.これにより、Contractのすべての機能にライブラリのすべての機能が追加されます.
USING LIBRARYに関連するサンプルコード
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./UIntFunctions.sol";

contract Game {
    uint public participants;
    bool public allowTeams;

    constructor (uint a){
        participants = a;
        if(UIntFunctions.isEven(a))
        {
              allowTeams = true;
        }
       
    }
}

CONSOLE LOG


JavaScriptのコンソール.logと同様にsolidityにも存在します.
// SPDX-License-Identifier: MIT
pragma solidity 0.7.5;

import "hardhat/console.sol";

contract Contract {
    constructor(uint x, string y, bool z) {
        console.log(x); // 1
        console.log(y); // Hello World!
        console.log(z); // true
    }
}
console.ロゴはハードキャップのライブラリを使用できます.

EVENLY DIVIDES


Base Functions


また、基本的な目的を持つ機能を作成し、他のライブラリ機能に再使用することもできます.
これにより、コードをより容易に乾かすことができます.
pragma solidity ^0.8.4;

library Prime {
    function dividesEvenly(uint a,uint b) external pure returns(bool){
        if(a%b==0)
        {return true;}
    }
}

IS PRIME

library UIntFunctions {
    function isEven(uint x) public pure returns(bool) {
        return x % 2 == 0;
    }
    function isOdd(uint x) public pure returns(bool) {
        return !isEven(x);
    } 
}
このコードのようにisODD関数はNOT演算子isEven関数のみを使用できます.
ISPRIMEを使用する簡単なコードは次のとおりです.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library Prime {
	function dividesEvenly(uint x, uint y) public pure returns(bool) {
		return (x % y == 0);
	}

	function isPrime(uint x) public pure returns(bool) {
		for(uint i = 2; i <= x / 2; i++) {
			if(dividesEvenly(x, i)) {
				return false;
			}
		}
		return true;
	}
}

NEXT PRIME


Block Global


Solidityの内部には、アクセスできる多くのグローバル属性にブロックがあります.ブロックには、このトランザクションが移行している現在のブロックに関する情報が表示されます.
block.coinbase-このブロックアドレスのminer
block.難易度-現在のブロックの難易度
block.ガス制限-ブロックの総ガス制限
block.number-現在のブロック番号
block.timestamp-ブロックの現在のタイムスタンプ(UNIX epoch後秒)
契約およびリポジトリでの使用は簡単です.
import "hardhat/console.sol";
contract MyExample {
    constructor() {
        console.log( block.timestamp ); // 1583271154
        console.log( block.number ); // 9600665
    }
}
pragma solidity ^0.8.4;

import "./Prime.sol";

contract PrimeGame {
    using Prime for uint;

    function isWinner() public view returns (bool) {
        return block.number.isPrime();
    }
}