Как создать смартконтракт «для простых смертных»

Как только начинаешь читать обзоры и возможности криптовалют чуть более чем все время на глаза попадаются слова «смартконтракты» и какие они прикольные, но вот с чего начать и как сделать это «небольно»… Для моих ребят и для всех заинтересованных — эта статья с картинками.

Как работать с Ethereum

Один из самых простых способов — и точно первый с которым стоит познакомиться — онлайн «кошелек» https://www.myetherwallet.com (часто также упоминается как MEW).
В нем Вы можете выбрать «тестовую» сеть — чтобы не платить реальными деньгами, либо платить ими — по Вашему желанию. Что собственно такое «платить» — это вводить свой приватный ключ к кошельку, на котором деньги (ETH) лежат.

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

После того как Вы получили ключ — Вы можете прямо там управлять деньгами или «создавать» контракты (зачем мы собственно это сейчас и делаем). Просто вставьте и нажмите «unlock»

Теперь ура ура — у нас есть адрес (0xB4DB2292B5B1c3A70EfcB59449cAf1ED313e33ba) — это как раз можно всем давать и слать на него ETH с бирж или обменников и тд — пока приватный ключ в тайне спрятан — или файл с ключем или любой другой способ его сокрытия — деньги на этом адресе надежно спрятаны…. Простите за повторения, но это на самом деле важно. После — Вы узнаете и про multisig адреса, и про trezor и остальное — но для новичка обязательно намертво уяснить что приватный ключ должен быть надежно укрыт.

Как создать Контракт

Тестовые сети — это как настоящая сеть Ethereum (по возможностям), только никто там не отвечает что сеть не «перегрузят» через пару дней, поэтому ETH в тестовой сети можно получить бесплатно (и проводить эксперименты бесплатно). На живой сети создание контракта стоит от нескольких долларов в зависимости от сложности кода.

В нашем же кошельке — есть вкладка «использовать контракты» и выбор тестовой сети. Про разные сети тут я оставляю Вам как домашнее задание почитать — это на личный вкус и цвет, вплоть до того что даже локальную сеть (testrpc) можно включить к этому же интрефейсу…

Но когда мы уже все поняли — и нажали кнопку «deploy» — то что мы видим? какой-то противный «байткод», когда читали мы до этого только о solidity языке (или еще чем-то, но давайте начнем с solidity как максимально простого веб-разработчикам).

Как получить код Контракта

Есть опять таки много разных способов — но я предлагаю начать с простейшего онлайн редактора Remix

Как мы видим код достаточно простой, если мы где-то допустим ошибку редактор нам поможет, ну а сам текст кода и мои комментарии ниже:

pragma solidity ^0.4.13; //обязательно имя компилятора
 
 //имя контракта обязательно, какбы имя класса
contract Test {
    //какая-то переменная
    //ее публичность говорит что читать ее можно "снаружи" класса
    //в данном случае - адрес владельца
    address public owner;
 
    //еще одна переменная 
    uint8 public maxResult;
 
    //конструктор класса = имя совпадает! вызывается при создании контракта один раз
    function Test() {
        //msg массив переменных транзакции с которой связано выполение кода, в данном случае мы владельца делаем от создателя транзакции (логично)
        owner = msg.sender; 
        maxResult = 100;
    }
 
    //дефолтная функция класса (и чтобы никто ничего нам не бросал - все транзакции отклоняем такие
    function() {
       revert();
    }
 
    //функция константа, она не требует транзакции тк не меняет ни одну переменную в контракте) поэтому бесплатно!
    function getResult(uint index) constant returns (uint8 a) {
        //да, есть еще другие системные переменные кроме msg)
        bytes32 blockHash = block.blockhash(index); 
        //и немного криптографических функций тоже есть
        bytes32 shaPlayer = sha3(owner, blockHash);
        //такой себе рендом от номера блока
        a = uint8(uint256(shaPlayer) % maxResult);
    }
}

А вот и в правой вкладке редактора нажав Contract details (bytecode, interface etc.) мы получаем тот самый байткод…

Как проверить на testrpc

Самый опять таки простой способ — скопировать инициализацию для web3 и запустить ее на локальной тестовой сети testrpc (ставить реально пару минут https://github.com/ethereumjs/testrpc).
Web3 — библиотека также не сложная — вот тут https://github.com/ethereum/web3.js можно скачать дистрибутив и почитать инструкции

try {
    var url = "http://localhost:8545";
    var web3 = new Web3(new Web3.providers.HttpProvider(url));
 
    window.addEventListener('load', function () {
        UiAlerts.addSuccess('web3', 'loaded');
		ContractsInit.load();
    });
} catch (e) {
    UiAlerts.addError('web3', e.toString())
}
 
var ContractsInit = {
    load: function () {
        var browser_test_sol_testContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"maxResult","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"getResult","outputs":[{"name":"a","type":"uint8"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":false,"type":"fallback"}]);
		Random.contract = browser_test_sol_testContract.new(
		   {
			 from: web3.eth.accounts[0], 
			 data: '0x6060604052341561000f57600080fd5b5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600060146101000a81548160ff021916908360ff1602179055505b5b6102468061007d6000396000f30060606040523615610055576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635d109aea146100685780638da5cb5b14610097578063995e4339146100ec575b341561006057600080fd5b5b600080fd5b005b341561007357600080fd5b61007b610129565b604051808260ff1660ff16815260200191505060405180910390f35b34156100a257600080fd5b6100aa61013c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156100f757600080fd5b61010d6004808035906020019091905050610161565b604051808260ff1660ff16815260200191505060405180910390f35b600060149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000834091506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140182600019166000191681526020019250505060405180910390209050600060149054906101000a900460ff1660ff16816001900481151561020f57fe5b0692505b50509190505600a165627a7a723058202d0cf04bc29b6f94f56a6b4351d6901430660f49e621bb035ff15c334d2612810029', 
			 gas: '4300000'
		   }, function (e, contract){
			if (typeof contract.address !== 'undefined') {
				 UiAlerts.addSuccess('Contract mined', contract.address);
				 ContractsInit.finish();
			}
		 })
	},
    finish: function () {
        $('#loading_boxes').hide();
        $('#loaded_boxes').show();
		UiAlerts.addSuccess('1', Random.contract.getResult(1));
		UiAlerts.addSuccess('2', Random.contract.getResult(2));		
    }
};
 
var Random = {
    contract : false
};

Приблизительно так (я вспомогательные классы не привожу вывода, это думаю не сложно). А вот то что статическая функция вызывается бесплатно — и видите мы даже ей ключа никакого не дали!!! — Random.contract.getResult(1) — это прямо супер!

Создание Контракта — Деплой!

Обратите внимание — с Remix можно тоже Publish делать, но раз мы с MEW начали — им и закончим.

Адрес контракта мы получим просто посмотрев транзакции по нашему адресу кошелька (с которого приватным ключем или файлом подписали создание) на http://etherscan.io/

Использование Контракта

Вот наш контрактик — можем выложить код, можем потом — главное он уже есть)

Мы берем адрес, abi нашего контракта (помните мы выписывали байткод и какбы хедер после компиляции для локального теста — так вот это он))))

[{"constant":true,"inputs":[],"name":"maxResult","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"getResult","outputs":[{"name":"a","type":"uint8"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":false,"type":"fallback"}]

И мы можем выполнить любую его «открытую» функцию (аж одну в нашем случае) или взять значение текущее переменной (две) — итого три варианта)

Оставить комментарий

XHTML: Вы можете использовать такие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">