+ {JSON.stringify(attrs.object, null, 2)}
+```
+
+ほとんどのフィールドは、[`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp)を使用して表示されます。
+
+```tsx
+
+ { funs.length > 0 &&
+ <>
+ Functions:
+ @`を含むコメントは、 [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) を通じて人間が読みやすいドキュメントに変換されます。
+Vyperのコメントは、Pythonと同様に、ハッシュ記号(`#`)で始まり、行末まで続きます。 `@<キーワード>`を含むコメントは、[NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html)によって、人間が読める
+ドキュメントを生成するために使用されます。
```python
from vyper.interfaces import ERC721
@@ -33,176 +35,206 @@ from vyper.interfaces import ERC721
implements: ERC721
```
-ERC-721インターフェイスは、Vyper言語に組み込まれています。 [コードの定義はこちら](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py)をご覧ください。 インターフェイスの定義は、VyperではなくPythonで書かれています。これは、インターフェイスがブロックチェーン内だけでなく、Pythonで書かれた外部クライアントからブロックチェーンにトランザクションを送る際にも使われるからです。
+ERC-721インターフェイスはVyper言語に組み込まれています。
+[コードの定義はこちらで確認できます](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py)。
+インターフェイスの定義はVyperではなくPythonで書かれています。なぜなら、インターフェイスはブロックチェーン内で使用されるだけでなく、Pythonで書かれている可能性のある外部クライアントからブロックチェーンにトランザクションを送信する際にも使用されるからです。
-第1行はインターフェイスをインポートし、第2行はここで実装することを指示します。
+最初の行でインターフェイスをインポートし、2行目でここで実装することを指定しています。
-### ERC-721のReceiverインターフェイス {#receiver-interface}
+### ERC721Receiverインターフェイス {#receiver-interface}
```python
-# Interface for the contract called by safeTransferFrom()
+# safeTransferFrom()によって呼び出されるコントラクトのインターフェイス
interface ERC721Receiver:
def onERC721Received(
```
-ERC-721は、2つの送信方法をサポートしています。
+ERC-721は2種類の送金をサポートしています。
-- `transferFrom`は、送信者が任意の送信先アドレスを指定するもので、送信の責任は送信者が担います。 このため無効なアドレスにも送信できますが、その場合はNFTは永遠に失われます。
-- `safeTransferFrom`は、送信先アドレスがコントラクトかどうかを確認します。 送信先アドレスがコントラクトであることを確認すると、ERC-721コントラクトが受信側のコントラクトにNFTを受け取りたいかどうかを尋ねます。
+- `transferFrom`: 送信者が任意の宛先アドレスを指定でき、
+ 送金の責任は送信者にあります。 これは、無効なアドレスに送金できることを意味し、その場合
+ NFTは永久に失われます。
+- `safeTransferFrom`: 宛先アドレスがコントラクトであるかどうかをチェックします。 もしそうであれば、ERC-721コントラクトは
+ 受信側のコントラクトにNFTを受け取りたいかどうかを尋ねます。
-`safeTransferFrom`リクエストに応答するには、受信側コントラクトが`ERC721Receiver`を実装していなければなりません。
+`safeTransferFrom`リクエストに応答するには、受信側コントラクトが`ERC721Receiver`を実装する必要があります。
```python
_operator: address,
_from: address,
```
-`_from`のアドレスは、トークンの現在の所有者のアドレスです。 `_operator`のアドレスは、 送信を要求したアドレスです(アローワンスにより、これらの 2 つが同一でない場合があります)。
+`_from`アドレスは、トークンの現在の所有者です。 `_operator`アドレスは、
+送金をリクエストしたアドレスです(アローワンスのため、この2つは同じでない場合があります)。
```python
_tokenId: uint256,
```
-ERC-721トークンのIDは、256ビットです。 通常トークンIDは、トークンの内容をハッシュ化して生成されます。
+ERC-721トークンIDは256ビットです。 通常、トークンIDはトークンが表すものの説明を
+ハッシュ化して作成されます。
```python
_data: Bytes[1024]
```
-このリクエストには、最大1024バイトのユーザーデータを含めることができます。
+リクエストには最大1024バイトのユーザーデータを含めることができます。
```python
) -> bytes32: view
```
-コントラクトが誤送信を受け入れるケースを防止するため、戻り値はブール値ではなく、256ビットの特定の値になっています。
+コントラクトが誤って送金を受け入れるケースを防ぐため、戻り値はブール値ではなく、
+特定の価を持つ256ビットです。
-この関数は`view`関数であるため、ブロックチェーンの状態を読み取るだけで、変更はできません。
+この関数は`view`であり、ブロックチェーンの状態を読み取ることはできますが、変更することはできません。
### イベント {#events}
-[イベント](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e)は、ブロックチェーン外のユーザーおよびサーバーにイベントを通知するために発行されます。 イベントの内容は、ブロックチェーン上のコントラクトでは利用できないことに注意してください。
+[イベント](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e)は、ブロックチェーン外のユーザーやサーバーにイベントを通知するために発行されます。 イベントの内容は、ブロックチェーン上のコントラクトからは
+利用できないことに注意してください。
```python
-# @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are
-# created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any
-# number of NFTs may be created and assigned without emitting Transfer. At the time of any
-# transfer, the approved address for that NFT (if any) is reset to none.
-# @param _from Sender of NFT (if address is zero address it indicates token creation).
-# @param _to Receiver of NFT (if address is zero address it indicates token destruction).
-# @param _tokenId The NFT that got transferred.
+# @dev 何らかのメカニズムによってNFTの所有権が変更されたときに発行されます。このイベントは、NFTが作成
+# (`from` == 0)および破棄(`to` == 0)されたときに発行されます。例外:コントラクト作成中、任意の
+# 数のNFTがTransferを発行せずに作成および割り当てられる場合があります。任意の
+# 送金時、そのNFTの承認済みアドレス(もしあれば)はnoneにリセットされます。
+# @param _from NFTの送信者(アドレスがゼロアドレスの場合、トークンの作成を示します)。
+# @param _to NFTの受信者(アドレスがゼロアドレスの場合、トークンの破棄を示します)。
+# @param _tokenId 送金されたNFT。
event Transfer:
sender: indexed(address)
receiver: indexed(address)
tokenId: indexed(uint256)
```
-これは、金額の代わりに`tokenId`を伝える点を除くとERC-20のTransferイベントと類似しています。 アドレスを所有しないユーザーはいないので、慣習的に、このイベントを使ってトークンの発行と破壊を報告しています。
+これは、金額の代わりに`tokenId`を報告する点を除けば、ERC-20のTransferイベントと似ています。
+ゼロアドレスを所有する者はいないため、慣例的にトークンの作成と破棄を報告するために使用します。
```python
-# @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero
-# address indicates there is no approved address. When a Transfer event emits, this also
-# indicates that the approved address for that NFT (if any) is reset to none.
-# @param _owner Owner of NFT.
-# @param _approved Address that we are approving.
-# @param _tokenId NFT which we are approving.
+# @dev NFTの承認済みアドレスが変更または再確認されたときに発行されます。ゼロ
+# アドレスは、承認済みアドレスがないことを示します。Transferイベントが発行されると、これも
+# そのNFTの承認済みアドレス(もしあれば)がnoneにリセットされることを示します。
+# @param _owner NFTの所有者。
+# @param _approved 承認するアドレス。
+# @param _tokenId 承認するNFT。
event Approval:
owner: indexed(address)
approved: indexed(address)
tokenId: indexed(uint256)
```
-ERC-721の承認は、ERC-20におけるアローワンスに類似した機能です。 特定のアドレスから、特定のトークンを送信することが可能です。 これにより、コントラクトがトークンを受け入れる際に対応するためのメカニズムが実現します。 コントラクトは、イベントをリッスンできないため、トークンが送信されてもそれを「把握」できないのです。 つまり、所有者はまず承認を提出してから、コントラクトに対して「私はあなたがトークンXを送信することを承認しましたので、〜を実行してください」というリクエストを送信するわけです。
+ERC-721の承認はERC-20のアローワンスに似ています。 特定のアドレスが特定の
+トークンを送金することが許可されます。 これにより、コントラクトがトークンを受け入れる際に応答するためのメカニズムが提供されます。 コントラクトは
+イベントをリッスンできないため、トークンを送金しただけでは、コントラクトはそのことを「知り」ません。 この方法では、
+所有者はまず承認を送信し、次にコントラクトに「トークン
+Xの送金を承認しました。どうぞ...」というリクエストを送信します。
-これは、ERC-721標準をERC-20と類似の標準にするための設計上の選択によるものです。 ERC-721トークンは非代替性であるため、コントラクトは、トークンの所有権を調べて特定のトークンを受け取ったかどうかを確認できます。
+これは、ERC-721標準をERC-20標準と類似させるための設計上の選択です。 ERC-721トークンは非代替性であるため、
+コントラクトはトークンの所有権を見ることで、特定のトークンを受け取ったことを
+識別することもできます。
```python
-# @dev This emits when an operator is enabled or disabled for an owner. The operator can manage
-# all NFTs of the owner.
-# @param _owner Owner of NFT.
-# @param _operator Address to which we are setting operator rights.
-# @param _approved Status of operator rights(true if operator rights are given and false if
-# revoked).
+# @dev 所有者のオペレーターが有効または無効になったときに発行されます。オペレーターは
+# 所有者のすべてのNFTを管理できます。
+# @param _owner NFTの所有者。
+# @param _operator オペレーター権限を設定するアドレス。
+# @param _approved オペレーター権限のステータス(権限が付与された場合はtrue、
+# 取り消された場合はfalse)。
event ApprovalForAll:
owner: indexed(address)
operator: indexed(address)
approved: bool
```
-場合によっては、委任状の機能のように、アカウントが所有する特定タイプのトークン(特定のコントラクトが管理するトークン)をすべて管理できる_オペレーター_ を持つことが便利な場合もあります。 例えば、私がコントラクトに対して、6カ月にわたりそのコントラクトとのやりとりを行っていないかどうかを確認する権限を与え、もしやりとりがない場合には、私のアセットを相続人に分配するように設定したいとします(相続人の一人が遺産分配を求めても、トランザクションによって呼び出されない限りコントラクトは何も実行できません)。 ERC-20では、継承コントラクトに対して大きなアローワンスを設定できますが、ERC-721の場合、非代替性を持つために不可能です。 そこで、オペレーターが同等の機能を提供します。
+委任状のように、特定タイプの(特定のコントラクトによって管理される)アカウントの全トークンを管理できる_オペレーター_がいると便利な場合があります。 例えば、私が6ヶ月間連絡を取っていないかどうかをチェックし、もしそうであれば私の資産を相続人に分配する権限をコントラクトに与えたいかもしれません(相続人の一人が要求した場合、コントラクトはトランザクションによって呼び出されない限り何もできません)。 ERC-20では、継承コントラクトに高いアローワンスを与えることができますが、
+ERC-721ではトークンが非代替性であるため、これは機能しません。 これが同等の機能です。
-`approved`の値を通じて、当該イベントが承認を求めるものか、承認を取り消したものかを確認することができます。
+`approved`の値は、イベントが承認のためのものか、承認の取り消しのためのものかを示します。
### 状態変数 {#state-vars}
-状態変数には、トークンの現在の状態、つまりどのトークンが存在し、誰が所有するかの情報が含まれます。 大部分の状態変数は`HashMap`オブジェクトであり、[2つのタイプ間に存在する一方向のマッピング](https://vyper.readthedocs.io/en/latest/types.html#mappings)です。
+これらの変数には、トークンの現在の状態、つまりどのトークンが利用可能で誰が所有しているかの情報が含まれています。 これらのほとんどは`HashMap`オブジェクトであり、[2つの型間に存在する一方向のマッピング](https://vyper.readthedocs.io/en/latest/types.html#mappings)です。
```python
-# @dev Mapping from NFT ID to the address that owns it.
+# @dev NFT IDからそれを所有するアドレスへのマッピング。
idToOwner: HashMap[uint256, address]
-# @dev Mapping from NFT ID to approved address.
+# @dev NFT IDから承認済みアドレスへのマッピング。
idToApprovals: HashMap[uint256, address]
```
-イーサリアムにおいて、ユーザーおよびコントラクトのIDは160ビットのアドレスで表示されます。 これら2つの変数は、トークンIDから、所有者および送信することを承認された者(それぞれにつき最大1つの変数)がマッピングされます。 イーサリアムでは、未初期化データは常にゼロであるため、所有者または承認済み送信者が存在しなければ、トークンの値はゼロになります。
+イーサリアムでは、ユーザーとコントラクトのIDは160ビットのアドレスで表されます。 これら2つの変数は、トークンIDから、
+その所有者と送金を承認された者(それぞれ最大1つ)にマッピングします。 イーサリアムでは、未初期化データは常にゼロであるため、
+所有者または承認済み送金者がいない場合、そのトークンの値はゼロになります。
```python
-# @dev Mapping from owner address to count of his tokens.
+# @dev 所有者アドレスからそのトークン数へのマッピング。
ownerToNFTokenCount: HashMap[address, uint256]
```
-この変数は、各所有者ごとのトークン数を保持します。 所有者とトークンはマッピングされないため、特定の所有者が持つトークンを特定するには、ブロックチェーンのイベント履歴を過去に遡って確認し、当該の`Transfer`イベントを確認するしかありません。 この変数を使用して、すべてのNFTでいつ取得したか知ることができ、それ以上調べる必要がありません。
+この変数は、各所有者のトークン数を保持します。 所有者からトークンへのマッピングはないため、
+特定の所有者が所有するトークンを識別する唯一の方法は、ブロックチェーンのイベント履歴を遡り、
+適切な`Transfer`イベントを見ることです。 この変数を使用して、すべてのNFTをいつ取得したかを知ることができ、
+それ以上調べる必要がありません。
-ただし、このアルゴリズムはユーザーインターフェイスおよび外部サーバーのみを対象とする点に注意してください。 ブロックチェーン上で実行されるコード自体は、過去イベントを読み込むことができません。
+このアルゴリズムは、ユーザーインターフェイスと外部サーバーに対してのみ機能することに注意してください。 ブロックチェーン上で実行されるコード
+自体は、過去のイベントを読み取ることはできません。
```python
-# @dev Mapping from owner address to mapping of operator addresses.
+# @dev 所有者アドレスからオペレーターアドレスのマッピングへのマッピング。
ownerToOperators: HashMap[address, HashMap[address, bool]]
```
-1つのアカウントには、複数のオペレーターを含めることができます。 しかし、単純な`HashMap`では、各キーごとに単一の値を持つため、複数のオペレーターを追跡するのに十分ではありません。 その代わりに、`HashMap[address, bool]`を値として使用します。 デフォルトでは、各アドレスの値は`False`になっていますが、これはオペレーターでないことを示します。 オペレーターに設定するには、値を`True`に変更してください。
+1つのアカウントに複数のオペレーターがいる場合があります。 単純な`HashMap`では、各キーが単一の値につながるため、
+それらを追跡するには不十分です。 代わりに、値として
+`HashMap[address, bool]`を使用できます。 デフォルトでは、各アドレスの値は`False`であり、
+オペレーターではないことを意味します。 必要に応じて値を`True`に設定できます。
```python
-# @dev Address of minter, who can mint a token
+# @dev トークンをミントできるミンターのアドレス
minter: address
```
-何らかの方法で、新規トークンを作成する必要があります。 このコントラクトでは、新規トークンを作成する権限を持つ唯一のエンティティは`minter`です。 使用事例がゲームなどの場合は、これで十分でしょう。 その他の目的の場合、より複雑なビジネスロジックを作成する必要があるでしょう。
+新しいトークンは何らかの方法で作成されなければなりません。 このコントラクトには、それを許可された単一のエンティティ、
+`minter`が存在します。 例えば、ゲームにとってはこれで十分でしょう。 他の目的のためには、
+より複雑なビジネスロジックを作成する必要があるかもしれません。
```python
-# @dev Mapping of interface id to bool about whether or not it's supported
+# @dev インターフェイスIDから、それがサポートされているかどうかを示すbool値へのマッピング
supportedInterfaces: HashMap[bytes32, bool]
-# @dev ERC165 interface ID of ERC165
+# @dev ERC165のERC165インターフェイスID
ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7
-# @dev ERC165 interface ID of ERC721
+# @dev ERC721のERC165インターフェイスID
ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd
```
-[ERC-165](https://eips.ethereum.org/EIPS/eip-165)では、コントラクトにおいてアプリケーションがどのようなやりとりを行うか、およびどのERC規格に準拠するのかを開示するメカニズムの仕様が規定されています。 このコントラクトの場合、ERC-165とERC-721に準拠しています。
+[ERC-165](https://eips.ethereum.org/EIPS/eip-165)は、コントラクトがアプリケーションと
+通信する方法、つまりどのERCに準拠しているかを公開するためのメカニズムを指定します。 この場合、コントラクトはERC-165とERC-721に準拠しています。
### 関数 {#functions}
-以下は、実際にERC-721で実装できる関数です。
+これらは、実際にERC-721を実装する関数です。
-#### コンストラクタ関数 {#constructor}
+#### コンストラクタ {#constructor}
```python
@external
def __init__():
```
-Pythonの場合と同様に、Vyperでもコンストラクタ関数は`__init__`で呼び出します。
+Vyperでは、Pythonと同様に、コンストラクタ関数は`__init__`と呼ばれます。
```python
"""
- @dev Contract constructor.
+ @dev コントラクトコンストラクタ。
"""
```
-PythonおよびVyperでは、複数行の文字列(文頭および文末を`"""`に付ける)を指定し、この文字列を利用しないことでもコメントを作成できます。 これらのコメントには、 [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html)を含めることも可能です。
+PythonやVyperでは、複数行の文字列(`"""`で始まり終わる)を指定し、それを一切使用しないことでコメントを作成することもできます。 これらのコメントには、
+[NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html)も含まれる場合があります。
```python
self.supportedInterfaces[ERC165_INTERFACE_ID] = True
@@ -210,57 +242,64 @@ PythonおよびVyperでは、複数行の文字列(文頭および文末を`""
self.minter = msg.sender
```
-状態変数にアクセスするには、`self.`を使用します(これも、Pythonと同様です)。
+状態変数にアクセスするには`self.<変数名>`を使用します(これもPythonと同じです)。
#### ビュー関数 {#views}
-ビュー関数は、ブロックチェーンの状態を変更しない関数であり、外部から呼び出されると無料で実行されます。 一方、コントラクトがビュー関数を呼び出す場合は全ノードで実行する必要があるため、ガス代が発生します。
+これらはブロックチェーンの状態を変更しない関数であり、したがって外部から
+呼び出された場合は無料で実行できます。 ビュー関数がコントラクトによって呼び出された場合でも、
+すべてのノードで実行する必要があるため、ガス代がかかります。
```python
@view
@external
```
-アットマーク (`@`)で始まる関数定義の前に置かれたこれらのキーワードを、_デコレータ_と呼びます。 デコレータは、関数を呼び出せる状況を特定します。
+関数定義の前にある、アットマーク(`@`)で始まるこれらのキーワードは、_デコレータ_と呼ばれます。 これらは
+関数を呼び出すことができる状況を指定します。
-- `@view`は、関数がビューであることを規定します。
-- `@external`は、関数がトランザクションおよび他のコントラクトで呼び出し可能であることを規定します。
+- `@view`は、この関数がビューであることを指定します。
+- `@external`は、この特定の関数がトランザクションや他のコントラクトによって呼び出されることを指定します。
```python
def supportsInterface(_interfaceID: bytes32) -> bool:
```
-Pythonとは異なり、Vyperは[静的型付け言語](https://wikipedia.org/wiki/Type_system#Static_type_checking)です。 つまり、[データ型](https://vyper.readthedocs.io/en/latest/types.html)を指定しないと変数、つまり関数のパラメータを宣言できません。 この場合では、入力パラメータは、256ビット値の`bytes32`です (256ビットは、[イーサリアム仮想マシン](/developers/docs/evm/)のネイティブワードサイズです) 。 出力は、ブール値です。 慣習により、関数におけるパラメータの名称はアンダースコア (`_`) で開始します。
+Pythonとは対照的に、Vyperは[静的型付け言語](https://wikipedia.org/wiki/Type_system#Static_type_checking)です。
+[データ型](https://vyper.readthedocs.io/en/latest/types.html)を特定せずに、変数や関数パラメータを宣言することはできません。 この場合、入力パラメータは`bytes32`、つまり256ビット値です
+(256ビットは[イーサリアム仮想マシン](/developers/docs/evm/)のネイティブワードサイズです)。 出力はブール
+値です。 慣例により、関数パラメータの名前はアンダースコア(`_`)で始まります。
```python
"""
- @dev Interface identification is specified in ERC-165.
- @param _interfaceID Id of the interface
+ @dev インターフェイスの識別はERC-165で指定されています。
+ @param _interfaceID インターフェイスのID
"""
return self.supportedInterfaces[_interfaceID]
```
-コンストラクタ(`__init__`)で設定した`self.supportedInterfaces`ハッシュマップが値を返します。
+コンストラクタ(`__init__`)で設定された`self.supportedInterfaces` HashMapから値を返します。
```python
-### VIEW FUNCTIONS ###
+### ビュー関数 ###
+
```
-これらは、ユーザーや他のコントラクトが利用できるトークンについての情報を提供するビュー関数です。
+これらは、トークンに関する情報をユーザーや他のコントラクトが利用できるようにするビュー関数です。
```python
@view
@external
def balanceOf(_owner: address) -> uint256:
"""
- @dev Returns the number of NFTs owned by `_owner`.
- Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid.
- @param _owner Address for whom to query the balance.
+ @dev `_owner`が所有するNFTの数を返します。
+ `_owner`がゼロアドレスの場合はスローします。ゼロアドレスに割り当てられたNFTは無効と見なされます。
+ @param _owner 残高を照会するアドレス。
"""
assert _owner != ZERO_ADDRESS
```
-この行は、`_owner`値がゼロでないことを[宣言](https://vyper.readthedocs.io/en/latest/statements.html#assert)します。 値がゼロの場合、エラーが発生し操作が元に戻されます。
+この行は、`_owner`がゼロでないことを[アサート](https://vyper.readthedocs.io/en/latest/statements.html#assert)します。 もしゼロであれば、エラーが発生し、操作は取り消されます。
```python
return self.ownerToNFTokenCount[_owner]
@@ -269,70 +308,74 @@ def balanceOf(_owner: address) -> uint256:
@external
def ownerOf(_tokenId: uint256) -> address:
"""
- @dev Returns the address of the owner of the NFT.
- Throws if `_tokenId` is not a valid NFT.
- @param _tokenId The identifier for an NFT.
+ @dev NFTの所有者のアドレスを返します。
+ `_tokenId`が有効なNFTでない場合はスローします。
+ @param _tokenId NFTの識別子。
"""
owner: address = self.idToOwner[_tokenId]
- # Throws if `_tokenId` is not a valid NFT
+ # `_tokenId`が有効なNFTでない場合はスローします
assert owner != ZERO_ADDRESS
return owner
```
-イーサリアム仮想マシン(EVM)では、値が格納されていないストレージはゼロになります。 `_tokenId`にトークンが含まれない場合、`self.idToOwner[_tokenId]`の値はゼロになります。 その場合、関数は元に戻されます。
+イーサリアム仮想マシン(EVM)では、値が格納されていないストレージはゼロになります。
+`_tokenId`にトークンがない場合、`self.idToOwner[_tokenId]`の値はゼロになります。 その場合、
+関数は元に戻されます。
```python
@view
@external
def getApproved(_tokenId: uint256) -> address:
"""
- @dev Get the approved address for a single NFT.
- Throws if `_tokenId` is not a valid NFT.
- @param _tokenId ID of the NFT to query the approval of.
+ @dev 単一のNFTの承認済みアドレスを取得します。
+ `_tokenId`が有効なNFTでない場合はスローします。
+ @param _tokenId 承認を照会するNFTのID。
"""
- # Throws if `_tokenId` is not a valid NFT
+ # `_tokenId`が有効なNFTでない場合はスローします
assert self.idToOwner[_tokenId] != ZERO_ADDRESS
return self.idToApprovals[_tokenId]
```
-`getApproved`は、ゼロの値を返す_可能性_がある点に注意してください。 有効なトークンが存在する場合、`self.idToApprovals[_tokenId]`の値が返されます。 承認者が存在しない場合、値はゼロになります。
+`getApproved`はゼロを返す_可能性がある_ことに注意してください。 トークンが有効な場合、`self.idToApprovals[_tokenId]`を返します。
+承認者がいない場合、その値はゼロです。
```python
@view
@external
def isApprovedForAll(_owner: address, _operator: address) -> bool:
"""
- @dev Checks if `_operator` is an approved operator for `_owner`.
- @param _owner The address that owns the NFTs.
- @param _operator The address that acts on behalf of the owner.
+ @dev `_operator`が`_owner`の承認済みオペレーターであるかどうかをチェックします。
+ @param _owner NFTを所有するアドレス。
+ @param _operator 所有者の代わりに機能するアドレス。
"""
return (self.ownerToOperators[_owner])[_operator]
```
-この関数は、「`_operator`」がこのコントラクト内の「`_owner`」のトークンをすべて管理できるかどうかをチェックします。 複数のオペレーターが存在する可能性があるため、ハッシュマップも2つのレベルが存在します。
+この関数は、`_operator`がこのコントラクト内の`_owner`のすべてのトークンを管理できるかどうかをチェックします。
+複数のオペレーターが存在する可能性があるため、これは2レベルのHashMapです。
-#### 送信ヘルパー関数 {#transfer-helpers}
+#### 送金ヘルパー関数 {#transfer-helpers}
-これらの関数は、トークンの送信またはトークン管理の一部のオペレーションを実装しています。
+これらの関数は、トークンの送金または管理の一部である操作を実装します。
```python
-### TRANSFER FUNCTION HELPERS ###
+### 送金関数ヘルパー ###
@view
@internal
```
-`@internal`のデコレータは、関数が同一コントラクト内の他の関数からのみアクセス可能であることを意味します。 これらの関数も、慣習によりアンダースコア (`_`) で開始します。
+このデコレータ`@internal`は、この関数が同じコントラクト内の他の関数からのみアクセス可能であることを意味します。 慣例により、これらの関数名もアンダースコア(`_`)で始まります。
```python
def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool:
"""
- @dev Returns whether the given spender can transfer a given token ID
- @param spender address of the spender to query
- @param tokenId uint256 ID of the token to be transferred
- @return bool whether the msg.sender is approved for the given token ID,
- is an operator of the owner, or is the owner of the token
+ @dev 指定されたスペンダーが指定されたトークンIDを送金できるかどうかを返します
+ @param spender 照会するスペンダーのアドレス
+ @param tokenId 送金されるトークンのuint256 ID
+ @return bool msg.senderが指定されたトークンIDに対して承認されているか、
+ 所有者のオペレーターであるか、トークンの所有者であるかどうか
"""
owner: address = self.idToOwner[_tokenId]
spenderIsOwner: bool = owner == _spender
@@ -341,117 +384,122 @@ def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool:
return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll
```
-アドレスからトークンを送信できるようにするには、次の3通りの方法があります:
+アドレスがトークンを送金できるようにするには、3つの方法があります。
-1. アドレスが、トークンの所有者であること
-2. アドレスが、トークンの使用を承認されていること
-3. アドレスが、トークンの所有者のオペレーターであること
+1. アドレスがトークンの所有者である
+2. アドレスがそのトークンを使用することを承認されている
+3. アドレスがトークンの所有者のオペレーターである
-上記の機能は、状態を変更しないためビュー機能とすることもできます。 オペレーションコストを軽減するには、ビュー機能と_指定できる_関数はビュー機能に_するべき_です。
+上記の関数は状態を変更しないため、ビューにすることができます。 運用コストを削減するために、ビューに_できる_関数は
+すべてビューに_すべき_です。
```python
@internal
def _addTokenTo(_to: address, _tokenId: uint256):
"""
- @dev Add a NFT to a given address
- Throws if `_tokenId` is owned by someone.
+ @dev 指定されたアドレスにNFTを追加します
+ `_tokenId`が誰かによって所有されている場合はスローします。
"""
- # Throws if `_tokenId` is owned by someone
+ # `_tokenId`が誰かによって所有されている場合はスローします
assert self.idToOwner[_tokenId] == ZERO_ADDRESS
- # Change the owner
+ # 所有者を変更
self.idToOwner[_tokenId] = _to
- # Change count tracking
+ # カウント追跡を変更
self.ownerToNFTokenCount[_to] += 1
@internal
def _removeTokenFrom(_from: address, _tokenId: uint256):
"""
- @dev Remove a NFT from a given address
- Throws if `_from` is not the current owner.
+ @dev 指定されたアドレスからNFTを削除します
+ `_from`が現在の所有者でない場合はスローします。
"""
- # Throws if `_from` is not the current owner
+ # `_from`が現在の所有者でない場合はスローします
assert self.idToOwner[_tokenId] == _from
- # Change the owner
+ # 所有者を変更
self.idToOwner[_tokenId] = ZERO_ADDRESS
- # Change count tracking
+ # カウント追跡を変更
self.ownerToNFTokenCount[_from] -= 1
```
-送信に問題が発生した場合、呼び出しは取り消されます。
+送金に問題がある場合、呼び出しを元に戻します。
```python
@internal
def _clearApproval(_owner: address, _tokenId: uint256):
"""
- @dev Clear an approval of a given address
- Throws if `_owner` is not the current owner.
+ @dev 指定されたアドレスの承認をクリアします
+ `_owner`が現在の所有者でない場合はスローします。
"""
- # Throws if `_owner` is not the current owner
+ # `_owner`が現在の所有者でない場合はスローします
assert self.idToOwner[_tokenId] == _owner
if self.idToApprovals[_tokenId] != ZERO_ADDRESS:
- # Reset approvals
+ # 承認をリセット
self.idToApprovals[_tokenId] = ZERO_ADDRESS
```
-必要な場合のみ、値を変更してください。 状態変数は、ストレージ上に保存されます。 ストレージへの書き込みは、EVM(イーサリアム仮想マシン)において[ガス代](/developers/docs/gas/)が最も高価なオペレーションの1つです。 既存の値の書き込みもコストが高いため、ストレージへの書き込みは最低限に抑えることをお勧めします。
+必要な場合のみ、値を変更してください。 状態変数はストレージに存在します。 ストレージへの書き込みは、
+EVM (イーサリアム仮想マシン) が行う最も高価な操作の1つです([ガス](/developers/docs/gas/)の観点から)。 したがって、既存の値を書き込むだけでも
+コストが高いため、これを最小限に抑えることをお勧めします。
```python
@internal
def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address):
"""
- @dev Execute transfer of a NFT.
- Throws unless `msg.sender` is the current owner, an authorized operator, or the approved
- address for this NFT. (NOTE: `msg.sender` not allowed in private function so pass `_sender`.)
- Throws if `_to` is the zero address.
- Throws if `_from` is not the current owner.
- Throws if `_tokenId` is not a valid NFT.
+ @dev NFTの送金を実行します。
+ `msg.sender`が現在の所有者、承認されたオペレーター、またはこのNFTの承認
+ 済みアドレスでない限り、スローします。(注:`msg.sender`はプライベート関数では許可されていないため、`_sender`を渡します。)
+ `_to`がゼロアドレスの場合はスローします。
+ `_from`が現在の所有者でない場合はスローします。
+ `_tokenId`が有効なNFTでない場合はスローします。
"""
```
-トークンの送信には2つの方法(通常モードと安全モード)が存在するため、この内部関数が提供されていますが、監査を容易にするために、コード内で送信するロケーションは1つだけにする必要があります。
+トークンを送金するには2つの方法(通常と安全)があるため、この内部関数がありますが、
+監査を容易にするために、コード内の1つの場所でのみ実行するようにしています。
```python
- # Check requirements
+ # 要件をチェック
assert self._isApprovedOrOwner(_sender, _tokenId)
- # Throws if `_to` is the zero address
+ # `_to`がゼロアドレスの場合はスローします
assert _to != ZERO_ADDRESS
- # Clear approval. Throws if `_from` is not the current owner
+ # 承認をクリアします。`_from`が現在の所有者でない場合はスローします
self._clearApproval(_from, _tokenId)
- # Remove NFT. Throws if `_tokenId` is not a valid NFT
+ # NFTを削除します。`_tokenId`が有効なNFTでない場合はスローします
self._removeTokenFrom(_from, _tokenId)
- # Add NFT
+ # NFTを追加
self._addTokenTo(_to, _tokenId)
- # Log the transfer
+ # 送金をログに記録
log Transfer(_from, _to, _tokenId)
```
-Vyper上でイベントを発行するには、`log`ステートメントを使用します(詳細は、[こちら](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)をご覧ください)。
+Vyperでイベントを発行するには、`log`ステートメントを使用します([詳細はこちら](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging))。
-#### 送信関数 {#transfer-funs}
+#### 送金関数 {#transfer-funs}
```python
-### TRANSFER FUNCTIONS ###
+### 送金関数 ###
@external
def transferFrom(_from: address, _to: address, _tokenId: uint256):
"""
- @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved
- address for this NFT.
- Throws if `_from` is not the current owner.
- Throws if `_to` is the zero address.
- Throws if `_tokenId` is not a valid NFT.
- @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else
- they maybe be permanently lost.
- @param _from The current owner of the NFT.
- @param _to The new owner.
- @param _tokenId The NFT to transfer.
+ @dev `msg.sender`が現在の所有者、承認されたオペレーター、またはこのNFTの承認
+ 済みアドレスでない限り、スローします。
+ `_from`が現在の所有者でない場合はスローします。
+ `_to`がゼロアドレスの場合はスローします。
+ `_tokenId`が有効なNFTでない場合はスローします。
+ @notice 呼び出し元は、`_to`がNFTを受信できることを確認する責任があります。さもないと、
+ 永久に失われる可能性があります。
+ @param _from NFTの現在の所有者。
+ @param _to 新しい所有者。
+ @param _tokenId 送金するNFT。
"""
self._transferFrom(_from, _to, _tokenId, msg.sender)
```
-この関数は、任意のアドレスに送信する機能を提供します。 送信先のアドレスがユーザーであるか、トークンの送信方法が分かっているコントラクトでない場合、送信するトークンはそのアドレスに置かれたまま利用できない状態になります。
+この関数を使用すると、任意のアドレスに送金できます。 アドレスがユーザーであるか、トークンの送金方法を知っているコントラクトでない限り、
+送金したトークンはそのアドレスでスタックし、使用できなくなります。
```python
@external
@@ -462,75 +510,80 @@ def safeTransferFrom(
_data: Bytes[1024]=b""
):
"""
- @dev Transfers the ownership of an NFT from one address to another address.
- Throws unless `msg.sender` is the current owner, an authorized operator, or the
- approved address for this NFT.
- Throws if `_from` is not the current owner.
- Throws if `_to` is the zero address.
- Throws if `_tokenId` is not a valid NFT.
- If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if
- the return value is not `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
- NOTE: bytes4 is represented by bytes32 with padding
- @param _from The current owner of the NFT.
- @param _to The new owner.
- @param _tokenId The NFT to transfer.
- @param _data Additional data with no specified format, sent in call to `_to`.
+ @dev NFTの所有権をあるアドレスから別のアドレスに送金します。
+ `msg.sender`が現在の所有者、承認されたオペレーター、またはこの
+ NFTの承認済みアドレスでない限り、スローします。
+ `_from`が現在の所有者でない場合はスローします。
+ `_to`がゼロアドレスの場合はスローします。
+ `_tokenId`が有効なNFTでない場合はスローします。
+ `_to`がスマートコントラクトの場合、`_to`で`onERC721Received`を呼び出し、
+ 戻り値が`bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`でない場合にスローします。
+ 注:bytes4はパディング付きのbytes32で表されます
+ @param _from NFTの現在の所有者。
+ @param _to 新しい所有者。
+ @param _tokenId 送金するNFT。
+ @param _data 指定されたフォーマットのない追加データで、`_to`への呼び出しで送信されます。
"""
self._transferFrom(_from, _to, _tokenId, msg.sender)
```
-問題が発生した場合にはトランザクションが元に戻され、コールに含まれるすべての事項が取り消されるため、先に送信を行っても構いません。
+問題が発生した場合はとにかく元に戻すので、先に送金しても問題ありません。
+呼び出しで行われたことはすべてキャンセルされます。
```python
- if _to.is_contract: # check if `_to` is a contract address
+ if _to.is_contract: # `_to`がコントラクトアドレスかどうかをチェック
```
-まず、アドレスがコントラクトであるか(コードを持つか)を確認してください。 アドレスがコントラクトでない場合、ユーザーのアドレスであれば、そのトークンを使用/送信できるようになります。 しかし、これがセキュリティを強化すると考えるべきではありません。 `safeTransferFrom`を使用した場合でも、秘密鍵が不明なアドレスに送信したトークンは失われる場合があります。
+まず、アドレスがコントラクト(コードがある場合)かどうかを確認します。 そうでない場合は、それがユーザーアドレスであり、ユーザーが
+トークンを使用または送金できると想定します。 しかし、それで
+安心しきってはいけません。 `safeTransferFrom`を使用しても、誰も秘密鍵を知らないアドレスに
+送金すると、トークンを失う可能性があります。
```python
returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data)
```
-ERC-721トークンを受信できるかどうかを確認するには、送信先のコントラクトを呼び出します。
+ターゲットコントラクトを呼び出して、ERC-721トークンを受信できるかどうかを確認します。
```python
- # Throws if transfer destination is a contract which does not implement 'onERC721Received'
+ # 送金先が'onERC721Received'を実装していないコントラクトの場合はスローします
assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32)
```
-送信先がコントラクトであるが、ERC-721トークンを受け付けない場合(または、この特定の送信を受け付けないと選択した場合)、操作を取り消してください。
+宛先がコントラクトであっても、ERC-721トークンを受け付けない(またはこの特定の
+送金を受け付けないと決定した)場合は、元に戻します。
```python
@external
def approve(_approved: address, _tokenId: uint256):
"""
- @dev Set or reaffirm the approved address for an NFT. The zero address indicates there is no approved address.
- Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner.
- Throws if `_tokenId` is not a valid NFT. (NOTE: This is not written the EIP)
- Throws if `_approved` is the current owner. (NOTE: This is not written the EIP)
- @param _approved Address to be approved for the given NFT ID.
- @param _tokenId ID of the token to be approved.
+ @dev NFTの承認済みアドレスを設定または再確認します。ゼロアドレスは、承認済みアドレスがないことを示します。
+ `msg.sender`が現在のNFT所有者または現在の所有者の承認済みオペレーターでない限り、スローします。
+ `_tokenId`が有効なNFTでない場合はスローします。(注:これはEIPには書かれていません)
+ `_approved`が現在の所有者である場合はスローします。(注:これはEIPには書かれていません)
+ @param _approved 指定されたNFT IDに対して承認されるアドレス。
+ @param _tokenId 承認されるトークンのID。
"""
owner: address = self.idToOwner[_tokenId]
- # Throws if `_tokenId` is not a valid NFT
+ # `_tokenId`が有効なNFTでない場合はスローします
assert owner != ZERO_ADDRESS
- # Throws if `_approved` is the current owner
+ # `_approved`が現在の所有者である場合はスローします
assert _approved != owner
```
-慣習により、承認者を設定したくない場合、自分のアドレスではなく、ゼロのアドレスを指定してください。
+慣例により、承認者を設定したくない場合は、自分自身ではなくゼロアドレスを指定します。
```python
- # Check requirements
+ # 要件をチェック
senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender
senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender]
assert (senderIsOwner or senderIsApprovedForAll)
```
-承認を設定するには、所有者であるか、所有者が承認したオペレーターである必要があります。
+承認を設定するには、所有者であるか、所有者によって承認されたオペレーターである必要があります。
```python
- # Set the approval
+ # 承認を設定
self.idToApprovals[_tokenId] = _approved
log Approval(owner, _approved, _tokenId)
@@ -538,95 +591,110 @@ def approve(_approved: address, _tokenId: uint256):
@external
def setApprovalForAll(_operator: address, _approved: bool):
"""
- @dev Enables or disables approval for a third party ("operator") to manage all of
- `msg.sender`'s assets. It also emits the ApprovalForAll event.
- Throws if `_operator` is the `msg.sender`. (NOTE: This is not written the EIP)
- @notice This works even if sender doesn't own any tokens at the time.
- @param _operator Address to add to the set of authorized operators.
- @param _approved True if the operators is approved, false to revoke approval.
+ @dev サードパーティ(「オペレーター」)が`msg.sender`の
+ すべての資産を管理するための承認を有効または無効にします。また、ApprovalForAllイベントも発行します。
+ `_operator`が`msg.sender`である場合はスローします。(注:これはEIPには書かれていません)
+ @notice これは、送信者がその時点でトークンを所有していなくても機能します。
+ @param _operator 承認済みオペレーターのセットに追加するアドレス。
+ @param _approved オペレーターが承認されている場合はTrue、承認を取り消す場合はfalse。
"""
- # Throws if `_operator` is the `msg.sender`
+ # `_operator`が`msg.sender`である場合はスローします
assert _operator != msg.sender
self.ownerToOperators[msg.sender][_operator] = _approved
log ApprovalForAll(msg.sender, _operator, _approved)
```
-#### 新しいトークンのミントと既存トークンの破壊 {#mint-burn}
+#### 新しいトークンのミントと既存トークンの破棄 {#mint-burn}
-コントラクトを作成したアカウントは`minter`となり、新規のNFTをミントする承認を受けたスーパーユーザーとなります。 ただし、ミンターは既存トークンをバーンすることはできません。 バーンできるのは、所有者および所有者の承認を受けたエンティティのみです。
+コントラクトを作成したアカウントは`minter`であり、新しいNFTをミントする権限を持つ
+スーパーユーザーです。 ただし、既存のトークンをバーンすることは許可されていません。 所有者、または所有者によって承認された
+エンティティのみがそれを行うことができます。
```python
-### MINT & BURN FUNCTIONS ###
+### ミント&バーン関数 ###
@external
def mint(_to: address, _tokenId: uint256) -> bool:
```
-操作が実行されない場合は常に元に戻されるため、この関数は常に`True`の値が返されます。
+操作が失敗した場合は元に戻されるため、この関数は常に`True`を返します。
```python
"""
- @dev Function to mint tokens
- Throws if `msg.sender` is not the minter.
- Throws if `_to` is zero address.
- Throws if `_tokenId` is owned by someone.
- @param _to The address that will receive the minted tokens.
- @param _tokenId The token id to mint.
- @return A boolean that indicates if the operation was successful.
+ @dev トークンをミントする関数
+ `msg.sender`がミンターでない場合はスローします。
+ `_to`がゼロアドレスの場合はスローします。
+ `_tokenId`が誰かによって所有されている場合はスローします。
+ @param _to ミントされたトークンを受け取るアドレス。
+ @param _tokenId ミントするトークンID。
+ @return 操作が成功したかどうかを示すブール値。
"""
- # Throws if `msg.sender` is not the minter
+ # `msg.sender`がミンターでない場合はスローします
assert msg.sender == self.minter
```
-新たなトークンをミントできるのは、このミンター(この ERC-721コントラクトを作成したアカウント)のみです。 ミンターの身元を変更したい場合、この点は将来的に問題になる可能性があります。 本番環境のコントラクトでは、ミンターがミンター特権を他のユーザーに譲渡できる機能が必要になるでしょう。
+ミンター(ERC-721コントラクトを作成したアカウント)のみが新しいトークンをミントできます。 これは、将来ミンターの
+IDを変更したい場合に問題になる可能性があります。 本番環境のコントラクトでは、ミンターが
+ミンター権限を他の誰かに譲渡できる関数が必要になるでしょう。
```python
- # Throws if `_to` is zero address
+ # `_to`がゼロアドレスの場合はスローします
assert _to != ZERO_ADDRESS
- # Add NFT. Throws if `_tokenId` is owned by someone
+ # NFTを追加します。`_tokenId`が誰かによって所有されている場合はスローします
self._addTokenTo(_to, _tokenId)
log Transfer(ZERO_ADDRESS, _to, _tokenId)
return True
```
-慣習により、新規トークンのミントは、ゼロアドレスからの送信としてカウントされます。
+慣例により、新しいトークンのミントはゼロアドレスからの送金としてカウントされます。
```python
@external
def burn(_tokenId: uint256):
"""
- @dev Burns a specific ERC721 token.
- Throws unless `msg.sender` is the current owner, an authorized operator, or the approved
- address for this NFT.
- Throws if `_tokenId` is not a valid NFT.
- @param _tokenId uint256 id of the ERC721 token to be burned.
+ @dev 特定のERC721トークンをバーンします。
+ `msg.sender`が現在の所有者、承認されたオペレーター、またはこのNFTの承認
+ 済みアドレスでない限り、スローします。
+ `_tokenId`が有効なNFTでない場合はスローします。
+ @param _tokenId バーンされるERC721トークンのuint256 ID。
"""
- # Check requirements
+ # 要件をチェック
assert self._isApprovedOrOwner(msg.sender, _tokenId)
owner: address = self.idToOwner[_tokenId]
- # Throws if `_tokenId` is not a valid NFT
+ # `_tokenId`が有効なNFTでない場合はスローします
assert owner != ZERO_ADDRESS
self._clearApproval(owner, _tokenId)
self._removeTokenFrom(owner, _tokenId)
log Transfer(owner, ZERO_ADDRESS, _tokenId)
```
-トークンの送信が許可されているユーザーは、そのトークンをバーンすることができます。 バーンは、ゼロアドレスへの送信と同じ外見を持ちますが、このゼロアドレスは実際にはこのトークンを受け取りません。 バーンを通じて、このトークンに使用されたすべてのストレージを解放できるため、トランザクションのガス代を軽減することができます。
+トークンの送金を許可されている人は誰でも、それをバーンすることが許可されています。 バーンはゼロアドレスへの送金と
+同等に見えますが、ゼロアドレスは実際にはトークンを受け取りません。 これにより、トークンに使用されていたすべてのストレージを
+解放でき、トランザクションのガス代を削減できます。
+
+## このコントラクトの使用 {#using-contract}
+
+Solidityとは対照的に、Vyperには継承がありません。 これは、コードをより明確にし、
+したがってセキュリティを確保しやすくするための意図的な設計上の選択です。 したがって、独自のVyper ERC-721コントラクトを作成するには、この
+コントラクトを取得し、
+必要なビジネスロジックを実装するように変更します。
-## コントラクトの使用方法 {#using-contract}
+## 結論 {#conclusion}
-Solidityとは異なり、Viperは相続機能を提供しません。 これは、コードをより明確にし、セキュリティを確保しやすくするための意図的な設計上の選択によるものです。 このため、あなた自身がVyperでERC-721コントラクトを作成する際は、[このコントラクト](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy)を用いて修正し、必要なビジネスロジックを実装してください。
+復習のために、このコントラクトの最も重要なアイデアをいくつか紹介します。
-### まとめ {#conclusion}
+- 安全な送金でERC-721トークンを受信するには、コントラクトは`ERC721Receiver`インターフェイスを実装する必要があります。
+- 安全な送金を使用しても、秘密鍵が不明なアドレスに送信すると、
+ トークンがスタックする可能性があります。
+- 操作に問題がある場合は、単に失敗値を返すのではなく、
+ 呼び出しを`revert`することをお勧めします。
+- ERC-721トークンは、所有者がいる場合に存在します。
+- NFTの送金を承認するには、3つの方法があります。 所有者であるか、特定のトークンに対して承認されているか、
+ または所有者のすべてのトークンのオペレーターであることができます。
+- 過去のイベントはブロックチェーンの外部からのみ表示されます。 ブロックチェーン内で実行されるコードは、それらを表示できません。
-このコントラクトにつき、最も重要なポイントを以下にまとめました:
+では、セキュアなVyperコントラクトを実装してみましょう。
-- 安全モードの送信を使ってERC-721トークンを受け取るには、コントラクトに`ERC721Receiver`インターフェイスを実装する必要があります。
-- 安全モードの送信を実行した場合でも、秘密鍵が不明なアドレスに送信したトークンは行方不明になる可能性があります。
-- 操作に問題が発生した場合、単に失敗値をリターンするのではなく、コール自体を`取り消す`ことをお勧めします。
-- ERC-721トークンには、必ず所有者が必要です。
-- NFTの送信を承認するには、3通りの方法があります。 承認できるのは、所有者であるか、特定トークンの送信を承認されているか、所有者のトークンすべてに対するオペレーターであるユーザーのみです。
-- 過去のイベントは、ブロックチェーン外でのみ表示されます。 ブロックチェーン内で実行されるコードは、表示できません。
+[私の他の作品はこちらでご覧いただけます](https://cryptodocguy.pro/).
-それではさっそく、セキュアなVyperコントラクトを実装してみましょう。
diff --git a/public/content/translations/ja/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/ja/developers/tutorials/erc20-annotated-code/index.md
index 56cf9b6b772..98fff8f466d 100644
--- a/public/content/translations/ja/developers/tutorials/erc20-annotated-code/index.md
+++ b/public/content/translations/ja/developers/tutorials/erc20-annotated-code/index.md
@@ -1,30 +1,28 @@
---
-title: "ERC-20コントラクトの詳細"
-description: OpenZeppelinのERC-20コントラクトの内容とそれが存在する理由
+title: "ERC-20コントラクトのウォークスルー"
+description: "OpenZeppelinのERC-20コントラクトには何が含まれており、それはなぜ存在するのでしょうか?"
author: Ori Pomerantz
lang: ja
-tags:
- - "Solidity"
- - "erc-20"
+tags: [ "Solidity", "ERC-20" ]
skill: beginner
published: 2021-03-09
---
## はじめに {#introduction}
-イーサリアムの最も一般的な用途の1つは、グループが取引可能なトークン、いわば独自の通貨を作ることです。 これらのトークンは通常、[ERC-20](/developers/docs/standards/tokens/erc-20/)という規格に準拠しています。 この規格により、流動性プールやウォレットなど、すべてのERC-20トークンで利用できるツールの作成が可能になります。 今回は、[OpenZeppelin Solidity ERC-20の実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)と、[インターフェース定義](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)について分析していきます。
+イーサリアムの最も一般的な用途の1つは、グループが取引可能なトークン、いわば独自の通貨を作ることです。 これらのトークンは、通常[ERC-20](/developers/docs/standards/tokens/erc-20/)という規格に従います。 この規格により、流動性プールやウォレットなど、すべてのERC-20トークンで利用できるツールの作成が可能になります。 この記事では、[OpenZeppelinのSolidityによるERC20実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)と、[インターフェース定義](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)を分析します。
-ここではアノテーション付きのソースコードを見ていきます。 ERC-20を実装する場合は、[こちらのチュートリアル](https://docs.openzeppelin.com/contracts/2.x/erc20-supply)をご覧ください。
+ここではアノテーション付きのソースコードを見ていきます。 ERC-20を実装したい場合は、[このチュートリアル](https://docs.openzeppelin.com/contracts/2.x/erc20-supply)をお読みください。
## インターフェース {#the-interface}
-ERC-20のような規格の目的は、ウォレットや分散型取引所のようなアプリケーション間で相互運用可能な多くのトークンの実装を可能にすることです。 しかしその実現には[インターフェース](https://www.geeksforgeeks.org/solidity-basics-of-interface/)が必要です。 トークンコントラクトを使用する必要があるすべてのコードは、インターフェースで同じ定義を使用することができ、その定義を使用するすべてのトークンコントラクトと互換性があります。それらにはMetaMaskなどのウォレット、etherscan.ioなどの分散型アプリケーション(Dapp)、流動性プールなどの異なるコントラクトが含まれます。
+ERC-20のような規格の目的は、ウォレットや分散型取引所のようなアプリケーション間で相互運用可能な多くのトークンの実装を可能にすることです。 それを実現するために、[インターフェース](https://www.geeksforgeeks.org/solidity/solidity-basics-of-interface/)を作成します。 トークンコントラクトを使用する必要があるコードは、それがMetaMaskのようなウォレット、etherscan.ioのようなdapp、または流動性プールのような別のコントラクトであっても、インターフェースで同じ定義を使用でき、そのインターフェースを使用するすべてのトークンコントラクトと互換性があります。

-経験豊富なプログラマーであれば、[Java](https://www.w3schools.com/java/java_interface.asp)や[C言語のヘッダーファイル](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html)で同様の構造を見たことがあるのではないでしょうか。
+経験豊富なプログラマーであれば、[Java](https://www.w3schools.com/java/java_interface.asp)や[Cのヘッダーファイル](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html)で同様の構造を見たことがあるかもしれません。
-これはOpenZeppelinによる[ERC-20インターフェースの定義](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)です。 [人間が読めるように](https://eips.ethereum.org/EIPS/eip-20)Solidityのコードにしています。 もちろん、インターフェースそのものは、_何をするか_を定義していません。 これは後述のコントラクトのソースコードで説明されています。
+これはOpenZeppelinによる[ERC-20インターフェース](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)の定義です。 これは、[人間が読める標準規格](https://eips.ethereum.org/EIPS/eip-20)をSolidityコードに変換したものです。 もちろん、インターフェース自体は、何かを行う_方法_を定義するものではありません。 これは後述のコントラクトのソースコードで説明されています。
@@ -32,7 +30,7 @@ ERC-20のような規格の目的は、ウォレットや分散型取引所の
// SPDX-License-Identifier: MIT
```
-Solidityのファイルには、ライセンス識別子が含まれているはずです。 ライセンス一覧は[こちら](https://spdx.org/licenses/)でご覧いただけます。 別のライセンスが必要な場合は、コメントしてください。
+Solidityのファイルには、ライセンス識別子が含まれているはずです。 [ライセンスのリストはこちら](https://spdx.org/licenses/)で確認できます。 別のライセンスが必要な場合は、コメントでその旨を説明してください。
@@ -40,13 +38,13 @@ Solidityのファイルには、ライセンス識別子が含まれているは
pragma solidity >=0.6.0 <0.8.0;
```
-Solidity言語は現在も急速に進化しており、新しいバージョンは古いコードと互換性がない場合があります(詳しくは[こちら](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html))。 そのため、この言語の最小バージョンだけでなく、コードをテストした最新バージョンも指定することをお勧めします。
+Solidity言語は現在も急速に進化しており、新しいバージョンは古いコードと互換性がない場合があります([詳しくはこちら](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html))。 そのため、言語の最小バージョンだけでなく、最大バージョン、つまりコードをテストした最新のバージョンも指定することをお勧めします。
```solidity
/**
- * @dev Interface of the ERC20 standard as defined in the EIP.
+ * @dev EIPで定義されているERC20標準のインターフェース。
*/
```
@@ -58,135 +56,135 @@ Solidity言語は現在も急速に進化しており、新しいバージョン
interface IERC20 {
```
-慣例では、インターフェース名は「`I`」で始まります。
+慣例では、インターフェース名は`I`で始まります。
```solidity
/**
- * @dev Returns the amount of tokens in existence.
+ * @dev 存在するトークンの総量を返します。
*/
function totalSupply() external view returns (uint256);
```
-この関数は`external`です。つまり、[コントラクトの外部からのみ呼び出すことができます](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2)。 コントラクト内のトークンの総供給量を返します。 この値は、イーサリアムで最も一般的な型である符号なし256ビット(イーサリアム仮想マシン(EVM)のネイティブワードサイズ)で返されます。 この関数も`view`であり、状態を変更しないため、ブロックチェーンのすべてのノードで実行するのではなく、単一のノードで実行できます。 このような関数はトランザクションを発生させず、[ガス代](/developers/docs/)もかかりません。
+この関数は`external`であり、[コントラクトの外部からのみ呼び出すことができる](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2)ことを意味します。
+コントラクト内のトークンの総供給量を返します。 この値は、イーサリアムで最も一般的な型である符号なし256ビット(256ビットはEVMのネイティブワードサイズ)で返されます。 この関数も`view`であり、状態を変更しないため、ブロックチェーンのすべてのノードで実行するのではなく、単一のノードで実行できます。 このような関数はトランザクションを生成せず、[ガス](/developers/docs/gas/)代もかかりません。
-**注:** 理論的には、コントラクト作成者が、実際の値よりも少ない総供給量を返し、各トークンを実際の価格よりも高価に見せることで、不正を行うことが出来るように思えるかもしれません。 しかし、そのような心配をするということは、ブロックチェーンの本質を忘れているということになります。 ブロックチェーン上で起こるすべてのことは、すべてのノードで検証できます。 検証をするためのすべてのコントラクトの機械語コードとストレージは、全ノードで入手可能です。 コントラクトのSolidityコードを公開する必要はありませんが、ソースコードとコンパイルに使用したSolidityのバージョンを公開しない限り、不正への懸念を真剣に受け止めてもらうことはできません。その場合は、提供した機械語コードで検証することができます。 例えば、[このコントラクト](https://etherscan.io/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD#code)をご覧ください。
+**注:** 理論的には、コントラクト作成者が、実際の値よりも少ない総供給量を返し、各トークンを実際の価格よりも高価に見せることで、不正を行うことが出来るように思えるかもしれません。 しかし、そのような心配をするということは、ブロックチェーンの本質を忘れているということになります。 ブロックチェーン上で起こるすべてのことは、すべてのノードで検証できます。 これを実現するため、すべてのコントラクトの機械語コードとストレージは、全ノードで入手可能です。 コントラクトのSolidityコードを公開する必要はありませんが、提供した機械語コードと照合して検証できるように、ソースコードとそれをコンパイルしたSolidityのバージョンを公開しない限り、誰もあなたのコントラクトを本気で相手にしないでしょう。
+例えば、[このコントラクト](https://eth.blockscout.com/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD?tab=contract)をご覧ください。
```solidity
/**
- * @dev Returns the amount of tokens owned by `account`.
+ * @dev `account`が所有するトークンの量を返します。
*/
function balanceOf(address account) external view returns (uint256);
```
-その名の通り、`balanceOf`はアカウントの残高を返します。 Solidityでは、イーサリアムアカウントは160ビットを保持する`address`型で識別されます。 また、`external`や`view`もあります。
+その名の通り、`balanceOf`はアカウントの残高を返します。 Solidityでは、イーサリアムアカウントは160ビットを保持する`address`型で識別されます。
+この関数も`external`かつ`view`です。
```solidity
/**
- * @dev Moves `amount` tokens from the caller's account to `recipient`.
+ * @dev `amount`のトークンを呼び出し元のアカウントから`recipient`に移動させます。
*
- * Returns a boolean value indicating whether the operation succeeded.
+ * 操作が成功したかどうかを示すブール値を返します。
*
- * Emits a {Transfer} event.
+ * {Transfer}イベントを発行します。
*/
function transfer(address recipient, uint256 amount) external returns (bool);
```
-`transfer`関数は、呼び出し元から別のアドレスにトークンを転送します。 これは状態の変化を伴うので、`view`ではありません。 ユーザーがこの関数を呼び出すと、トランザクションが作成され、ガス代がかかります。 さらに、`Transfer`というイベントが発行され、ブロックチェーン上の全ノードにそのイベントが通知されます。
+`transfer`関数は、呼び出し元から別のアドレスにトークンを転送します。 これは状態の変化を伴うので、`view`ではありません。
+ユーザーがこの関数を呼び出すと、トランザクションが作成され、ガス代がかかります。 さらに、`Transfer`というイベントが発行され、ブロックチェーン上の全員にそのイベントが通知されます。
この関数には、2つの異なる呼び出し元のタイプに応じて、2つのタイプの出力があります。
-- ユーザーがユーザーインターフェースから関数を直接呼び出す場合。 通常、トランザクションを送信したユーザーは、その応答を待ちません。応答にどれくらいの時間がかかるか分からないからです。 ユーザーは、トランザクションレシート(トランザクションハッシュによって識別可能)を探すか、`Transfer`イベントを探すことで状況を把握できます。
-- 他のコントラクトがトランザクション全体の一部として関数を呼び出す場合。 これらのコントラクトは、すぐに結果を得ることができます。関数が同じトランザクション内で実行されるため、関数の戻り値を使用できるからです。
+- ユーザーがユーザーインターフェースから関数を直接呼び出す場合。 通常、ユーザーはトランザクションを送信すると、応答を待ちません。応答には不確定な時間がかかる可能性があるためです。 ユーザーは、トランザクションレシート(トランザクションハッシュによって識別される)を探すか、`Transfer`イベントを探すことで状況を把握できます。
+- 他のコントラクトが、全体的なトランザクションの一部として関数を呼び出す場合。 これらのコントラクトは、同じトランザクション内で実行されるため、関数の戻り値を使用でき、すぐに結果を得ることができます。
同じタイプの出力は、コントラクトの状態を変更する他の関数によって作成されます。
-割当量(allowance)を設定すると、あるアカウントが別の所有者に属しているトークンの一部を使えるようになります。 これは、コントラクトが売り手として機能する場合などに役立ちます。 コントラクトはイベントを監視できないため、買い手が売り手のコントラクトにトークンを直接転送した場合、売り手のコントラクトはその支払いを認識できません。 代わりに、買い手が売り手のコントラクトに一定量の使用を許可し、売り手がその量を転送するようにします。 この処理は売り手のコントラクトが呼び出した関数を通して行われるため、売り手のコントラクトは処理が成功したかどうかを確認できます。
+割当量(`allowance`)により、あるアカウントが別の所有者に属しているトークンの一部を使えるようになります。
+これは、例えば、コントラクトが売り手として機能する場合などに役立ちます。 コントラクトはイベントを監視できないため、買い手が売り手のコントラクトにトークンを直接転送した場合、売り手のコントラクトはその支払いを認識できません。 代わりに、買い手が売り手のコントラクトに一定量の使用を許可し、売り手がその量を転送します。
+この処理は売り手のコントラクトが呼び出す関数を通して行われるため、売り手のコントラクトは処理が成功したかどうかを確認できます。
```solidity
/**
- * @dev Returns the remaining number of tokens that `spender` will be
- * allowed to spend on behalf of `owner` through {transferFrom}. これは
- * デフォルトでゼロです。
+ * @dev {transferFrom}を通じて`spender`が`owner`に代わって使用できる、残りのトークン数を返します。これは
+ * デフォルトではゼロです。
*
- * This value changes when {approve} or {transferFrom} are called.
+ * この値は、{approve}または{transferFrom}が呼び出されると変化します。
*/
function allowance(address owner, address spender) external view returns (uint256);
```
-`allowance`関数を使用すると、誰でも、あるアドレス(`owner`)が別のアドレス(`spender`)に使用を許可している割当量(allowance)を照会できます。
+`allowance`関数により、誰でも、あるアドレス(`owner`)が別のアドレス(`spender`)に使用を許可している割当量を照会できます。
```solidity
/**
- * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
+ * @dev `spender`が呼び出し元のトークンに対して持つ割当量を`amount`に設定します。
*
- * Returns a boolean value indicating whether the operation succeeded.
+ * 操作が成功したかを示すブール値を返します。
*
- * IMPORTANT: Beware that changing an allowance with this method brings the risk
- * that someone may use both the old and the new allowance by unfortunate
- * transaction ordering. One possible solution to mitigate this race
- * condition is to first reduce the spender's allowance to 0 and set the
- * desired value afterwards:
+ * 重要: このメソッドで割当量を変更すると、不運なトランザクションの順序によって、誰かが古い割当量と新しい割当量の両方を使用するリスクがあります。
+ * この競合状態を緩和するための一つの解決策は、まずspenderの割当量を0に減らしてから、目的の値を設定することです。
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
- * Emits an {Approval} event.
+ * {Approval}イベントを発行します。
*/
function approve(address spender, uint256 amount) external returns (bool);
```
-`approve`関数は、割当量を作成します。 これがどのように悪用される可能性があるのかについて、該当のメッセージを必ず読んでください。 イーサリアムでは、自分のトランザクションの順序は制御できますが、他のユーザーのトランザクションが発生したことを確認してからトランザクションを送信しない限り、他のユーザーのトランザクションが実行される順序を制御することはできません。
+`approve`関数は、割当量を作成します。 これがどのように悪用される可能性があるのかについて、該当のメッセージを必ず読んでください。 イーサリアムでは、自分のトランザクションの順序は制御できますが、相手方のトランザクションが発生したことを確認してから自分のトランザクションを送信しない限り、他のユーザーのトランザクションが実行される順序を制御することはできません。
```solidity
/**
- * @dev Moves `amount` tokens from `sender` to `recipient` using the
- * allowance mechanism. `amount` is then deducted from the caller's
- * allowance.
+ * @dev 割当メカニズムを使用して、`amount`のトークンを`sender`から`recipient`に移動させます。`amount`は呼び出し元の割当量から差し引かれます。
*
- * Returns a boolean value indicating whether the operation succeeded.
+ * 操作が成功したかを示すブール値を返します。
*
- * Emits a {Transfer} event.
+ * {Transfer}イベントを発行します。
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
```
-最後に、使用者(spender)が`transferFrom`を使用して、割当量 (allowance)を実際に使用します。
+最後に、使用者(`spender`)が`transferFrom`を使用して、割当量(`allowance`)を実際に使用します。
```solidity
/**
- * @dev Emitted when `value` tokens are moved from one account (`from`) to
- * another (`to`).
+ * @dev `value`のトークンがあるアカウント(`from`)から
+ * 別のアカウント(`to`)に移動したときに発行されます。
*
- * Note that `value` may be zero.
+ * `value`はゼロになる場合があることに注意してください。
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
- * @dev Emitted when the allowance of a `spender` for an `owner` is set by
- * a call to {approve}. `value` is the new allowance.
+ * @dev {approve}の呼び出しによって`owner`に対する`spender`の割当量が設定されたときに発行されます。`value`は新しい割当量です。
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
```
-これらのイベントは、ERC-20コントラクトの状態が変更されるタイミングで発行されます。
+これらのイベントは、ERC-20コントラクトの状態が変更されると発行されます。
## 実際のコントラクト {#the-actual-contract}
-以下は、[こちらから取得した](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)、ERC-20規格を採用している実際のコントラクトです。 そのまま使うためのものではありませんが、[継承](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm)することで使用可能なコントラクトに拡張することができます。
+これはERC-20規格を実装した実際のコントラクトで、[こちら](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)から引用しました。
+これはそのまま使用するためのものではありませんが、それから[継承](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm)して、使えるものに拡張することができます。
```solidity
// SPDX-License-Identifier: MIT
@@ -195,7 +193,7 @@ pragma solidity >=0.6.0 <0.8.0;
-### インポートステートメント {#import-statements}
+### インポート文 {#import-statements}
コントラクト定義では、上記のインターフェース定義に加え、別の2つのファイルをインポートします。
@@ -206,48 +204,43 @@ import "./IERC20.sol";
import "../../math/SafeMath.sol";
```
-- `GSN/Context.sol`は、イーサ(ETH)を持たないユーザーがブロックチェーンを使用できるようにするシステムである、[OpenGSN](https://www.opengsn.org/)を使用するために必要な定義です。 これは古いバージョンであることに注意してください。OpenGSNと統合する場合は、[こちらのチュートリアルをご覧ください](https://docs.opengsn.org/javascript-client/tutorial.html)。
-- [ SafeMathライブラリ](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/)は、オーバーフローを起こさずに加算と減算を実行できるようにするために使用されます。 このライブラリが必要な理由は、これがないと、1つのトークンを持っているユーザーが何らかの方法で2つのトークンを使用した場合、2^256-1のトークンを持ってしまう可能性があるためです。
+- `GSN/Context.sol`は、etherを持たないユーザーがブロックチェーンを使用できるようにするシステムである[OpenGSN](https://www.opengsn.org/)を使用するために必要な定義です。 これは古いバージョンであることに注意してください。OpenGSNと統合する場合は、[このチュートリアル](https://docs.opengsn.org/javascript-client/tutorial.html)を使用してください。
+- [SafeMathライブラリ](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/)は、Solidityバージョン\*\*<0.8.0\*\*の算術オーバーフロー/アンダーフローを防ぎます。 Solidity ≥0.8.0では、算術演算はオーバーフロー/アンダーフローで自動的にリバートするため、SafeMathは不要です。 このコントラクトは、古いコンパイラバージョンとの後方互換性のためにSafeMathを使用しています。
-以下のコメントは、コントラクトの目的を説明しています。
+このコメントは、コントラクトの目的を説明しています。
```solidity
/**
- * @dev Implementation of the {IERC20} interface.
+ * @dev {IERC20}インターフェースの実装。
*
- * This implementation is agnostic to the way tokens are created. This means
- * that a supply mechanism has to be added in a derived contract using {_mint}.
- * For a generic mechanism see {ERC20PresetMinterPauser}.
+ * この実装は、トークンが作成される方法には依存しません。これは
+ * 供給メカニズムを、{_mint}を使用して派生コントラクトに追加する必要があることを意味します。
+ * 一般的なメカニズムについては、{ERC20PresetMinterPauser}を参照してください。
*
- * TIP: For a detailed writeup see our guide
- * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
- * to implement supply mechanisms].
+ * ヒント: 詳細な解説については、ガイド
+ * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[供給メカニズムの実装方法]を参照してください。
*
- * We have followed general OpenZeppelin guidelines: functions revert instead
- * of returning `false` on failure. This behavior is nonetheless conventional
- * and does not conflict with the expectations of ERC20 applications.
+ * OpenZeppelinの一般的なガイドラインに従っています。関数は失敗時に`false`を返すのではなく、リバートします。この動作は慣例的であり、ERC20アプリケーションの期待と矛盾しません。
*
- * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
- * This allows applications to reconstruct the allowance for all accounts just
- * by listening to said events. Other implementations of the EIP may not emit
- * these events, as it isn't required by the specification.
+ * さらに、{transferFrom}の呼び出し時に{Approval}イベントが発行されます。
+ * これにより、アプリケーションは、これらのイベントをリッスンするだけで、すべてのアカウントの割当量を再構築できます。EIPの他の実装では、
+ * 仕様で要求されていないため、これらのイベントを発行しない場合があります。
*
- * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
- * functions have been added to mitigate the well-known issues around setting
- * allowances. See {IERC20-approve}.
+ * 最後に、割当量設定に関する既知の問題を緩和するために、非標準の{decreaseAllowance}および{increaseAllowance}関数が追加されています。
+ * {IERC20-approve}を参照してください。
*/
```
-### コントラクトの定義 {#contract-definition}
+### コントラクト定義 {#contract-definition}
```solidity
contract ERC20 is Context, IERC20 {
```
-この行では、継承を指定しています。ここでは、`IERC20`とOpenGSNのための`Context`を継承しています。
+この行では、継承を指定しています。ここでは、上記の`IERC20`と、OpenGSNのための`Context`を継承しています。
@@ -257,19 +250,19 @@ contract ERC20 is Context, IERC20 {
```
-この行では、`SafeMath`ライブラリを`uint256`型にアタッチしています。 このライブラリの詳細については、[こちら](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol)をご覧ください。
+この行では、`SafeMath`ライブラリを`uint256`型にアタッチしています。 このライブラリは[こちら](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol)で確認できます。
-### 変数の定義 {#variable-definitions}
+### 変数定義 {#variable-definitions}
-これらの定義では、コントラクトの状態変数を指定します。 変数には、`private`で宣言しているものがありますが、ブロックチェーン上の他のコントラクトから読み取れないというだけです。 _ブロックチェーンに秘密はありません_。すべてのノードのソフトウェアは、すべてのブロックのすべてのコントラクトの状態を保持します。 状態変数は、慣例として`_`のように命名されます。
+これらの定義では、コントラクトの状態変数を指定します。 これらの変数は`private`で宣言されていますが、これはブロックチェーン上の他のコントラクトから読み取れないというだけです。 _ブロックチェーンに秘密はありません_。すべてのノードのソフトウェアは、すべてのブロックですべてのコントラクトの状態を保持します。 慣例として、状態変数は`_`と命名されます。
-最初の2つの変数は、[マッピング](https://www.tutorialspoint.com/solidity/solidity_mappings.htm)であり、キーが数値であることを除いて、[連想配列](https://wikipedia.org/wiki/Associative_array)とほぼ同じような振る舞いをします。 ストレージは、デフォルト(ゼロ)とは異なる値を持つエントリのみに割り当てられます。
+最初の2つの変数は[マッピング](https://www.tutorialspoint.com/solidity/solidity_mappings.htm)であり、キーが数値である点を除けば、おおよそ[連想配列](https://wikipedia.org/wiki/Associative_array)と同じように動作します。 ストレージは、デフォルト(ゼロ)とは異なる値を持つエントリにのみ割り当てられます。
```solidity
mapping (address => uint256) private _balances;
```
-最初のマッピングである`_balances`は、トークンを保持しているアドレスとそれぞれの残高です。 残高にアクセスするには、`_balances[]`という構文を使用します。
+最初のマッピングである`_balances`は、アドレスとそれぞれのこのトークンの残高です。 残高にアクセスするには、`_balances[]`という構文を使用します。
@@ -277,7 +270,7 @@ contract ERC20 is Context, IERC20 {
mapping (address => mapping (address => uint256)) private _allowances;
```
-この変数`_allowances`には、前述の割当量(allowance)が格納されます。 最初のインデックスは、トークンの所有者であり、2番目のインデックスは割当量(allowance)を使用するコントラクトです。 アドレスAが、アドレスBのアカウントから使える量にアクセスするには、`_allowances[B][A]`のようにします。
+この変数`_allowances`には、前述の割当量が格納されます。 最初のインデックスはトークンの所有者であり、2番目のインデックスは割当量を持つコントラクトです。 アドレスAがアドレスBのアカウントから使える量にアクセスするには、`_allowances[B][A]`を使用します。
@@ -297,78 +290,77 @@ contract ERC20 is Context, IERC20 {
この3つの変数は、可読性を向上させるために使用されます。 最初の2つの変数は自明ですが、`_decimals`はそうではありません。
-イーサリアムには浮動小数点変数も小数変数もない一方で、 ユーザーはトークンの分割を好みます。 人々が金を通貨にすると決めた理由の一つとして、誰かがアヒル一羽の値段の分だけ牛を買おうとしたときに、お金を崩すのが難しかったことが挙げられます。
+一方で、イーサリアムには浮動小数点変数も小数変数もありません。 他方で、人間はトークンを分割できることを好みます。 人々が金を通貨に決めた理由の一つは、誰かが牛の価値のアヒル分を買おうとしたときに、お釣りを作るのが難しかったからです。
-これを解決するには整数で追跡すればよいのですが、実際のトークンの代わりに、価値が非常に小さな小数トークンで計算します。 イーサ(ETH)の場合、小数トークンはウェイ(wei)と呼ばれており、10^18 weiが 1 ETHと等価です。 執筆時点では、10,000,000,000,000 weiが、約1米ドルまたは約1ユーロセントです。
+解決策は、整数で追跡し、実際のトークンの代わりに、ほとんど価値のない小数トークンを数えることです。 etherの場合、小数トークンはweiと呼ばれ、10^18 weiが1 ETHと等価です。 執筆時点で、10,000,000,000,000 weiは、約1米ドルまたは1ユーロセントです。
-アプリケーションには、トークンの残高を表示する方法が必要です。 ユーザーが3,14,000,000,000,000,000,000,000weiを持っている場合、それは3.14 ETHでしょうか? それとも、31.41 ETHでしょうか? 3,141 ETHでしょうか? イーサ (ETH) の場合、1 ETHが10^18 weiと定義されていますが、トークンでは別の値を選択可能です。 トークンを分割する必要がなければ、値がゼロの`_decimals`を使用できます。 ETHと同じ基準を使用したい場合は、**18**の値を指定してください。
+アプリケーションは、トークンの残高を表示する方法を知る必要があります。 ユーザーが3,141,000,000,000,000,000 weiを持っている場合、それは3.14 ETHでしょうか? 31.41 ETHでしょうか? 3,141 ETHでしょうか? etherの場合、10^18 weiが1 ETHと定義されていますが、あなたのトークンでは別の値を選択できます。 トークンを分割する必要がなければ、値がゼロの`_decimals`を使用できます。 ETHと同じ基準を使用したい場合は、値**18**を使用してください。
### コンストラクタ {#the-constructor}
```solidity
/**
- * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
- * a default value of 18.
+ * @dev {name}と{symbol}の値を設定し、{decimals}を
+ * デフォルト値の18で初期化します。
*
- * To select a different value for {decimals}, use {_setupDecimals}.
+ * {decimals}に別の値を選択するには、{_setupDecimals}を使用します。
*
- * All three of these values are immutable: they can only be set once during
- * construction.
+ * これら3つの値はすべて不変です。構築時に一度しか設定できません。
*/
constructor (string memory name_, string memory symbol_) public {
+ // Solidity ≥0.7.0では、'public'は暗黙的であり、省略できます。
+
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
```
-コンストラクタは、コントラクトが最初に作成されたときに呼び出されます。 慣例として関数パラメータは、 `_`のように命名されます。
+コンストラクタは、コントラクトが最初に作成されたときに呼び出されます。 慣例として関数パラメータは、`_`のように命名されます。
### ユーザーインターフェース関数 {#user-interface-functions}
```solidity
/**
- * @dev Returns the name of the token.
+ * @dev トークンの名前を返します。
*/
function name() public view returns (string memory) {
return _name;
}
/**
- * @dev Returns the symbol of the token, usually a shorter version of the
- * name.
+ * @dev トークンのシンボルを返します。通常は名前の短いバージョンです。
+ * 名前です。
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
- * @dev Returns the number of decimals used to get its user representation.
- * For example, if `decimals` equals `2`, a balance of `505` tokens should
- * be displayed to a user as `5,05` (`505 / 10 ** 2`).
+ * @dev ユーザー表現を取得するために使用される小数点以下の桁数を返します。
+ * 例えば、`decimals`が`2`の場合、`505`トークンの残高は
+ * `5,05` (`505 / 10 ** 2`)としてユーザーに表示されるべきです。
*
- * Tokens usually opt for a value of 18, imitating the relationship between
- * ether and wei. This is the value {ERC20} uses, unless {_setupDecimals} is
- * called.
+ * トークンは通常、etherとweiの関係を模倣して、値18を選択します。これは、{_setupDecimals}が呼び出されない限り、{ERC20}が使用する値です。
*
- * NOTE: This information is only used for _display_ purposes: it in
- * no way affects any of the arithmetic of the contract, including
- * {IERC20-balanceOf} and {IERC20-transfer}.
+ * 注: この情報は_表示_目的でのみ使用されます。これは
+ * {IERC20-balanceOf}や{IERC20-transfer}を含む、コントラクトのどの算術にも
+ * 影響を与えません。
*/
function decimals() public view returns (uint8) {
return _decimals;
}
```
-これらの関数(`name`、`symbol`、`decimals`)は、ユーザーインターフェースがコントラクトの情報を入手できるようするため、ユーザーインターフェースにコントラクトの情報が正しく表示されるようになります。
+これらの関数`name`、`symbol`、`decimals`は、ユーザーインターフェースがあなたのコントラクトについて知り、正しく表示できるようにするのに役立ちます。
-戻り値の型は、 `string memory`です。メモリに格納されている文字列が返されることを意味します。 文字列などの変数は、以下の3つの場所に格納できます。
+戻り値の型は`string memory`で、メモリに格納されている文字列を返すことを意味します。 文字列などの変数は、3つの場所に格納できます。
-| | 存続期間 | コントラクトアドレス | ガス代 |
-| ------ | -------- | ---------- | ------------------------ |
-| メモリ | 関数呼び出しの間 | 読み取り/書き込み | 数十または数百(上位のロケーションほど高い) |
-| コールデータ | 関数呼び出しの間 | 読み取り専用 | 戻り値型としては使用できず、関数パラメータ型のみ |
-| ストレージ | 変更されるまで | 読み取り/書き込み | 高額(読み取りに800、書き込みに20 k) |
+| | 存続期間 | コントラクトアクセス | ガス代 |
+| ------ | ------- | ---------- | ----------------------------------------- |
+| Memory | 関数呼び出し中 | 読み取り/書き込み | 数十または数百(上位のロケーションほど高い) |
+| コールデータ | 関数呼び出し中 | 読み取り専用 | 戻り値型としては使用できず、関数パラメータ型のみ |
+| ストレージ | 変更されるまで | 読み取り/書き込み | 高額(読み取りに800、書き込みに20k) |
このケースでは、`memory`の使用が最善の選択肢です。
@@ -378,7 +370,7 @@ contract ERC20 is Context, IERC20 {
```solidity
/**
- * @dev See {IERC20-totalSupply}.
+ * @dev {IERC20-totalSupply}を参照してください。
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
@@ -391,30 +383,30 @@ contract ERC20 is Context, IERC20 {
```solidity
/**
- * @dev See {IERC20-balanceOf}.
+ * @dev {IERC20-balanceOf}を参照してください。
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
```
-アカウントの残高を読み取ります。 誰でも他のユーザーのアカウント残高を取得できることに注意してください。 どのノードでも取得可能な情報であるため、隠そうとしても無駄です。 _ブロックチェーンに秘密はありません_。
+アカウントの残高を読み取ります。 誰でも他の人のアカウント残高を取得できることに注意してください。 この情報はどのノードでも入手可能であるため、隠そうとしても無駄です。 _ブロックチェーンに秘密はありません。_
### トークンの転送 {#transfer-tokens}
```solidity
/**
- * @dev See {IERC20-transfer}.
+ * @dev {IERC20-transfer}を参照してください。
*
- * Requirements:
+ * 要件:
*
- * - `recipient` cannot be the zero address.
- * - the caller must have a balance of at least `amount`.
+ * - `recipient`はゼロアドレスであってはなりません。
+ * - 呼び出し元は少なくとも`amount`の残高を持っている必要があります。
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
```
-`transfer`関数は、送信者のアカウントから別のアカウントにトークンを転送するために呼び出します。 戻り値がブール値になっていますが、この値は常に**true**を返すことに注意してください。 転送が失敗した場合、コントラクトは、呼び出しを取り消します。
+`transfer`関数は、送信者のアカウントから別のアカウントにトークンを転送するために呼び出します。 戻り値がブール値ですが、その値は常に**true**であることに注意してください。 転送が失敗した場合、コントラクトは呼び出しをリバートします。
@@ -424,44 +416,44 @@ contract ERC20 is Context, IERC20 {
}
```
-`_transfer`関数は、実際の作業を行います。 これはprivate関数であり、他のコントラクト関数からのみ呼び出せます。 慣例として、private関数は状態変数と同様に、`_`のように命名されます。
+`_transfer`関数が実際の作業を行います。 これはprivate関数であり、他のコントラクト関数からのみ呼び出せます。 慣例として、private関数は状態変数と同様に`_`と命名されます。
-通常、Solidityでは、メッセージ送信者に`msg.sender`を使用します。 しかし、[OpenGSN](http://opengsn.org/)では使えません。 イーサ(ETH)無しのトークンのトランザクションを許可したい場合は、`_msgSender()`を使用しなければなりません。 通常のトランザクションでは、`msg.sender`を返しますが、イーサ(ETH)無しのトランザクションの場合は、メッセージを中継したコントラクトではなく、元の署名者を返します。
+通常、Solidityでは、メッセージ送信者に`msg.sender`を使用します。 しかし、それでは[OpenGSN](http://opengsn.org/)が機能しません。 トークンでetherレスのトランザクションを許可したい場合は、`_msgSender()`を使用する必要があります。 通常のトランザクションでは`msg.sender`を返しますが、etherレスのトランザクションの場合は、メッセージを中継したコントラクトではなく、元の署名者を返します。
-### 割当量(allowance)関連の関数 {#allowance-functions}
+### 割当量関数 {#allowance-functions}
-割当量機能を実装した関数には、`allowance`、`approve`、 `transferFrom`、`_approve`があります。 さらに、OpenZeppelin実装には、基本的な標準に加えてセキュリティを向上させる `increaseAllowance`や`decreaseAllowance`などの複数の機能が含まれます。
+これらは割当量機能を実装する関数です: `allowance`、`approve`、`transferFrom`、`_approve`。 さらに、OpenZeppelin実装は、セキュリティを向上させる機能である`increaseAllowance`と`decreaseAllowance`を含むように、基本的な標準を超えています。
#### allowance関数 {#allowance}
```solidity
/**
- * @dev See {IERC20-allowance}.
+ * @dev {IERC20-allowance}を参照してください。
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
```
-`allowance`関数を使用すると、誰でも割当量を確認することができます。
+`allowance`関数を使用すると、誰でも任意の割当量を確認することができます。
#### approve関数 {#approve}
```solidity
/**
- * @dev See {IERC20-approve}.
+ * @dev {IERC20-approve}を参照してください。
*
- * Requirements:
+ * 要件:
*
- * - `spender` cannot be the zero address.
+ * - `spender`はゼロアドレスであってはなりません。
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
```
-この関数は、割当量を作成するときに呼び出します。 上述の`transfer`関数と似ています。
+この関数は、割当量を作成するときに呼び出します。 上記の`transfer`関数と似ています。
-- この関数は、単に実際に作業を行うinternal関数(この場合は`_approve`)を呼び出します。
-- この関数は、成功した場合は`true`を返し、失敗した場合は取り消します。
+- この関数は、単に実際に作業を行う内部関数(この場合は`_approve`)を呼び出します。
+- この関数は、成功した場合は`true`を返し、失敗した場合はリバートします。
@@ -471,25 +463,25 @@ contract ERC20 is Context, IERC20 {
}
```
-internal関数を使用して、状態変更が起こる場所の数を最小限にしています。 状態を変更する_すべての_関数には、潜在的なセキュリティリスクがあり、セキュリティ監査が必要です。 このような方法で、間違いを犯す可能性を下げています。
+内部関数を使用して、状態変更が起こる場所の数を最小限にしています。 状態を変更する_すべての_関数には潜在的なセキュリティリスクがあり、セキュリティ監査が必要です。 この方法で、間違いを犯す可能性を下げています。
#### transferFrom関数 {#transferFrom}
-これは、使用者(spender)が割当量(allowance)を使用するために呼び出す関数です。 これには、使う量の転送操作と、その量を割当量(allowance)から減らす操作の、2つの操作が必要になります。
+これは、使用者(`spender`)が割当量を使用するために呼び出す関数です。 これには、使用される量を転送し、その量だけ割当量を減らすという2つの操作が必要です。
```solidity
/**
- * @dev See {IERC20-transferFrom}.
+ * @dev {IERC20-transferFrom}を参照してください。
*
- * Emits an {Approval} event indicating the updated allowance. これは
- * EIPでは必要ありません。 {ERC20}の最初にある注意事項を参照してください。
+ * 更新された割当量を示す{Approval}イベントを発行します。これは
+ * EIPでは要求されていません。{ERC20}の冒頭の注記を参照してください。
*
- * Requirements:
+ * 要件:
*
- * - `sender` and `recipient` cannot be the zero address.
- * - `sender` must have a balance of at least `amount`.
- * - the caller must have allowance for ``sender``'s tokens of at least
- * `amount`.
+ * - `sender`と`recipient`はゼロアドレスであってはなりません。
+ * - `sender`は少なくとも`amount`の残高を持っている必要があります。
+ * - 呼び出し元は、`sender`のトークンに対して少なくとも
+ * `amount`の割当量を持っている必要があります。
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual
override returns (bool) {
@@ -498,7 +490,8 @@ internal関数を使用して、状態変更が起こる場所の数を最小限
-`a.sub(b, "message")`関数の呼び出しでは、次の2つのことを行います。 まず、`a-b`を計算します。これが新しい割当量になります。 次に、この結果が負の数になっていないかをチェックします。 負になっている場合、提供されているメッセージを表示して、呼び出しが取り消されます。 呼び出しが取り消されると、呼び出し中に実行されたすべての処理が無効になるため、`_transfer`を元に戻す必要がないことに注意してください。
+`a.sub(b, "message")`関数の呼び出しでは、次の2つのことを行います。 まず、`a-b`を計算します。これが新しい割当量になります。
+次に、この結果が負の数になっていないかをチェックします。 負になっている場合、提供されているメッセージを表示して呼び出しがリバートされます。 呼び出しがリバートされると、その呼び出し中に以前に実行されたすべての処理は無視されるため、`_transfer`を元に戻す必要はありません。
```solidity
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount,
@@ -507,50 +500,49 @@ internal関数を使用して、状態変更が起こる場所の数を最小限
}
```
-#### OpenZeppelinによる安全性の向上 {#openzeppelin-safety-additions}
+#### OpenZeppelinの安全追加機能 {#openzeppelin-safety-additions}
-ゼロ以外の割当量を別のゼロ以外の値に設定することには、リスクが伴います。自分が制御できるのは自分のトランザクションの順序のみであり、他のユーザーのトランザクションの順序を制御することはできないからです。 アリスという初心者ユーザーと、ビルという誠実さに欠けるユーザーがいるとします。 アリスは、ビルが提供しているサービスを購入することにしました。購入には5トークンの費用がかかるため、アリスは5トークンの割当量(allowance)をビルに付与しました。
+ゼロ以外の割当量を別のゼロ以外の値に設定することにはリスクが伴います。なぜなら、自分が制御できるのは自分のトランザクションの順序のみであり、他のユーザーのトランザクションの順序は制御できないからです。 経験の浅いアリスと、不誠実なビルという2人のユーザーがいるとします。 アリスはビルからサービスを受けたいと考えており、その費用は5トークンだと思っています。そこで、彼女はビルに5トークンの割当量を与えます。
-その後、ビルの設定した価格が何らかの理由で10トークンに上がりました。 アリスは依然としてそのサービスの購入を希望しており、ビルへの割当量を10に設定したトランザクションを送信しました。 ビルは、トランザクションプールでこの新しいトランザクションを確認した瞬間に、より早くマイニングされるようにかなり高いガス代を設定した、アリスの5トークンを使うトランザクションを送信します。 この方法で、ビルは5トークンを使います。その後、アリスが送信した新しい割当量がマイニングされたら、さらに10トークンを使います。こうして、アリスが承認するつもりだった量を超える、合計15トークンを使えることになります。 この手法は、[フロントランニング](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running)と呼ばれます。
+その後、何かが変わり、ビルの価格は10トークンに上がりました。 まだサービスを受けたいアリスは、ビルの割当量を10に設定するトランザクションを送信します。 ビルはこの新しいトランザクションをトランザクションプールで確認した瞬間に、アリスの5トークンを使うトランザクションを送信し、より早くマイニングされるように非常に高いガス価格を設定します。 この方法で、ビルは最初に5トークンを使い、アリスの新しい割当量がマイニングされたら、さらに10トークンを使って合計15トークンを得ることができます。これはアリスが承認するつもりだった額よりも多いです。 このテクニックは[フロントランニング](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running)と呼ばれます。
-| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
-| ----------------- | ------- | ----------------------------- | ------ | ------ | ------------ |
-| approve(Bill, 5) | 10 | | | 5 | 0 |
-| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
-| approve(Bill, 10) | 11 | | | 10 | 5 |
-| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 |
+| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
+| ------------------------------------ | ------- | ------------------------------------------------ | ------ | ------ | ------------ |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
+| approve(Bill, 10) | 11 | | | 10 | 5 |
+| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 |
-この問題を回避するには、割当量を特定の量に変更できる2つの関数(`increaseAllowance`と`decreaseAllowance`)を使用します。 これらの関数を使用すれば、ビルがすでに5トークンを使用していた場合、その後に使用できるのは残りの5トークンのみとなります。 タイミングに応じて、次のような2つの動作が考えられますが、いずれの場合でもビルが取得するのは10トークンのみです。
+この問題を回避するには、2つの関数(`increaseAllowance`と`decreaseAllowance`)を使用して、割当量を特定の量だけ変更します。 これにより、ビルがすでに5トークンを使用していた場合でも、その後に使用できるのは追加の5トークンのみとなります。 タイミングに応じて、次のような2つの動作が考えられますが、いずれの場合でもビルが取得するのは10トークンのみです。
A:
-| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
-| -------------------------- | -------:| ---------------------------- | ------:| -------:| ------------ |
-| approve(Bill, 5) | 10 | | | 5 | 0 |
-| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
-| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 |
-| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 |
+| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
+| --------------------------------------------- | ------: | ----------------------------------------------- | -----: | ------: | ------------ |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
+| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 |
+| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 |
B:
-| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
-| -------------------------- | -------:| ----------------------------- | ------:| --------:| ------------:|
-| approve(Bill, 5) | 10 | | | 5 | 0 |
-| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 |
-| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 |
+| アリスのトランザクション | アリスのノンス | ビルのトランザクション | ビルのノンス | ビルの割当量 | ビルのアリスからの総収入 |
+| --------------------------------------------- | ------: | ------------------------------------------------ | -----: | -------: | -----------: |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 |
+| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 |
```solidity
/**
- * @dev Atomically increases the allowance granted to `spender` by the caller.
+ * @dev 呼び出し元によって付与された`spender`への割当量をアトミックに増加させます。
*
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
+ * これは{approve}の代替手段であり、{IERC20-approve}で説明されている問題を緩和するために使用できます。
*
- * Emits an {Approval} event indicating the updated allowance.
+ * 更新された割当量を示す{Approval}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `spender` cannot be the zero address.
+ * - `spender`はゼロアドレスであってはなりません。
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
@@ -558,23 +550,22 @@ B:
}
```
-`a.add(b)`関数は、安全な加算です。 万が一、`a`+`b`>=`2^256`のような計算が行われても、通常の加算で発生してしまうオーバー(アンダー)フローが発生しません。
+`a.add(b)`関数は、安全な加算です。 万が一`a`+`b`>=`2^256`となっても、通常の加算のようにラップアラウンドしません。
```solidity
/**
- * @dev Atomically decreases the allowance granted to `spender` by the caller.
+ * @dev 呼び出し元によって付与された`spender`への割当量をアトミックに減少させます。
*
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
+ * これは{approve}の代替手段であり、{IERC20-approve}で説明されている問題を緩和するために使用できます。
*
- * Emits an {Approval} event indicating the updated allowance.
+ * 更新された割当量を示す{Approval}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `spender` cannot be the zero address.
- * - `spender` must have allowance for the caller of at least
- * `subtractedValue`.
+ * - `spender`はゼロアドレスであってはなりません。
+ * - `spender`は呼び出し元に対して、少なくとも
+ * `subtractedValue`の割当量を持っている必要があります。
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue,
@@ -587,27 +578,27 @@ B:
次の4つの関数(`_transfer`、`_mint`、`_burn`、`_approve`)は、実際の処理を行います。
-#### \_transfer関数 {#_transfer}
+#### _transfer関数 {#_transfer}
```solidity
/**
- * @dev Moves tokens `amount` from `sender` to `recipient`.
+ * @dev トークン`amount`を`sender`から`recipient`に移動させます。
*
- * This is internal function is equivalent to {transfer}, and can be used to
- * e.g., implement automatic token fees, slashing mechanisms, etc.
+ * この内部関数は{transfer}と同等であり、
+ * 例えば、自動的なトークン手数料やスラッシングメカニズムなどを実装するために使用できます。
*
- * Emits a {Transfer} event.
+ * {Transfer}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `sender` cannot be the zero address.
- * - `recipient` cannot be the zero address.
- * - `sender` must have a balance of at least `amount`.
+ * - `sender`はゼロアドレスであってはなりません。
+ * - `recipient`はゼロアドレスであってはなりません。
+ * - `sender`は少なくとも`amount`の残高を持っている必要があります。
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
```
-`_transfer`関数は、トークンをあるアカウントから別のアカウントへ転送します。 この関数は、(送信者自身のアカウントから転送する)`transfer`と、(割当量を使用するために他のユーザーのアカウントから転送する)`transferFrom`の両方から呼び出されます。
+この`_transfer`関数は、トークンをあるアカウントから別のアカウントへ転送します。 この関数は、`transfer`(送信者自身のアカウントからの転送)と`transferFrom`(割当量を使用して他のユーザーのアカウントから転送)の両方から呼び出されます。
@@ -628,11 +619,11 @@ B:
このコントラクトを使用するには2つの方法があります。
1. 自分のコードのテンプレートとして使う
-1. [このコントラクトを継承](https://www.bitdegree.org/learn/solidity-inheritance)し、変更する必要がある関数のみをオーバーライドする
+2. [コントラクトから継承](https://www.bitdegree.org/learn/solidity-inheritance)し、修正が必要な関数のみをオーバーライドする
-OpenZeppelin ERC-20のコードはすでに監査を受けており、安全であることが知られているため、2つ目の方法をお勧めします。 継承を使用すると、変更した関数が明らかになります。他のユーザーは、変更された特定の関数を監査するだけで、そのコントラクトを信頼することができます。
+OpenZeppelinのERC-20コードはすでに監査を受けており、安全であることが示されているため、2つ目の方法がはるかに優れています。 継承を使用すると、変更した関数が明らかになり、人々はコントラクトを信頼するためにそれらの特定の関数のみを監査すればよくなります。
-多くの場合、トークンの所有者が変わるたびに関数を実行すると便利です。 ただし、`_transfer`は非常に重要な関数ですが、安全でない書き込みをしてしまう可能性があるため(下記参照)、オーバーライドしないことをお勧めします。 この解決策として、`_beforeTokenTransfer`という[フック関数](https://wikipedia.org/wiki/Hooking)があります。 この関数をオーバライドすれば、転送のたびに呼び出されるようになります。
+多くの場合、トークンの所有者が変わるたびに関数を実行すると便利です。 しかし、`_transfer`は非常に重要な関数であり、安全でない書き方をしてしまう可能性があるため(下記参照)、オーバーライドしないことをお勧めします。 解決策は、[フック関数](https://wikipedia.org/wiki/Hooking)である`_beforeTokenTransfer`です。 この関数をオーバーライドすれば、転送のたびに呼び出されるようになります。
@@ -641,7 +632,7 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
_balances[recipient] = _balances[recipient].add(amount);
```
-この2行で、実際に転送を行っています。 この2行の間に**何もない**ことと、転送する量を送信者から減算してから、その量を受取人に加算していることに注意してください。 この2行の間に別のコントラクトへの呼び出しがある場合、このコントラクトで不正を行うために使用される可能性があるため、このことは非常に重要になります。 こうすることで、転送がアトミックになる(他の操作に割り込まれないようになる)ため、転送の途中で何かが発生することはなくなります。
+この2行で、実際に転送を行っています。 この2行の間には**何も**なく、受取人に加算する前に送信者から転送額を減算していることに注意してください。 この2行の間に別のコントラクトへの呼び出しがある場合、このコントラクトで不正を行うために使用される可能性があるため、このことは非常に重要になります。 こうすることで、転送がアトミックになり、その途中で何も起こらなくなります。
@@ -650,23 +641,25 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
}
```
-最後に、`Transfer`イベントを発行します。 イベントは、スマートコントラクトからアクセスできません。しかし、ブロックチェーンの外で実行されているコードは、イベントをリッスンして対応することができます。 例えば、ウォレットで所有者がより多くのトークンを得た時期を追跡できます。
+最後に、`Transfer`イベントを発行します。 イベントはスマートコントラクトからアクセスできませんが、ブロックチェーンの外で実行されているコードは、イベントをリッスンして対応することができます。 例えば、ウォレットは所有者がより多くのトークンを得た時期を追跡できます。
-#### \_mint関数と\_burn関数 {#_mint-and-_burn}
+#### _mint関数と_burn関数 {#_mint-and-_burn}
-この2つの関数(`_mint`と`_burn`)は、トークンの総供給量を変更します。 これらはinternalであり、このコントラクト内にこれらを呼び出す関数はありません。そのため、コントラクトを継承し、新しいトークンのミントや既存のトークンのバーンを実行する条件を決定する独自のロジックを追加する場合にのみ役立ちます。
+この2つの関数(`_mint`と`_burn`)は、トークンの総供給量を変更します。
+これらは内部関数であり、このコントラクト内にこれらを呼び出す関数はありません。そのため、コントラクトを継承し、どのような条件下で新しいトークンをミントし、既存のトークンをバーンするかを決定する独自のロジックを追加する場合にのみ役立ちます。
-**注:** すべてのERC-20トークンには、トークン管理を規定している独自のビジネスロジックがあります。 例えば、固定した供給量のコントラクトでは、コンストラクタ内で `_mint`のみを呼び出す可能性があり、`_burn`を呼び出すことはありません。 トークンを販売するコントラクトは、支払いが行われたタイミングで`_mint`を呼び出し、天井知らずのインフレを避けるために、ある時点で`_burn`を呼び出すことが考えられます。
+**注:** すべてのERC-20トークンには、トークン管理を規定する独自のビジネスロジックがあります。
+例えば、固定供給量のコントラクトでは、コンストラクタ内で`_mint`のみを呼び出し、`_burn`を呼び出すことはありません。 トークンを販売するコントラクトは、支払いが行われたタイミングで`_mint`を呼び出し、おそらく、天井知らずのインフレを避けるためにある時点で`_burn`を呼び出します。
```solidity
- /** @dev Creates `amount` tokens and assigns them to `account`, increasing
- * the total supply.
+ /** @dev `amount`のトークンを作成して`account`に割り当て、
+ * 総供給量を増やします。
*
- * Emits a {Transfer} event with `from` set to the zero address.
+ * `from`がゼロアドレスに設定された{Transfer}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `to` cannot be the zero address.
+ * - `to`はゼロアドレスであってはなりません。
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
@@ -677,21 +670,21 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
}
```
-トークンの総額が変更された場合は、`_totalSupply`を必ずアップデートしてください。
+トークンの総数が変更された場合は、`_totalSupply`を必ずアップデートしてください。
-```
+```solidity
/**
- * @dev Destroys `amount` tokens from `account`, reducing the
- * total supply.
+ * @dev `account`から`amount`のトークンを破棄し、
+ * 総供給量を減らします。
*
- * Emits a {Transfer} event with `to` set to the zero address.
+ * `to`がゼロアドレスに設定された{Transfer}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `account` cannot be the zero address.
- * - `account` must have at least `amount` tokens.
+ * - `account`はゼロアドレスであってはなりません。
+ * - `account`は少なくとも`amount`のトークンを持っている必要があります。
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
@@ -706,23 +699,23 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
`_burn`関数は、方向が逆であることを除き`_mint`とほぼ同じです。
-#### \_approve関数 {#_approve}
+#### _approve関数 {#_approve}
-これは、実際の割当量(allowance)を指定する関数です。 所有者は自身の現在の残高よりも高い割当量を指定できることに注意してください。 残高は転送時にチェックされるため、割当量の作成時の残高と異なっていても問題ありません。
+これは、実際に割当量を指定する関数です。 所有者は自身の現在の残高よりも高い割当量を指定できることに注意してください。 残高は転送時にチェックされ、割当量の作成時の残高と異なる可能性があるため、これは問題ありません。
```solidity
/**
- * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
+ * @dev `owner`のトークンに対する`spender`の割当量を`amount`に設定します。
*
- * This internal function is equivalent to `approve`, and can be used to
- * e.g., set automatic allowances for certain subsystems, etc.
+ * この内部関数は`approve`と同等であり、
+ * 例えば、特定のサブシステムに対する自動的な割当量などを設定するために使用できます。
*
- * Emits an {Approval} event.
+ * {Approval}イベントを発行します。
*
- * Requirements:
+ * 要件:
*
- * - `owner` cannot be the zero address.
- * - `spender` cannot be the zero address.
+ * - `owner`はゼロアドレスであってはなりません。
+ * - `spender`はゼロアドレスであってはなりません。
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
@@ -733,7 +726,7 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
-`Approval`イベントを発行します。 アプリケーションがどのように書かれているかによって異なりますが、使用者(spender)のコントラクトには、所有者またはこれらのイベントをリッスンしているサーバーのいずれかによって承認(Approval)が通知されます。
+`Approval`イベントを発行します。 アプリケーションがどのように書かれているかによって異なりますが、使用者(`spender`)のコントラクトには、所有者またはこれらのイベントをリッスンしているサーバーのいずれかによって承認が通知されます。
```solidity
emit Approval(owner, spender, amount);
@@ -741,57 +734,61 @@ OpenZeppelin ERC-20のコードはすでに監査を受けており、安全で
```
-### 小数変数の変更 {#modify-the-decimals-variable}
+### decimals変数の変更 {#modify-the-decimals-variable}
```solidity
/**
- * @dev Sets {decimals} to a value other than the default one of 18.
+ * @dev {decimals}をデフォルト値の18以外の値に設定します。
*
- * WARNING: This function should only be called from the constructor. Most
- * applications that interact with token contracts will not expect
- * {decimals} to ever change, and may work incorrectly if it does.
+ * 警告: この関数はコンストラクタからのみ呼び出すべきです。ほとんどの
+ * トークンコントラクトと対話するアプリケーションは、
+ * {decimals}が変更されることを想定しておらず、変更されると誤動作する可能性があります。
*/
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
```
-この関数は、`_decimals`変数を変更します。`_decimals`変数は、量(金額)の解釈方法をユーザーインターフェースに伝えるのに使用されます。 コンストラクタから呼び出される必要があります。 その後のどの時点においても、この関数を呼び出すと不正になります。アプリケーションは、このような処理をするようには設計されていません。
+この関数は`_decimals`変数を変更します。この変数は、量の解釈方法をユーザーインターフェースに伝えるのに使用されます。
+コンストラクタから呼び出すべきです。 その後のどの時点においてもこの関数を呼び出すと不正になり、アプリケーションはこのような処理をするようには設計されていません。
### フック {#hooks}
```solidity
/**
- * @dev Hook that is called before any transfer of tokens. これには
+ * @dev トークンのあらゆる転送の前に呼び出されるフック。これには
* ミントとバーンが含まれます。
*
- * Calling conditions:
+ * 呼び出し条件:
*
- * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * will be to transferred to `to`.
- * - when `from` is zero, `amount` tokens will be minted for `to`.
- * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
- * - `from` and `to` are never both zero.
+ * - `from`と`to`が両方ともゼロでない場合、`from`のトークンの`amount`が
+ * `to`に転送されます。
+ * - `from`がゼロの場合、`amount`のトークンが`to`のためにミントされます。
+ * - `to`がゼロの場合、`from`のトークンの`amount`がバーンされます。
+ * - `from`と`to`が両方ともゼロになることはありません。
*
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
+ * フックについてさらに学ぶには、xref:ROOT:extending-contracts.adoc#using-hooks[フックの使用]を参照してください。
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
```
-このフック関数は、転送中に呼び出されます。 空になっていますが、何かを実行するのにこの関数が必要な場合は、オーバーライドしてください。
+このフック関数は、転送中に呼び出されます。 ここでは空になっていますが、何かを実行するのにこの関数が必要な場合は、オーバーライドしてください。
-## まとめ {#conclusion}
+## 結論 {#conclusion}
確認のため、このコントラクトの最も重要な点を以下にまとめています(個人的な意見のため、他者にとって重要な点とは異なる場合があります) 。
-- _ブロックチェーンに秘密はありません_。 スマートコントラクトがアクセスできる情報は、世界中で利用可能であることを意味します。
-- 自分のトランザクションの順序は自分で制御できますが、他のユーザーのトランザクションが発生するタイミングは制御できません。 これが、割当量(allowance)の変更に伴うリスクになります。変更により、使用者(spender)が変更前と変更後の両方の割当量を使用できてしまうためです。
-- `uint256`型の値がオーバー(アンダー)フローします。 つまり、例えば_0-1=2^256-1_です。 これが望ましい動作ではない場合、プログラムで確認する必要があります(または、それを行うSafeMathライブラリを使用します)。 この仕様は、[Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html)で変更されていることに注意してください。
-- 監査を容易にするため、特定の場所で特定の型のすべての状態変更を行います。 例えば、`_approve`が、`approve`、`transferFrom`、`increaseAllowance`、`decreaseAllowance`などによって呼び出されるのは、この理由です。
-- (`_transfer`で見られるように)状態変更は、処理の途中で他の操作に割り込まれることがないアトミックである必要があります。 これは状態変更中に、一貫性のない状態が存在するためです。 例えば、送信者の残高からトークンを差し引いた時点から、受取人の残高にそのトークンを加えるまでの間は、存在すべき数よりも少ない数のトークンが存在することになります。 この2つの処理の間に別の操作(特に、異なるコントラクトの呼び出しなど)がある場合、このトークンの状態が悪用される可能性があります。
+- ブロックチェーンには秘密はありません。 スマートコントラクトがアクセスできる情報は、全世界で利用可能です。
+- 自分のトランザクションの順序は自分で制御できますが、他のユーザーのトランザクションが発生するタイミングは制御できません。 これが、割当量の変更が危険となりうる理由です。変更により、使用者(`spender`)が両方の割当量の合計を使用できてしまうためです。
+- `uint256`型の値はラップアラウンドします。 言い換えると、_0-1=2^256-1_となります。 これが望ましい動作ではない場合、プログラムで確認する必要があります(または、それを行うSafeMathライブラリを使用します)。 これは[Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html)で変更されたことに注意してください。
+- 監査を容易にするため、特定の場所で特定の型のすべての状態変更を行います。
+ これが、例えば`approve`、`transferFrom`、`increaseAllowance`、`decreaseAllowance`によって呼び出される`_approve`が存在する理由です。
+- 状態変更は、(`_transfer`で見られるように)処理の途中で他のアクションに割り込まれることがないアトミックである必要があります。 これは状態変更中に、一貫性のない状態が存在するためです。 例えば、送信者の残高から差し引いた時点から、受取人の残高に加えるまでの間は、存在するべき数よりも少ないトークンが存在することになります。 この2つの処理の間に別の操作(特に、異なるコントラクトの呼び出しなど)がある場合、このトークンの状態が悪用される可能性があります。
+
+ここまで、OpenZeppelin ERC-20コントラクトがどのように書かれているか、特に、より安全に記述する方法を学びました。是非自分でも安全なコントラクトとアプリケーションを作成してみてください。
-ここまで、OpenZeppelin ERC-20コントラクトがどのように書かれているかについて見てきました。特に、より安全に記述する方法を学びました。是非自分でも安全なコントラクトとアプリケーションを作成してみてください。
+[私の他の作品はこちらでご覧いただけます](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ja/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/ja/developers/tutorials/erc20-with-safety-rails/index.md
index ed97fc06bfd..26fabbd4847 100644
--- a/public/content/translations/ja/developers/tutorials/erc20-with-safety-rails/index.md
+++ b/public/content/translations/ja/developers/tutorials/erc20-with-safety-rails/index.md
@@ -1,10 +1,9 @@
---
-title: ERC-20の安全策
-description: つまらないミスをするのを避ける方法
+title: "安全策を備えたERC-20"
+description: "ユーザーのうっかりミスを防ぐ方法"
author: Ori Pomerantz
lang: ja
-tags:
- - "ERC-20"
+tags: [ "ERC-20" ]
skill: beginner
published: 2022-08-15
---
@@ -13,48 +12,51 @@ published: 2022-08-15
イーサリアムの素晴らしい点の1つとして、トランザクションを変更したり取り消したりできる中央機関が存在しないことがあります。 反対に、イーサリアムでは、ユーザーの間違いや不正なトランザクションを取り消す権限を持つ中央機関が存在しないことがデメリットになりえます。 この記事では、[ERC-20](/developers/docs/standards/tokens/erc-20/)トークンでユーザーがしてしまうよくあるミスや、そのミスを防ぐトークンの作成方法について説明します。また、中央機関に権限を与えることについても説明します (例えば、アカウントの凍結など) 。
-注意: [OpenZeppelin ERC-20トークンコントラクト](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20)を使いますが、このコントラクト自体について詳しくは説明しません。 ERC-20トークンコントラクトの詳細については、[こちら](/developers/tutorials/erc20-annotated-code)をご覧ください。
+この記事では[OpenZeppelin ERC-20トークンコントラクト](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20)を使用しますが、その詳細については説明しませんのでご注意ください。 この情報については、[こちら](/developers/tutorials/erc20-annotated-code)をご覧ください。
-全てのソースコードを表示したい場合は、次のようにします。
+完全なソースコードを確認したい場合は、以下を参照してください。
1. [Remix IDE](https://remix.ethereum.org/)を開きます。
-2. クローンGitHubアイコン () をクリックします。
+2. GitHubのクローンアイコン()をクリックします。
3. GitHubリポジトリ`https://github.com/qbzzt/20220815-erc20-safety-rails`をクローンします。
-4. 「**contracts > erc20-safety-rails.sol**」を開きます。
+4. **contracts > erc20-safety-rails.sol**を開きます。
## ERC-20コントラクトの作成 {#creating-an-erc-20-contract}
-安全策を講じるための機能を追加する前に、ERC-20コントラクトが必要になります。 この記事では、[OpenZeppelin Contracts Wizard](https://docs.openzeppelin.com/contracts/5.x/wizard)を使って加えます。 もう一つブラウザで開いて、次の手順に従ってください。
+安全策を講じるための機能を追加する前に、ERC-20コントラクトが必要になります。 この記事では、[OpenZeppelin Contracts Wizard](https://docs.openzeppelin.com/contracts/5.x/wizard)を使用します。 別のブラウザで開き、以下の手順に従ってください。
+
+1. **ERC20**を選択します。
-1. **ERC20**を選びます。
2. 次の設定値を入力します。
| パラメータ | 値 |
| -------------- | ---------------- |
| 名前 | SafetyRailsToken |
- | Symbol | SAFE |
+ | 記号 | SAFE |
| Premint | 1000 |
| 機能 | なし |
| Access Control | Ownable |
| Upgradability | なし |
-3. 上にスクロールして (Remixを使う場合は) **Open in Remix**をクリックしてください。別の環境を使う場合は、**ダウンロード**をクリックしてください。 ここでは、Remixを使用していることとします。他の環境を使用する場合は、適宜変更してください。
-4. これで完全なERC-20コントラクトがあります。 「`.deps` > `npm`」でインポートしたコードを展開して確認できます。
-5. コントラクトをコンパイル、デプロイ、そして操作してERC-20 コントラクトとして機能していることを確認します。 Remixの使用方法を学びたいならば、[このチュートリアルが役立ちます](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth)。
+3. 上にスクロールして、(Remixの場合は) **Open in Remix** を、別の環境を使用する場合は **Download** をクリックします。 ここでは、Remixを使用していることとします。他の環境を使用する場合は、適宜変更してください。
+
+4. これで完全に機能するERC-20コントラクトができました。 `.deps` > `npm` を展開すると、インポートされたコードを確認できます。
-## よくあるミス {#common-mistakes}
+5. コントラクトをコンパイル、デプロイ、そして操作して、ERC-20コントラクトとして機能していることを確認します。 Remixの使い方を学ぶ必要がある場合は、[このチュートリアル](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth)を使用してください。
-### ミスのタイプ {#the-mistakes}
+## よくある間違い {#common-mistakes}
-ユーザーは、間違ったアドレスへトークンを送信してしまうことがあります。 なぜ間違って送ってしまった理由を知ることはできませんが、よく発生するミスのタイプで頻繁に検出できる次のものがあります。
+### 間違い {#the-mistakes}
-1. トークンをコントラクト自身のアドレスに送信する。 例えば、[OptimismのOPトークン](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c)では、[12万](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042#tokentxns)を超えるOPトークンが2か月もしないうちに累積していることがわかります。 これは、人々の膨大な資産がただ単に失われていることを表しています。
+ユーザーは、間違ったアドレスへトークンを送信してしまうことがあります。 ユーザーが何を意図していたかを知ることはできませんが、頻繁に発生し、かつ検出しやすいエラーには2つのタイプがあります。
-2. トークンを[外部所有アカウント](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs)や[スマートコントラクト](/developers/docs/smart-contracts)に相当しない空アドレスへ送信する。 このミスがどのくらいの頻度で発生するかについての統計はありません。[1件のインシデントで2千万トークンを失っているものもあります](https://gov.optimism.io/t/message-to-optimism-community-from-Wintermute/2595)。
+1. トークンをコントラクト自身のアドレスに送信する。 例えば、[OptimismのOPトークン](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c)は、2か月足らずで[120,000](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000042)以上のOPトークンを蓄積してしまいました。 これは、おそらく人々が失ってしまったであろう、かなりの額の資産に相当します。
-### 送金を防止する {#preventing-transfers}
+2. トークンを空のアドレス、つまり[外部所有アカウント](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs)や[スマートコントラクト](/developers/docs/smart-contracts)ではないアドレスに送信してしまうこと。 これがどのくらいの頻度で発生するかについての統計はありませんが、[あるインシデントでは20,000,000トークンが失われる可能性がありました](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595)。
-OpenZeppelinのERC-20コントラクトには、[`_beforeTokenTransfer`というフック](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368)があり、トークンを送金する前に呼び出されます。 デフォルトでは、このフックは何も行いません。しかし、独自の機能をフックに掛けることで、問題がある場合に元に戻すなどのチェックが可能です。
+### 送金の防止 {#preventing-transfers}
+
+OpenZeppelinのERC-20コントラクトには、トークンが送金される前に呼び出される[`_beforeTokenTransfer`というフック](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368)が含まれています。 デフォルトでは、このフックは何も行いませんが、問題がある場合にトランザクションをリバートするチェックなど、独自の機能を実装するために利用できます。
このフックを使用するには、コンストラクタの後に次の関数を加えます。
@@ -67,42 +69,42 @@ OpenZeppelinのERC-20コントラクトには、[`_beforeTokenTransfer`という
}
```
-Solidityにあまり詳しくない人ならば、次の関数の箇所は馴染みがないかもしれません。
+Solidityにあまり詳しくない方には、この関数の一部の要素は目新しいかもしれません。
```solidity
internal virtual
```
-上記の`virtual`キーワードでは、`ERC20`から機能を継承し、関数をオーバーライドして、他のコントラクトも同様にこのコントラクトの機能を継承して、この関数をオーバーライドできるようにしています。
+`virtual`キーワードは、私たちが`ERC20`から機能を継承してこの関数をオーバーライドしたのと同じように、他のコントラクトが私たちのコントラクトから継承してこの関数をオーバーライドできることを意味します。
```solidity
override(ERC20)
```
-ERC20トークンの`_beforeTokenTransfer`の定義を[オーバーライド](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding)することを明示的に指定しなければなりません。 一般的なセキュリティの観点において、暗黙的な定義よりも明示的な定義の方がはるかに良いとされています。記述されていれば、それが実行されることを忘れないからです。 オーバーライドするスーパークラスの `_beforeTokenTransfer`を指定しなければならないのも同様の理由です。
+`_beforeTokenTransfer`のERC20トークン定義を[オーバーライド](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding)していることを明示的に指定する必要があります。 一般的に、セキュリティの観点からは、暗黙的な定義よりも明示的な定義の方がはるかに優れています。目の前にあれば、何かをしたことを忘れることはありません。 これが、どのスーパークラスの`_beforeTokenTransfer`をオーバーライドしているかを指定する必要がある理由でもあります。
```solidity
super._beforeTokenTransfer(from, to, amount);
```
-上記は、継承しているコントラクトから継承元のコントラクトの `_beforeTokenTransfer`関数を呼び出しています。 この場合は、`ERC20`のみであり、`Ownable`にはこのフックがありません。 現時点では、`ERC20._beforeTokenTransfer`は何も行いません。コントラクトはデプロイ後に変更できないため、再デプロイによって将来に機能が追加された場合に備えて呼び出しています。
+この行は、継承元のコントラクトのうち、`_beforeTokenTransfer`関数を持つものの関数を呼び出します。 この場合、それは`ERC20`のみです。`Ownable`にはこのフックはありません。 現在`ERC20._beforeTokenTransfer`は何も行いませんが、将来機能が追加された場合に備えて呼び出します (コントラクトはデプロイ後に変更できないため、その場合はコントラクトを再デプロイすることになります)。
### 要件のコーディング {#coding-the-requirements}
-次の要件を関数に対して加えたいと思います。
+この関数に以下の要件を追加します。
-- `to`アドレスをERC-20コントラクト自体のアドレスである`address(this)`と等しくできないようにすること。
-- `to`アドレスを空にすることができないこと。また、次のいずれかであること。
- - 外部所有アカウント (EOA) 。 アドレスがEOAであるかどうかを直接確認することはできませんが、アドレスのETH残高を確認することはできます。 EOAは、たとえ使用されなくなったとしても、ほとんどの場合、残高が残っています。これは、最後のweiまで使うのは困難だからです。
- - スマートコントラクト。 アドレスがスマートコントラクトであるかどうかのテストは少し大変です。 [`EXTCODESIZE`](https://www.evm.codes/#3b)という外部コードの長さをチェックするオペコードがありますが、Solidityでは直接使用することはできません。 これには、[Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html)というEVMアセンブリを使う必要があります。 Solidityから使用できる他の値 ([ `.code`および `.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)) もありますが、コストがそれよりも高くなります。
+- `to`アドレスは、ERC-20コントラクト自体のアドレスである`address(this)`であってはならない。
+- `to`アドレスは空であってはならず、以下のいずれかでなければならない。
+ - 外部所有アカウント (EOA)。 アドレスがEOAであるかどうかを直接確認することはできませんが、アドレスのETH残高は確認できます。 EOAは、使用されなくなった後でもほとんどの場合、残高が残っています。最後のweiまで使い切るのは困難だからです。
+ - スマートコントラクト。 アドレスがスマートコントラクトであるかどうかのテストは、少し難しくなります。 外部コード長をチェックする[`EXTCODESIZE`](https://www.evm.codes/#3b)というオペコードがありますが、Solidityで直接利用することはできません。 そのためには、EVMアセンブリである[Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html)を使用する必要があります。 Solidityから使用できる他の値 ([`.code` や `.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)) もありますが、それらはより多くのコストがかかります。
-新しいコードを1行ずつ見てみましょう。
+新しいコードを1行ずつ見ていきましょう。
```solidity
- require(to != address(this), "Can't send tokens to the contract address");
+ require(to != address(this), "コントラクトアドレスにトークンを送信することはできません");
```
-これが最初の要件です。`to`と`this(address)`が等しくないことを確認しています。
+これが最初の要件で、`to`と`address(this)`が同じでないことを確認します。
```solidity
bool isToContract;
@@ -111,53 +113,53 @@ ERC20トークンの`_beforeTokenTransfer`の定義を[オーバーライド](ht
}
```
-上記は、アドレスがコントラクトかどうかを確認する方法です。 Yulから出力を直接受け取ることはできません。そのため、代わりに結果を保持する変数を定義しています (この場合は `isToContract`) 。 Yulでは、すべてのオペコードが関数として動作します。 したがって、最初に[`EXTCODESIZE`](https://www.evm.codes/#3b)を呼び出してコントラクトサイズを取得し、次に[`GT`](https://www.evm.codes/#11)でゼロでないことを確認します (符号なし整数を扱っているため、当然、負の値にすることはできません) 。 その後、結果を`isToContract`に書き込んでいます。
+このようにして、アドレスがコントラクトであるかどうかを確認します。 Yulから直接出力を受け取ることはできないので、代わりに結果を保持する変数(この場合は`isToContract`)を定義します。 Yulは、すべてのオペコードが関数としてみなされる仕組みになっています。 そこで、まず[`EXTCODESIZE`](https://www.evm.codes/#3b)を呼び出してコントラクトのサイズを取得し、次に[`GT`](https://www.evm.codes/#11)を使ってそれがゼロでないことを確認します(符号なし整数を扱っているので、もちろん負になることはありません)。 そして、その結果を`isToContract`に書き込みます。
```solidity
- require(to.balance != 0 || isToContract, "Can't send tokens to an empty address");
+ require(to.balance != 0 || isToContract, "空のアドレスにトークンを送信することはできません");
```
-最後に、空アドレスのチェックをしています。
+そして最後に、空のアドレスに対する実際のチェックを行います。
## 管理者アクセス {#admin-access}
-間違いを取り消せる管理者がいると、便利なことがあります。 悪用される可能性を減らすには、管理者を[マルチシグ](https://blog.logrocket.com/security-choices-multi-signature-wallets/)にして、各アクションに対する複数人の同意を必要にします。 この記事では、次の2つの管理機能を持つものとします。
+間違いを取り消せる管理者がいると、便利なことがあります。 悪用の可能性を減らすため、この管理者を[マルチシグ](https://blog.logrocket.com/security-choices-multi-signature-wallets/)にして、あるアクションに対して複数の人が合意しなければならないようにすることができます。 この記事では、2つの管理機能について説明します。
-1. アカウントの凍結と解凍。 これは、アカウントが侵害された可能性がある場合などに役立ちます。
+1. アカウントの凍結と凍結解除。 これは、例えば、アカウントが侵害された可能性がある場合に便利です。
2. アセットのクリーンアップ。
- 時には、詐欺師が正当であると思わせるために、本物のトークンコントラクトに偽物のトークンを送信することがあります。 [こちら](https://optimistic.etherscan.io/token/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe?a=0x4200000000000000000000000000000000000042)に、その例があります。 正当なERC-20コントラクトは、[0x4200....0042](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042)です。 装っているスキャムは、[0x234....bbe](https://optimistic.etherscan.io/address/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe)です。
+ 詐欺師が正当性を装うために、本物のトークンコントラクトに偽のトークンを送ることがあります。 例えば、[こちら](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe?tab=holders)をご覧ください。 正規のERC-20コントラクトは [0x4200....0042](https://optimism.blockscout.com/token/0x4200000000000000000000000000000000000042) です。 それになりすました詐欺コントラクトは [0x234....bbe](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe) です。
- また、正当なERC-20トークンを誤ってコントラクト自体に送信してしまう可能性もあります。これが、アセットのクリーンアップ方法が必要になるもう1つの理由です。
+ また、ユーザーが正規のERC-20トークンを誤って私たちのコントラクトに送ってしまう可能性もあります。これも、それらを取り出す方法が必要となるもう一つの理由です。
-OpenZeppelinでは、管理者アクセスを可能にする次の2つのメカニズムを提供しています。
+OpenZeppelinは、管理者アクセスを可能にする2つのメカニズムを提供しています。
-- [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable)コントラクトでは、所有者は1人です。 `onlyOwner` [modifier](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm)のある関数は、その所有者のみしか呼び出せません。 所有者は、所有権を他の人に譲渡することも、完全に放棄することもできます。 通常、それ以外のアカウントの権限は変わりません。
-- [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control)コントラクトでは、[ロールベースのアクセス制御 (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control)機能があります。
+- [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable)コントラクトには、単一の所有者がいます。 `onlyOwner` [修飾子](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm)を持つ関数は、その所有者のみが呼び出すことができます。 所有者は、所有権を他の誰かに譲渡したり、完全に放棄したりすることができます。 他のすべてのアカウントの権限は、通常は同一です。
+- [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control)コントラクトには、[ロールベースのアクセス制御(RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control)があります。
-この記事では、簡潔にするために`Ownable`を使っています。
+この記事では、簡潔にするために`Ownable`を使用します。
-### コントラクトの凍結および解凍 {#freezing-and-thawing-contracts}
+### コントラクトの凍結と凍結解除 {#freezing-and-thawing-contracts}
-コントラクトの凍結と解凍において、次のいくつかの変更が必要になります。
+コントラクトの凍結と凍結解除には、いくつかの変更が必要です。
-- どのアドレスが凍結されているかを追跡するために、アドレスを[ブール値](https://en.wikipedia.org/wiki/Boolean_data_type)で[マッピング](https://www.tutorialspoint.com/solidity/solidity_mappings.htm)します。 すべての値の初期値はゼロです。これは、ブール値でfalseとして解釈されます。 デフォルトでは、アカウントを凍結しないため、このようにしています。
+- どのアドレスが凍結されているかを追跡するための、アドレスから[ブール値](https://en.wikipedia.org/wiki/Boolean_data_type)への[マッピング](https://www.tutorialspoint.com/solidity/solidity_mappings.htm)。 すべての値は最初はゼロで、ブール値の場合はfalseと解釈されます。 デフォルトではアカウントは凍結されていないので、これは望ましい動作です。
```solidity
mapping(address => bool) public frozenAccounts;
```
-- アカウントが凍結または解除されたときに、関係者に対して[イベント](https://www.tutorialspoint.com/solidity/solidity_events.htm)で通知します。 技術的観点では、アカウントの凍結および解除におけるアクションでは、イベントは必要ありません。しかし、オフチェーンのコードで、これらのイベントをリッスンして何が起こっているかわかると便利です。 関係者に対して何かが発生したときに、スマートコントラクトでイベントを発行することは、良いマナーであるとされています。
+- アカウントが凍結または凍結解除されたときに関係者に通知するための[イベント](https://www.tutorialspoint.com/solidity/solidity_events.htm)。 技術的には、これらのアクションにイベントは必須ではありませんが、オフチェーンのコードがこれらのイベントをリッスンして何が起こっているかを知るのに役立ちます。 他の誰かに関連する可能性のあることが起こったときに、スマートコントラクトがイベントを発行することは、良いマナーとされています。
- どのタイミングでアカウントの凍結または解除されたかを検索できるように、イベントにインデックスを付けています。
+ イベントにはインデックスが付けられるため、あるアカウントが凍結または凍結解除されたすべての回を検索できるようになります。
```solidity
- // When accounts are frozen or unfrozen
+ // アカウントが凍結または凍結解除されたとき
event AccountFrozen(address indexed _addr);
event AccountThawed(address indexed _addr);
```
-- アカウントを凍結および解凍するための関数。 これらの2つの関数は、ほぼ同一であるため凍結する関数についてのみ説明します。
+- アカウントを凍結および凍結解除するための関数。 これらの2つの関数はほぼ同一なので、ここでは凍結関数についてのみ説明します。
```solidity
function freezeAccount(address addr)
@@ -165,27 +167,27 @@ OpenZeppelinでは、管理者アクセスを可能にする次の2つのメカ
onlyOwner
```
- [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm)が付けられた関数では、他のスマートコントラクトまたはトランザクションから直接呼び出すことができます。
+ [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm)とマークされた関数は、他のスマートコントラクトから、またはトランザクションによって直接呼び出すことができます。
```solidity
{
- require(!frozenAccounts[addr], "Account already frozen");
+ require(!frozenAccounts[addr], "アカウントはすでに凍結されています");
frozenAccounts[addr] = true;
emit AccountFrozen(addr);
} // freezeAccount
```
- アカウントがすでに凍結されている場合は、処理を取消します。 それ以外の場合は、凍結してイベントを`emit`します。
+ アカウントがすでに凍結されている場合は、リバートします。 そうでなければ、アカウントを凍結し、イベントを`emit`します。
-- `_beforeTokenTransfer`を凍結されたアカウントから資金が移動されないよう変更します。 凍結されたアカウントへの送金は、引き続き可能であることに注意してください。
+- 凍結されたアカウントから資金が移動されないように`_beforeTokenTransfer`を変更します。 凍結されたアカウントへの送金は、引き続き可能であることに注意してください。
```solidity
- require(!frozenAccounts[from], "The account is frozen");
+ require(!frozenAccounts[from], "アカウントは凍結されています");
```
### アセットのクリーンアップ {#asset-cleanup}
-コントラクト自体が保持しているERC-20トークンを解放するには、それに属しているトークンコントラクトの関数である[`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer)または[`approve`](https://eips.ethereum.org/EIPS/eip-20#approve)を呼び出す必要があります。 この場合、Allowanceで無駄にガスを消費するのはもったいないため、直接送金 (transfer) の方がよいでしょう。
+このコントラクトが保有するERC-20トークンを解放するには、それらが属するトークンコントラクトの[`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer)または[`approve`](https://eips.ethereum.org/EIPS/eip-20#approve)のいずれかの関数を呼び出す必要があります。 この場合、Allowanceでガスを無駄にする意味はないので、直接送金した方が良いでしょう。
```solidity
function cleanupERC20(
@@ -198,7 +200,7 @@ OpenZeppelinでは、管理者アクセスを可能にする次の2つのメカ
IERC20 token = IERC20(erc20);
```
-これは、アドレスがトークンを受け取った場合に、コントラクトにオブジェクトを作成するための構文です。 ERC20トークンがソースコード (4行目を参照) の一部として定義されており、OpenZeppelinのERC-20コントラクトのインターフェースである[IERC20の定義](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)がそのファイルに含まれているためこれが可能です。
+これは、アドレスを受け取ったときにコントラクトのオブジェクトを作成するための構文です。 これが可能なのは、ソースコードの一部としてERC20トークンの定義があり(4行目を参照)、そのファイルにはOpenZeppelinのERC-20コントラクトのインターフェースである[IERC20の定義](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)が含まれているためです。
```solidity
uint balance = token.balanceOf(address(this));
@@ -206,8 +208,10 @@ OpenZeppelinでは、管理者アクセスを可能にする次の2つのメカ
}
```
-上記は、すべてのトークンをクリーンアップする関数です。 このプロセスを自動化することで、ユーザーから手動で残高を取得するよりも効率化できます。
+これはクリーンアップ関数なので、トークンを残さないようにします。 ユーザーから手動で残高を取得する代わりに、プロセスを自動化した方が良いでしょう。
+
+## 結論 {#conclusion}
-## まとめ {#conclusion}
+これは完璧な解決策ではありません。「ユーザーの間違い」によって発生する問題に完璧な解決策はないのです。 しかし、この種のチェックを使用することで、少なくともいくつかの間違いを防ぐことができます。 アカウントを凍結する機能は危険を伴いますが、ハッカーから盗まれた資金を奪うことで、特定のハッキングによる被害を限定するために使用できます。
-「ユーザーの間違い」によって発生する問題に完璧な解決策はないため、これらは完全な解決策ではありません。 しかしながら、この記事のようなチェックをすることで、少なくともいくつかのミスを防止できます。 アカウントの凍結機能は危険を伴うものの、ハッカーが資金を盗むことを防ぎ、ハッキングによる被害を特定の範囲内におさめるために使うことができます。
+[私の他の作品はこちらでご覧いただけます](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ja/developers/tutorials/ethereum-for-web2-auth/index.md b/public/content/translations/ja/developers/tutorials/ethereum-for-web2-auth/index.md
new file mode 100644
index 00000000000..d5bb7ed4da2
--- /dev/null
+++ b/public/content/translations/ja/developers/tutorials/ethereum-for-web2-auth/index.md
@@ -0,0 +1,886 @@
+---
+title: "Web2認証にイーサリアムを使用する"
+description: "このチュートリアルを読むことで、デベロッパーはイーサリアムログイン (Web3) をSAMLログインと統合できるようになります。SAMLは、Web2でシングルサインオンやその他の関連サービスを提供するために使用される標準です。 これにより、Web2リソースへのアクセスをイーサリアム署名を通じて認証できるようになり、ユーザー属性はアテステーションから取得されます。"
+author: Ori Pomerantz
+tags: [ "web2", "認証", "eas" ]
+skill: beginner
+lang: ja
+published: 2025-04-30
+---
+
+## はじめに
+
+[SAML](https://www.onelogin.com/learn/saml)は、Web2で[IDプロバイダー (IdP)](https://en.wikipedia.org/wiki/Identity_provider#SAML_identity_provider) が[サービスプロバイダー (SP)](https://en.wikipedia.org/wiki/Service_provider_\(SAML\))にユーザー情報を提供するために使用される標準です。
+
+このチュートリアルでは、イーサリアム署名をSAMLと統合し、まだイーサリアムをネイティブにサポートしていないWeb2サービスに対して、ユーザーがイーサリアムウォレットを使用して認証できるようにする方法を学びます。
+
+このチュートリアルは、2つの異なる読者を対象に書かれていることに注意してください。
+
+- イーサリアムを理解していて、SAMLを学ぶ必要があるイーサリアム関係者
+- SAMLとWeb2認証を理解していて、イーサリアムを学ぶ必要があるWeb2関係者
+
+そのため、すでにご存知の入門的な内容が多く含まれています。 適宜読み飛ばしてください。
+
+### イーサリアム関係者向けのSAML
+
+SAMLは中央集権型のプロトコルです。 サービスプロバイダー (SP) は、IDプロバイダー (IdP) との間、またはそのIdPの証明書に署名した[証明書認証局](https://www.ssl.com/article/what-is-a-certificate-authority-ca/)との間に、既存の信頼関係がある場合にのみ、IdPからのアサーション (「これは私のユーザーJohnで、A、B、Cを行う権限を持つべきである」など) を受け入れます。
+
+たとえば、SPは企業に旅行サービスを提供する旅行代理店、IdPは企業の社内ウェブサイトであるとします。 従業員が出張の予約をする際、旅行代理店は、実際に旅行の予約を許可する前に、従業員を会社の認証に送ります。
+
+
+
+これが、ブラウザ、SP、IdPの3つのエンティティがアクセスを交渉する方法です。 SPは、ブラウザを使用しているユーザーについて事前に何も知る必要はなく、IdPを信頼するだけで済みます。
+
+### SAML関係者向けのイーサリアム
+
+イーサリアムは分散型システムです。
+
+
+
+ユーザーは秘密鍵を持っています (通常はブラウザ拡張機能に保存されています)。 秘密鍵から公開鍵を導出し、そこから20バイトのアドレスを導出できます。 ユーザーがシステムにログインする必要がある場合、ノンス (1回限りの値) を持つメッセージに署名するよう要求されます。 サーバーは、署名がそのアドレスによって作成されたことを検証できます。
+
+
+
+署名はイーサリアムアドレスを検証するだけです。 他のユーザー属性を取得するには、通常[アテステーション](https://attest.org/)を使用します。 アテステーションには通常、以下のフィールドがあります。
+
+- **証明者**、アテステーションを行ったアドレス
+- **受取人**、アテステーションが適用されるアドレス
+- **データ**、名前や権限など、証明されるデータ
+- **スキーマ**、データの解釈に使用されるスキーマのID。
+
+イーサリアムの分散型の性質により、どのユーザーでもアテステーションを作成できます。 どのアテステーションが信頼できるかを判断するには、証明者のIDが重要です。
+
+## セットアップ
+
+最初のステップは、SAML SPとSAML IdPが互いに通信できるようにすることです。
+
+1. ソフトウェアをダウンロードします。 この記事のサンプルソフトウェアは、[github](https://github.com/qbzzt/250420-saml-ethereum)にあります。 異なるステージは異なるブランチに保存されています。このステージでは `saml-only` を使用します。
+
+ ```sh
+ git clone https://github.com/qbzzt/250420-saml-ethereum -b saml-only
+ cd 250420-saml-ethereum
+ pnpm install
+ ```
+
+2. 自己署名証明書でキーを作成します。 これは、キーがそれ自体の証明書認証局であることを意味し、サービスプロバイダーに手動でインポートする必要があります。 詳細については、[OpenSSLのドキュメント](https://docs.openssl.org/master/man1/openssl-req/)を参照してください。
+
+ ```sh
+ mkdir keys
+ cd keys
+ openssl req -new -x509 -days 365 -nodes -sha256 -out saml-sp.crt -keyout saml-sp.pem -subj /CN=sp/
+ openssl req -new -x509 -days 365 -nodes -sha256 -out saml-idp.crt -keyout saml-idp.pem -subj /CN=idp/
+ cd ..
+ ```
+
+3. サーバー (SPとIdPの両方) を起動します。
+
+ ```sh
+ pnpm start
+ ```
+
+4. URL [http://localhost:3000/](http://localhost:3000/)でSPにアクセスし、ボタンをクリックしてIdP (ポート3001) にリダイレクトします。
+
+5. IdPにメールアドレスを入力し、**サービスプロバイダーにログイン**をクリックします。 サービスプロバイダー (ポート3000) にリダイレクトされ、メールアドレスで認識されていることを確認します。
+
+### 詳細な説明
+
+ステップバイステップで起こることは次のとおりです。
+
+
+
+#### src/config.mts
+
+このファイルには、IDプロバイダーとサービスプロバイダー両方の設定が含まれています。 通常、これら2つは異なるエンティティですが、ここでは簡潔にするためにコードを共有します。
+
+```typescript
+const fs = await import("fs")
+
+const protocol="http"
+```
+
+今のところテストだけなので、HTTPを使用して問題ありません。
+
+```typescript
+export const spCert = fs.readFileSync("keys/saml-sp.crt").toString()
+export const idpCert = fs.readFileSync("keys/saml-idp.crt").toString()
+```
+
+通常は両方のコンポーネントで利用可能な公開鍵 (直接信頼されるか、信頼された証明書認証局によって署名される) を読み取ります。
+
+```typescript
+export const spPort = 3000
+export const spHostname = "localhost"
+export const spDir = "sp"
+
+export const idpPort = 3001
+export const idpHostname = "localhost"
+export const idpDir = "idp"
+
+export const spUrl = `${protocol}://${spHostname}:${spPort}/${spDir}`
+export const idpUrl = `${protocol}://${idpHostname}:${idpPort}/${idpDir}`
+```
+
+両コンポーネントのURLです。
+
+```typescript
+export const spPublicData = {
+```
+
+サービスプロバイダーの公開データです。
+
+```typescript
+ entityID: `${spUrl}/metadata`,
+```
+
+慣例的に、SAMLでは`entityID`はエンティティのメタデータが利用可能なURLです。 このメタデータはここの公開データに対応しますが、XML形式である点が異なります。
+
+```typescript
+ wantAssertionsSigned: true,
+ authnRequestsSigned: false,
+ signingCert: spCert,
+ allowCreate: true,
+ assertionConsumerService: [{
+ Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
+ Location: `${spUrl}/assertion`,
+ }]
+ }
+```
+
+私たちの目的にとって最も重要な定義は `assertionConsumerServer` です。 これは、サービスプロバイダーに何かをアサートする (例えば、「この情報を送信するユーザーは somebody@example.com です」) ためには、URL `http://localhost:3000/sp/assertion` に [HTTP POST](https://www.w3schools.com/tags/ref_httpmethods.asp) を使用する必要があることを意味します。
+
+```typescript
+export const idpPublicData = {
+ entityID: `${idpUrl}/metadata`,
+ signingCert: idpCert,
+ wantAuthnRequestsSigned: false,
+ singleSignOnService: [{
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
+ Location: `${idpUrl}/login`
+ }],
+ singleLogoutService: [{
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
+ Location: `${idpUrl}/logout`
+ }],
+ }
+```
+
+IDプロバイダーの公開データも同様です。 これは、ユーザーをログインさせるには `http://localhost:3001/idp/login` にPOSTし、ユーザーをログアウトさせるには `http://localhost:3001/idp/logout` にPOSTすることを指定しています。
+
+#### src/sp.mts
+
+これはサービスプロバイダーを実装するコードです。
+
+```typescript
+import * as config from "./config.mts"
+const fs = await import("fs")
+const saml = await import("samlify")
+```
+
+SAMLを実装するために [`samlify`](https://www.npmjs.com/package/samlify) ライブラリを使用します。
+
+```typescript
+import * as validator from "@authenio/samlify-node-xmllint"
+saml.setSchemaValidator(validator)
+```
+
+`samlify` ライブラリは、XMLが正しいこと、期待される公開鍵で署名されていることなどを検証するパッケージを必要とします。 この目的のために [`@authenio/samlify-node-xmllint`](https://www.npmjs.com/package/@authenio/samlify-node-xmllint) を使用します。
+
+```typescript
+const express = (await import("express")).default
+const spRouter = express.Router()
+const app = express()
+```
+
+[`express`](https://expressjs.com/)の [`Router`](https://expressjs.com/en/5x/api.html#router)は、ウェブサイト内にマウントできる「ミニウェブサイト」です。 この場合、すべてのサービスプロバイダーの定義をグループ化するために使用します。
+
+```typescript
+const spPrivateKey = fs.readFileSync("keys/saml-sp.pem").toString()
+
+const sp = saml.ServiceProvider({
+ privateKey: spPrivateKey,
+ ...config.spPublicData
+})
+```
+
+サービスプロバイダー自身の表現は、すべての公開データと、情報に署名するために使用する秘密鍵です。
+
+```typescript
+const idp = saml.IdentityProvider(config.idpPublicData);
+```
+
+公開データには、サービスプロバイダーがIDプロバイダーについて知る必要があるすべてのものが含まれています。
+
+```typescript
+spRouter.get(`/metadata`,
+ (req, res) => res.header("Content-Type", "text/xml").send(sp.getMetadata())
+)
+```
+
+他のSAMLコンポーネントとの相互運用性を確保するため、サービスプロバイダーとIDプロバイダーは、公開データ (メタデータと呼ばれる) をXML形式で `/metadata` にて利用可能にする必要があります。
+
+```typescript
+spRouter.post(`/assertion`,
+```
+
+これは、ブラウザが自身を識別するためにアクセスするページです。 アサーションにはユーザー識別子 (ここではメールアドレスを使用) が含まれ、追加の属性を含めることもできます。 これは、上記のシーケンス図のステップ7のハンドラです。
+
+```typescript
+ async (req, res) => {
+ // console.log(`SAML response:\n${Buffer.from(req.body.SAMLResponse, 'base64').toString('utf-8')}`)
+```
+
+コメントアウトされたコマンドを使用して、アサーションで提供されるXMLデータを確認できます。 これは[base64でエンコード](https://en.wikipedia.org/wiki/Base64)されています。
+
+```typescript
+ try {
+ const loginResponse = await sp.parseLoginResponse(idp, 'post', req);
+```
+
+IDサーバーからのログインリクエストを解析します。
+
+```typescript
+ res.send(`
+
+
+ Hello ${loginResponse.extract.nameID}
+
+
+ `)
+ res.send();
+```
+
+ユーザーにログインが成功したことを示すために、HTMLレスポンスを送信します。
+
+```typescript
+ } catch (err) {
+ console.error('Error processing SAML response:', err);
+ res.status(400).send('SAML authentication failed');
+ }
+ }
+)
+```
+
+失敗した場合は、ユーザーに通知します。
+
+```typescript
+spRouter.get('/login',
+```
+
+ブラウザがこのページを取得しようとするときに、ログインリクエストを作成します。 これは、上記のシーケンス図のステップ1のハンドラです。
+
+```typescript
+ async (req, res) => {
+ const loginRequest = await sp.createLoginRequest(idp, "post")
+```
+
+ログインリクエストをPOSTするための情報を取得します。
+
+```typescript
+ res.send(`
+
+
+
+```
+
+このページは、フォーム (下記参照) を自動的に送信します。 これにより、ユーザーはリダイレクトされるために何もする必要がありません。 これは、上記のシーケンス図のステップ2です。
+
+```typescript
+
+
+
+ `)
+ }
+)
+
+app.use(express.urlencoded({extended: true}))
+```
+
+[このミドルウェア](https://expressjs.com/en/5x/api.html#express.urlencoded) は [HTTPリクエスト](https://www.tutorialspoint.com/http/http_requests.htm)のボディを読み取ります。 ほとんどのリクエストはそれを必要としないため、Expressはデフォルトでそれを無視します。 POSTはボディを使用するため、これが必要です。
+
+```typescript
+app.use(`/${config.spDir}`, spRouter)
+```
+
+サービスプロバイダーディレクトリ (`/sp`) にルーターをマウントします。
+
+```typescript
+app.get("/", (req, res) => {
+ res.send(`
+
+
+
+
+
+ `)
+})
+```
+
+ブラウザがルートディレクトリを取得しようとした場合は、ログインページへのリンクを提供します。
+
+```typescript
+app.listen(config.spPort, () => {
+ console.log(`service provider is running on http://${config.spHostname}:${config.spPort}`)
+})
+```
+
+このExpressアプリケーションで `spPort` をリッスンします。
+
+#### src/idp.mts
+
+これはIDプロバイダーです。 これはサービスプロバイダーと非常によく似ており、以下の説明は異なる部分についてです。
+
+```typescript
+const xmlParser = new (await import("fast-xml-parser")).XMLParser(
+ {
+ ignoreAttributes: false, // Preserve attributes
+ attributeNamePrefix: "@_", // Prefix for attributes
+ }
+)
+```
+
+サービスプロバイダーから受け取ったXMLリクエストを読み取り、理解する必要があります。
+
+```typescript
+const getLoginPage = requestId => `
+```
+
+この関数は、上記のシーケンス図のステップ4で返される、自動送信フォーム付きのページを作成します。
+
+```typescript
+
+
+ ログインページ
+
+
+ ログインページ
+
+
+
+
+const idpRouter = express.Router()
+
+idpRouter.post("/loginSubmitted", async (req, res) => {
+ const loginResponse = await idp.createLoginResponse(
+```
+
+これは、上記のシーケンス図のステップ5のハンドラです。 [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125)はログインレスポンスを作成します。
+
+```typescript
+ sp,
+ {
+ authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport',
+ audience: sp.entityID,
+```
+
+オーディエンスはサービスプロバイダーです。
+
+```typescript
+ extract: {
+ request: {
+ id: req.body.requestId
+ }
+ },
+```
+
+リクエストから抽出された情報です。 リクエストで重要なパラメータはrequestIdで、これによりサービスプロバイダーはリクエストとそのレスポンスを一致させることができます。
+
+```typescript
+ signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // Ensure signing
+```
+
+レスポンスに署名するためのデータを持つために `signingKey` が必要です。 サービスプロバイダーは署名されていないリクエストを信頼しません。
+
+```typescript
+ },
+ "post",
+ {
+ email: req.body.email
+```
+
+これは、サービスプロバイダーに送り返すユーザー情報を持つフィールドです。
+
+```typescript
+ }
+ );
+
+ res.send(`
+
+
+
+
+
+
+
+ `)
+})
+```
+
+ここでも、自動送信フォームを使用します。 これは、上記のシーケンス図のステップ6です。
+
+```typescript
+
+// ログインリクエスト用のIdPエンドポイント
+idpRouter.post(`/login`,
+```
+
+これはサービスプロバイダーからログインリクエストを受け取るエンドポイントです。 これは、上記のシーケンス図のステップ3のハンドラです。
+
+```typescript
+ async (req, res) => {
+ try {
+ // parseLoginRequestが動作しなかったための回避策
+ // const loginRequest = await idp.parseLoginRequest(sp, 'post', req)
+ const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8'))
+ res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"]))
+```
+
+[`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144)を使用して認証リクエストのIDを読み取ることができるはずです。 しかし、動作させることができず、それに多くの時間を費やす価値もなかったので、[汎用XMLパーサー](https://www.npmjs.com/package/fast-xml-parser)を使用します。 必要な情報は、XMLのトップレベルにある `` タグ内の `ID` 属性です。
+
+## イーサリアム署名の使用
+
+ユーザーIDをサービスプロバイダーに送信できるようになったので、次のステップは信頼できる方法でユーザーIDを取得することです。 Viemを使用すると、ウォレットにユーザーアドレスを尋ねるだけで済みますが、これはブラウザに情報を要求することを意味します。 私たちはブラウザを制御していないため、そこから得られる応答を自動的に信頼することはできません。
+
+代わりに、IdPはブラウザに署名するための文字列を送信します。 ブラウザのウォレットがこの文字列に署名すれば、それが本当にそのアドレスであること (つまり、そのアドレスに対応する秘密鍵を知っていること) を意味します。
+
+これを実際に確認するには、既存のIdPとSPを停止し、次のコマンドを実行します。
+
+```sh
+git checkout eth-signatures
+pnpm install
+pnpm start
+```
+
+次に、[SP](http://localhost:3000)にアクセスし、指示に従ってください。
+
+この時点では、イーサリアムアドレスからメールアドレスを取得する方法がわからないため、代わりに `<イーサリアムアドレス>@bad.email.address` をSPに報告します。
+
+### 詳細な説明
+
+変更点は、前の図のステップ4-5にあります。
+
+
+
+変更したファイルは `idp.mts` だけです。 以下が変更された部分です。
+
+```typescript
+import { v4 as uuidv4 } from 'uuid'
+import { verifyMessage } from 'viem'
+```
+
+これら2つの追加ライブラリが必要です。 [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)値を作成するために [`uuid`](https://www.npmjs.com/package/uuid) を使用します。 値自体は問題ではなく、一度しか使用されないという事実が重要です。
+
+[`viem`](https://viem.sh/) ライブラリを使用すると、イーサリアムの定義を使用できます。 ここでは、署名が実際に有効であることを検証するためにこれが必要です。
+
+```typescript
+const loginPrompt = "サービスプロバイダーにアクセスするには、このノンスに署名してください: "
+```
+
+ウォレットは、ユーザーにメッセージに署名する許可を求めます。 ノンスだけのメッセージはユーザーを混乱させる可能性があるため、このプロンプトを含めます。
+
+```typescript
+// ここにrequestIDを保持する
+let nonces = {}
+```
+
+応答するためには、リクエスト情報が必要です。 リクエストと一緒に送信し (ステップ4)、それを受け取る (ステップ5) こともできます。 しかし、潜在的に敵対的なユーザーの制御下にあるブラウザから得られる情報は信頼できません。 したがって、ノンスをキーとしてここに保存する方が良いでしょう。
+
+簡潔さのために、ここでは変数としてこれを行っていることに注意してください。 ただし、これにはいくつかの欠点があります。
+
+- サービス拒否攻撃に対して脆弱です。 悪意のあるユーザーが複数回ログオンを試み、メモリを使い果たす可能性があります。
+- IdPプロセスを再起動する必要がある場合、既存の値を失います。
+- 各プロセスが独自の変数を持つため、複数のプロセス間で負荷分散を行うことはできません。
+
+本番システムでは、データベースを使用し、何らかの有効期限メカニズムを実装します。
+
+```typescript
+const getSignaturePage = requestId => {
+ const nonce = uuidv4()
+ nonces[nonce] = requestId
+```
+
+ノンスを作成し、後で使用するために `requestId` を保存します。
+
+```typescript
+ return `
+
+
+
+
+
+ 署名してください
+
+
+
+
+
+`
+}
+```
+
+残りは標準のHTMLです。
+
+```typescript
+idpRouter.get("/signature/:nonce/:account/:signature", async (req, res) => {
+```
+
+これはシーケンス図のステップ5のハンドラです。
+
+```typescript
+ const requestId = nonces[req.params.nonce]
+ if (requestId === undefined) {
+ res.send("Bad nonce")
+ return ;
+ }
+
+ nonces[req.params.nonce] = undefined
+```
+
+リクエストIDを取得し、再利用されないように `nonces` からノンスを削除します。
+
+```typescript
+ try {
+```
+
+署名が無効になる方法が非常に多いため、これを `try ...` でラップします。 catch`ブロックで、スローされたエラーをキャッチします。
+
+```typescript
+ const validSignature = await verifyMessage({
+ address: req.params.account,
+ message: `${loginPrompt}${req.params.nonce}`,
+ signature: req.params.signature
+ })
+```
+
+シーケンス図のステップ5.5を実装するには、[`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage#verifymessage) を使用します。
+
+```typescript
+ if (!validSignature)
+ throw("Bad signature")
+ } catch (err) {
+ res.send("Error:" + err)
+ return ;
+ }
+```
+
+ハンドラの残りの部分は、1つの小さな変更を除いて、以前に `/loginSubmitted` ハンドラで行ったことと同等です。
+
+```typescript
+ const loginResponse = await idp.createLoginResponse(
+ .
+ .
+ .
+ {
+ email: req.params.account + "@bad.email.address"
+ }
+ );
+```
+
+実際のメールアドレスは持っていないので (次のセクションで取得します)、今のところはイーサリアムアドレスを返し、それがメールアドレスではないことを明確にマークします。
+
+```typescript
+// ログインリクエスト用のIdPエンドポイント
+idpRouter.post(`/login`,
+ async (req, res) => {
+ try {
+ // parseLoginRequestが動作しなかったための回避策
+ // const loginRequest = await idp.parseLoginRequest(sp, 'post', req)
+ const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8'))
+ res.send(getSignaturePage(samlRequest["samlp:AuthnRequest"]["@_ID"]))
+ } catch (err) {
+ console.error('SAMLレスポンスの処理中にエラーが発生しました:', err);
+ res.status(400).send('SAML認証に失敗しました');
+ }
+ }
+)
+```
+
+ステップ3のハンドラでは、`getLoginPage` の代わりに `getSignaturePage` を使用します。
+
+## メールアドレスの取得
+
+次のステップは、サービスプロバイダーによって要求された識別子であるメールアドレスを取得することです。 そのためには、[Ethereum Attestation Service (EAS)](https://attest.org/) を使用します。
+
+アテステーションを取得する最も簡単な方法は、[GraphQL API](https://docs.attest.org/docs/developer-tools/api)を使用することです。 このクエリを使用します。
+
+```
+query GetAttestationsByRecipient {
+ attestations(
+ where: {
+ recipient: { equals: "${getAddress(ethAddr)}" }
+ schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" }
+ }
+ take: 1
+ ) {
+ data
+ id
+ attester
+ }
+}
+```
+
+この[`schemaId`](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977)には、メールアドレスのみが含まれます。 このクエリは、このスキーマのアテステーションを要求します。 アテステーションのサブジェクトは `recipient` と呼ばれます。 これは常にイーサリアムアドレスです。
+
+警告:ここでアテステーションを取得する方法には、2つのセキュリティ上の問題があります。
+
+- 中央集権的なコンポーネントであるAPIエンドポイント `https://optimism.easscan.org/graphql` にアクセスしています。 `id`属性を取得し、オンチェーンでルックアップしてアテステーションが本物であることを確認できますが、APIエンドポイントは、アテステーションについて通知しないことで、依然としてアテステーションを検閲できます。
+
+ この問題は解決不可能ではありません。独自のGraphQLエンドポイントを実行し、チェーンログからアテステーションを取得できますが、私たちの目的には過剰です。
+
+- 私たちは証明者のIDを見ていません。 誰でも偽の情報を私たちに与えることができます。 実際の環境では、信頼できる証明者のセットを持ち、彼らのアテステーションのみを参照します。
+
+これを実際に確認するには、既存のIdPとSPを停止し、次のコマンドを実行します。
+
+```sh
+git checkout email-address
+pnpm install
+pnpm start
+```
+
+次に、メールアドレスを入力します。 これを行うには2つの方法があります。
+
+- 秘密鍵を使用してウォレットをインポートし、テスト用の秘密鍵 `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` を使用します。
+
+- 自分のメールアドレスにアテステーションを追加します。
+
+ 1. アテステーションエクスプローラーの[スキーマ](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977)に移動します。
+
+ 2. **スキーマで証明**をクリックします。
+
+ 3. 受信者としてイーサリアムアドレスを入力し、メールアドレスとしてメールアドレスを入力し、**オンチェーン**を選択します。 次に、**アテステーションを作成**をクリックします。
+
+ 4. ウォレットでトランザクションを承認します。 ガスを支払うために、[Optimism Blockchain](https://app.optimism.io/bridge/deposit)にETHが必要です。
+
+どちらの場合も、これを行った後、[http://localhost:3000](http://localhost:3000) にアクセスして指示に従ってください。 テスト用の秘密鍵をインポートした場合、受け取るメールは `test_addr_0@example.com` です。 独自のアドレスを使用した場合は、証明した内容になります。
+
+### 詳細な説明
+
+
+
+新しいステップはGraphQL通信、ステップ5.6と5.7です。
+
+再度、`idp.mts`の変更部分を示します。
+
+```typescript
+import { GraphQLClient } from 'graphql-request'
+import { SchemaEncoder } from '@ethereum-attestation-service/eas-sdk'
+```
+
+必要なライブラリをインポートします。
+
+```typescript
+const graphqlEndpointUrl = "https://optimism.easscan.org/graphql"
+```
+
+[各ブロックチェーンに個別のエンドポイント](https://docs.attest.org/docs/developer-tools/api)があります。
+
+```typescript
+const graphqlClient = new GraphQLClient(graphqlEndpointUrl, { fetch })
+```
+
+エンドポイントのクエリに使用できる新しい`GraphQLClient`クライアントを作成します。
+
+```typescript
+const graphqlSchema = 'string emailAddress'
+const graphqlEncoder = new SchemaEncoder(graphqlSchema)
+```
+
+GraphQLは、バイトを持つ不透明なデータオブジェクトのみを提供します。 それを理解するためにはスキーマが必要です。
+
+```typescript
+const ethereumAddressToEmail = async ethAddr => {
+```
+
+イーサリアムアドレスからメールアドレスを取得する関数です。
+
+```typescript
+ const query = `
+ query GetAttestationsByRecipient {
+```
+
+これはGraphQLクエリです。
+
+```typescript
+ アテステーション(
+```
+
+アテステーションを探しています。
+
+```typescript
+ where: {
+ recipient: { equals: "${getAddress(ethAddr)}" }
+ schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" }
+ }
+```
+
+必要なアテステーションは、私たちのスキーマにあり、受信者が`getAddress(ethAddr)`であるものです。 [`getAddress`](https://viem.sh/docs/utilities/getAddress#getaddress)関数は、アドレスが正しい[チェックサム](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md)を持つことを保証します。 GraphQLは大文字と小文字を区別するため、これは必要です。 「0xBAD060A7」、「0xBad060A7」、および「0xbad060a7」は異なる値です。
+
+```typescript
+ take: 1
+```
+
+見つかったアテステーションの数に関係なく、最初のものだけが必要です。
+
+```typescript
+ ) {
+ data
+ id
+ attester
+ }
+ }`
+```
+
+受け取りたいフィールドです。
+
+- `attester`: アテステーションを送信したアドレス。 通常、これはアテステーションを信頼するかどうかを決定するために使用されます。
+- `id`: アテステーションID。 この値を使用して、[アテステーションをオンチェーンで読み取り](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000021?tab=read_proxy&source_address=0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088#0xa3112a64)、GraphQLクエリからの情報が正しいことを確認できます。
+- `data`: スキーマデータ (この場合はメールアドレス)。
+
+```typescript
+ const queryResult = await graphqlClient.request(query)
+
+ if (queryResult.attestations.length == 0)
+ return "no_address@available.is"
+```
+
+アテステーションがない場合は、明らかに不正であるが、サービスプロバイダーには有効に見える値を返します。
+
+```typescript
+ const attestationDataFields = graphqlEncoder.decodeData(queryResult.attestations[0].data)
+ return attestationDataFields[0].value.value
+}
+```
+
+値がある場合は、`decodeData`を使用してデータをデコードします。 提供されるメタデータは不要で、値自体のみが必要です。
+
+```typescript
+ const loginResponse = await idp.createLoginResponse(
+ sp,
+ {
+ .
+ .
+ .
+ },
+ "post",
+ {
+ email: await ethereumAddressToEmail(req.params.account)
+ }
+ );
+```
+
+新しい関数を使用してメールアドレスを取得します。
+
+## 分散化については?
+
+この構成では、イーサリアムとメールアドレスのマッピングに信頼できる証明者に依存している限り、ユーザーは他人になりすますことはできません。 しかし、私たちのIDプロバイダーは依然として中央集権的なコンポーネントです。 IDプロバイダーの秘密鍵を持っている人は誰でも、サービスプロバイダーに偽の情報を送信できます。
+
+[マルチパーティ計算 (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) を使用した解決策があるかもしれません。 将来のチュートリアルでそれについて書きたいと思っています。
+
+## まとめ
+
+イーサリアム署名のようなログオン標準の採用は、鶏が先か卵が先かの問題に直面します。 サービスプロバイダーは、可能な限り広い市場にアピールしたいと考えています。 ユーザーは、ログオン標準のサポートを心配することなく、サービスにアクセスできることを望んでいます。
+イーサリアムIdPなどのアダプターを作成することは、このハードルを乗り越えるのに役立ちます。
+
+[私の他の作品はこちらでご覧いただけます](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ja/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/ja/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md
index 119b5ca92b0..7e34b96fcf2 100644
--- a/public/content/translations/ja/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md
+++ b/public/content/translations/ja/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md
@@ -1,13 +1,8 @@
---
-title: イーサリアム開発入門
+title: "イーサリアム開発入門"
description: "この文書は、はじめてイーサリアム開発を行う初心者用のガイドです。 APIエンドポイントの立ち上げ、コマンドライン・リクエストの作成、さらにweb3スクリプトの作成までをステップごとに説明します。 ブロックチェーンの開発経験は必要ありません!"
author: "Elan Halpern"
-tags:
- - "JavaScript"
- - "ethers.js"
- - "ノード"
- - "クエリ"
- - "Alchemy"
+tags: [ "JavaScript", "ethers.js", "ノード", "クエリ", "Alchemy" ]
skill: beginner
lang: ja
published: 2020-10-30
@@ -15,46 +10,46 @@ source: Medium
sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-development-using-alchemy-c3d6a45c567f
---
-
+
-この記事は、はじめてイーサリアム開発を行う初心者向けのガイドです。 このチュートリアルでは、[Alchemy](https://alchemyapi.io/)を使用します。Alchemyは、何百万人ものユーザーを持つ代表的なブロックチェーン開発者向けプラットフォームで、最も人気が高いブロックチェーンアプリ( Maker、0x、MyEtherWallet、Dharma、Kyberなど)のうち7割がAlchemyを使用しています。 Alchemyを使用するとイーサリアムチェーン上でAPIエンドポイントにアクセスできるため、トランザクションの読み書きが可能になります。
+この記事は、はじめてイーサリアム開発を行う初心者向けのガイドです。 このチュートリアルでは、[Alchemy](https://alchemyapi.io/)を使用します。これは、Maker、0x、MyEtherWallet、Dharma、Kyberといったトップクラスのブロックチェーンアプリの70%に採用され、数百万人のユーザーを支える、業界をリードするブロックチェーン開発者プラットフォームです。 Alchemyを使用するとイーサリアムチェーン上でAPIエンドポイントにアクセスできるため、トランザクションの読み書きが可能になります。
-このチュートリアルでは、Alchemyにサインアップする方法から、最初のweb3 スクリプトを作成するまでを学習します。 ブロックチェーンの開発経験は必要ありません!
+Alchemyへのサインアップから、最初のWeb3スクリプト作成までご案内します! ブロックチェーンの開発経験は必要ありません!
## 1. 無料のAlchemyアカウントにサインアップする {#sign-up-for-a-free-alchemy-account}
-Alchemyのアカウントを作成するのは簡単です。 [こちら](https://auth.alchemyapi.io/signup)から無料でサインアップしてください。
+Alchemyのアカウント作成は簡単です。[こちらから無料でサインアップしてください](https://auth.alchemy.com/)。
-## 2. Alchemy アプリを作成する {#create-an-alchemy-app}
+## 2. Alchemyアプリを作成する {#create-an-alchemy-app}
イーサリアムチェーンと通信し、Alchemy製品を使用するには、あなたのリクエストを認証するためのAPIキーが必要になります。
-APIキーは、[ダッシュボード](http://dashboard.alchemyapi.io/)で作成できます。 新規キーを作成するには、以下の手順で「Create App」に移動します。
+APIキーは[ダッシュボードから作成](https://dashboard.alchemy.com/)できます。 新しいキーを作成するには、以下のように「Create App」に移動してください:
-ダッシュボードの表示を許可していただいた[_ShapeShift_](https://shapeshift.com/) _に感謝します!_
+_ダッシュボードの表示を許可していただいた[_ShapeShift_](https://shapeshift.com/)に、心より感謝申し上げます!_
-
+
-「Create App」の下にある詳細情報に記入して、新規キーを取得してください。 ここでは、あなたが以前に作成したアプリや、あなたのチームが作成したアプリも確認できます。 どのアプリについても、「View Key(キーを表示)」をクリックすると既存のキーを取得できます。
+「Create App」の下にある詳細情報に記入して、新しいキーを取得してください。 ここでは、あなたが以前に作成したアプリや、あなたのチームが作成したアプリも確認できます。 どのアプリについても、「View Key」をクリックすると既存のキーを取得できます。
-
+
-あるいは、カーソルを「Apps(アプリ)」の部分に移動させ、希望するアプリを選択する方法でも既存のAPIキーを取得することができます。 ここでは、「View Key(キーを表示)」できる他、「Edit App(アプリを編集)」して、特定のドメインをホワイトリストに追加したり、開発者ツールを参照したり、アナリティクスを確認することができます。
+「Apps」にカーソルを合わせていずれかを選択することでも、既存のAPIキーを取得できます。 ここでは「View Key」の表示に加え、「Edit App」で特定のドメインをホワイトリストに登録したり、複数の開発者ツールを閲覧したり、アナリティクスを確認したりすることができます。
-
+
-## 3. コマンドラインでリクエストを作成する {#make-a-request-from-the-command-line}
+## 3. コマンドラインからリクエストを行う {#make-a-request-from-the-command-line}
-JSON-RPCとcurlを使用して、Alchemy経由でイーサリアムブロックチェーンとのやり取りを行います。
+JSON-RPCとcurlを使用して、Alchemy経由でイーサリアムブロックチェーンとやり取りをします。
-マニュアルでリクエストを作成する場合は、`JSON-RPC`の`POST`リクエストを使ってやりとりすることをお勧めします。 `Content-Type: application/json`のヘッダーと、クエリの`POST`本文に、以下のフィールドを入力してください:
+手動リクエストの場合は、`POST`リクエストを介して`JSON-RPC`とやり取りすることをお勧めします。 `Content-Type: application/json`ヘッダーと、以下のフィールドを含むクエリを`POST`ボディとして渡すだけです:
-- `jsonrpc`:JSON-RPC のバージョン - 現在対応しているのは バージョン`2.0` のみです。
-- `method`:ETH APIメソッド。 [APIリファレンスを参照してください。](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc)
+- `jsonrpc`: JSON-RPCのバージョン — 現在は`2.0`のみがサポートされています。
+- `method`: ETH APIメソッド。 [APIリファレンスを参照](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc)
- `params`: メソッドに渡すパラメータのリストです。
-- `id`: このリクエストのIDです。 この値は応答によって返されるため、どのリクエストに対する応答なのかを追跡できます。
+- `id`: リクエストのIDです。 この値はレスポンスによって返されるため、どのリクエストに対するレスポンスなのかを追跡できます。
-以下の例は、コマンドラインから現在のガス代の情報を取得するコードです。
+以下は、コマンドラインから現在のガス価格を取得するために実行できる一例です:
```bash
curl https://eth-mainnet.alchemyapi.io/v2/demo \
@@ -63,37 +58,37 @@ curl https://eth-mainnet.alchemyapi.io/v2/demo \
-d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}'
```
-_**注意:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo)は、`https://eth-mainnet.alchemyapi.io/v2/**your-api-key` など、あなた自身のAPIキーと置き換えてください。_
+_**注:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) を、ご自身のAPIキー `https://eth-mainnet.alchemyapi.io/v2/**your-api-key` に置き換えてください。_
-**出力:**
+**結果:**
```json
{ "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 }
```
-## 4. Web3 クライアントを設定する {#set-up-your-web3-client}
+## 4. Web3クライアントのセットアップ {#set-up-your-web3-client}
-**すでにクライアントをインストール済みの場合は、** 現在のノードプロバイダーのURLを、APIキーを含むAlchemyのURL( `"https://eth-mainnet.alchemyapi.io/v2/your-api-key"`など)に変更します。
+**既存のクライアントをお持ちの場合:** 現在のノードプロバイダーのURLを、ご自身のAPIキーを含むAlchemyのURL `“https://eth-mainnet.alchemyapi.io/v2/your-api-key\"` に変更してください。
-**_注意:_** 以下のスクリプトは、 コマンドラインで実行するのではなく、**ノードコンテキスト**または**ファイルに保存した形で**実行する必要があります。 Nodeまたはnpmがインストールされていない場合は、[Mac用設定ガイド](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs) をご覧ください。
+**_注:_** 以下のスクリプトは、コマンドラインから実行するのではなく、**nodeコンテキスト**で実行するか、**ファイルに保存する**必要があります。 まだNodeまたはnpmをインストールしていない場合は、こちらの[Mac用クイックセットアップガイド](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs)をご覧ください。
-Alchemyと統合可能な[Web3ライブラリ](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries)は無数に存在しますが、このチュートリアルでは、Alchemyとシームレスに動作するように構築・設定されたweb3.jsの完全互換版である[Alchemy Web3](https://docs.alchemy.com/reference/api-overview)をお勧めします。 Alchemy Web3は、自動リトライや WebScoket に対する充実したサポートなどの利点を持っています。
+Alchemyと統合できる[Web3ライブラリ](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries)はたくさんありますが、web3.jsのドロップインリプレースメントとして、Alchemyとシームレスに動作するように構築・設定された[Alchemy Web3](https://docs.alchemy.com/reference/api-overview)の使用をお勧めします。 これにより、自動リトライや堅牢なWebSocketサポートなど、複数の利点が得られます。
-Alchemy Web3.jsをインストールするには、 **プロジェクトディレクトリに移動して**、以下を実行します。
+AlchemyWeb3.jsをインストールするには、**プロジェクトディレクトリに移動し**、以下を実行してください:
-**Yarnの場合:**
+**Yarnの場合:**
```
yarn add @alch/alchemy-web3
```
-**NPMの場合:**
+**NPMの場合:**
```
npm install @alch/alchemy-web3
```
-Alchemyのノードインフラとやり取りするには、Node.jsで実行するか、JavaScriptファイルに以下の行を追加します:
+Alchemyのノードインフラストラクチャとやり取りするには、NodeJSで実行するか、このコードをJavaScriptファイルに追加してください:
```js
const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
@@ -102,26 +97,26 @@ const web3 = createAlchemyWeb3(
)
```
-## 5. はじめてのWeb3スクリプトを作成しましょう! {#write-your-first-web3-script}
+## 5. 最初のWeb3スクリプトを書きましょう! {#write-your-first-web3-script}
-それではさっそく、実際にweb3のプログラミングを始めましょう。まずは、イーサリアム・メインネットにおける最新のブロック番号を出力する簡単なスクリプトを作成します。
+それでは、少しWeb3プログラミングを試してみましょう。イーサリアムメインネットから最新のブロック番号を出力する簡単なスクリプトを作成します。
-**1. すでに実行していない場合、ターミナルで新規のプロジェクトディレクトリを作成し、cdコマンドで移動します。**
+\*\*1. **まだ作成していない場合は、ターミナルで新しいプロジェクトディレクトリを作成し、そこにcdで移動してください:**
```
mkdir web3-example
cd web3-example
```
-**2. まだ実行していない場合、Alchemy web3(または任意の web3)の依存関係をプロジェクトにインストールします。**
+\*\*2. **まだインストールしていない場合は、Alchemy Web3(または任意のWeb3)の依存関係をプロジェクトにインストールしてください:**
```
npm install @alch/alchemy-web3
```
-**3. `index.js`という名称のファイルを作成し、以下の内容を追加します:**
+\*\*3. **`index.js`という名前のファイルを作成し、次の内容を追加してください:**
-> 最終的には、`demo`をあなたのAlchemy HTTP API keyに置き換える必要があります。
+> 最終的には`demo`をご自身のAlchemy HTTP APIキーに置き換える必要があります。
```js
async function main() {
@@ -133,22 +128,22 @@ async function main() {
main()
```
-非同期関数についてよく理解していない場合は、 この[Mediumの記事](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c)を参照してください。
+async(非同期処理)に慣れていませんか? こちらの[Mediumの投稿](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c)をご確認ください。
-**4. ノードを使用して、ターミナルで実行します。**
+\*\*4. **nodeを使ってターミナルで実行します**
```
node index.js
```
-**5. コンソールに、最新のブロック番号が出力されるはずです。**
+\*\*5. **コンソールに最新のブロック番号が出力されているはずです!**
```
The latest block number is 11043912
```
-**よくできました! おめでとうございます! Alchemyを使用した最初のweb3スクリプトが完成しました 🎉**
+**素晴らしい!** おめでとうございます! **これでAlchemyを使って最初のWeb3スクリプトが書けました 🎉**
-次は何を学べば良いのかわからない場合は、 [「ハローワールド・スマートコントラクトガイド」](https://docs.alchemyapi.io/tutorials/hello-world-smart-contract)を使って、はじめてのスマートコントラクトのデプロイとSolidityプログラミングに挑戦するか、[ダッシュボード・デモアプリ](https://docs.alchemyapi.io/tutorials/demo-app)でダッシュボードに関するあなたの知識をテストしてみましょう!
+次に何をすればいいかわからないですか? [Hello Worldスマートコントラクトガイド](https://www.alchemy.com/docs/hello-world-smart-contract)で最初のスマートコントラクトをデプロイしてSolidityプログラミングを試すか、[ダッシュボードデモアプリ](https://docs.alchemyapi.io/tutorials/demo-app)でダッシュボードの知識を試してみてください!
-_[Alchemyに無料登録し](https://auth.alchemyapi.io/signup)、[ドキュメンテーション](https://docs.alchemyapi.io/)を確認してください。また、[Twitter](https://twitter.com/AlchemyPlatform)_をフォローして、最新ニュースをチェックしてください。
+_[Alchemyに無料でサインアップ](https://auth.alchemy.com/)し、[ドキュメント](https://www.alchemy.com/docs/)をチェックして、最新ニュースは[Twitter](https://twitter.com/AlchemyPlatform)でフォローしてください。_
diff --git a/public/content/translations/ja/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/ja/developers/tutorials/guide-to-smart-contract-security-tools/index.md
index 9a1ae545f7a..58df2c54541 100644
--- a/public/content/translations/ja/developers/tutorials/guide-to-smart-contract-security-tools/index.md
+++ b/public/content/translations/ja/developers/tutorials/guide-to-smart-contract-security-tools/index.md
@@ -1,105 +1,102 @@
---
-title: スマートコントラクト関連セキュリティツールのガイド
-description: テストおよびプログラム分析に関する3種類のテクニックの概要
+title: "スマートコントラクトセキュリティツールのガイド"
+description: "3つの異なるテストおよびプログラム分析手法の概要"
author: "Trailofbits"
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "セキュリティ"
+tags: [ "Solidity", "スマート契約", "セキュリティ" ]
skill: intermediate
published: 2020-09-07
-source: セキュアなコントラクトの開発
+source: Building secure contracts
sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis
---
-このチュートリアルでは、以下の3種類のテスト/プログラム分析テクニックを取り上げます:
+ここでは、3つの特徴的なテストおよびプログラム分析の手法を使用します。
-- **[Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/)を用いた静的解析**では、プログラムのすべてのパスにつき、様々なプログラム表示(例:制御フローグラフ)を通じて同時に近似値を求め、分析します。
-- **[Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/)を用いたファジング**では、疑似乱数に基づいて生成したトランザクションを用いてコードを実行します。 ファザーは、特定のプロパティに違反する一連のトランザクションを見つけようとします。
-- **[Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/)を用いたシンボリック実行**は、各実行パスを数式に変換した上で、制約条件をチェックできるフォーマルな検証テクニックです。
+- **[Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/)による静的解析。** プログラムのすべてのパスが、異なるプログラム表示(例:制御フローグラフ)を通じて、同時に近似、分析されます。
+- **[Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/)によるファジング。** コードは、トランザクションの疑似ランダム生成によって実行されます。 ファザーは、特定のプロパティに違反する一連のトランザクションを見つけようとします。
+- **[Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/)によるシンボリック実行。** 各実行パスを数式に変換し、その上で制約をチェックできる形式的検証テクニックです。
-上記の手法はそれぞれの利点と欠点を持つため、[特定の用途](#determining-security-properties)に合わせて選択すべきです。
+各テクニックには長所と短所があり、[特定のケース](#determining-security-properties)で役立ちます:
-| 手法 | ツール | 用途 | 速度 | バグを見落とす可能性 | 偽陽性の可能性 |
-| -------- | --------- | ------------------------ | --- | ---------- | ------- |
-| 静的解析 | Slither | CLI およびスクリプト | 数秒 | 中程度 | 低い |
-| ファジング | Echidna | Solidityのプロパティ | 数分間 | 低い | なし |
-| シンボリック実行 | Manticore | Solidity のプロパティおよび スクリプト | 数時間 | なし* | なし |
+| テクニック | ツール | 使用法 | 速度 | 見逃されるバグ | 誤検知 |
+| -------- | --------- | -------------------- | --- | ------- | --- |
+| 静的解析 | Slither | CLIとスクリプト | 数秒 | 中 | 低 |
+| ファジング | Echidna | Solidityのプロパティ | 数分間 | 低 | なし |
+| シンボリック実行 | Manticore | Solidityのプロパティとスクリプト | 数時間 | なし\* | なし |
-* すべてのパスをタイムアウトなしで検証した場合
+- すべてのパスがタイムアウトなしで探索された場合
-**Slither**は、コントラクトを数秒間で分析できますが、 静的解析は誤検知を伴う場合があり、複雑なチェック作業(例:算術演算の検査)にはあまり適していません。 Slitherは、APIを通じてプッシュボタンによりビルトインの検知器にアクセスするか、ユーザー定義のチェック作業用のAPIを通じて実行します。
+**Slither**は数秒でコントラクトを分析しますが、静的解析は誤検知につながる可能性があり、複雑なチェック(算術チェックなど)にはあまり適していません。 Slitherは、API経由で実行し、組み込みの検出器にプッシュボタンでアクセスするか、ユーザー定義のチェックを行います。
-**Echidna**では、検出に数分間を要しますが、偽陽性は検出しません。 Echidnaでは、Solidityで作成され、ユーザーが提供したセキュリティ属性をチェックします。 ただし、ランダムな検索に基づくため、すべてのバグを検出するとは限りません。
+**Echidna**は、実行に数分を要しますが、生成するのは真陽性のみです。 Echidnaは、ユーザーが提供した、Solidityで記述されたセキュリティプロパティをチェックします。 ランダムな探索に基づいているため、バグを見逃す可能性があります。
-**Manticore**は、「最も徹底的な」分析を行います。 Echidnaの場合と同様に、ユーザーが提供した属性を検証します。 検出時間はさらに長くなりますが、特定のプロパティを検証でき、偽陽性を検出することもありません。
+**Manticore**は、"最もヘビー級"の分析を実行します。 Echidnaと同様に、Manticoreはユーザーが提供したプロパティを検証します。 実行にはより時間がかかりますが、プロパティの有効性を証明でき、誤検知を報告しません。
-## 推奨するワークフロー {#suggested-workflow}
+## 推奨ワークフロー {#suggested-workflow}
-まず、Slitherに内蔵されている検出機能で開始し、現時点において単純なバグが存在せず、今後も紛れ込む可能性がないことを確認しましょう。 Slither を使って、継承、変数の依存関係、および構造的な問題についてチェックします。 コードベースの規模が拡大するのに伴い、Echidnaを使って、ステートマシンにおけるより複雑なプロパティをテストします。 また、上書きされる機能に対する保護などのSolidityでは提供されない保護については、Slitherを使ってカスタムチェックを作成してください。 最後にManticoreを使用して、セキュリティに関する最重要のプロパティ(例:算術演算)のみに対象を絞った検証を行います。
+まずSlitherの組み込み検出器から始めて、単純なバグが現在存在しないこと、そして後で入り込まないことを確認します。 Slitherを使用して、継承、変数の依存関係、構造上の問題に関連するプロパティをチェックします。 コードベースが大きくなるにつれて、Echidnaを使用してステートマシンのより複雑なプロパティをテストします。 Solidityでは利用できない保護(関数のオーバーライドに対する保護など)のために、Slitherを再検討してカスタムチェックを開発します。 最後に、Manticoreを使用して、重要なセキュリティプロパティ(算術演算など)の的を絞った検証を実行します。
-- SlitherのCLIを使って、よくある問題を検出する
-- Echidnaを使って、スマートコントラクトにおける高度なセキュリティ関連プロパティをテストする
-- Slitherを使って、カスタムの静的解析を作成する
-- 最重要なセキュリティ属性について詳細な保証が必要になったら、Manticoreを使用する
+- SlitherのCLIを使用して、一般的な問題を検出する
+- Echidnaを使用して、コントラクトの高レベルのセキュリティプロパティをテストする
+- Slitherを使用して、カスタムの静的チェックを作成する
+- 重要なセキュリティプロパティの詳細な保証が必要になったら、Manticoreを使用する
-**単体テストに関する注意事項**: 高品質のソフトウェア開発には、単体テストが必須です。 一方で、セキュリティ欠陥を検出する上で、単体テストは最善の方法とは言えません。 通常、単体テストはコードの望ましい動作を確認するため(つまり、通常の環境において予想通りに動作するかどうか)に用いられますが、セキュリティ上の欠陥は、デベロッパが見落としていた周縁的なケースで発生する場合が多いのです。 スマートコントラクトを対象とする数十件のセキュリティレビューを調査した結果、[単体テストのカバレッジは、クライアントのコード上で特定されたセキュリティ上の欠陥の数や重大性には影響を与えていないことが分かりました](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/)。
+**単体テストに関する注記**。 高品質のソフトウェアを構築するには、単体テストが必要です。 しかし、これらのテクニックはセキュリティ上の欠陥を見つけるのに最適というわけではありません。 単体テストは通常、コードの正常な動作(つまり、通常のコンテキストで期待どおりにコードが機能すること)をテストするために使用されますが、セキュリティ上の欠陥は、開発者が考慮しなかったエッジケースに存在する傾向があります。 数十件のスマートコントラクトのセキュリティレビューに関する我々の調査では、クライアントのコードで発見されたセキュリティ上の欠陥の数や重大度に対して、[単体テストのカバレッジは影響を与えませんでした](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/)。
-## 対象とするセキュリティ属性を決定する {#determining-security-properties}
+## セキュリティプロパティの決定 {#determining-security-properties}
-コードを効果的にテスト、検証するには、まず、対象とすべき分野を特定する必要があります。 セキュリティのためのリソースには限りがありますから、コードベースにおける脆弱な部分や高価値の部分に注力して、この取り組みを最適化することが重要です。 これには、脅威モデリングの手法を用いるとよいでしょう。 以下の事項をレビューしてください:
+コードを効果的にテストおよび検証するには、注意が必要な領域を特定する必要があります。 セキュリティに費やすリソースは限られているため、労力を最適化するには、コードベースの脆弱な部分や価値の高い部分を特定することが重要です。 脅威モデリングが役立ちます。 以下をレビューすることを検討してください:
-- [迅速リスク評価](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html)(短時間に完了しなければならない場合に推奨するアプローチです)
-- [データ中心システムにおける脅威モデル作成ガイド](https://csrc.nist.gov/publications/detail/sp/800-154/draft)(別名:NIST 800-154)
-- [Shostackスレッド・モデリング](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998)
-- [STRIDE](https://wikipedia.org/wiki/STRIDE_(security)) / [DREAD](https://wikipedia.org/wiki/DREAD_(risk_assessment_model))
+- [迅速なリスク評価](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (時間がない場合に推奨されるアプローチ)
+- [データ中心システム脅威モデリングガイド](https://csrc.nist.gov/pubs/sp/800/154/ipd)(別名NIST 800-154)
+- [Shostack脅威モデリング](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998)
+- [STRIDE](https://wikipedia.org/wiki/STRIDE_\(security\)) / [DREAD](https://wikipedia.org/wiki/DREAD_\(risk_assessment_model\))
- [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.)
-- [アサーションを活用する](https://blog.regehr.org/archives/1091)
+- [アサーションの使用](https://blog.regehr.org/archives/1091)
-### 構成要素 {#components}
+### コンポーネント {#components}
-どの事項をチェックしたいのかを把握しておくと、適切なツール選択に役立ちます。
+何をチェックしたいかを知ることも、適切なツールを選ぶのに役立ちます。
-スマートコントラクトにおいて問題となる可能性が高い分野としては、以下が挙げられます:
+スマートコントラクトに頻繁に関連する幅広い分野には、以下が含まれます:
-- **状態マシン** ほとんどのコントラクトは、状態マシンとして表示することが可能です。 ですから、(1)無効な状態に達していないか、(2)状態が有効かつ到達しうるか、および(3)コントラクトをトラップする状態が存在しないか、についてチェックするとよいでしょう。
+- **ステートマシン。** ほとんどのコントラクトはステートマシンとして表現できます。 (1) 無効なステートに到達できないこと、(2) ステートが有効である場合に到達可能であること、(3) コントラクトをトラップするステートがないこと、を確認することを検討してください。
- - 状態マシンの仕様をテストするのに適しているのは、EchidnaとManticoreです。
+ - EchidnaとManticoreは、ステートマシンの仕様をテストするのに適したツールです。
-- **アクセス管理。** あなたのシステムに特権ユーザー(例:所有者、管理者など)が含まれる場合、(1)各ユーザーが、権限を持つアクションのみ実行可能であること、および(2)権限レベルがより上のユーザーによるアクションをブロックできる下位ユーザーが存在しないこと、を確認してください。
+- **アクセス制御。** システムに特権ユーザー(例:オーナー、コントローラーなど)がいる場合 (1) 各ユーザーが許可されたアクションのみを実行できること、(2) より特権的なユーザーからのアクションをブロックできるユーザーがいないこと、を保証する必要があります。
- - アクセス管理については、Slither、Echidna、およびManticoreのいずれも適切なチェックを実行できます。 例えばSlitherでは、ホワイトリストに登録された関数のうち、onlyOwner修飾子を持たない関数のみをチェックすることができます。 一方、EchidnaおよびManticoreは、コントラクトが特定のステートに達した場合のみに権限が付与される場合など、より複雑なアクセス管理を確認するのに適しています。
+ - Slither、Echidna、Manticoreは、正しいアクセス制御をチェックできます。 例えばSlitherは、`onlyOwner`修飾子を欠く関数がホワイトリスト登録済みのものだけであることをチェックできます。 EchidnaとManticoreは、コントラクトが特定のステートに達した場合にのみ許可が与えられるなど、より複雑なアクセス制御に役立ちます。
-- **算術演算。** 算術演算が正しく実行されるかを確認することは、非常に重要です。 オーバーフロー/アンダーフローを防止するには、`SafeMath`を常に利用することを推奨しますが、同時に、端数処理に関する問題やコントラクトをトラップしてしまうような欠陥など、その他の演算上の欠陥についても確認する必要があります。
+- **算術演算。** 算術演算の健全性をチェックすることは非常に重要です。 あらゆる場所で`SafeMath`を使用することは、オーバーフロー/アンダーフローを防ぐための良い一歩ですが、丸め誤差の問題やコントラクトをトラップする欠陥など、他の算術的な欠陥も考慮する必要があります。
- - この分野では、Manticoreを使用するのがよいでしょう。 当該の算術演算がSMTソルバーの対象範囲外である場合は、Echidnaを選択してもよいです。
+ - ここではManticoreが最良の選択です。 算術がSMTソルバーの範囲外である場合は、Echidnaを使用できます。
-- **継承の正確性。** Solidityで作成したコントラクトは、複数の継承に大きく依存しています。 シャドーイング関数において`super`コールが含まれていない場合や、C3 linearizationの順序の誤解釈などのミスは、容易に発生する可能性があります。
+- **継承の正確性。** Solidityコントラクトは多重継承に大きく依存しています。 `super`呼び出しを欠いたシャドウイング関数や、誤って解釈されたC3線形化の順序などの間違いは、簡単に発生し得ます。
- - これらの問題を検出するには、Slitherが最適です。
+ - Slitherは、これらの問題を確実に検出するためのツールです。
-- **外部とのやりとり。** コントラクトは相互にやりとりを行いますが、外部のコントラクトの中には信用すべきでないものもあります。 例えば、あなたのコントラクトが外部オラクルに依存する場合、利用可能なオラクルの半分が汚染されていれば、あなたのコントラクトはセキュアであるとは言えないでしょう。
+- **外部とのやりとり。** コントラクトは相互にやりとりしますが、一部の外部コントラクトは信頼すべきではありません。 例えば、コントラクトが外部のオラクルに依存している場合、利用可能なオラクルの半分が侵害されても、そのコントラクトは安全なままでしょうか?
- - コントラクトにおける外部とのやりとりをテストするには、ManticoreおよびEchidnaが最適です。 Manticoreには、外部のコントラクトをスタブするためのメカニズムが内蔵されています。
+ - ManticoreとEchidnaは、コントラクトと外部とのやりとりをテストするための最良の選択です。 Manticoreには、外部コントラクトをスタブするための組み込みメカニズムがあります。
-- **規格適合性。** イーサリアムの標準(例:ERC-20)には、これまで様々な設計ミスが含まれていました。 ですから、作成するコントラクトの規格上の制約に十分注意してください。
- - Slither、Echidna、およびManticoreはいずれも、特定の規格に対する非遵守を検知するのに役立ちます。
+- **標準準拠。** イーサリアムの標準(例:ERC20)には、その設計に欠陥があった歴史があります。 構築の基盤となる標準の制限に注意してください。
+ - Slither、Echidna、Manticoreは、特定の標準からの逸脱を検出するのに役立ちます。
-### ツール選択の早見表 {#tool-selection-cheatsheet}
+### ツール選択のチートシート {#tool-selection-cheatsheet}
-| 構成要素 | ツール | 具体例 |
-| -------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 状態マシン | Echidna、Manticore | |
-| アクセス管理 | Slither、Echidna、Manticore | [Slither エクササイズ2](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md)、[Echidna エクササイズ2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) |
-| 算術演算 | Manticore、Echidna | [Echidna エクササイズ1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md)、[Manticore エクササイズ1~3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) |
-| 継承の正確さ | Slither | [Slither エクササイズ1](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) |
-| 外部とのやりとり | Manticore、Echidna | |
-| 規格の遵守 | Slither、Echidna、Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) |
+| コンポーネント | ツール | 実例: |
+| -------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| ステートマシン | Echidna、Manticore | |
+| アクセス制御 | Slither、Echidna、Manticore | [Slither 演習 2](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md)、[Echidna 演習 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) |
+| 算術演算 | Manticore、Echidna | [Echidna 演習 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md)、[Manticore 演習 1~3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) |
+| 継承の正確性 | Slither | [Slither 演習 1](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) |
+| 外部とのやりとり | Manticore、Echidna | |
+| 標準準拠 | Slither、Echidna、Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) |
-コントラクトの目的に応じて他の分野についてもチェックする必要がありますが、あらゆるスマートコントラクトにおいて、上記の大まかな注力分野から確認することをお勧めします。
+目標によっては他の領域もチェックする必要がありますが、これらの大まかな重点領域は、あらゆるスマートコントラクトシステムにとって良い出発点となります。
-本サイトのパブリック監査には、検証/テスト済みのプロパティの具体例が含まれています。 実際のセキュリティ関連プロパティについてレビューしたい場合は、以下のレポートの`Automated Testing and Verification(自動テスト/検証)`セクションを参照してください。
+我々の公開監査には、検証またはテストされたプロパティの例が含まれています。 実際のセキュリティプロパティをレビューするには、以下のレポートの`Automated Testing and Verification`のセクションを読むことを検討してください:
- [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf)
- [Balancer](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf)
diff --git a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract-fullstack/index.md
index e57b51fa783..b5025cc984c 100644
--- a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract-fullstack/index.md
+++ b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract-fullstack/index.md
@@ -1,87 +1,90 @@
---
-title: 初心者向けのHello Worldスマートコントラクト - フルスタック
-description: イーサリアムでの簡単なスマートコントラクトの作成とデプロイに関する入門チュートリアル
+title: "初心者向けのHello Worldスマートコントラクト - フルスタック"
+description: "イーサリアムでの簡単なスマートコントラクトの作成とデプロイに関する入門チュートリアル。"
author: "nstrike2"
tags:
- - "Solidity"
- - "Hardhat"
- - "Alchemy"
- - "スマートコントラクト"
- - "デプロイ"
- - "ブロックエクスプローラ"
- - "フロントエンド"
- - "トランザクション"
+ [
+ "Solidity",
+ "hardhat",
+ "Alchemy",
+ "スマート契約",
+ "デプロイ",
+ "ブロックエクスプローラー",
+ "フロントエンド",
+ "トランザクション"
+ ]
skill: beginner
lang: ja
published: 2021-10-25
---
-このガイドはブロックチェーンの開発の初心者で、どこから始めたらよいか分からなかったり、スマートコントラクトのデプロイやインタラクト方法について分からない方向けのものです。 これから一緒に、Goerliテストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追ってたどりましょう。その際、[MetaMask](https://metamask.io)、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org)と[Alchemy](https://alchemyapi.io/eth)を使用します。
+このガイドは、ブロックチェーン開発の初心者で、どこから始めればよいか、スマートコントラクトのデプロイやインタラクトの方法がわからない方を対象としています。 [MetaMask](https://metamask.io)、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org)、[Alchemy](https://alchemy.com/eth) を使って、Goerliテストネットワークでシンプルなスマートコントラクトを作成し、デプロイする手順を説明します。
-このチュートリアルを完了するためにはAlchemyのアカウントが必要です。 [無料でアカウント登録する](https://www.alchemy.com/).
+このチュートリアルを完了するには、Alchemyのアカウントが必要です。 [無料アカウントにサインアップ](https://www.alchemy.com/)
-質問がある場合は、いつでもお気軽に[Alchemy Discord](https://discord.gg/gWuC7zB)でお問い合わせください。
+ご不明な点がありましたら、[Alchemy Discord](https://discord.gg/gWuC7zB) までお気軽にお問い合わせください。
-## パート1: Hardhatを利用してスマートコントラクトを作りデプロイする {#part-1}
+## パート1 - Hardhatを使用してスマートコントラクトを作成・デプロイする {#part-1}
-### イーサリアムネットワークに接続する {#connect-to-the-ethereum-network}
+### Ethereumネットワークに接続する {#connect-to-the-ethereum-network}
-イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここではAlchemyの無料アカウントを使用します。このブロックチェーンのデベロッパープラットフォームとAPIにより、独自のノードを実行することなく、イーサリアムチェーンとの通信が可能になります。 Alchemyには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。
+イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡潔にするため、ブロックチェーン開発者プラットフォームであり、APIでもあるAlchemyの無料アカウントを使用します。これにより、自分でノードを実行することなく、Ethereumチェーンと通信できます。 Alchemyには、モニタリングと分析のための開発者ツールもあります。このチュートリアルでは、これらのツールを利用して、スマートコントラクトのデプロイで内部的に何が起こっているかを理解します。
-### アプリのAPIキーの作成 {#create-your-app-and-api-key}
+### アプリとAPIキーを作成する {#create-your-app-and-api-key}
-Alchemyのアカウントを作成した後、アプリを作成することでAPIキーを生成することができます。 これにより、Goerliテストネットへのリクエストが可能になります。 テストネットに詳しくない場合は、[Alchemyのネットワークの選択ガイド](https://docs.alchemyapi.io/guides/choosing-a-network)をお読みください。
+Alchemyのアカウントを作成したら、アプリを作成してAPIキーを生成できます。 これにより、Goerliテストネットにリクエストを送信できるようになります。 テストネットに馴染みがない場合は、[Alchemyのネットワーク選択ガイド](https://www.alchemy.com/docs/choosing-a-web3-network) をお読みください。
-Alchemyダッシュボード上にあるナビゲーションバーで**Apps**ドロップダウンがあります。そこで、**Create App**をクリックします。
+Alchemyのダッシュボードで、ナビゲーションバーにある **Apps** ドロップダウンを見つけ、**Create App** をクリックします。
-
+
-アプリに「_Hello World_」という名前を付けて、短い説明を書きます。 環境は、**Staging**を選択します。ネットワークは、**Goerli**を選択します。
+アプリに「_Hello World_」という名前を付け、簡単な説明を記述します。 環境として **Staging** を、ネットワークとして **Goerli** を選択します。
-
+
-_注意: 必ず**Goerli**を選択してください。そうしないと、このチュートリアルどおり行きません。_
+_注: 必ず **Goerli** を選択してください。選択しないと、このチュートリアルは機能しません。_
-**Create app**をクリックしてください。 アプリが下の表に表示されます。
+**Create app** をクリックします。 作成したアプリが下の表に表示されます。
-### イーサリアムアカウントの作成 {#create-an-ethereum-account}
+### Ethereumアカウントを作成する {#create-an-ethereum-account}
-トランザクションの送受信には、イーサリアムアカウントが必要です。 ここでは、MetaMaskを使います。MataMaskは、ユーザーがイーサリアムのアカウントアドレスを管理できるブラウザーの仮想ウォレットです。
+トランザクションを送受信するには、Ethereumアカウントが必要です。 ここでは、ユーザーがEthereumアカウントアドレスを管理できる、ブラウザ上の仮想ウォレットであるMetaMaskを使用します。
-Metamaskのアカウントは[こちら](https://metamask.io/download)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は(実際に支払いが発生しないように)右上の「Goerli Test Network」に切り替えてください。
+MetaMaskアカウントは、[こちら](https://metamask.io/download)から無料でダウンロードして作成できます。 アカウントを作成するとき、またはすでにアカウントをお持ちの場合は、右上の「Goerli Test Network」に必ず切り替えてください (実在の通貨を扱わないようにするため)。
-### ステップ4: フォーセットからイーサリアムを追加する {#step-4-add-ether-from-a-faucet}
+### ステップ4: フォーセットからイーサを追加する {#step-4-add-ether-from-a-faucet}
-テストネットワークにスマートコントラクトをデプロイするには、偽のETHが複数必要になります。 GoerliネットワークでETHを取得するには、Goerliフォーセットに移動し、あなたのGoerliのアカウントアドレスを入力します。 Goerliフォーセットは最近、不安定になることがあります。試せるオプションのリストは、[テストネットワークのページ](/developers/docs/networks/#goerli)を参照してください。
+スマートコントラクトをテストネットワークにデプロイするには、偽のETHが必要です。 GoerliネットワークでETHを取得するには、Goerliフォーセットにアクセスし、Goerliアカウントアドレスを入力します。 Goerliフォーセットは最近、少し信頼性が低い場合があります。試せるオプションの一覧については、[テストネットワークのページ](/developers/docs/networks/#goerli) を参照してください:
-_注意: ネットワークの混雑状況によっては、時間がかかる場合があります。_
+_注: ネットワークの混雑により、しばらく時間がかかる場合があります。_
+``
### ステップ5: 残高を確認する {#step-5-check-your-balance}
-あなたのウォレットにETHがあることをダブルチェックし、[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)リクエストを[Alchemyのコンポーザーツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使って出してみましょう。 リクエストすると、ウォレット内のETHの量が返却されます。 詳細については、[Alchemyの短いチュートリアルにあるコンポーザーツールの使用方法](https://youtu.be/r6sjRxBZJuU)をご覧ください。
+ウォレットにETHが入っていることを再確認するために、[Alchemyのcomposerツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) を使って [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) リクエストを実行してみましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 詳細については、[composerツールの使用方法に関するAlchemyの短いチュートリアル](https://youtu.be/r6sjRxBZJuU) をご覧ください。
-MetaMaskアカウントのアドレスを入力し、**Send Request**をクリックします。 以下のコードスニペットのようなレスポンスが来ます。
+MetaMaskアカウントのアドレスを入力し、**Send Request** をクリックします。 以下のようなコードスニペットのレスポンスが表示されます。
```json
{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }
```
-> _注意: この結果の単位はweiであり、ETHではありません。 weiはETHの最小単位として使われています。_
+> _注: この結果はETHではなく、wei単位です。_ _Weiはetherの最小単位として使用されます。_
-ご安心ください。 私たちの偽物のお金はすべてそこにあります。
+ふう! 私たちの偽物のお金はすべてそこにあります。
### ステップ6: プロジェクトを初期化する {#step-6-initialize-our-project}
-まず、プロジェクトのフォルダを作成する必要があります。 コマンドラインに移動し、次のように入力します。
+まず、プロジェクト用のフォルダを作成する必要があります。 コマンドラインに移動し、次のように入力します。
```
mkdir hello-world
cd hello-world
```
-プロジェクトフォルダ内に入ったら、`npm init`を使用してプロジェクトを初期化します。
+プロジェクトフォルダに入ったので、`npm init`を使用してプロジェクトを初期化します。
-> npmをまだインストールしていない場合は、[こちら](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)の手順に従いNode.jsとnpmをインストールします。
+> まだnpmがインストールされていない場合は、[Node.jsとnpmをインストールするための指示](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)に従ってください。
このチュートリアルでは、初期化における質問にどのように答えるかには重点を置いていません。 参考までに、私たちは次のように行いました。
@@ -111,29 +114,29 @@ About to write to /Users/.../.../.../hello-world/package.json:
}
```
-package.jsonを承認すれば完了です。
+package.jsonを承認すれば完了です!
-### ステップ7: Hardhatのダウンロード {#step-7-download-hardhat}
+### ステップ7: Hardhatをダウンロードする {#step-7-download-hardhat}
Hardhatは、イーサリアムのソフトウェアをコンパイル、デプロイ、テスト、デバッグするための開発環境です。 デベロッパーがライブチェーンにデプロイする前に、スマートコントラクトや分散型アプリケーション(Dapp)をローカルに構築する際に役立ちます。
-先ほど作成した`hello-world`プロジェクト内で、以下を実行します。
+`hello-world`プロジェクト内で次を実行します。
```
npm install --save-dev hardhat
```
-[インストール手順](https://hardhat.org/getting-started/#overview)の詳細については、こちらのページをご覧ください。
+[インストール手順](https://hardhat.org/getting-started/#overview)の詳細については、このページをご覧ください。
### ステップ8: Hardhatプロジェクトを作成する {#step-8-create-hardhat-project}
-先ほど作成した`hello-world`プロジェクトフォルダ内で、以下を実行します。
+`hello-world`プロジェクトフォルダ内で、以下を実行します:
```
npx hardhat
```
-ウェルカムメッセージと、次に何をするのかを選択できるオプションが表示されます。 「Create an empty hardhat.config.js」を選択します。
+ウェルカムメッセージと、次に何をするのかを選択できるオプションが表示されます。 「create an empty hardhat.config.js」を選択してください。
```
888 888 888 888 888
@@ -153,57 +156,57 @@ Create a sample project
Quit
```
-これで、プロジェクト内に`hardhat.config.js`ファイルが生成されます。 プロジェクトの設定を明記するのにチュートリアルの後半でこれを使用します。
+これにより、プロジェクトに `hardhat.config.js` ファイルが生成されます。 チュートリアルの後半で、これを使用してプロジェクトのセットアップを指定します。
### ステップ9: プロジェクトフォルダを追加する {#step-9-add-project-folders}
-プロジェクトを整理するために、2つの新しいフォルダを作成します。 コマンドラインで、`hello-world`プロジェクトのルートディレクトリに移動し、次のように入力します。
+プロジェクトを整理するために、2つの新しいフォルダを作成しましょう。 コマンドラインで、`hello-world` プロジェクトのルートディレクトリに移動し、次のように入力します:
```
mkdir contracts
mkdir scripts
```
-- `contracts/`は、Hello Worldスマートコントラクトのコードファイルを格納する場所です。
-- `scripts/`は、コントラクトをデプロイして対話するスクリプトを保持する場所です。
+- `contracts/` には、hello worldスマートコントラクトのコードファイルを保存します
+- `scripts/` には、コントラクトをデプロイして対話するためのスクリプトを保存します
### ステップ10: コントラクトを作成する {#step-10-write-our-contract}
-一体いつになったらコードを書くのだろうと疑問をお持ちではないでしょうか 。 まさに、その時です!
+「いつになったらコードを書くのだろう?」と思っているかもしれませんね。 その時が来ました!
-あなたのお気に入りのエディターでhello-worldプロジェクトを開きます。 スマートコントラクトは、最も一般的にはSolidityで書かれています。そのため、Solidityでスマートコントラクトを作成します。
+お好きなエディタでhello-worldプロジェクトを開いてください。 スマートコントラクトは、最も一般的にはSolidityで記述されており、今回もSolidityを使ってスマートコントラクトを作成します。
-1. `contracts`フォルダに移動し、`HelloWorld.sol`という名前の新規ファイルを作成します。
-2. 以下は、このチュートリアルで使用するHello Worldスマートコントラクトのサンプルです。 以下の内容を`HelloWorld.sol`ファイルにコピーします。
+1. `contracts` フォルダに移動し、`HelloWorld.sol` という名前の新しいファイルを作成します。
+2. 以下は、このチュートリアルで使用するHello Worldスマートコントラクトのサンプルです。 以下の内容を `HelloWorld.sol` ファイルにコピーしてください。
-_注意: 必ずコメントを読み、このコントラクトの処理内容を理解してください。_
+_注: このコントラクトが何をするのかを理解するために、必ずコメントをお読みください。_
```
-// Specifies the version of Solidity, using semantic versioning.
-// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+// Solidityのバージョンをセマンティックバージョニングで指定します。
+// 詳細: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity >=0.7.3;
-// Defines a contract named `HelloWorld`.
-// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+// `HelloWorld` という名前のコントラクトを定義します。
+// コントラクトは関数とデータ (その状態) の集合です。一度デプロイされると、コントラクトはEthereumブロックチェーン上の特定のアドレスに存在します。詳細: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
- //Emitted when update function is called
- //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.
+ // update関数が呼び出されたときに発行されます
+ //スマートコントラクトのイベントは、ブロックチェーン上で何かが起こったことをコントラクトがアプリのフロントエンドに伝える方法です。フロントエンドは特定のイベントを「リッスン」し、それが起こったときに行動を起こすことができます。
event UpdatedMessages(string oldStr, string newStr);
- // Declares a state variable `message` of type `string`.
- // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
+ // `string` 型の状態変数 `message` を宣言します。
+ // 状態変数は、その値がコントラクトのストレージに永続的に保存される変数です。`public` キーワードにより、変数はコントラクトの外部からアクセス可能になり、他のコントラクトやクライアントが値をアクセスするために呼び出せる関数が作成されます。
string public message;
- // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
- // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ // 多くのクラスベースのオブジェクト指向言語と同様に、コンストラクタはコントラクト作成時に一度だけ実行される特別な関数です。
+ // コンストラクタはコントラクトのデータを初期化するために使用されます。詳細:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
- // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
+ // 文字列引数 `initMessage` を受け取り、その値をコントラクトの `message` ストレージ変数に設定します)。
message = initMessage;
}
- // A public function that accepts a string argument and updates the `message` storage variable.
+ // 文字列引数を受け取り、 `message` ストレージ変数を更新する公開関数です。
function update(string memory newMessage) public {
string memory oldMsg = message;
message = newMessage;
@@ -212,15 +215,15 @@ contract HelloWorld {
}
```
-これは、作成時にメッセージを保存する基本的なスマートコントラクトです。 `update`関数を呼び出すことで更新できます。
+これは、作成時にメッセージを保存する基本的なスマートコントラクトです。 `update` 関数を呼び出すことで更新できます。
### ステップ11: MetaMaskとAlchemyをプロジェクトに接続する {#step-11-connect-metamask-alchemy-to-your-project}
-ここまでで、MetaMaskウォレットとAlchemyアカウントを作成し、スマートコントラクトも作成しました。次はこの3つを接続しましょう。
+MetaMaskウォレットとAlchemyアカウントを作成し、スマートコントラクトも作成しました。次はこの3つを接続しましょう。
-ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この許可をプログラムに与えるために、秘密鍵を環境ファイルに安全に格納する作業を行います。 AlchemyのAPIキーもここに保存します。
+ウォレットから送信されるすべてのトランザクションには、一意の秘密鍵を使用した署名が必要です。 プログラムにこの許可を与えるために、秘密鍵を環境ファイルに安全に保存することができます。 AlchemyのAPIキーもここに保存します。
-> トランザクションの送信の詳細については、[こちらのチュートリアル](https://docs.alchemyapi.io/alchemy/tutorials/sending-transactions-using-web3-and-alchemy)のweb3使ったトランザクションの送信に関する内容をご覧ください。
+> トランザクションの送信についてさらに詳しく知るには、web3を使用したトランザクションの送信に関する[このチュートリアル](https://www.alchemy.com/docs/hello-world-smart-contract#step-11-connect-metamask--alchemy-to-your-project) を確認してください。
まず、プロジェクトディレクトリにdotenvパッケージをインストールします。
@@ -228,31 +231,31 @@ contract HelloWorld {
npm install dotenv --save
```
-次に、プロジェクトのルートディレクトリに`.env`ファイルを作成します。 MetaMask秘密鍵とHTTP Alchemy API URLをファイルに加えます。
+次に、プロジェクトのルートディレクトリに `.env` ファイルを作成します。 そのファイルに、MetaMaskの秘密鍵とHTTP Alchemy APIのURLを追加します。
-環境ファイルの名前は、必ず`.env`にしてください。そうしないと環境ファイルとして認識されません。
+環境ファイルは `.env` という名前にする必要があります。そうしないと、環境ファイルとして認識されません。
-`process.env`や`.env-custom`などの名前を付けないでください。
+`process.env` や `.env-custom` など、他の名前にしないでください。
-- 秘密鍵をエクスポートするには、[こちらの手順](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key)に従ってください。
-- HTTP Alchemy APIのURLを取得するには、以下を参照してください。
+- 秘密鍵をエクスポートするための[これらの手順](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key)に従ってください
+- HTTP Alchemy API URLを取得するには、以下を参照してください

-`.env`ファイルは次のようになります。
+`.env`は次のようになります:
```
API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
```
-これらの変数を実際にコードに接続するために、ステップ13でこれらの変数を`hardhat.config.js`ファイル内で参照します。
+これらをコードに実際に接続するために、ステップ13で`hardhat.config.js`ファイル内のこれらの変数を参照します。
### ステップ12: Ethers.jsをインストールする {#step-12-install-ethersjs}
-Ethers.jsは、よりユーザーフレンドリーなメソッドで[標準のJSON-RPCメソッド](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc)をラップすることにより、イーサリアムとの対話やリクエストを簡単に行うためのライブラリです。
+Ethers.jsは、[標準的なJSON-RPCメソッド](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc)をよりユーザーフレンドリーなメソッドでラップすることにより、Ethereumとのインタラクションやリクエストを容易にするライブラリです。
-Hardhatを使用すると、追加のツールと拡張機能のための[プラグイン](https://hardhat.org/plugins/)を統合できます。 コントラクトのデプロイでは、[Ethersプラグイン](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers)を利用します。
+Hardhatでは、追加のツールや拡張機能のために[プラグイン](https://hardhat.org/plugins/)を統合することができます。 コントラクトのデプロイには[Ethersプラグイン](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers)を利用します。
プロジェクトのホームディレクトリで以下を実行します。
@@ -260,11 +263,11 @@ Hardhatを使用すると、追加のツールと拡張機能のための[プラ
npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
```
-### ステップ13: hardhat.config.jsをアップデートする {#step-13-update-hardhat-configjs}
+### ステップ13: hardhat.config.jsを更新する {#step-13-update-hardhat-configjs}
-ここまでで、いくつかの依存関係とプラグインを追加しました。次に、`hardhat.config.js`を更新して、プロジェクトがそれらすべてについて認識できるようにする必要があります。
+ここまでで、いくつかの依存関係とプラグインを追加しました。次に、プロジェクトがそれらすべてを認識できるように、`hardhat.config.js`を更新する必要があります。
-`hardhat.config.js`を以下のように更新します。
+`hardhat.config.js`を次のように更新します:
```javascript
/**
@@ -291,7 +294,7 @@ module.exports = {
### ステップ14: コントラクトをコンパイルする {#step-14-compile-our-contract}
-ここまででしっかりと動作していることを確認するため、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みのHardhatタスクの1つです。
+ここまでの作業がうまくいっていることを確認するために、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みのHardhatタスクの1つです。
コマンドラインで以下を実行します。
@@ -299,19 +302,19 @@ module.exports = {
npx hardhat compile
```
-`SPDX license identifier not provided in source file`という警告が表示される場合がありますが、心配する必要はありません。警告が表示されないのがベストですが、 表示された場合は、いつでも[Alchemy discord](https://discord.gg/u72VCg3)でメッセージを送信できます。
+`SPDX license identifier not provided in source file` という警告が表示されるかもしれませんが、心配する必要はありません。それ以外はすべて問題ないはずです! うまくいかない場合は、いつでも[Alchemy Discord](https://discord.gg/u72VCg3)でメッセージを送ることができます。
-### ステップ15: デプロイスクリプトを書く {#step-15-write-our-deploy-script}
+### ステップ15: デプロイスクリプトを作成する {#step-15-write-our-deploy-script}
コントラクトの作成と設定ファイルの作成が完了したら、いよいよコントラクトのデプロイのためのスクリプトを作成します。
-`scripts/`フォルダに移動して、`deploy.js`という名前のファイルを新規に作成し、以下の内容を追加します。
+`scripts/`フォルダに移動して`deploy.js`という名前の新しいファイルを作成し、次の内容を追加します:
```javascript
async function main() {
const HelloWorld = await ethers.getContractFactory("HelloWorld")
- // Start deployment, returning a promise that resolves to a contract object
+ // デプロイを開始し、コントラクトオブジェクトに解決されるpromiseを返す
const hello_world = await HelloWorld.deploy("Hello World!")
console.log("Contract deployed to address:", hello_world.address)
}
@@ -324,23 +327,23 @@ main()
})
```
-Hardhatがコードの各行で行っている驚くべき内容については、Hardhatの[コントラクトチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で説明されています。以下では、その説明を採用しています。
+Hardhatは、[コントラクトのチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で、これらのコードの各行が何をするかを非常にうまく説明しています。ここではその説明を採用しました。
```javascript
const HelloWorld = await ethers.getContractFactory("HelloWorld")
```
-ethers.jsの`ContractFactory`は新しいスマートコントラクトをデプロイするための抽象化であり、ここでの`HelloWorld`はhello worldコントラクトのインスタンスのための[ファクトリ](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming))です。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`および`Contract`インスタンスはデフォルトで最初の署名者 (所有者) に接続されます。
+ethers.jsの `ContractFactory` は、新しいスマートコントラクトをデプロイするために使用される抽象化です。したがって、ここでの `HelloWorld` は、私たちのhello worldコントラクトのインスタンスのための[ファクトリ](https://en.wikipedia.org/wiki/Factory_\(object-oriented_programming\))です。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`と`Contract`のインスタンスは、デフォルトで最初の署名者 (所有者) に接続されます。
```javascript
const hello_world = await HelloWorld.deploy()
```
-`ContractFactory`で`deploy()`を呼び出すとデプロイメントが開始され、`Contract`オブジェクトに解決すべき`Promise`が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。
+`ContractFactory`で`deploy()`を呼び出すとデプロイが開始され、`Contract`オブジェクトに解決される`Promise`が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。
### ステップ16: コントラクトをデプロイする {#step-16-deploy-our-contract}
-ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、以下を実行します。
+ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、次を実行します:
```bash
npx hardhat run scripts/deploy.js --network goerli
@@ -349,34 +352,34 @@ npx hardhat run scripts/deploy.js --network goerli
次のような画面が表示されるはずです。
```bash
-Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
+コントラクトがデプロイされたアドレス: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
```
-**このアドレスを保存してください**。 このアドレスをチュートリアルの後半で使用します。
+**このアドレスを保存してください**。 このアドレスはチュートリアルの後半で使用します。
-[Goerli etherscan](https://goerli.etherscan.io)に移動し、コントラクトアドレスを検索すると、コントラクトが正常にデプロイされていることを確認できるはずです。 トランザクションは以下のようなものになります。
+[Goerli etherscan](https://goerli.etherscan.io) にアクセスしてコントラクトアドレスを検索すると、正常にデプロイされたことを確認できるはずです。 トランザクションは以下のようなものになります。

-`From`アドレスはMetaMaskアカウントのアドレスと一致し、`To`アドレスは「**Contract Creation**」と表示されます。 トランザクション内容をクリックすると、`To`フィールドにコントラクトアドレスが表示されます.
+`From`アドレスはMetaMaskアカウントのアドレスと一致し、`To`アドレスには**Contract Creation**と表示されます。 トランザクションをクリックすると、`To`フィールドにコントラクトアドレスが表示されます。

-おめでとうございます! イーサリアムのテストネットにスマートコントラクトをデプロイできました.
+おめでとうございます! Ethereumテストネットにスマートコントラクトをデプロイできました。
-内部で何が起こっているのかを理解するために、[Alchemyダッシュボード](https://dashboard.alchemyapi.io/explorer)のExplorerタブに移動してみましょう。 Alchemyのアプリが複数ある場合は、必ずアプリでフィルタリングし、「**Hello World**」を選択してください。
+内部で何が起こっているのかを理解するために、[Alchemyダッシュボード](https://dashboard.alchemy.com/explorer)のExplorerタブに移動してみましょう。 複数のAlchemyアプリをお持ちの場合は、必ずアプリでフィルタリングし、**Hello World**を選択してください。

-ここでは、`.deploy()`関数を呼び出した際に、HardhatもしくはEthersが内部で行ったJSON-RPCメソッドを見ることができます。 ここで2つの重要なメソッドがあります。まずは、[`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction)です。これは、Goerliチェーンにコントラクトを書き込むリクエストです。次に[`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash)は、ハッシュを指定してトランザクションに関する情報を読み取るリクエストです。 トランザクションの送信の詳細については、[こちら](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)のチュートリアルにあるWeb3を使用したトランザクションの送信をご覧ください。
+ここでは、`.deploy()`関数を呼び出した際に、Hardhat/Ethersが内部で行ったいくつかのJSON-RPCメソッドを見ることができます。 ここでの2つの重要なメソッドは、コントラクトをGoerliチェーンに書き込むリクエストである [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) と、ハッシュが与えられたトランザクションに関する情報を読み取るリクエストである [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash) です。 トランザクションの送信についてさらに詳しく知るには、[Web3を使用したトランザクション送信に関するチュートリアル](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)を確認してください。
-## パート2: スマートコントラクトとのやり取り {#part-2-interact-with-your-smart-contract}
+## パート2: スマートコントラクトとインタラクトする {#part-2-interact-with-your-smart-contract}
スマートコントラクトをGoerliネットワークに正常にデプロイできました。それでは、スマートコントラクトとやり取りする方法について学びましょう。
-### interact.jsファイルの作成 {#create-a-interactjs-file}
+### interact.jsファイルを作成する {#create-a-interactjs-file}
-このファイルに、やり取りするスクリプトを記述します。 パート1でインストールしたEthers.jsライブラリを使用します。
+このファイルに、インタラクトするスクリプトを記述します。 パート1でインストールしたEthers.jsライブラリを使用します。
`scripts/`フォルダ内に、`interact.js`という名前の新しいファイルを作成し、次のコードを追加します。
@@ -388,9 +391,9 @@ const PRIVATE_KEY = process.env.PRIVATE_KEY
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
```
-### .envファイルの更新 {#update-your-env-file}
+### .envファイルを更新する {#update-your-env-file}
-新しい環境変数を使用します。そのため、[以前に作成した](#step-11-connect-metamask-&-alchemy-to-your-project)`.env`ファイルに定義する必要があります。
+新しい環境変数を使用するため、[以前に作成した](#step-11-connect-metamask-&-alchemy-to-your-project)`.env`ファイルに定義する必要があります。
Alchemyの`API_KEY`とスマートコントラクトがデプロイされている`CONTRACT_ADDRESS`の定義を加える必要があります。
@@ -407,14 +410,14 @@ CONTRACT_ADDRESS = "0x"
### コントラクトABIを取得する {#grab-your-contract-ABI}
-コントラクト[ABI(アプリケーションバイナリインターフェイス)](/glossary/#abi)は、スマートコントラクトと対話するためのインターフェイスです。 Hardhatは自動的にABIを生成して、`HelloWorld.json`ファイルに保存します。 ABIを使うには、`interact.js`ファイルに次のコードを追加して、コンテンツをパースする必要があります。
+コントラクトの[ABI (アプリケーションバイナリインターフェイス)](/glossary/#abi)は、スマートコントラクトとインタラクトするためのインターフェイスです。 Hardhatは自動的にABIを生成して、`HelloWorld.json`ファイルに保存します。 ABIを使うには、`interact.js`ファイルに次のコードを追加して、コンテンツをパースする必要があります。
```javascript
// interact.js
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
```
-ABIを表示したい場合は、次のコードを追加することでコンソールに出力できます:
+ABIを確認したい場合は、コンソールに出力できます:
```javascript
console.log(JSON.stringify(contract.abi))
@@ -428,13 +431,13 @@ npx hardhat run scripts/interact.js
### コントラクトのインスタンスを作成する {#create-an-instance-of-your-contract}
-コントラクトを操作するには、コード内にコントラクトのインスタンスを作成する必要があります。 Ethers.jsでこれを行うには、次の3つのコンセプトを機能させる必要があります。
+コントラクトを操作するには、コード内にコントラクトのインスタンスを作成する必要があります。 Ethers.jsでこれを行うには、次の3つのコンセプトを扱う必要があります。
1. Provider - ブロックチェーンへの読み取りおよび書き込みアクセスを提供するノードプロバイダです。
-2. Signer - トランザクションに署名するイーサリアムアカウントを表します。
+2. Signer - トランザクションに署名するEthereumアカウントを表します。
3. Contract - オンチェーンにデプロイされた特定のコントラクトを表すEthers.jsのオブジェクトです。
-前の手順で取得したコントラクABIを使って、コントラクトのインスタンスを作成します。
+前の手順で取得したコントラクトABIを使って、コントラクトのインスタンスを作成します。
```javascript
// interact.js
@@ -458,11 +461,11 @@ const helloWorldContract = new ethers.Contract(
Provider、Signer、Contractの詳細については、[ethers.jsドキュメント](https://docs.ethers.io/v5/)をご覧ください。
-### initメッセージの読み取り {#read-the-init-message}
+### initメッセージを読み込む {#read-the-init-message}
-`initMessage = "Hello world!"`を使用してコントラクトをデプロイしたことを思い出せますでしょうか? ここでは、スマートコントラクトに保存されているメッセージを読み取り、コンソールに出力します。
+`initMessage = "Hello world!"`を使用してコントラクトをデプロイしたことを覚えていますか? ここでは、スマートコントラクトに保存されているメッセージを読み取り、コンソールに出力します。
-JavaScriptでは、ネットワークとのやり取りで非同期関数を使います。 非同期関数の詳細については、[この記事の中ほど](https://blog.bitsrc.io/Understanding-asynchronous-javascript-the-event-loop-74cd408419ff)をご覧ください。
+JavaScriptでは、ネットワークとのインタラクトで非同期関数を使います。 非同期関数についてさらに詳しく知るには、[このmediumの記事](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff)をお読みください。
以下のコードを使用して、スマートコントラクトの`message`関数を呼び出し、initメッセージを読み取ります。
@@ -478,19 +481,19 @@ async function main() {
main()
```
-ターミナルで`npx hardware run scripts/interact.js`を入力してファイルを実行すると、次のレスポンスが表示されるはずです。
+ターミナルで `npx hardhat run scripts/interact.js` を使用してファイルを実行すると、次のようなレスポンスが表示されます。
```
The message is: Hello world!
```
-おめでとうございます! イーサリアムブロックチェーンからスマートコントラクトのデータを正常に読み取ることができました。
+おめでとうございます! Ethereumブロックチェーンからスマートコントラクトのデータを正常に読み取ることができました。お見事!
-### メッセージの更新 {#update-the-message}
+### メッセージを更新する {#update-the-message}
-メッセージを読み取るだけでなく、`update`関数を使ってスマートコントラクトに保存されたメッセージを更新することもできます。 かなりイケてますよね?
+メッセージを読み取るだけでなく、`update`関数を使ってスマートコントラクトに保存されたメッセージを更新することもできます。 かなりクールでしょう?
-メッセージを更新するには、インスタンス化されたコントラクトのオブジェクトで`update`関数を直接呼び出します。
+メッセージを更新するには、インスタンス化されたContractオブジェクトで`update`関数を直接呼び出します。
```javascript
// interact.js
@@ -508,13 +511,13 @@ async function main() {
main()
```
-11行目で、返されたトランザクションのオブジェクトに対して `.wait()`を呼び出していることに注目してください。 これにより、スクリプトが関数を終了する前に、トランザクションがブロックチェーン上でマイニングされるまで待機することを確実にします。 `.wait()`を呼び出しを含めなかった場合、スクリプトは、コントラクト内で更新された`message`の値を表示しないことがあります。
+11行目で、返されたトランザクションオブジェクトに対して `.wait()` を呼び出していることに注目してください。 これにより、スクリプトが関数を終了する前に、トランザクションがブロックチェーン上でマイニングされるまで待機することが保証されます。 `.wait()` の呼び出しを含めなかった場合、スクリプトは、コントラクト内で更新された `message` の値を表示しないことがあります。
-### 新しいメッセージの読み取り {#read-the-new-message}
+### 新しいメッセージを読み込む {#read-the-new-message}
-[前の手順](#read-the-init-message)を繰り返して、更新された`message`の値を読み取ることができるのに違いありません。 その新しい値を出力するために必要となる変更を、少し考えてみましょう!
+[前の手順](#read-the-init-message)を繰り返して、更新された `message` の値を読み取ることができるはずです。 少し時間を取って、新しい値を表示するために必要な変更を加えられるか試してみましょう!
-ヒントが必要ですか?この時点で、あなたの`interact.js`ファイルは次のようになるはずです。
+ヒントが必要な場合は、この時点で`interact.js`ファイルがどのようになるかを示します。
```javascript
// interact.js
@@ -556,7 +559,7 @@ async function main() {
main()
```
-このスクリプトを実行するだけで、古いメッセージ、更新ステータス、および新しいメッセージがコンソールに出力されるのを確認できるはずです。
+このスクリプトを実行するだけで、古いメッセージ、更新ステータス、および新しいメッセージがターミナルに出力されるのを確認できるはずです。
`npx hardhat run scripts/interact.js --network goerli`
@@ -566,29 +569,29 @@ Updating the message...
The new message is: This is the new message.
```
-このスクリプトの実行中、新しいメッセージが読み込まれる前に、 `Updating the message...`のステップの読み込みにしばらく時間がかかることに気づくかもしれません。 これはマイニングプロセスによるものです。マイニング中のトランザクションの追跡に興味があるならば、[Alchemy mempool](https://dashboard.alchemyapi.io/mempool)にアクセスしてトランザクションのステータスを確認できます。 トランザクションがドロップされた場合は、[Goerli Etherscan](https://goerli.etherscan.io)を確認してトランザクションのハッシュを検索することもできます。
+このスクリプトの実行中、新しいメッセージが読み込まれる前に、 `Updating the message...` のステップの読み込みにしばらく時間がかかることに気づくかもしれません。 これはマイニングプロセスによるものです。マイニング中のトランザクションの追跡に興味があるならば、[Alchemyメンプール](https://dashboard.alchemyapi.io/mempool)にアクセスしてトランザクションのステータスを確認できます。 トランザクションがドロップされた場合は、[Goerli Etherscan](https://goerli.etherscan.io) を確認してトランザクションハッシュを検索することも役立ちます。
## パート3: スマートコントラクトをEtherscanに公開する {#part-3-publish-your-smart-contract-to-etherscan}
-あなたは、スマートコントラクトに命を吹き込むことに大変な努力をしました。それでは、その努力を世界に共有しましょう!
+あなたは、スマートコントラクトに命を吹き込むために大変な努力をしました。さあ、その成果を世界に共有しましょう!
-Etherscanでスマートコントラクトを検証すると、誰でもソースコードを表示して、あなたのスマートコントラクトとやり取りできるようになります。 さあ、始めましょう!
+Etherscanでスマートコントラクトを検証すると、誰でもソースコードを表示して、あなたのスマートコントラクトとインタラクトできるようになります。 さあ、始めましょう!
### ステップ1: EtherscanアカウントでAPIキーを生成する {#step-1-generate-an-api-key-on-your-etherscan-account}
EtherscanのAPIキーは、公開しようとしているスマートコントラクトを所有していることを確認するために必要になります。
-Etherscanアカウントをお持ちでない場合は、[アカウントの登録](https://etherscan.io/register)をしてください。
+Etherscanアカウントをお持ちでない場合は、[アカウントにサインアップ](https://etherscan.io/register)してください。
-ログインしたら、ナビゲーションバーでユーザー名を見つけ、その上にマウスを移動して、「**My profile**」ボタンを選択します。
+ログインしたら、ナビゲーションバーでユーザー名を見つけ、その上にカーソルを合わせて **My profile** ボタンを選択します。
-プロフィールページにサイドナビゲーションバーが表示されます。 サイドナビゲーションバーで、**API Keys**を選択します。 次に、「Add」ボタンを押して新しいAPIキーを作成し、アプリに**hello-world**という名前を付けて、「**Create New API**」ボタンを押します。
+プロフィールページにサイドナビゲーションバーが表示されます。 サイドナビゲーションバーで、**API Keys**を選択します。 次に、「Add」ボタンを押して新しいAPIキーを作成し、アプリに **hello-world** という名前を付けて、「**Create New API Key**」ボタンを押します。
新しいAPIキーがAPIキーテーブルに表示されるはずです。 APIキーをクリップボードにコピーします。
次に、EtherscanのAPIキーを`.env`ファイルに加える必要があります。
-そうすると、`.env`ファイルは次のようになります。
+追加した後、`.env`ファイルは次のようになります。
```javascript
API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
@@ -598,17 +601,17 @@ CONTRACT_ADDRESS = "your-contract-address"
ETHERSCAN_API_KEY = "your-etherscan-key"
```
-### Hardhatにデプロイされたスマートコントラクト {#hardhat-deployed-smart-contracts}
+### Hardhatでデプロイされたスマートコントラクト {#hardhat-deployed-smart-contracts}
-#### hardhat-etherscanのインストール {#install-hardhat-etherscan}
+#### hardhat-etherscanをインストールする {#install-hardhat-etherscan}
-あなたのコントラクトをEtherscanへ公開するのは、Hardhatを使って簡単にできます。 はじめに、まず`hardhat-etherscan`プラグインをインストールしてください。 `hardhat-etherscan`は、スマートコントラクトのソースコードとEtherscan上のABIを自動的に検証します。 インストールするには、`hello-world`ディレクトリで次のコマンドを実行します。
+Hardhatを使ってコントラクトをEtherscanへ公開するのは簡単です。 まず、`hardhat-etherscan`プラグインをインストールする必要があります。 `hardhat-etherscan`は、スマートコントラクトのソースコードとEtherscan上のABIを自動的に検証します。 インストールするには、`hello-world`ディレクトリで次のコマンドを実行します。
```text
npm install --save-dev @nomiclabs/hardhat-etherscan
```
-インストールをしたら、`hardhat.config.js`の先頭に次のステートメントを含んだEtherscan構成オプションを追加します。
+インストールしたら、`hardhat.config.js`の先頭に次のステートメントを含め、Etherscanの構成オプションを追加します。
```javascript
// hardhat.config.js
@@ -630,14 +633,14 @@ module.exports = {
},
},
etherscan: {
- // Your API key for Etherscan
- // Obtain one at https://etherscan.io/
+ // Etherscan用のAPIキー
+ // https://etherscan.io/ で取得
apiKey: ETHERSCAN_API_KEY,
},
}
```
-#### Etherscan上でスマートコントラクトを検証する {#verify-your-smart-contract-on-etherscan}
+#### Etherscanでスマートコントラクトを検証する {#verify-your-smart-contract-on-etherscan}
すべてのファイルが保存され、すべての`.env`変数が正しく構成されていることを確認してください。
@@ -647,9 +650,9 @@ module.exports = {
npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!'
```
-`DEPLOYED_CONTRACT_ADDRESS`がGoerliテストネットワーク上にデプロイされたスマートコントラクトのアドレスであることを確認してください。 また、最後の引数 (`'Hello World!'`) は、 [パート1のデプロイ手順](#write-our-deploy-script)で使われたの文字列値と同じでなければなりません。
+`DEPLOYED_CONTRACT_ADDRESS`がGoerliテストネットワーク上にデプロイされたスマートコントラクトのアドレスであることを確認してください。 また、最後の引数(`'Hello World!'`)は、[パート1のデプロイスクリプト作成手順](#write-our-deploy-script)で使用した文字列値と同じでなければなりません。
-順調に行けば、コンソールに次のメッセージが表示されます。
+すべてが順調に進めば、ターミナルに次のメッセージが表示されます。
```text
Successfully submitted source code for contract
@@ -661,69 +664,69 @@ Successfully verified contract HelloWorld on Etherscan.
https://goerli.etherscan.io/address/#contracts
```
-おめでとうございます! これで、あなたのスマートコントラクトコードは、Etherscan上にあります。
+おめでとうございます! これで、あなたのスマートコントラクトコードはEtherscan上にあります。
-### Etherscanであなたのスマートコントラクトを確認する {#check-out-your-smart-contract-on-etherscan}
+### Etherscanであなたのスマートコントラクトを確認しましょう! {#check-out-your-smart-contract-on-etherscan}
-コンソールに表示されているリンクに移動すると、Etherscanで公開されているスマートコントラクトコードとABIが表示されます。
+ターミナルに表示されているリンクに移動すると、Etherscanで公開されているスマートコントラクトコードとABIが表示されます。
-**ヤッホー!栄冠を手にしました。 これで、誰でもスマートコントラクトを呼び出したり、書き込んだりできるようになりました。 次にあなたが何を構築するか楽しみにしています。**
+**ヤッター!やりましたね! これで、誰でもスマートコントラクトを呼び出したり、書き込んだりできるようになりました。 次にあなたが何を構築するか楽しみにしています。**
-## パート4: フロントエンドとスマートコントラクトの統合 {#part-4-integrating-your-smart-contract-with-the-frontend}
+## パート4 - スマートコントラクトをフロントエンドと統合する {#part-4-integrating-your-smart-contract-with-the-frontend}
このチュートリアルを終えると、次の方法がわかるようになります。
- MetaMaskウォレットをdappに接続する
-- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) APIを使用してスマートコントラクトからデータを読み取る。
-- MetaMaskを使用してイーサリアムトランザクションに署名する
+- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) APIを使用してスマートコントラクトからデータを読み取る
+- MetaMaskを使用してEthereumトランザクションに署名する
-このdappでは、フロントエンドフレームワークで[React](https://reactjs.org/)を使っていますが、Web3の機能をプロジェクトに導入することに焦点を当てているので、Reactの基本を説明することに多くの時間を費やさないことに注意してください。
+このdappでは、フロントエンドフレームワークとして[React](https://react.dev/)を使用します。ただし、このプロジェクトではWeb3機能を導入することに主に焦点を当てているため、Reactの基礎を詳しく説明する時間はあまりかけない点に注意してください。
-前提条件として、Reactについて初心者レベルの理解をしている必要があります。 知らなければ、公式の[React入門チュートリアル](https://reactjs.org/tutorial/tutorial.html)を読むことをお勧めします。
+前提条件として、Reactについて初心者レベルの理解をしている必要があります。 そうでない場合は、公式の[React入門チュートリアル](https://react.dev/learn)を完了することをお勧めします。
-### スターターファイルのクローン {#clone-the-starter-files}
+### スターターファイルをクローンする {#clone-the-starter-files}
-まず、このプロジェクトの開始ファイルを取得するために[「hello-world-part-four」GitHubリポジトリ](https://github.com/alchemyplatform/hello-world-part-four-tutorial)に行き、このリポジトリのクローンをローカルマシンに作成します。
+まず、[hello-world-part-four GitHubリポジトリ](https://github.com/alchemyplatform/hello-world-part-four-tutorial)にアクセスして、このプロジェクトのスターターファイルを取得し、このリポジトリをローカルマシンにクローンします。
-クローンしたリポジトリをローカルで開きます。 `starter-files`と`completed`の2つのフォルダが含まれています。
+クローンしたリポジトリをローカルで開きます。 `starter-files`と`completed`の2つのフォルダが含まれていることに注意してください。
-- `starter-files` - **このディレクトリで作業します**。UIをイーサリアムウォレットおよび[パート3](#part-3)でEtherscanに公開したスマートコントラクトに接続します。
+- `starter-files` - **このディレクトリで作業します**。UIをEthereumウォレットおよび[パート3](#part-3)でEtherscanに公開したスマートコントラクトに接続します。
- `completed`には、チュートリアル全体が完了したものが入っています。行き詰まった場合にのみ、参考として使ってください。
次に、`starter-files`のコピーをお気に入りのコードエディタで開き、`src`フォルダに移動します。
-これから作成するすべてのコードは、`src`フォルダに保存されます。 `HelloWorld.js`コンポーネントと JavaScriptファイルである`util/interact.js`を編集して、プロジェクトにWeb3の機能を追加していきます。
+私たちが書くコードはすべて`src`フォルダの下に置かれます。 `HelloWorld.js`コンポーネントと`util/interact.js`JavaScriptファイルを編集して、プロジェクトにWeb3機能を追加します。
-### スターターファイルの確認 {#check-out-the-starter-files}
+### スターターファイルを確認する {#check-out-the-starter-files}
コーディングを開始する前に、スターターファイルで提供されるものを探索してみましょう。
-#### Reactプロジェクトの実行 {#get-your-react-project-running}
+#### Reactプロジェクトを実行する {#get-your-react-project-running}
まずは、ブラウザでReactプロジェクトを実行しましょう。 Reactの素晴らしいところは、一度ブラウザでプロジェクトを実行すると、保存した変更がブラウザでも同時に更新されることです。
-プロジェクトを実行するには、次のようにターミナルで`starter-files`フォルダのルートディレクトリに移動し、`npm install`を実行してプロジェクトの依存関係をインストールします。
+プロジェクトを実行するには、`starter-files`フォルダのルートディレクトリに移動し、ターミナルで`npm install`を実行してプロジェクトの依存関係をインストールします。
```bash
cd starter-files
npm install
```
-インストールが完了したら、ターミナルで`npm start`を実行します。
+インストールが完了したら、ターミナルで`npm start`を実行します:
```bash
npm start
```
-これにより、ブラウザで[http://localhost:3000/](http://localhost:3000/)を開くと、プロジェクトのフロントエンドが表示されます。 これは、1つのフィールド \(スマートコントラクトに保存されているメッセージを更新する場所\) である「Connect Wallet」ボタン、および「Update」ボタンで構成されています。
+これにより、ブラウザで[http://localhost:3000/](http://localhost:3000/)が開かれ、プロジェクトのフロントエンドが表示されます。 これは、1つのフィールド \(スマートコントラクトに保存されているメッセージを更新する場所\)、「Connect Wallet」ボタン、および「Update」ボタンで構成されています。
-どちらのボタンをクリックしても、機能しないことがわかります。この機能をプログラムする必要があるためです。
+どちらのボタンをクリックしても機能しないことに気づくでしょう。これは、まだその機能をプログラムする必要があるためです。
#### `HelloWorld.js`コンポーネント {#the-helloworld-js-component}
エディタの`src`フォルダに戻り、`HelloWorld.js`ファイルを開きましょう。 このファイルには、これから作業を進めていく主要なReactコンポーネントが含まれています。すべての内容を理解することが非常に重要です。
-このファイルの先頭には、いくつかの重要なステートメントがあるこに気が付くでしょう。Reactライブラリ、useEffectフックとuseStateフック、`./util/interact.js`のいくつかのアイテムなど、プロジェクトを実行するために必要になります (これらについては、すぐに詳しく説明します!) 。また、Alchemyのロゴがあります
+このファイルの先頭には、プロジェクトを実行するために必要な、Reactライブラリ、useEffectフックとuseStateフック、`./util/interact.js`からのいくつかのアイテム (これらについては、すぐに詳しく説明します!)、そしてAlchemyのロゴなど、いくつかのimport文があることに気づくでしょう。
```javascript
// HelloWorld.js
@@ -753,14 +756,14 @@ const [message, setMessage] = useState("No connection to the network.")
const [newMessage, setNewMessage] = useState("")
```
-それぞれの変数は以下の用途で使われます。
+それぞれの変数は以下の内容を表します。
- `walletAddress` - ユーザーのウォレットアドレスを格納する文字列
-- `status` - ユーザーにdappの操作方法を案内する補助メッセージを文字列として格納する
+- `status`- ユーザーにdappのインタラクト方法を案内する補助メッセージを格納する文字列
- `message` - スマートコントラクトの現在のメッセージを格納する文字列
- `newMessage` - スマートコントラクトに書き込まれる新しいメッセージを格納する文字列
-ステート変数の後に、`useEffect` 、`addSmartContractListener`、 `addWalletListener`、 `connectWalletPressed`、`onUpdatePressed`の未実装の5つの関数があります。 次に、それらが何をするのかを説明します。
+ステート変数の後に、`useEffect`、`addSmartContractListener`、`addWalletListener`、`connectWalletPressed`、`onUpdatePressed`の5つの未実装の関数があります。 次に、それらが何をするのかを説明します。
```javascript
// HelloWorld.js
@@ -787,10 +790,10 @@ const onUpdatePressed = async () => {
}
```
-- [`useEffect`](https://reactjs.org/docs/hooks-effect.html)- コンポーネントがレンダリングされた後に呼び出されるReactフックです。 空の配列`[]`のプロップが渡されているため \(4行目を参照\)、コンポーネントの_最初_のレンダリングでのみ呼び出されます。 ここでは、スマートコントラクトに保存されている現在のメッセージのロード、スマートコントラクトとウォレットリスナーの呼び出し、ウォレットが既に接続されているかどうかを反映してUIを更新するのに使います。
+- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html) - これは、コンポーネントがレンダリングされた後に呼び出されるReactフックです。 空の配列`[]`のプロップが渡されているため \(4行目を参照\)、コンポーネントの_最初の_レンダリングでのみ呼び出されます。 ここでは、スマートコントラクトに保存されている現在のメッセージをロードし、スマートコントラクトとウォレットリスナーを呼び出し、ウォレットが既に接続されているかどうかを反映してUIを更新します。
- `addSmartContractListener` - この関数では、HelloWorldコントラクトの`UpdatedMessages`イベントを監視し、スマートコントラクトでメッセージが変更されたときにUIを更新するリスナーを設定します。
- `addWalletListener` - この関数では、ユーザーがウォレットを切断したときやアドレスを切り替えたときなど、ユーザーのMetaMaskウォレットのステートの変化を検出するリスナーを設定します。
-- `connectWalletPressed` - この関数は、ユーザーのMetaMaskウォレットをdappに接続するのに呼び出されます。
+- `connectWalletPressed`- この関数は、ユーザーのMetaMaskウォレットをdappに接続するのに呼び出されます。
- `onUpdatePressed` - この関数は、ユーザーがスマートコントラクトに保存されているメッセージを更新したいときに呼び出されます。
このファイルの終盤には、コンポーネントのUIがあります。
@@ -830,32 +833,33 @@ return (
-
-
+
+
+
)
```
このコードを注意深く読むと、さまざまなステート変数がUIのどの場所で使用されているかがわかります。
-- 6~12行目では、ユーザーのウォレットが接続されている場合 \(すなわち、`walletAddress.length > 0`\)、 ID「walletButton;」に省略されたユーザーの`walletAddress`がボタンに表示されます。 それ以外の場合は、単に「Connect Wallet」と表示されます。
+- 6~12行目では、ユーザーのウォレットが接続されている場合 \(すなわち`walletAddress.length > 0`\)、ID「walletButton」のボタンに省略されたユーザーの`walletAddress`が表示されます。それ以外の場合は、単に「Connect Wallet」と表示されます。
- 17行目では、`message`文字列でキャプチャされたスマートコントラクトに保存されている現在のメッセージを表示します。
-- 23~26行目では、テキストフィールドの入力が変化したときに[制御コンポーネント](https://reactjs.org/docs/forms.html#controlled-components)を使用して `newMessage`ステート変数を更新します。
+- 23~26行目では、[制御されたコンポーネント](https://legacy.reactjs.org/docs/forms.html#controlled-components)を使用して、テキストフィールドの入力が変化したときに`newMessage`ステート変数を更新します。
-ステート変数に加えて、IDが`publishButton`と`walletButton`である、それぞれがクリックされると`connectWalletPressed`および`onUpdatePressed`関数が呼び出されることがわります。
+ステート変数に加えて、IDが`publishButton`と`walletButton`であるボタンがそれぞれクリックされると、`connectWalletPressed`および`onUpdatePressed`関数が呼び出されることがわかります。
最後に、この`HelloWorld.js`コンポーネントがどこに加えられるかについて説明します。
-他のすべてのコンポーネントのコンテナとして機能する、Reactのメインコンポーネントである`App.js`ファイルを表示すると、`HelloWorld.js`コンポーネントが7行目に挿入されていることが分かります。
+`App.js`ファイルは、他のすべてのコンポーネントのコンテナとして機能するReactのメインコンポーネントですが、このファイルを表示すると、`HelloWorld.js`コンポーネントが7行目に挿入されていることが分かります。
-最後の最後となりますが、提供されているもう1つのファイル、`interact.js`ファイルを確認してみましょう。
+最後に、提供されているもう1つのファイル、`interact.js`ファイルを確認してみましょう。
#### `interact.js`ファイル {#the-interact-js-file}
-[M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)のパラダイムを実践したいので、dappのロジック、データ、ルールを管理するすべての関数を含んだファイルを分割し、これらの関数をフロントエンド \(`HelloWorld.js`コンポーネント\) にエクスポートできるようにします。
+[M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)パラダイムに従うため、dappのロジック、データ、ルールを管理するすべての関数を含む個別のファイルを作成し、それらの関数をフロントエンド \(私たちの`HelloWorld.js`コンポーネント\) にエクスポートできるようにします。
-👆🏽まさにこれが`interact.js`ファイルの目的です。
+👆🏽まさにこれが`interact.js`ファイルの目的です!
-`src`ディレクトリの`util`フォルダに移動すると、`interact.js`というファイルが含まれていることがわかります。これには、スマートコントラクトとのやり取り、ウォレット関数と変数が含まれています。
+`src`ディレクトリの`util`フォルダに移動すると、`interact.js`というファイルが含まれていることがわかります。これには、すべてのスマートコントラクトとのインタラクション、ウォレット関数、変数が含まれています。
```javascript
// interact.js
@@ -875,35 +879,35 @@ export const updateMessage = async (message) => {}
`helloWorldContract`オブジェクトの後の4つの未実装の関数は、次のことを行います。
-- `loadCurrentMessage` - この関数は、スマートコントラクトに保存されている現在のメッセージをロードするロジックを扱います。 [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3)を使ってHello Worldスマートコントラクトの_read_の呼び出しを行います。
-- `connectWallet` - この関数は、私たちのdappをユーザーのMetaMaskに接続します。
-- `getCurrentWalletConnected` - この関数は、ページの読み込み時にイーサリアムアカウントが既にdappに接続されているかどうかを確認し、それに応じてUIを更新します。
-- `updateMessage` - この関数は、スマートコントラクトに保存されているメッセージを更新します。 Hello Worldスマートコントラクトで_write_の呼び出しが行われるため、ユーザーのMetaMaskウォレットでは、メッセージを更新するためにイーサリアムトランザクションに署名する必要があります。
+- `loadCurrentMessage` - この関数は、スマートコントラクトに保存されている現在のメッセージをロードするロジックを扱います。 [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3)を使用して、Hello Worldスマートコントラクトへの_読み取り_呼び出しを行います。
+- `connectWallet` - この関数は、ユーザーのMetaMaskをdappに接続します。
+- `getCurrentWalletConnected` - この関数は、ページの読み込み時にEthereumアカウントが既にdappに接続されているかどうかを確認し、それに応じてUIを更新します。
+- `updateMessage` - この関数は、スマートコントラクトに保存されているメッセージを更新します。 Hello Worldスマートコントラクトで_書き込み_呼び出しが行われるため、ユーザーのMetaMaskウォレットでは、メッセージを更新するためにEthereumトランザクションに署名する必要があります。
何をするか理解したので、スマートコントラクトから読み取る方法を解明していきましょう。
-### ステップ3: スマートコントラクトからの読み込み {#step-3-read-from-your-smart-contract}
+### ステップ3: スマートコントラクトから読み取る {#step-3-read-from-your-smart-contract}
スマートコントラクトから読み取るには、次の設定を正しく行う必要があります。
-- イーサリアムチェーンへのAPI接続
-- あなたのスマートコントラクトがロードされたインスタンス
+- EthereumチェーンへのAPI接続
+- スマートコントラクトのロードされたインスタンス
- スマートコントラクトの関数を呼び出す関数
- スマートコントラクトから読み取っているデータが変更されたときの更新を監視するリスナー
-手順がたくさんあるように感じますが、心配しないでください! それぞれの方法を1つずつ説明していきます。 :\)
+手順がたくさんあるように感じますが、心配しないでください! それぞれの方法を1つずつ説明していきます。 :)
-#### イーサリアムチェーンへのAPI接続を確立する {#establish-an-api-connection-to-the-ethereum-chain}
+#### EthereumチェーンへのAPI接続を確立する {#establish-an-api-connection-to-the-ethereum-chain}
-チュートリアルのパート2で私たちは、[Alchemy Web3キーを使ってスマートコントラクトから読み込みました](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)。 チェーンから読み取るには、あなたのdappでAlchemy Web3キーがまた必要になります。
+このチュートリアルのパート2で、[Alchemy Web3キーを使用してスマートコントラクトから読み取った](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)ことを覚えていますか? チェーンから読み取るには、dappでAlchemy Web3キーも必要になります。
-もしなければ、最初に、 `starter-files`のルートディレクトリへ移動して、次のコマンドをコンソールで実行して[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)をインストールしてください。
+まだインストールしていない場合は、まず`starter-files`のルートディレクトリに移動し、ターミナルで次のコマンドを実行して[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)をインストールしてください。
```text
npm install @alch/alchemy-web3
```
-[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)は、[Web3.js](https://docs.web3js.org/)のラッパーであり、強化されたAPIメソッドや重要なメリットを提供し、Web3デベロッパーの負担を軽減します。 最小限の設定で使えるように設計されているので、アプリですぐに使用可能です。
+[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)は[Web3.js](https://docs.web3js.org/)のラッパーであり、強化されたAPIメソッドやその他の重要なメリットを提供し、web3開発者としての作業を容易にします。 最小限の設定で使えるように設計されているので、アプリですぐに使用可能です。
次に、[dotenv](https://www.npmjs.com/package/dotenv)パッケージをプロジェクトディレクトリにインストールします。これにより、APIキーを取得した後に安全な場所に保管できるようになります。
@@ -911,15 +915,15 @@ npm install @alch/alchemy-web3
npm install dotenv --save
```
-dappでは、HTTP API キーの代わりに**Websockets APIキー**を使用します。これにより、スマートコントラクトに保存されたメッセージが変更されたときに検出するリスナーを設定できます。
+dappでは、HTTP APIキーの代わりに**Websockets APIキーを使用します**。これにより、スマートコントラクトに保存されたメッセージが変更されたときに検出するリスナーを設定できます。
-APIキーを取得したら、ルートディレクトリに `.env`ファイルを作成し、Alchemy Websocketsの URLを.envファイルに加えます。 `.env`ファイルは次のようになります。
+APIキーを取得したら、ルートディレクトリに `.env`ファイルを作成し、Alchemy Websocketsの URLをそのファイルに追加します。 その後、`.env`ファイルは次のようになります。
```javascript
REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/
```
-これで、私たちのdappにAlchemy Web3エンドポイントを設定する準備が整いました。 `util`フォルダー内に入っている`interact.js`に戻り、ファイルの先頭に次のコードを加えてください。
+これで、dappにAlchemy Web3エンドポイントを設定する準備が整いました。 `util`フォルダー内に入っている`interact.js`に戻り、ファイルの先頭に次のコードを加えてください。
```javascript
// interact.js
@@ -932,23 +936,23 @@ const web3 = createAlchemyWeb3(alchemyKey)
//export const helloWorldContract;
```
-上記のコードでは、まず`.env`ファイルから Alchemyキーをインポートし、次に`alchemyKey`を`createAlchemyWeb3`に渡してAlchemy Web3エンドポイントへ確立しています。
+上記のコードでは、まず`.env`ファイルから Alchemyキーをインポートし、次に`alchemyKey`を`createAlchemyWeb3`に渡してAlchemy Web3エンドポイントを確立しています。
エンドポイントの準備できたので、スマートコントラクトをロードするときです!
#### Hello Worldスマートコントラクトをロードする {#loading-your-hello-world-smart-contract}
-Hello Worldスマートコントラクトをロードするには、そのコントラクトアドレスとABIが必要です。[このチュートリアルのパート3](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan)を終了していれば、両方ともEtherscanから入手できます。
+Hello Worldスマートコントラクトをロードするには、そのコントラクトアドレスとABIが必要です。これらは、[このチュートリアルのパート3](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan)を完了していれば、Etherscanで見つけることができます。
-#### EtherscanからコントラクトABIを入手する方法 {#how-to-get-your-contract-abi-from-etherscan}
+#### EtherscanからコントラクトABIを取得する方法 {#how-to-get-your-contract-abi-from-etherscan}
-このチュートリアルのパート3を飛ばした場合は、アドレス[0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code)にあるHelloWorldコントラクトを使ってください。 ABIは、[こちら](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code)にあります。
+このチュートリアルのパート3を飛ばした場合は、アドレス[0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code)のHelloWorldコントラクトを使用できます。 そのABIは[こちら](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code)で見つけることができます。
-コントラクトのABIは、コントラクトが呼び出す関数を指定し、関数が確実に意図しているフォーマットでデータを返すようにするために必要です。 コントラクトABIをコピーしたら、それを`contract-abi.json`という名前のJSONファイルとして`src`ディレクトリに保存しましょう。
+コントラクトのABIは、コントラクトが呼び出す関数を指定し、関数が期待するフォーマットでデータを確実に返すようにするために必要です。 コントラクトABIをコピーしたら、それを`contract-abi.json`という名前のJSONファイルとして`src`ディレクトリに保存しましょう。
contract-abi.jsonは、srcフォルダーに格納されている必要があります。
-コントラクトアドレス、ABI、Alchemy Web3エンドポイントを用意することで、[コントラクトメソッド](https://docs.web3js.org/api/web3-eth-contract/class/Contract)を使ってスマートコントラクトのインスタンスをロードすることができます。 コントラクトABIを`interact.js`ファイルにインポートし、コントラクトアドレスを加えます。
+コントラクトアドレス、ABI、Alchemy Web3エンドポイントを用意したので、[contractメソッド](https://docs.web3js.org/api/web3-eth-contract/class/Contract)を使ってスマートコントラクトのインスタンスをロードすることができます。 コントラクトABIを`interact.js`ファイルにインポートし、コントラクトアドレスを加えます。
```javascript
// interact.js
@@ -986,21 +990,19 @@ export const helloWorldContract = new web3.eth.Contract(
)
```
-私たちのコントラクトがロードされたので、`loadCurrentMessage`関数を実装できます!
+コントラクトがロードされたので、`loadCurrentMessage`関数を実装できます!
#### `interact.js`ファイルに`loadCurrentMessage`を実装する {#implementing-loadCurrentMessage-in-your-interact-js-file}
-これは非常にシンプルな関数です。 私たちのコントラクトから読み取るのに、単純な非同期のWeb3の呼び出しを作成します。 この関数では、スマートコントラクトに保存されているメッセージを返します。
+これは非常にシンプルな関数です。 コントラクトから読み取るために、単純な非同期のweb3呼び出しを作成します。 この関数では、スマートコントラクトに保存されているメッセージを返します。
-`interact.js`ファイルの `loadCurrentMessage`を次のように更新してください。
+// interact.jsexport const loadCurrentMessage = async () => {
+const message = await helloWorldContract.methods.message().call()
+return message
+}
```javascript
-// interact.js
-
-export const loadCurrentMessage = async () => {
- const message = await helloWorldContract.methods.message().call()
- return message
-}
+`interact.js`ファイルの `loadCurrentMessage`を次のように更新してください。
```
このスマートコントラクトをUIに表示したいので、`HelloWorld.js`コンポーネントの `useEffect`関数を次のように更新します。
@@ -1015,48 +1017,48 @@ useEffect(async () => {
}, [])
```
-`loadCurrentMessage`は、コンポーネントの最初のレンダリングで1回だけ呼び出されることに注目してください。 この後、`addSmartContractListener`を実装して、スマートコントラクト内のメッセージが変更された後にUIを自動的に更新できるようにします。
+注: `loadCurrentMessage`は、コンポーネントの最初のレンダリング時に1回だけ呼び出されるようにします。 この後、`addSmartContractListener`を実装して、スマートコントラクト内のメッセージが変更された後にUIを自動的に更新できるようにします。
-リスナーについて詳しく説明する前に、これまでの内容を確認してみましょう! `HelloWorld.js`ファイルと`interact.js`ファイルを保存し、[http://localhost: 3000/](http://localhost:3000/)へアクセスしてください。
+リスナーについて詳しく説明する前に、これまでの内容を確認してみましょう! `HelloWorld.js`ファイルと`interact.js`ファイルを保存し、[http://localhost:3000/](http://localhost:3000/)にアクセスしてください。
-現在、「ネットワークに接続されていません」というメッセージが表示されなくなっていることがわかります。 代わりに、スマート コントラクトに保存されているメッセージが反映されます。 カッコイイ!
+現在、「ネットワークに接続されていません」というメッセージが表示されなくなっていることがわかります。 代わりに、スマートコントラクトに保存されているメッセージが反映されます。 カッコイイ!
-#### 今や、UIにスマートコントラクトに保存されたメッセージが反映されるようになりました。 {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract}
+#### UIにスマートコントラクトに保存されたメッセージが反映されるはずです {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract}
それでは、リスナーについて説明していきます。
#### `addSmartContractListener`を実装する {#implement-addsmartcontractlistener}
-[このチュートリアルのパート1](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract)で記述した`HelloWorld.sol`ファイルについて振り返ると、`UpdatedMessages`というスマートコントラクトのイベントがあったと思います。このイベントは、スマートコントラクトの`update`関数が呼び出された後に発行されます \(9 行目と27行目を参照\)。
+このチュートリアルシリーズの[パート1で作成した`HelloWorld.sol`ファイル](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract)を思い出すと、スマートコントラクトの`update`関数が呼び出された後に`UpdatedMessages`というスマートコントラクトイベントが発行されることを思い出すでしょう(9行目と27行目を参照)。
```javascript
// HelloWorld.sol
-// Specifies the version of Solidity, using semantic versioning.
-// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+// Solidityのバージョンをセマンティックバージョニングで指定します。
+// 詳細: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity ^0.7.3;
-// Defines a contract named `HelloWorld`.
-// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+// `HelloWorld` という名前のコントラクトを定義します。
+// コントラクトは関数とデータ (その状態) の集合です。一度デプロイされると、コントラクトはEthereumブロックチェーン上の特定のアドレスに存在します。詳細: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
- //Emitted when update function is called
- //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.
+ // update関数が呼び出されたときに発行されます
+ //スマートコントラクトのイベントは、ブロックチェーン上で何かが起こったことをコントラクトがアプリのフロントエンドに伝える方法です。フロントエンドは特定のイベントを「リッスン」し、それが起こったときに行動を起こすことができます。
event UpdatedMessages(string oldStr, string newStr);
- // Declares a state variable `message` of type `string`.
- // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
+ // `string` 型の状態変数 `message` を宣言します。
+ // 状態変数は、その値がコントラクトのストレージに永続的に保存される変数です。`public` キーワードにより、変数はコントラクトの外部からアクセス可能になり、他のコントラクトやクライアントが値をアクセスするために呼び出せる関数が作成されます。
string public message;
- // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
- // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ // 多くのクラスベースのオブジェクト指向言語と同様に、コンストラクタはコントラクト作成時に一度だけ実行される特別な関数です。
+ // コンストラクタはコントラクトのデータを初期化するために使用されます。詳細:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
- // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
+ // 文字列引数 `initMessage` を受け取り、その値をコントラクトの `message` ストレージ変数に設定します)。
message = initMessage;
}
- // A public function that accepts a string argument and updates the `message` storage variable.
+ // 文字列引数を受け取り、 `message` ストレージ変数を更新する公開関数です。
function update(string memory newMessage) public {
string memory oldMsg = message;
message = newMessage;
@@ -1065,9 +1067,9 @@ contract HelloWorld {
}
```
-スマートコントラクトイベントは、ブロックチェーンで何かが起こったこと \(すなわち、_イベント_の発生 \) をフロントエンドアプリケーションに伝える方法です。特定のイベントを「リスニング」して、それが起きた時にアクションを実行します。
+スマートコントラクトイベントは、ブロックチェーンで何かが起こったこと \(すなわち、_イベント_の発生\) をフロントエンドアプリケーションに伝える方法です。フロントエンドは特定のイベントを「リスニング」して、それが起きた時にアクションを実行します。
-具体的には、`addSmartContractListener`関数がHello Worldスマートコントラクトの`UpdatedMessages`イベントをリッスンしており、新しいメッセージを表示するようにUIの更新をします。
+`addSmartContractListener`関数は、具体的にはHello Worldスマートコントラクトの`UpdatedMessages`イベントをリッスンし、新しいメッセージを表示するようにUIを更新します。
`addSmartContractListener`を次のように変更します。
@@ -1081,7 +1083,7 @@ function addSmartContractListener() {
} else {
setMessage(data.returnValues[1])
setNewMessage("")
- setStatus("🎉 Your message has been updated!")
+ setStatus("🎉 メッセージが更新されました!")
}
})
}
@@ -1089,10 +1091,10 @@ function addSmartContractListener() {
リスナーがイベントを検出したときに何が起こるかを詳しく解説します。
-- イベントの発行時にエラーが発生した場合、そのエラーは`status`ステート変数を介してUIに反映する。
-- それ以外の場合は、返された`data`オブジェクトを使う。 `data.returnValues`は、配列にある最初のエレメントがインデックスの0に格納されている配列です。配列の最初のエレメントには前のメッセージが格納され、2番目のエレメントには更新されたメッセージが格納されます。 つまり、イベントが成功すると、`message`文字列を更新されたメッセージに設定し、`newMessage`文字列をクリアし、`status`ステート変数を更新します。 これにより、新しいメッセージがスマートコントラクトに公開されたことを反映しています。
+- イベントの発行時にエラーが発生した場合、そのエラーは`status`ステート変数を介してUIに反映されます。
+- それ以外の場合は、返された`data`オブジェクトを使います。 `data.returnValues`は、0からインデックス付けされた配列で、配列の最初の要素には前のメッセージが格納され、2番目の要素には更新されたメッセージが格納されます。 つまり、イベントが成功すると、`message`文字列を更新されたメッセージに設定し、`newMessage`文字列をクリアし、`status`ステート変数を更新して、新しいメッセージがスマートコントラクトに公開されたことを反映させます。
-最後に、`useEffect`関数でリスナーを呼び出して、`HelloWorld.js`コンポーネントの最初のレンダリング時にリスナーが初期化されるようにしましょう。 あなたの`useEffect`関数全体は、次のようになります。
+最後に、`useEffect`関数でリスナーを呼び出して、`HelloWorld.js`コンポーネントの最初のレンダリング時にリスナーが初期化されるようにしましょう。 全体として、`useEffect`関数は次のようになります。
```javascript
// HelloWorld.js
@@ -1104,43 +1106,43 @@ useEffect(async () => {
}, [])
```
-スマートコントラクトから読み取れるようになったので、スマートコントラクトに書き込む方法も理解できるとなおよいでしょう! ただし、dappに書き込むには、まずイーサリアムウォレットをdappに接続する必要があります。
+スマートコントラクトから読み取れるようになったので、スマートコントラクトに書き込む方法も理解できると素晴らしいですね! ただし、dappに書き込むには、まずEthereumウォレットをdappに接続する必要があります。
-それでは、次にイーサリアムウォレット \(MetaMask\) を設定し、それをdappに接続することに取り組んでいきましょう!
+それでは、次にEthereumウォレット \(MetaMask\) を設定し、それをdappに接続することに取り組みましょう!
-### ステップ4: イーサリアムウォレットのセットアップ {#step-4-set-up-your-ethereum-wallet}
+### ステップ4: Ethereumウォレットを設定する {#step-4-set-up-your-ethereum-wallet}
-イーサリアムチェーンに何かを書き込むには、ユーザーは仮想ウォレットの秘密鍵を使ってトランザクションに署名しなければなりません。 このチュートリアルでは、イーサリアムアカウントアドレスの管理に使用されるブラウザの仮想ウォレットである[MetaMask](https://metamask.io/)を使用します。これにより、エンドユーザーは、このランザクションの署名がとても簡単になります。
+Ethereumチェーンに何かを書き込むには、ユーザーは仮想ウォレットの秘密鍵を使ってトランザクションに署名しなければなりません。 このチュートリアルでは、Ethereumアカウントアドレスの管理に使用されるブラウザの仮想ウォレットである[MetaMask](https://metamask.io/)を使用します。これにより、エンドユーザーは、このトランザクションの署名が非常に簡単になります。
-イーサリアムのトランザクションの仕組みの詳細については、イーサリアム・ファウンデーションの[こちらのページ](/developers/docs/transactions/)をご覧ください。
+イーサリアム上のトランザクションの仕組みについてさらに詳しく知りたい場合は、イーサリアム・ファウンデーションの[こちらのページ](/developers/docs/transactions/)をご覧ください。
-#### MetaMaskをダウンロード {#download-metamask}
+#### MetaMaskをダウンロードする {#download-metamask}
-Metamaskのアカウントは[こちら](https://metamask.io/download)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は\( 実際に支払いが発生しないように \)右上の「Goerli Test Network」に切り替えてください。
+MetaMaskアカウントは、[こちら](https://metamask.io/download)から無料でダウンロードして作成できます。 アカウントを作成するとき、またはすでにアカウントをお持ちの場合は、右上の「Goerli Test Network」に必ず切り替えてください \(実在の通貨を扱わないようにするため\)。
-#### フォーセットからイーサ(ETH)を追加 {#add-ether-from-a-faucet}
+#### フォーセットからetherを追加する {#add-ether-from-a-faucet}
-イーサリアムブロックチェーンでトランザクションに署名するには、偽のETHが必要になります。 ETHを取得するには、 [FaucETH](https://fauceth.komputing.org)にアクセスしてGoerliアカウントアドレスを入力し、「Request funds」をクリックしてください。 そしてドロップダウンで「Ethereum Testnet Goerli」を選択し、最後に「Request funds」ボタンを再度クリックします。 MetamaskアカウントにETHが表示されるはずです。
+Ethereumブロックチェーンでトランザクションに署名するには、偽のEthが必要です。 Ethを取得するには、[FaucETH](https://fauceth.komputing.org)にアクセスしてGoerliアカウントアドレスを入力し、「Request funds」をクリックし、ドロップダウンで「Ethereum Testnet Goerli」を選択し、最後に「Request funds」ボタンを再度クリックします。 MetamaskアカウントにETHが表示されるはずです。
-#### 残高の確認 {#check-your-balance}
+#### 残高を確認する {#check-your-balance}
-残高を再確認するために、[Alchemyのコンポーザーツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用して[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)をリクエストしてみましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 Metamaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。
+残高を確認するために、[Alchemyのcomposerツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用して[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)リクエストを行いましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 MetaMaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。
```text
{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
```
-**注:** この結果の単位は、ETHではなくweiです。 weiはETHの最小単位として使われています。 weiからETHへ変換すると、1 eth = 10¹⁸ weiになります。 つまり、0xde0b6b3a7640000を10進数に変換すると、1\*10¹⁸となり、1 ETHに相当します。
+**注:** この結果はethではなくwei単位です。 weiはETHの最小単位として使われています。 weiからETHへ変換すると、1 eth = 10¹⁸ weiになります。 つまり、0xde0b6b3a7640000を10進数に変換すると、1\*10¹⁸となり、1 ETHに相当します。
-ご安心ください。 これで、偽のお金を手に入れました。 🤑
+ふう! これで、偽のお金を手に入れました。 🤑
-### ステップ5: メタマスクをUIへ接続する {#step-5-connect-metamask-to-your-UI}
+### ステップ5: MetaMaskをUIに接続する {#step-5-connect-metamask-to-your-UI}
MetaMaskウォレットが設定されたので、分散型アプリケーション(Dapp)を接続しましょう。
#### `connectWallet`関数 {#the-connectWallet-function}
-`interact.js`ファイルの`connectWallet`関数を実装します。この関数は、`HelloWorld.js`コンポーネントで呼び出します。
+`interact.js`ファイルで`connectWallet`関数を実装します。この関数は、`HelloWorld.js`コンポーネントで呼び出します。
`connectWallet`を次のように変更しましょう。
@@ -1154,7 +1156,7 @@ export const connectWallet = async () => {
method: "eth_requestAccounts",
})
const obj = {
- status: "👆🏽 Write a message in the text-field above.",
+ status: "👆🏽 上のテキストフィールドにメッセージを書き込んでください。",
address: addressArray[0],
}
return obj
@@ -1172,8 +1174,7 @@ export const connectWallet = async () => {
@@ -1187,20 +1188,20 @@ export const connectWallet = async () => {
まず、ブラウザで`window.ethereum`が有効になっているかどうかをチェックしています。
-`window.ethereum`は、MetaMaskおよび他のウォレットプロバイダーによって挿入されるグローバルAPIであり、ウェブサイトがユーザーのイーサリアムアカウントを要求できるようにするものです。 承認されると、ユーザーが接続しているブロックチェーンからデータを読み取ったり、メッセージやトランザクションへの署名をユーザーに提案したりできるようになります。 詳細については、[MetaMaskのドキュメント](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)を参照してください。
+`window.ethereum`は、MetaMaskやその他のウォレットプロバイダーによって挿入されるグローバルAPIで、WebサイトがユーザーのEthereumアカウントを要求できるようにするものです。 承認されると、ユーザーが接続しているブロックチェーンからデータを読み取ったり、メッセージやトランザクションへの署名をユーザーに提案したりできるようになります。 詳細については[MetaMaskのドキュメント](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)をご覧ください。
-`window.ethereum`が_存在しない_場合は、MeTaMaskがインストールされていないことを意味します。 その結果、空の文字列に設定された、返される`address`と、ユーザーがMetaMaskをインストールする必要があることを伝える`status`JSXオブジェクトが入ったJSONオブジェクトが返されます。
+`window.ethereum`が_存在しない_場合、それはMetaMaskがインストールされていないことを意味します。 これにより、返される`address`が空の文字列で、`status` JSXオブジェクトがユーザーにMetaMaskをインストールするよう促すJSONオブジェクトが返されます。
-`window.ethereum`が_存在_する場合、興味深いことが起こります。
+さて、`window.ethereum`が_存在する_場合、ここからが面白くなります。
-try/catch ループを使用して、[`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)を呼び出すことでMetaMaskに接続しようとしています。 この関数を呼び出すと、ブラウザでMetaMaskが開き、ユーザーはウォレットを分散型アプリケーション(Dapp)に接続するように求められます。
+try/catchループを使用して、[`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)を呼び出してMetaMaskへの接続を試みます。 この関数を呼び出すと、ブラウザでMetaMaskが開き、ユーザーはウォレットを分散型アプリケーション(Dapp)に接続するように求められます。
-- ユーザーが接続を選んだ場合、`method: "eth_requestAccounts"`は、分散型アプリケーション(Dapp)に接続されているすべてのユーザーのアカウントアドレスを含む配列を返します。 `connectWallet`関数は、配列内の_最初の_`address`と\(9 行目参照\)、ユーザーにスマートコントラクトにメッセージを書き込むように促す`status`メッセージが入ったJSONオブジェクトを返します。
-- ユーザーが接続を拒否した場合、JSONオブジェクトには、返される`address`に入る空の文字列と、ユーザーが接続を拒否したことを示す`status`メッセージが入ることになります。
+- ユーザーが接続を選んだ場合、`method: "eth_requestAccounts"`は、dappに接続されているすべてのユーザーのアカウントアドレスを含む配列を返します。 まとめると、`connectWallet`関数は、この配列の_最初の_`address`(9行目参照)と、ユーザーにスマートコントラクトへのメッセージを書き込むよう促す`status`メッセージを含むJSONオブジェクトを返します。
+- ユーザーが接続を拒否した場合、JSONオブジェクトには返される`address`の空文字列と、ユーザーが接続を拒否したことを示す`status`メッセージが含まれます。
これで、`connectWallet`関数を作成できたので、次のステップでは、この関数を`HelloWorld.js`コンポーネントに呼び出します。
-#### `connect Wallet`関数を`Hello World.js`UIコンポーネントに加える {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component}
+#### `connectWallet`関数を`HelloWorld.js`UIコンポーネントに追加する {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component}
`HelloWorld.js`にある `connectWalletPressed`関数に移動し、次のように更新します。
@@ -1216,19 +1217,19 @@ const connectWalletPressed = async () => {
`interact.js`ファイルによって、機能の大部分が`HelloWorld.js`コンポーネントからどのように抽象化されているかに注目してください。 これは、モデルビューコントローラ(M-V-C)パラダイムに準拠しているためです。
-`connectWalletPressed`では、単にインポートされた`connectWallet`関数のawait呼び出しを行っています。さらに、そのレスポンスを使用し、`status`と`walletAddress`変数を状態フックを介して更新しています。
+`connectWalletPressed`では、インポートした`connectWallet`関数をawaitで呼び出し、そのレスポンスを使って状態フックを介して`status`と`walletAddress`変数を更新します。
それでは、両方のファイル \(`HelloWorld.js`と`interact.js`\) を保存して、これまでのUIをテストしてみましょう。
-[http://localhost:3000/](http://localhost:3000/)でブラウザを開き、ページ右上にある「Connect Wallet」ボタンを押します。
+[http://localhost:3000/](http://localhost:3000/)ページでブラウザを開き、ページ右上にある「Connect Wallet」ボタンを押します。
MetaMaskがインストールされている場合は、ウォレットを分散型アプリケーション(Dapp)に接続するように求められます。 接続リクエストを承認します。
-ウォレットボタンに、接続した自分のアドレスが表示されているはずです。 やりましたね🔥
+ウォレットボタンに、接続した自分のアドレスが表示されているはずです! やった!🔥
-次に、ページを更新してみてください。変ですね。 ウォレットボタンによって、すでに接続しているにもかかわらずMetaMaskに接続するよう求められます。
+次に、ページを再読み込みしてみてください... これは奇妙です。 ウォレットボタンによって、すでに接続しているにもかかわらずMetaMaskに接続するよう求められます。
-しかし、恐れるに足りません。 `getCurrentWalletConnected`を実装することで、簡単にこれを修正できます。この関数は、アドレスが分散型アプリケーション(Dapp) にすでに接続されているかどうかを確認し、それに応じてUIを更新します。
+しかし、恐れることはありません! これを簡単に修正できます(分かりましたか?) `getCurrentWalletConnected`を実装することで、アドレスがすでにdappに接続されているかどうかを確認し、それに応じてUIを更新できます!
#### `getCurrentWalletConnected`関数 {#the-getcurrentwalletconnected-function}
@@ -1246,12 +1247,12 @@ export const getCurrentWalletConnected = async () => {
if (addressArray.length > 0) {
return {
address: addressArray[0],
- status: "👆🏽 Write a message in the text-field above.",
+ status: "👆🏽 上のテキストフィールドにメッセージを書き込んでください。",
}
} else {
return {
address: "",
- status: "🦊 Connect to MetaMask using the top right button.",
+ status: "🦊 右上のボタンを使ってMetaMaskに接続してください。",
}
}
} catch (err) {
@@ -1268,8 +1269,7 @@ export const getCurrentWalletConnected = async () => {
@@ -1279,9 +1279,9 @@ export const getCurrentWalletConnected = async () => {
}
```
-このコードは、前述の`connectWallet`関数に_非常に_似ています。
+このコードは、前のステップで作成した`connectWallet`関数に非常に似ています。
-主な違いとしては、ユーザーがウォレットに接続するためにMetaMaskを開く`eth_requestAccounts`メソッドを呼び出す代わりに、 ここでは`eth_accounts`メソッドを呼び出しています。これは、現在、分散型アプリケーション(Dapp)に接続されているMetaMaskのアドレスを含む配列を単に返すだけです。
+主な違いは、ユーザーがウォレットを接続するためにMetaMaskを開く`eth_requestAccounts`メソッドを呼び出す代わりに、ここでは`eth_accounts`メソッドを呼び出している点です。これは、現在dappに接続されているMetaMaskのアドレスを含む配列を単に返すだけです。
この関数を動作させるため、`HelloWorld.js`コンポーネントの`useEffect`関数で呼び出しましょう。
@@ -1299,13 +1299,13 @@ useEffect(async () => {
}, [])
```
-`walletAddress`状態変数と`status`状態変数を更新するのに、呼び出した`getCurrentWalletConnected`のレスポンスを使用していることに注目してください。
+`walletAddress`と`status`の状態変数を更新するのに、`getCurrentWalletConnected`の呼び出しのレスポンスを使用していることに注目してください。
このコードを加えたら、ブラウザウィンドウを更新してみてください。
素晴らしい! リフレッシュ後も、ボタンには接続されていることが示されており、接続されたウォレットのアドレスのプレビューが表示されているはずです。
-#### `addWalletListener`の実装 {#implement-addwalletlistener}
+#### `addWalletListener`を実装する {#implement-addwalletlistener}
分散型アプリケーション(Dapp)ウォレットの設定の最終ステップは、ウォレットリスナーを実装することです。これにより、ユーザーが接続を切断したり、アカウントを切り替えたりした場合など、ウォレットの状態が変更されたときにUIが更新されます。
@@ -1319,10 +1319,10 @@ function addWalletListener() {
window.ethereum.on("accountsChanged", (accounts) => {
if (accounts.length > 0) {
setWallet(accounts[0])
- setStatus("👆🏽 Write a message in the text-field above.")
+ setStatus("👆🏽 上のテキストフィールドにメッセージを書き込んでください。")
} else {
setWallet("")
- setStatus("🦊 Connect to MetaMask using the top right button.")
+ setStatus("🦊 右上のボタンを使ってMetaMaskに接続してください。")
}
})
} else {
@@ -1330,7 +1330,7 @@ function addWalletListener() {
)
@@ -1338,11 +1338,11 @@ function addWalletListener() {
}
```
-この時点で何が起こっているかを理解するのに私たちの助けは必要ないと思いますが、完璧な理解を目指しているので簡単に説明します。
+この時点で何が起こっているかを理解するのに私たちの助けは必要ないと思いますが、念のため、簡単に説明します。
-- まず、ブラウザで`window.ethereum`が有効になっているか\(すなわち MetaMaskがインストールされているか\)を関数がチェックしています。
- - 有効になっていない場合、ユーザーにMetaMaskのインストールを求めるJSX文字列を`status`状態変数に設定します。
- - 有効になっている場合、MetaMaskウォレットの状態変更をリッスンしている3行目の`window.ethereum.on("accountsChanged")`リスナーを設定します。この状態変更には、ユーザーが追加のアカウントを分散型アプリケーション(Dapp)に接続した場合、アカウントを切り替えた場合、アカウントを切断した場合が含まれます。 少なくとも1つのアカウントが接続されていれば、`accounts`配列の最初のアカウントがリスナーから返されたときに、`walletAddress`状態変数が更新されます。 それ以外の場合は、`walletAddress`に空の文字列が設定されます。
+- まず、この関数は`window.ethereum`が有効になっているか(つまり、MetaMaskがインストールされているか)をチェックします。
+ - 有効でない場合、`status`状態変数を、ユーザーにMetaMaskのインストールを促すJSX文字列に設定するだけです。
+ - 有効になっている場合、3行目のリスナー`window.ethereum.on("accountsChanged")`を設定します。これはMetaMaskウォレットの状態変更をリッスンします。これには、ユーザーがdappに追加のアカウントを接続した場合、アカウントを切り替えた場合、アカウントを切断した場合が含まれます。 少なくとも1つのアカウントが接続されていれば、`walletAddress`状態変数は、リスナーから返された`accounts`配列の最初のアカウントとして更新されます。 それ以外の場合、`walletAddress`には空の文字列が設定されます。
最後に、`useEffect`関数で次のように呼び出す必要があります。
@@ -1364,21 +1364,21 @@ useEffect(async () => {
完成です! ウォレットのすべての機能をプログラミングしました。 次は最後のタスクです。スマートコントラクトに保存されているメッセージを更新します。
-### ステップ6: `updateMessage`関数の実装する {#step-6-implement-the-updateMessage-function}
+### ステップ6: `updateMessage`関数を実装する {#step-6-implement-the-updateMessage-function}
-友よ!最終段階にたどり着きました。 `interact.js`ファイルの`updateMessage`で、次のことを実行します。
+さあ、最終段階にたどり着きました。 `interact.js`ファイルの`updateMessage`で、次のことを実行します。
-1. スマートコンタクトに公開したいメッセージが有効であることを確認する。
+1. スマートコントラクトに公開したいメッセージが有効であることを確認する。
2. MetaMaskを使用してトランザクションに署名する
3. `HelloWorld.js`フロントエンドコンポーネントでこの関数を呼び出す。
-これには、それほど時間を要しません。dappを完成させましょう!
+これには、それほど時間はかかりません。dappを完成させましょう!
#### 入力エラー処理 {#input-error-handling}
当然ながら、関数の開始時に何らかの入力エラー処理を行うことは理にかなっています。
-MetaMaskエクステンションがインストールされていない場合や接続されているウォレットがない場合 \(つまり、渡された `address`が空の文字列\) 、 `message`は空の文字列になります。 次のエラー処理を`updateMessage`に追加しましょう。
+MetaMaskエクステンションがインストールされていない場合、接続されているウォレットがない場合 \(つまり、渡された `address`が空の文字列の場合\) 、または`message`が空の文字列の場合は、関数が早期にリターンするようにします。 次のエラー処理を`updateMessage`に追加しましょう。
```javascript
// interact.js
@@ -1387,13 +1387,13 @@ export const updateMessage = async (address, message) => {
if (!window.ethereum || address === null) {
return {
status:
- "💡 Connect your MetaMask wallet to update the message on the blockchain.",
+ "💡 ブロックチェーン上のメッセージを更新するには、MetaMaskウォレットを接続してください。",
}
}
if (message.trim() === "") {
return {
- status: "❌ Your message cannot be an empty string.",
+ status: "❌ メッセージを空の文字列にすることはできません。",
}
}
}
@@ -1401,21 +1401,21 @@ export const updateMessage = async (address, message) => {
入力エラーを適切に処理できるようなりました。それでは、MetaMaskを介してトランザクションに署名をします。
-#### トランザクションへ署名する {#signing-our-transaction}
+#### トランザクションに署名する {#signing-our-transaction}
-従来のWeb3イーサリアムトランザクションにすでに慣れている場合は、次に記述するコードは非常に馴染みのあるものになるでしょう。 入力エラー処理コードの下に、次の`updateMessage`を加えます。
+従来のweb3 Ethereumトランザクションにすでに慣れている場合は、次に記述するコードは非常に馴染みのあるものになるでしょう。 入力エラー処理コードの下に、次の`updateMessage`を加えます。
```javascript
// interact.js
-//set up transaction parameters
+//トランザクションパラメータを設定する
const transactionParameters = {
- to: contractAddress, // Required except during contract publications.
- from: address, // must match user's active address.
+ to: contractAddress, // コントラクト公開時以外は必須。
+ from: address, // ユーザーのアクティブなアドレスと一致する必要がある。
data: helloWorldContract.methods.update(message).encodeABI(),
}
-//sign the transaction
+//トランザクションに署名する
try {
const txHash = await window.ethereum.request({
method: "eth_sendTransaction",
@@ -1426,11 +1426,10 @@ try {
✅{" "}
- View the status of your transaction on Etherscan!
+ Etherscanでトランザクションのステータスを表示してください!
- ℹ️ Once the transaction is verified by the network, the message will be
- updated automatically.
+ ℹ️ トランザクションがネットワークによって検証されると、メッセージは自動的に更新されます。
),
}
@@ -1443,45 +1442,45 @@ try {
何をしているか、説明していきましょう。 まず、次のようにトランザクションパラメータを設定します。
-- `to`に受取人のアドレス\(スマートコントラクト\)を設定します 。
-- `from`では、関数に渡した`address`変数であるトランザクションの署名者を指定します。
-- `data`には、Hello Worldスマートコントラクトの `update`メソッドへの呼び出しが含まれており、`message`文字列変数を入力として受け取っています。
+- `to`は受信者アドレス(スマートコントラクト)を指定します
+- `from`はトランザクションの署名者を指定します。これは関数に渡した`address`変数です。
+- `data`には、Hello Worldスマートコントラクトの`update`メソッドへの呼び出しが含まれており、`message`文字列変数を入力として受け取っています。
-次に、`window.ethereum.request`をawaitで呼び出して、MetaMaskにトランザクションの署名を依頼します。 11行目と12行目で、ethメソッド `eth_sendTransaction`を指定し、`transactionParameters`を渡していることに注目してください。
+次に、`window.ethereum.request`をawaitで呼び出して、MetaMaskにトランザクションの署名を依頼します。 11行目と12行目で、ethメソッド`eth_sendTransaction`を指定し、`transactionParameters`を渡していることに注目してください。
この時点で、ブラウザでMetaMaskが開かれ、ユーザーにトランザクションの署名または拒否を求めます。
-- トランザクションが成功した場合、この関数は、Etherscanでトランザクションについての詳細を確認するようユーザーに求める`status`JSX文字列が入ったJSONオブジェクトを返します。
+- トランザクションが成功した場合、この関数は、`status` JSX文字列がEtherscanでトランザクションについての詳細を確認するようユーザーに促すJSONオブジェクトを返します。
- トランザクションが失敗した場合、この関数は、エラーメッセージを伝える`status`文字列が入ったJSONオブジェクトを返します。
-全体では、`updateMessage`関数は次のようになります。
+全体として、`updateMessage`関数は次のようになります。
```javascript
// interact.js
export const updateMessage = async (address, message) => {
- //input error handling
+ //入力エラー処理
if (!window.ethereum || address === null) {
return {
status:
- "💡 Connect your MetaMask wallet to update the message on the blockchain.",
+ "💡 ブロックチェーン上のメッセージを更新するには、MetaMaskウォレットを接続してください。",
}
}
if (message.trim() === "") {
return {
- status: "❌ Your message cannot be an empty string.",
+ status: "❌ メッセージを空の文字列にすることはできません。",
}
}
- //set up transaction parameters
+ //トランザクションパラメータを設定する
const transactionParameters = {
- to: contractAddress, // Required except during contract publications.
- from: address, // must match user's active address.
+ to: contractAddress, // コントラクト公開時以外は必須。
+ from: address, // ユーザーのアクティブなアドレスと一致する必要がある。
data: helloWorldContract.methods.update(message).encodeABI(),
}
- //sign the transaction
+ //トランザクションに署名する
try {
const txHash = await window.ethereum.request({
method: "eth_sendTransaction",
@@ -1492,11 +1491,10 @@ export const updateMessage = async (address, message) => {
✅{" "}
- View the status of your transaction on Etherscan!
+ Etherscanでトランザクションのステータスを表示してください!
- ℹ️ Once the transaction is verified by the network, the message will
- be updated automatically.
+ ℹ️ トランザクションがネットワークによって検証されると、メッセージは自動的に更新されます。
),
}
@@ -1523,18 +1521,18 @@ const onUpdatePressed = async () => {
}
```
-とても綺麗ででシンプルです。 そして、なんということでしょう。 dappの完成です。
+とてもクリーンでシンプルです。 そして、なんと... dappの完成です!!!
-**更新**ボタンを試してみてください!
+**Update**ボタンを試してみてください!
-### 自分自身でカスタムdappを作る {#make-your-own-custom-dapp}
+### 独自のカスタムdappを作成する {#make-your-own-custom-dapp}
-おめでとう!あなたは、このチュートリアルを最後までやりきりました! おさらいすると、以下の方法を学びました。
+おめでとうございます!チュートリアルの最後までたどり着きました! おさらいすると、以下の方法を学びました。
- MetaMaskウォレットをdappプロジェクトに接続する
-- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) APIを使用してスマートコントラクトからデータを読み取る。
-- MetaMaskを使用してイーサリアムトランザクションに署名する
+- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) APIを使用してスマートコントラクトからデータを読み取る
+- MetaMaskを使用してEthereumトランザクションに署名する
-これで、このチュートリアルのスキルを応用して独自のカスタムdappプロジェクトを構築するための準備が整いました。 何かご質問がございましたら、[Alchemy Discord](https://discord.gg/gWuC7zB)でいつでもお気軽にお問い合わせください。 🧙♂️
+これで、このチュートリアルのスキルを応用して独自のカスタムdappプロジェクトを構築するための準備が整いました。 いつものように、ご質問があれば、[Alchemy Discord](https://discord.gg/gWuC7zB)でお気軽にお問い合わせください。 🧙♂️
-このチュートリアルを通して体験したことやフィードバックがあれば、Twitter[@alchemyplatform](https://twitter.com/AlchemyPlatform)でタグ付けしてお知らせください。
+このチュートリアルを完了したら、Twitterで[@alchemyplatform](https://twitter.com/AlchemyPlatform)にタグ付けして、感想やフィードバックをお知らせください!
diff --git a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md
index 7cef5459340..8130177db6e 100644
--- a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md
+++ b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md
@@ -1,73 +1,62 @@
---
-title: 初心者向けのHello Worldスマートコントラクト
-description: イーサリアムでの簡単なスマートコントラクトの作成とデプロイに関する入門チュートリアル
+title: "初心者向けのHello Worldスマートコントラクト"
+description: "イーサリアムでの簡単なスマートコントラクトの作成とデプロイに関する入門チュートリアル。"
author: "elanh"
-tags:
- - "Solidity"
- - "Hardhat"
- - "alchemy"
- - "スマートコントラクト"
- - "デプロイ"
+tags: [ "Solidity", "hardhat", "Alchemy", "スマート契約", "デプロイ" ]
skill: beginner
lang: ja
published: 2021-03-31
---
-このチュートリアルは、ブロックチェーンの開発が初めてで、どこから始めたらよいのか分からない場合や、 スマートコントラクトをデプロイしてやり取りする方法を理解したいだけの場合に、最適なガイドとなります。 このチュートリアルでは、仮想ウォレット([MetaMask](https://metamask.io/))、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org/)、[Alchemy](https://alchemyapi.io/eth)を使用して、Goerliテストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追って説明します(現時点でしっかりと理解できていなくても、心配はご無用です。後ほど説明します)。
+このガイドは、ブロックチェーンの開発が初めてでどこから始めたらよいのか分からない方や、スマートコントラクトをデプロイして対話する方法を理解したいだけの方に最適です。 このチュートリアルでは、仮想ウォレット([MetaMask](https://metamask.io/))、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org/)、[Alchemy](https://www.alchemy.com/)を使用して、Sepoliaテストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追って説明します(現時点でしっかりと理解できていなくても、心配はご無用です。後ほど説明します)。
-> **警告**
->
-> 🚧 非推奨の通知
->
-> このガイドでは、Goerliテストネットワークをスマートコントラクトの作成とデプロイに使用しています。 ただし、イーサリアム・ファウンデーションにより、[Goerliが間もなく廃止予定](https://www.alchemy.com/blog/goerli-faucet-deprecation)であることが発表されました。
->
-> このチュートリアルでは、[Sepolia](https://www.alchemy.com/overviews/sepolia-testnet)および[Sepoliaフォーセット](https://sepoliafaucet.com/)の利用を推奨します。
+このチュートリアルの[パート2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract)では、デプロイ後のスマートコントラクトとの対話方法について、[パート3](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan)ではEtherscanで公開する方法について説明します。
-このチュートリアルの[パート2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract)では、ここでデプロイしたスマートコントラクトとやり取りする方法について説明します。[パート3](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan)では、そのスマートコントラクトをEtherscanで公開する方法について説明します。
-
-質問がある場合は、いつでも[Alchemy Discord](https://discord.gg/gWuC7zB)でお問い合わせください。
+ご不明な点がございましたら、[Alchemy Discord](https://discord.gg/gWuC7zB)までお気軽にお問い合わせください!
## ステップ1: イーサリアムネットワークに接続する {#step-1}
-イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここではAlchemyの無料アカウントを使用します。これは独自のノードを実行することなく、イーサリアムチェーンとの通信を可能にするブロックチェーンのデベロッパープラットフォームとAPIです。 このプラットフォームには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。 Alchemyのアカウントをお持ちでない場合は、[こちら](https://dashboard.alchemyapi.io/signup)から無料で登録できます。
+イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここではAlchemyの無料アカウントを使用します。これは独自のノードを実行することなく、イーサリアムチェーンとの通信を可能にするブロックチェーンのデベロッパープラットフォームとAPIです。 このプラットフォームには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。 Alchemyアカウントをお持ちでない場合は、[こちらから無料で登録](https://dashboard.alchemy.com/signup)できます。
-## ステップ2: アプリ(およびAPI キー)を作成する {#step-2}
+## ステップ2: アプリ(およびAPIキー)を作成する {#step-2}
-Alchemyのアカウントを作成すると、アプリを作成することでAPIキーを生成できるようになります。 これにより、Goerliテストネットワークへのリクエストが可能になります。 テストネットに詳しくない場合は、[こちらのページ](/developers/docs/networks/)をご覧ください。
+Alchemyのアカウントを作成した後、アプリを作成することでAPIキーを生成することができます。 これにより、Sepoliaテストネットワークへのリクエストが可能になります。 テストネットに詳しくない場合は、[こちらのページ](/developers/docs/networks/)をご覧ください。
-1. ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemyダッシュボードの「Create App」ページに移動してください。
+1. Alchemyダッシュボードのナビゲーションバーで「Select an app」を選択し、「Create new app」をクリックして、「Create new app」ページに移動します。
-
+
-2. アプリに「Hello World」という名前を付け、簡単な説明を記述し、環境に「Staging」を選択(アプリのブックキーピングに使用)し、ネットワークに「Goerli」を選択します。
+2. アプリに「Hello World」という名前を付け、簡単な説明を提示し、「Infra & Tooling」などのユースケースを選択します。 次に、「Ethereum」を検索してネットワークを選択します。
-
+
-3. 「Create app」をクリックして完了です。 アプリが下の表に表示されます。
+3. 「Next」をクリックして続行し、次に「Create app」をクリックすれば完了です! ナビゲーションバーのドロップダウンメニューにアプリが表示され、APIキーをコピーできるようになります。
## ステップ3: イーサリアムアカウント(アドレス)を作成する {#step-3}
-トランザクションの送受信には、イーサリアムアカウントが必要です。 このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットであるMetamaskを使用します。 [トランザクション](/developers/docs/transactions/)の詳細。
+トランザクションの送受信には、イーサリアムアカウントが必要です。 このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットであるMetamaskを使用します。 [トランザクション](/developers/docs/transactions/)に関する詳細はこちら。
+
+MetaMaskは[こちら](https://metamask.io/download)からダウンロードして、無料でイーサリアムアカウントを作成できます。 アカウントを作成するとき、またはすでにアカウントをお持ちの場合は、(実際のお金を使わないように)ネットワークのドロップダウンメニューを使用して「Sepolia」テストネットワークに切り替えてください。
-Metamaskのアカウントは[こちら](https://metamask.io/download)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は(実際に支払いが発生しないように)右上の「Goerli Test Network」に切り替えてください。
+Sepoliaがリストに表示されない場合は、メニューから「高度な設定」に進み、下にスクロールして「テストネットワークを表示」をオンに切り替えます。 ネットワーク選択メニューで、「カスタム」タブを選択してテストネットのリストを見つけ、「Sepolia」を選択します。
-
+
-## ステップ4: フォーセットからイーサ(ETH)を追加する {#step-4}
+## ステップ4: フォーセットからイーサを追加する {#step-4}
-テストネットワークにスマートコントラクトをデプロイするには、偽のETHが必要になります。 ETHを取得するには、[Goerliフォーセット](https://goerlifaucet.com/)にアクセスし、Alchemyアカウントでログインしてウォレットアドレスを入力し、「Send Me ETH」をクリックしてください。 ネットワークトラフィックのために偽のETHを受け取るのに時間がかかる場合があります。 (この記事の執筆時点では、30分ほどかかりました。) MetaMaskアカウントにETHが表示されるはずです!
+テストネットワークにスマートコントラクトをデプロイするには、偽のEthが必要になります。 Sepolia ETHを入手するには、[Sepoliaネットワーク詳細](/developers/docs/networks/#sepolia)にアクセスして、さまざまなフォーセットのリストを表示します。 1つが機能しない場合は、別のものを試してください。枯渇している場合があります。 ネットワークのトラフィックにより、偽のETHの受信に時間がかかる場合があります。 その後すぐに、MetaMaskアカウントにETHが表示されるはずです!
## ステップ5: 残高を確認する {#step-5}
-残高を再確認するために、[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)を[Alchemyのコンポーザーツール](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用してリクエストしてみましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 MetaMaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。
+残高があることを再確認するために、[Alchemyのcomposerツール](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest)を使用して[eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance)リクエストを作成しましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 MetaMaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。
```json
{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }
```
-> **注:** この結果の単位は、ETHではなくweiです。 weiはETHの最小単位として使われています。 weiからETHへ変換すると、1 eth = 1018 weiになります。 つまり、0x2B5E3AF16B1880000を10進数に変換すると、5\*10¹⁸となり、5 ETHに相当します。
+> \*\*注:\*\*この結果の単位はETHではなくweiです。 weiはETHの最小単位として使われています。 weiからETHへの変換は、1 eth = 1018 weiです。 したがって、0x2B5E3AF16B1880000を10進数に変換すると5\*10¹⁸になり、これは5 ETHに相当します。
>
-> ご安心ください。 偽のお金はすべてそこにあります 。
+> ふう! 偽のお金がすべて揃いました 。
## ステップ6: プロジェクトを初期化する {#step-6}
@@ -78,18 +67,18 @@ mkdir hello-world
cd hello-world
```
-プロジェクトフォルダ内に入ったら、`npm init`を使用してプロジェクトを初期化します。 まだnpmがインストールされていない場合は、[こちらの手順](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)に従ってください(Node.jsも必要となりますので、こちらもダウンロードしてください。)
+プロジェクトフォルダに入ったので、`npm init`を使用してプロジェクトを初期化します。 npmをまだインストールしていない場合は、[これらの手順](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)に従ってください(Node.jsも必要なので、それもダウンロードしてください!)。
```
npm init
```
-インストール時の質問についてはどのように回答してもかまいませんが、参考までに以前行った回答を以下に示します。
+インストールの質問にどう答えるかは重要ではありませんが、参考までに私たちの回答方法を次に示します。
```
package name: (hello-world)
version: (1.0.0)
-description: hello world smart contract
+description: hello world スマートコントラクト
entry point: (index.js)
test command:
git repository:
@@ -101,7 +90,7 @@ About to write to /Users/.../.../.../hello-world/package.json:
{
"name": "hello-world",
"version": "1.0.0",
- "description": "hello world smart contract",
+ "description": "hello world スマートコントラクト",
"main": "index.js",
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1"
@@ -111,19 +100,19 @@ About to write to /Users/.../.../.../hello-world/package.json:
}
```
-package.jsonを承認すれば完了です。
+package.jsonを承認すれば完了です!
## ステップ7: [Hardhat](https://hardhat.org/getting-started/#overview)をダウンロードする {#step-7}
Hardhatは、イーサリアムのソフトウェアをコンパイル、デプロイ、テスト、デバッグするための開発環境です。 デベロッパーがライブチェーンにデプロイする前に、スマートコントラクトや分散型アプリケーション(Dapp)をローカルに構築する際に役立ちます。
-先ほど作成した`hello-world`プロジェクト内で、以下を実行します。
+`hello-world`プロジェクト内で次を実行します。
```
npm install --save-dev hardhat
```
-[インストール手順](https://hardhat.org/getting-started/#overview)の詳細については、こちらのページをご覧ください。
+[インストール手順](https://hardhat.org/getting-started/#overview)の詳細については、このページをご覧ください。
## ステップ8: Hardhatプロジェクトを作成する {#step-8}
@@ -133,7 +122,7 @@ npm install --save-dev hardhat
npx hardhat
```
-ウェルカムメッセージと、次に何をするのかを選択できるオプションが表示されます。 「Create an empty hardhat.config.js」を選択します。
+ウェルカムメッセージと、次に何をするのかを選択できるオプションが表示されます。 「create an empty hardhat.config.js」を選択してください。
```
888 888 888 888 888
@@ -153,7 +142,7 @@ Create a sample project
Quit
```
-`hardhat.config.js`ファイルが生成されます。このファイルでプロジェクトのすべての設定を行います(ステップ13で行います)。
+これにより `hardhat.config.js` ファイルが生成されます。ここでプロジェクトのすべてのセットアップを指定します(ステップ13)。
## ステップ9: プロジェクトフォルダを追加する {#step-9}
@@ -164,55 +153,55 @@ mkdir contracts
mkdir scripts
```
-- `contracts/`は、Hello Worldスマートコントラクトのコードファイルを格納する場所です。
-- `scripts/`は、コントラクトをデプロイして対話するスクリプトを保持する場所です。
+- `contracts/` には、hello worldスマートコントラクトのコードファイルを保存します
+- `scripts/` には、コントラクトをデプロイして対話するためのスクリプトを保存します
## ステップ10: コントラクトを作成する {#step-10}
-一体いつになったらコードを書くのだろうと疑問をお持ちではないでしょうか 。 このステップ10でコードを書いていきましょう。
+一体いつになったらコードを書くのだろう、と思っているかもしれませんね。 さあ、このステップ10でコードを書き始めましょう。
-お気に入りのエディタでhello-worldプロジェクトを開きます(通常は[VScode](https://code.visualstudio.com/)を使用しています)。 スマートコントラクトは、Solidityと呼ばれる言語で記述されています。HelloWorld.solスマートコントラクトの作成にこの言語を使用します。
+お気に入りのエディタでhello-worldプロジェクトを開きます([VSCode](https://code.visualstudio.com/)がおすすめです)。 スマートコントラクトはSolidityという言語で書かれており、これを使ってHelloWorld.solスマートコントラクトを作成します。
-1. 「contracts」フォルダに移動し、HelloWorld.solという名前の新規ファイルを作成します。
-2. 以下は、このチュートリアルで使用するイーサリアム・ファウンデーションのHello Worldスマートコントラクトのサンプルです。 以下の内容をコピーして、HelloWorld.solファイルに貼り付けます。コメントを読んで、このコントラクトが何を行うのかを理解してください。
+1. 「contracts」フォルダに移動し、HelloWorld.solという名前の新規ファイルを作成します。
+2. 以下は、このチュートリアルで使用するイーサリアム・ファウンデーションのHello Worldスマートコントラクトのサンプルです。 以下の内容をHelloWorld.solファイルにコピー&ペーストし、コメントを読んでこのコントラクトが何をするのかを理解してください。
```solidity
-// Specifies the version of Solidity, using semantic versioning.
-// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+// セマンティックバージョニングを使用して、Solidityのバージョンを指定します。
+// 詳細はこちら: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity ^0.7.0;
-// Defines a contract named `HelloWorld`.
-// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+// `HelloWorld`という名前のコントラクトを定義します。
+// コントラクトは関数とデータ(その状態)の集合です。デプロイされると、コントラクトはイーサリアムのブロックチェーン上の特定のアドレスに配置されます。詳細はこちら: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
- // Declares a state variable `message` of type `string`.
- // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
+ // `string`型の状態変数`message`を宣言します。
+ // 状態変数は、その値がコントラクトストレージに永続的に保存される変数です。`public`キーワードは、変数をコントラクトの外部からアクセス可能にし、他のコントラクトやクライアントがその値をアクセスするために呼び出せる関数を作成します。
string public message;
- // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
- // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ // 多くのクラスベースのオブジェクト指向言語と同様に、コンストラクタはコントラクト作成時にのみ実行される特別な関数です。
+ // コンストラクタは、コントラクトのデータを初期化するために使用されます。詳細はこちら:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
- // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
+ // 文字列引数`initMessage`を受け入れ、その値をコントラクトの`message`ストレージ変数に設定します。
message = initMessage;
}
- // A public function that accepts a string argument and updates the `message` storage variable.
+ // 文字列引数を受け入れ、`message`ストレージ変数を更新する公開関数です。
function update(string memory newMessage) public {
message = newMessage;
}
}
```
-これは、作成時にメッセージを保存し、`update`関数を呼び出すことで更新できる非常にシンプルなスマートコントラクトです。
+これは、作成時にメッセージを保存し、`update`関数を呼び出すことで更新できる、非常にシンプルなスマートコントラクトです。
## ステップ11: MetaMaskとAlchemyをプロジェクトに接続する {#step-11}
-ここまでで、MetaMaskウォレットとAlchemyアカウントを作成し、スマートコントラクトも作成しました。次はこの3つを接続しましょう。
+MetaMaskウォレットとAlchemyアカウントを作成し、スマートコントラクトも作成しました。次はこの3つを接続しましょう。
-仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この権限をプログラムに提供するため、秘密鍵(およびAlchemy APIキー)を環境ファイルに安全に保存できます。
+仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この許可をプログラムに与えるために、秘密鍵(とAlchemyのAPIキー)を環境ファイルに安全に格納する作業を行います。
-> トランザクションの送信の詳細については、web3を使用したトランザクションの送信に関する[こちらのチュートリアル](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。
+> トランザクションの送信について詳しく知るには、web3を使用したトランザクション送信に関する[このチュートリアル](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。
まず、プロジェクトディレクトリにdotenvパッケージをインストールします。
@@ -220,37 +209,37 @@ contract HelloWorld {
npm install dotenv --save
```
-次に、 `.env`ファイルをプロジェクトのルートディレクトリに作成し、そのファイルにMetamaskの秘密鍵とHTTP Alchemy APIのURLを追加します。
+次に、プロジェクトのルートディレクトリに`.env`ファイルを作成し、MetaMaskの秘密鍵とHTTP Alchemy API URLを追加します。
-- 秘密鍵をエクスポートするには、[こちらの手順](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key)に従ってください。
-- HTTP Alchemy APIのURLを取得するには、以下を参照してください。
+- [これらの手順](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/)に従って秘密鍵をエクスポートします
+- HTTP Alchemy API URLを取得するには、以下を参照してください
-
+
-Alchemy APIのURLをコピーします。
+Alchemy API URLをコピーする
-`.env`ファイルは次のようになります。
+`.env`は次のようになります:
```
-API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
+API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
```
-これらの変数を実際にコードに接続するために、ステップ13でこれらの変数を`hardhat.config.js`ファイル内で参照します。
+これらをコードに実際に接続するために、ステップ13で`hardhat.config.js`ファイル内のこれらの変数を参照します。
-.envファイルをコミットしないでください! .envファイルを誰かと共有したり公開したりしないようにしてください。秘密が漏洩する可能性があります。 バージョン管理ツールを使用している場合は、.envをgitignoreファイルに追加します。
+.envはコミットしないでください! .envは決して他人と共有したり、公開したりしないように注意してください。共有することで、あなたのアカウント情報が漏洩する可能性があります。 バージョンを管理する場合は、.envをgitignoreファイルに追加してください。
## ステップ12: Ethers.jsをインストールする {#step-12-install-ethersjs}
-Ethers.jsは、よりユーザーフレンドリーなメソッドで[標準のJSON-RPCメソッド](/developers/docs/apis/json-rpc/)をラップすることにより、イーサリアムとの対話やリクエストを簡単にするライブラリです。
+Ethers.jsは、[標準のJSON-RPCメソッド](/developers/docs/apis/json-rpc/)をよりユーザーフレンドリーなメソッドでラップすることで、イーサリアムとの対話やリクエストを容易にするライブラリです。
-Hardhatは、追加のツールと拡張機能のための[プラグイン](https://hardhat.org/plugins/)の統合を非常に簡単にしてくれます。 コントラクトのデプロイメントに[Ethersプラグイン](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers)を利用します([Ethers.js](https://github.com/ethers-io/ethers.js/)には、複数の非常にクリーンなコントラクトのデプロイメント方法があります)。
+Hardhatでは、追加のツールや拡張機能のための[プラグイン](https://hardhat.org/plugins/)を非常に簡単に統合できます。 コントラクトのデプロイには[Ethersプラグイン](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers)を活用します([Ethers.js](https://github.com/ethers-io/ethers.js/)には非常にクリーンなコントラクトデプロイメントメソッドがあります)。
プロジェクトのホームディレクトリで以下を実行します。
@@ -258,13 +247,13 @@ Hardhatは、追加のツールと拡張機能のための[プラグイン](http
npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
```
-次のステップの`hardhat.config.js`でもEthers(.js)が必要になります。
+次のステップで、`hardhat.config.js`にethersもrequireします。
## ステップ13: hardhat.config.jsを更新する {#step-13-update-hardhatconfigjs}
-ここまでで、いくつかの依存関係とプラグインを追加しました。次に、`hardhat.config.js`を更新して、プロジェクトがそれらすべてについて認識できるようにする必要があります。
+ここまでで、いくつかの依存関係とプラグインを追加しました。次に、プロジェクトがそれらすべてを認識できるように、`hardhat.config.js`を更新する必要があります。
-`hardhat.config.js`を以下のように更新します。
+`hardhat.config.js`を次のように更新します:
```
require('dotenv').config();
@@ -277,10 +266,10 @@ const { API_URL, PRIVATE_KEY } = process.env;
*/
module.exports = {
solidity: "0.7.3",
- defaultNetwork: "goerli",
+ defaultNetwork: "sepolia",
networks: {
hardhat: {},
- goerli: {
+ sepolia: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`]
}
@@ -290,7 +279,7 @@ module.exports = {
## ステップ14: コントラクトをコンパイルする {#step-14-compile-our-contracts}
-ここまででしっかりと動作していることを確認するため、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みのHardhatタスクの1つです。
+ここまでの作業がうまくいっていることを確認するために、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みのHardhatタスクの1つです。
コマンドラインで以下を実行します。
@@ -298,19 +287,19 @@ module.exports = {
npx hardhat compile
```
-`SPDX license identifier not provided in source file`という警告が表示される場合がありますが、心配する必要はありません。警告が表示されないのがベストですが、 表示された場合は、いつでも[Alchemy discord](https://discord.gg/u72VCg3)でメッセージを送信できます。
+`SPDX license identifier not provided in source file`という警告が表示されるかもしれませんが、心配する必要はありません。それ以外は問題ないはずです! うまくいかない場合は、いつでも[Alchemy Discord](https://discord.gg/u72VCg3)でメッセージを送ることができます。
-## ステップ15: デプロイスクリプトを書く {#step-15-write-our-deploy-scripts}
+## ステップ15: デプロイスクリプトを作成する {#step-15-write-our-deploy-scripts}
コントラクトの作成と設定ファイルの作成が完了したら、いよいよコントラクトのデプロイのためのスクリプトを作成します。
-`scripts/`フォルダに移動して、`deploy.js`という名前のファイルを新規に作成し、以下の内容を追加します。
+`scripts/`フォルダに移動して`deploy.js`という名前の新しいファイルを作成し、次の内容を追加します:
```
async function main() {
const HelloWorld = await ethers.getContractFactory("HelloWorld");
- // Start deployment, returning a promise that resolves to a contract object
+ // デプロイを開始し、コントラクトオブジェクトに解決されるpromiseを返します
const hello_world = await HelloWorld.deploy("Hello World!");
console.log("Contract deployed to address:", hello_world.address);}
@@ -322,48 +311,49 @@ main()
});
```
-Hardhatがコードの各行で行っている驚くべき内容については、Hardhatの[コントラクトチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で説明されています。以下では、その説明を採用しています。
+Hardhatは、[コントラクトのチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で、これらのコードの各行が何をするかを非常にうまく説明しています。ここではその説明を採用しました。
```
const HelloWorld = await ethers.getContractFactory("HelloWorld");
```
-ethers.jsの`ContractFactory`は新しいスマートコントラクトをデプロイするための抽象化であり、ここでの`HelloWorld`はhello worldコントラクトのインスタンスのためのファクトリです。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`および`Contract`インスタンスはデフォルトで最初の署名者に接続されます。
+ethers.jsの`ContractFactory`は、新しいスマートコントラクトをデプロイするために使用される抽象化です。したがって、ここでの`HelloWorld`は、私たちのhello worldコントラクトのインスタンスのためのファクトリです。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`および`Contract`インスタンスはデフォルトで最初の署名者に接続されます。
```
const hello_world = await HelloWorld.deploy();
```
-`ContractFactory`で`deploy()`を呼び出すとデプロイメントが開始され、`Contract`に解決すべき`Promise`が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。
+`ContractFactory`で`deploy()`を呼び出すとデプロイメントが開始され、`Contract`に解決される`Promise`が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。
## ステップ16: コントラクトをデプロイする {#step-16-deploy-our-contract}
-ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、以下を実行します。
+ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、次を実行します:
```
-npx hardhat run scripts/deploy.js --network goerli
+npx hardhat run scripts/deploy.js --network sepolia
```
次のような画面が表示されるはずです。
```
-Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
+コントラクトがデプロイされたアドレス: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
```
-[Goerli etherscan](https://goerli.etherscan.io/)に移動し、コントラクトアドレスを検索すると、コントラクトが正常にデプロイされていることを確認できるはずです。 トランザクションは以下のようなものになります。
+[Sepolia etherscan](https://sepolia.etherscan.io/)にアクセスし、コントラクトアドレスを検索すると、正常にデプロイされたことが確認できるはずです。 トランザクションは以下のようなものになります。
-
+
-`From`アドレスはMetaMaskアカウントアドレスと一致する必要があります。Toアドレスには「Contract Creation」と表示されますが、トランザクションをクリックすると、`To`フィールドにコントラクトアドレスが表示されます。
+`From`アドレスはMetaMaskアカウントのアドレスと一致し、`To`アドレスは「Contract Creation」と表示されますが、トランザクションをクリックすると`To`フィールドにコントラクトアドレスが表示されます。
-
+
-おめでとうございます! イーサリアムチェーンにスマートコントラクトをデプロイできました 🎉
+おめでとうございます! イーサリアムチェーンにスマートコントラクトをデプロイできました 🎉
-内部で何が起こっているのかを理解するために、[Alchemyダッシュボード](https://dashboard.alchemyapi.io/explorer)のExplorerタブに移動してみましょう。 Alchemyのアプリが複数ある場合は、必ずアプリでフィルタリングし、「Hello World」を選択してください。 
+内部で何が起こっているのかを理解するために、[Alchemyダッシュボード](https://dashboard.alchemyapi.io/explorer)のExplorerタブに移動してみましょう。 Alchemyアプリが複数ある場合は、必ずアプリでフィルタリングし、「Hello World」を選択してください。
+
-ここでは、`.deploy()`関数を呼び出した際に、Hardhat/Ethersが内部で行ったJSON-RPCの呼び出しを見ることができます。 ここで呼び出している2つの重要なJSON-RPCは、実際にGoerliチェーン上でコントラクトを書き込むリクエストの[`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction)と、(トランザクションの際の典型的なパターンである)ハッシュを与えられているトランザクションに関する情報を読み取るリクエストの[`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash)です。 トランザクションの送信の詳細については、こちらのチュートリアルの[Web3を使用したトランザクションの送信](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。
+ここでは、`.deploy()`関数を呼び出したときにHardhat/Ethersが内部で行ったいくつかのJSON-RPCコールを確認できます。 ここで注目すべき重要なコールは2つあります。1つは、コントラクトをSepoliaチェーンに実際に書き込むためのリクエストである[`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction)で、もう1つはハッシュが与えられたトランザクションに関する情報を読み取るためのリクエストである[`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash)です(これはトランザクションにおける典型的なパターンです)。 トランザクションの送信についてさらに詳しく知りたい場合は、[Web3を使用したトランザクションの送信](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)に関するチュートリアルをご覧ください。
-こちらのチュートリアルのパート1は以上となります。パート2では初期メッセージの更新による[スマートコントラクトとの実際のやり取り](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract)を、パート3では[Etherscanへのスマートコントラクトの公開](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan)を行い、やり取りする方法を学びます。
+このチュートリアルのパート1は以上です。パート2では、最初のメッセージを更新して[スマートコントラクトと実際に対話](https://www.alchemy.com/docs/interacting-with-a-smart-contract)し、パート3では[スマートコントラクトをEtherscanに公開](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan)して、誰もがその対話方法を知ることができるようにします。
-**Alchemyの詳細については、 [ウェブサイト](https://alchemyapi.io/eth)をご覧ください。 アップデートを見逃したくない場合は、 [こちら](https://www.alchemyapi.io/newsletter)でニュースレターを購読してください。 [Twitter](https://twitter.com/alchemyplatform)もあわせてフォローし、[Discord](https://discord.com/invite/u72VCg3)**にもご参加ください。
+**Alchemyについてもっと知りたいですか? 私たちの[ウェブサイト](https://www.alchemy.com/eth)をご覧ください。 アップデートを見逃したくないですか? [こちら](https://www.alchemy.com/newsletter)でニュースレターに登録してください! 私たちの[Discord](https://discord.gg/u72VCg3)にもぜひご参加ください。**
diff --git a/public/content/translations/ja/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/ja/developers/tutorials/how-to-implement-an-erc721-market/index.md
index b77db2aa191..2ebda7147f7 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-implement-an-erc721-market/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-implement-an-erc721-market/index.md
@@ -1,12 +1,8 @@
---
-title: ERC-721マーケットを実装する方法
-description: 分散型のクラシファイドボード(掲示板)に、トークン化されたアイテムを出品する方法
+title: "ERC-721マーケットを実装する方法"
+description: "分散型のクラシファイドボード(掲示板)に、トークン化されたアイテムを出品する方法"
author: "Alberto Cuesta Cañada"
-tags:
- - "スマートコントラクト"
- - "erc-721"
- - "Solidity"
- - "トークン"
+tags: [ "スマート契約", "ERC-721", "Solidity", "トークン" ]
skill: intermediate
lang: ja
published: 2020-03-19
@@ -22,17 +18,17 @@ Gumtree、Ebay、Craigslistといったインターネット掲示板が登場
ブロックチェーン技術は、この掲示板市場をさらに変革するものです。以下では、その方法について紹介します。
-## マネタイゼーション(収益化) {#monetization}
+## 収益化 {#monetization}
パブリックブロックチェーンにおける掲示板のビジネスモデルは、Ebayなどの企業のビジネスモデルとは異なります。
-まず第一に、 [脱中心化](/developers/docs/web2-vs-web3/)されている点を指摘すべきでしょう。 既存の掲示板プラットフォームは、自社サーバーを運用する必要があります。 しかし、分散型プラットフォームの運営はユーザーが実行するため、プラットフォーム所有者はコア・プラットフォームを稼働させるコストを負担する必要がありません。
+まず、[分散化という観点](/developers/docs/web2-vs-web3/)があります。 既存の掲示板プラットフォームは、自社サーバーを運用する必要があります。 しかし、分散型プラットフォームの運営はユーザーが実行するため、プラットフォーム所有者はコア・プラットフォームを稼働させるコストを負担する必要がありません。
-次に、プラットフォームにアクセスする機能を提供するウェブサイトまたはインターフェイスといったフロントエンドがあります。 フロントエンドには、いくつかのオプションがあります。 プラットフォーム所有者は、ユーザーのアクセス権限を制限し、インターフェイスを有料で使わせることができます。 一方で、プラットフォーム所有者がアクセス権限を開放し(人々に力を!)、ユーザーが自由にインターフェイスを開発できるようにすることもできます。 あるいは、これら2つの極端なアプローチの中間を選択することもできます。
+次に、プラットフォームにアクセスする機能を提供するウェブサイトまたはインターフェイスといったフロントエンドがあります。 フロントエンドには、いくつかのオプションがあります。 プラットフォーム所有者は、ユーザーのアクセス権限を制限し、インターフェイスを有料で使わせることができます。 プラットフォームの所有者は、アクセスを開放することも決定できます (Power to the People!) そして、誰でもプラットフォームへのインターフェースを構築できるようにします。 あるいは、これら2つの極端なアプローチの中間を選択することもできます。
-_私よりもビジネス感覚に優れている方は、これをどのように収益化すべきかについてよくご存じでしょう。 分散型のクラシファイドについて私が言えるのは、既存の掲示板プラットフォームとは異なっており、おそらく収益化が可能だということです。_
+_私よりも先見の明のあるビジネスリーダーは、これを収益化する方法を知っているでしょう。 私にわかるのは、これが現状とは異なり、おそらく利益になるだろうということだけです。_
-掲示板プラットフォームについては、自動化や支払い方法の視点からも考えることができます。 一部の商品は、[トークン化を非常に効果的に実行でき](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) 、掲示板での取引に適しています。 トークン化されたアセットは、ブロックチェーン上で簡単に移転できます。 また、ブロックチェーンでは、非常に複雑な支払い方法も簡単に実装できます。
+掲示板プラットフォームについては、自動化や支払い方法の視点からも考えることができます。 一部のものは、非常に[効果的にトークン化](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com)され、クラシファイドボードで取引できます。 トークン化されたアセットは、ブロックチェーン上で簡単に移転できます。 また、ブロックチェーンでは、非常に複雑な支払い方法も簡単に実装できます。
私はここに、ビジネスチャンスがあると感じているわけです。 トランザクションごとに複雑な支払経路を設定しつつ、運用コストが発生しない掲示板を、簡単に実装できるからです。 私は、ブロックチェーン・コミュニティから必ず、これを活用するアイディアが生まれてくると考えています。
@@ -40,9 +36,9 @@ _私よりもビジネス感覚に優れている方は、これをどのよう
## 実装 {#implementation}
-私たちは少し前に、具体的なビジネスケースに基づく実装やその他のリソースを提供する [オープンソースのリポジトリ](https://github.com/HQ20/contracts?ref=hackernoon.com)を立ち上げました。ぜひアクセスしてください。
+少し前に、ビジネスケースのサンプル実装やその他の特典を含む[オープンソースリポジトリ](https://github.com/HQ20/contracts?ref=hackernoon.com)を開始しました。ぜひご覧ください。
-この [イーサリアム・クラシファイド掲示板](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) のコードもレポジトリから入手できますので、自由に活用してください。 ただし、このコードは監査を経ていないため、お金を伴う取引を開始する前に、各自でデューデリジェンスを行う必要があります。
+この[Ethereumクラシファイドボード](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com)のコードはそこにあります。どうぞご自由にお使いください。 ただし、このコードは監査を経ていないため、お金を伴う取引を開始する前に、各自でデューデリジェンスを行う必要があります。
掲示板における基本的な機能はシンプルなものです。 掲示板におけるすべての投稿は、いくつかのフィールドを含む構造体に過ぎません:
@@ -67,9 +63,9 @@ mapping(uint256 => Trade) public trades;
次に、どのようなアイテムを扱う必要があり、取引の支払いにはどの通貨を使うかについて考える必要があります。
-取扱アイテムについては、[ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com)インターフェイスを実装すればよいです。このインターフェイスは、[デジタル資産と最も相性がよいのは事実ですが](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com)、現実に存在するアイテムをブロックチェーン上で表現するための手段に過ぎません。 この掲示板用の ERC-721コントラクトはコンストラクタで指定するため、掲示板に含まれるアセットは前もってトークン化しておく必要があります。
+アイテムについては、[ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com)インターフェースを実装することだけを求めます。これは現実世界のアイテムをブロックチェーンで表現する方法にすぎませんが、[デジタルアセットで最も効果的に機能します](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com)。 この掲示板用の ERC-721コントラクトはコンストラクタで指定するため、掲示板に含まれるアセットは前もってトークン化しておく必要があります。
-支払い機能についても、ほぼ同じです。 大部分のブロックチェーン・プロジェクトでは、独自の [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com)暗号通貨を定義しています。 DAIのように、著名な暗号通貨を採用する場合もあります。 このクラシファイド掲示板では、コンストラクタにおいて通貨を指定する必要があるだけです。 簡単ですね。
+支払い機能についても、ほぼ同じです。 ほとんどのブロックチェーンプロジェクトは、独自の[ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com)暗号通貨を定義しています。 DAIのように、著名な暗号通貨を採用する場合もあります。 このクラシファイド掲示板では、コンストラクタにおいて通貨を指定する必要があるだけです。 簡単ですね。
```solidity
constructor (
@@ -127,18 +123,18 @@ function cancelTrade(uint256 _trade)
Trade memory trade = trades[_trade];
require(
msg.sender == trade.poster,
- "Trade can be cancelled only by poster."
+ "取引は投稿者のみがキャンセルできます。"
);
- require(trade.status == "Open", "Trade is not Open.");
+ require(trade.status == "Open", "取引はオープン状態ではありません。");
itemToken.transferFrom(address(this), trade.poster, trade.item);
trades[_trade].status = "Cancelled";
emit TradeStatusChange(_trade, "Cancelled");
}
```
-以上です! これで、実装が完了しました。 この掲示板もそうですが、ビジネスコンセプトをコードで表現すると、驚くほど簡潔であることが少なくありません。 私たちのレポジトリから、[完成したコントラクト](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol)を入手できます。
+以上です! これで、実装が完了しました。 この掲示板もそうですが、ビジネスコンセプトをコードで表現すると、驚くほど簡潔であることが少なくありません。 完全なコントラクトは[私たちのリポジトリ](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol)で確認してください。
-## まとめ {#conclusion}
+## 結論 {#conclusion}
クラシファイド掲示板は、インターネットの普及に伴い爆発的に規模を拡大した一般的な市場構成であり、非常に人気のあるビジネスモデルを大手数社が独占している状態です。
@@ -146,4 +142,4 @@ function cancelTrade(uint256 _trade)
この記事は、実際の掲示板ビジネスと、技術的な実装との間にあるギャップを埋めるための試みです。 この記事に記載された知識を基に、適切なスキルを持つユーザーであれば、掲示板ビジネスのビジョンと実装ロードマップを生み出すことができるでしょう。
-いつものように、面白いプロジェクトを進行中で助言が必要な場合は、[ぜひご連絡ください](https://albertocuesta.es/)! いつでも喜んでお手伝いします。
+いつものように、面白いプロジェクトを進行中で助言が必要な場合は、ぜひ[ご連絡ください](https://albertocuesta.es/)! いつでも喜んでお手伝いします。
diff --git a/public/content/translations/ja/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/ja/developers/tutorials/how-to-mint-an-nft/index.md
index ef610e4373a..dab2badc296 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-mint-an-nft/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-mint-an-nft/index.md
@@ -1,28 +1,26 @@
---
-title: NFTのミント方法(NFTチュートリアルシリーズの2/3)
-description: このチュートリアルでは、スマートコントラクトとWeb3を使用してEthereumブロックチェーン上でNFTをミントする方法を説明します。
+title: "NFTのミント方法(NFTチュートリアルシリーズの2/3)"
+description: "このチュートリアルでは、スマートコントラクトとWeb3を使用してイーサリアムブロックチェーン上でNFTをミントする方法を説明します。"
author: "Sumi Mudgil"
-tags:
- - "ERC-721"
- - "alchemy"
- - "Solidity"
- - "スマートコントラクト"
+tags: [ "ERC-721", "Alchemy", "Solidity", "スマート契約" ]
skill: beginner
lang: ja
published: 2021-04-22
---
-[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): $69,000,000 [3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): $11,000,000 [Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): $6,000,000
+[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 6900万ドル
+[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 1100万ドル
+[Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 600万ドル
-いずれもAlchemyの強力なAPIを使ってNFTをミントしています。 このチュートリアルでは、\<10分以内でNFTをミントする方法を説明します。
+いずれもAlchemyの強力なAPIを使ってNFTをミントしています。 このチュートリアルでは、\<10分で同じことを行う方法を説明します。
-「NFTのミント」とは、ブロックチェーン上にERC-721トークンのユニークなインスタンスを公開することです。 [NFTチュートリアルシリーズのパート1](/developers/tutorials/how-to-write-and-deploy-an-nft/)で作成したスマートコントラクトを使って、Web3のスキルを駆使し、NFTをミントしてみましょう。 このチュートリアルが終わるころには、あなた(とウォレット) の望むがままにNFTをミントできるようになります。
+「NFTのミント」とは、ブロックチェーン上にERC-721トークンのユニークなインスタンスを公開することです。 この[NFTチュートリアルシリーズのパート1](/developers/tutorials/how-to-write-and-deploy-an-nft/)で作成したスマートコントラクトを使って、Web3のスキルを駆使し、NFTをミントしてみましょう。 このチュートリアルが終わるころには、あなた(とウォレット)が望むだけNFTをミントできるようになります。
さあ、始めましょう。
## ステップ1: Web3をインストールする {#install-web3}
-NFTスマートコントラクトの作成に関する最初のチュートリアルに沿って進めている場合、すでにEthers.jsを使用していることと思います。 Web3はEthersと同様、イーサリアムブロックチェーンへのリクエストを簡単に作成するために使用されるライブラリです。 このチュートリアルでは、自動再試行と堅牢なWebSocketサポートを提供する拡張Web3ライブラリ、[Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3)を使用します。
+NFTスマートコントラクトの作成に関する最初のチュートリアルに沿って進めている場合、すでにEthers.jsを使用した経験があるはずです。 Web3はEthersと同様、イーサリアムブロックチェーンへのリクエストを簡単に作成するために使用されるライブラリです。 このチュートリアルでは、自動再試行と堅牢なWebSocketサポートを提供する拡張Web3ライブラリである[Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3)を使用します。
プロジェクトのホームディレクトリで以下を実行します。
@@ -32,7 +30,7 @@ npm install @alch/alchemy-web3
## ステップ2: `mint-nft.js`ファイルを作成する {#create-mintnftjs}
-scriptsディレクトリ内に`mint-nft.js`ファイルを作成し、以下のコード行を追加します。
+`scripts`ディレクトリ内に`mint-nft.js`ファイルを作成し、以下のコード行を追加してください。
```js
require("dotenv").config()
@@ -43,19 +41,19 @@ const web3 = createAlchemyWeb3(API_URL)
## ステップ3: コントラクトABIを取得する {#contract-abi}
-コントラクトABI(アプリケーションバイナリインターフェイス)は、スマートコントラクトと対話するためのインターフェイスです。 コントラクトABIの詳細については、[こちら](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is)をご覧ください。 Hardhatは自動的にABIを生成して、`MyNFT.json`ファイルに保存します。 このABIを使用するには、`mint-nft.js`に次のコードを追加して、ABIをパースする必要があります。
+コントラクトABI (Application Binary Interface) は、スマートコントラクトと対話するためのインターフェイスです。 コントラクトABIの詳細は[こちら](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is)をご覧ください。 Hardhatは自動的にABIを生成し、`MyNFT.json`ファイルに保存します。 これを使用するには、`mint-nft.js`ファイルに以下のコード行を追加してコンテンツを解析する必要があります。
```js
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
```
-ABIを表示したい場合は、次のコードを追加することでコンソールに出力できます:
+ABIを確認したい場合は、コンソールに出力できます:
```js
console.log(JSON.stringify(contract.abi))
```
-`mint-nft.js`を実行し、コンソールに出力されたABIを表示するには、ターミナルに移動して次のコードを実行します。
+`mint-nft.js`を実行し、コンソールに出力されたABIを確認するには、ターミナルに移動して以下を実行します。
```js
node scripts/mint-nft.js
@@ -63,61 +61,61 @@ node scripts/mint-nft.js
## ステップ4: IPFSを使用してNFTのメタデータを設定する {#config-meta}
-パート1のチュートリアルを思い出してください。スマートコントラクトの`mintNFT`関数は、NFTのメタデータを記述したJSONドキュメントで解決すべきtokenURIパラメータを取り込みます。その結果、NFTが生成され、名前、記述、画像、その他の属性などの設定可能なプロパティを実装することができます。
+パート1のチュートリアルで触れたように、`mintNFT`スマートコントラクト関数は、`tokenURI`パラメータを受け取ります。このパラメータは、NFTのメタデータを記述したJSONドキュメントに解決される必要があります。このメタデータこそがNFTに命を吹き込み、名前、説明、画像、その他の属性などの設定可能なプロパティを持たせることを可能にするのです。
-> _Interplanetary File System(IPFS)は、分散型ファイルシステムでデータを格納、共有するための分散プロトコルであり、ピアツーピアネットワークです。_
+> _Interplanetary File System (IPFS) は、分散ファイルシステムでデータを保存・共有するための、分散型プロトコルでありピアツーピアネットワークです。_
-私たちは、NFTアセットとメタデータを保存してNFTを真に分散化するために、便利なIPFS APIとツールキットであるPinataを使用します。 Pinataアカウントをお持ちでない場合は、[こちら](https://app.pinata.cloud)から無料アカウントにサインアップし、メールアドレスの認証手順を完了してください。
+NFTが真に分散化されるように、便利なIPFS APIおよびツールキットであるPinataを使用して、NFTのアセットとメタデータを保存します。 Pinataのアカウントをお持ちでない場合は、[こちら](https://app.pinata.cloud)から無料アカウントにサインアップし、メールアドレスの認証手続きを完了してください。
-アカウント作成後の手順:
+アカウントを作成したら:
-- 「Files」ページに移動し、ページの左上にある青色の「Upload」ボタンをクリックします。
+- 「Files」ページに移動し、ページの左上にある青い「Upload」ボタンをクリックします。
-- Pinataに画像をアップロードします。これがNFTの画像アセットになります。 アセットに好きな名前を付けてください。
+- 画像をPinataにアップロードします。これがあなたのNFTの画像アセットになります。 アセットには自由に名前を付けてかまいません。
-- アップロード後、「Files」ページのテーブルにファイル情報が表示されます。 また、CID列も表示されます。 隣のコピーボタンをクリックするとCIDをコピーできます。 アップロードは`https://gateway.pinata.cloud/ipfs/`で確認できます。 例えば、IPFSで使われている画像は、[こちら](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5)です。
+- アップロード後、「Files」ページのテーブルにファイル情報が表示されます。 CID列も表示されます。 隣にあるコピーボタンをクリックすると、CIDをコピーできます。 アップロードしたファイルは `https://gateway.pinata.cloud/ipfs/` で確認できます。 例えば、私たちが使用した画像はIPFS上の[こちら](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5)にあります。
-視覚型学習者のために、上記の手順を要約します。
+視覚的に学習したい方のために、上記の手順を以下にまとめます。

-次に、Pinataにもう1件ドキュメントをアップロードしますが、 その前にドキュメントを作成する必要があります。
+さて、Pinataにもう一つドキュメントをアップロードします。 しかしその前に、それを作成する必要があります。
-ルートディレクトリに`nft-metadata.json`というファイルを新規作成し、以下のjsonコードを追加してください。
+ルートディレクトリに `nft-metadata.json` という新しいファイルを作成し、以下のJSONコードを追加してください。
```json
{
"attributes": [
{
- "trait_type": "Breed",
- "value": "Maltipoo"
+ "trait_type": "品種",
+ "value": "マルプー"
},
{
- "trait_type": "Eye color",
- "value": "Mocha"
+ "trait_type": "目の色",
+ "value": "モカ"
}
],
- "description": "The world's most adorable and sensitive pup.",
+ "description": "世界で最も愛らしくて繊細な子犬です。",
"image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
- "name": "Ramses"
+ "name": "ラムセス"
}
```
-json内のデータは自由に変更できます。 属性セクションを削除または追加できます。 最も重要なことは、画像フィールドがIPFS画像の位置を指していることを確認することです。そうしないと、NFTに(とても可愛い)犬の写真が含まれます。
+JSON内のデータは自由に変更してかまいません。 `attributes`セクションは削除したり、追加したりできます。 最も重要なのは、`image`フィールドがあなたのIPFS画像の場所を指していることを確認することです。さもなければ、あなたのNFTには(とてもかわいい!) 犬の写真が含まれてしまいます。
-JSONファイルの編集が終わったら、保存して、画像のアップロードと同じ手順でPinataにアップロードしてください。
+JSONファイルの編集が終わったら保存し、画像をアップロードしたのと同じ手順でPinataにアップロードしてください。
-
+
## ステップ5: コントラクトのインスタンスを作成する {#instance-contract}
-ここで、私たちのコントラクトと対話するには、コード内でインスタンスを作成する必要があります インスタンスの作成には、コントラクトアドレスが必要になります。コントラクトをデプロイする際に使用したアドレスを検索することで、デプロイメントまたは[Etherscan](https://sepolia.etherscan.io/)から取得できます。
+さて、コントラクトとやりとりするには、コード内でそのインスタンスを作成する必要があります。 そのためにはコントラクトアドレスが必要ですが、これはデプロイメントから取得するか、コントラクトのデプロイに使用したアドレスを[Blockscout](https://eth-sepolia.blockscout.com/)で検索することで取得できます。
-
+
-上記の例では、コントラクトのアドレスは、0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778です。
+上記の例では、コントラクトアドレスは`0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778`です。
-次に、Web3の[コントラクトメソッド](https://docs.web3js.org/api/web3-eth-contract/class/Contract)を活用して、ABIとアドレスを使用したコントラクトを作成します。 `mint-nft.js`ファイルに以下を追加します。
+次に、ABIとアドレスを使い、Web3の[contractメソッド](https://docs.web3js.org/api/web3-eth-contract/class/Contract)でコントラクトを作成します。 `mint-nft.js`ファイルに、以下を追加します。
```js
const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
@@ -125,39 +123,39 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
```
-## ステップ6: `.env`ファイルをアップデートする {#update-env}
+## ステップ6: `.env`ファイルを更新する {#update-env}
-それでは、イーサリアムチェーンにトランザクションを作成して送信するために、公開されているイーサリアムのアカウントアドレスを使用してアカウントのノンスを取得します(以下で説明します)。
+さて、イーサリアムチェーンにトランザクションを作成して送信するために、あなたの公開イーサリアムアカウントアドレスを使用してアカウントのノンス(後述)を取得します。
-`.env`ファイルにあなたの公開鍵を追加します。チュートリアルのパート1を完了している場合、`.env`ファイルは次のようになっているはずです。
+あなたの公開鍵を`.env`ファイルに追加してください。チュートリアルのパート1を完了している場合、`.env`ファイルは次のようになっているはずです:
```js
-API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key"
-PRIVATE_KEY = "your-private-account-address"
-PUBLIC_KEY = "your-public-account-address"
+API_URL = "https://eth-sepolia.g.alchemy.com/v2/あなたのAPIキー"
+PRIVATE_KEY = "あなたのプライベートアカウントアドレス"
+PUBLIC_KEY = "あなたのパブリックアカウントアドレス"
```
## ステップ7: トランザクションを作成する {#create-txn}
-まず、`mintNFT(tokenData)`という名前の関数を定義し、次のようにトランザクションを作成してみましょう。
+まず、`mintNFT(tokenData)`という名前の関数を定義し、以下のようにトランザクションを作成します。
-1. _PRIVATE_KEY_と_PUBLIC_KEY_を`.env`ファイルから取得します。
+1. `.env`ファイルから_PRIVATE_KEY_と_PUBLIC_KEY_を取得します。
-1. 次に、アカウントのノンスを確認します。 ノンスの指定は、あなたのアドレスから送信されたトランザクションの数を追跡するために使用されます。これは、セキュリティ目的で、[リプレイ攻撃](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce)を防ぐために必要となります。 あなたのアドレスから送信されたトランザクションの数を取得するには、 [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount)を使用します。
+2. 次に、アカウントのノンスを確認する必要があります。 ノンスの仕様は、あなたのアドレスから送信されたトランザクション数を追跡するために使用されます。これは、セキュリティ上の目的と、[リプレイ攻撃](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce)を防ぐために必要です。 あなたのアドレスから送信されたトランザクション数を取得するには、[getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount)を使用します。
-1. 最後に、以下の情報を使用してトランザクションを設定します。
+3. 最後に、以下の情報でトランザクションをセットアップします。
-- `'from': PUBLIC_KEY` — トランザクションの発信元は公開アドレス
+- `'from': PUBLIC_KEY` — トランザクションの発信元である、私たちの公開アドレス
-- `'to': contractAddress` — 対話し、トランザクションを送信したいコントラクト
+- `'to': contractAddress` — やりとりを行い、トランザクションを送信したいコントラクト
-- `'nonce': nonce` — アドレスから送信されたトランザクションの数を持つアカウントのノンス
+- `'nonce': nonce` — 私たちのアドレスから送信されたトランザクション数を含むアカウントのノンス
-- `'gas': estimatedGas` —トランザクションを完了するために必要な推定ガス
+- `'gas': estimatedGas` — トランザクションを完了するために必要な推定ガス量
-- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — このトランザクションで実行したい計算。今回の場合は、NFTを発行すること。
+- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — このトランザクションで実行したい計算、この場合はNFTのミント
-`mint-nft.js`ファイルは、現在このような状態になっているはずです。
+`mint-nft.js`ファイルは次のようになっているはずです:
```js
require('dotenv').config();
@@ -175,7 +173,7 @@ PUBLIC_KEY = "your-public-account-address"
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
- //the transaction
+ //トランザクション
const tx = {
'from': PUBLIC_KEY,
'to': contractAddress,
@@ -188,9 +186,9 @@ PUBLIC_KEY = "your-public-account-address"
## ステップ8: トランザクションに署名する {#sign-txn}
-さて、トランザクションを作成したら、それを送信するために署名する必要があります。 ここで秘密鍵を使用します。
+トランザクションを作成したので、次に送信するために署名する必要があります。 ここで秘密鍵を使用します。
-`web3.eth.sendSignedTransaction`はトランザクションハッシュを提供することで、トランザクションがきちんとマイニングされ、ネットワークによってドロップされていないことを確認できます。 トランザクション署名のセクションにいくつかエラーチェックを追加することで、トランザクションが正常に完了したかどうかを確認できるようにしておきます。
+`web3.eth.sendSignedTransaction`はトランザクションハッシュを返します。これを使用して、トランザクションがマイニングされ、ネットワークによってドロップされなかったことを確認できます。 トランザクション署名のセクションでは、トランザクションが正常に実行されたかどうかを知るために、エラーチェックを追加していることにお気づきでしょう。
```js
require("dotenv").config()
@@ -208,7 +206,7 @@ const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
- //the transaction
+ //トランザクション
const tx = {
from: PUBLIC_KEY,
to: contractAddress,
@@ -225,13 +223,13 @@ async function mintNFT(tokenURI) {
function (err, hash) {
if (!err) {
console.log(
- "The hash of your transaction is: ",
+ "トランザクションのハッシュ: ",
hash,
- "\nCheck Alchemy's Mempool to view the status of your transaction!"
+ "\nAlchemyのメンプールでトランザクションのステータスを確認してください!"
)
} else {
console.log(
- "Something went wrong when submitting your transaction:",
+ "トランザクションの送信中に問題が発生しました:",
err
)
}
@@ -239,24 +237,24 @@ async function mintNFT(tokenURI) {
)
})
.catch((err) => {
- console.log(" Promise failed:", err)
+ console.log(" Promiseが失敗しました:", err)
})
}
```
-## ステップ9: `mintNFT`を呼び出し、ノード`mint-nft.js`を実行する {#call-mintnft-fn}
+## ステップ9: `mintNFT`を呼び出し、`node mint-nft.js`を実行する {#call-mintnft-fn}
-Pinataにアップロードした`metadata.json`を覚えているでしょうか。 Pinataからそのハッシュコードを取得し、`https://gateway.pinata.cloud/ipfs/`をパラメータとして、関数`mintNFT`に渡します。
+Pinataにアップロードした`metadata.json`を覚えていますか? Pinataからそのハッシュコードを取得し、`https://gateway.pinata.cloud/ipfs/`をパラメータとして`mintNFT`関数に渡します。
-ハッシュコードを取得する方法をこちらにご紹介します。
+ハッシュコードを取得する方法は次のとおりです。
-_Pinataでnftメタデータハッシュコードを取得する方法_
+_PinataでNFTメタデータのハッシュコードを取得する方法_
-> 別のウィンドウで`https://gateway.pinata.cloud/ipfs/`を読み込んでみて、コピーしたハッシュコードが**metadata.json**にリンクしているか確認します。 以下のスクリーンショットと類似したページが表示されるはずです。
+> 別のウィンドウで `https://gateway.pinata.cloud/ipfs/` を読み込み、コピーしたハッシュコードがあなたの**metadata.json**にリンクしていることを再確認してください。 ページは下のスクリーンショットのようになっているはずです。
-_ページにjsonメタデータが表示されるはずです_
+_ページにJSONメタデータが表示されるはずです_
-最終的には、次のようなコードになっているはずです。
+すべてをまとめると、コードは次のようになります。
```js
require("dotenv").config()
@@ -274,7 +272,7 @@ const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
- //the transaction
+ //トランザクション
const tx = {
from: PUBLIC_KEY,
to: contractAddress,
@@ -291,13 +289,13 @@ async function mintNFT(tokenURI) {
function (err, hash) {
if (!err) {
console.log(
- "The hash of your transaction is: ",
+ "トランザクションのハッシュ: ",
hash,
- "\nCheck Alchemy's Mempool to view the status of your transaction!"
+ "\nAlchemyのメンプールでトランザクションのステータスを確認してください!"
)
} else {
console.log(
- "Something went wrong when submitting your transaction:",
+ "トランザクションの送信中に問題が発生しました:",
err
)
}
@@ -305,25 +303,27 @@ async function mintNFT(tokenURI) {
)
})
.catch((err) => {
- console.log("Promise failed:", err)
+ console.log("Promiseが失敗しました:", err)
})
}
mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP")
```
-次に、`node scripts/mint-nft.js`を実行してNFTをデプロイします。 数秒後にターミナル上に次のようなレスポンスが表示されるはずです。
+さて、`node scripts/mint-nft.js`を実行して、NFTをミントしましょう。 数秒後、ターミナルに次のような応答が表示されるはずです。
- The hash of your transaction is: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8
+ ```
+ トランザクションのハッシュ: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8
- Alchemyのメンプールをチェックし、あなたのトランザクションのステータスを確認しましょう。
+ Alchemyのメンプールでトランザクションのステータスを確認してください!
+ ```
-[Alchemy mempool](https://dashboard.alchemyapi.io/mempool)にアクセスして、トランザクションのステータス(保留中、マイニング中、ネットワークによってドロップされたかどうか)を確認します。 トランザクションが削除された場合は、 [Sepolia Etherscan](https://sepolia.etherscan.io/)を確認してトランザクションハッシュを検索することもできます。
+次に、[Alchemyメンプール](https://dashboard.alchemyapi.io/mempool)にアクセスして、トランザクションのステータス(ペンディング、マイニング済み、またはネットワークによるドロップ)を確認します。 トランザクションがドロップされた場合は、[Blockscout](https://eth-sepolia.blockscout.com/)でトランザクションハッシュを検索して確認することも役立ちます。
-_EtherscanでNFTトランザクションハッシュを表示します_
+_EtherscanでNFTトランザクションハッシュを表示_
-以上で完了です。 イーサリアムブロックチェーン上にデプロイしてNFTをミントしました。
+以上です。 これで、イーサリアムブロックチェーン上でNFTをデプロイし、ミントしました
-`mint-nft.js`を使えば、あなたの心(ウォレット)が望むだけ、NFTをミントすることができます。 NFTのメタデータを記述した新しいtokenURIを必ず渡してください(この作業を怠ると、異なるIDを備えた同一のものを大量に作成してしまいます)。
+`mint-nft.js`を使えば、あなた(とウォレット)が望むだけNFTをミントできます。 必ずNFTのメタデータを記述した新しい`tokenURI`を渡すようにしてください(そうしないと、IDが違うだけで同一のものを大量に作ってしまうことになります)。
-ウォレットにNFTを表示する方法については、[パート3: ウォレットにNFTを表示する方法](/developers/tutorials/how-to-view-nft-in-metamask/)をご覧ください。
+おそらく、ウォレットで自分のNFTを披露したいと思うでしょう。そのために、ぜひ[パート3: ウォレットでNFTを表示する方法](/developers/tutorials/how-to-view-nft-in-metamask/)もチェックしてください。
diff --git a/public/content/translations/ja/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/ja/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md
index af2a8e5f252..715d54d0ea2 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md
@@ -1,30 +1,26 @@
---
-title: Solidity で、スマートコントラクトのテスト用モックアップを作成する方法
-description: テストでは、コントラクトのモックアップを使用すべき理由
+title: "Solidity で、スマートコントラクトのテスト用モックアップを作成する方法"
+description: "テストでは、コントラクトのモックアップを使用すべき理由"
author: Markus Waas
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "テスト"
- - "モック"
+tags: [ "Solidity", "スマート契約", "テスト", "モックアップ作成" ]
skill: intermediate
published: 2020-05-02
source: soliditydeveloper.com
sourceUrl: https://soliditydeveloper.com/mocking-contracts
---
-[モック・オブジェクト](https://wikipedia.org/wiki/Mock_object) は、オブジェクト指向プログラミングにおいて一般的なデザインパターンです。 「モック」という言葉は、古フランス語で「からかう」という意味を持つ「mocquer」が由来で、「本物を模倣する」という意味に発展しました。これこそ、プログラミングにで「モックアップ」を作成する作業です。 あなたが作成したスマートコントラクトについて「からかう」必要はありませんが、「モックアップ」の作成はできる限り必ず行ってください。 後々、楽になります。
+「[モックオブジェクト](https://wikipedia.org/wiki/Mock_object)」は、オブジェクト指向プログラミングにおいて一般的なデザインパターンです。 「モック」という言葉は、古フランス語で「からかう」という意味を持つ「mocquer」が由来で、「本物を模倣する」という意味に発展しました。これこそ、プログラミングにで「モックアップ」を作成する作業です。 あなたが作成したスマートコントラクトについて「からかう」必要はありませんが、「モックアップ」の作成はできる限り必ず行ってください。 後々、楽になります。
-## コントラクトのモックアップを使った単体テスト {#unit-testing-contracts-with-mocks}
+## モックを使ったコントラクトの単体テスト {#unit-testing-contracts-with-mocks}
-コントラクトのモックアップを作成するとは、究極的に、オリジナルとほぼ同様に動作するものの、デベロッパが簡単に管理できる第2のバージョンを作成することです。 複雑なコントラクトを開発すると、[コントラクト全体の一部のみを単体テストする](/developers/docs/smart-contracts/testing/)必要が発生する場合が少なくありません。 問題となるのは、この一部分をテストする上で、非常に具体的なコントラクトの状態を再現する必要があるものの、再現するのが難しい場合です。
+コントラクトのモックアップを作成するとは、究極的に、オリジナルとほぼ同様に動作するものの、デベロッパが簡単に管理できる第2のバージョンを作成することです。 複雑なコントラクトを扱うことになると、[コントラクトのごく一部だけを単体テスト](/developers/docs/smart-contracts/testing/)したい場合がよくあります。 問題となるのは、この一部分をテストする上で、非常に具体的なコントラクトの状態を再現する必要があるものの、再現するのが難しい場合です。
テストに求められる状態を再現するために、テストを設定するための複雑なロジックを作成する代わりに、モックアップを作成すればよいのです。 コントラクトのモックアップは、継承を使って簡単に作成できます。 オリジナル版を継承したモックアップのコントラクトを作成するだけです。 モックアップでは、機能をオーバーライドすることができます。 この点については、具体例で見てみましょう。
-## 例:プライベートのERC-20コントラクト {#example-private-erc20}
+## 例: Private ERC20 {#example-private-erc20}
-ここでは、当初にプライベート期間が設定された ERC-20 コントラクトを使って説明します。 トークン所有者はプライベートユーザーを管理でき、当初トークンを受け取ることができるのはプライベートユーザーのみになります。 設定した時間が経過した後は、すべてのユーザーがトークンを使用できるようになります。 参考までに、この例では新しいOpenZeppelinコントラクトv3に含まれている[`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks)フックを使用しています。
+ここでは、当初にプライベート期間が設定された ERC-20 コントラクトを使って説明します。 トークン所有者はプライベートユーザーを管理でき、当初トークンを受け取ることができるのはプライベートユーザーのみになります。 設定した時間が経過した後は、すべてのユーザーがトークンを使用できるようになります。 ちなみに、新しいOpenZeppelin contracts v3の[`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks)フックを使用しています。
```solidity
pragma solidity ^0.6.0;
@@ -90,17 +86,17 @@ contract PrivateERC20Mock is PrivateERC20 {
- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.`
- `PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.`
-Solidityの新しいバージョン(0.6)を使用しているため、オーバーライド可能な関数については`virtual`のキーワードを追加して、オーバーライド関数をオーバーライドする必要があります。 このため、両方の`isPublic`関数にこのキーワードを追加します。
+新しいSolidityバージョン0.6を使用しているため、オーバーライドされる関数には`virtual`キーワードを、オーバーライドする関数には`override`を追加する必要があります。 では、両方の`isPublic`関数にそれらを追加しましょう。
-これで、単体テストで`PrivateERC20Mock`を使えるようになりました。 プライベート利用期間中の動作をテストしたい場合は、`setIsPublic(false)`を使用し、パブリック利用期間については`setIsPublic(true)`を使ってテストしてください。 もちろん、[time helpers](https://docs.openzeppelin.com/test-helpers/0.5/api#increase)を使って、対象時間を変更することもできます。 しかし、すでにモックアップの有用性について理解できたでしょう。単に時間を進めるよりも、モックアップを利用した方が望ましいシナリオがすぐに思い浮かぶはずです。
+これで、単体テストで代わりに`PrivateERC20Mock`を使用できます。 プライベート利用期間中の動作をテストしたい場合は`setIsPublic(false)`を、同様にパブリック利用期間のテストには`setIsPublic(true)`を使用します。 もちろん、この例では[タイムヘルパー](https://docs.openzeppelin.com/test-helpers/0.5/api#increase)を使って、時間も同様に変更することもできます。 しかし、すでにモックアップの有用性について理解できたでしょう。単に時間を進めるよりも、モックアップを利用した方が望ましいシナリオがすぐに思い浮かぶはずです。
-## 複数のコントラクトに対してモックアップを作成する場合 {#mocking-many-contracts}
+## 多数のコントラクトのモック {#mocking-many-contracts}
-モックアップごとに新たなコントラクトを作成するのは煩雑な作業ですね。 これを避けたい場合は、[MockContract](https://github.com/gnosis/mock-contract)ライブラリを参照してください。 このライブラリを用いることで、コントラクトの動作をその場でオーバーライドし、変更することができます。 ただしこのライブラリは、別のコントラクトに対する呼び出しのみに対応していますので、今回は使用できません。
+モックアップごとに新たなコントラクトを作成するのは煩雑な作業ですね。 これが気になる場合は、[MockContract](https://github.com/gnosis/mock-contract)ライブラリをご覧ください。 これにより、コントラクトの動作をその場でオーバーライドして変更できます。 ただしこのライブラリは、別のコントラクトに対する呼び出しのみに対応していますので、今回は使用できません。
-## モックアップは、その他にも利点があります {#mocking-can-be-even-more-powerful}
+## モックはさらに強力になりうる {#mocking-can-be-even-more-powerful}
モックアップ作成のメリットは、他にもあります。
-- 関数の追加:特定の関数をオーバーライドする機能だけでなく、関数を追加できることも有益です。 トークンを対象とする場合のよい例としては、`ミント`機能を追加することで、ユーザーが新規トークンを無料で手に入れられるようにすることができます。
+- 関数の追加:特定の関数をオーバーライドする機能だけでなく、関数を追加できることも有益です。 トークンの良い例として、追加の`mint`関数を持たせることで、どのユーザーでも新しいトークンを無料で取得できるようにすることが挙げられます。
- テストネットでの使用:Dapp と共に、テストネット上でコントラクトをデプロイ、テストする際は、モックアップの活用を検討すべきです。 本当に必要な場合を除き、関数をオーバーライドすることは避けるべきです。 結局のところ、実際のロジックをテストする必要があるからです。 しかし例えば、コントラクトのステートを、新たにデプロイする必要なしで開始時点にリセットするだけのリセット機能は、有益な場合があるでしょう。 言うまでもなく、メインネット用のコントラクトにはこのようなリセット機能を含めてはなりません。
diff --git a/public/content/translations/ja/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/ja/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md
index e481f540dfb..177724c76a1 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md
@@ -1,17 +1,12 @@
---
-title: スマートコントラクトのテストにEchidnaを使用する方法
-description: Echidnaを使用して、スマートコントラクトを自動でテストする方法
+title: "Echidnaを使用してスマートコントラクトをテストする方法"
+description: "Echidnaを使用してスマートコントラクトを自動テストする方法"
author: "Trailofbits"
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "セキュリティ"
- - "テスト"
- - "ファジング"
+tags: [ "Solidity", "スマート契約", "セキュリティ", "テスト", "ファジング" ]
skill: advanced
published: 2020-04-10
-source: セキュアなコントラクトの構築
+source: Building secure contracts
sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna
---
@@ -19,53 +14,53 @@ sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/progr
Echidnaは、Dockerまたはコンパイル済みのバイナリを使用してインストールします。
-### DockerからEchidnaをインストールする {#echidna-through-docker}
+### DockerによるEchidna {#echidna-through-docker}
```bash
docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox
```
-_最後のコマンドは、現在のディレクトリにアクセスできるdockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、dockerからファイル上のツールを実行できます。_
+_最後のコマンドは、現在のディレクトリにアクセスできるDockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、Dockerからファイル上のツールを実行できます。_
-dockerで、以下を実行します:
+Docker内で次を実行します:
```bash
solc-select 0.5.11
cd /home/training
```
-### バイナリの入手先 {#binary}
+### バイナリ {#binary}
[https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0)
-## プロパティベースのファジングとは {#introduction-to-property-based-fuzzing}
+## プロパティベースファジング入門 {#introduction-to-property-based-fuzzing}
-Echidnaは、プロパティベースのファザーです。これについては、以前のブログ投稿([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/)、[2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/)、[3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/))を参照してください。
+Echidnaはプロパティベースのファザーであり、以前のブログ投稿([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/)、[2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/)、[3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/))で説明しています。
### ファジング {#fuzzing}
-[ファジング ](https://wikipedia.org/wiki/Fuzzing)は、セキュリティコミュニティでよく知られているテクニックです。 ファジングでは、プログラム内のバグを見つけるために、大小のランダムな入力を生成することを行います。 通常のソフトウェアを対象とするファザー([AFL](http://lcamtuf.coredump.cx/afl/)や[LibFuzzer](https://llvm.org/docs/LibFuzzer.html)など)は、効率的にバグを特定できるツールであると評価されています。
+[ファジング](https://wikipedia.org/wiki/Fuzzing)は、セキュリティコミュニティでよく知られているテクニックです。 プログラム内のバグを見つけるために、ある程度ランダムな入力を生成するものです。 従来のソフトウェア用のファザー([AFL](http://lcamtuf.coredump.cx/afl/)や[LibFuzzer](https://llvm.org/docs/LibFuzzer.html)など)は、バグを見つけるための効率的なツールとして知られています。
-入力をまったくランダムに生成するだけでなく、適切な入力を生成するための多くのテクニックや戦略を活用できます:
+純粋にランダムな入力生成以外に、適切な入力を生成するための多くのテクニックや戦略があります。以下に例を挙げます。
-- 各実行から取得したフィードバックに基づき、入力を生成する。 例えば、新しく生成された入力値が新しいパスの発見を導いている場合、それに近い新しい入力値を生成することは理にかなっています。
-- 構造上の制約を考慮した入力を生成する。 例えば、入力にチェックサム付のヘッダーが含まれている場合、ファザーにチェックサムを検証する入力を生成させることも有益です。
-- 既知の入力に基づいて新たな入力を生成する。大規模な有効な入力のデータセットにアクセスできる場合、まったくランダムに生成するのではなく、それらに基づいて新たな入力を生成することができます。 この場合、参照するデータを_シード_と呼びます。
+- 各実行からフィードバックを取得し、それを使用して生成をガイドします。 例えば、新しく生成された入力が新しいパスの発見につながる場合、それに近い新しい入力を生成することは理にかなっています。
+- 構造的制約を尊重して入力を生成する。 例えば、入力にチェックサム付きのヘッダーが含まれている場合、ファザーにチェックサムを検証する入力を生成させるのは理にかなっています。
+- 既知の入力を使用して新しい入力を生成する:有効な入力の大規模なデータセットにアクセスできる場合、ファザーはゼロから生成を開始するのではなく、それらから新しい入力を生成できます。 これらは通常、_シード_と呼ばれます。
-### プロパティベースのファジング {#property-based-fuzzing}
+### プロパティベースファジング {#property-based-fuzzing}
-Echidnaは、プロパティに基づくファジングを実行するファザーであり、[QuickCheck](https://wikipedia.org/wiki/QuickCheck)の影響を強く受けたプログラムです。 クラッシュを監視する従来のファザーとは異なり、Echidnaでは、ユーザー定義の不変条件を壊そうとします。
+Echidnaは、[QuickCheck](https://wikipedia.org/wiki/QuickCheck)に強くインスパイアされたプロパティベースファジングという、ファザーの特定の種類に属します。 クラッシュを見つけようとする従来のファザーとは対照的に、Echidnaはユーザー定義の不変条件を破ろうとします。
-スマートコントラクトにおける不変条件とは、コントラクトにおいて不適切または無効な状態が発生しうるSolidityの関数を意味します。具体的には、以下が挙げられます:
+スマートコントラクトにおける不変条件とは、コントラクトが到達しうる不正または無効な状態を表すSolidity関数であり、次のようなものが含まれます。
-- 不適切なアクセス制御:攻撃者がコントラクトの所有者になる場合。
-- 不適切な状態マシン:コントラクトの一次停止中に、トークンを送信できる。
-- 不適切な計算: ユーザーは残高をアンダーフローし無制限に無料トークンを取得できる。
+- 不正なアクセス制御:攻撃者がコントラクトの所有者になる。
+- 不正な状態マシン:コントラクトが一時停止している間にトークンを転送できる。
+- 不正な算術演算:ユーザーが残高をアンダーフローさせ、無制限の無料トークンを取得できる。
-### Echidnaを使って、プロパティをテストする {#testing-a-property-with-echidna}
+### Echidnaでプロパティをテストする {#testing-a-property-with-echidna}
-それでは、Echidnaを使ってスマートコントラクトをテストする方法を見てみましょう。 対象は、[ `token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol)のスマートコントラクトです。
+Echidnaを使ってスマートコントラクトをテストする方法を見ていきましょう。 対象は、次のスマートコントラクト[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol)です。
```solidity
contract Token{
@@ -83,26 +78,26 @@ contract Token{
}
```
-このトークンは、以下のプロパティを持つと想定します:
+このトークンは、以下のプロパティを持つと想定します。
-- ユーザーは、最大1000トークンを所持できる
-- このトークン(ERC-20トークンではない)は、送信不可である
+- 誰でも最大1000トークンを保有できます
+- このトークンは転送できません(ERC20トークンではありません)
### プロパティを記述する {#write-a-property}
-Echidnaのプロパティは、Solidityの関数です。 プロパティは、以下の条件を満たす必要があります:
+Echidnaのプロパティは、Solidityの関数です。 プロパティは、以下の条件を満たす必要があります。
- 引数を持たない
-- 実行に成功した場合、 `true` を返す
-- `echidna`で始まる名前を持つ
+- 成功した場合に`true`を返す
+- 名前が`echidna`で始まる
-Echidnaは、以下を実行します:
+Echidnaは、以下を実行します。
-- このプロパティをテストするためのランダムなトランザクションを自動で生成する。
-- プロパティが `false`またはエラーを返すすべてのトランザクションを報告する。
-- プロパティの呼び出しに伴う副作用を無視する(つまり、プロパティが状態変数を変更した場合、テスト後にこの変更を破棄する)
+- プロパティをテストするために、任意のトランザクションを自動的に生成します。
+- プロパティが`false`を返すか、エラーをスローするトランザクションを報告します。
+- プロパティ呼び出し時の副作用を破棄する(つまり、プロパティが状態変数を変更した場合、テスト後にその変更は破棄されます)
-以下のプロパティは、呼び出し元のユーザーが所持するトークンが1000以下であることを確認します。
+以下のプロパティは、呼び出し元が1000トークンを超えて保有していないことをチェックします。
```solidity
function echidna_balance_under_1000() public view returns(bool){
@@ -120,36 +115,36 @@ contract TestToken is Token{
}
```
-[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol)は、プロパティを実装し、このトークンを継承します。
+[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol)はプロパティを実装し、トークンを継承します。
-### コントラクトを開始する {#initiate-a-contract}
+### コントラクトの初期化 {#initiate-a-contract}
-Echidnaでは、引数なしの[コンストラクタ](/developers/docs/smart-contracts/anatomy/#constructor-functions)が必要です。 コントラクトにおいて特定の初期化が必要な場合、コンストラクタ上で実行する必要があります。
+Echidnaには、引数のない[コンストラクタ](/developers/docs/smart-contracts/anatomy/#constructor-functions)が必要です。 コントラクトに特定の初期化が必要な場合、コンストラクタで行う必要があります。
-Echidnaには、いくつかの特定のアドレスが含まれます:
+Echidnaには、いくつかの特定のアドレスが含まれます。
-- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72`:コンストラクタを呼び出すアドレスです。
-- `0x10000`、`0x20000`、`0x00a329C0648769a73afAC7F9381e08fb43DBEA70`:他の関数をランダムに呼び出すアドレスです。
+- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72`はコンストラクタを呼び出します。
+- `0x10000`、`0x20000`、および`0x00a329C0648769a73afAC7F9381e08fb43DBEA70`は、他の関数をランダムに呼び出します。
-このチュートリアルでは特定の初期化を実行する必要がないため、コンストラクタは空になります。
+この例では特定の初期化は必要ないため、コンストラクタは空になります。
-### Echidnaを実行する {#run-echidna}
+### Echidnaの実行 {#run-echidna}
-以下のコードで、Echidnaを起動します:
+Echidnaは次のように起動します。
```bash
echidna-test contract.sol
```
-contract.solに複数のコントラクトが含まれる場合、実行したいコントラクトを指定できます:
+contract.solに複数のコントラクトが含まれる場合、対象を指定できます。
```bash
echidna-test contract.sol --contract MyContract
```
-### プロパティテストのまとめ {#summary-testing-a-property}
+### まとめ:プロパティのテスト {#summary-testing-a-property}
-以下は、このチュートリアルにおけるEchidnaの実行をまとめたものです。
+以下は、この例におけるEchidnaの実行をまとめたものです。
```solidity
contract TestToken is Token{
@@ -172,11 +167,12 @@ echidna_balance_under_1000: failed!💥
...
```
-Echidnaは、 `backdoor`が呼び出された場合、このプロパティが侵害されることを確認しました。
+Echidnaは、`backdoor`が呼び出された場合にプロパティが違反することを発見しました。
-## ファジング中に呼び出す関数を絞り込む {#filtering-functions-to-call-during-a-fuzzing-campaign}
+## ファジングキャンペーン中に呼び出す関数をフィルタリングする {#filtering-functions-to-call-during-a-fuzzing-campaign}
-ファジングの対象となる関数を絞り込む方法を見ていきましょう。 以下のスマートコントラクトを対象とします:
+ファジング対象となる関数をフィルタリングする方法を見ていきましょう。
+対象は、次のスマートコントラクトです。
```solidity
contract C {
@@ -227,7 +223,9 @@ contract C {
}
```
-この簡単な例は、状態変数を変更する特定のトランザクションのシーケンスをEchidnaに見つけさせるものです。 これは、ファザーにとって容易ではありません([Manticore](https://github.com/trailofbits/manticore)のようなシンボリック実行ツールを使用することをお勧めします)。 Echidnaで、以下のように検証を実行します:
+この簡単な例は、状態変数を変更する特定のトランザクションのシーケンスをEchidnaに見つけさせるものです。
+これはファザーにとって困難です([Manticore](https://github.com/trailofbits/manticore)のようなシンボリック実行ツールの使用が推奨されます)。
+Echidnaを実行して、これを確認できます。
```bash
echidna-test multi.sol
@@ -236,30 +234,32 @@ echidna_state4: passed! 🎉
Seed: -3684648582249875403
```
-### 対象の関数を絞り込む {#filtering-functions}
+### 関数のフィルタリング {#filtering-functions}
-2つのリセット関数(`reset1`と`reset2`)がすべての状態変数を`false`に設定するため、Echidnaはこのコントラクトをテストするための正しいシーケンスを見つけられません。 しかしEchidnaでは、リセット関数をブラックリストに含めるか、 `f`、`g`、 `h`、および `i`の関数のみをホワイトリストに含める特別の機能が利用できます。
+2つのリセット関数(`reset1`と`reset2`)がすべての状態変数を`false`に設定するため、Echidnaがこのコントラクトをテストするための正しいシーケンスを見つけるのは困難です。
+しかし、Echidnaの特別な機能を使用して、リセット関数をブラックリストに登録するか、`f`、`g`、
+`h`、`i`関数のみをホワイトリストに登録することができます。
-関数をブラックリストに登録するには、設定ファイルを以下のように指定します:
+関数をブラックリストに登録するには、この設定ファイルを使用します。
```yaml
filterBlacklist: true
filterFunctions: ["reset1", "reset2"]
```
-関数を絞り込むもう一つの方法は、ホワイトリストに含まれる関数を列挙することです。 これには、設定ファイルを以下のように指定します:
+関数をフィルタリングするもう1つのアプローチは、ホワイトリストに登録された関数をリストアップすることです。 そのためには、この設定ファイルを使用します。
```yaml
filterBlacklist: false
filterFunctions: ["f", "g", "h", "i"]
```
-- `filterBlacklist`の初期値は`true`です。
-- 絞り込みは、名前のみ(パラメータなし)で実行されます。 `f()`と`f(uint256)`の両方が含まれる場合、`"f"`で絞り込むと両方の関数がヒットします。
+- `filterBlacklist`のデフォルト値は`true`です。
+- フィルタリングは、名前のみ(パラメータなし)で実行されます。 `f()`と`f(uint256)`の両方がある場合、フィルタ`"f"`は両方の関数にマッチします。
-### Echidnaを実行する {#run-echidna-1}
+### Echidnaの実行 {#run-echidna-1}
-設定ファイル `blacklist.yaml` に従ってEchidnaを実行するには、以下のようにします:
+Echidnaを構成ファイル`blacklist.yaml`で実行するには、次のようにします。
```bash
echidna-test multi.sol --config blacklist.yaml
@@ -272,11 +272,11 @@ echidna_state4: failed!💥
i()
```
-Echidnaは、プロパティをfalseにするトランザクションのシーケンスを瞬時に特定します。
+Echidnaは、プロパティを偽にするトランザクションのシーケンスをほぼ瞬時に見つけます。
-### 対象の関数を絞り込む作業のまとめ {#summary-filtering-functions}
+### まとめ:関数のフィルタリング {#summary-filtering-functions}
-Echidnaでは、ファジングで呼び出す機能を絞り込むために、ブラックリストあるいはホワイトリストの関数を使用します:
+Echidnaは、ファジングキャンペーン中に呼び出す関数を、以下を使用してブラックリストまたはホワイトリストに登録できます。
```yaml
filterBlacklist: true
@@ -288,11 +288,11 @@ echidna-test contract.sol --config config.yaml
...
```
-Echidnaは、`filterBlacklist`のブール値に基づき、`f1`、`f2`、および `f3`の関数をブラックリストに含めるか、これらの関数のみを呼び出してファジングを実行します。
+Echidnaは、`filterBlacklist`ブール値の値に応じて、`f1`、`f2`、`f3`をブラックリストに登録するか、これらのみを呼び出すファジングキャンペーンを開始します。
## EchidnaでSolidityのアサーションをテストする方法 {#how-to-test-soliditys-assert-with-echidna}
-次の短いチュートリアルでは、Echidnaを使って、コントラクトに含まれるアサーションをテストします。 以下のようなコントラクトを想定します:
+この短いチュートリアルでは、Echidnaを使用してコントラクトのアサーションチェックをテストする方法を説明します。 以下のようなコントラクトを想定します。
```solidity
contract Incrementor {
@@ -309,7 +309,7 @@ contract Incrementor {
### アサーションを記述する {#write-an-assertion}
-引き算を実行した後に、`tmp`の値が`counter`の値以下であることを確認したいとします。 Echidnaのプロパティで記述することもできますが、`tmp`値をどこかに格納する必要があります。 これには、以下のようなアサーションを用いることができます:
+その差を返した後に、`tmp`が`counter`以下であることを確認したいと思います。 Echidnaのプロパティを記述することもできますが、`tmp`の値をどこかに保存する必要があります。 代わりに、このようなアサーションを使用できます。
```solidity
contract Incrementor {
@@ -324,15 +324,15 @@ contract Incrementor {
}
```
-### Echidnaを実行する {#run-echidna-2}
+### Echidnaの実行 {#run-echidna-2}
-アサーションの失敗をテストできるようにするには、[Echidnaの設定ファイル](https://github.com/crytic/echidna/wiki/Config)として `config.yaml` を作成します:
+アサーション失敗テストを有効にするには、[Echidna設定ファイル](https://github.com/crytic/echidna/wiki/Config) `config.yaml`を作成します。
```yaml
checkAsserts: true
```
-このコントラクトをEchidnaで実行すると、次のような期待通りの結果が得られます:
+このコントラクトをEchidnaで実行すると、期待通りの結果が得られます。
```bash
echidna-test assert.sol --config config.yaml
@@ -346,11 +346,11 @@ assertion in inc: failed!💥
Seed: 1806480648350826486
```
-このように、Echidnaでは、アサーション違反の一部を`inc`関数で報告します。 1つの関数に対し複数のアサーションを含めることは可能ですが、どのアサーションが失敗したのか区別できなくなります。
+ご覧のとおり、Echidnaは`inc`関数でのアサーションの失敗を報告します。 1つの関数に複数のアサーションを追加することは可能ですが、Echidnaはどのアサーションが失敗したかを特定できません。
-### アサーションをいつ、どのように使用すべきか {#when-and-how-use-assertions}
+### アサーションを使用する状況とその方法 {#when-and-how-use-assertions}
-アサーションは、特にチェックしたい条件が`f`という特定の操作を適切に用いることと直接関係する場合に、プロパティを明示しない代替手段として用いることができます。 コードにアサーションを追加することで、このコードを実行した直後に強制的にチェックが実行されます。
+アサーションは、特にチェック対象の条件が何らかの操作`f`の正しい使用に直接関連する場合、明示的なプロパティの代替として使用できます。 コードの後にアサーションを追加すると、そのコードが実行された直後にチェックが強制的に行われます。
```solidity
function f(..) public {
@@ -362,7 +362,7 @@ function f(..) public {
```
-反対に、Echidnaのプロパティを明示的に使用する場合、トランザクションがランダムに実行されるため、チェックをどの時点で強制的に実行させるかを決定しにくくなります。 この場合、以下のような回避策を用いることもできます:
+対照的に、明示的なEchidnaプロパティを使用すると、トランザクションがランダムに実行され、いつチェックされるかを正確に強制する簡単な方法はありません。 この回避策を行うことは依然として可能です。
```solidity
function echidna_assert_after_f() public returns (bool) {
@@ -371,22 +371,22 @@ function echidna_assert_after_f() public returns (bool) {
}
```
-しかし、以下の問題点が残ります:
+しかし、いくつかの問題があります。
-- `f`が`internal`あるいは`external`と宣言されている場合、違反になる。
-- どの引数を使って`f`を呼び出すべきかが不明確である。
-- `f`が元に戻された場合、このプロパティは違反になる。
+- `f`が`internal`または`external`として宣言されている場合は失敗します。
+- `f`を呼び出すのにどの引数を使用すべきかが不明確です。
+- `f`がリバートされると、プロパティは失敗します。
-全般的なアサーションの使用については、この[John Regehrの提案](https://blog.regehr.org/archives/1091)に従うことを推奨します:
+一般に、アサーションの使用方法については、[John Regehr氏の推奨事項](https://blog.regehr.org/archives/1091)に従うことをお勧めします。
-- アサーションチェック中には、副作用を強制しない。 例:`assert(ChangeStateAndReturn() == 1)`
-- 明らかなステートメントは、アサートしない。 例:`var`を`uint`と宣言している場合、`assert(var >= 0)`は必要ない。
+- アサーションチェック中に副作用を強制しないでください。 例:`assert(ChangeStateAndReturn() == 1)`
+- 明らかなステートメントをアサートしないでください。 例えば、`var`が`uint`として宣言されている場合の`assert(var >= 0)`などです。
-最後に、`assert`の代わりに`require`を用いるのは**避けてください**。Echidnaではrequireを検出できません。(ただしこの場合でも、コントラクトは元に戻されます)。
+最後に、`assert`の代わりに`require`を**使用しないでください**。Echidnaはそれを検出できません(ただし、コントラクトはいずれにしてもリバートします)。
-### アサーションチェックのまとめ {#summary-assertion-checking}
+### まとめ:アサーションチェック {#summary-assertion-checking}
-以下は、この例におけるEchidnaの実行をまとめたものです:
+以下は、この例におけるEchidnaの実行をまとめたものです。
```solidity
contract Incrementor {
@@ -413,11 +413,11 @@ assertion in inc: failed!💥
Seed: 1806480648350826486
```
-Echidnaは、`inc`のアサーションにつき、この関数が大きな引数で複数回呼び出された場合に違反となりうることを発見しました。
+Echidnaは、`inc`のアサーションが、この関数が大きな引数で複数回呼び出された場合に失敗する可能性があることを見つけました。
-## Echidnaコーパスを収集、修正する {#collecting-and-modifying-an-echidna-corpus}
+## Echidnaコーパスの収集と変更 {#collecting-and-modifying-an-echidna-corpus}
-次に、Echidnaを使ってトランザクションのコーパスを収集し、これを利用する方法について見ていきましょう。 対象は、[`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol)のスマートコントラクトです。
+Echidnaを使ってトランザクションのコーパスを収集し、利用する方法について見ていきましょう。 対象は、次のスマートコントラクト[`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol)です。
```solidity
contract C {
@@ -437,7 +437,9 @@ contract C {
}
```
-以下の短いコードは、状態変数を変更する特定の値をEchidnaに発見させます。 これは、ファザーにとって容易ではありません([Manticore](https://github.com/trailofbits/manticore)のようなシンボリック実行ツールを使用することをお勧めします)。 Echidnaで、以下のように検証を実行します:
+この簡単な例では、状態変数を変更するために、Echidnaに特定の値を探索させます。 これはファザーにとって困難です
+([Manticore](https://github.com/trailofbits/manticore)のようなシンボリック実行ツールの使用が推奨されます)。
+Echidnaを実行して、これを確認できます。
```bash
echidna-test magic.sol
@@ -448,30 +450,31 @@ echidna_magic_values: passed! 🎉
Seed: 2221503356319272685
```
-ただしEchidnaでは、ファジングの実行中もコーパスを収集することができます。
+しかし、このファジングキャンペーンの実行中にEchidnaを使用してコーパスを収集することは依然として可能です。
-### コーパスを収集する {#collecting-a-corpus}
+### コーパスの収集 {#collecting-a-corpus}
-コーパスを収集するには、まずコーパスのディレクトリを作成します:
+コーパス収集を有効にするには、コーパスディレクトリを作成します。
```bash
mkdir corpus-magic
```
-さらに、[Echidnaの設定ファイル](https://github.com/crytic/echidna/wiki/Config)である `config.yaml` を作成します:
+そして、[Echidna設定ファイル](https://github.com/crytic/echidna/wiki/Config)である`config.yaml`を作成します。
```yaml
coverage: true
corpusDir: "corpus-magic"
```
-これで、ツールを実行しながら収集したコーパスをチェックできるようになりました:
+これでツールを実行し、収集したコーパスを確認できます。
```bash
echidna-test magic.sol --config config.yaml
```
-この段階ではEchidnaはまだ適切なmagic値を特定できませんが、収集したコーパスを確認することはできます。 例えば、以下のようなファイルが収集されました:
+Echidnaはまだ正しいマジック値を見つけることができませんが、収集したコーパスを見ることができます。
+例えば、これらのファイルの1つは次のとおりでした。
```json
[
@@ -516,17 +519,18 @@ echidna-test magic.sol --config config.yaml
]
```
-言うまでもなく、この入力はプロパティ違反をトリガーしません。 しかし、次のステップでこれを修正することができます。
+明らかに、この入力はプロパティの失敗をトリガーしません。 しかし、次のステップでは、そのためにこれを変更する方法を見ていきます。
-### コーパスをシードする {#seeding-a-corpus}
+### コーパスのシーディング {#seeding-a-corpus}
-Echidnaを`magic`関数に対応するように設定する必要があります。 この入力が適切なパラメータを使用できるように、コピーし、変更します。
+`magic`関数を扱うために、Echidnaには少し助けが必要です。 入力をコピーして変更し、適切な
+パラメータを使用するようにします。
```bash
cp corpus/2712688662897926208.txt corpus/new.txt
```
-`magic(42,129,333,0)`を呼び出せるように`new.txt`を変更します。 その上で、Echidnaを再実行します:
+`new.txt`を`magic(42,129,333,0)`を呼び出すように変更します。 これでEchidnaを再実行できます。
```bash
echidna-test magic.sol --config config.yaml
@@ -542,11 +546,11 @@ Seed: -7293830866560616537
```
-今回は、プロパティ違反がただちに検出されました。
+今回は、プロパティが即座に違反していることがわかりました。
-## ガス消費量が多いトンラザクションを見つける {#finding-transactions-with-high-gas-consumption}
+## ガス消費量の多いトランザクションの発見 {#finding-transactions-with-high-gas-consumption}
-ガス消費量が多いトランザクションを特定するために、Echidnaを使用する方法について見ていきましょう。 対象は、次のスマートコントラクトです:
+Echidnaを使用してガス消費量が多いトランザクションを見つける方法を見ていきましょう。 対象は、次のスマートコントラクトです。
```solidity
contract C {
@@ -571,9 +575,10 @@ contract C {
}
```
-ここでは、`expensive`でガス消費量が高くなる可能性があります。
+ここで`expensive`は大きなガス消費量を持つ可能性があります。
-この時点では、Echidna上で常にテストすべきプロパティを設定する必要があり、`echidna_test`は常に`true`を返します。 Echidnaを実行して、これを確認します:
+現在、Echidnaは常にテスト対象のプロパティを必要とします。ここでは`echidna_test`が常に`true`を返します。
+Echidnaを実行して、これを確認できます。
```
echidna-test gas.sol
@@ -583,24 +588,24 @@ echidna_test: passed! 🎉
Seed: 2320549945714142710
```
-### ガス消費量を測定する {#measuring-gas-consumption}
+### ガス消費量の測定 {#measuring-gas-consumption}
-Ethidnaでガスの消費量を確認できるようにするには、 `config.yaml`を以下のように設定します:
+Echidnaでガス消費を有効にするには、設定ファイル`config.yaml`を作成します。
```yaml
estimateGas: true
```
-この例では、結果を分かりやすくするために、次のようにトランザクションシーケンスのサイズを減らしています。
+この例では、結果を理解しやすくするために、トランザクションシーケンスのサイズも小さくします。
```yaml
seqLen: 2
estimateGas: true
```
-### Echidnaを実行する {#run-echidna-3}
+### Echidnaの実行 {#run-echidna-3}
-設定が完了したら、次のようにEchidnaを実行します:
+設定ファイルが作成されたら、次のようにEchidnaを実行できます。
```bash
echidna-test gas.sol --config config.yaml
@@ -617,12 +622,13 @@ Seed: -325611019680165325
```
-- 表示されたガス量は、[HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-)による見積もりです。
+- 表示されるガスは、[HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-)によって提供される推定値です。
-### ガス量を削減する呼び出しを対象外にする {#filtering-out-gas-reducing-calls}
+### ガスを削減する呼び出しの除外 {#filtering-out-gas-reducing-calls}
-**ファジング実行時に呼び出す関数を絞り込む方法**のチュートリアルでは、特定の関数をテストの対象外にする方法を示しました。
-この作業は、ガス量を正確に見積もる上で非常に重要です。 以下の例を検討してみましょう:
+上記の「**ファジングキャンペーン中に呼び出す関数のフィルタリング**」のチュートリアルでは、テストからいくつかの関数を削除する方法を示しています。
+これは、正確なガス見積もりを得るために重要となる場合があります。
+次の例を考えてみましょう。
```solidity
contract C {
@@ -648,7 +654,7 @@ contract C {
}
```
-Echidnaがすべての関数を呼び出せる場合、ガス代が高いトランザクションを見つけることは困難になるでしょう。
+Echidnaがすべての関数を呼び出せる場合、ガス代が高いトランザクションを簡単に見つけることはできません。
```
echidna-test pushpop.sol --config config.yaml
@@ -662,7 +668,8 @@ clear used a maximum of 35916 gas
push used a maximum of 40839 gas
```
-なぜかと言えば、ガス代は`addrs`のサイズに依存しており、ランダムに呼び出した場合は配列がほぼ空になるためです。 このような場合、 `pop`と`clear`をブラックリストに追加することで、より正確な結果を得ることができます。
+これは、コストが`addrs`のサイズに依存し、ランダムな呼び出しでは配列がほとんど空のままになる傾向があるためです。
+しかし、`pop`と`clear`をブラックリストに登録すると、はるかに良い結果が得られます。
```yaml
filterBlacklist: true
@@ -677,9 +684,9 @@ push used a maximum of 40839 gas
check used a maximum of 1484472 gas
```
-### ガス消費量が高いトランザクションを見つける作業のまとめ {#summary-finding-transactions-with-high-gas-consumption}
+### まとめ:ガス消費量の多いトランザクションの発見 {#summary-finding-transactions-with-high-gas-consumption}
-Echidnaでは、`estimateGas`の設定オプションを使用してガス消費量の多いトランザクションを特定することができます:
+Echidnaは、`estimateGas`設定オプションを使用して、ガス消費量の多いトランザクションを見つけることができます。
```yaml
estimateGas: true
@@ -690,4 +697,4 @@ echidna-test contract.sol --config config.yaml
...
```
-Echidnaは、ファジングを実行した後、各関数ごとにガス消費量が最大となるシーケンスを報告します。
+ファジングキャンペーンが終了すると、Echidnaは各関数の最大ガス消費量を持つシーケンスを報告します。
diff --git a/public/content/translations/ja/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/ja/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md
index baa9cab81c5..7e10233e51b 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md
@@ -1,17 +1,12 @@
---
-title: Manticoreを使ってスマートコントラクトのバグを特定する方法
-description: Manticoreを使って、自動でスマートコントラクト上のバグを特定する
+title: "Manticoreを使ってスマートコントラクトのバグを特定する方法"
+description: "Manticoreを使って、自動でスマートコントラクト上のバグを特定する方法"
author: Trailofbits
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "セキュリティ"
- - "テスト"
- - "フォーマルな検証"
+tags: [ "Solidity", "スマート契約", "セキュリティ", "テスト", "形式的検証" ]
skill: advanced
published: 2020-01-13
-source: セキュアなコントラクトの構築
+source: Building secure contracts
sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore
---
@@ -19,25 +14,25 @@ sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/progr
## インストール {#installation}
-Manticoreを使用するには、Python 3.6 が必要です。 pipでインストールすることも、Dockerを使用してインストールすることもできます。
+Manticoreには、Python 3.6以上が必要です。 pipでインストールすることも、Dockerを使用してインストールすることもできます。
-### DockerでManticoreをインストールする場合 {#manticore-through-docker}
+### Docker経由のManticore {#manticore-through-docker}
```bash
docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox
```
-_最後のコマンドは、現在のディレクトリにアクセスできるdockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、dockerからファイル上のツールを実行することができます。_
+_最後のコマンドは、現在のディレクトリにアクセスできるDockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、Dockerからファイル上のツールを実行できます。_
-Dockerで、以下を実行します:
+Docker内で、以下を実行します。
```bash
solc-select 0.5.11
cd /home/trufflecon/
```
-### pipでManticoreをインストールする場合 {#manticore-through-pip}
+### pip経由のManticore {#manticore-through-pip}
```bash
pip3 install --user manticore
@@ -45,9 +40,9 @@ pip3 install --user manticore
solc 0.5.11を推奨します。
-### スクリプトを実行する {#running-a-script}
+### スクリプトの実行 {#running-a-script}
-Python 3では、以下のPythonスクリプトを実行します:
+Python 3でPythonスクリプトを実行するには:
```bash
python3 script.py
@@ -55,60 +50,60 @@ python3 script.py
## 動的シンボリック実行の概要 {#introduction-to-dynamic-symbolic-execution}
-### 動的シンボリック実行とは何か {#dynamic-symbolic-execution-in-a-nutshell}
+### 動的シンボリック実行の簡単な説明 {#dynamic-symbolic-execution-in-a-nutshell}
-動的シンボリック実行(DSE)は、高度な意味認識に基づき状態空間を探索するプログラム解析手法です。 この手法は、`path predicates`と呼ばれる数式で表される「プログラム・パス」を発見するものです。 概念的には、この手法は2つのステップによりパス述語を操作します:
+動的シンボリック実行(DSE)は、高度な意味認識に基づき状態空間を探索するプログラム解析手法です。 この手法は、`パス述語`と呼ばれる数式で表される「プログラムパス」の発見に基づいています。 概念的には、この手法は2つのステップでパス述語を操作します:
-1. プログラムの入力に対する制約を参照して、プログラム・パスを構築します。
-2. プログラム・パスは、関連パスを実行させるプログラムの入力を生成します。
+1. パス述語は、プログラムの入力に対する制約を使用して構築されます。
+2. パス述語は、関連するパスを実行させるプログラム入力を生成するために使用されます。
-このアプローチでは、具体値で実行する際に、特定されたすべてのプログラムの状態をトリガーしうるという意味で誤検出が発生しません。 例えば、解析において整数のオーバーフローが特定された場合、このオーバーフローは確実に再現可能です。
+このアプローチでは、特定されたすべてのプログラム状態が具体的な実行中にトリガーされうるという意味で、誤検出(偽陽性)は発生しません。 例えば、解析で整数オーバーフローが発見された場合、その再現性が保証されます。
-### パス述語の具体例 {#path-predicate-example}
+### パス述語の例 {#path-predicate-example}
-DSEの仕組みを理解するために、以下の例を考えてみましょう。
+DSEがどのように機能するかを理解するために、次の例を考えてみましょう。
```solidity
function f(uint a){
if (a == 65) {
- // A bug is present
+ // バグが存在します
}
}
```
-`f()`には2つのパスが含まれているため、DSEにより、2つの異なるパス述語が構築されます。
+`f()`には2つのパスが含まれているため、DSEは2つの異なるパス述語を構築します。
-- 第1のパス: `a == 65`
-- 第2のパス: `Not (a == 65)`
+- パス1: `a == 65`
+- パス2: `Not (a == 65)`
-それぞれのパス述語は、いわゆる[SMTソルバー](https://wikipedia.org/wiki/Satisfiability_modulo_theories)に投入できる数式であり、SMTソルバーはこの等式を解決しようとします。 `第1のパス`では、ソルバーは、このパスが`a = 65`で探索可能だと返します。 `第2のパス`では、ソルバーは、`a`に対し、65以外の任意の値を与えることができます(例: `a = 0`)。
+各パス述語は、いわゆる[SMTソルバー](https://wikipedia.org/wiki/Satisfiability_modulo_theories)に与えることができる数式であり、ソルバーはその方程式を解こうとします。 `パス1`では、ソルバーは `a = 65` でパスを探索できると応答します。 `パス2`では、ソルバーは `a` に65以外の任意の値、例えば `a = 0` を与えることができます。
-### プロパティを検証する {#verifying-properties}
+### プロパティの検証 {#verifying-properties}
-Manticoreでは、各パスの実行全体を完全に制御できます。 このため、ほぼすべての事項に対して任意の制限を加えることができます。 この制御を通じて、コントラクトのプロパティを作成することができます。
+Manticoreでは、各パスのすべての実行を完全に制御できます。 その結果、ほとんどすべてのものに任意の制約を追加できます。 この制御により、コントラクトに関するプロパティを作成できます。
-次の例を考えてみましょう:
+次の例を考えてみましょう。
```solidity
function unsafe_add(uint a, uint b) returns(uint c){
- c = a + b; // no overflow protection
+ c = a + b; // オーバーフロー保護なし
return c;
}
```
-この関数を探索するには、1つのパスしか存在しません。
+この関数には、探索するパスが1つしかありません。
-- パス1: `c = a + b`
+- パス1: `c = a + b`
-Manticoreを使用することで、オーバーフローの有無を確認し、パス述語に制限を加えられます。
+Manticoreを使用すると、オーバーフローをチェックし、パス述語に制約を追加できます。
- `c = a + b AND (c < a OR c < b)`
-上記の述語パスが実行可能となる`a`および`b`の値を見つけられる場合、オーバーフローが特定できたことになります。 例えば、ソルバーは、`a = 10 , b = MAXUINT256`という入力を生成できます。
+上記のパス述語が実行可能になるような `a` と `b` の評価を見つけることができれば、オーバーフローを発見したことになります。 例えば、ソルバーは `a = 10 , b = MAXUINT256` という入力を生成できます。
-次に、上記を修正したコードを見てみましょう:
+修正版を考えてみましょう。
```solidity
function safe_add(uint a, uint b) returns(uint c){
@@ -119,17 +114,17 @@ function safe_add(uint a, uint b) returns(uint c){
}
```
-オーバーフローを確認するために数式は、以下のようになるでしょう:
+オーバーフローチェックに関連する数式は次のようになります。
-- `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)`
+- `c = a + b AND (c >= a) AND (c >= b) AND (c < a OR c < b)`
-この数式は解くことができません。言い換えれば、`safe_add`において、`c`の値が常に増加することを**証明**しています。
+この数式は解けません。言い換えれば、これは `safe_add` において `c` が常に増加することの**証明**です。
-このように、DSEはコード上の任意の制限について検証できるパワフルなツールです。
+したがって、DSEはコード上の任意の制約を検証できる強力なツールです。
-## Manticoreで実行する {#running-under-manticore}
+## Manticoreでの実行 {#running-under-manticore}
-以下に、Manticore APIを用いて、スマートコントラクトを探索する方法を紹介します。 対象となるスマートコントラクトは、[`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol)です。
+ここでは、Manticore APIを使ってスマートコントラクトを探索する方法を見ていきます。 対象は、次のスマートコントラクト [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) です。
```solidity
pragma solidity >=0.4.24 <0.6.0;
@@ -143,15 +138,15 @@ contract Simple {
}
```
-### スタンドアロンの探索を実行する {#run-a-standalone-exploration}
+### スタンドアロン探索の実行 {#run-a-standalone-exploration}
-以下のコマンドから、スマートコントラクト上で直接Manticoreを実行できます(`project`は、Solidityファイルでもプロジェクトディレクトリでも構いません)。
+次のコマンドで、スマートコントラクト上で直接Manticoreを実行できます(`project`はSolidityファイル、またはプロジェクトディレクトリです):
```bash
$ manticore project
```
-実行すると、以下のようなテストケースが出力されます(順番は異なる可能性があります):
+次のようなテストケースの出力が得られます(順序は変わる可能性があります):
```
...
@@ -166,39 +161,40 @@ $ manticore project
...
```
-Manticoreは、追加情報が提供されない限り、新規のシンボリック・トランザクションを使って、コントラクト上で新規パスが発見されるまでコントラクトを探索します。 Manticoreでは、トランザクションが失敗した場合(例:状態が元に戻された後)は、新規のトランザクションを実行しません。
+追加情報がない場合、Manticoreはコントラクト上で新しいパスを探索しなくなるまで、新しいシンボリック
+トランザクションでコントラクトを探索します。 Manticoreは、失敗したトランザクションの後(例: revertの後)には、新しいトランザクションを実行しません。
-Manticoreでは、 `mcore_*`ディレクトリに情報を出力します。 このディレクトリには、以下が含まれます:
+Manticoreは、`mcore_*`ディレクトリに情報を出力します。 このディレクトリには、とりわけ次のものが含まれます。
-- `global.summary`:カバレッジとコンパイラに関する警告
-- `test_XXXXX.summary`:テストケースごとのカバレッジ、最後の命令、およびアカウント残高
-- `test_XXXXX.tx`:テストケースごとの詳細なトランザクションリスト
+- `global.summary`: カバレッジとコンパイラの警告
+- `test_XXXXX.summary`: カバレッジ、最後の命令、テストケースごとのアカウント残高
+- `test_XXXXX.tx`: テストケースごとのトランザクションの詳細リスト
-この例では、以下に該当する7つのテストケースが特定されました(ファイル名の順番は異なるかもしれません):
+ここでは、Manticoreは7つのテストケースを見つけます。これらは以下に対応します(ファイル名の順序は変わる可能性があります):
-| | トランザクション 0 | トランザクション 1 | トランザクション 2 | 結果 |
-|:--------------------:|:----------:|:----------:| ---------- |:------:|
-| **test_00000000.tx** | コントラクトの作成 | f(!=65) | f(!=65) | STOP |
-| **test_00000001.tx** | コントラクトの作成 | フォールバック関数 | | REVERT |
-| **test_00000002.tx** | コントラクトの作成 | | | RETURN |
-| **test_00000003.tx** | コントラクトの作成 | f(65) | | REVERT |
-| **test_00000004.tx** | コントラクトの作成 | f(!=65) | | STOP |
-| **test_00000005.tx** | コントラクトの作成 | f(!=65) | f(65) | REVERT |
-| **test_00000006.tx** | コントラクトの作成 | f(!=65) | フォールバック関数 | REVERT |
+| | トランザクション0 | トランザクション1 | トランザクション2 | 結果 |
+| :-------------------------------------------------------: | :-------: | :------------------------: | -------------------------- | :----: |
+| **test_00000000.tx** | コントラクト作成 | f(!=65) | f(!=65) | STOP |
+| **test_00000001.tx** | コントラクト作成 | フォールバック関数 | | REVERT |
+| **test_00000002.tx** | コントラクト作成 | | | RETURN |
+| **test_00000003.tx** | コントラクト作成 | f(65) | | REVERT |
+| **test_00000004.tx** | コントラクト作成 | f(!=65) | | STOP |
+| **test_00000005.tx** | コントラクト作成 | f(!=65) | f(65) | REVERT |
+| **test_00000006.tx** | コントラクト作成 | f(!=65) | フォールバック関数 | REVERT |
_探索サマリーにおける「f(!=65)」は、f が 65 以外の値で呼び出されたことを意味します。_
-ご覧のように、Manticoreでは、すべての成功した/元に戻されたトランザクションにつき、固有のテストケースを生成します。
+お気づきのように、Manticoreは成功したトランザクションやrevertされたトランザクションごとに、一意のテストケースを生成します。
-高速な探索を行いたい場合は、`--quick-mode`フラグを使用してください(バグ検出、ガス代計算等が省略されます)。
+高速なコード探索を行いたい場合は `--quick-mode` フラグを使用してください(バグ検出器、ガス計算などを無効にします)。
-### Manticore APIを使ってスマートコントラクトを操作する {#manipulate-a-smart-contract-through-the-api}
+### APIによるスマートコントラクトの操作 {#manipulate-a-smart-contract-through-the-api}
-このセクションでは、Manticore Python APIを使ってスマートコントラクトを操作する方法について詳しく説明します。 Pythonの拡張子である`*.py`を持つ新規ファイルを作成し、APIコマンド(基本知識については以下で説明します)をファイルに追加して必要なコードを書いてから、`$ python3 *.py`コマンドで実行します。 また、Pythonのコンソールから直接コマンドを実行することもできます。コンソールを起動する際のコマンドは、`$ python3`です。
+このセクションでは、Manticore Python APIを介してスマートコントラクトを操作する方法について詳しく説明します。 Pythonの拡張子である\*.pyを持つ新規ファイルを作成し、APIコマンド(基本知識については以下で説明します)をファイルに追加して必要なコードを書いてから、$ python3 \*.pyコマンドで実行します。 また、Pythonのコンソールから直接コマンドを実行することもできます。コンソールを起動する際のコマンドは、$ python3です。
-### アカウントを作成する {#creating-accounts}
+### アカウントの作成 {#creating-accounts}
-まず、以下のコマンドを持つ新規のブロックチェーンを立ち上げる必要があります。
+最初に行うべきことは、次のコマンドで新しいブロックチェーンを開始することです。
```python
from manticore.ethereum import ManticoreEVM
@@ -206,13 +202,13 @@ from manticore.ethereum import ManticoreEVM
m = ManticoreEVM()
```
-[m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account)により、コントラクトではないアカウントが作成されます。
+非コントラクトアカウントは [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) を使用して作成されます。
```python
user_account = m.create_account(balance=1000)
```
-Solidityで作成したコントラクトについては、[m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract)でデプロイします。
+Solidityコントラクトは [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract) を使用してデプロイできます。
```solidity
source_code = '''
@@ -225,24 +221,24 @@ contract Simple {
}
}
'''
-# Initiate the contract
+# コントラクトを初期化する
contract_account = m.solidity_create_contract(source_code, owner=user_account)
```
#### まとめ {#summary}
-- [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account)と[m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract)を使用して、ユーザーアカウントとコントラクトアカウントを作成できます。
+- [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) と [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract) でユーザーアカウントとコントラクトアカウントを作成できます。
-### トランザクションを実行する {#executing-transactions}
+### トランザクションの実行 {#executing-transactions}
-Manticoreは、2種類のトランザクションに対応しています:
+Manticoreは2種類のトランザクションをサポートしています。
-- 生トランザクション:すべての関数を探索します。
-- 名前付きトランザクション:1つの関数だけを探索します。
+- Rawトランザクション: すべての関数が探索されます
+- 名前付きトランザクション: 1つの関数のみが探索されます
-#### 生トランザクション {#raw-transaction}
+#### Rawトランザクション {#raw-transaction}
-生トランザクションは、[m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction)で実行されます。
+Rawトランザクションは [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction) を使用して実行されます。
```python
m.transaction(caller=user_account,
@@ -251,12 +247,12 @@ m.transaction(caller=user_account,
value=value)
```
-呼び出し元、アドレス、データ、トランザクションの値は、具体値あるいはシンボリック値のどちらでも構いません:
+トランザクションの呼び出し元、アドレス、データ、または値は、具象値またはシンボリック値のいずれかです。
-- [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value)は、シンボリック値を生成します。
-- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer)は、シンボリックなバイト配列を生成します。
+- [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) はシンボリック値を生成します。
+- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) はシンボリックバイト配列を生成します。
-以下の例を確認してください:
+以下の例をご覧ください:
```python
symbolic_value = m.make_symbolic_value()
@@ -267,40 +263,41 @@ m.transaction(caller=user_account,
value=symbolic_value)
```
-データがシンボリック値の場合、Manticoreは、トランザクションの実行時にコントラクトに含まれるすべての関数を探索します。 関数がどのように選択されるかを理解するには、[Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/)の記事におけるフォールバック関数についての説明を参照してください。
+データがシンボリックの場合、Manticoreはトランザクションの実行中にコントラクトのすべての関数を探索します。 関数の選択がどのように機能するかを理解するには、[Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/)の記事にあるフォールバック関数の説明を参照すると役立ちます。
#### 名前付きトランザクション {#named-transaction}
-関数は、名前から実行できます。 `f(uint var)`につき、シンボリック値を用いて、user_accountから、0 etherで実行する場合、以下を使用します:
+関数は名前で実行できます。
+`f(uint var)` をシンボリック値で、user_accountから、0 etherで実行するには、次のようにします。
```python
symbolic_var = m.make_symbolic_value()
contract_account.f(symbolic_var, caller=user_account, value=0)
```
-トランザクションの`value`を指定しない場合、デフォルトでは0になります。
+トランザクションの `value` が指定されていない場合、デフォルトで0になります。
#### まとめ {#summary-1}
-- トランザクションの引数は、具体値またはシンボリック値のどちらでもよい。
-- 生トランザクションは、すべての関数を探索する。
-- 関数は、名前で呼び出すことができる。
+- トランザクションの引数は具象値またはシンボリック値にできます
+- Rawトランザクションはすべての関数を探索します
+- 関数は名前で呼び出すことができます
### ワークスペース {#workspace}
-`m.workspace`は、生成されたすべてのファイルにおける出力ディレクトリとして使用されるディレクトリです。
+`m.workspace` は、生成されたすべてのファイルの出力ディレクトリとして使用されるディレクトリです。
```python
print("Results are in {}".format(m.workspace))
```
-### 探索を終了する {#terminate-the-exploration}
+### 探索の終了 {#terminate-the-exploration}
-探索を停止するには、[m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize)を使用します。 このメソッドが呼び出された時点で、さらにトランザクションは送信されなくなり、Manticoreは探索済みの各パスにつきテストケースを生成します。
+探索を停止するには [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize) を使用します。 このメソッドが呼び出されると、それ以上のトランザクションは送信されなくなり、Manticoreは探索された各パスのテストケースを生成します。
-### Manticoreを使った実行のまとめ {#summary-running-under-manticore}
+### まとめ: Manticoreでの実行 {#summary-running-under-manticore}
-上記のステップをまとめると、以下のようになります:
+これまでのすべてのステップをまとめると、次のようになります。
```python
from manticore.ethereum import ManticoreEVM
@@ -317,14 +314,14 @@ symbolic_var = m.make_symbolic_value()
contract_account.f(symbolic_var)
print("Results are in {}".format(m.workspace))
-m.finalize() # stop the exploration
+m.finalize() # 探索を停止
```
-紹介したすべてのコードは、[`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)でアクセスできます。
+上記のすべてのコードは [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) にあります。
-## スローイングパスを取得する {#getting-throwing-paths}
+## 例外をスローするパスの取得 {#getting-throwing-paths}
-次に、 `f()`において例外を発生させるパスに対する、特定のインプットを生成します。 ここでも、対象となるスマートコントラクトは[`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol)です。
+次に、`f()`で例外を発生させるパスの特定の入力を生成します。 対象は、引き続き次のスマートコントラクト [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) です。
```solidity
pragma solidity >=0.4.24 <0.6.0;
@@ -337,26 +334,26 @@ contract Simple {
}
```
-### 状態情報を使用する {#using-state-information}
+### 状態情報の使用 {#using-state-information}
-実行された各パスには、それぞれのブロックチェーンの状態が含まれています。 状態は、readyまたはkilledのどちらかです。killedは、THROWまたはREVERTに達したことを意味します。
+実行された各パスには、それぞれのブロックチェーンの状態があります。 状態はready(準備完了)かkilled(強制終了)のいずれかです。killedはTHROWまたはREVERT命令に到達したことを意味します。
-- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing):readyに該当する状態のリスト(REVERT/INVALIDを実行しなかった状態)
-- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings):killedに該当する状態のリスト
-- [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings):すべての状態
+- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): 準備完了状態のリスト(REVERT/INVALIDを実行していない状態)
+- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): 強制終了された状態のリスト
+- [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): すべての状態
```python
for state in m.all_states:
- # do something with state
+ # stateで何かを行う
```
-状態情報は、アクセス可能です。 以下の例をご覧ください:
+状態情報にアクセスできます。 以下の例をご覧ください:
-- `state.platform.get_balance(account.address)`:アカウント残高
-- `state.platform.transactions`:トランザクションのリスト
-- `state.platform.transactions[-1].return_data`:最後のトランザクションで返されたデータ
+- `state.platform.get_balance(account.address)`: アカウントの残高
+- `state.platform.transactions`: トランザクションのリスト
+- `state.platform.transactions[-1].return_data`: 最後のトランザクションによって返されたデータ
-最後のトランザクションによって返されるデータは配列ですが、以下のようにABI.deserializeで値に変換できます:
+最後のトランザクションによって返されたデータは配列であり、ABI.deserializeで値に変換できます。例:
```python
data = state.platform.transactions[0].return_data
@@ -365,7 +362,7 @@ data = ABI.deserialize("uint", data)
### テストケースの生成方法 {#how-to-generate-testcase}
-テストケースを生成するには、「[m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase)」を使用します。
+テストケースを生成するには [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) を使用します。
```python
m.generate_testcase(state, 'BugFound')
@@ -373,13 +370,13 @@ m.generate_testcase(state, 'BugFound')
### まとめ {#summary-2}
-- 状態は、m.all_statesでイテレートできる
-- `state.platform.get_balance(account.address)`は、アカウント残高を返す
-- `state.platform.transactions`は、トランザクションのリストを返す
-- `transaction.return_data`は、返されたデータを示す
-- `m.generate_testcase(state, name)`は、状態に対する入力を生成する
+- m.all_statesで状態をイテレートできます
+- `state.platform.get_balance(account.address)`はアカウントの残高を返します
+- `state.platform.transactions`はトランザクションのリストを返します
+- `transaction.return_data`は返されたデータです
+- `m.generate_testcase(state, name)`は状態の入力を生成します
-### スローイングパス取得のまとめ {#summary-getting-throwing-path}
+### まとめ: 例外をスローするパスの取得 {#summary-getting-throwing-path}
```python
from manticore.ethereum import ManticoreEVM
@@ -395,7 +392,8 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account)
symbolic_var = m.make_symbolic_value()
contract_account.f(symbolic_var)
-## Check if an execution ends with a REVERT or INVALID
+## 実行がREVERTまたはINVALIDで終了するかどうかを確認します
+
for state in m.terminated_states:
last_tx = state.platform.transactions[-1]
if last_tx.result in ['REVERT', 'INVALID']:
@@ -403,13 +401,14 @@ for state in m.terminated_states:
m.generate_testcase(state, 'ThrowFound')
```
-紹介したすべてのコードは、[`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)でアクセスできます。
+上記のすべてのコードは [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) にあります。
-_terminated_stateが返したすべての状態は結果の値がREVERTまたはINVALIDであるため、上記よりも簡略なスクリプトを作成することもできました。上記のスクリプト例は、Manticore APIの操作方法を説明することを目的としたものです。_
+_terminated_stateによって返されるすべての状態は結果としてREVERTまたはINVALIDを持つため、もっと単純なスクリプトを生成することもできましたが、この例はAPIの操作方法を実証するためだけのものです。_
-## 制約を追加する {#adding-constraints}
+## 制約の追加 {#adding-constraints}
-次に、探索を制限する方法について確認しましょう。 ここでは、`f()`のドキュメンテーションにおいて、この関数は決して`a == 65`で呼び出されることはないと記載されていると想定します。このため、`a == 65`のバグは、実際にはバグではありません。 ここでも、対象のスマートコントラクトは[`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol)です。
+探索を制約する方法を見ていきます。 `f()`のドキュメントには、この関数が`a == 65`で呼び出されることはないと
+記載されていると仮定します。したがって、`a == 65`のバグは実際のバグではありません。 対象は、引き続き次のスマートコントラクト [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) です。
```solidity
pragma solidity >=0.4.24 <0.6.0;
@@ -424,22 +423,22 @@ contract Simple {
### 演算子 {#operators}
-[演算子](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py)モジュールは、制約を容易に操作する上で役立ちます。特に、以下の操作を提供します:
+[Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py)モジュールは制約の操作を容易にし、とりわけ以下を提供します。
-- Operators.AND
-- Operators.OR
-- Operators.UGT(符号なし大なり)
-- Operators.UGE(符号なし以上)
-- Operators.ULT(符号なし小なり)
-- Operators.ULE(符号なし、以下)
+- Operators.AND,
+- Operators.OR,
+- Operators.UGT (符号なしでより大きい),
+- Operators.UGE (符号なしで以上),
+- Operators.ULT (符号なしでより小さい),
+- Operators.ULE (符号なしで以下)。
-このモジュールをインポートするには、以下を使用します:
+モジュールをインポートするには、次を使用します。
```python
from manticore.core.smtlib import Operators
```
-`Operators.CONCAT`は、配列に値を連結するために使用します。 例えば、トランザクションのreturn_dataは、他の値に対して検証可能な値に変更する必要があります:
+`Operators.CONCAT`は、配列を値に連結するために使用されます。 例えば、トランザクションのreturn_dataは、別の値と比較チェックするために値に変更する必要があります。
```python
last_return = Operators.CONCAT(256, *last_return)
@@ -447,11 +446,12 @@ last_return = Operators.CONCAT(256, *last_return)
### 制約 {#state-constraint}
-制約の対象は、グローバルあるいは特定の状態のみのどちらでも構いません。
+制約は、グローバルまたは特定の状態に対して使用できます。
#### グローバル制約 {#state-constraint}
-グローバル制約を追加するには、`m.constraint(constraint)`を使用します。 例えば以下のように、シンボリックアドレスからコントラクトを呼び出し、このアドレスを特定の値に制限することができます:
+グローバル制約を追加するには `m.constrain(constraint)` を使用します。
+例えば、シンボリックアドレスからコントラクトを呼び出し、このアドレスを特定の値に制限することができます。
```python
symbolic_address = m.make_symbolic_value()
@@ -462,23 +462,25 @@ m.transaction(caller=user_account,
value=0)
```
-#### 状態に対する制約 {#state-constraint}
+#### 状態制約 {#state-constraint}
-特定の状態に対して制約を追加するには、[state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain)を使用します。 特定の状態における一部のプロパティをチェックしてから、状態に制限を追加することができます。
+[state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) を使用して、特定の状態に制約を追加します。
+これは、探索後に状態を制約して、そのプロパティをチェックするために使用できます。
-### 制約を確認する {#checking-constraint}
+### 制約のチェック {#checking-constraint}
-制約が実行可能かどうかを確認するには、`solver.check(state.constraints)`を使用します。 例えば以下では、symbolic_valueが「65」以外の値でなければならないという制約を追加した上で、状態が実行可能かどうかをチェックします。
+`solver.check(state.constraints)`を使用して、制約がまだ実行可能かどうかを確認します。
+例えば、次はsymbolic_valueを65とは異なる値に制約し、状態がまだ実行可能かどうかをチェックします。
```python
state.constrain(symbolic_var != 65)
if solver.check(state.constraints):
- # state is feasible
+ # 状態は実行可能です
```
-### 制約追加のまとめ {#summary-adding-constraints}
+### まとめ: 制約の追加 {#summary-adding-constraints}
-これまでのコードに制約を追加すると、以下のようになります:
+前のコードに制約を追加すると、次のようになります。
```python
from manticore.ethereum import ManticoreEVM
@@ -499,11 +501,12 @@ contract_account.f(symbolic_var)
no_bug_found = True
-## Check if an execution ends with a REVERT or INVALID
+## 実行がREVERTまたはINVALIDで終了するかどうかを確認します
+
for state in m.terminated_states:
last_tx = state.platform.transactions[-1]
if last_tx.result in ['REVERT', 'INVALID']:
- # we do not consider the path were a == 65
+ # a == 65のパスは考慮しません
condition = symbolic_var != 65
if m.generate_testcase(state, name="BugFound", only_if=condition):
print(f'Bug found, results are in {m.workspace}')
@@ -513,4 +516,4 @@ if no_bug_found:
print(f'No bug found')
```
-ここで紹介したすべてのコードは、[`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)からアクセスできます。
+上記のすべてのコードは [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) にあります。
diff --git a/public/content/translations/ja/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/ja/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md
index 2196e56b178..c881486e9a9 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md
@@ -1,34 +1,29 @@
---
-title: Slitherを使用してスマートコントラクトのバグを見つける方法
-description: Slitherを使用してスマートコントラクトのバグを自動的に見つける方法
+title: "Slitherを使用してスマートコントラクトのバグを見つける方法"
+description: "Slitherを使用してスマートコントラクトのバグを自動的に見つける方法"
author: Trailofbits
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "セキュリティ"
- - "テスト"
- - "静的解析"
+tags: [ "Solidity", "スマート契約", "セキュリティ", "テスト" ]
skill: advanced
published: 2020-06-09
-source: セキュアなコントラクトの構築
+source: Building secure contracts
sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither
---
-## Slitherの使い方 {#how-to-use-slither}
+## Slitherの使用方法 {#how-to-use-slither}
このチュートリアルでは、Slitherを使って、スマートコントラクトのバグを自動で検出する方法を学びます。
- [インストール](#installation)
-- [コマンドラインの使い方](#command-line)
-- [静的解析入門](#static-analysis):静的解析の簡単な紹介
-- [API](#api-basics):Python APIの説明
+- [コマンドラインの使用方法](#command-line)
+- [静的解析入門](#static-analysis): 静的解析の簡単な紹介
+- [API](#api-basics): Python APIの説明
## インストール {#installation}
-Slitherには、Python 3.6以上が必要です。 pipでインストールすることも、Dockerを使用してインストールすることもできます。
+SlitherにはPython 3.6以上が必要です。 pipでインストールすることも、Dockerを使用してインストールすることもできます。
-pipによるSlitherのインストール
+pipによるSlitherのインストール:
```bash
pip3 install --user slither-analyzer
@@ -41,18 +36,18 @@ docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox
```
-_最後のコマンドは、現在のディレクトリにアクセスできるDockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、Dockerからファイル上のツールを実行することができます。_
+_最後のコマンドは、現在のディレクトリにアクセスできるDockerでeth-security-toolboxを実行します。 ホストからファイルを変更し、Dockerからファイル上のツールを実行できます。_
-Docker内で実行する:
+Docker内で、以下を実行します。
```bash
solc-select 0.5.11
cd /home/trufflecon/
```
-### スクリプトを実行する {#running-a-script}
+### スクリプトの実行 {#running-a-script}
-Python3でPythonスクリプトを実行するには、以下を実行します:
+Python 3でPythonスクリプトを実行するには:
```bash
python3 script.py
@@ -60,23 +55,23 @@ python3 script.py
### コマンドライン {#command-line}
-**コマンドラインとユーザー定義スクリプトの比較**:Slitherには、多くの一般的なバグを見つけるための事前定義された検出器のセットが付属しています。 コマンドラインでSlitherを呼び出すとすべての検出器が実行されますので、静的解析の詳しい知識は必要ありません:
+**コマンドラインとユーザー定義スクリプト。** Slitherには、多くの一般的なバグを見つけるための事前定義された検出器のセットが付属しています。 コマンドラインからSlitherを呼び出すとすべての検出器が実行されるため、静的解析に関する詳細な知識は必要ありません。
```bash
slither project_paths
```
-Slitherでは、検出器に加えて、[プリンター](https://github.com/crytic/slither#printers)と[ツール](https://github.com/crytic/slither#tools)によるコードレビュー機能も利用できます。
+検出器に加えて、Slitherにはその[printers](https://github.com/crytic/slither#printers)と[tools](https://github.com/crytic/slither#tools)を介したコードレビュー機能があります。
-プライベート検出器およびGitHubでの統合にアクセスするには、[crytic.io](https://github.com/crytic)を使用します。
+[crytic.io](https://github.com/crytic)を使用すると、プライベートな検出器やGitHubとの統合にアクセスできます。
## 静的解析 {#static-analysis}
-Slither静的解析フレームワークの機能と設計は、ブログ投稿 ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/)、[2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) と[学術論文](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf)で説明されています。
+Slither静的解析フレームワークの機能と設計については、ブログ投稿 ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) や [学術論文](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf)で説明されています。
-静的解析には、さまざまな種類があります。 静的解析の技法は、[clang](https://clang-analyzer.llvm.org/)や[gcc](https://lwn.net/Articles/806099/)といったコンパイラで採用されているだけでなく、[Infer](https://fbinfer.com/)、[CodeClimate](https://codeclimate.com/)、および[FindBugs](http://findbugs.sourceforge.net/)、ならびに[Frama-C](https://frama-c.com/)や[Polyspace](https://www.mathworks.com/products/polyspace.html)といったフォーマルなメソッドに基づくツールの基盤でもあります。
+静的解析には、さまざまな種類があります。 おそらくご存じのように、[clang](https://clang-analyzer.llvm.org/)や[gcc](https://lwn.net/Articles/806099/)などのコンパイラはこれらの研究技術に依存していますが、それはまた、([Infer](https://fbinfer.com/)、[CodeClimate](https://codeclimate.com/)、[FindBugs](http://findbugs.sourceforge.net/)、そして[Frama-C](https://frama-c.com/)や[Polyspace](https://www.mathworks.com/products/polyspace.html)のような形式的手法に基づくツール) の基礎ともなっています。
-ここでは、静的解析の手法や研究者について網羅的に取り上げる余裕はありません。 その代わりに、皆さんがバグを特定し、コードを理解する上で効果的に静的解析の手法を利用できるように、Slitherの仕組みを理解する上で必要な事項のみに焦点を当てます。
+ここでは、静的解析の技術と研究者を網羅的に検討するわけではありません。 その代わり、皆さんがバグを発見しコードを理解するためにSlitherをより効果的に使えるよう、Slitherがどのように機能するかを理解するために必要なことに焦点を当てます。
- [コード表現](#code-representation)
- [コード解析](#analysis)
@@ -84,13 +79,13 @@ Slither静的解析フレームワークの機能と設計は、ブログ投稿
### コード表現 {#code-representation}
-単一の実行パスについて推論する動的解析とは対照的に、静的解析では一度にすべてのパスを対象として推論します。 これには、別のコード表現が必要です。 最も一般的なコード表現は、抽象構文木(AST)および制御フローグラフ(CFG)の2つです。
+単一の実行パスについて推論する動的解析とは対照的に、静的解析では一度にすべてのパスを対象として推論します。 そのために、異なるコード表現に依存しています。 最も一般的なものは、抽象構文木 (AST) と制御フローグラフ (CFG) の2つです。
-### 抽象構文木(AST) {#abstract-syntax-trees-ast}
+### 抽象構文木 (AST) {#abstract-syntax-trees-ast}
-ASTは、コンパイラがコードを解析するたびに用いられます。 おそらく、静的解析を実行できる最も基本的な構造だと言えるでしょう。
+ASTは、コンパイラがコードを解析するたびに使用されます。 これは、おそらく静的解析を実行できる最も基本的な構造です。
-一言で言えば、ASTは構造化されたツリーであり、通常、各リーフに変数または定数が含まれ、内部ノードはオペランドまたは制御フロー操作です。 次のコードを検討してみましょう:
+要するに、ASTは構造化された木であり、通常、各リーフには変数または定数が含まれ、内部ノードはオペランドまたは制御フロー操作です。 次のコードを考えてみましょう。
```solidity
function safeAdd(uint a, uint b) pure internal returns(uint){
@@ -101,15 +96,15 @@ function safeAdd(uint a, uint b) pure internal returns(uint){
}
```
-対応するASTは、次のとおりです:
+対応するASTは以下の通りです。

-Slitherでは、solcがエクスポートしたASTを使用します。
+SlitherはsolcによってエクスポートされたASTを使用します。
-ASTは簡単に構築できますが、入れ子構造を持ちます。 このため、解析が簡単でない場合があります。 例えば、`a + b <= a`の式で使用される操作を識別するには、まず`<=`を解析し、次に`+`を解析する必要があります。 一般的なアプローチは、ツリーを再帰的に移動するいわゆるVisitorパターンを使用することです。 Slitherには、[`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py)という汎用的なVisitorが含まれています。
+ASTは簡単に構築できますが、入れ子構造になっています。 そのため、解析が必ずしも簡単ではない場合があります。 例えば、`a + b <= a`という式で使われる演算を特定するには、まず`<=`を解析し、次に`+`を解析しなければなりません。 一般的なアプローチは、木構造を再帰的に走査する、いわゆるビジターパターンを使用することです。 Slitherには、[`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py)に汎用的なビジターが含まれています。
-次のコードは、`ExpressionVisitor`を使用して式に加算が含まれているかどうかを検出します:
+次のコードは`ExpressionVisitor`を使用して、式に加算が含まれているかどうかを検出します。
```python
from slither.visitors.expression.expression import ExpressionVisitor
@@ -124,58 +119,58 @@ class HasAddition(ExpressionVisitor):
if expression.type == BinaryOperationType.ADDITION:
self._result = True
-visitor = HasAddition(expression) # expression is the expression to be tested
+visitor = HasAddition(expression) # expression はテスト対象の式です
print(f'The expression {expression} has a addition: {visitor.result()}')
```
-### 制御フローグラフ(CFG) {#control-flow-graph-cfg}
+### 制御フローグラフ (CFG) {#control-flow-graph-cfg}
-2番目によく用いられるコード表現は、制御フローグラフ(CFG)です。 名前が示すように、すべての実行パスを可視化するグラフベースの表現です。 各ノードには、1つまたは複数の命令が含まれます。 グラフのエッジ部分は、制御フロー操作(if/then/else、ループなど)を表します。 先ほどの例をCFGで表すと、次のようになります:
+2番目に一般的なコード表現は、制御フローグラフ (CFG) です。 その名の通り、すべての実行パスを公開するグラフベースの表現です。 各ノードには、1つまたは複数の命令が含まれます。 グラフのエッジは、制御フロー操作 (if/then/else、ループなど) を表します。 前の例のCFGは次のようになります。

-CFGは、大部分の解析の土台となる表現です。
+CFGは、ほとんどの解析がその上に構築される表現です。
-他にも、様々なコード表現が存在します。 それぞれの表現には、実行したい解析に応じて長所と短所があります。
+他にも多くのコード表現が存在します。 それぞれの表現には、実行したい解析に応じて長所と短所があります。
### 解析 {#analysis}
-Slitherで実行できる最もシンプルな解析タイプは、構文解析です。
+Slitherで実行できる最も簡単な種類の解析は、構文解析です。
### 構文解析 {#syntax-analysis}
-Slitherは、コードおよび表現に含まれるさまざまな構成要素を移動しながら、パターンマッチングに類似したアプローチで矛盾や欠陥を発見します。
+Slitherは、パターンマッチングのようなアプローチを用いて、コードのさまざまな構成要素とその表現を走査し、矛盾や欠陥を見つけることができます。
-例えば、以下の検出器は構文関連の問題を探します:
+例えば、以下の検出器は構文関連の問題を探します。
-- [状態変数のシャドーイング](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing):すべての状態変数でイテレートし、継承されたコントラクトから変数がシャドーされているかを確認します([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62))。
+- [状態変数のシャドーイング](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): すべての状態変数を反復処理し、継承されたコントラクトの変数をシャドーイングしているものがないかチェックします ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62))
-- [不適切なERC-20インターフェース](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface):不適切なERC-20関数の署名を探します([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55))。
+- [不正確なERC20インターフェース](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): 不正確なERC20関数のシグネチャを探します ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55))
### 意味解析 {#semantic-analysis}
-構文解析とは対照的に、意味解析は、より深くコードの「意味」を解析します。 この解析手法は、いくつかの種類に大別できます。 意味解析は、より強力で有益な結果を得られますが、より複雑なコードを書く必要があります。
+構文解析とは対照的に、意味解析はより深く掘り下げ、コードの「意味」を解析します。 この系統には、いくつかの広範な種類の解析が含まれます。 それらはより強力で有用な結果につながりますが、記述もより複雑になります。
-意味解析は、最も高度な脆弱性検出に用いられています。
+意味解析は、最も高度な脆弱性検出に使用されます。
-#### データ依存解析 {#fixed-point-computation}
+#### データ依存性解析 {#fixed-point-computation}
-`variable_a`の値が`variable_b`の影響を受けるパスが存在する場合、`variable_a`の変数は`variable_b`に対して依存関係を持ちます。
+`variable_a`の値が`variable_b`に影響されるパスが存在する場合、変数`variable_a`は`variable_b`にデータ依存していると言われます。
-次のコードでは、`variable_a`は`variable_b`に依存しています:
+次のコードでは、`variable_a`は`variable_b`に依存しています。
```solidity
// ...
variable_a = variable_b + 1;
```
-Slitherでは、中間表現(以下を参照)を利用して、[データの依存関係](https://github.com/crytic/slither/wiki/data-dependency)を解析する機能が搭載されています。
+Slitherには、その中間表現 (後のセクションで説明) のおかげで、組み込みの[データ依存性](https://github.com/crytic/slither/wiki/data-dependency)機能が備わっています。
-データ依存関係を解析する具体例としては、[危険をもたらす厳密な等値の検出器](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities)を参照してください。 ここで、Slitherは、ある危険な値に対する厳密な等値比較を発見しようと試みます([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87))。その上で、攻撃者がコントラクトをトラップできる状態を防止するために、`==`ではなく、`>=`または`<=`を使用するようにユーザーに警告します。 検出器はまず、`balanceOf(address)`の呼び出しにおける戻り値を危険な値だと見なし([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64))、データ依存関係エンジンを使用してその使用状況を追跡します。
+データ依存性の使用例は、[危険な厳密等価性検出器](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities)にあります。 ここでは、Slitherは危険な値との厳密な等価比較を探し ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87))、攻撃者がコントラクトを罠にかけるのを防ぐために、`==`ではなく`>=`または`<=`を使用すべきであるとユーザーに通知します。 とりわけ、検出器は `balanceOf(address)` の呼び出しの戻り値を危険とみなし ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64))、その使用状況を追跡するためにデータ依存性エンジンを使用します。
-#### 不動点の計算 {#fixed-point-computation}
+#### 不動点計算 {#fixed-point-computation}
-解析がエッジを辿ってCFG全体を移動する場合、すでに訪問済みのノードを発見する可能性が高いでしょう。 例えば、以下のようなループがある場合です:
+解析がCFGを走査してエッジをたどる場合、すでに訪れたノードに遭遇する可能性があります。 例えば、以下のようにループが存在する場合です。
```solidity
for(uint i; i < range; ++){
@@ -183,23 +178,23 @@ for(uint i; i < range; ++){
}
```
-この場合、解析をいつ停止するかを指定する必要があります。 それには、(1)ノードごとにイテレートする上限回数を設定するか、(2)いわゆる_不動点_を計算する、という2つの戦略があります。 不動点とは、当該ノードをさらに解析しても有益な情報が得られない点を意味します。
+解析はいつ停止すべきかを知る必要があります。 ここには2つの主要な戦略があります。(1) 各ノードを有限回反復する、(2) いわゆる_不動点_を計算する。 不動点とは、基本的に、そのノードを解析しても、もはや有意義な情報が得られないことを意味します。
-不動点を使用する実例としては、リエントランシー検出器が挙げられます。Slitherでは、当該のノードを探索し、外部からの呼び出しを見つけて、ストレージへの書き込み/読み取りを行います。 この処理を通じて不動点に到達すると([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131))、探索を停止し、様々なリエントランシーのパターン([reentrancy_beign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py))、([reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py))、([reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py))に基づき、結果を解析してリエントランシーが存在するか否かを判定します。
+不動点の使用例は、リエントランシー検出器に見られます。Slitherはノードを探索し、外部呼び出し、ストレージへの書き込みと読み込みを探します。 不動点に達すると ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131))、探索を停止し、さまざまなリエントランシーパターン ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)) を通じて結果を解析し、リエントランシーが存在するかどうかを確認します。
-効率的な不動点計算を用いた解析を作成するには、解析において情報がどのように拡散するかをよく理解しておく必要があります。
+効率的な不動点計算を用いた解析を書くには、解析がどのように情報を伝播させるかをよく理解する必要があります。
### 中間表現 {#intermediate-representation}
-中間表現(IR)は、オリジナルのコードよりも静的解析を実行しやすくした言語です。 Slitherでは、SolidityをSlither独自のIRである[SlithIR](https://github.com/crytic/slither/wiki/SlithIR)に変換します。
+中間表現 (IR) とは、元の言語よりも静的解析に適した言語のことです。 Slitherは、Solidityを独自の中間表現である [SlithIR](https://github.com/crytic/slither/wiki/SlithIR) に変換します。
-基本的なチェックを作成したいだけの場合は、SlithIRを理解する必要はありません。 ただし、より高度な意味解析を作成したい場合は、SlithIRの知識が有益になるでしょう。 [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir)および[SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa)のプリンターは、コードがどのように変換されるかを理解する上で役立ちます。
+基本的なチェックを書きたいだけなら、SlithIRを理解する必要はありません。 しかし、高度な意味解析を書く予定がある場合は、役立つでしょう。 [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) および [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) プリンターは、コードがどのように変換されるかを理解するのに役立ちます。
## APIの基本 {#api-basics}
-Slitherには、コントラクトの基本的な属性や関数について探索できるAPIが含まれています。
+Slitherには、コントラクトとその関数の基本的な属性を探索できるAPIがあります。
-コードベースを読み込むには、以下を実行します:
+コードベースを読み込むには、次のようにします。
```python
from slither import Slither
@@ -207,32 +202,32 @@ slither = Slither('/path/to/project')
```
-### コントラクトや関数を探索する {#exploring-contracts-and-functions}
+### コントラクトと関数の探索 {#exploring-contracts-and-functions}
-`Slither`オブジェクトは、以下を持ちます:
+`Slither`オブジェクトには以下のものがあります。
-- `contracts (list(Contract)`:コントラクトのリスト
-- `contracts_derived (list(Contract)`:他のコントラクトに継承されていないコントラクトのリスト(コントラクトのサブセット)
-- `get_contract_from_name (str)`:名前でコントラクトを返します
+- `contracts (list(Contract))`: コントラクトのリスト
+- `contracts_derived (list(Contract))`: 他のコントラクトによって継承されていないコントラクトのリスト (コントラクトのサブセット)
+- `get_contract_from_name (str)`: 名前からコントラクトを返します
-`Contract`オブジェクトには、以下のものがあります。
+`Contract`オブジェクトには以下のものがあります。
-- `name (str)`:コントラクトの名前
-- `functions (list(Function))`:関数のリスト
-- `modifiers (list(Modifier))`:修飾子のリスト
-- `all_functions_called (list(Function/Modifier))`:コントラクトがリーチできるすべての内部関数のリスト
-- `inheritance (list(Contract))`:継承されたコントラクトのリスト
-- `get_function_from_signature (str)`:署名から関数を返します
-- `get_modifier_from_signature (str)`:署名から修飾子を返します
-- `get_state_variable_from_name (str)`:名前から状態変数を返します
+- `name (str)`: コントラクトの名前
+- `functions (list(Function))`: 関数のリスト
+- `modifiers (list(Modifier))`: 修飾子のリスト
+- `all_functions_called (list(Function/Modifier))`: コントラクトから到達可能なすべての内部関数のリスト
+- `inheritance (list(Contract))`: 継承されたコントラクトのリスト
+- `get_function_from_signature (str)`: シグネチャからFunctionを返します
+- `get_modifier_from_signature (str)`: シグネチャからModifierを返します
+- `get_state_variable_from_name (str)`: 名前からStateVariableを返します
-`Function`オブジェクトまたは`Modifier`オブジェクトは、以下を持ちます:
+`Function`または`Modifier`オブジェクトには以下のものがあります。
-- `name (str)`:関数の名前
-- `contract (contract)`:この関数を宣言したコントラクト
-- `nodes (list(Node))`:この関数/修飾子のCFGを攻勢するノードのリスト
-- `entry_point (Node)`: CFG (制御フローグラフ) のエントリポイント
-- `variables_read (list(Variable))`: 読み込まれた変数のリスト
+- `name (str)`: 関数の名前
+- `contract (contract)`: 関数が宣言されているコントラクト
+- `nodes (list(Node))`: 関数/修飾子のCFGを構成するノードのリスト
+- `entry_point (Node)`: CFGのエントリポイント
+- `variables_read (list(Variable))`: 読み取られた変数のリスト
- `variables_written (list(Variable))`: 書き込まれた変数のリスト
-- `state_variables_read (list(StateVariable))`: 読み込まれた状態変数のリスト (読み込まれた変数のサブセット)
-- `state_variables_written (list(StateVariable))`: 書き込まれた状態変数のリスト (書き込まれた変数のサブセット)
+- `state_variables_read (list(StateVariable))`: 読み取られた状態変数のリスト (variables`readのサブセット)
+- `state_variables_written (list(StateVariable))`: 書き込まれた状態変数のリスト (variables`writtenのサブセット)
diff --git a/public/content/translations/ja/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/ja/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md
index 8c4d3d5f70e..eb24ffc5346 100644
--- a/public/content/translations/ja/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md
+++ b/public/content/translations/ja/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md
@@ -1,12 +1,9 @@
---
-title: Tellorをオラクルとしてセットアップする方法
-description: プロトコルにTellorオラクルを統合する作業を開始するためのガイド
+title: "Tellorをオラクルとしてセットアップする方法"
+description: "プロトコルにTellorオラクルを統合する作業を開始するためのガイド"
author: "Tellor"
lang: ja
-tags:
- - "Solidity"
- - "スマートコントラクト"
- - "オラクル"
+tags: [ "Solidity", "スマート契約", "オラクル" ]
skill: beginner
published: 2021-06-29
source: Tellor Docs
@@ -15,11 +12,11 @@ sourceUrl: https://docs.tellor.io/tellor/
確認クイズ:あなたのプロトコルはもうすぐ完成しますが、オフチェーンのデータにアクセスするにはオラクルが必要です。何をすればよいでしょうか?
-## (ソフトな)前提知識 {#soft-prerequisites}
+## (緩やかな) 前提条件 {#soft-prerequisites}
この投稿は、なるべくシンプルかつ明快に、オラクルフィードにアクセスする方法を説明するものです。 ただし、オラクルについて理解するには以下のプログラミングスキルが必要です。
-前提条件:
+前提知識:
- ターミナルを操作できる
- npmがインストール済みである
@@ -29,17 +26,17 @@ Tellorは、実装可能かつ開発継続中のオープンソースのオラ
## 概要 {#overview}
-Tellorは、オフチェーンのデータポイントの値(例:BTC/USD)を請求できるオラクルシステムです。報告者は、イーサリアムの全スマートコントラクトがアクセスできるオンチェーンのデータバンクに対してこの値を追加するために競います。 このデータバンクへの入力は、ステーキング済みの報告者で構成されるネットワークにより保護されています。 Tellorは、暗号資産経済におけるインセンティブの仕組みを活用し、Tellorのトークン、トリビュート(TRB)、および紛争メカニズムに基づき、正直なデータを提出した報告者に報酬を与え、悪意のユーザーを処罰します。
+Tellorは、オフチェーンのデータポイントの値(例:BTC/USD)を請求できるオラクルシステムです。報告者は、イーサリアムの全スマートコントラクトがアクセスできるオンチェーンのデータバンクに対してこの値を追加するために競います。 このデータバンクへの入力は、ステーキング済みの報告者で構成されるネットワークにより保護されています。 Tellorは暗号経済的なインセンティブの仕組みを活用し、TellorのトークンであるTributes(TRB)の発行と紛争メカニズムを通じて、誠実なデータを提出したレポーターに報酬を与え、悪意のあるアクタを罰します。
このチュートリアルでは、以下について説明します:
- 導入および稼働に必要な初回ツールキットの設定方法
- 簡単な実例に基づくステップごとの説明
-- 現在Tellorをテストできるネットワークのアドレスリスト
+- 現在Tellorをテストできるテストネットのネットワークアドレス一覧
-## Tellorを使うには {#usingtellor}
+## UsingTellorの使用 {#usingtellor}
-まず、Tellorをオラクルとして使用するために必要な基本ツールをインストールします。 Tellorのユーザーコントラクトをインストールするには、[このパッケージ](https://github.com/tellor-io/usingtellor)を使ってください。
+まず、Tellorをオラクルとして使用するために必要な基本ツールをインストールします。 Tellor User Contractsをインストールするには、[このパッケージ](https://github.com/tellor-io/usingtellor)を使用します:
`npm install usingtellor`
@@ -49,7 +46,7 @@ Tellorは、オフチェーンのデータポイントの値(例:BTC/USD)
### BTC/USDの例 {#btcusd-example}
-この「UsingTellor」コントラクトを継承し、Tellorのアドレスをコントラクタの引数として渡します:
+この「UsingTellor」コントラクトを継承し、Tellorのアドレスをコンストラクタの引数として渡します:
具体的なコードは、以下のようになります:
@@ -59,7 +56,7 @@ import "usingtellor/contracts/UsingTellor.sol";
contract PriceContract is UsingTellor {
uint256 public btcPrice;
- //This Contract now has access to all functions in UsingTellor
+ //このコントラクトは、UsingTellor のすべての関数にアクセスできるようになりました
constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {}
@@ -77,8 +74,8 @@ function setBtcPrice() public {
}
```
-コントラクトアドレスの完全なリストについては、[こちら](https://docs.tellor.io/tellor/the-basics/contracts-reference)を参照してください。
+コントラクトアドレスの完全なリストは、[こちら](https://docs.tellor.io/tellor/the-basics/contracts-reference)を参照してください。
-利便性のために、UsingTellorのリポジトリには簡単な統合を目的としたバージョンである[Tellor Playground](https://github.com/tellor-io/TellorPlayground)コントラクトが含まれています。 有益な関数のリストについては、 [こちら](https://github.com/tellor-io/sampleUsingTellor#tellor-playground)を参照してください。
+利便性のために、UsingTellorのリポジトリには簡単な統合を目的としたバージョンである[Tellor Playground](https://github.com/tellor-io/TellorPlayground)コントラクトが含まれています。 便利な関数の一覧は[こちら](https://github.com/tellor-io/sampleUsingTellor#tellor-playground)をご覧ください。
-Tellorオラクルをより堅牢に実装したい場合は、[こちらで](https://github.com/tellor-io/usingtellor/blob/master/README.md)利用可能な関数の全リストを確認してください。
+Tellorオラクルのより堅牢な実装については、利用可能な関数の完全なリストを[こちら](https://github.com/tellor-io/usingtellor/blob/master/README.md)で確認してください。