Привет, незнакомец!

Похоже, вы здесь новенький. Чтобы принять участие, нажмите одну из кнопок ниже!

Смарт-контракт на Solidity: Частина 3 — візитка — address, конструктор, змінна msg

отредактировано December 2017 Раздел: Смарт Контракты

Серія уроків була взята з сайту inaword.ru

На попередньому уроці ми написали смарт-контракт візитку. На цьому уроці ми покращимо нашу візитку - зокрема заборонимо всім, крім власника, змінювати дані всередині візитки. А також торкнемося тем:

  • змінна msg
  • конструктор контракту
  • тип address
  • виняток throw

Код нашої візитки з попереднього уроку:

pragma solidity ^0.4.13;

contract BusinessCard {

    mapping (bytes32 => string) data;

    function setData(string key, string value) {
        data[sha3(key)] = value;
    }

    function getData(string key) constant returns(string) {
        return data[sha3(key)];
    }

}

Нагадаю - методом getData ми можемо отримати значення, записане раніше на візитці. А метод setData дозволяв змінити значення.

Після того як смарт-контракт буде створений всередині мережі Ethereum він буде доступний будь-якій людині в мережі. Це означає, що будь-який учасник мережі Ethereum може виконати як функцію getData так і функцію setData. Таким чином ми маємо небезпеку того, що інший користувач, викликавши функцію setData, змінить дані на нашій візитці. А ми б хотіли щоб змінювати їх міг тільки власник візитки. Давайте вирішимо цю проблему!

Усередині контракту нам доступна глобальна змінна msg. Це структура з декількома полями. З цими полями ми будемо знайомитися в міру необхідності. Зараз ми познайомимося з полем sender. Отже, msg.sender - це адреса того, хто виконує контракт в даний момент. Того хто викликав функцію. Тип цього поля address.

Таким чином, для того щоб заборонити змінювати дані візитки стороннім особам контрактом досить перевірити чи є адреса того хто виконує контракт в даний момент адресою власника візитки. Тобто, якщо msg.sender дорівнює адресі власника візитки, то ми виконуємо setData. В іншому випадку повідомляємо про помилку.

І тут виникає питання. Як отримати адресу власника візитки? При створенні контракту викликається спеціальна функція - конструктор. Вона має таку ж назву як і сам контракт і нічого не повертає.

function Ім'яКонтракту() {
     ...
}

Ми вже знаємо, що у msg.sender зберігається адреса того, хто виконує контракт на даний момент. Оскільки той, хто створює візитку і є власник візитки, то нам достатньо отримати в конструкторі msg.sender і зберегти його всередині контракту для подальшого порівняння.

Виправимо наш контракт:

pragma solidity ^0.4.13;

contract BusinessCard {

    mapping (bytes32 => string) data;

    address owner;

    function BusinessCard() {
        owner = msg.sender;
    }

    function setData(string key, string value) {
        if(msg.sender != owner) 
            throw;
        data[sha3(key)] = value;
    }

    function getData(string key) constant returns(string) {
        return data[sha3(key)];
    }

}

Тепер наш контракт містить змінну owner, в яку конструктор зберігає адресу творця-власника візитки. А в функції setData у нас з'явилася умова:

if(msg.sender != owner) 
            throw;

Незнайоме нам слово throw змушує контракт припинити роботу. В останніх версіях solidity не рекомендується використовувати throw. А для перевірки будь-якої умови припинення роботи функції рекомендують використовувати конструкцію require (умова). Якщо умова не виконується, то функція зупиняється. Між способами зупинки роботи функції є істотна різниця, але ми її поки розглядати не будемо. Просто перепишемо наш код з require.

pragma solidity ^0.4.13;

contract BusinessCard {

    mapping (bytes32 => string) data;

    address owner;

    function BusinessCard() {
        owner = msg.sender;
    }

    function setData(string key, string value) {
        require(msg.sender == owner);
        data[sha3(key)] = value;
    }

    function getData(string key) constant returns(string) {
        return data[sha3(key)];
    }

}

Давайте тепер перевіримо роботу нашого контракту. Створіть контракт в мережі Ethereum (див. урок 1). Зверніть увагу на поле Account.

Поле account - це адреса вашого облікового запису. Саме від його імені ви на даний момент працюєте і саме від його імені був створений контракт. Якщо ви зараз викличете setData з будь-якими даними (наприклад: «email», «cromlehg@gmail.com»), то дані всередині контакту успішно зміняться.

З метою тестування Remix дозволяє змінити адресу облікового запису. У списку, що випадає, account оберіть будь-яку іншу адресу. А тепер спробуйте викликати setData і ви отримаєте повідомлення про помилку - виняток. Контракт не дозволив нам змінити дані, бо адреса власника візитки інший.

Статус останньої операції remix відображає в консолі.

Отже, ми в цьому уроці дізналися як отримати адресу того хто виконує контракт на даний момент. Дізналися що таке конструктор. І що найважливіше - навчилися обмежувати доступ до функцій контракту і тестувати!

На цьому поки все. Продовження читати тут.

Войдите или Зарегистрируйтесь чтобы комментировать.