Remix

為什麼我無法通過我的 HTML GUI 與我的所有智能合約功能進行互動?

  • May 13, 2022

我注意到了一些非常奇怪的事情……

我有一個具有兩個功能的智能合約。我能夠很好地與它們(在 Remix、Web3 Provider Environment、pragma solidity ^0.8.2 中)進行互動。但是,當我嘗試通過我的 Dapp (HTML GUI) 呼叫相同的函式時,我只能****與我的一個函式互動,而不能與另一個函式互動。

請幫助我了解發生了什麼。

在下面找到我的solidity函式片段:

   struct CryptoGift {
   address from;
   address to;
   uint256 tokenId;
   string  tokenName;
   string  messageToRecipient;
   uint256 createdAt;
   uint256 firstReminderAt;
   uint256 transferDate;
}
 
CryptoGift[] private allGifts;
mapping(address => CryptoGift[]) private myGifts;

function viewAllGifts() public view returns ( CryptoGift[] memory ) {   
   return allGifts;   
}

function viewMyGifts() public view returns ( CryptoGift[] memory ) {        
   return myGifts[msg.sender];
}

在 Remix 中,使用ENVIRONENT: Web3 Provider ACCOUNT: 0xb35abE6Cbf39AF6b547dB36C4645140F1d807413,兩者的功能viewAllGiftsviewMyGifts工作都很完美,如下圖所示:

說明這兩個函式都在 Remix 環境中工作

但是,在我的 HTML 文件中,viewAllGifts可以完美執行,而viewMyGifts無法正常執行。

viewMyGifts在下面找到我在javascript中的函式的片段:

contractMethods.viewMyGifts().call( ({}), (error, result)=> {
   console.log("Your in viewMyGifts"); 
   console.log("ethAddress: " +ethAddress);
   console.log("Result: " +result);
   console.log("Error: " +error);
 if(!error){ }
 else{}
});

上面的程式碼產生:

Your in viewMyGifts
ethAddress: 0xb35abe6cbf39af6b547db36c4645140f1d807413
Result: 
Error: null 

儘管…

contractMethods.viewAllGifts().call( ({}), (error, result)=> {
   console.log("Your in viewAllGifts"); 
   console.log("ethAddress: " +ethAddress);
   console.log("Result: " +result);
   console.log("Error: " +error);
 if(!error){ }
    else{}
});



Your in viewAllGifts
ethAddress: 0xb35abe6cbf39af6b547db36c4645140f1d807413
Result: 0xb35abE6Cbf39AF6b547dB36C4645140F1d807413,0x22Eb94E0DD34B70B9E718595D71bF5CF3065b1c4,100,BOO,I love you Boo 0,0,1652339951,1652339981,1652340011,0xb35abE6Cbf39AF6b547dB36C4645140F1d807413,0x22Eb94E0DD34B70B9E718595D71bF5CF3065b1c4,101,BOO,I love you Boo 1,0,1652339957,1652339987,1652340017,0xb35abE6Cbf39AF6b547dB36C4645140F1d807413,0x22Eb94E0DD34B70B9E718595D71bF5CF3065b1c4,102,BOO,I love you Boo 2,0,1652339962,1652339992,1652340022,0xb35abE6Cbf39AF6b547dB36C4645140F1d807413,0x22Eb94E0DD34B70B9E718595D71bF5CF3065b1c4,103,BOO,I love you Boo 3,0,1652339967,1652339997,1652340027
app.js:36 Error: null

感謝您的幫助!

那是因為你msg.sender在一個view函式中使用。

此變數用於事務,但在只讀函式上可能msg.sender為空。

將您的功能更改為 -

function viewMyGifts(address account) public view returns ( CryptoGift[] memory ) {        
   return myGifts[account];
}

我覺得有點愚蠢 XD,因為解決方案是如此簡單……

解決方案,因為它是一種非同步方法,所以(是的,你猜對了)簡單地將函式包裝在 Async/await 中,如下面的程式碼所示。

async function generateTheviewMyGiftsTiles (){
 await contractMethods.viewAllGifts().call( ({}), (error, result)=> {
   console.log("Your in viewAllGifts"); 
   console.log("ethAddress: " +ethAddress);
   console.log("Result: " +result);
   console.log("Error: " +error);

   if(!error){ }
   else{}
 });
}

上面的程式碼現在產生了預期的結果。

我在原始程式碼中沒有得到任何收益的原因僅僅是因為編譯器會呼叫該contractMethods.viewAllGifts().call()函式,但不會等待任何結果而只是繼續執行下一個函式。將 包裝在 async/await 中會強制編譯器在繼續執行下一個函式之前contractMethods.viewAllGifts().call()等待結果。contractMethods.viewAllGifts().call()

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