Как сделать приватную функцию в Serpent?

Я читал этот учебник по контрактам и их реализации в Serpent и внизу страницы 13:

Каждый раз, когда мы ссылаемся на функцию внутри контракта, мы должны вызывать ее из себя (ссылка на текущий контракт). Обратите внимание, что любая функция может быть вызвана непосредственно пользователем. Например, предположим, что у нас есть функция A и функция B. Если у B есть логика, которая отправляет эфир, а A просто проверяет, должен ли быть отправлен эфир, и A вызывает B для отправки эфира, злоумышленник может просто вызвать функцию B. и получить эфир, даже не проходя проверку. Мы можем исправить это, не помещая этот тип логики в отдельные функции.

Мне не ясно, являются ли функции A и B частью одного и того же контракта. Может ли контракт вызывать функцию из другого на том же узле? Если да, то как он или как он может узнать свой экземпляр (себя)?

Я бы порекомендовал взглянуть на Solidity вместо Serpent, он неплохо справляется с этими проблемами.

Ответы (1)

A и B являются функциями в одном контракте.

Описанная проблема заключается в том, что наивная реализация B может быть вызвана кем угодно. В настоящее время Serpent не имеет «частного» модификатора, который можно было бы прикрепить к определенным функциям, поэтому его вызов вне контракта вызывает исключение. Сейчас это можно сделать, проверив, что caller( msg.sender) self:

def B():
    if msg.sender != self:
        ~invalid()
    # send the ether

В качестве альтернативы можно сделать B макросом. B не будет функцией и будет встраивать код B в A, эффективно реализуя то, что предлагает учебник: «Мы можем исправить это, не помещая этот тип логики в отдельные функции».


Контракт может вызывать другой контракт в Serpent, и его синтаксис похож на другие языки: «instance.foo» foo, где внутри selfбудет экземпляр.