Как договор Ethereum может получать данные с веб-сайта?

Каков процесс /рабочий процесс за процессом, в котором контракт Ethereum получает некоторые данные с веб-сайта?

77 голосов | спросил Dawny33 20 Jpm1000000pmWed, 20 Jan 2016 19:48:00 +030016 2016, 19:48:00

4 ответа


75

Вы можете использовать Oraclize , чтобы сделать именно это. (Это пример Oracle - механизм получения информации о реальном мире в контракт и из него.)

Ниже приведены примеры здесь , а также документирование нашего API Solidity .

Oraclize доступен как на mainnet, так и testnet , так что с ним нужно быть уверенным, но если вам нужна любая поддержка, не стесняйтесь спрашивать - у нас даже есть канал gitter здесь .

Как вы видите, выборка данных с веб-сайта выглядит так: просто, используя функцию oraclize_query .

Наше хорошее поведение предоставляется TLSNotary и может быть легко проверено с помощью этот веб-монитор на стороне клиента .

Например, чтобы получить цену ETHXBT от тикера Kraken:

import "dev.oraclize.it/api.sol";

contract KrakenPriceTicker is usingOraclize {
    string public ETHXBT;

    function PriceTicker() {
        oraclize_setNetwork(networkID_testnet);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        oraclize_query("URL", "json(https://api.kraken.com/0/public/Ticker?pair=ETHXBT).result.XETHXXBT.c.0");
    }

    function __callback(bytes32 myid, string result, bytes proof) {
        if (msg.sender != oraclize_cbAddress()) throw;
        ETHXBT = result;
        // do something with ETHXBT
    }
} 
ответил Thomas Bertani 20 Jpm1000000pmWed, 20 Jan 2016 19:58:25 +030016 2016, 19:58:25
34

Вы не можете сделать это напрямую; Контракты Ethereum не могут пострадать от URL-адресов, потому что Ethereum нуждается в каждом, чтобы иметь возможность самостоятельно проверять результат выполнения любого данного контракта, и вы не можете гарантировать, что все они получат одинаковый результат от любого заданного URL.

Что вы можете сделать, так это получить стороннюю или комбинацию сторонних сторон, чтобы набрать URL-адрес для вас и рассказать вам, что они нашли. Они могут сделать это либо путем подписания данных, чтобы ваш контракт мог проверить подпись (это то, что мы делаем на Reality Keys ) или путем отправки данных из их контракта в ваш контракт (это то, что делают Oraclize).

Посмотрите Etheropt в GitHub для рабочего примера.

Недостатком этого подхода является то, что ваши пользователи должны доверять службе, которая нажимает на URL. Если эта служба повреждена или взломана, это приведет к появлению SFYL. (Oraclize предоставляет нотариальное подтверждение TLS, что данные, которые они предоставили, были данными, которые они предоставили вам, действительно были предоставлены по URL-адресу, но это действительно не помогает реальному риску безопасности. Обнаружение того, что они дали вам неправильный ответ, проблема в том, что ваш контракт по-прежнему будет принимать их ответ, хотя все знают, что они лгут ...)

Существуют некоторые потенциальные альтернативные подходы к этой проблеме, которые не зависят от репутации; Самый известный из них - Augur, который заставляет участников рынка голосовать за результат и имеет систему стимулов, которые, как они надеются, заставят людей голосовать честно. Кроме того, есть несколько интересных предложений между полностью доверенными службами и голосованием чистого пользователя, например Мартин Кёппельманн «Конечный оракул» .

ответил Edmund Edgar 27 MarpmSun, 27 Mar 2016 12:54:26 +03002016-03-27T12:54:26+03:0012 2016, 12:54:26
8

Подробное учебное пособие о том, как контракт может получить данные, был написан для клиента Python Ethereum (pyethapp):

https://github.com/ethereum/pyethapp /вики /Создание-а-User-Service: -Tutorial

  

Одной из самых сильных отличительных особенностей pyethapp является его способность   легко создавать встроенные пользовательские сервисы: скрипты, написанные на python   которые запускаются вместе с pyethapp и запускают код при запуске и каждый раз   вы получаете новый блок. Это позволяет создавать «серверные демоны»,   для приложений, для которых требуется периодическая автоматическая поддержка, например   RANDAO, каналы передачи данных, «децентрализованные приложения Dropbox», будильники,   децентрализованные службы облачных вычислений и т. д.

Pyethapp предоставляет on_start и on_block крючки, которые позволяют запускать код при запуске и при обработке блока. Пример кода из учебника:

https://github.com/ethereum/pyethapp/blob/разработка /примеры /urlfetcher.py

import json, re
import random
import sys
import ethereum.blocks
import ethereum.utils
import ethereum.abi
import rlp
try:
    from urllib.request import build_opener 
except:
    from urllib2 import build_opener

my_privkey = ethereum.utils.sha3('qwufqhwiufyqwiugxqwqcwrqwrcqr')
my_address = ethereum.utils.privtoaddr(my_privkey).encode('hex')
print 'My address', my_address
# Address of the main proxy contract
my_contract_address = ethereum.utils.normalize_address('0xd53096b3cf64d4739bb774e0f055653e7f2cd710')

# Makes a request to a given URL (first arg) and optional params (second arg)
def make_request(*args):
    opener = build_opener()
    opener.addheaders = [('User-agent',
                          'Mozilla/5.0'+str(random.randrange(1000000)))]
    try: 
        return opener.open(*args).read().strip()
    except Exception as e:
        try:
            p = e.read().strip()
        except:
            p = e
        raise Exception(p)


true, false = True, False
# ContractTranslator object for the main proxy contract
ct = ethereum.abi.ContractTranslator([{"constant": false, "type": "function", "name": "get(string)", "outputs": [{"type": "int256", "name": "out"}], "inputs": [{"type": "string", "name": "url"}]}, {"inputs": [{"indexed": false, "type": "string", "name": "url"}, {"indexed": false, "type": "address", "name": "callback"}, {"indexed": false, "type": "uint256", "name": "responseId"}, {"indexed": false, "type": "uint256", "name": "fee"}], "type": "event", "name": "GetRequest(string,address,uint256,uint256)"}])
# ContractTranslator object for the contract that is used for testing the main contract
ct2 = ethereum.abi.ContractTranslator([{"constant": false, "type": "function", "name": "callback(bytes,uint256)", "outputs": [], "inputs": [{"type": "bytes", "name": "response"}, {"type": "uint256", "name": "responseId"}]}])

app, my_nonce, chainservice = None, None, None

# Called once on startup
def on_start(_app):
    print 'Starting URL translator service'
    global app, my_nonce, chainservice
    app = _app
    chainservice = app.services.chain
    my_nonce = chainservice.chain.head.get_nonce(my_address)


# Called every block
def on_block(blk):
    global my_nonce, chainservice
    for receipt in blk.get_receipts():
        for _log in receipt.logs:
            # Get all logs to the proxy contract address of the right type
            if _log.address == my_contract_address:
                log = ct.listen(_log)
                if log and log["_event_type"] == "GetRequest":
                    print 'fetching: ', log["url"]
                    # Fetch the response
                    try:
                        response = make_request(log["url"])
                    except:
                        response = ''
                    print 'response: ', response
                    # Create the response transaction
                    txdata = ct2.encode('callback', [response, log["responseId"]])
                    tx = ethereum.transactions.Transaction(my_nonce, 60 * 10**9, min(100000 + log["fee"] / (60 * 10**9), 2500000), log["callback"], 0, txdata).sign(my_privkey)
                    print 'txhash: ', tx.hash.encode('hex')
                    print 'tx: ', rlp.encode(tx).encode('hex')
                    # Increment the nonce so the next transaction is also valid
                    my_nonce += 1
                    # Send it
                    success = chainservice.add_transaction(tx, broadcast_only=True)
                    assert success
                    print 'sent tx'

В руководстве объясняется:

  

По существу, экземпляр этой службы, выполняемой доверенной стороной, позволяетEthereum заключает контракты на доступ к любому каналу данных, доступному через   REST API через Интернет.

ответил eth 24 FebruaryEurope/MoscowbFri, 24 Feb 2017 00:43:40 +0300000000amFri, 24 Feb 2017 00:43:40 +030017 2017, 00:43:40
3

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

ответил Tomachi 20 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 20 Sep 2017 06:40:29 +0300 2017, 06:40:29

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132