我还是很新的反应和坚定,不知道从哪里开始。我可以更新一个字符串,并希望在更改它之后打印出来。但我想要发条链上的绳子。返回值仍然是“未定义的”。
我的index.ts文件:
export function MyString(contract: Contract) {
const { state, send } = useContractFunction(contract, "setString", {});
return { state, send };
}
export function GetMyString(contract: Contract) {
const { value, error } = useCall({
contract: contract,
method: 'getString',
args: []
}) ?? {};
if (error) {
console.log("Error: ", error.message);
return undefined;
}
console.log("value", value);
return value;
}我的反应成分:
import React, { useState } from 'react';
import { useEthers } from "@usedapp/core";
import { ethers } from "ethers";
import myStringContractAbi from "./abi/myString.json";
import { myStringContractAddress } from "./contracts";
import { Contract } from "@ethersproject/contracts";
import { MyString, GetMyString } from "./hooks"
function App() {
const { activateBrowserWallet, account, deactivate } = useEthers();
const simpleContractInterface = new ethers.utils.Interface(myStringContractAbi);
const contract = new Contract(myStringContractAddress, simpleContractInterface, ethers.getDefaultProvider(42));
const { send, state } = MyString(contract);
const value = GetMyString(contract);
const [text, setText] = useState<string>("")
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newText = event.target.value === "" ? "" : String(event.target.value)
setText(newText)
}
const sendString = async () => {
send(text);
}
const getContractString = async () => {
console.log("APP VALUE", value);
alert(value);
}
React.useEffect(() => {
state.status === 'Exception' && console.log('State of set String: ', state.errorMessage);
state.status === 'Success' && console.log('Set String successfully!');
})
return (
<div>
{!account && <button onClick={() => activateBrowserWallet()}> Connect </button>}
{account && (
<div>
<button onClick={deactivate}>Disconnect</button>
</div>
)}
<div>
{account ? (
<div>My Account Address: {account} </div>
) : (
<div>Kein Account verbunden!</div>
)}
</div>
<input onChange={handleChange} />
<button onClick={sendString}>Call Function</button>
<button onClick={getContractString}>Call Get String Function</button>
</div>
);
}
export default App;这是我的合同:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyString {
string public myString;
constructor() {
myString = "Not set yet";
}
function setString(string memory _myString) public {
myString = _myString;
}
function getString() public view returns (string memory) {
return myString;
}
}有人能帮我吗?你还需要其他信息吗?谢谢
发布于 2022-05-14 10:03:32
如果您想获得任何值,则不能使用useContractFunction。不要使用useCall,也不要使用ethers库。
示例useCall
import { useCall } from '@usedapp/core';
import { Contract } from '@ethersproject/contracts'; // comes with `@usedapp/core`
import {utils} from 'ethers';
const CONTRACT_ADDR = "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853";
const Interface = new utils.Interface(ABI); // ABI is array
const ContractInstance = new Contract(CONTRACT_ADDR, Interface);
// Custom contract payable function
const useTokenBalance = () => {
const { value, error } = useCall({
contract: ContractInstance,
method: 'TokenBalance',
args: [] /* params */
});
if(error) {
return undefined
}
console.log("value", value);
return value;
};
function App() {
//...
const TokenBalance = useTokenBalance();
const getTokenBalance = async () => {
alert(TokenBalance);
}
}API文档:https://usedapp-docs.netlify.app/docs/api%20reference/hooks/#usecall
如何在ethers钩子框架中使用useDApp库;
import { useEthers } from '@usedapp/core';
import { Contract as CTR } from 'ethers';
const CONTRACT_ADDR = "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853";
function App() {
//...
const { account, library } = useEthers();
const getTokenBalance = async () => {
const signer = library.getSigner();
const ctr = new CTR(CONTRACT_ADDR, ABI, signer);
let tx = await ctr.TokenBalance(/* params */);
alet(tx);
}
}API文档:https://docs.ethers.io/v5/api/contract/contract/#Contract--creating
测试版本;
^5.6.5 ethers^1.0.2 @usedapp/core更新
完整的源代码;
import './App.css';
import { useEthers, useContractFunction, useCall } from '@usedapp/core';
import {useState, useEffect, useCallback } from 'react';
import {utils, constants, BigNumber, Contract as CTR} from 'ethers';
import { Contract } from '@ethersproject/contracts'
const ENDPOINT = "http://127.0.0.1:4000";
const CONTRACT_ADDR = "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9";
const ABI = require('./Post.json').abi;
const Interface = new utils.Interface(ABI);
const Instance = new Contract(CONTRACT_ADDR, Interface);
const useAddMessage = () => {
const { state, send, event } = useContractFunction(
Instance,
'addMessage',
{}
);
return { state, send, event };
};
function App() {
const { state: addMessageState, send: addMessage } = useAddMessage();
const { activateBrowserWallet, account, library, chainId } = useEthers();
const [ownerBalance, set_ownerBalance] = useState(0);
const [contractInstance, set_contractInstance] = useState(null);
const [msg, setMsg] = useState("");
const [chainMsgs, setChainMsgs] = useState([]);
// Error watching
useEffect(() => {
addMessageState.status === 'Exception' &&
console.log('addMessageState: ', addMessageState.errorMessage);
addMessageState.status === 'Success' &&
console.log('Successfully added message to chain');
}, [addMessageState]);
useEffect(() => {
if(account){
library.getBalance(account).then(balance => {
set_ownerBalance(utils.formatUnits(balance, "ether"));
});
set_contractInstance(new CTR(CONTRACT_ADDR, ABI, library.getSigner()));
}
}, [account]);
const addMsg = async () => {
if(msg.length > 0){
let addedMessage = await addMessage(msg);
// when below function correctly worked, that triggered `Error watching` statement
}
};
const getMsg = async () => {
let chainMessages = await contractInstance.getMessages({from: account});
setChainMsgs(chainMessages);
};
return (
<>
<header>
{
!account &&
<button onClick={() => activateBrowserWallet()} >Connect Wallet</button>
}
{
account &&
<>
<div style={{display: 'flex'}}>
<h1 id="msg-addr">{ellipseAddress(account, 5)}</h1>
<span style={{margin: '0 0.5rem'}}>{ownerBalance} ETH</span>
</div>
<br />
</>
}
</header>
<main>
{
account &&
<>
<section>
<input type={"text"} placeholder={"Leave trail"} value={msg} onChange={e => setMsg(e.target.value)} />
<button onClick={async () => await addMsg()}>Add Message</button>
</section>
<section>
<button onClick={async () => await getMsg()}>Get Message</button>
{
chainMsgs.length > 0 &&
<ul>
{chainMsgs.map((chainMsg, i) => {
return (
<li key={i}>{chainMsg}</li>
)
})}
</ul>
}
</section>
</>
}
</main>
</>
);
}
function ellipseAddress(address='', width=10) {
return !address ? '' : address.slice(0, width) + "..." + address.slice(-width);
}
export default App;

正确检查来自package.json的软件包版本;
"dependencies": {
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@usedapp/core": "^1.0.2",
"ethers": "^5.6.5",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.0"
}发布于 2022-01-22 11:49:02
这可能是因为您要传递给account的getMessages(String(account))在可靠性方面与address类型不同。
实际上,要存储发件人的地址,您不必将帐户作为函数参数传递。Etherum已经将呼叫者地址检测为msg.sender。
坚实的:
function getMessages() public view returns (string[] memory)
{
return messages[msg.sender];
}在react端,只需调用函数而不传递参数。
const handleLoad = () => {
getMessages()
}发布于 2022-01-23 18:10:35
我建议您查看js中的有关承诺,但是要查看应该等待的返回值,则需要使用较长的历史时间--这可以这样做-- const {state, send} = await useContractFunction(...),但是为了使用“等待”关键字,使用它的函数应该有关键字async (postContract: Contract) =>,请记住,对块链的所有读写都使用承诺。
https://stackoverflow.com/questions/70812225
复制相似问题