# 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))
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://archive-docs.klaytn.foundation/content/dapp/tutorials/klaystagram/7.-feedpage/7-4.-transferownership-component.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
