Web3js

Drizzle cacheSend 輸出“cacheSend is not a function”錯誤,但使用 send 時 tx 工作

  • July 11, 2020

我在我的新開源項目中使用 Drizzle 和 react-hooks,但 cacheSend 輸出總是“cacheSend 不是函式”

這行帶有send的程式碼按預期工作

const stackId = contract.methods.createMerchant(value.name, value.category, value.weburl).send({from: drizzleState.accounts[0]})

而是使用cacheSend返回錯誤**“cacheSend 不是函式”**

const stackId = contract.methods["createMerchant"].cacheSend(value.name, value.category, value.weburl, {
 from: drizzleState.accounts[0]
})

每次我在這個項目中使用 cacheSend 時,我都會收到“cacheSend 不是函式”錯誤

我的 index.js 我在其中設置了 Drizzle 選項

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

// import drizzle functions and contract artifact
import { Drizzle } from "drizzle";
import Coupoken from "./contracts/Coupoken.json";

// let drizzle know what contracts we want and how to access our test blockchain
const options = {
 contracts: [Coupoken],
 web3: {
   fallback: {
     type: "ws",
     url: "ws://127.0.0.1:9545",
   },
 },
};

// setup drizzle
const drizzle = new Drizzle(options);

ReactDOM.render(<App drizzle={drizzle}/>, document.getElementById('root'));

這是我載入組件的 App.js

import React, { useState, useEffect, Fragment } from 'react'
import ReadString from "./ReadString";
import SetString from "./SetString";
import SetMerchant from "./SetMerchant";
import SetCoupon from "./SetCoupon";

const App = props => {
 const [drizzleReadinessState, setDrizzleReadinessState] = useState({drizzleState: null, loading: true})
 const { drizzle } = props

 useEffect(
   () => {
     const unsubscribe = drizzle.store.subscribe( () => {
       // every time the store updates, grab the state from drizzle
       const drizzleState = drizzle.store.getState()
       // check to see if it's ready, if so, update local component state
       if (drizzleState.drizzleStatus.initialized) {
         setDrizzleReadinessState({drizzleState: drizzleState, loading: false})
       }
     })
     return () => {
       unsubscribe()
     }
   }, [drizzle.store, drizzleReadinessState]
 )

 return (
   drizzleReadinessState.loading ?
     "Loading Drizzle..."
     :
     <Fragment>
       <ReadString drizzle={drizzle} drizzleState={drizzleReadinessState.drizzleState} />
       <SetString drizzle={drizzle} drizzleState={drizzleReadinessState.drizzleState} />
       <SetMerchant drizzle={drizzle} drizzleState={drizzleReadinessState.drizzleState} />
       <SetCoupon drizzle={drizzle} drizzleState={drizzleReadinessState.drizzleState} />
     </Fragment>
 )
}

export default App

我的組件

import React, { useState } from "react"
import { useForm } from "react-hook-form";

const SetMerchant = props => {
 const [stackId, setStackID] = useState(null)
 const { drizzle, drizzleState } = props
 const { Coupoken } = drizzleState.contracts

 const { register, handleSubmit, watch, errors } = useForm();
 const onSubmit = data => {
   setValue(data)
 };


 const setValue = value => {
   const contract = drizzle.contracts.Coupoken
   console.log(contract.methods["createMerchant"]);
   // let drizzle know we want to call the `set` method with `value`
   const stackId = contract.methods["createMerchant"].cacheSend(value.name, value.category, value.weburl, {
     from: drizzleState.accounts[0]
   })
   // save the `stackId` for later reference
   setStackID(stackId)
 }

 const getTxStatus = () => {
   // get the transaction states from the drizzle state
   const { transactions, transactionStack } = drizzleState

   // get the transaction hash using our saved `stackId`
   const txHash = transactionStack[stackId]

   // if transaction hash does not exist, don't display anything
   if (!txHash) return null;

   // otherwise, return the transaction status
   return `Transaction status: ${transactions[txHash] && transactions[txHash].status}`
 }

 return (
   <div>
     <h2>Register Merchant</h2>
     <form onSubmit={handleSubmit(onSubmit)}>
       <div className="row">
         <div className="six columns">
           <label htmlFor="name">Name</label>
           <input name="name" className="u-full-width" ref={register({ required: true, pattern: /^[A-Za-z]+$/i, maxLength: 40})} />
           {errors.name && <span>Use a valid input</span>}
         </div>
         <div className="six columns">
           <label htmlFor="name">Category</label>
           <input name="category" className="u-full-width" ref={register({ required: true, pattern: /^[A-Za-z]+$/i, maxLength: 40 })} />
           {errors.category && <span>Use a valid input</span>}
         </div>
       </div>
       <div className="row">
         <div className="u-full-width">
           <label htmlFor="weburl">Website</label>
           <input name="weburl" className="u-full-width" ref={register({ required: true, maxLength: 40 })} />
           {errors.weburl && <span>Use a valid input</span>}
           </div>
         </div>
       <input className="button-primary" type="submit" value="Submit" />
     </form>
     <div>{getTxStatus()}</div>
   </div>
 )
}

export default SetMerchant

github 儲存庫可在此處獲得

感謝您的時間

解決了將 open zeppelin 回滾到 2.5.1 並使用 pragma 0.5.0,drizzle 可能與使用 pragma 0.6 版本的最後一個 open zeppelin 版本存在一些不兼容問題。Drizzle 與solidity 0.6 存在兼容性問題。

引用自:https://ethereum.stackexchange.com/questions/83667