Содержание

Создание контракта на Solidity

Контракт может быть создан “извне” через транзакцию в сети Ethereum или изнутри контракта Solidity.

Среды разработки с пользовательским интерфейсом (UI), такие как Remix, делают процесс разработки достаточно легким.

Создавать контракт программно в Ethereum лучше всего используя Javascript API web3.js. На сегодняшний день он имеет метод, называемый web3.eth.Contract, который облегчает создание контракта.

Когда контракт создан, его конструктор (функция, название которой совпадает с названием контракта) вызывается только один раз. Конструктор не обязателен. Позволяется использовать только один конструктор, и это означает, что перегрузка в Solidity не поддерживается.

Внутренне, аргументы конструктора передаются в ABI закодированными после кода самого контракта, но Вам не нужно об этом беспокоиться, если Вы используете web3.js.

Если смарт-контракт должен создавать другой контракт, то исходный код (и бинарный) создаваемого контракта должен быть известен создающему контракту.

pragma solidity ^0.4.16;

contract OwnedToken {
    // TokenCreator — это тип контракта, который определен ниже.
    // Это нормально, если он не используется для 
    // создания нового контракта.
    TokenCreator creator;
    address owner;
    bytes32 name;

    // Это конструктор контракта.
    function OwnedToken(bytes32 _name) public {
        // Глобальные переменные доступны по имени
        // и не доступны, например, через this.owner. Это также
        // относится к функциям, и особенно внутри конструктора,
        // их можно вызвать только так ("внутренне"),
        // потому что сам контракт еще не существует.
        owner = msg.sender;
        // Выполняется явное преобразование типа из `address`
        // в `TokenCreator` и предполагается, что тип
        // вызывающего контракта — TokenCreator. Нет 
        // реального способа это проверить.
        creator = TokenCreator(msg.sender);
        name = _name;
    }

    function changeName(bytes32 newName) public {
        // Только создатель контракта может изменить имя.
        // Сравнение возможно с того момента, когда контракты
        // конвертированы в адреса.
        if (msg.sender == address(creator))
            name = newName;
    }

    function transfer(address newOwner) public {
        // Только текущий собственник может переводить
        // токены.
        if (msg.sender != owner) return;
        // Заметьте, что здесь вызывается функция,
        // которая объявлена в контракте ниже. Если
        // вызов не удался, то выполнение здесь 
        // немедленно остановится.
        if (creator.isTokenTransferOK(owner, newOwner))
            owner = newOwner;
    }
}

contract TokenCreator {
    function createToken(bytes32 name)
       public
       returns (OwnedToken tokenAddress)
    {
        // Создание нового Токена и возврат его адрес.
        // Возвращаемый тип — просто `address`,
        // так как это самый закрытый тип в ABI.
        return new OwnedToken(name);
    }

    function changeName(OwnedToken tokenAddress, bytes32 name)  public {
        // И снова внешний тип `tokenAddress` — это
        // просто `address`.
        tokenAddress.changeName(name);
    }

    function isTokenTransferOK(address currentOwner, address newOwner)
        public
        view
        returns (bool ok)
    {
        // Проверка некоторого произвольного условия.
        address tokenAddress = msg.sender;
        return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff);
    }
}
Материал был полезен? Поделитесь в соц. сетях:
Логотип echain.ru

Добавить комментарий

Ваш e-mail не будет опубликован.