Глава 3
____________________________________
[ 86 ]
___________________________________
По отношению к контракту
sample6
цепочка наследования имеет вид:
sample6, sample5, sample4, sample2, sample3, sample1
Цепочка наследования начинается с самого младшего контракта и заканчивается
самым старшим.
Абстрактные контракты
Контракты, которые содержат только прототипы функций, но не их реализацию,
называются
абстрактными контрактами
. Такие контракты не могут быть ском-
пилированы (даже если они содержат реализованные функции наряду с нереализо-
ванными функциями). Если контракт наследуется от абстрактного контракта и не
реализует все нереализованные функции путем переопределения, то такой контракт
сам становится абстрактным.
Абстрактные контракты объявляются только для того, чтобы сделать интерфейс
известным компилятору. Это полезно, когда вы обращаетесь к развернутому
контракту и вызываете его функции. Вот простой пример, который демонстрирует
такую ситуацию:
contract sample1
{
function a() returns (int b);
}
contract sample2
{
function myFunc()
{
sample1 s = sample1(0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970);
//без абстрактного контракта эта часть кода
//вызовет ошибку компиляции
s.a();
}
}
Библиотеки
Библиотеки почти не отличаются от контрактов, но их назначение состоит в том,
что они размещаются только один раз по определенному адресу, а затем повторно
используются различными контрактами. Это означает, что если вызываются функ-
ции библиотеки, то их код выполняется в контексте вызывающего контракта. Клю-
чевое слово
this
будет указывать на вызывающий контракт, и, что важно, можно
получить доступ к хранилищу вызывающего контракта. Поскольку библиотека
является изолированным фрагментом исходного кода, она может получить доступ
только к статическим переменным вызывающего контракта и только в том случае,
Разработка
смарт-контрактов
____________________________________
[ 87 ]
___________________________________
если доступ предоставлен в явном виде (в противном случае не будет иного спосо-
ба обращения).
Библиотеки не могут иметь свои статические переменные. Они не поддерживают
наследование и не могут получать эфир. Библиотеки могут содержать структуры и
перечисления.
Как только библиотека Solidity размещена в блокчейне, ей может воспользоваться
любой желающий, — если знает ее адрес и имеет на руках исходный код (только
прототипы или полную реализацию). Исходный код нужен компилятору Solidity,
чтобы убедиться, что методы, которые вы собираетесь вызывать, действительно
содержатся в библиотеке.
Ознакомьтесь с небольшим примером кода:
library math
{
function addInt(int a, int b) returns (int c)
{
return a + b;
}
}
contract sample
{
function data() returns (int d)
{
return math.addInt(1, 2);
}
}
Мы не можем вставить адрес библиотеки в исходный код контракта. Вместо этого
мы должны сообщить компилятору адрес библиотеки в процессе компиляции.
Библиотеки имеют много вариантов применения. Рассмотрим два основных случая
использования библиотек:
если у вас есть много контрактов, которые содержат общий код, вы можете по-
местить общий код в виде библиотеки. Это позволит сэкономить газ, потому что
расход газа зависит в том числе и от размера контракта. Следовательно, мы мо-
жем в некотором смысле воспринимать библиотеку как родительский контракт
по отношению к контрактам, которые ее используют. Но использование роди-
тельских контрактов вместо библиотек не приводит к экономии газа, потому что
при наследовании происходит копирование родительского кода. Поскольку биб-
лиотеки рассматриваются как родительские контракты, библиотечные функции
с ограниченной внутренней видимостью копируются в контракт, который их ис-
пользует. В противном случае внутренние функции библиотеки не могут быть
вызваны контрактом — ведь для этого потребуется внешний вызов, а внутрен-
ние функции не могут быть вызваны при помощи внешнего вызова;
Do'stlaringiz bilan baham: |