рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдзреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд░реЗрдВ

рдЫрд╡рд┐

рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдХреА рд╢рд░реНрддреЛрдВ рдХреЛ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЬрдм рднреА рдЖрдк рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдг рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдПрдХ рдЕрдиреБрдмрдВрдз рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рддрд░реАрдХрд╛ рд╣реИред рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рдЖрдк рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рдХрджрдо рдЙрдард╛рдирд╛ рд╣реИред

рдореИрдВ рдмрддрд╛рдКрдВрдЧрд╛:

  1. рдЯреЗрд╕реНрдЯ рдХрд╛ рдорд╛рд╣реМрд▓ рдХреИрд╕реЗ рддреИрдпрд╛рд░ рдХрд░реЗрдВред
  2. рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЯреНрд░рдлрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВред

рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдЙрди рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЕрднреА рдПрдереЗрд░рд┐рдпрдо рдкрд░ рд╕реНрдорд╛рд░реНрдЯ рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯреНрд╕ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рджреЗрд░реА рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рд╣реИред рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрдо рд╕реЗ рдХрдо рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рд╕реЙрд▓рд┐рдбрд┐рдЯреА рдХрд╛ рдмреБрдирд┐рдпрд╛рджреА рдЬреНрдЮрд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

1. рдЯреЗрд╕реНрдЯ рдХрд╛ рдорд╛рд╣реМрд▓ рдХреИрд╕реЗ рддреИрдпрд╛рд░ рдХрд░реЗрдВ


рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдзреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди Truffle рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдкрд░реАрдХреНрд╖рдг рд▓реЗрдЦрди рдЙрдкрдХрд░рдг рд╣реИред Truffle рдкрд░, рдЖрдк рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдЙрддреНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░реНрдг рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рд╛рдЗрдЯ рд╕реЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг Node.js рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдлрд┐рд░ рдПрдХ рдЯрд░реНрдорд┐рдирд▓ рдЦреЛрд▓реЗрдВ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Truffle рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:

npm install -g truffle 

Truffle рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЯрд░реНрдорд┐рдирд▓ рдХреЛ рдмрдВрдж рдХрд┐рдП рдмрд┐рдирд╛, рдлрдВрдбрд┐рдВрдЧ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдПрдВ:

 mkdir Funding 

рдЕрдЧрд▓рд╛, рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдкрд░ рдЬрд╛рдПрдВ:

 cd Funding 

рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдБ:

 truffle init 

рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реЛрд▓реНрдбрд░ рдФрд░ рдлрд╛рдЗрд▓реЗрдВ рдлрдВрдбрд┐рдВрдЧ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рдмрдирд╛рдИ рдЬрд╛рдПрдВрдЧреА:

рдЫрд╡рд┐

рдЖрдЧреЗ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдмреАрдЪ, рд╣рдо рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред

рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдореЛрдЪрд╛ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╡рд░реНрдгрди рдФрд░ рдпрд╣ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ ред

рдЪрд╛рдп рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬреЛ рдЪреЗрдХ рдХреЗ рд▓рд┐рдП рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ "рд╢реИрд▓рд┐рдпрд╛рдБ" рд╣реИрдВ, рдФрд░ рдЪрд╛рдп рд╣рдореЗрдВ рдпрд╣ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИред рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ рд╣рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ред

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдореЛрдЪрд╛ рдЯреНрд░рдлрд▓ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд╛рдИ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЯрд░реНрдорд┐рдирд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдореВрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ, рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдБ:

 npm install chai 

рдореИрдВрдиреЗ рдордирдорд╛рдиреА рдкрд░рд┐рд╢реБрджреНрдзрддрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд╛рдИ-рдмрд┐рдЧрдирдореНрдмрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рднреА рд╕реНрдерд╛рдкрд┐рдд рдХреА:

 npm install --save-dev chai-bignumber 

рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╡рд╛рддрд╛рд╡рд░рдг рдЗрд╕рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдЕрдм рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

2. рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЯреНрд░рдлрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ


рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдПрдХ рдЕрдиреБрдмрдВрдз рд╡рд┐рдХрд╕рд┐рдд рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдЖрдкрдХреЛ рджрд╛рди рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдзрди рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рд╛рд╢рд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рдЕрдзрд┐рдХ рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЬреЛ рд░рд╛рд╢рд┐ рдЬрдорд╛ рд╣реБрдИ рд╣реИ рдФрд░ рдЬреЛ рд░рд╛рд╢рд┐ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдЙрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдлрд╝рдВрдбрд┐рдВрдЧ -> рдЕрдиреБрдмрдВрдз рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкрд░ рдЬрд╛рдПрдВред рдлрдВрдбрд┐рдВрдЧ / рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯреНрд╕ рдореЗрдВ, рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде Funding.sol рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВ .sol - рдпрд╣ рдЯреЗрд╕реНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реНрдорд╛рд░реНрдЯ рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯ рд╣реЛрдЧрд╛ред

Funding.sol рдореЗрдВ, рдирд┐рдореНрди рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:

 pragma solidity 0.4.24; contract Funding { uint public raised; uint public goal; address public owner; event Donated(uint donation); event Withdrew(uint amount); modifier onlyOwner() { require(owner == msg.sender); _; } modifier isFinished() { require(isFunded()); _; } modifier notFinished() { require(!isFunded()); _; } constructor (uint _goal) public { owner = msg.sender; goal = _goal; } function isFunded() public view returns (bool) { return raised >= goal; } function donate() public payable notFinished { uint refund; raised += msg.value; if (raised > goal) { refund = raised - goal; raised -= refund; msg.sender.transfer(refund); } emit Donated(msg.value); } function withdraw() public onlyOwner isFinished { uint amount = address(this).balance; owner.transfer(amount); emit Withdrew(amount); } } 

рдЕрдиреБрдмрдВрдз рддреИрдпрд╛рд░ рд╣реИред рд╣рдо рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗред

рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ Ethereum рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдЕрдиреБрдмрдВрдз рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИрдВред рдпрд╣ рдареЗрдХреЗ рдкрд░ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХрд╛ рдореБрдЦреНрдп рддрд░реАрдХрд╛ рд╣реИред

рдлрд╝рдВрдбрд┐рдВрдЧ рдкрд░ рдЬрд╛рдПрдБ -> рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдФрд░ 2_funding.js рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ, рдЗрд╕рдореЗрдВ рдирд┐рдореНрди рдХреЛрдб рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

 const Funding = artifacts.require("./Funding.sol"); const ETHERS = 10**18; const GOAL = 20 * ETHERS; module.exports = function(deployer) { deployer.deploy(Funding, GOAL); }; 

рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЯреНрд░рдлрд▓ рдкрд░реАрдХреНрд╖рдг рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ, рдлрдВрдбрд┐рдВрдЧ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдХреЗ рдореВрд▓ рдореЗрдВ рдЬрд╛рдПрдВ, рдЬреЛ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рддреИрдпрд╛рд░реА рдХреЗ рджреМрд░рд╛рди рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рджрд░реНрдЬ рдХрд░реЗрдВ:

 truffle test 

рдпрджрд┐ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдирд┐рдореНрди рдЖрдЙрдЯрдкреБрдЯ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ, рддреЛ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рдЫрд╡рд┐

рдЕрдм рдЯреЗрд╕реНрдЯ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рд╕реНрд╡рд╛рдореА рд╕рддреНрдпрд╛рдкрди



рдлрд╝рдВрдбрд┐рдВрдЧ -> рдкрд░реАрдХреНрд╖рдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рдПрдХреНрд╕рдЯреЗрдВрд╢рди .js рдХреЗ рд╕рд╛рде рдПрдХ test_funding.js рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВред рдпрд╣ рд╡рд╣ рдлрд╛рдЗрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗ рдЬрд╛рдПрдВрдЧреЗред

рдирд┐рдореНрди рдХреЛрдб рдХреЛ test_funding.js рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:

 const Funding = artifacts.require("Funding"); require("chai").use(require("chai-bignumber")(web3.BigNumber)).should(); contract("Funding", function([account, firstDonator, secondDonator]) { const ETHERS = 10**18; const GAS_PRICE = 10**6; let fundingContract = null; it("should check the owner is valid", async () => { fundingContract = await Funding.deployed(); const owner = await fundingContract.owner.call() owner.should.be.bignumber.equal(account); }); 

рдкрд░реАрдХреНрд╖рдг рдореЗрдВ, рд╣рдо рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдлрд╝рдВрдбрд┐рдВрдЧ рдЕрдиреБрдмрдВрдз рдЙрд╕ рдорд╛рд▓рд┐рдХ рдХреЗ рдкрддреЗ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдиреЗ рдЕрдиреБрдмрдВрдз рдХреЛ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдерд╛ред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЦрд╛рддрд╛ рд╕рд░рдгреА рдХрд╛ рдкрд╣рд▓рд╛ рддрддреНрд╡ рд╣реИред Truffle рдЖрдкрдХреЛ рджрд╕ рдкрддреЛрдВ рддрдХ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╣рдореЗрдВ рдХреЗрд╡рд▓ рддреАрди рдкрддреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рджрд╛рди рдХреА рд╕реНрд╡реАрдХреГрддрд┐ рдФрд░ рдзрди рдЙрдЧрд╛рд╣реА рдХреЗ рдЕрдВрдд рдХрд╛ рд╕рддреНрдпрд╛рдкрди


рдЗрд╕ рдЦрдВрдб рдореЗрдВ рд╣рдо рдЬрд╛рдБрдЪ рдХрд░реЗрдВрдЧреЗ:

  1. рджрд╛рди рдХреА рд╕реНрд╡реАрдХреГрддрд┐ рдФрд░ рд░рд╛рд╢рд┐ред
  2. рджрд╛рди рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд░рд╛рд╢рд┐ рддрдХ рдкрд╣реБрдБрдЪ рдЧрдпрд╛ рд╣реИред
  3. рдЕрдЧрд░ рдЖрдк рдЬрд░реВрд░рдд рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдЪрдВрджрд╛ рд▓реЗрддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред
  4. рджрд╛рди рдХреА рдХреБрд▓ рд░рд╛рд╢рд┐ред
  5. рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд░рд╛рд╢рд┐ рдПрдХрддреНрд░ рдХреА рдЧрдИ рд╣реИ рддреЛ рдХреНрдпрд╛ рдореИрдВ рдзрди рдЬреБрдЯрд╛рдирд╛ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддрд╛ рд╣реВрдВред

рд╣рдо рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВрдЧреЗ рдФрд░ рдЙрдирдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ:

 . . . . . . . . . . . . . . . . . . . . . . const ETHERS = 10**18; const GAS_PRICE = 10**6; let fundingContract = null; let txEvent; function findEvent(logs, eventName) { let result = null; for (let log of logs) { if (log.event === eventName) { result = log; break; } } return result; }; it("should accept donations from the donator #1", async () => { const bFirstDonator= web3.eth.getBalance(firstDonator); const donate = await fundingContract.donate({ from: firstDonator, value: 5 * ETHERS, gasPrice: GAS_PRICE }); txEvent = findEvent(donate.logs, "Donated"); txEvent.args.donation.should.be.bignumber.equal(5 * ETHERS); const difference = bFirstDonator.sub(web3.eth.getBalance(firstDonator)).sub(new web3.BigNumber(donate.receipt.gasUsed * GAS_PRICE)); difference.should.be.bignumber.equal(5 * ETHERS); }); 

рдкрд░реАрдХреНрд╖рдг рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ 2 рдЕрдВрдХ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ:

  1. рдШрдЯрдирд╛рдУрдВ (рдИрд╡реЗрдВрдЯреНрд╕) рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдФрд░ рдЗрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЦреЛрдЬ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред
  2. рдкрд░реАрдХреНрд╖рдг рдФрд░ рдЧрдгрдирд╛ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдЧреИрд╕ рдХреЗ рд▓рд┐рдП рдЖрдВрддрд░рд┐рдХ рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдирд┐рд░рдВрддрд░ GAS_PRICE)ред

рдЕрдм рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдореЗрдВ, рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА:

  • рдХрд┐ рд╣рдо рджрд╛рди () рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдХрд░ рджрд╛рди рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ;
  • рд╣рдорд╛рд░реЗ рд▓рд┐рдП рджрд╛рди рдХреА рдЧрдИ рд░рд╛рд╢рд┐ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рджрд░реНрд╢рд╛рдИ рдЧрдИ рд╣реИ;
  • рдЬрд┐рд╕рдиреЗ рдзрдирд░рд╛рд╢рд┐ рджрд╛рди рдХреА, рд╢реЗрд╖ рд░рд╛рд╢рд┐ рджрд╛рди рдХреА рдЧрдИ рд░рд╛рд╢рд┐ рд╕реЗ рдШрдЯ рдЧрдИред

 it("should check if donation is not completed", async () => { const isFunded = await fundingContract.isFunded(); isFunded.should.be.equal(false); }); 

рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ, рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рдзрди рдЙрдЧрд╛рд╣рдирд╛ рдЕрднреА рддрдХ рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИред

 it("should not allow to withdraw the fund until the required amount has been collected", async () => { let isCaught = false; try { await fundingContract.withdraw({ gasPrice: GAS_PRICE }); } catch (err) { isCaught = true; } isCaught.should.be.equal(true); }); 

рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рдЬрдм рддрдХ рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд░рд╛рд╢рд┐ рдирд╣реАрдВ рдорд┐рд▓ рдЬрд╛рддреА рддрдм рддрдХ рд╣рдо рдзрдирд░рд╛рд╢рд┐ рдирд╣реАрдВ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗред

 it("should accept donations from the donator #2", async () => { const bSecondDonator= web3.eth.getBalance(secondDonator); const donate = await fundingContract.donate({ from: secondDonator, value: 20 * ETHERS, gasPrice: GAS_PRICE }); txEvent = findEvent(donate.logs, "Donated"); txEvent.args.donation.should.be.bignumber.equal(20 * ETHERS); const difference = bSecondDonator.sub(web3.eth.getBalance(secondDonator)).sub(new web3.BigNumber(donate.receipt.gasUsed * GAS_PRICE)); difference.should.be.bignumber.equal(15 * ETHERS); }); 

рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рдпрджрд┐ рдЖрдк рдПрдХ рдмрдбрд╝реА рд░рд╛рд╢рд┐ рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рджрд╛рди () рд╡рд┐рдзрд┐ рдЙрд╕ рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдзрдирд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддреА рд╣реИ рдФрд░ рд╡рд╛рдкрд╕ рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдиреЗ рдЬрд╝рд░реВрд░рдд рд╕реЗ рдЬрд╝реНрдпрд╛рджрд╛ рджрд╛рди рдХрд┐рдпрд╛ рд╣реИред рдпрд╣ рд░рд╛рд╢рд┐ рдЙрд╕ рд░рд╛рд╢рд┐ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рд╣реИ рдЬреЛ рдЬрдорд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рд╡рд╣ рд░рд╛рд╢рд┐ рдЬреЛ рдЖрдк рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

 it("should check if the donation is completed", async () => { const notFunded = await fundingContract.isFunded(); notFunded.should.be.equal(true); }); it("should check if donated amount of money is correct", async () => { const raised = await fundingContract.raised.call(); raised.should.be.bignumber.equal(20 * ETHERS); }); it("should not accept donations if the fundraising is completed", async () => { let isCaught = false; try { await fundingContract.donate({ from: firstDonator, value: 10 * ETHERS }); } catch (err) { isCaught = true; } isCaught.should.be.equal(true); }); 

рдЗрди рддреАрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА:

  • рдзрди рдЙрдЧрд╛рд╣рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ;
  • рджрд╛рди рдХреА рд░рд╛рд╢рд┐ рд╕рд╣реА рд╣реИ;
  • рдХреЛрдИ рдФрд░ рдирд╣реАрдВ рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдзрди рдЙрдЧрд╛рд╣рдиреЗ рдХрд╛ рдХрд╛рдо рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред

рдзрди рдХреА рдирд┐рдХрд╛рд╕реА


рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рдЕрдкрдиреА рдЬрд░реВрд░рдд рдХреА рд░рд╛рд╢рд┐ рдПрдХрддреНрд░ рдХреА, рдЕрдм рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

  . . . . . . . . . . . . . . . . . . . . . . it("should allow the owner to withdraw the fund", async () => { const bAccount = web3.eth.getBalance(account); const withdraw = await fundingContract.withdraw({ gasPrice: GAS_PRICE }); txEvent = findEvent(withdraw.logs, "Withdrew"); txEvent.args.amount.should.be.bignumber.equal(20 * ETHERS); const difference = web3.eth.getBalance(account).sub(bAccount); difference.should.be.bignumber.equal(await fundingContract.raised.call() - withdraw.receipt.gasUsed * GAS_PRICE); }); 

рдЖрд╣рд░рдг () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ, рд╣рдордиреЗ рдЕрдкрдиреЗ рдорд╛рдорд▓реЗ рдЦрд╛рддреЗ рдореЗрдВ, рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдХреЗ рдорд╛рд▓рд┐рдХ рдХреЗ рдзрди рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗ рд▓рд┐рдпрд╛ред рдлрд┐рд░ рд╣рдордиреЗ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рд╣рдордиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдкрдиреА рдЬрд╝рд░реВрд░рдд рдХреА рд░рд╛рд╢рд┐ рд╡рд╛рдкрд╕ рд▓реЗ рд▓реА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдВрддрд░ рдореЗрдВ рдзрди рдХреА рдирд┐рдХрд╛рд╕реА рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ рд╢реЗрд╖ рд░рд╛рд╢рд┐ рдореЗрдВ рдЕрдВрддрд░ рд▓рд┐рдЦреЗрдВ ред рдкрд░рд┐рдгрд╛рдо рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рджрд╛рди рдХреА рд░рд╛рд╢рд┐ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рд▓реЗрдирджреЗрди рд╢реБрд▓реНрдХред рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкрд░реАрдХреНрд╖рдг рдФрд░ рдЧрдгрдирд╛ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЧреИрд╕ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдХреАрдордд рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреАред

рд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рд╛ рдЯреНрд░рдлрд▓ рдЯреЗрд╕реНрдЯ рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рдПрдВред рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдкрд░рд┐рдгрд╛рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЫрд╡рд┐

рдкрд░рд┐рдгрд╛рдо


рдореИрдВрдиреЗ рдПрдХ рд╕рд░рд▓ рдФрд░ рд╕рдордЭ рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реА рднрд╛рд╖рд╛ рдореЗрдВ рд╕реНрдорд╛рд░реНрдЯ рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯреНрд╕ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА: рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рддреИрдпрд╛рд░ рдХрд░рдиреЗ рд╕реЗ рд▓реЗрдХрд░ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рддрдХред

рдЕрдм рдЖрдк рдХрд┐рд╕реА рднреА рд╕реНрдорд╛рд░реНрдЯ рдЕрдиреБрдмрдВрдз рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

Source: https://habr.com/ru/post/hi432012/


All Articles