Содержание

Адрес в Solidity

address: Содержит 20-байтное значение (размер адреса в Ethereum). Также типы “адрес” имеют члены и служат основой для всех контрактов.

Операторы:

  • <=, <, ==, !=, >= и >

Примечание

Начиная с версии 0.5.0 контракты не вытекают из адреса, но все равно могут быть явно преобразованы в адрес.

Члены адреса

  • balance и transfer

Можно запросить баланс адреса, используя свойство balance, и отправить эфир (в единице wei) на адрес, используя функцию transfer:

address x = 0x123;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);

Примечание

Если x — это адрес контракта, то его код (более конкретно: его fallback-функция, если присутствует) будет выполнен вместе с вызовом transfer (это особенность EVM и она не может быть предотвращена). Если выполнение не удастся или закончится газ, то эфир будет возвращен, а текущий контракт прекратится с исключением.

  • send

send — это низкоуровневый аналог функции transfer. Если выполнение не удастся, то текущий контракт не остановится с исключением, но send вернет false.

Предупреждение

Существует несколько опасностей при использовании send: передача не удастся, если глубина стека вызовов достигнет 1024. Также, передача не удастся, если у получателя закончится газ. Поэтому для того, чтобы защитить передачу эфира, нужно всегда проверять возвращаемое значение функции send, использовать transfer или еще лучше — использовать шаблон, в котором получатель забирает деньги.

  • call, callcode и delegatecall

Чтобы взаимодействовать с контрактами, которые не придерживаются ABI, существует функция call, которая принимает произвольное число аргументов любого типа. Эти аргументы дополняются до 32 байтов и объединяются, за исключением случая, когда первый аргумент закодирован точно в 4 байта. В этом случае, он не дополняется, чтобы позволить использовать здесь сигнатуры функций.

address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("register", "MyName");
nameReg.call(bytes4(keccak256("fun(uint256)")), a);

call возвращает логическое значение, указывающее, была ли вызванная функция завершена (true) или было вызвано исключение EVM (false). Доступ к фактическим данным невозможен (для этого нужно было бы заранее знать кодировку и размер).

Можно регулировать предоставленный газ с помощью модификатора .gas():

namReg.call.gas(1000000)("register", "MyName");

Подобным образом можно контролировать значение эфира:

nameReg.call.value(1 ether)("register", "MyName");

Наконец, эти модификаторы можно объединять. Их порядок не имеет значения:

nameReg.call.gas(1000000).value(1 ether)("register", "MyName");

Примечание

Пока невозможно использовать модификаторы газа или значения для перегруженных функций. Обходным путем является введение специального случая для газа и значения, и повторно проверить, присутствуют ли они в месте разрешения перегрузки.

Подобным образом можно использовать delegatecall: разница в том, что используется только код данного адреса, а все другие аспекты (хранилище, баланс, …) берутся из текущего контракта. Цель delegatecall в том, чтобы использовать код библиотеки, который хранится в другом контракте. Пользователь должен убедиться, что расположение хранилища в обоих контрактах подходит для использования delegatecall.

Все три функции call, delegatecall и callcode очень низкоуровневые, их следует использовать как крайнее средство, поскольку они нарушают тип безопасности Solidity.

.gas() доступен для всех трем методов, в то время как .value() не поддерживается delegatecall.

Примечание

Все контракты наследуют члены адреса, поэтому возможно запрашивать баланс текущего контракта, используя this.balance.

Примечание

Использование callcode не рекомендуется, и эта функция будет удалена в будущем.

Предупреждение

Все эти функции низкоуровневые, и их нужно использовать с осторожностью. А именно, любой неизвестный контракт может быть вредоносным. И вызов этого контракта может вызвать другой контракт, поэтому нужно быть готовыми к изменениям переменных в этом другом контракте.

Материал был полезен? Поделитесь в соц. сетях:
Логотип echain.ru

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

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