์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[1014] truffle ํŠธ๋Ÿฌํ”Œ ๋ฆฌ์•กํŠธ๋ฅผ ํ™œ์šฉํ•ด ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ transaction ๋งŒ๋“ค๊ธฐ - ์‚ฌ๊ณผ๋†์žฅ ๋งŒ๋“ค๊ธฐ

๋ฌธ์•ต 2021. 10. 14. 12:29

- 1๊ต์‹œ -

 

๐Ÿ”…  ์š”์ฒญ ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ

user - client - web3 - metamask - ๊ฐ€๋‚˜์‰ฌ

 

 

 

๐Ÿ”… ๋ฉ”ํƒ€๋งˆ์Šคํฌ๊ณผ ์—ฐ๊ฒฐํ•˜์—ฌ truffle ์—์„œ react ํ™œ์šฉํ•˜๊ธฐ (๊ธฐ๋ณธ ๊ตฌ์กฐ)

 

 

1. ํŠธ๋Ÿฌํ”Œ์—์„œ ๋ฆฌ์•กํŠธ ์ž‘์—…ํ™˜๊ฒฝ ์„ธํŒ…ํ•˜๊ธฐ

> truffle unbox react

ํŠธ๋Ÿฌํ”Œ์ด ๊น”๋ ค์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” 
> npm install -g truffle ๋จผ์ € ํ•ด์ฃผ๊ธฐ

 

๐Ÿ’š truffle ์—์„œ react ์ด์šฉํ•˜๊ธฐ

https://muna76.tistory.com/113

 

[1013] Truffle ํŠธ๋Ÿฌํ”Œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ ์ž‘์—…ํ•˜๊ธฐ - with. ganache & Meta mask & react

- 1๊ต์‹œ - ๐Ÿ”… ๋ฉ”ํƒ€๋งˆ์Šคํฌ๋ž€? - ๊ฐœ์ธ์˜ ๊ณ„์ •์˜ ์ฃผ์†Œ๊ฐ’์„ ์ €์žฅํ•ด์„œ ์ด๋”๋ฆฌ์›€๊ณผ ์ด๋”๋ฆฌ์›€ ํ† ํฐ์„ ์‰ฝ๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ. - ํ•ซ์›”๋ ›์ด๋ผ๊ณ ๋„ ํ•จ. - ์‹œ๋“œํ‚ค๋ผ๋Š”๊ฒƒ์ด ์กด์žฌํ•จ. (

muna76.tistory.com

 

 

2. ganache ์‹คํ–‰ ํ›„ metamask ์—ฐ๊ฒฐํ•˜๊ธฐ

 

ํด๋ผ์ด์–ธํŠธ์™€ metamask ์—ฐ๊ฒฐ ( web3์ด์šฉ ) -> truffle์ด ์•Œ์•„์„œ ํ•ด์คŒ

 

 

 


 

- 2๊ต์‹œ -

 

3. truffle-config.js ํŒŒ์ผ ์„ค์ •ํ•ด์ฃผ๊ธฐ

root ๋””๋ ‰ํ† ๋ฆฌ > truffle-config.js ํŒŒ์ผ ์ˆ˜์ •

 

network:{
	development:{
    	host:"127.0.0.1"
        port:7545,
        network_id:"*"
    },
    develop:{
    	port: 8545
    }
}

 

โ—โ—โ— ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์—ด์—ˆ๋˜ ์ฃผ์†Œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋‹ค๋ฅธ ๋ถ€๋ผ์šฐ์ €์—์„œ ์—ด๊ธฐ!!->

๊ทธ๋ƒฅ ๋ณต๋ถ™ํ•˜์ง€๋ง๊ณ  ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•  ๋•Œ ctrl + shift + v ํ•ด์ฃผ๋ฉด ๋จ โ—โ—โ—

 

 

 

4. ๋‚ด๊ฐ€ ๋ฐฐํฌํ•  contract ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

 

- ์—ฌ๊ธฐ์„œ ์›ํ•˜๋Š”๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋จ!

์ด ๋ถ€๋ถ„์€ ๋’ค์—์„œ 

์‚ฌ๊ณผ๋†์žฅ ๋งŒ๋“ค๊ธฐ๋กœ ์‹ค์Šตํ•ด๋ณผ๊ฒƒ์ž„!! - 

 

 

 

5. contract ์ฝ”๋“œ ์ปดํŒŒ์ผํ•˜๊ธฐ

> truffle compile

 

-root ๋””๋ ‰ํ† ๋ฆฌ > clinet > src > contracts ํด๋”๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Œ.

์ด ํŒŒ์ผ์„ ๋“ค์–ด๊ฐ€๋ณด๋ฉด json ์•ˆ์— abi์™€ byte ๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ์Œ!

 

web3๋กœ ์ปดํŒŒ์ผ ์ง„ํ–‰ํ–ˆ์„ ๋•Œ -> abi / bin ํด๋” ๋”ฐ๋กœ ์ƒ๊ฒผ์—ˆ์ง€๋งŒ 

truffle๋กœ ํ•˜๋‹ˆ -> abi/ bin ํด๋” ๋‚ด์šฉ์„ ํ•œ๋ฐ ํ•ฉ์ณ์ค€๊ฒƒ์ž„~

 

 

 

6. contract ๋‚ด์šฉ์„ ๋ฐฐํฌํ•˜๊ธฐ

> truffle migrate

ํ„ฐ๋ฏธ๋„ ๋ช…๋ น์–ด ์‹คํ–‰ ํ›„ (์ด๋•Œ gas ์†Œ๋ชจ ๋˜์—ˆ์„ ๊ฒƒ์ž„! ์ด๋”๊ฐ€ ๊นŽ์—ฌ์žˆ์œผ๋ฉด ์‹คํ–‰ ์ •์ƒ์ ์œผ๋กœ ๋˜์—ˆ๋‹ค๋Š”๊ฑธ ํ™•์ธ ๊ฐ€๋Šฅ!)

migrations ํด๋”์— ์ฝ”๋“œ ์ž‘์„ฑ

 

 

 

7. react ์‹คํ–‰ํ•˜๊ธฐ

> cd clinet && npm run start

 

 

 

>> ๋ฆฌ์•กํŠธ ์‹คํ–‰ ํ–ˆ์„ ๋•Œ ์ด๋Ÿฐ ํ™”๋ฉด์ด ๋‚˜์˜จ๋‹ค๋ฉด ์„ฑ๊ณต~~

 

 

โ—โ— ๋งŒ์•ฝ ์‹คํ–‰ํ–ˆ๋Š”๋ฐ ๊ณ„์† ๋กœ๋”ฉ๋งŒ ๋œจ๊ณ  ์ด๋Ÿฐ ํ™”๋ฉด์ด ์•ˆ๋‚˜์˜จ๋‹ค๋ฉด?

 

- ๋ฉ”ํƒ€๋งˆ์Šคํฌ์—์„œ ๊ฐ€๋‚˜์‰ฌ๋ฅผ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ๋Š” ๊ณ„์ •๊ณผ ํ˜„์žฌ ํด๋ผ์ด์–ธํŠธ ์ฃผ์†Œ์™€ ์—ฐ๊ฒฐ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณผ๊ฒƒ!

์—ฌ๊ธฐ์„œ >> ๊ฐ€๋‚˜์‰ฌ๋ฅผ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ๋Š” ๊ณ„์ • <<์ด๋ž€, ๋‚ด๊ฐ€ ๊ฐ€๋‚˜์‰ฌ์—์„œ ์ƒ์„ฑ๋œ ๊ฐœ์ธํ‚ค๋ฅผ ์ž…๋ ฅํ•œ ๊ณ„์ •์„ ๋งํ•จ.

 

 

 

์ด๋ ‡๊ฒŒ ๋œจ๋ฉด ์•ˆ๋˜๊ณ , 

๊ณ„์ • ๊ฐ€์ ธ์˜ค๊ธฐํ•ด์„œ

๋‚ด๊ฐ€ ๊ฐ€๋‚˜์‰ฌ์—์„œ ๊ฐœ์ธํ‚ค ๊ฐ€์ ธ์˜จ๊ฑฐ ์ž…๋ ฅํ•œ ๊ทธ ๊ณ„์ •!!

๊ทธ๊ฑฐ๋ž‘ localhost:3000์ด๋ž‘ ์—ฐ๊ฒฐ ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผํ•จ!!

 

 

 

 

 

์—ฐ๊ฒฐ์ด ์•ˆ๋˜์–ด์žˆ์œผ๋ฉด, ์ด๋ ‡๊ฒŒ

์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ ํ•ด์„œ

์—ฐ๊ฒฐ ์‹œ์ผœ์ค˜์•ผ ํ•จ~

 

 

 

- ๋‹น์—ฐํžˆ ์ฃผ์†Œ 7545๋„ ์ž…๋ ฅ๋˜์–ด์žˆ๋Š” ์ƒํƒœ์—ฌ์•ผ ํ•จ! (๊ฐ€๋‚˜์‰ฌ ์ฃผ์†Œ - ์ด๊ฑฐ๋ฅผ truffle-config.js์—๋„ ์„ธํŒ…ํ•ด์คฌ์—ˆ์Œ)

 

 

๐Ÿ”… App.js ํŒŒ์ผ ์ฝ”๋“œ ํŒŒํ—ค์น˜๊ธฐ

 

root ํด๋” - client - src - app.js

import SimpleStorageContract from "./contracts/SimpleStorage.json";

 

 

๐Ÿ”น ./contracts/SimpleStorage.json 

- ์ปดํŒŒ์ผ ์ง„ํ–‰ํ• ๋•Œ ์ƒ๊ฒผ๋˜ ํด๋”์ž„. ์—ฌ๊ธฐ์— abi / byte ๋‚ด์šฉ์ด ๋‹ด๊ฒจ์žˆ๋‹ค๊ณ  ํ–ˆ์Œ!

ํ•œ๋ฒˆ์˜ import๋กœ ๋‘๊ฐœ์˜ ๋‚ด์šฉ์„ ๋ชจ๋‘ ๊ฐ€์ ธ์™”๋‹ค๊ณ  ํ• ์ˆ˜์žˆ์ฐŒ.

 

๐Ÿ”น App component 

- ์ œ์ผ ๋จผ์ € ์‹œ์ž‘๋˜๋Š” ๋ถ€๋ถ„!

why? -> index.js ํŒŒ์ผ์„ ๋ณด์ž

ReactDOM.render(<App />, document.getElementById('root'));

App ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ทธ๋ฆฌ๊ฒ ๋‹ค๊ณ  ๋˜์–ด์žˆ์Œ์„ ํ™•์ธ ๊ฐ€๋Šฅ

 

- ํด๋ž˜์Šคํ˜•์œผ๋กœ ์„ ์–ธ๋˜์—ˆ์Œ

 

componentDidMount = async () => {
    try {
      // Get network provider and web3 instance.
      const web3 = await getWeb3();

      // Use web3 to get the user's accounts.
      const accounts = await web3.eth.getAccounts();
      const networkId = await web3.eth.net.getId();
.
.
.

- const web3 = await getweb3() : ๋ฉ”ํƒ€๋งˆ์Šคํฌ ์—ฐ๊ฒฐ์ž‘์—…. "getweb3()" ์š” ์•„์ด๋Š” getWeb3.js ํŒŒ์ผ์„ ๋œปํ•จ.

getWeb3.js์—์„œ๋Š” window.ehereum ์ด ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๊ณ  ์žˆ์œผ๋ฉด ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ์—ฐ๊ฒฐํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋˜์–ด ์žˆ์Œ!

 

- const accounts = await web3.eth.getAccounts() : getAccounts() ๊ฐ€ rpc ํ†ต์‹  ๋งค์†Œ๋“œ์ž„ ๊ณ„์ • ๊ฐ€์ ธ์˜ค๋ผ๋Š” ๋œป.

 

- const networkId = await web3.eth.net.getId() : ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ rpc ๋งค์†Œ๋“œ. ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ์ ‘์†ํ•  ๋•Œ ์ž…๋ ฅํ–ˆ๋˜ id๊ฐ’ ๊ฐ€์ ธ์˜ค๋ผ๋Š” ๋œป

 

	//SimpleStorageContract -> ์ €๊ธฐ ์‹ฌํ”Œ ์Šคํ† ๋ฆฌ์ง€ json ํŒŒ์ผ๋œปํ•จ. ๊ทธ์•ˆ์—์„œ networks๊ฐ์ฒด ๊ฐ€์ ธ์˜จ๊ฑฐ
      const deployedNetwork = SimpleStorageContract.networks[networkId];
     // networks๊ฐ์ฒด ์š”๊ธฐ์ž‰๋„ค
      //   {
      //     "events": {},
      //     "links": {},
      //     "address": "0x4E3B49bA55a2601e87C1e39742b411BA47fa1b90",
      //     "transactionHash": "0x148436ea5699ce83eb2dc11aa7433906"
      //   }
      
//์ด์ œ ์ปจํŠธ๋ž™ํŠธ ์•ˆ์— ์žˆ๋Š” ๋‚ด์šฉ์— ์ ‘์†ํ•˜๋ ค๊ณ ~
const instance = new web3.eth.Contract(
        SimpleStorageContract.abi, //abi๊ฐ’ ๊ฐ€์ ธ์˜ค๊ณ 
        deployedNetwork && deployedNetwork.address, 
        // address ๊ฐ’ -> ๋ฐฐํฌํ•œ ์ปจํŠธ๋ž™ํŠธ์— ๋“ค์–ด์žˆ๋Š” ์ฃผ์†Œ๊ฐ’ ๊ฐ€์ ธ์™€์„œ instance ์—๋‹ค๊ฐ€ ๋‹ด์•„!

 

 

 

 


- 3๊ต์‹œ -

 

๐Ÿ”… ์‚ฌ๊ณผ๋†์žฅ ๋งŒ๋“ค์–ด์–ด์–ด์–ด์–ด~!

 

 

 

๐Ÿ”น contract ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

 

 

1.  ๋””ํดํŠธ ํด๋”๋ฅผ ์ง€์›Œ์„œ ํ•„์š”์—†๋Š” ํด๋”๋Š” ๋‚ ๋ ค์ฃผ๊ธฐ

 

- (ํ˜„์žฌ ์‹ค์Šตํ•˜๋˜ ํด๋” ๊ธฐ์ค€์œผ๋กœ) contracts ํด๋”!

๊ธฐ๋ณธ ํ‹€ ๊ตฌ์กฐ๋ฅผ ์ตํžˆ๋Š๋ผ ์ปดํŒŒ์ผํ–ˆ์„๋•Œ ์ƒ๊ฒผ๋˜ ํŒŒ์ผ์„ ์ง€์›Œ์ค€๋‹ค! client > src > contracts > [  ]

- client > contracts > SimpleStorage.sol ๋””ํดํŠธ ํŒŒ์ผ์ด๋ฏ€๋กœ ์ง€์›Œ์ฃผ๊ธฐ

- ๋ฐฐํฌํ• ๋•Œ ์ƒ๊ฒผ๋˜ ํŒŒ์ผ๋„ ์ง€์›Œ์ฃผ์ž client > migrations > 2_deploy_contracts.js ์‚ญ์ œ

 

 

 

 

2. contract ํŒŒ์ผ๊ณผ migration ํŒŒ์ผ ๋งŒ๋“ค์–ด๋†“๊ณ  ์‹œ์ž‘ํ•˜๊ธฐ

 

- ์‚ฌ๊ณผ ๋†์žฅ์„ ๋งŒ๋“ค๊ฑฐ๋‹ˆ๊นŒ contract ํŒŒ์ผ๋ช…์„ fruitshop์œผ๋กœ ๋งŒ๋“ค์ž!

> truffle create contract Fruitshop
> truffle create migration fruitshop

- ์ดํ›„ ํŒŒ์ผ๋“ค์ด ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์ค€๋‹ค!

(contracts > Fruitshop.sol ์ด๋ž‘ migrations > 1633127453_fruitshop.js ์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒ๊ฒจ์•ผ๋Œ)

 

 

 

 

3. migrations ํด๋” ํŒŒ์ผ ๋ฏธ๋ฆฌ ์ž‘์„ฑํ•ด์ฃผ๊ธฐ

- ๋””ํดํŠธ๊ฐ’์œผ๋กœ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์—ˆ๊ธฐ๋•œ์— ๋ฐ”๊ฟ”์ค€๋‹น

- ๊ฑ initial ํŒŒ์ผ์— ์žˆ๋Š” ์–˜ ๋ณต๋ถ™ํ•ด์„œ ํŒŒ์ผ ์ด๋ฆ„๋งŒ ๋งž์ถฐ์„œ ์ž˜ ๋ฐ”๊ฟ”์ค˜์„œ ์‚ฌ์šฉ

- migrations > 2_fruitshop.js ์ฝ”๋“œ ์ˆ˜์ •

var Fruitshop = artifacts.require("./Migrations.sol");

module.exports = function(_deployer) {
  // Use deployer to state migration tasks.
  _deployer.deploy(Fruitshop);
};

 

 

 

 

4. solidity ์–ธ์–ด ์ž‘์„ฑํ•ด์ฃผ๊ธฐ

FruitShop.sol ์ž‘์„ฑ

๐Ÿ”น a. ๋ณด๋‚ธ ์‚ฌ๋žŒ์˜ ๊ณ„์ •์ด ์‚ฌ๊ณผ๋ฅผ ์ด ๋ช‡๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฐ€?

๐Ÿ”น b. ์‚ฌ๊ณผ ๊ตฌ๋งค์‹œ : ํ•ด๋‹น ๊ณ„์ •(์ฃผ์†Œ)์— ์‚ฌ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ์ฝ”๋“œ ์ž‘์„ฑ

๐Ÿ”น c. ์‚ฌ๊ณผ ํŒ๋งค์‹œ : "๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ x ์‚ฌ๊ณผ ๊ตฌ๋งค ๊ฐ€๊ฒฉ" ๋งŒํผ ํ† ํฐ์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ ,

                            ์‚ฌ๊ณผ๋ฅผ 0๊ฐœ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ธฐ

๐Ÿ”น d. ๋‚ด ์‚ฌ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜

 

a. ๋ณด๋‚ธ ์‚ฌ๋žŒ์˜ ๊ณ„์ •์ด ์‚ฌ๊ณผ๋ฅผ ์ด ๋ช‡๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฐ€?

Contract Fruitshop {
	mapping(address=>uint)myApple;
    constructor() public{
    }
}

- mapping ํ•จ์ˆ˜ ์ด์šฉ!

key : address , value : uint ์ธ myApple ํ•จ์ˆ˜ 

 

 

b. ์‚ฌ๊ณผ ๊ตฌ๋งค์‹œ : ํ•ด๋‹น ๊ณ„์ •(์ฃผ์†Œ)์— ์‚ฌ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ์ฝ”๋“œ ์ž‘์„ฑ

function buyApple() payable public{
	myApple[msg.sender]++;
}
//ํ† ํฐ ๊ฑฐ๋ž˜๊ฐ€ ์ด๋ฃจ์–ด์ง€๋ฏ€๋กœ payable ์ถ”๊ฐ€

 

 

c-1. ์‚ฌ๊ณผ ํŒ๋งค์‹œ : "๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ x ์‚ฌ๊ณผ ๊ตฌ๋งค ๊ฐ€๊ฒฉ" ๋งŒํผ ํ† ํฐ์„ ๋ฐ˜ํ™˜

 

- ์ผ๋‹จ ์‚ฌ๊ณผ ํŒ๋งค์‹œ , ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ๋ฅผ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜!

function sellApple(uint _applePrice) public {
	uint totalPrice = (myApple[msg.sender]* _applePrice); 
          //์ด ๊ฐ€๊ฒฉ   =  ์‚ฌ๊ณผ ํŒ์‚ฌ๋žŒ์˜ ์‚ฌ๊ณผ๊ฐฏ์ˆ˜ x ์‚ฌ๊ณผ ๊ฐ€๊ฒฉ
}

 

- ์‚ฌ๊ณผ๋ฅผ ํŒ”์•˜์œผ๋‹ˆ๊น ๋‚ด ์‚ฌ๊ณผ์˜ ๊ฐฏ์ˆ˜๋ฅผ 0๊ฐœ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•จ!

function sellApple (uint _applePrice) public {
	uint totalPrice = (myApple[msg.sender] * _applePrice);
    myApple[msg.sender] = 0; // ํŒ๋งค์ž์˜ ์‚ฌ๊ณผ 0๊ฐœ๋กœ ๋ฐ”๊ฟ”
}

 

-  ํŒ๋งค์ž์˜ ์ฃผ์†Œ์—๋‹ค๊ฐ€ ์‚ฌ๊ณผ ๊ฐ€๊ฒฉ๋งŒํผ ํ† ํฐ ์ „๋‹ฌํ•˜๊ธฐ 

function sellApple (uint _applePrice) payable public {
	uint totalPrice = (myApple[msg.sender] * _applePrice);
    myApple[msg.sender] = 0;
    msg.sender.transfer(totalPrice); // ๋ณด๋‚ธ์‚ฌ๋žŒ์˜ ์ฃผ์†Œ์— ์ด ๊ฐ€๊ฒฉ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค
}

* payable : ์ด ํ•จ์ˆ˜์—์„œ๋Š” ํ† ํฐ์˜ ๊ฑฐ๋ž˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป

transfer ๋ถ€๋ถ„์ด ์™œ ํ™˜๋ถˆ์ด๋ผ๋Š”๊ฑฐ์ง€..? ํŒ๋งค์ž๊ฐ€ ์‚ฌ๊ณผ ํŒ ๊ธˆ์•ก๋งŒํผ ๋ˆ ๋ฐ›๋Š”๋‹ค๋Š” ๋œป ์•„๋‹Œ๊ฐ€

 

โ—โ— ์œ„ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ๋นจ๊ฐ„์ค„์ด ๋œจ๋Š”๋ฐ, ์ด ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ์ฝ”๋“œ๋ฅผ ๊ณ ์น˜๋ฉด , ์ปดํŒŒ์ผํ•˜๋Š” ๊ณผ์ •์—์„œ ๋˜ ์˜ค๋ฅ˜๊ฐ€ ๋‚  ๊ฒƒ์ž„. ๋นจ๊ฐ„์ค„์ด ๋– ๋„ ๊ทธ๋ƒฅ ๊ทธ๋Œ€๋กœ ๋ƒ…๋‘ฌ์•ผ ํ•จ.

why ? -> ์šฐ๋ฆฌ๊ฐ€ ํ™”๋ฉด์œผ๋กœ ๋ณด๋Š”, ์ฆ‰ vs๊ฐ€ ์†”๋ฆฌ๋””ํ‹ฐ ์–ธ์–ด๋ฅผ ํ•ด์„ํ•ด์ฃผ๋Š” ๋ฒ„์ „์€ 8๋ฒ„์ „์ธ๋ฐ, ํŠธ๋Ÿฌํ”Œ์—์„œ ์ปดํŒŒ์ผํ• ๋•Œ ์†”๋ฆฌ๋””ํ‹ฐ ์–ธ์–ด๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฒ„์ „์€ 5๋ฒ„์ „์ž„. 

truffle version 
solcjs 0.5.16


solcjs --version
solcjs 0.8.9
-------------------------

ํ•ด์„๋˜๋Š” ์†”๋ฆฌ๋””ํ‹ฐ ์–ธ์–ด ๋ฒ„์ „์ด ๋‹ค๋ฆ„!

 

 

 

d. ๋‚ด ์‚ฌ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜

function getMyApple() public view returns(uint){
	return myApple[msg.sender];
}

 

------- ์—ฌ๊ธฐ๊นŒ์ง€ solidity ์ฝ”๋“œ ์ž‘์„ฑ ๋! ์ด์ œ ์ด๊ฑธ ๋ฆฌ์•กํŠธ๋กœ ๊ตฌ๋™ํ•ด๋ด…๋‹ˆ๋‹ค!

 

( ์ปดํŒŒ์ผ๊ณผ ๋ฐฐํฌ ํ•„์ˆ˜ - 

> truffle compile ์ดํ›„ contracts ํด๋”์— ํŒŒ์ผ ์ƒ๊ฒผ๋Š”์ง€ ํ™•์ธ

> truffle migrate  ๊ฐ€์Šค ๋น ์ง„๊ฑฐ ํ™•์ธ )

 

๐Ÿ”… solidity๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ๋ฆฌ์•กํŠธ๋กœ ๊ตฌ๋™์‹œ์ผœ๋ณด๊ธฐ

 

1. ๋ฆฌ์•กํŠธ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— app.js ํŒŒ์ผ ๋‹ค ์ˆ˜์ •ํ•ด์•ผ ํ•จ!

import SimpleStorageContract from "./contracts/SimpleStorage.json" ๋ถ€๋ถ„ ๋ฐ”๊ฟ”์ฃผ๊ณ 

App ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ „๋ถ€ ์ง€์šฐ๊ณ  ์ƒˆ๋กœ ์ž‘์„ฑ.

 

import React, { Component } from "react";
import FruitshopContract from "./contracts/Fruitshop.json";
import getWeb3 from "./getWeb3";

import "./App.css";



export default App;

(์ง€์šด ์ƒํƒœ. ์—ฌ๊ธฐ๋‹ค๊ฐ€ ์ฝ”๋“œ ์ถ”๊ฐ€)

 

 

2. ์ผ๋‹จ ๊ทธ๋ ค์ง€๋Š” ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ๋“ค

import React, { Component } from "react";
import FruitshopContract from "./contracts/Fruitshop.json";
import getWeb3 from "./getWeb3";

import "./App.css";

const App = ()=>{
	return (
    	<div>
        <h1>์‚ฌ๊ณผ ๊ฐ€๊ฒฉ : 10 ETH </h1>
            <button> Buy </button>
            <p> ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ : 0 </p>
            <button> Sell (ํŒ๋งค ๊ฐ€๊ฒฉ์€ {0 * 10}ETH) </button>
        </div>
    )
}

export default App;

(์ž‘์„ฑ ํ›„ npm run start ํ•ด์„œ ํ™”๋ฉด ํ™•์ธํ•˜๊ธฐ)

 

 

 

3- a. ์ƒํƒœ๋ฅผ ์ €์žฅ ํ•˜๊ธฐ

import React, { Component, useState } from "react";
import FruitshopContract from "./contracts/Fruitshop.json";
import getWeb3 from "./getWeb3";

import "./App.css";

const App = ()=>{
    const [myApple, setMyApple] = useState(0);
	return (
    	<div>
        <h1>์‚ฌ๊ณผ ๊ฐ€๊ฒฉ : 10 ETH </h1>
            <button> Buy </button>
            <p> ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ : {myApple} </p>
            <button> Sell (ํŒ๋งค ๊ฐ€๊ฒฉ์€ {myApple * 10}ETH) </button>
        </div>
    )
}

export default App;

 

 

3-b. onClick ํ•จ์ˆ˜ ์ง€์ •

import React, { Component, useState } from "react";
import FruitshopContract from "./contracts/Fruitshop.json";
import getWeb3 from "./getWeb3";

import "./App.css";

const App = ()=>{
    const [myApple, setMyApple] = useState(0);
    
    const buyApple = ()=>{
    // buy๋‹ˆ๊นŒ ์‚ฌ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋จ
    	setMyApple(prev=>prev+1); // ํ˜น์€ setMyApple(myApple+1);๋„ ๊ฐ€๋Šฅ. ํ‘œํ˜„ ๋ฐฉ์‹ ์ฐจ์ด
    }
    
    const sellApple = ()=>{
    	// ๊ฐ€์ง„๊ฑฐ ์ „๋ถ€ 0์œผ๋กœ ๋งŒ๋“ค๊ธฐ
        setMyApple(0);
    }
	return (
    	<div>
        <h1>์‚ฌ๊ณผ ๊ฐ€๊ฒฉ : 10 ETH </h1>
            <button onClick={()=>buyApple()}> Buy </button>
            <p> ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ : {myApple} </p>
            <button onClick={()=>sellApple()}> Sell (ํŒ๋งค ๊ฐ€๊ฒฉ์€ {myApple * 10}ETH) </button>
        </div>
    )
}

export default App;

 

 

 

์šฐ์™• ๋‚˜ ๋ฐฑ๋ฒˆ ๋ˆ„๋ฆ„

 

 

 

 

 

๊ทธ๋Ÿฌ๋ฉด ์š”๋Ÿฐ ์‹์œผ๋กœ ํ™”๋ฉด์ด ๋œน๋‹ˆ๋ ์•„์•„

 

 

 

 

 

 

4. useEffect ์„ ์–ธํ•˜๊ธฐ : componentDidMount WEB3 ๊ฐ€์ ธ์™€์„œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ ์—ฐ๊ฒฐํ•˜๊ธฐ

 

import getWeb3 from "./getWeb3";
...

const getweb = async ()=>{ //web3 ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ
	let web3 = await getWeb3()
    console.log(web3); // ์‹คํ–‰์ด ์ž˜ ๋˜์—ˆ๋‹ค๋ฉด ์ฝ˜์†”์— ์—ฌ๋Ÿฌ ๊ฐ์ฒด๊ฐ€ ์ฐํž๊ฒƒ์ด์•ผ
}

useEffect(()=>{
	getweb(); // ์Ÿค๋ฅผ ์—ฌ๊ธฐ์„œ ํ˜ธ์ถœ! web3 ๊ฐ€์ ธ์™“
},[])

 

 

 


 

 

 

- 4๊ต์‹œ -

 

@truffle/contract 

> npm install @truffle/contract

* ์ฃผ์˜- ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ client ์•ˆ์— ๋“ค์–ด๊ฐ€์žˆ๋Š”๊ฑฐ ํ™•์ธํ•˜๊ณ  ์„ค์น˜ ํ•ด์•ผ ํ•จ *

์ฝ”๋“œ๋ฅผ ์ข€ ๋” ๊ฐ„์†Œํ™” & ๊น”๋”ํ•˜๊ฒŒ ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•จ. 

 

์–˜๋ฅผ ์™œ ์“ฐ๋Š”๊ฑด์ง€ ์•„์ง ํ™•์‹คํžˆ ์ดํ•ด๋Š” ๋ชปํ•˜๊ฒ ์Œ... ์‚ฌ์šฉ๋ฒ•์€ ํ™ˆํŽ˜์ด์ง€์— ์ž˜ ๋‚˜์™€์žˆ์Œ

https://www.npmjs.com/package/@truffle/contract

 

@truffle/contract

A better contract abstraction for Ethereum (formerly EtherPudding)

www.npmjs.com

 

 

5-a. @truffle/contract ๊ฐ€์ ธ์˜ค๊ธฐ

const contract = require('@truffle/contract');

์ด๋ ‡๊ฒŒ contract๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋˜๋ฉด web3 ์•ˆ์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ข€ ๋” ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•ด์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค..? 

=> ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง„๋‹ค

 

const getweb = async()=>{
	let web3 = await getWeb3()
	let fruitsop = contract(FruitshopContract) // ์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ ์จ์ฃผ๋ฉด 
    fruitshop.setProvider(web3.currentProvider) // ๋ฐ”๋กœ ๊ฐ€์ ธ์™€์„œ ์“ธ ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฒƒ ๊ฐ™์€๋ฐ...
    
    let instance = await fruitshop.deployed()
    
    console.log(instance)
}

 

๊ณผ์—ฐ instance ๊ฐ’์ด console์— ์ฐํžˆ๋Š”์ง€ 

๋ฆฌ์•กํŠธ๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณธ๋‹ค!

 

5-b. WEB3 ๋ฅผ ํ†ตํ•ด์„œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ ์ฃผ์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ

const getweb = async()=>{
	let web3 = await getWeb3()
	let fruitsop = contract(FruitshopContract) // ์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ ์จ์ฃผ๋ฉด 
    fruitshop.setProvider(web3.currentProvider) // ๋ฐ”๋กœ ๊ฐ€์ ธ์™€์„œ ์“ธ ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฒƒ ๊ฐ™์€๋ฐ...
    
    let instance = await fruitshop.deployed()
    //๊ณ„์ • ๊ฐ€์ ธ์˜ค๊ธฐ
    let accounts = await web3.eth.getAccounts()
    console.log(instance)
    console.log(accounts)  // ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ์žˆ๋Š” ์ฃผ์†Œ๋ž‘ ๊ฐ™์€์ง€ ๋น„๊ตํ•ด๋ณด๊ธฐ
}

์ฝ˜์†”์— ์ฐ์€ accounts ์™€ ์‹ค์ œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ ๊ณ„์ • ์ฃผ์†Œ์™€ ๊ฐ™์€์ง€ ๋น„๊ตํ•ด๋ณด๊ธฐ

1 -> ์ฝ˜์†”์— ์ฐ์€ accounts 

2 -> ์‹ค์ œ ๋ฉ”ํƒ€๋งˆ์Šคํฌ์— ๋“ค์–ด๊ฐ€์žˆ๋Š” ์ฃผ์†Œ (๊ฐœ์ธํ‚ค). ์ด๊ฑฐ๋Š” ์ €๊ธฐ ๊ณ„์ •๋ช… ๋ˆ„๋ฅด๋ฉด ๋ณต์‚ฌ ๋จ

 

๋น„๊ตํ•ด์„œ ๊ฐ™์œผ๋ฉด ์ž˜ ๊ฐ€์ ธ์˜จ๊ฒƒ~

 

instance / accounts ์–ด๋””์„œ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

buyApple/ sellApple ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. 

 

๊ทผ๋ฐ ์ด instance๋Š” ์ง€์—ญ๋ณ€์ˆ˜๋กœ, ํ•ด๋‹น ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์ด์šฉ ๊ฐ€๋Šฅํ•จ. 

์–ด๋–ป๊ฒŒ instance๋ฅผ buyApple/ sellApple ํ•จ์ˆ˜์—์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ?

 

6. instance ์ƒํƒœ๋กœ ์ €์žฅํ•˜๊ธฐ

์ƒํƒœ๋Š” ๊ฐ์ฒด๋ฅผ ์ €์žฅ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€? 

=> ์ €์žฅ ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ useState๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ณต์žกํ•ด์ง.

์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด useReducer๋กœ ์ €์žฅํ•ด์„œ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ๊ฒƒ์ž„~!

 

a. instance 

b. accounts 

c. web3 (์–˜๋Š” util์ด๋ผ๋Š” ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ž„)

์ด๋ ‡๊ฒŒ ์„ธ๊ฐ€์ง€๋ฅผ reducer์— ๋‹ด์•„์„œ ์‚ฌ์šฉํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Œ!

 

 

๐Ÿ”น instance / accounts / web3 -> reducer๋กœ ์ƒํƒœ์— ์ €์žฅํ•˜๊ธฐ

 

import React, { Component, useEffect , useReducer } from "react";

const App= ()=>{
	let initialState = { web3:null , instance:null , account:null }
	const [state,dispatch] = useReducer(reducer,initialState)
    
    function reducer(state,action){
    switch(action.type){
    	case "INIT":
        	let {web3,instance,account} = action //๋น„๊ตฌ์กฐํ• ๋‹น๋ฌธ
        	return{
            	...state, //ํ˜„์žฌ ์ƒํƒœ๊ฐ’ ๋ณต์‚ฌ
                web3,
                instance, // instance:action.instance ์ด๊ฑธ ์ค„์—ฌ์„œ ์”€
                account // ๊ทผ๋ฐ ๋น„๊ตฌ์กฐํ• ๋‹น๋ฌธ ์จ์„œ ์–ด๋–ป๊ฒŒ ์ด๋ ‡๊ฒŒ ์ค„์–ด๋“œ๋Š”๊ฑด์ง€ ๋ชจ๋ฅด๊ฒ ...
            }
    	}
    }
    
    let InitActions = {
    	type:"INIT",
        web3,
        instance,
        account:account[0] //์–˜๋Š” ๋ฐฐ์—ด๋กœ ๋‹ด๊ฒจ์žˆ์–ด์„œ ์–˜๋งŒ ๋ฐ”๊ฟ”์ฃผ๊ธฐ
    }
    dispatch (InitActions)
    
    //๋‚ด์šฉ์„ ๋ณด๋‚ผ ๋•Œ
    //dispatch({type:"INIT"}) //action.type์ด 'INIT'์ธ ์ผ€์ด์Šค์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์ค˜๋ž‘
    //๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ๋ณต์žกํ•ด์ง„๋‹ค๊ณ  ์œ„์—์ฒ˜๋Ÿผ let InitialActions ๋งŒ๋“ค์–ด์„œ ์ฝ”๋“œ ๋ฐ”๊พธ์‹ฌ.
    // ์ด๊ฒŒ ๋” ๋ณต์žกํ•˜์ง€ ์•Š๋‚˜์—ฌ..??
    
    

}

์•”ํŠผ ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด 

instance / account / web3 ๋ฅผ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด ์ค€ ๊ฒƒ์ž„!

 

 

 

 


 

 

- 5๊ต์‹œ -

 

๐Ÿ”น (์ด์–ด์„œ) instance / account / web3๊ฐ€ ์ƒํƒœ์— ์ €์žฅ์ด ์ž˜ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

 

react devtool - component ํ™•์ธ

 

 

์•„๋‹ˆ ๊ทผ๋ฐ accounts๊ฐ€ undefined๊ฐ€ ๋œจ๋ฉด ์•ˆ๋˜๋Š”๋ฐ ์™œ ์–ธ๋””๊ฐ€ ๋œจ์ง€

-> ์˜คํƒ€์˜€์Œ... account ๊ฐ’์„ ์„ ์–ธํ•ด์ค„๋•Œ accounts ๋ผ๊ณ  ํ•ด์„œ ์ž˜๋ชป ๋œ ๊ฒƒ์ž„..

๋‹ค์‹œ ์ œ๋Œ€๋กœ ์ž˜ ๋œธ

 

 

=> ์ด์ œ instance / account / web3 ๋ฅผ buyApple / sellApple ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋”ฐ!

 

๐Ÿ”น ์‚ฌ์šฉํ•˜๊ธฐ

const buyApple = async()=>{
	let {instance,account} = state; //๋น„๊ตฌ์กฐ ํ• ๋‹น๋ฌธ์ด์—ฌ
        await instance.buyApple({
    	from : account, //๋‚ด๊ฐ€ ์–˜ํ•œํ…Œ ๋ณด๋‚ผ๊ฑด๋ฐ
        value:1000000000000000000, //๋‹จ์œ„๊ฐ€ wei // ์ด๋งŒํผ์„ ๋ณด๋‚ผ๊ฑฐ์•ผ
        gas:90000, //๊ฐ€์Šค๋Š” ์ด๋งŒํผ์œผ๋กœ ํ• ๊ฑฐ์•ผ
    }) //์–˜๋Š” ๊ทธ๋ƒฅ ์™ธ์›Œ์•ผ ํ•˜๋Š” ๊ตฌ๋ฌธ์ด๋ผ๊ณ  ํ•จ.. ๊ด„ํ˜ธ ์•ˆ์— ๊ฐ์ฒด๋กœ ๋‹ด๋Š”๊ฑฐ
    setMyApple(prev=>prev+1);
}

 

> npm run start 

 

ํ™”๋ฉด์—์„œ ์ด๋”๋ฆฌ์›€์œผ๋กœ ์‚ฌ๊ณผ ์‚ฌ๋Š”๊ฒƒ์ž„..

 

 

๋‚ด๊ฐ€ ์ด๋”๋ฅผ ์ฃผ๊ณ  ์‚ฌ๊ณผ๋ฅผ ์ƒ€๋Š”๋ฐ

 

๊ทธ ์ƒํƒœ์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ์‚ฌ๊ณผ๊ฐ€ ์‚ฌ๋ผ์ง.

์ด๋ถ€๋ถ„์„ ๊ณ ์ณ์ฃผ๊ธฐ ์œ„ํ•ด 

 

7. ํ˜„์žฌ ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ๊ณผ๋ฅผ return ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

 

const getApple = async(instance)=>{ //์ธ์ž๊ฐ’์œผ๋กœ ๋ฐ›์•„์ค˜์•ผ instance ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    if(instance == null) return
    let {instance} = state;
    let result = await instance.getMyApple();
    //์ƒํƒœ๋ฅผ ๋ฐ”๊ฟ€๊ฒƒ์ด์•ผ ๋ญ˜๋กœ? ๋ธ”๋ก์ฒด์ธ์—์„œ ๋ฐ›์•„์˜จ ํ˜„์žฌ ๋‚ด ์‚ฌ๊ณผ๋ฅผ ๋ฐ›์•„์˜จ ๊ฒฐ๊ณผ๊ฐ’์œผ๋กœ
    setApple(result.toNumber())//๋ฐ›์•„์˜ฌ ๋•Œ string ๊ฐ’์ด๋ฏ€๋กœ int๋กœ ๋ฐ”๊ฟ”์ฃผ๊ธฐ
}

 

// ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ getweb ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ˜ธ์ถœํ•ด์ฃผ๊ธฐ (getweb์€ useEffect์—์„œ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ)

const getweb = ()=>{

...
getApple(instance) // ์ธ์ž๊ฐ’์œผ๋กœ ๋„˜๊ฒจ์ค˜์•ผ instance๊ฐ’์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Œ
}

 

 

 

 

 

 

โ•โ• web3.utils ์‚ฌ์šฉํ•˜๊ธฐ

const buyApple = async()=>{
	let {instance,account, web3} = state; //๋น„๊ตฌ์กฐ ํ• ๋‹น๋ฌธ์ด์—ฌ
        await instance.buyApple({
    	from : account,
        value: web3.utils.toWei("10","ether"), 
        // ์ธ์ž๊ฐ’์œผ๋กœ "์ˆซ์ž" , "๋‹จ์œ„" ๋ฐ›์•„์„œ -> ํ•ด๋‹น ์ˆซ์ž์˜ ํ•ด๋‹น ๋‹จ์œ„๋งŒํผ์„ wei ๋‹จ์œ„๋กœ ๋ณ€ํ™˜ํ•ด์คŒ 
        // ๊ธ๊นŒ 10ether๊ฐ€ ๋ช‡ wei์•ผ? ํ•˜๋Š” ๋งค์†Œ๋“œ๋ผ๊ณ  ํ• ์ˆ˜์žˆ์Œ
        gas:90000,
    })
    setMyApple(prev=>prev+1);
}

 

 

 

8. ์‚ฌ๊ณผ๋ฅผ ํŒŒ๋Š” ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

const sellApple = async()=>{
	let { instance,account,web3 }=state
    //์ปจํŠธ๋ž™ํŠธ์—์„œ sellApple์€ ์ธ์ž๊ฐ’์œผ๋กœ ๊ฐ€๊ฒฉ์„ ๋ฐ›์•„์คฌ์—ˆ์œผ๋‹ˆ๊นŒ ์—ฌ๊ธฐ๋„ ์ธ์ž๋ฅผ ๋„ฃ์–ด์คŒ
    await instance.sellApple(web3.utils.toWei("10","ether"),{//์ธ์ž๋กœ ๋ณด๋‚ผ ํ† ํฐ์„ ๋„ฃ์–ด์ค€๊ฒƒ.๋‹จ์œ„wei
    	from:account,
        gas:90000,
    }) // buyApple ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์“ฐ๋Š” ๋ฌธ๋ฒ• ์™ธ์šฐ๊ธฐ!
    setApple(0)
}

 

 

 

 

๋ฐ˜์‘ํ˜•