Skip to content

Commit

Permalink
Merge pull request #24 from Hyuntae-91/master
Browse files Browse the repository at this point in the history
Common-patterns λ²ˆμ—­ μ™„λ£Œ
  • Loading branch information
dongsam committed Nov 27, 2018
2 parents adaf155 + 0322dc3 commit cde18f3
Showing 1 changed file with 122 additions and 131 deletions.
253 changes: 122 additions & 131 deletions common-patterns.rst
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
###############
Common Patterns
자주 μ“°μ΄λŠ” νŒ¨ν„΄
###############

.. index:: withdrawal

.. _withdrawal_pattern:

*************************
Withdrawal from Contracts
μ»¨νŠΈλž™νŠΈμ—μ„œμ˜ 좜금
*************************

The recommended method of sending funds after an effect
is using the withdrawal pattern. Although the most intuitive
method of sending Ether, as a result of an effect, is a
direct ``send`` call, this is not recommended as it
introduces a potential security risk. You may read
more about this on the :ref:`security_considerations` page.
Effect 이후 κΈ°κΈˆμ†‘κΈˆμ— μžˆμ–΄ κ°€μž₯ ꢌμž₯λ˜λŠ” 방법은
좜금 νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. Effect의 결과둜 Etherλ₯Ό μ†‘κΈˆν•˜λŠ”
κ°€μž₯ 직관적인 방법은 직접 ``send`` λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒμ΄κ² μ§€λ§Œ,
잠재적인 λ³΄μ•ˆμœ„ν˜‘μ„ 초래 ν•  수 μžˆμœΌλ―€λ‘œ ꢌμž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
:ref:`security_consideration` νŽ˜μ΄μ§€μ—μ„œ λ³΄μ•ˆμ— λŒ€ν•΄ 더 μ•Œμ•„ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

This is an example of the withdrawal pattern in practice in
a contract where the goal is to send the most money to the
contract in order to become the "richest", inspired by
`King of the Ether <https://www.kingoftheether.com/>`_.

In the following contract, if you are usurped as the richest,
you will receive the funds of the person who has gone on to
become the new richest.
λ‹€μŒμ€ `King of the Ether <https://www.kingoftheether.com/>`_ μ—μ„œ
μ˜κ°μ„ λ°›μ•„ μž‘μ„±λœ "richest"κ°€ 되기 μœ„ν•΄ κ°€μž₯ λ§Žμ€ λˆμ„
μ»¨νŠΈλž™νŠΈλ‘œ μ†‘κΈˆν•˜λŠ” μ‹€μ œ μΆœκΈˆνŒ¨ν„΄ μ˜ˆμ œμž…λ‹ˆλ‹€.

λ‹€μŒμ˜ μ»¨νŠΈλž™νŠΈμ—μ„œ 당신이 "richest"λ₯Ό λΉΌμ•—κΈ΄λ‹€λ©΄, μƒˆλ‘­κ²Œ "richest"
κ°€ 된 μ‚¬λžŒμœΌλ‘œλΆ€ν„° κΈ°κΈˆμ„ 돌렀 받을 κ²ƒμž…λ‹ˆλ‹€.

::

Expand Down Expand Up @@ -54,14 +52,14 @@ become the new richest.

function withdraw() public {
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
// λ¦¬μ—”νŠΈλž€μ‹œ(re-entrancy) 곡격을 μ˜ˆλ°©ν•˜κΈ° μœ„ν•΄
// μ†‘κΈˆν•˜κΈ° 전에 보λ₯˜μ€‘인 ν™˜λΆˆμ„ 0으둜 κΈ°μ–΅ν•΄ λ‘μ‹­μ‹œμ˜€.
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
}

This is as opposed to the more intuitive sending pattern:
λ‹€μŒμ€ 직관적인 μ†‘κΈˆνŒ¨ν„΄κ³Ό μ •λ°˜λŒ€μΈ νŒ¨ν„΄μž…λ‹ˆλ‹€.

::

Expand All @@ -78,7 +76,7 @@ This is as opposed to the more intuitive sending pattern:

function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) {
// This line can cause problems (explained below).
// ν˜„μž¬μ˜ 라인이 문제의 원인이 될 수 μžˆμŠ΅λ‹ˆλ‹€. (μ•„λž˜μ—μ„œ μ„€λͺ…됨)
richest.transfer(msg.value);
richest = msg.sender;
mostSent = msg.value;
Expand All @@ -89,73 +87,73 @@ This is as opposed to the more intuitive sending pattern:
}
}

Notice that, in this example, an attacker could trap the
contract into an unusable state by causing ``richest`` to be
the address of a contract that has a fallback function
which fails (e.g. by using ``revert()`` or by just
consuming more than the 2300 gas stipend). That way,
whenever ``transfer`` is called to deliver funds to the
"poisoned" contract, it will fail and thus also ``becomeRichest``
will fail, with the contract being stuck forever.
λ³Έ μ˜ˆμ œμ—μ„œ, λ°˜λ“œμ‹œ μ•Œμ•„λ‘¬μ•Ό ν•  것은, κ³΅κ²©μžκ°€ μ‹€νŒ¨
fallbackν•¨μˆ˜λ₯Ό 가진 μ»¨νŠΈλž™νŠΈ μ£Όμ†Œλ₯Ό ``richest`` 둜 λ§Œλ“€μ–΄
μ»¨νŠΈλž™νŠΈλ₯Ό ν•  수 μ—†λŠ” μƒνƒœλ‘œ λ§Œλ“€ 수 μžˆλ‹€λŠ” μ μž…λ‹ˆλ‹€.
(예λ₯Όλ“€μ–΄ ``revert()`` λ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ λ‹¨μˆœνžˆ 2300개 μ΄μƒμ˜ κ°€μŠ€λ₯Ό μ†ŒλΉ„μ‹œν‚΄μœΌλ‘œμ¨)
κ·Έλ ‡κ²Œν•˜λ©΄, "poisoned" μ»¨νŠΈλž™νŠΈμ— κΈ°κΈˆμ„ ``transfer`` ν•˜κΈ°μœ„ν•΄ μ†‘κΈˆμ΄
μš”μ²­ 될 λ•Œλ§ˆλ‹€ μ»¨νŠΈλž™νŠΈμ™€ λ”λΆˆμ–΄ ``becomeRichest`` 도 μ‹€νŒ¨ ν• 
것이고, μ΄λŠ” μ»¨νŠΈλž™νŠΈκ°€ μ˜μ›νžˆ μ§„ν–‰λ˜μ§€ μ•Šκ²Œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€.

In contrast, if you use the "withdraw" pattern from the first example,
the attacker can only cause his or her own withdraw to fail and not the
rest of the contract's workings.
λ°˜λŒ€λ‘œ, 첫번째 μ˜ˆμ œμ—μ„œ "withdraw" νŒ¨ν„΄μ„ μ‚¬μš©ν•œλ‹€λ©΄
곡격자의 좜금만 μ‹€νŒ¨ν•  것이고, λ‚˜λ¨Έμ§€ μ»¨νŠΈλž™νŠΈλŠ” μ œλŒ€λ‘œ λ™μž‘ ν•  κ²ƒμž…λ‹ˆλ‹€.

.. index:: access;restricting

******************
Restricting Access
μ œν•œλœ μ•‘μ„ΈμŠ€
******************

Restricting access is a common pattern for contracts.
Note that you can never restrict any human or computer
from reading the content of your transactions or
your contract's state. You can make it a bit harder
by using encryption, but if your contract is supposed
to read the data, so will everyone else.
μ œν•œλœ μ•‘μ„ΈμŠ€λŠ” μ»¨νŠΈλž™νŠΈμ—μ„œμ˜ 일반적인 νŒ¨ν„΄μž…λ‹ˆλ‹€.
μ•Œμ•„λ‘¬μ•Ό ν•  것은, λ‹€λ₯Έμ‚¬λžŒμ΄λ‚˜ 컴퓨터가 λ‹Ήμ‹ μ˜
μ»¨νŠΈλž™νŠΈ μƒνƒœμ˜ λ‚΄μš©μ„ μ½λŠ”κ²ƒμ„ κ²°μ½” μ œν•œ ν•  수
μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ•”ν˜Έν™”λ₯Ό μ‚¬μš©ν•¨μœΌλ‘œμ¨ μ»¨νŠΈλž™νŠΈλ₯Ό
더 읽기 μ–΄λ ΅κ²Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ»¨νŠΈλž™νŠΈκ°€
데이터λ₯Ό 읽으렀고 ν•œλ‹€λ©΄, λ‹€λ₯Έ λͺ¨λ“  μ‚¬λžŒλ“€ λ˜ν•œ
λ‹Ήμ‹ μ˜ 데이터λ₯Ό 읽을 수 μžˆμ„κ²ƒμž…λ‹ˆλ‹€.

You can restrict read access to your contract's state
by **other contracts**. That is actually the default
unless you declare make your state variables ``public``.
**λ‹€λ₯Έ μ»¨νŠΈλž™νŠΈλ“€** 이 μ»¨νŠΈλž™νŠΈ μƒνƒœλ₯Ό
읽지 λͺ» ν•˜λ„λ‘ κΆŒν•œμ„ μ œν•œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
μƒνƒœλ³€μˆ˜λ₯Ό ``public`` 으둜 μ„ μ–Έν•˜μ§€ μ•ŠλŠ” ν•œ,
이 μ œν•œμ€ λ””ν΄νŠΈλ‘œ μ œκ³΅λ©λ‹ˆλ‹€.

Furthermore, you can restrict who can make modifications
to your contract's state or call your contract's
functions and this is what this section is about.
κ²Œλ‹€κ°€, μ»¨νŠΈλž™νŠΈ μƒνƒœλ₯Ό μˆ˜μ •ν•˜κ±°λ‚˜ μ»¨νŠΈλž™νŠΈ ν•¨μˆ˜λ₯Ό 호좜
ν•  수 μžˆλŠ” μ‚¬λžŒμ„ μ œν•œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λ‹€μŒμ΄ λ°”λ‘œ λ³Έ μ„Ήμ…˜μ— λŒ€ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

.. index:: function;modifier

The use of **function modifiers** makes these
restrictions highly readable.
**function modifiers** λ₯Ό μ‚¬μš©ν•˜λ©΄ 이런 μ œν•œμ„
맀우 μ•Œμ•„λ³΄κΈ° μ‰½κ²Œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

::

pragma solidity ^0.4.11;

contract AccessRestriction {
// These will be assigned at the construction
// phase, where `msg.sender` is the account
// creating this contract.
// 이것듀은 κ±΄μ„€λ‹¨κ³„μ—μ„œ ν• λ‹Ήλ©λ‹ˆλ‹€.
// μ—¬κΈ°μ„œ, `msg.sender` λŠ”
// 이 계약을 μƒμ„±ν•˜λŠ” κ³„μ •μž…λ‹ˆλ‹€.
address public owner = msg.sender;
uint public creationTime = now;

// Modifiers can be used to change
// the body of a function.
// If this modifier is used, it will
// prepend a check that only passes
// if the function is called from
// a certain address.
// μˆ˜μ •μžλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜μ˜
// 본문을 λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
// 이 μˆ˜μ •μžκ°€ μ‚¬μš©λ˜λ©΄,
// ν•¨μˆ˜κ°€ νŠΉμ • μ£Όμ†Œμ—μ„œ 호좜 된
// κ²½μš°μ—λ§Œ ν†΅κ³Όν•˜λŠ” 검사가
// μΆ”κ°€λ©λ‹ˆλ‹€.
modifier onlyBy(address _account)
{
require(msg.sender == _account);
// Do not forget the "_;"! It will
// be replaced by the actual function
// body when the modifier is used.
// "_;" λ₯Ό κΉœλΉ‘ν•˜μ§€ λ§ˆμ„Έμš”! μˆ˜μ •μžκ°€
// μ‚¬μš© 될 λ•Œ, "_;"κ°€ μ‹€μ œ ν•¨μˆ˜
// 본문으둜 λŒ€μ²΄λ©λ‹ˆλ‹€.
_;
}

/// Make `_newOwner` the new owner of this
/// contract.
/// `_newOwner` λ₯Ό 이 μ»¨νŠΈλž™νŠΈμ˜
/// μƒˆ μ†Œμœ μžλ‘œ λ§Œλ“­λ‹ˆλ‹€.
function changeOwner(address _newOwner)
public
onlyBy(owner)
Expand All @@ -168,9 +166,9 @@ restrictions highly readable.
_;
}

/// Erase ownership information.
/// May only be called 6 weeks after
/// the contract has been created.
/// μ†Œμœ κΆŒ 정보λ₯Ό μ§€μš°μ‹­μ‹œμ˜€.
/// μ»¨νŠΈλž™νŠΈκ°€ μƒμ„±λœ ν›„ 6μ£Όκ°€
/// μ§€λ‚˜μ•Ό 호좜 될 수 μžˆμŠ΅λ‹ˆλ‹€.
function disown()
public
onlyBy(owner)
Expand All @@ -179,12 +177,12 @@ restrictions highly readable.
delete owner;
}

// This modifier requires a certain
// fee being associated with a function call.
// If the caller sent too much, he or she is
// refunded, but only after the function body.
// This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`.
// 이 μˆ˜μ •μžλŠ” ν•¨μˆ˜ 호좜과 κ΄€λ ¨λœ
// νŠΉμ • μš”κΈˆμ„ μš”κ΅¬ν•©λ‹ˆλ‹€.
// ν˜ΈμΆœμžκ°€ λ„ˆλ¬΄ λ§Žμ€ κΈˆμ•‘μ„ μ†‘κΈˆν–ˆμ„μ‹œ,
// ν•¨μˆ˜ λ³Έλ¬Έ μ΄ν›„μ—λ§Œ ν™˜κΈ‰μ΄ λ©λ‹ˆλ‹€.
// μ΄λŠ” 솔리디티 0.4.0 μ΄μ „μ˜ λ²„μ „μ—μ„œλŠ” μœ„ν—˜ν–ˆμ—ˆλ‹€.
// `_;` μ΄ν›„μ˜ 뢀뢄은 μŠ€ν‚΅λ  κ°€λŠ₯성이 μžˆμ—ˆλ‹€.
modifier costs(uint _amount) {
require(msg.value >= _amount);
_;
Expand All @@ -197,78 +195,71 @@ restrictions highly readable.
costs(200 ether)
{
owner = _newOwner;
// just some example condition
// λͺ‡ κ°€μ§€μ˜ 예제 쑰건
if (uint(owner) & 0 == 1)
// This did not refund for Solidity
// before version 0.4.0.
// μ΄λŠ” 솔리디티 0.4.0 μ΄μ „μ˜
// λ²„μ „μ—μ„œλŠ” ν™˜λΆˆλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
return;
// refund overpaid fees
// 초과 μš”κΈˆμ— λŒ€ν•œ ν™˜λΆˆ
}
}

A more specialised way in which access to function
calls can be restricted will be discussed
in the next example.
ν•¨μˆ˜ν˜ΈμΆœμ— λŒ€ν•œ μ•‘μ„ΈμŠ€λ₯Ό μ œν•œ ν•  수 μžˆλŠ” 보닀 νŠΉλ³„ν•œ
방법에 λŒ€ν•΄μ„œλŠ” λ‹€μŒ μ˜ˆμ œμ—μ„œ μ„€λͺ…ν•©λ‹ˆλ‹€.

.. index:: state machine

*************
State Machine
μƒνƒœ λ¨Έμ‹ 
*************

Contracts often act as a state machine, which means
that they have certain **stages** in which they behave
differently or in which different functions can
be called. A function call often ends a stage
and transitions the contract into the next stage
(especially if the contract models **interaction**).
It is also common that some stages are automatically
reached at a certain point in **time**.
μ»¨νŠΈλž™νŠΈλŠ” μ’…μ’… μƒνƒœλ¨Έμ‹ μΈ κ²ƒμ²˜λŸΌ λ™μž‘ν•©λ‹ˆλ‹€. λ‹€μ‹œ 말해,
μ»¨νŠΈλž™νŠΈλ“€μ΄ λ‹€λ₯΄κ²Œ λ™μž‘ν•˜κ±°λ‚˜ λ‹€λ₯Έ ν•¨μˆ˜λ“€μ— μ˜ν•΄ ν˜ΈμΆœλ˜λŠ”
μ–΄λ– ν•œ **단계** λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€.
ν•¨μˆ˜ ν˜ΈμΆœμ€ μ’…μ’… 단계λ₯Ό 끝내고 μ»¨νŠΈλž™νŠΈλ₯Ό λ‹€μŒ λ‹¨κ³„λ‘œ μ „ν™˜
μ‹œν‚΅λ‹ˆλ‹€. (특히 μ»¨νŠΈλž™νŠΈ λͺ¨λΈμ΄ **μƒν˜Έμž‘μš©** 인 κ²½μš°μ—)
λ˜ν•œ, **μ‹œκ°„** 의 νŠΉμ • μ§€μ μ—μ„œ 일뢀 단계에 μžλ™μœΌλ‘œ 도달
ν•˜λŠ” 것이 μΌλ°˜μ μž…λ‹ˆλ‹€.

An example for this is a blind auction contract which
starts in the stage "accepting blinded bids", then
transitions to "revealing bids" which is ended by
"determine auction outcome".
예λ₯Ό λ“€μ–΄ "λΈ”λΌμΈλ“œ μž…μ°°μ„ μˆ˜λ½ν•˜λŠ”" λ‹¨κ³„μ—μ„œ μ‹œμž‘ν•˜μ—¬
"μ˜₯μ…˜ κ²°κ³Ό κ²°μ •"으둜 λλ‚˜λŠ” "곡개 μž…μ°°"둜 μ „ν™˜ν•˜λŠ”
λΈ”λΌμΈλ“œ μ˜₯μ…˜ μ»¨νŠΈλž™νŠΈκ°€ μžˆμŠ΅λ‹ˆλ‹€.

.. index:: function;modifier

Function modifiers can be used in this situation
to model the states and guard against
incorrect usage of the contract.
이 μƒν™©μ—μ„œ μƒνƒœλ₯Ό λͺ¨λΈλ§ν•˜κ³  μ»¨νŠΈλž™νŠΈμ˜ 잘λͺ»λœ μ‚¬μš©μ„
λ°©μ§€ν•˜κΈ° μœ„ν•΄ ν•¨μˆ˜ μˆ˜μ •μžλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Example
예제
=======

In the following example,
the modifier ``atStage`` ensures that the function can
only be called at a certain stage.

Automatic timed transitions
are handled by the modifier ``timeTransitions``, which
should be used for all functions.

.. note::
**Modifier Order Matters**.
If atStage is combined
with timedTransitions, make sure that you mention
it after the latter, so that the new stage is
taken into account.

Finally, the modifier ``transitionNext`` can be used
to automatically go to the next stage when the
function finishes.

.. note::
**Modifier May be Skipped**.
This only applies to Solidity before version 0.4.0:
Since modifiers are applied by simply replacing
code and not by using a function call,
the code in the transitionNext modifier
can be skipped if the function itself uses
return. If you want to do that, make sure
to call nextStage manually from those functions.
Starting with version 0.4.0, modifier code
will run even if the function explicitly returns.
λ‹€μŒμ˜ μ˜ˆμ œμ—μ„œ,
μˆ˜μ •μž ``atStage`` λŠ” ν•¨μˆ˜κ°€ νŠΉμ • λ‹¨κ³„μ—μ„œλ§Œ
ν˜ΈμΆœλ˜λ„λ‘ 보μž₯ν•΄ μ€λ‹ˆλ‹€.

μžλ™ timed transitions λŠ”
λͺ¨λ“  ν•¨μˆ˜μ—μ„œ μ‚¬μš©λ˜λŠ” μˆ˜μ •μž ``timeTransitions``
에 μ˜ν•΄ μ²˜λ¦¬λ©λ‹ˆλ‹€.

.. μ•Œμ•„λ‘κΈ°::
**μˆ˜μ •μž μ£Όλ¬Έ κ΄€λ ¨ 사항**.
atStage μˆ˜μ •μžκ°€ timedTransitions μˆ˜μ •μžμ™€
κ²°ν•©λœλ‹€λ©΄, 후미에 λ°˜λ“œμ‹œ 이 결합에 λŒ€ν•΄ μ–ΈκΈ‰ν•˜μ—¬,
μƒˆλ‘œμš΄ 단계가 κ³ λ €λ˜λ„λ‘ ν•˜μ‹­μ‹œμ˜€.

λ§ˆμ§€λ§‰μœΌλ‘œ, μˆ˜μ •μž ``transitionNext`` λŠ” ν•¨μˆ˜κ°€ 끝났을 λ•Œ,
μžλ™μ μœΌλ‘œ λ‹€μŒ λ‹¨κ³„λ‘œ λ„˜μ–΄κ°€λ„λ‘ ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.

.. μ•Œμ•„λ‘κΈ°::
**μˆ˜μ •μžλŠ” μŠ€ν‚΅ 될 수 μžˆμŠ΅λ‹ˆλ‹€**.
μ΄λŠ” 솔리디티 0.4.0 이전 λ²„μ „μ—μ„œλ§Œ μ μš©λ©λ‹ˆλ‹€:
μˆ˜μ •μžλŠ” λ‹¨μˆœνžˆ μ½”λ“œλ₯Ό κ΅μ²΄ν•˜κ³  ν•¨μˆ˜ ν˜ΈμΆœμ„ μ‚¬μš©ν•˜μ§€
μ•ŠμŒμœΌλ‘œμ¨ μ μš©λ˜λ―€λ‘œ, ν•¨μˆ˜ μžμ²΄μ—μ„œ return을
μ‚¬μš©ν•˜λ©΄, transitionNext μˆ˜μ •μžμ˜ μ½”λ“œλ₯Ό μŠ€ν‚΅
ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό μ‚¬μš©ν•˜κ³  μ‹Άλ‹€λ©΄, λ°˜λ“œμ‹œ
κ·Έ ν•¨μˆ˜λ“€μ—μ„œ nextStageλ₯Ό μˆ˜λ™μœΌλ‘œ ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€.
0.4.0 버전 λΆ€ν„°λŠ” ν•¨μˆ˜κ°€ λͺ…μ‹œμ μœΌλ‘œ return λ˜λŠ”
κ²½μš°μ—λ„ μˆ˜μ •μž μ½”λ“œκ°€ μ‹€ν–‰λ©λ‹ˆλ‹€.

::

Expand All @@ -283,7 +274,7 @@ function finishes.
Finished
}

// This is the current stage.
// 이 뢀뢄이 ν˜„μž¬μ˜ λ‹¨κ³„μž…λ‹ˆλ‹€.
Stages public stage = Stages.AcceptingBlindedBids;

uint public creationTime = now;
Expand All @@ -297,28 +288,28 @@ function finishes.
stage = Stages(uint(stage) + 1);
}

// Perform timed transitions. Be sure to mention
// this modifier first, otherwise the guards
// will not take the new stage into account.
// timed transitionsλ₯Ό μˆ˜ν–‰ν•˜μ‹­μ‹œμ˜€.
// 이 μˆ˜μ •μžλ₯Ό λ¨Όμ € μ–ΈκΈ‰ν•΄μ•Ό ν•©λ‹ˆλ‹€. 그렇지 μ•ŠμœΌλ©΄,
// Guardsκ°€ μƒˆλ‘œμš΄ 단계λ₯Ό κ³ λ €ν•˜μ§€ μ•Šμ„ 것 μž…λ‹ˆλ‹€.
modifier timedTransitions() {
if (stage == Stages.AcceptingBlindedBids &&
now >= creationTime + 10 days)
nextStage();
if (stage == Stages.RevealBids &&
now >= creationTime + 12 days)
nextStage();
// The other stages transition by transaction
// λ‹€λ₯Έ λ‹¨κ³„λŠ” κ±°λž˜μ— μ˜ν•΄ μ „ν™˜λ©λ‹ˆλ‹€.
_;
}

// Order of the modifiers matters here!
// μˆ˜μ •μžμ˜ μˆœμ„œκ°€ μ€‘μš”ν•©λ‹ˆλ‹€!
function bid()
public
payable
timedTransitions
atStage(Stages.AcceptingBlindedBids)
{
// We will not implement that here
// μš°λ¦¬λŠ” μ—¬κΈ°μ„œ 그것을 κ΅¬ν˜„ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€.
}

function reveal()
Expand All @@ -328,8 +319,8 @@ function finishes.
{
}

// This modifier goes to the next stage
// after the function is done.
// 이 μˆ˜μ •μžλŠ” ν•¨μˆ˜κ°€ μ™„λ£Œλœ ν›„
// λ‹€μŒ λ‹¨κ³„λ‘œ μ΄λ™ν•©λ‹ˆλ‹€.
modifier transitionNext()
{
_;
Expand Down

0 comments on commit cde18f3

Please sign in to comment.