Dapp-Development

this.contract.deployed() 不是函式

  • November 20, 2019

我正在為我的智能合約製作一個 React 前端,但在將它連接到我的 React 程式碼時遇到了問題。

以下是我的程式碼的相關部分:

import TruffleContract from 'truffle-contract'

...

class App extends Component {
 constructor(props) {
   super(props);

   // Initialize MetaMask plugin
   this.web3 = new Web3();
   const isMetaMaskEnabled = () => !!window.web3;

   if (!isMetaMaskEnabled()) {
     alert('Add the Metamask pluging to your browser to continue');
     return;
   }

   if (window.ethereum) {
     window.web3 = new Web3(window.ethereum)
     try {
       // Request account access if needed
       window.ethereum.enable().then(() => {
         console.log("Accounts now exposed")
       }).catch((error) => {
         console.log(error)
       })
     } catch(error) {
       // User denied account access
       console.log(error).then(() => {
         console.log("unable to obtain MetaMask Account")
       })
     }
   } else if (window.web3) {
     window.web3 = new Web3(window.web3.currentProvider).then(() => {
       console.log("Accounts always exposed")
     }).catch((error) => {
       console.log(error)
     })
   } else {
     console.log("Non-Ethereum browser detected. You should consider trying MetaMask!")
   }

   this.web3.eth.net.getNetworkType()
   .then(function(netID) {
     while (netID !== 'main') {
       // alert('Select Main Ethereum Network in MetaMask')
     }
   });

   this.state = {
     ...
     uAddress: '0x0'
   }

   this.users = TruffleContract(Users);
   this.users.setProvider(window.web3.currentProvider)

   this.users = this.users.bind(this)
 }

 componentDidMount() {
   this.users.deployed().then((instance) => {
     this.setState( {uAddress: instance.address} )
   })
 }

當我嘗試在 this.users 上呼叫 deploy() 時,出現錯誤,

TypeError: this.users.deployed is not a function

我知道有人問過類似的問題,但他們使用 abi 和合約地址創建合約實例,而不是使用 TruffleContract 方法。我想知道是否有可能以這種方式工作。

萬一有人來這裡尋找答案,我已經想通了。

我改變了我的契約實例。我創建了一個單獨的 js 文件來儲存一個包含所有契約數據的對象;

module.exports = {
 address: "(Your-Contract-Address-Goes_here)",
 abi: [
   {
    (Your-Contract-ABI-goes-here)
   }
 ]
}

然後創建實例,我得到 Web3 並使用 web3.eth.Contract 方法;

const Web3 = require("web3");
const web3 = new Web3(
 new Web3.providers.HttpProvider(
   "https://rinkeby.infura.io/v3/(You-Infura-Secret-Goes-Here)"
 )
);

const Contract = require("Path-To-Contract");
const contractInstance = new web3.eth.Contract(
 Contract.abi,
 Contract.address
);

現在你應該可以像這樣使用 web3 api 呼叫你的合約了,

let data = contract.method.Contract_Method.call(Any-Varibles-Go-Here).encodeABI();
web3.eth.sendTransaction(data [,callback]);

發送 write 方法有點不同,使用 Infura 實際上也需要您簽署自己的交易並使用web3.eth.sendSignedTransaction(),但我不會在這裡詳細說明。如果您使用的是 Metamask,或者我認為 Dapper 儘管我沒有嘗試過,它會按照我解釋的方式工作。Metamask 將簽署您在他們自己的節點上發送的交易,我相信這就是為什麼這樣做,但 Infura 不會在他們的節點上簽署交易。

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