Klaytn Docs
Search…
7-4. TransferOwnership Component
transfer ownership
  1. 1.
    TransferOwnership component's role
  2. 2.
    Component code
    2-1. Rendering transferOwnership button
    2-2. TransferOwnership component
  3. 3.
    Interact with contract: transferOwnership method
  4. 4.
    Update data to store: updateOwnerAddress action

1) TransferOwnership component's role

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

2-1) Rendering TransferOwnership button

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).
1
// src/components/Feed.js
2
3
<div className="FeedPhoto">
4
// ...
5
{
6
userAddress === currentOwner && (
7
<TransferOwnershipButton
8
className="FeedPhoto__transferOwnership"
9
id={id}
10
issueDate={issueDate}
11
currentOwner={currentOwner}
12
/>
13
)
14
}
15
// ...
16
</div>
Copied!

2-2) TransferOwnership component

1
// src/components/TransferOwnership.js
2
3
import React, { Component } from 'react'
4
import { connect } from 'react-redux'
5
import * as photoActions from 'redux/actions/photos'
6
import ui from 'utils/ui'
7
import { isValidAddress } from 'utils/crypto'
8
import Input from 'components/Input'
9
import Button from 'components/Button'
10
11
import './TransferOwnership.scss'
12
13
class TransferOwnership extends Component {
14
state = {
15
to: null,
16
warningMessage: '',
17
}
18
19
handleInputChange = (e) => {
20
this.setState({
21
[e.target.name]: e.target.value,
22
})
23
}
24
25
handleSubmit = (e) => {
26
e.preventDefault()
27
const { id, transferOwnership } = this.props
28
const { to } = this.state
29
30
if (!isValidAddress(to)) {
31
return this.setState({
32
warningMessage: '* Invalid wallet address',
33
})
34
}
35
transferOwnership(id, to)
36
ui.hideModal()
37
}
38
39
render() {
40
const { id, issueDate, currentOwner } = this.props
41
return (
42
<div className="TransferOwnership">
43
<h3 className="TransferOwnership__copyright">Copyright. {id}</h3>
44
<p className="TransferOwnership__issueDate">Issue Date {issueDate}</p>
45
<form className="TransferOwnership__form" onSubmit={this.handleSubmit}>
46
<Input
47
className="TransferOwnership__from"
48
name="from"
49
label="Current Owner"
50
value={currentOwner}
51
readOnly
52
/>
53
<Input
54
className="TransferOwnership__to"
55
name="to"
56
label="New Owner"
57
onChange={this.handleInputChange}
58
placeholder="Transfer Ownership to..."
59
err={this.state.warningMessage}
60
required
61
/>
62
<Button
63
type="submit"
64
title="Transfer Ownership"
65
/>
66
</form>
67
</div>
68
)
69
}
70
}
71
72
const mapDispatchToProps = (dispatch) => ({
73
transferOwnership: (id, to) => dispatch(photoActions.transferOwnership(id, to)),
74
})
75
76
export default connect(null, mapDispatchToProps)(TransferOwnership)
Copied!

3) Interact with contract: transferOwnership method

We already made transferOwnership function in Klaystagram contract at chapter 4. Write Klaystagram Smart Contract. Let's call it from application.
  1. 1.
    Invoke the contract method: transferOwnership
    • id: Photo's tokenId
    • to: Address to transfer photo's ownership
  2. 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. 3.
    After sending the transaction, show progress along the transaction lifecycle using Toast component.
  4. 4.
    If the transaction successfully gets into a block, call updateOwnerAddress function to update new owner's address into the feed page.
1
// src/redux/actions/photo.js
2
3
export const transferOwnership = (tokenId, to) => (dispatch) => {
4
/**
5
* 1. Invoke the contract method: `transferOwnership`
6
* id: photo's token id
7
* to: new owner's address
8
*/
9
KlaystagramContract.methods.transferOwnership(tokenId, to).send({
10
// 2. Set transaction options
11
from: getWallet().address,
12
gas: '20000000',
13
})
14
.once('transactionHash', (txHash) => {
15
// 3. After sending the transaction,
16
// show progress along the transaction lifecycle using `Toast` component.
17
ui.showToast({
18
status: 'pending',
19
message: `Sending a transaction... (transferOwnership)`,
20
txHash,
21
})
22
})
23
.once('receipt', (receipt) => {
24
ui.showToast({
25
status: receipt.status ? 'success' : 'fail',
26
message: `Received receipt! It means your transaction is
27
in klaytn block (#${receipt.blockNumber}) (transferOwnership)`,
28
link: receipt.transactionHash,
29
})
30
31
// 4. If the transaction successfully gets into a block,
32
// call `updateOwnerAddress` function to update new owner's address into the feed page.
33
dispatch(updateOwnerAddress(tokenId, to))
34
})
35
.once('error', (error) => {
36
ui.showToast({
37
status: 'error',
38
message: error.toString(),
39
})
40
})
41
}
Copied!

4) Update information in redux store: updateOwnerAddress action

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 OWNER_HISTORY and setFeed.
1
const updateOwnerAddress = (tokenId, to) => (dispatch, getState) => {
2
const { photos: { feed } } = getState()
3
const newFeed = feed.map((photo) => {
4
if (photo[ID] !== tokenId) return photo
5
photo[OWNER_HISTORY].push(to)
6
return photo
7
})
8
dispatch(setFeed(newFeed))
9
}
Copied!