Простой смарт-контракт начинается с очень простого примера.
contract ZhaoxiStorage {
uint storedData;
function set(uint x) {
storedData = x;
}
function get() constant returns (uint retVal) {
return storedData;
}
}В Solidity контракт состоит из набора кода (функций контракта) и данных (состояния контракта). Контракт расположен по адресу в блокчейне Ethereum.
uint storeData Эта строка кода объявляет переменную состояния с именем StoredData и типа беззнакового целого числа uint. Его можно рассматривать как запись в базе данных, которую можно запрашивать и изменять, вызывая функции. В Ethereum обычно это может сделать только владелец контракта. В этом примере функции set и get используются для изменения и запроса значения переменной соответственно.
Как и во многих других языках, при доступе к переменным состояния нет необходимости добавлять такой префикс впереди.
Любой может вызвать метод set, чтобы установить номер, отличный от опубликованного вами. Но ваши номера останутся в истории блокчейна. Как увеличить лимиты доступа, мы узнаем позже.
Пример криптовалюты Следующий контракт реализует криптовалюту в ее простейшей форме. С помощью этого кода каждый может отправлять деньги другим без регистрации имени пользователя и пароля, если у него есть пара открытого и закрытого ключей Ethereum.
contract ZhaoxiCoin {
// Ключевое слово «public» делает переменную доступной вне контракта.
address public minter;
mapping (address => uint) public balances;
// Событие позволяет легким клиентам эффективно реагировать на изменения.
event Sent(address from, address to, uint amount);
// Код, создающий функцию, запускается только при создании контракта.
function ZhaoxiCoin() {
minter = msg.sender;
}
// Создатель контракта может позвонить в Mint
function mint(address receiver, uint amount) {
if (msg.sender != minter) return;
balances[receiver] += amount;
}
// send может быть вызван любым владельцем токена
function send(address receiver, uint amount) {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Sent(msg.sender, receiver, amount);
}
}address public minter Эта строка кода объявляет общедоступную переменную состояния типа адреса. Размер значения типа адреса составляет 160 бит, что подходит для хранения адреса контракта или чужих открытых и закрытых ключей. Ключевое слово public автоматически сгенерирует функцию доступа для изменяемой им переменной состояния. Переменные без ключевого слова public не будут доступны другим контрактам. Кроме того, можно писать только код внутри этого контракта. Автоматически генерируемые функции следующие:
function minter() returns (address) { return minter; }Следующая строка сопоставления кода (address => uint) public balances; Создается общедоступная переменная состояния, но ее тип более сложный. Этот тип сопоставляет некоторый адрес с беззнаковым целым числом. Отображение можно рассматривать как хеш-таблицу, и значение, соответствующее каждому возможному ключу, практически инициализируется нулями. Для сопоставления невозможно получить связанный список, содержащий все его ключи или значения. Поэтому нам нужно запомнить, что мы добавили в отображение. В этом примере функция доступа, сгенерированная ключевым словом public, будет более сложной, и ее код будет примерно следующим:
function balances(address _account) returns (uint balance) {
return balances[_account];
}Событие отправлено (адрес, адрес, значение uint) Эта строка кода объявляет «событие». Запускается последней строкой кода в функции отправки. Клиенты могут прослушивать эти события, вызванные блокчейном. При срабатывании события прослушиватель одновременно получит параметры from, to и value, которые можно удобно использовать для отслеживания транзакций. Чтобы прослушать это событие, вы можете использовать следующий код:
ZhaoxiCoin.Sent().watch({}, '', function(error, result) {
if (!error) {
console.log("ZhaoxiCoin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
" to " + result.args.to + ".");
console.log("Balances now:\n" +
"Sender: " + ZhaoxiCoin.balances.call(result.args.from) +
"Receiver: " + ZhaoxiCoin.balances.call(result.args.to));
}
}Здесь есть специальная функция ZhaoxiCoin. Это конструктор, который будет запущен при создании контракта и не может быть вызван позже. Он будет постоянно хранить адрес создателя контракта. msg (наряду с tx и блоком) — это глобальная переменная, содержащая некоторые свойства, принадлежащие блокчейну, к которым можно получить доступ с помощью кода контракта. msg.sender всегда сохраняет адрес внешнего вызывающего объекта текущей функции.
Наконец, функции, которые на самом деле вызываются пользователями или другими контрактами для выполнения функций этого контракта, — это mint и send. Если кто-то, кроме создателя контракта, позвонит в mint, ничего не произойдет. Отправить может вызвать любой человек (владеющий определенным количеством токенов) для отправки одних монет другим.
Выше приведен полный код и описание простой криптовалюты.