# 7-4. TransferOwnership Component

![transfer ownership](https://2361259531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fo8dCjygb765jszAbMUcT%2Fuploads%2Fgit-blob-da754a4dfcc2548bbc9846f0fa985b503c598561%2Fklaystagram-transferownership.png?alt=media\&token=cac37fc0-2282-4bfa-9506-978aba92fe87)

1. `TransferOwnership` component's role
2. Component code

   2-1. Rendering `transferOwnership` button

   2-2. `TransferOwnership` component
3. Interact with contract: `transferOwnership` method
4. Update data to store: `updateOwnerAddress` action

## 1) `TransferOwnership` component's role <a href="#id-1-transferownership-component-s-role" id="id-1-transferownership-component-s-role"></a>

The owner of photo can transfer photo's ownership to another user. By sending `transferOwnership` transaction, new owner's address will be saved in ownership history, which keep tracks of past owner addresses.

## 2) Component code <a href="#id-2-component-code" id="id-2-component-code"></a>

### 2-1) Rendering `TransferOwnership` button <a href="#id-2-1-rendering-transferownership-button" id="id-2-1-rendering-transferownership-button"></a>

We are going to render `TransferOwnership` button on the `FeedPhoto` component only when photo's owner address matches with logged-in user's address (which means you are the owner).

```javascript
// src/components/Feed.js

<div className="FeedPhoto">
  // ...
  {
    userAddress.toUpperCase() === currentOwner.toUpperCase() && (
      <TransferOwnershipButton
        className="FeedPhoto__transferOwnership"
        id={id}
        issueDate={issueDate}
        currentOwner={currentOwner}
      />
    )
  }
  // ...
</div>
```

### 2-2) `TransferOwnership` component <a href="#id-2-2-transferownership-component" id="id-2-2-transferownership-component"></a>

```javascript
// src/components/TransferOwnership.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import * as photoActions from 'redux/actions/photos'
import ui from 'utils/ui'
import { isValidAddress } from 'utils/crypto'
import Input from 'components/Input'
import Button from 'components/Button'

import './TransferOwnership.scss'

class TransferOwnership extends Component {
  state = {
    to: null,
    warningMessage: '',
  }

  handleInputChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    })
  }

  handleSubmit = (e) => {
    e.preventDefault()
    const { id, transferOwnership } = this.props
    const { to } = this.state

    if (!isValidAddress(to)) {
      return this.setState({
        warningMessage: '* Invalid wallet address',
      })
    }
    transferOwnership(id, to)
    ui.hideModal()
  }

  render() {
    const { id, issueDate, currentOwner } = this.props
    return (
      <div className="TransferOwnership">
        <h3 className="TransferOwnership__copyright">Copyright. {id}</h3>
        <p className="TransferOwnership__issueDate">Issue Date  {issueDate}</p>
        <form className="TransferOwnership__form" onSubmit={this.handleSubmit}>
          <Input
            className="TransferOwnership__from"
            name="from"
            label="Current Owner"
            value={currentOwner}
            readOnly
          />
          <Input
            className="TransferOwnership__to"
            name="to"
            label="New Owner"
            onChange={this.handleInputChange}
            placeholder="Transfer Ownership to..."
            err={this.state.warningMessage}
            required
          />
          <Button
            type="submit"
            title="Transfer Ownership"
          />
        </form>
      </div>
    )
  }
}

const mapDispatchToProps = (dispatch) => ({
  transferOwnership: (id, to) => dispatch(photoActions.transferOwnership(id, to)),
})

export default connect(null, mapDispatchToProps)(TransferOwnership)
```

## 3) Interact with contract: `transferOwnership` method <a href="#id-3-interact-with-contract-transferownership-method" id="id-3-interact-with-contract-transferownership-method"></a>

We already made `transferOwnership` function in Klaystagram contract at chapter [4. Write Klaystagram Smart Contract](https://archive-docs.klaytn.foundation/content/dapp/tutorials/klaystagram/4.-write-klaystagram-smart-contract). Let's call it from application.

1. Invoke the contract method: `transferOwnership`
   * `id:` Photo's tokenId
   * `to:` Address to transfer photo's ownership
2. Set transaction options
   * `from`: An account that sends this transaction and pays the transaction fee.
   * `gas`: The maximum amount of gas that the `from` account is willing to pay for this transaction.
3. After sending the transaction, show progress along the transaction lifecycle using `Toast` component.
4. If the transaction successfully gets into a block, call `updateOwnerAddress` function to update new owner's address into the feed page.

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

export const transferOwnership = (tokenId, to) => (dispatch) => {
  // 1. Invoke the contract method: transferOwnership
  try{
    KlaystagramContract.methods.transferOwnership(tokenId, to).send({
      
      // 2. Set transaction options
      from: getWallet().address,
      gas: '20000000',
    }, (error, txHash) => {
      if (error) throw error;

      // 3. After sending the transaction,
      // show progress along the transaction lifecycle using `Toast` component.
      ui.showToast({
        status: 'pending',
        message: `Sending a transaction... (transferOwnership)`,
        txHash,
      })
    })
      .then((receipt) => {
        ui.showToast({
          status: receipt.status ? 'success' : 'fail',
          message: `Received receipt! It means your transaction is
            in klaytn block (#${receipt.blockNumber}) (transferOwnership)`,
          link: receipt.transactionHash,
        })

        // 4. If the transaction successfully gets into a block,
        // call `updateOwnerAddress` function to update new owner's address into the feed page.
        dispatch(updateOwnerAddress(tokenId, to))
      })
  } catch (error) {
    ui.showToast({
      status: 'error',
      message: error.toString(),
    })
  }
}
```

## 4) Update information in redux store: `updateOwnerAddress` action <a href="#id-4-update-information-in-redux-store-updateowneraddress-action" id="id-4-update-information-in-redux-store-updateowneraddress-action"></a>

After transferring ownership, FeedPhoto needs to be rerendered with new owner's address.\
To update new owner's address, let's call `feed` data from store and find the photo that has the tokenId from the receipt. Then push new owner's address to photo's `ownerHistory` and setFeed.

```javascript
const updateOwnerAddress = (tokenId, to) => (dispatch, getState) => {
  const { photos: { feed } } = getState()
  const newFeed = feed.map((photo) => {
    if (photo['id'] !== tokenId) return photo
    photo['ownerHistory'] = [...photo['ownerHistory'], to]
    return photo
  })
  dispatch(setFeed(newFeed))
}
```
