Comments 83
Смотрю с точки зрения обычного программиста. В ваших смартконтрактах реально принято код загружать такими константами вида 1000000000000000000
? Ведь это какое-то наивное детское программирование, хоть и называется громким словом solidity. Это неправильно на кучу слоёв.
Слой 1. Можно легко пропустить где-нибудь нолик или неправильно их сосчитать и неправильно понять код. Язык должен позволять писать 1_000_000_000_000_000_000
. Если позволяет, программисты должны этим пользоваться.
Слой 2. Это всё равно неправильно, потому что вероятность ошибки с пропуском нолика существует до сих пор. Должна существовать предопределённая именованная константа вроде WEI_PER_ETHER = 1_000_000_000_000_000_000
, и в коде должна использоваться только она. Тогда станет понятнее, что происходит и вероятность ошибки ещё снизится.
Слой 3. И это всё равно неправильно, потому что можно неправильно сделать вычисления. Например, умножить там, где надо разделить, передав не 10-18, а 10+18 попугаев. Нужны предопределённые функции или макросы с понятными именами вроде convertWeiToEther(weiAmount)
и convertEtherToWei(etherAmount)
.
Слой 4. И это всё равно неправильно, потому что можно по ошибке забыть вызвать макрос. Должна быть объектная типизированная модель, исключающая возможность присваивания неправильного значения. Что-нибудь вроде WEI.amount(uint256 value)
возвращает объект типа Amount
, и чтобы получить сумму в эфире, надо вызвать WEI.amount(value).toEther()
. При этом не следует использовать сырые значения в числах слишком часто, только в исключительных случаях вроде окончательного обмена данными с внешним источником. В идеале это должно быть спрятано в методах родительских контрактов и всякие msg.value
уже должны иметь тип Amount
и писать надо msg.value.subtract(MY_TOKEN.amount(tokens))
, где константа Currency MY_TOKEN = createStableCurrency(Ether.amount(1/5000))
. Я придерживаюсь синтаксиса джавы, но это необязательно. Язык может и перегрузку операторов поддерживать, тогда можно писать msg.value - MY_TOKEN.amount(tokens)
, но при этом компиляция не пролезет, если попытаетесь эфир вычесть из токенов или сложить токены с веями.
Пока всё выглядит так, что детям дали бомбой поиграться. И не надо рассказывать мне про стоимость исполнения на Etherium VM. Хороший оптимизирующий компилятор можно выкинуть все эти слои абстракций, сгенерировав точно такой же конечный код.
Слой 1. Можно легко пропустить где-нибудь нолик или неправильно их сосчитать и неправильно понять код. Язык должен позволять писать 1_000_000_000_000_000_000. Если позволяет, программисты должны этим пользоваться.
Это уродство и никто так писать не должен. Если вам это нравиться — так и пишите, но про «должны» — забудьте.
Слой 3. И это всё равно неправильно, потому что можно неправильно сделать вычисления. Например, умножить там, где надо разделить, передав не 10-18, а 10+18 попугаев.
Зачем вообще жить, если можно что-то сделать неправильно? Неважно, какой разрядности числа — всё это теряется и от разрядности ничего не зависит. Это просто рассуждения человека, который не привык к логике за пределами плавучки.
Должна быть объектная типизированная модель, исключающая возможность присваивания неправильного значения.
Это тот же самый ЖС, где типизация тут прикручена сбоку. А такой модели нет в и жаве.
Что-нибудь вроде WEI.amount(uint256 value) возвращает объект типа Amount, и чтобы получить сумму в эфире, надо вызвать WEI.amount(value).toEther().
И что же это изменит? Мне это в рамках value как-то помешает ошибиться?
Ну и самое главное, что никакой «суммы в эфире» — нет. Автор сам настроил себе абстракций и сам же их и должен поддерживать. Т.е. WEI.amount(value).toEther() == value по определению. Тут прослеживается, опять же, узость мышления и вас и автора, которые не могут мыслить за рамками плавучки.
В идеале это должно быть спрятано в методах родительских контрактов и всякие msg.value уже должны иметь тип Amount и писать надо msg.value.subtract(MY_TOKEN.amount(tokens)), где константа Currency MY_TOKEN = createStableCurrency(Ether.amount(1/5000)).
Это пустые рассуждения. Есть уровень языка, а есть уровень рантайма. Это общая проблема людей из мира жавы и иже с ним, которые не отличают язык от рантайма.
Есть язык, не важно какой, он умеет только складывать чиселки. Есть некая система(ниже языка), которая экспортирует api в язык. Естественно, что это api существует в рамках «ниже языка» и уже поверх него нагромождаются всякие абстракции. И неважно кто поставщик этих абстракций — вендор языка, либо кто-либо ещё. Всё это существует за рамками языка.
Язык может и перегрузку операторов поддерживать, тогда можно писать msg.value — MY_TOKEN.amount(tokens), но при этом компиляция не пролезет, если попытаетесь эфир вычесть из токенов или сложить токены с веями.
Жава не поддерживает, как и 99% языков. Что дальше?
Опять же — попытка пихать и рассуждать в придуманных вами абстракциях на уровне «языка». Язык он про сложение чиселок. Так везде. В жаве нет логики «нельзя сложить рубли с доллары» — потому что это логика внешнего уровня.
Точно так же и тут. Токены — это логика внешнего уровня — на уровне языка/платформы их не существует. Точно так же как на уровне жавы не существует рублей. И почему-то вы не идёте и не жалуетесь на это.
Пока всё выглядит так, что детям дали бомбой поиграться. И не надо рассказывать мне про стоимость исполнения на Etherium VM. Хороший оптимизирующий компилятор можно выкинуть все эти слои абстракций, сгенерировав точно такой же конечный код.
Такого компилятора у жавы нет, как и у 99% языков. Что же с этим поделать? Откуда он должен взяться тут?
Ну и самое главное, как я уже говорил. Это мир жаваскрипта( и этот «язык» — это жаваскрипт) — там люди не знают о типизации, компиляторах и прочем. Хипстерский мир вообще компилятор увидел только с релизом ллвм. Точно так же, как в мире жавы не знают о компилтайме и мощной типизации, как это знают в том же мире С++.
В жаве нет логики «нельзя сложить рубли с доллары» — потому что это логика внешнего уровня.
Но в "жаву" такую логику можно при желании добавить. А тут — либо нельзя, либо можно, но как нам не рассказали. И на остальные ваши рассуждения — тот же самый ответ.
Но в «жаву» такую логику можно при желании добавить.
Сюда так же.
А тут — либо нельзя, либо можно, но как нам не рассказали.
Классы есть, типы есть, перегрузка есть. Вроде как всё необходимое есть, а уже далее — дело техники.
И на остальные ваши рассуждения — тот же самый ответ.
Да не тот же. Автор(комментария) предлагает взять из копеек сделать рубли в рамках целых чисел. Он предлагает делать из переменной как минимум пару, а это уже усложнение операций( что явно противоречит его концепции «компилятор все поправит»).
По мне так автор просто пытается натянуть свои представления из мира плавучки на данную ситуацию.
А проблема решается просто — не надо вводить новых сущностей. Это в реальном мире есть рубли и копейки, а в данном мире рублей нет.
Поэтому всё решается очень просто. Есть копейки. Есть цена в копейках за цент(токен). И всё сразу стало ясно и понятно.
Объясню ситуацию ещё проще. У автора была задача продать центы за копейки. Он ввёл для себя доллары, рубли. Исчисляет цены в них. Потом переводит значения одних в доллары, других в рубли, потом считает и потом переводит обратно. Вопрос — зачем?
Автор(комментария) предлагает взять из копеек сделать рубли в рамках целых чисел
Где я это предлагал? Я предлагал не работать с голыми числами вообще, ни с целыми, ни с дробными. Их надо видеть только в точках взаимодействия с внешними системами. А там уже тип зависит от того, который навязан внешней системой. Я ничего не говорил ни про целые, ни про дробные, ни про пару. Объект класса Amount может всё внутри переводить в ваши любимые вэи, может использовать дробные числа, может хранить пару, это без разницы. В этом суть абстракции. Завтра точности вэев станет недостаточно, поделят их ещё в тысячу раз и что тогда? Если у вас код абстрагирован от представления, поменять придётся только один класс.
Где я это предлагал?
Каноничный пример того, как «я не я и шкура не моя».
Я предлагал не работать с голыми числами вообще, ни с целыми, ни с дробными.
Нет, предполагалась логика именно плавучки и не иначе. Абстракция вот так взять и поменялось логику работы с данными/операциями. И попрошу я вас описать «как» и вы ничего не ответите.
А там уже тип зависит от того, который навязан внешней системой.
Не верно. В рамках зерокост абстракций( а именно их вы определили) тип очень даже влияет на абстракции.
Объект класса Amount может всё внутри переводить в ваши любимые вэи, может использовать дробные числа, может хранить пару, это без разницы.
Не верно. Типичный пример манипуляций, когда говорим одно, а после делаем вид, что говорили другое.
Вы говорили не просто об абстракциях, а о зерокост абстракциях. Вот тут:
Хороший оптимизирующий компилятор можно выкинуть все эти слои абстракций, сгенерировав точно такой же конечный код.
А теперь как удобно получается. Уже завелась шарманка об «а если», «а поменять один класс». Об этом вы изначально не говорили, а переобувание на ходу — любимый приём болтунов.
Нет, предполагалась логика именно плавучки и не иначе.
Вы таки считаете, что лучше знаете, что у меня в голове происходит, чем я сам? Боюсь, спорить и в чём-то не соглашаться с человеком, который так считает, абсолютно бессмысленно. Поэтому продолжать не буду.
Вы таки считаете, что лучше знаете, что у меня в голове происходит, чем я сам?
Глупая попытка. Никто и нигде верить вас не должен. Именно поэтому ваши «я считал так, а не иначе» — никого не волнуют. Вы пишите то, что пишите. И это интерпретирую так, как интерпретирую. Если вы не согласны — аргументируйте. «я так не думаю/ как вы знаете что я имел ввиду» — это глупо и это не работает.
Так бы в мире ничего не работало. Сказал одно, а потом «я не то имел ввиду».
А поводу плавучки — вот доказательства: habrahabr.ru/post/338084/#comment_10419964
Если вам это нравиться — так и пишите, но про «должны» — забудьте.
Во всех языках мира придуманы разделители групп разрядов. Где-то апостроф сверху, где-то запятая снизу, где-то пробел. Это сделали не потому что кому-то нравится, а потому что это снижает вероятность ошибки. Подчерки лишь пример синтаксиса, он может быть любым, но вероятность ошибки должен снижать.
Выражения про плавучку абсолютно не понимаю. При чём здесь какая-то плавучка? Я говорю, численное представление суммы должно быть абстрагировано. Неважно, что там внутри. А вы мне про какую-то плавучку. Я и слов-то таких не употребляю никогда.
Жава не поддерживает, как и 99% языков. Что дальше?
Яркий пример, когда хочется что-то сказать, а сказать нечего. Перегрузку операторов поддерживают многие языки. Из популярных больше поддерживают, чем не поддерживают. Да и суть не в этом, можно и .subtract
писать, это не сильно хуже.
Язык он про сложение чиселок. Так везде.
Какое-то у вас примитивное представление о программировании. Либо вы на ассемблере всю жизнь пишете, тогда простительно.
Такого компилятора у жавы нет, как и у 99% языков. Что же с этим поделать? Откуда он должен взяться тут?
Джавовый JIT (Hotspot C2) вполне способен на такие оптимизации. Я полагаю, Clang с кодом на C++ легко разделается тоже. Тут вполне тривиальная цепочка оптимизаций инлайнинга, эскейп-анализа и констант-фолдинга. Это всё в теории компиляции известно десятилетиями. Не знаю, что там в солидити, но учитывая, какие деньги крутятся в этериуме, хорошего компиляторщика нанять не должно быть большой проблемой.
Смысл последнего абзаца в том, что этериум = джаваскрипт и ничего с этим не поделаешь? Я думаю, в основу платформы никакая типизация не заложена и на ней вполне можно сделать нормальный язык, компилируемый в этериум. Либо он уже существует, просто автор этой статьи не умеет им пользоваться.
Во всех языках мира придуманы разделители групп разрядов. Где-то апостроф сверху, где-то запятая снизу, где-то пробел. Это сделали не потому что кому-то нравится, а потому что это снижает вероятность ошибки. Подчерки лишь пример синтаксиса, он может быть любым, но вероятность ошибки должен снижать.
Очередная манипуляция. Вам говорили не о какой-то там фиче в каких-то там языках, а ваших заявлениях на тему «программисты ДОЛЖНЫ использовать это».
Вот именно про «должны» и отвечайте.
Выражения про плавучку абсолютно не понимаю. При чём здесь какая-то плавучка? Я говорю, численное представление суммы должно быть абстрагировано. Неважно, что там внутри. А вы мне про какую-то плавучку. Я и слов-то таких не употребляю никогда.
Притом, вся ваша «логика» и ответы — это «пальцем в небо» и не более того. Я уже говорил о том, что это уровень языка, а не уровень ваших абстракций. Вы же это, благополучно, проигнорировали.
Вы пытаетесь требовать с языка и платформы интерфейсов для логики внешнего мира. Это то же самое, что с жавы требовать наличие абстракций для рублей. Ваши попытки изначально некорректны.
А по поводу плавучки — это прямо выводится из ваших предложений, ведь только в рамках неё рождается подобная логика. В противном случае — она бы просто не родилась бы.
Яркий пример, когда хочется что-то сказать, а сказать нечего. Перегрузку операторов поддерживают многие языки. Из популярных больше поддерживают, чем не поддерживают. Да и суть не в этом, можно и .subtract писать, это не сильно хуже.
Ярки пример пустой болтовни и глупых ссылок.
В верхней строке мы видим одну хипстоту, в половине которой вообще ваш синтаксис не работает и нет типизации. Т.е. мимо. В нижней строке из живого и типизированного — это кресты, сишарп — всё.
Где оно работает? В луа? Без типов и через жопу? Удачи сравнить веи с эфирами. Что там ещё. Пистон? К тому же, это всё рантайм и никакого зерокост.
Таким образом из всех языков подобное могут только кресты, скорее всего шарп/раст, но раст пока не взлетел.
И того — два языка. Скорее всего даже шарп не подойдёт и того — полтора. Один живой и второй не взлетевший.
Какое-то у вас примитивное представление о программировании. Либо вы на ассемблере всю жизнь пишете, тогда простительно.
Ну дак покажите мне операции уровня языка за рамками сложения чиселок. Это же просто и без болтовни.
Джавовый JIT (Hotspot C2) вполне способен на такие оптимизации.
Не способен. Причина проста — жава просто неспособна на подобные абстракции.
Я полагаю, Clang с кодом на C++ легко разделается тоже.
Я за вас уже сказал это. Зачем повторять?
Тут вполне тривиальная цепочка оптимизаций инлайнинга, эскейп-анализа и констант-фолдинга.
Тут вполне тривиальное перечисление знакомых базвордов. Как я уже говорил — опишите мне механизм подобных абстракций поверх uint256, который был бы зерокост. Его нет и именно поэтому вы его не опишите.
Это всё в теории компиляции известно десятилетиями. Не знаю, что там в солидити, но учитывая, какие деньги крутятся в этериуме, хорошего компиляторщика нанять не должно быть большой проблемой.
Опять же. Как мы уже выясниили — на подобное способен сишный компилятор и мистический хотспот. Остальные, как я понимаю, так же не способны нанять хорошего компиляторщика, да? Вот ведь идиоты.
Шланг всего-то всем миром пилят десятилетие, как и хотспот санраклом. А надо было просто нанять хорошего компиляторщика и он бы за пару лет сваял.
Именно поэтому ни у одного языка не было приличного компилятора до появления ллвм. Они так же — просто не додумались нанять хорошего компиляторщика. Бывает.
Смысл последнего абзаца в том, что этериум = джаваскрипт и ничего с этим не поделаешь? Я думаю, в основу платформы никакая типизация не заложена и на ней вполне можно сделать нормальный язык, компилируемый в этериум. Либо он уже существует, просто автор этой статьи не умеет им пользоваться.
Смысл последнего абзаца в том, что есть сообщество. Вы не способны думать в рамках обстоятельств реального мира. Причина — ваша специализация. Так же со всем остальным.
Вся эта тема существует и базируется в рамках жаваскрипт мира. А жаваскрипт стеком не пользуются «хорошие компиляторщиики» и прочее. Можно глянуть на какой-нибудь там тайпскрипт, который не язык, а хелворд. Но это максимум до чего дошел мир жаваскрипта. Хотя есть причина тому, хотя это больше оправдание — он совместим с ЖС.
WAT? Вы либо лежали в криогенной камере последние лет 10 и не в курсе, что Java-вский JIT сейчас умеет, а что нет. Либо просто болтаете о том, что чего в принципе не знаете. Не изволите ли уточнить, что из двух?Джавовый JIT (Hotspot C2) вполне способен на такие оптимизации.Не способен. Причина проста — жава просто неспособна на подобные абстракции.
Вы вообще различаете язык Java, JDK и JRE?
Вот объясните мне, эксперты, что с вами не так? Вы не умеете читать? Хотя что я могу ожидать от верующих — уж явно не объективности.
Специально для вас расшифрую.
Не способен. Причина проста — жава(язык) просто неспособна на подобные абстракции.
Расшифрую ещё более тщательно. Неважно какой там жит. Жит не выпилит ГЦ, жит не выпилит рантайм рефлексию, жит не наделит жаву нормальной типизацией, жит не сделает из дженериков что-то уровня крестовых шаблонов.
Так что вы своим комментарием подтвердили, что вы совершенно не компетентны для обсуждения того, что Java может, а что нет.
Именно он позволяет Java держать лидирующие позиции в тестах на производительность.
В мире влажных мечтаний адептов, возможно.
И повторюсь, это не что-то отдельное от Java — это часть стандартной JVM.
И что же из этого следует?
Так что вы своим комментарием подтвердили, что вы совершенно не компетентны для обсуждения того, что Java может, а что нет.
И что же конкретно я своим комментарием подтвердил и на основании чего.
uint256 tokens = tokensPerOneEther * msg.value / 1000000000000000000;
можно записать как
uint256 tokens = tokensPerOneEther * msg.value / 1 ether;
Но с точки зрения понимания сути оно мне кажется хуже, хотя и вероятность ошибки ниже.
Есть и другие полезные константы, типа minutes, days, years и т.п.
1 ether
получше, чем восемнадцать нулей, хотя скрывается тот факт, что оно выражено в веях. Возможно, это ничего, если все привыкли считать, что всё и всегда выражено в веях. Но оно опять же явно не так. В коде автора, например, есть tokensPerOneEther = 5000
, а вовсе не цена одного токена в веях. Очевидно, что не всегда удобно работать с веями, надо с разными единицами уметь.
Возможно, это ничего, если все привыкли считать, что всё и всегда выражено в веях.
Это именно то, о чём я говорил. Вы сознались в том, что не привыкли, а значит привыкли вы к чему? Правильно, к плавучке, где можно менять порядок как угодно и складывать величины разного порядка.
От того вам и не привычен константный порядок.
Но оно опять же явно не так.
Явно так.
В коде автора, например, есть tokensPerOneEther = 5000, а вовсе не цена одного токена в веях
Правильно, потому что автор так же пока не отвык от плавучки. И именно в веях она и должна быть выражена.
Очевидно, что не всегда удобно работать с веями, надо с разными единицами уметь.
Очевидно, что вам удобно игнорировать те обстоятельства, о которым вас сообщают. Токены — это левая логика. Её не существует в рамках платформы. Это не аналог веям.
На уровне платформы существуют только веи. И никаких других единиц попросту не существует.
На уровне платформы существуют только веи. И никаких других единиц попросту не существует.
Но на входе-выходе существуют эфирные монеты и много чего ещё. У НАСА был спускаемый аппарат, который навернулся из-за нестыковок между метрической и имперской системой. Вы постоянно "тычете" оппонента в "плавучку", которой в его комментариях нет. Он как раз говорит о такой штуке, как единицы измерения, закодированные в виде типов. Это сильно уменьшает вероятность ошибки, т.к. при попытке комбинирования в одной операции вы либо получите ошибку компиляции, либо корректное преобразование, закодированное один раз в логике типа.
Но на входе-выходе существуют эфирные монеты и много чего ещё.
Не существует.
У НАСА был спускаемый аппарат, который навернулся из-за нестыковок между метрической и имперской системой.
Это к теме отношения не имеет. Решение проблемы не в кастылянии, а в приведении всего к одному виду. И именно про это я и говорю.
Он как раз говорит о такой штуке, как единицы измерения, закодированные в виде типов.
Нет. Он уже уплыл с темы 10 раз и слушать, что говорят подобные персонажи — себе дороже. Сначала он говорил про зерокост, потом вдруг о зерокосте забыл и прочее и прочее.
Так же, я на этот так же отвечал, но он это проигнорировал. Эфирные монеты и прочее и прочее — это логика сверху языка. Т.е. как в жаве логика работы с рублями. Вы же не требуете от жавы готовой логики работы с рублями? На входе ведь рубли есть.
Плюс, он путает( как и большинство) язык и рантайм. Т.е. язык и набор библиотек, которые поставляются с языком. Я об этом так же говорил. Так же — он не понимает, что токены — это не сущности платформы, а сущности внешние. Я об этом так же сказал.
Никто не говорит о том, что не надо делать удобные обёртки/абстракции. Я говорил о другом, а именно о взаимоисключающих параграфах в предложении данного персонажа. Не надо мне приписывать что-то не моё.
Вы постоянно «тычете» оппонента в «плавучку», которой в его комментариях нет.
Если там нет слова «плавучка» — это не значит, что её там нет. Если вы не можете это вывести сами, то я вам показал цитату, в которой персонаж явно говорил о том, что логика с константным порядком ему непривычна.
Это сильно уменьшает вероятность ошибки, т.к. при попытке комбинирования в одной операции вы либо получите ошибку компиляции, либо корректное преобразование, закодированное один раз в логике типа.
Нельзя преобразовать сантиметры в метры не потеряв сантиметров. Всё это не работает. Вы предлагаете, опять же, экспортировать логику плавучки.
В логике же данной единственные операции, которые имеют смысл — это fromEther и прочее, что итак есть — выше уже показали. Это просто набор констант для смены порядка.
Эти константы позволяют вам приводить любые величины к общему виду — веям. И никаких проблем с преобразование дальше нет. Хотя что-то отличное от веев — вы сами туда тащите.
Ни в чём другом, кроме веев, считать по определению нельзя.
закодированное один раз в логике типа.
Нельзя считать в других типах. Нельзя в рамках точности милиметры считать в сантиметрах. Это всё плавучка — гоните её, либо сознайтесь в этом.
Всякий раз как вы говорите об эфирах — вы подразумеваете плавучку. Именно плавучка для вас меньшие единицы превращает в доли. Именно поэтому вы так просто рассуждаете о типах-эфирах и прочем( том же преобразовании).
За рамками её просто эфиров быт не может. К эфиру надо прикрутить ещё остаток. И уже у нас не эфир, а пара. И уже во много раз больше операций. И где обещанный зерокост?
Я даже не понимаю как это должно и может работать. WEI.amount(value).toEther() — что мы получаем? Только эфиры? А где веи? А если это веи, то чем они отличаются от веев? Это веи + эфиры? Как это.
Вкладка «Contracts», раздел «Custom tokens», кнопка "+ Watch token"
0x0AfFa06e7Fbe5bC9a764C979aA66E8256A631f02
Token name: Polybius Token
decimals: 6
symbol: PLBT
После этого на странице с аккаунтом, на который закинули plbt появится баланс PLBT и возможность куда-то эти токены отправить.
Это просто цифра внутри контракта, которая говорит, что адресу X принадлежит Y токенов. Поэтому переживать не о чем.
а также содержит ряд известных уязвимостей на уровне компилятора языка Solidity, например, подвержен так называемой short address attack
ЁПРСТ! Вы хотите сказать, что существует уязвимость компилятора, которая делает нормальные с виду контракты уязвимыми — и она до сих пор не закрыта?
При написании нормального смартконтракта нужно думать о куче дополнительных вещей, о которых не всегда думают при обычном программировании: стоимость выполнения тех или иных операций (выраженная в деньгах), максимальные ограничения на стоимость в рамках одной транзакции (чтобы контракт не заблокировался), ну и куча ошибок компиллятора, которые надо знать и на уровне кода от них защищаться. Об этом, возможно, еще напишу другие посты.
стоимость выполнения тех или иных операций (выраженная в деньгах)
В идеале об этом должен компилятор думать. Он должен это измерять, компилировать, оптимизируя именно эту стоимость, выдавать вам советы в виде предупреждений и т. д. В светлом будущем, наверно, так и будет :-)
Достаточно системно рассматриваются примеры на официальном сайте ethereum.org.
Если программируете свободно на других языках, то можно попробовать такой формат — learnxinyminutes.com/docs/solidity.
Ну а перед сном надо читать вот это — solidity.readthedocs.io/en/develop/contracts.html
Контракт «owned» полностью работоспособен и предельно прост, однако несет в себе одну скрытую угрозу, ведь при вызове функции «changeOwner» мы можем по ошибке указать несуществующий адрес, а значит, потеряем контроль над контрактом
А как у Вас проверяются «полномочия» нового владельца? Насколько я понимаю в вашем варианте любой желающий может использовать функцию «changeOwner» и стать новым владельцем. Или это не так?
смены владельца на случай, если наш private key будет скомпромитирован,
Скомпрометирован — значит стал известен посторонним/утерян/и т.д…
Таким образом тот кому стал известен private key меняет владельца на свой адрес. В чем тогда смысл этой функции? Видится что только в гонке — кто быстрее сменит адрес владельца — настоящий владелец или посторонний которому стал известен private key
Бывают ситуации, когда вы не уверены, скомпрометирован ключ или нет. К примеру, машина с ключом была заражена вирусом или доступ к ней получил посторонний. В такой ситуации лучше перестраховаться и перенести все привязанные контракты на другой ключ. В принципе да, именно в гонке и смысл. Злоумышленник мог не целиться прямо на ключ, а просто получить всю информацию из взломанной системы и неспеша с ней разбираться. Тогда есть все шансы его опередить.
Скомпрометирован не означает "украден". Предполагается, что у владельца есть в запасе какое-то время.
Также можно указать себя в качестве автора контракта, конечно, если вы не пишете контракт для какого-нибудь скамового проекта, где стесняетесь указать себя в качестве автора.Вот это просто убило.
/sarcasm/
Разумеется, если ты не указываешь себя как автор, то это только потому что проект скамовый. Не по какой-либо другой причине. Анонимность вообще зло. Даешь доступ в интернет по паспорту. Криптовалюты ведь и созданы для однозначной идентификации пользователей. Открой все данные о себе, ведь тебе нечего скрывать, а если не открываешь, то значит ты занимаешься скамом и твое место тюрьма.
/sarcasm/
Нет, понятно, что мы overreacting, но блин, именно фразы вида «если стесняешься указать себя в качестве автора, значит тебе есть что скрывать, значит ты пишешь скамовый проект» и есть тот ручеек, с которого начинается та самая река. И особенно цинично это звучит в проектах связанных с криптой.
На самом деле, рассмотренный смартконтракт в чистом виде скам, т.к. объективно никак не защищает интересов инвесторов (покупателей токенов). Такие контракты не должны быть в боевых проектах. Он всего лишь демонстрирует принципы организации краудсейла с технической точки зрения.
Касательно анонимности и ICO. Не открою америку, если скажу, что и в классическом венчуре и в ICO деньги дают прежде всего команде. Успешные анонимные ICO — большая редкость. Поэтому если вы не делаете скам (в проекте, в смартконтракте), то напишите, кто Вы есть такой, чтобы инвесторы видели, что Вы готовы ответить за базар:) Но это лишь мое мнение, возможно, я идеализирую. Но в нашим проектах PROVER и OpenLongevity мы руководствуемся именно такими принципами.
Ощущается явная проблема с чувством юмора:)Выбор темы для шуток лучше характеризует человека, чем его серьезные речи:)
Поэтому если вы не делаете скам (в проекте, в смартконтракте), то напишите, кто Вы есть такой, чтобы инвесторы видели, что Вы готовы ответить за базар:)На самом деле это не дает никакой «ответственности за базар», Вы путаете направление подтверждения:)
Подпись в ico нужна только если Вы хотите доказать что это Ваш ico.
А вот ответственность за него Вы будете нести только если Вы вне ico подтвердите что это Ваш ico, подпись в ico для ответственности за базар не нужна.
Упрощенно говоря если в ico указаны данные Васи Пупкина, то с Васи Пупкина на этом основании Вы ни копейки не стрясете. Это с одной стороны.
С другой стороны если Вася Пупкин где-то вне ico признался что это его ico, то Вы и без подписи в ico сможете стрясти с него копеечку.
Ну и контракты по ссылке не стоит считать эталоном — например, они подвержены той же short address attack.
Вот мой контракт проекта PROVER действительно прекрасен, но он реализует вполне конкретную бизнес-логику, требуемую именно для моего проекта.
Думаю, для меня была бы полезна статья про Ethereum VM. Конечно, я могу найти ее и в другом месте, но мне понравился ваш слог и вы явно разбираетесь в теме, так что, думаю, ваша статья на Хабре по этой теме была бы полезна.
```contract Crowdsale is owned {
uint256 public totalSupply;
mapping (address => uint256) public balanceOf;
event Transfer(address indexed from, address indexed to, uint256 value);
function Crowdsale() payable owned() {
totalSupply = 21000000;
balanceOf[this] = 20000000;
balanceOf[owner] = totalSupply — balanceOf[this];
Transfer(this, owner, balanceOf[owner]);
}
function () payable {
```
?
contract EasyCrowdsale is EasyToken {
function EasyCrowdsale() payable EasyToken() {}
function withdraw() public onlyOwner {
owner.transfer(this.balance);
}
}
ИМХО должен быть первым адрес кошелька куда владелец отправит\снимет токены? как определено выше
function transfer(address _to, uint256 _value) public {…
function withdrawToUserWallet(address _to, uint256 _value) public returns(bool success){
balanceOf[msg.sender] > _value;
return msg.sender.transfer(_to, _value);
}
Я конечно не эксперт, но не подвержен ли ваш контракт проблемам с reentrancy?
Перевод эфира должен вызвать такой же обработчик по умолчанию на sender
, который в ответ может передать еще эфира контракту ICO, вызвав тем самым обработчик по умолчанию...
Насколько я понял, речь шла о вот этой строчке: msg.sender.transfer(msg.value - valueWei);
Такая ситуация может возникнуть например вот в каком случае. Рассмотрим немного модифицированный контракт, который умеет делать withdraw не только владельцу — но и на любой указанный владельцем адрес. И предположим, что владелец того контракта решил сделать withdraw на адрес нашего (не спрашивайте зачем, допустим это была ошибка). При этом суммарная переведенная сумма оказалась больше чем у нас оставалось токенов.
В итоге делается посылка "сдачи" обратно отправителю, что интерпретируется тем контрактом как покупка токенов, но поскольку токены там уже закончились, сумма возвращается обратно к нам.
Что произойдет в таком случае? Это будет цикл или рекурсия?
То есть все-таки рекурсия, а не цикл?
Но тогда это можно попробовать превратить в атаку, за счет того что balanceOf[this]
меняется уже после перевода "сдачи". Например, если в такой смартконтракт добавить миграцию на новую версию с голосованием токенами, злоумышленник может купить себе количество токенов, достаточное для "кворума", и сменить контракт на свой.
(сообщение удалено)
Также пр разработке посмотрите на фреймворк truffle, позволяет запускать юниттесты
Смарт контракты Ethereum: пишем простой контракт для ICO