Язык Solidity: Глабальные переменные и функции блокчейна (Урок 6)
Язык Solidity: Глабальные переменные и функции блокчейна (Урок 6)
Предыдущие уроки:
Язык Solidity: Неllo World (Урок 1)
Язык Solidity: Типы данных (Урок 2)
Язык Solidity: Переменные состояния контракта (Урок 3)
Язык Solidity: Массивы и соответствия (Урок 4)
Язык Solidity: Структуры (Урок 5)
Что они есть и зачем
Эти элементы языка сообщают нам всю необходимую информацию о текущей транзакции, блоке. В функциях определена функцианальность взаимодействия с блокчейном непосредственно из контракта. Этакие системные вызовы Ethereum-a. Как уже привелось приведу аналогию с PHP: есть в PHP глобальные массивы $_SERVER, а также $_GET и $_POST. С помощью их элементов мы получаем системные данные, а также данные переданные от пользователя в запросе к PHP-скрипту. Так вот рассмотренные далее члены, можно поначалу сравнить с этими элементами языка PHP. А к функциям msg.send и suicide - можно привести аналогию echo и exit (хотя это не совсем так происходит технически - ну на то он и блокчейн, а не простой web-сервер).По привычки будем их изучать в контексте функций-оберток (ну вот такой я Java-люб :))
И так начнем по категориям.
Параметры текущего блока
Блок можно образно считать неким домом на длинной улице, а транзакции - его квартиры.
Вы можете узнать адрес своей управляющей компании, номер дома, дату его постройки и т.д.
Точно также блок - является глобальным объектом для транзакций (записей в нем), который в своем заголовке хранит необходимую информацию о своих свойствах.
Рассмотрим на примере как эти данные блока получит:
pragma solidity ^0.4.0;
/*
Параметры текущего блока
*/
contract ChainVars {
// block.coinbase - адрес майнера блока
function getBlockCoinbase() constant returns (address) {
return block.coinbase;
}
// block.number - номер текущего блока
// в разных форках блокчейна отличается
function getBlockNumber() constant returns (uint) {
return block.number;
}
// block.timestamp таймштамп блока (имеет псевдоним now)
function getBlockTimestamp() constant returns (uint) {
return block.timestamp;
}
// block.gaslimit лимит газа блока
function getBlockGaslimit() constant returns (uint) {
return block.gaslimit;
}
}
Параметры сообщения (вызова контракта)
Продолжая дальше нашу аналогию с домами:
Допустим несколько членов (или все вместе) одной семьи идут в гости в другую квартиру.
При этом в одну сторону улицы строятся все новые и новые дома, и все стараются переезжать в новостройки (про кого не забыли власти).
Ну а гости, как мы знаем обычно что-то с собой приносят. Либо гостинец, либо простуду. ;)
Таким образом msg.sender - гость собственной персоной (может даже еще не знакомый).
msg.value - это он нам денег (токенов в wei) принес, msg.gas - сколько времени и сил всему нашему дому пришлось потратить на прием (обслуживание) гостя, а msg.data, собственно то о чем гость пришел поболтать.
pragma solidity ^0.4.0;
/*
Параметры сообщения (вызова контракта)
*/
contract ChainVars2 {
// msg.data - данные, переданные при вызове
function getMsgData() constant returns (bytes) {
return msg.data;
}
// msg.gas - количество израсходованного (смайненого) газа
function getMsgGas() constant returns (uint) {
return msg.gas;
}
// msg.sender - отправитель (вызвавший аккаунт)
// В Remix это значение справа сверху на вкладке Run под типом VM
function getMsgSender() constant returns (address) {
return msg.sender;
}
// Это количество переданных вам ether-ов в wei
function getValueInWei() returns (uint) {
return msg.value;
}
}
Параметры транзакции
Ну здесь все просто: по какому курсу прием гостя (в wei) и кто его прислал.
pragma solidity ^0.4.0;
/*
Параметры транзакции
*/
contract ChainVars3 {
// цена на газ в wei
function getTXGasprice() constant returns (uint) {
return tx.gasprice;
}
// Адрес инициатора вызова (первый в цепочке вызовов)
// Это на случай, когда создана система контрактов (контракты вызывают друг-друга)
function getTXOrigin() constant returns (address) {
return tx.origin;
}
}
Информация об адресах и балансе
Ну и самый шикотильный вопрос, который нас интересует: сколько денег вообще у меня (this - именно контракта, а не его создателя), и у гостя (этот может быть и контрактом и реальным пользователем) всего.
pragma solidity ^0.4.0;
/*
Информация об адресах
*/
contract ChainVars4 {
// Возвращает адрес себя
// каждый раз при создании контракта из VM или другого контракта (new) - он будет новый
function whoiam() constant returns (address) {
return this;
}
// Таким образом мы можем узнать баланс на счету текущего контракта
function getCurrentBalance() constant returns (uint) {
return this.balance;
}
// Узнать баланс другого аккаунта можно так
function getBl() constant returns (uint) {
address adr1 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
return adr1.balance;
}
}
Есть еще функции: (address).send() - передает wei пользователю, (address).call() - вызывает его функции контракта, а также suicide().
Последняя позволяет контракту самоликвидироваться.
Но, поскольку все эти функции в моих уроках потребуют записи контрактов в блокчейн - то нам нужно будет установить и настроить geth и его установкой и изучению работы с ним мы займемся в следующем уроке.