blockchain-2023-2024-spring

Увод в Solidity

Въпроси и бележки

Модификатори

Модификатори за достъп
Модификатори на компилатора

Ако изпуснем модификатор, се приема by default модификаторът с най-висок приоритет

Restrictors and function modifiers

Restrictors(require statements)

Инструментариум, с който ограничаваме поведението на функцията, за да можем да осигурим по-високо ниво на точност на изпълнението на бизнес логиката

require(<boolean expression>, "string message to display if expression is false")

Ако булевият израз се оцени до лъжа, то се връща газта до момента и се дава причината.

Обикновено се поставят в началото на функциите с цел потенциално спестяване на газ.

Модификатори(restrictor modifiers)
    modifier isHigher5(uint256 _val) {
        require(_val > 5, "Number must be higher than 5");
        _; // placeholder, взема се кода на функцията и се продължава
    }

    function setValue(uint256 _val) public isHigher5(_val) {
        num = _val;
    }

Пример


//SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract HelloContract {
    // uint256 private num = 0; // можем да укажем модификатор за достъп на полетата
    uint256 num = 0;

    constructor() {
    }

    modifier isHigher5(uint256 _val) {
        require(_val > 5, "Number must be higher than 5");
        _;
    }

    function setValue(uint256 _val) public isHigher5(_val) {
        num = _val;
    }

    // модификатор за достъп, модификатор за компилатор, модификатор за requirements, тип върнатата стойност
    function getValue() public view returns(uint256, uint256) {
        // по дефиниция само четат
        return (num, num + 1);
    }

    function divTest(uint v1, uint v2) public pure returns(uint256) {

        return v1 / v2;
    }
}

Наследяване

    contract A {
        uint256 internal  num = 10;
    }

    contract B is A {
        function getNum() public view returns(uint256) {

            return num;
        }
    }

    contract C is A, B {

    }

Типове данни

Всички state fields by default са storage.
Всичко извън state fields по конвенция е memory или calldata/stack

Работа с масиви и памет


//SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;


contract NewContract {
    uint32[] private array;

    function setArray(uint32[] calldata arr) public {
        delete array;
        require(array.length == 0, "This ain't working");
        for(uint256 i = 0; i < arr.length; ++i) {
            array.push(arr[i]);
        }
    }

    function getArray() public view returns(uint32[] memory) {
        return array;
    }

    function setLocalArray(uint256 _size) public pure returns(uint256[] memory) {
        uint256[] memory arr = new uint256[](_size);
        // заделяме памет
        // ако не използваме new, arr има стойност подобна на null

        for(uint256 i = 0; i < _size; ++i) {
            arr[i] = i;
            // няма .push(i) метод, масивът не се преоразмерява
        }
        return arr;
    }
}

Сравняване на низове и масиви

    function comparestr(string calldata str1,
                        string calldata str2) public pure returns(bool) {

        return keccak256(abi.encode(str1)) == keccak256(abi.encode(str2));
    }

    function comparearr() public pure returns(bool) {
        uint8[5] memory arr1 = [1, 2, 3, 4, 5];
        uint8[5] memory arr2 = [1, 2, 3, 4, 5];
        //arr2[2] = 7;

        return keccak256(abi.encode(arr1)) == keccak256(abi.encode(arr2));
    }

Mappings

contract NewContract {
    uint32[] private array;
    mapping(uint32 => address) mapp;
    uint32[] keys;
    ...

Remix Specific