政府は景気後退には陥っていないと言っていますが、同時に、経済のほぼすべての部門で急激なインフレ、金利の上昇、レイオフについて耳にしています。
仮想通貨とTradFiが最も深刻な影響を受けているにもかかわらず、多くの企業は依然としてトークン、プロトコル、およびDeFi製品を構築しています.あなたはその一人ですか?
今日はデータ型について話しますが、しばらくお待ちください。とても重要なお知らせがあります。 MIT の 60 歳以上の教授が、もはや重要ではない科目についての講義で学生を苦しめていると想像するかもしれません。しかし、そうではありません。
データ型は依然として重要であり、無視すると深刻な結果につながります。この記事を読むために費やした 8 分間が無駄にならないように、すべての潜在的な問題について簡単に説明し、対処するようにします。
JavaScript や Python などの最新の言語は、「ダック タイピング」を使用して変数の型を決定しています。この種の式a = 2 + 2
を変数に割り当てると、言語インタープリターはそれが数値を扱っていることを認識し、このリテラルに対して数学演算を実行します。
ダックタイピングは、「アヒルのように歩き、アヒルのように鳴くなら、それはアヒルに違いない」という言葉で説明できます。その意味を詳しく見てみると、それは完全に理にかなっています。リテラルに文字と数字が含まれている場合、それは文字列でなければならず、それは明らかです。しかし、数字がある場合はどうでしょうか。
boolean
、 integer
、 decimal
、 float
、またはdate
のどれですか。ほとんどの場合、言語インタープリターは型を正しい方法で処理します。問題は、プログラムが (単純な) 方程式を大量に実行する必要がある場合に始まります。
「アヒルのように歩き、アヒルのように鳴くなら、それはアヒルに違いない」ですよね?実際にはそうではありません。
次の段落では、イーサリアムの一般的な単位であるwei
とgwei
について言及しています。私たちが共通の言語を話すように、彼らを簡単に紹介しましょう。
最小単位は1ウェイで、 1 イーサは1,000,000,000,000,000,000 ウェイ(18 個のゼロ) に相当します。繰り返します-18個のゼロ。これほど多くの数に頭を悩ませるのは難しいことですが、それらは違いを生み、重要な意味を持ちます。
次の一般的な金種は1 gweiです。 1イーサは1,000,000,000 gwei (9 つのゼロ) に相当します。 Gwei は人間にとってより耐えやすいものです。 (ウインクウインク)
要約しましょう - 1 イーサは次のようになります。
テクニカル ノート: イーサリアムには、実行レイヤーとコンセンサス レイヤーの 2 つのレイヤーがあります。実行層はweiを使用してイーサ値を表し、コンセンサス層はgweiを使用しています。あなたがブロックチェーン開発者である場合は、両方とやり取りすることを学ぶ必要があります.
私はステークフィッシュのソフトウェア エンジニアです。私は DeFi 製品パレットの構築を担当しており、最新のものの 1 つは、イーサリアムのヒントと MEV プールです。
2022 年 9 月 15 日以降、すべてのバリデーターはトランザクションのヒントを得る資格があり、MEV に参加して追加の報酬を獲得できます。バリデーターが新しいブロックを提案すると、トランザクションのヒントと MEV が獲得されます。
私たちは、すべての報酬を共通の金庫に集め、ユーザーがそこから分け前を請求できるようにするスマート コントラクトを構築することにしました。私は私たちの製品を宣伝しようとしているわけではありませんが、この記事の文脈を設定する必要があります.
この製品にもっと興味がある場合は、ここで詳細を読むことができます。私の経験以外は何も売りません。
前述したように、バリデーターが獲得したトランザクションのヒントと MEV 報酬を受け取るスマート コントラクトがあります。これは、スマート コントラクトの残高がかなり大きいことを意味します。現在 963+ イーサ ($1.1M) であり、8671 人のバリデーターが貢献しています。
イーサリアムの実行とコンセンサス層の間の同期を担う重要な部分はOracleです。これは、どのバリデーターがプールに貢献しているかを判断できる非常に重要なシステムです。
オラクルは Python で書かれていますが、JavaScript で書くこともできます - 問題は変わらず、すぐに証明します。
コードを深く掘り下げましょう。
現在、スマート コントラクトの残高は 963,135,554,442,603,402,422 wei (963 イーサ) です。この数は、人間だけでなくコンピューター (正確には言語通訳者) にとっても理解しにくいものです。 JavaScript を確認してみましょう:
const vault_balance = parseInt("963135554442603402422") console.log(vault_balance) // 963135554442603400000 (lost 2422 wei in total)
string
からint
にバランスをキャストしただけで、すでに2422 wei
不足しています。まだ方程式を実行していません。
多くのバリデーターが貢献したおかげで、スマートコントラクトの残高は非常に高くなっています。それでは、契約残高の平均バリデータシェアを計算してみましょう。
const vault_balance = parseInt("963135554442603402422") const validator_count = 8671 const avg_validator_contribution = vault_balance / validator_count // 111075487768723730 (lost 7 wei per validator)
平均シェアは 0.111 イーサです。しかし、この金額は正しくありません。実際には 7 ウェイ足りません。全部で60,697 wei
です (7 wei x 8671 バリデータ)。後で正しい番号を表示します。
損失のうさぎの穴をさらに進んでみましょう - 与えられたバリデータごとの報酬の合計額を計算しましょう。ユーザーがバリデーターを開始するために 32 イーサを入金する必要があることに注意してください。そのため、バリデーターの残高からそれを差し引きます。
例として、32.779 イーサの残高を持つスマート コントラクトに貢献する 1 つのランダム バリデーターを取り上げます。
const vault_balance = parseInt("963135554442603402422") // (lost 2422 wei) const validator_count = 8671 const avg_validator_contribution = vault_balance / validator_count // (lost 7 wei) const initial_deposit = parseInt("32000000000000000000") const validator_balance = parseInt("32779333896000000000") const total_validator_rewards = validator_balance - initial_deposit + avg_validator_contribution // 890409383768723700 (lost 23 wei per validator)
このバリデーターが獲得した総報酬は 0.8904 イーサに相当しますが、この値も正確ではありません。この時点で、合計で199,443 wei
(23 ウェイ x 8671 バリデーター) の誤算がありました。ご覧のとおり、この数値の計算方法は持続可能ではありません。
上記のコードには 2 つの問題があります。
2^53 - 1
のみです。これは、 9007199254740991 wei
(0.009 イーサ) まで処理できることを意味します。
BigInt
を使用することもできましたが、除算に問題がありました。 「浮動」値になってしまいます。フロートは概算であるため、金融におけるすべての悪の根源です。つまり、精度が失われます。小数を使用する必要があります。 (10 進数と浮動小数点数の主な違いは、10 進数は正確な値を格納し、浮動小数点数は近似値を格納することです。)
JavaScript で Ethereum 関連のコーディングを行ったことがある場合は、 ethers.js
について聞いたことがあるはずです。このライブラリには、ブロックチェーンと対話するために必要なすべてのユーティリティが含まれています。上記の問題を解決するには、非常に大きな数をサポートし、小数を適切に処理するBigNumber
というツールの 1 つを使用します。
やってみましょう!
const vault_balance = BigNumber.from("963135554442603402422") // no loss const validator_count = BigNumber.from(8671) const avg_validator_contribution = vault_balance.div(validator_count) // no loss // 111075487768723723 const initial_deposit = BigNumber.from("32000000000000000000") const validator_balance = BigNumber.from("32779333896000000000") const total_validator_rewards = validator_balance.sub(initial_deposit).add(avg_validator_contribution) // 890409383768723723
ご覧のとおり、正確な数値が得られました。これが実際に正しい数値であることをどのように確認できますか?私が正しいことを証明するために、Python で同じ演習を繰り返します。
Python は長整数をサポートしているため、JavaScript で見られたように値が突然切り捨てられることはありません。残念ながら、デフォルトではすべての浮動小数点数をfloat
として決定します。
vault_balance = int("963135554442603402422") # no loss validator_count = 8671 avg_validator_contribution = vault_balance / validator_count # 111075487768723728 (5 wei too much) initial_deposit = int("32000000000000000000") validator_balance = int("32779333896000000000") total_validator_rewards = validator_balance - initial_deposit + avg_validator_contribution # 890409383768723712 (lost 11 wei)
どこで正確さが失われたのだろうか?部門はavg_validator_contribution
をdecimal
ではなくfloat
にキャストしました。正しいスニペットは次のようになります。
vault_balance = Decimal("963135554442603402422") validator_count = Decimal(8671) avg_validator_contribution = vault_balance / validator_count # 111075487768723723 initial_deposit = Decimal("32000000000000000000") validator_balance = Decimal("32779333896000000000") total_validator_rewards = validator_balance - initial_deposit + avg_validator_contribution # 890409383768723723
現在、Python と JavaScript によって返される値は正確です。自分でチェック!
この種の損失はごくわずかであり、簡単に見逃すことができます。多くの場合、それらが時間の経過とともに複合し、かなりの数に成長したときに、それらについて知ることができます.
このような状況は、開発者だけでなく、財務や法務などの他の部門にとっても常に頭の痛い問題です。数式は常にテストする必要があります。
Twitter で私をフォローしてくれたら、私にとって世界を意味します。私は、ソフトウェア エンジニアリングとブロックチェーンに活動の焦点を当てています。私は自分の作品のほとんどをオープンソース化しているので、私の GitHubをチェックしてみてください。