# 7-1. Connect Contract to Frontend

1. `src/klaytn`
   * caver.js
   * KlaystagramContract.js
2. `src/redux`

## 1) `src/klaytn` <a href="#id-1-src-klaytn" id="id-1-src-klaytn"></a>

`src/klaytn`: Contains files that help interact with Klaytn blockchain.

* `src/klaytn/caver.js`: Instantiates caver within configured setting.

  참고) caver-js는 Klaytn 노드와 연결하여 해당 노드나 Klaytn에 배포된 컨트랙트와의 상호작용을 지원해주는 RPC 라이브러리입니다.
* `src/klaytn/Klaystagram.js`: Creates an instance of contract using caver-js API. 이 인스턴스를 통해 컨트랙트와 상호작용할 수 있습니다

### `caver.js` <a href="#caver-js" id="caver-js"></a>

```javascript
/**
 * caver-js 라이브러리는 Klaytn 노드에 연결하게 해줍니다.
 * 'rpcURL' 값을 변경하여 특정 Klaytn 노드에 연결할 수 있습니다.
 * default rpcURL is 'https://public-en-baobab.klaytn.net'.
 */
import Caver from 'caver-js'

export const config = {
  rpcURL: 'https://public-en-baobab.klaytn.net'
}

export const cav = new Caver(config.rpcURL)

export default cav
```

연결 후 caver를 이용하여 스마트 컨트랙트의 메서드를 호출할 수 있습니다.

### `KlaystagramContract.js` <a href="#klaystagramcontract-js" id="klaystagramcontract-js"></a>

```javascript
// klaytn/KlaystagramContract.js

import { cav } from 'klaytn/caver'

/**
 * 1. 컨트랙트 인스턴스 생성
    * 예시: new cav.klay.Contract(DEPLOYED_ABI, DEPLOYED_ADDRESS)
    * 이 인스턴스를 통해 컨트랙트 메서드를 호출할 수 있습니다.
 */

const KlaystagramContract = DEPLOYED_ABI
  && DEPLOYED_ADDRESS
  && new cav.klay.Contract(DEPLOYED_ABI, DEPLOYED_ADDRESS)

export default KlaystagramContract
```

컨트랙트와 상호작용하려면 컨트랙트 인스턴스가 필요합니다.

`KlaystagramContract`는 `DEPLOYED_ABI`(Application Binary Interface)와 `DEPLOYED_ADDRESS`를 `cav.klay.Contract` API에 전달하여 배포된 Klaystagram 컨트랙트와 상호작용할 컨트랙트 인스턴스를 생성합니다.

`Klaystagram.sol` 컨트랙트를 컴파일 & 배포할 때([5. 컨트랙트 배포](https://archive-ko.docs.klaytn.foundation/content/dapp/tutorials/klaystagram/5.-deploy-contract)), `deployedABI`과 `deployedAddress` 파일을 이미 생성하였습니다. 이 파일들은 Klaystagram 컨트랙트의 ABI와 배포된 컨트랙트의 주소를 담고 있습니다.

웹팩 설정 덕분에 변수(`DEPLOYED_ADDRESS`, `DEPLOYED_ABI`)를 통해 이들 파일에 접근할 수 있습니다.

* `DEPLOYED_ADDRESS`는 배포된 컨트랙트의 주소를 반환합니다.
* `DEPLOYED_ABI`는 Klaystagram 컨트랙트의 ABI를 반환합니다.

**cf) `contract ABI`(Application Binary Interface)**\
`contract ABI` is the interface for calling contract methods. 이러한 인터페이스를 통해 아래와 같이 컨트랙트 메서드를 호출할 수 있습니다.

* `contractInstance.methods.methodName().call()`
* `contractInstance.methods.methodName().send({ ... })`

**Now we are ready to interact with contract in the application.**\
\&#xNAN;*cf. For more information, refer to* [*caver.klay.Contract*](https://archive-ko.docs.klaytn.foundation/content/dapp/sdk/caver-js/v1.4.1/api-references/caver.klay.contract)*.*

## 2) `src/redux` <a href="#id-2-src-redux" id="id-2-src-redux"></a>

Klaystagram 인스턴스로 API 함수를 만들 것입니다. API 함수를 호출한 후 리덕스 스토어를 사용하여 모든 데이터의 흐름을 제어합니다.

1. 컨트랙트 인스턴스를 임포트합니다.

   컴포넌트가 컨트랙트와 상호작용해야 할 때 `KlaystagramContract` 인스턴스를 사용하여 컨트랙트 메서드를 호출할 수 있습니다.
2. 컨트랙트 메서드를 호출합니다.
3. 컨트랙트에 데이터를 저장합니다.

   트랜잭션 실행이 성공하면 컨트랙트에서 리덕스 스토어로 정보를 저장하기 위해 리덕스 액션을 호출합니다.

```javascript
// src/redux/actions/photos.js

// 1. 컨트랙트 인스턴스를 임포트합니다.
import KlaystagramContract from 'klaytn/KlaystagramContract'

const setFeed = (feed) => ({
  type: SET_FEED,
  payload: { feed },
})

const updateFeed = (tokenId) => (dispatch, getState) => {

  // 2. Call contract method (CALL): getPhoto()
  KlaystagramContract.methods.getPhoto(tokenId).call()
    .then((newPhoto) => {
      const { photos: { feed } } = getState()
      const newFeed = [feedParser(newPhoto), ...feed]

      // 3. 컨트랙트에 데이터를 저장합니다.
      dispatch(setFeed(newFeed))
    })
}
```

리덕스 스토어는 프론트엔드에서의 모든 데이터의 흐름을 제어합니다.
