Хотите создавать смарт-контракты, которые могут выполнять функции на основе прогнозной модели? Вы хотите, чтобы ваш проект полностью соответствовал модным словам? Что ж, этот урок создан специально для вас! Во-первых, это предполагает, что вы имеете некоторое представление о том, как использовать Python, Flask и Solidity.

Начнем с модели, которую мы будем запрашивать. Это микросервис Flask, который позволит нам создать API, который мы можем вызывать из Oracalize.

Сначала у нас есть игрушечная модель, на которой мы будем использовать линейную регрессию. Входные данные представляют собой набор из трех примеров с набором векторов в трехмерном пространстве:

[1.,1.,5.],
 
[2.,2.,5.],
[3.,3.,1.]

И значения, соответствующие этим векторам.

[0.,0.,1.]

Самое замечательное в sklearn - это то, что у него есть единый API для множества моделей. По сути, API предоставляет следующее.

  1. Выберите модель и инициализируйте ее необязательными аргументами
  2. Подгоните модель с помощью метода Fit
  3. выполнять прогнозы с использованием метода прогнозирования

Набор данных, который мы используем, полностью искусственный и адаптирован к используемому нами методу машинного обучения. В нем первые два вектора отображаются в ноль, а третий вектор - в один.

Тип машинного обучения, который мы будем выполнять, - это регрессия. Что делает регрессия, так это разделение набора точек прямой линией.

reg_model = linear_model.LinearRegression()
reg_model.fit([[1.,1.,5.], [2.,2.,5.], [3.,3.,1.]], [0.,0.,1.])

Метод fit принимает два аргумента. Один из них - это обучающие данные, а другой - цели для обучающих данных.

Для краткости мы показываем как характеристики обучающих данных, так и целевые данные в качестве аргументов для соответствия без создания переменных.

pickle.dump(reg_model, open('some_model.pkl', 'wb'))

Здесь мы сохраняем модель в файл. Рекомендуется сохранять модели, особенно при работе с реальными данными, поскольку для изучения реальных наборов данных требуется время вычислений. Другой причиной может быть выполнение только логического вывода модели, а не ее повторное обучение.

Следующим шагом будет использование flask для предоставления API, который мы можем вызвать с помощью Orcalize.

@app.route('/prediction/api/v1.0/some_prediction', methods=['GET'])
def get_prediction():

Здесь мы создаем маршрут, который будет использоваться Oracalize (вы также сможете использовать его из веб-браузера для тестирования).

feature1 = float(request.args.get('f1'))
feature2 = float(request.args.get('f2'))
feature3 = float(request.args.get('f3'))

Затем мы получаем три функции, анализируя строку URL-адреса запроса и сохраняя их.

Теперь мы создадим запрос с помощью Oracalize. Ниже приведен запрос, который мы будем использовать. Обратите внимание, что аргументы жестко запрограммированы в запросе, в части 2 мы будем использовать вычисление с помощью Docker для выполнения этого запроса.

json(https://6ee957cb.ngrok.io/prediction/api/v1.0/some_prediction?f1=4&f2=4&f3=4).result

Это указывает Oracalize запросить URL-адрес и проанализировать ответ JSON, чтобы получить результат.

Несколько замечаний по использованию Oracalize

  1. Лучше всего использовать версию 0.4.20, потому что в более поздних версиях Solidity есть критические изменения.
  2. Для Oracalize все запросы оплачиваются, даже если вы используете тестовую сеть, поэтому у вас есть реалистичные цены.
  3. В приведенном ниже синтаксисе и во многих, которые вы найдете в Интернете, используется относительный импорт из github. Если вы используете Truffle, вам придется загрузить API вручную.
  4. Если вы не знаете, что такое обратный вызов, функция __callback выполняется после выполнения запроса.

Разберем смарт-контракт. Он состоит из четырех основных частей.

pragma solidity 0.4.20;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
//This contract was derived from the Orcalize documentation
contract ExampleSklearnContract is usingOraclize {

Это стандартная инициализация смарт-контракта с помощью Oracalize. Мы импортируем и наследуем, чтобы сделать API доступным для нас.

    string public inference_result;
    event LogConstructorInitiated(string nextStep);
    event LogInferenceUpdated(string price);
    event LogNewOraclizeQuery(string description); 

Мы создаем то место, куда мы собираемся поместить результат и все события в нашем смарт-контракте.

function ExampleSklearnContract () payable{
        
   LogConstructorInitiated("Contract created. Call updateInference() to get a result");
    }

Здесь мы определяем конструктор и делаем его платным.

function __callback(bytes32 myid, string result, bytes proof) {
           require(msg.sender == oraclize_cbAddress()); 
           inference_result = result;
           LogInferenceUpdated(inference_result);
           
    }

Мы определяем обратный вызов, который будет выполнен после завершения нашего запроса. Мы меняем объявленное ранее значение результата.

function updateInference() payable {
        
        if (oraclize_getPrice("URL") > this.balance) { 
            LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
        } 
        else {
            LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer.."); 
            oraclize_query("URL", "json(http://<your_url_here>/prediction/api/v1.0/some_prediction?f1=1&f2=1&f3=1).result");
        }
    }

Здесь мы выполняем запрос Oracalize и убеждаемся, что можем за него заплатить. Если вы хотите использовать вышеуказанный контракт, обязательно измените ‹your_url_here› на свою конечную точку.

Ниже представлена ​​закомментированная версия смарт-контракта, app.py и requirements.txt.

Ссылки

  1. App.py является производным от App.py из https://github.com/Soluto/python-flask-sklearn-docker-template
  2. Смарт-контракт основан на примерах кода из документации Oracalize по адресу http://docs.oraclize.it/#ethereum.