memoryは処理中のみ保存し、storageは処理後、ブロックチェーンに保存される。
pragma solidity ^0.8.17;
contract Register {
struct Data {
string name;
uint256 age;
string hobby;
}
// 全ユーザのアドレスを保存
address[] public users;
mapping(address => Data) accounts;
function registerAccount(string memory _name, uint256 _age, string memory _hobby)
public
returns (bool)
{
if (!isUserExist(msg.sender)) {
users.push(msg.sender);
}
// msg.sender はトランザクション送信者
accounts[msg.sender].name = _name;
accounts[msg.sender].age = _age;
accounts[msg.sender].hobby = _hobby;
return true;
}
function isUserExist(address user) public view returns (bool) {
for (uint256 i = 0; i < users.length; i++) {
if (users[i] == user) {
return true;
}
}
return false;
}
function ViewAccount(address user) public view returns (string memory, uint256, string memory) {
string memory _name = accounts[user].name;
uint256 _age = accounts[user].age;
string memory _hobby = accounts[user].hobby;
return (_name, _age, _hobby);
}
}
remixでデプロイのテストができる

metamaskアカウントでsepoliaにdeployする
https://sepolia.etherscan.io/
フロントエンド
import React from "react";
import Resister from "./Register.json";
import getWeb3 from "./getWeb3";
// import "./App.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
web3: null,
accounts: null,
contract: null,
name: null,
age: null,
hobby: null,
address: "",
outputName: null,
outputAge: null,
outputHobby: null,
};
}
componentDidMount = async () => {
try {
const web3 = await getWeb3();
const accounts = await web3.eth.getAccounts();
const networkId = await web3.eth.net.getId();
const deployedNetwork = Resister.networks[networkId];
const instance = new web3.eth.Contract(
Resister.abi,
deployedNetwork && deployedNetwork.address
);
this.setState({ web3, accounts, contract: instance });
} catch (error) {
alert(
`Failed to load web3, accounts, or contract. Check console for details.`
);
console.error(error);
}
const { accounts } = this.state;
console.log(accounts);
};
// アカウント情報の登録
writeRecord = async () => {
const { accounts, contract, name, age, hobby } = this.state;
const result = await contract.methods.registerAccount(name, age, hobby).send({
from: accounts[0],
});
console.log(result);
if (result.status === true) {
alert('会員登録が完了しました。');
}
};
// アカウント情報の読み込み
viewRecord = async () => {
const { contract, accounts } = this.state;
console.log(contract);
const result = await contract.methods.viewAccount(accounts[0]).call();
console.log(result);
const outputName = result[0];
const outputAge = result[1];
const outputHobby = result[2];
this.setState({ outputName, outputAge, outputHobby });
};
handleChange = (name) => (event) => {
this.setState({ [name]: event.target.value });
};
render() {
return (
<div className="App">
<br />
<form>
<div>
<label>氏名:</label>
<input
onChange={this.handleChange("name")} />
</div>
<div>
<label>年齢:</label>
<input
onChange={this.handleChange("age")} />
</div>
<div>
<label>趣味:</label>
<input
onChange={this.handleChange("hobby")} />
</div>
<button type='button' onClick={this.writeRecord}>
会員登録
</button>
</form>
<br />
<br />
<form>
<label>検索したいアドレスを入力してください。</label>
<input onChange={this.handleChange("address")} />
<button type='button' onClick={this.viewRecord}>
検索
</button>
</form>
<br />
<br />
{this.state.outputName ? <p>氏名: {this.state.outputName}</p> : <p></p>}
{this.state.outputAge ? <p>年齢: {this.state.outputAge}</p> : <p></p>}
{this.state.outputHobby ? <p>趣味: {this.state.outputHobby}</p> : <p></p>}
</div>
);
}
}
export default App;
ちょっと記事が古いので期待通りに動かないが、