如何使用solidity從錢包地址獲取相應的代幣地址
pragma solidity >=0.4.25 <0.9.0; contract HelloBlockchain { struct token { address token; uint256 balance; } token[] res; function getBalances(address walletAddress, address[] memory tokenAddress) public returns(token[] memory){ for (uint i = 0; i < tokenAddress.length; i++) { (bool success, bytes memory data) = address(tokenAddress[i]).call(abi.encodeWithSignature("balanceOf(address)", walletAddress)); uint256 amount = abi.decode(data, (uint256)); res.push(token(tokenAddress[i], amount)); } return res; } }
函式參數是一個錢包地址和一個代幣地址數組,該函式將遍歷代幣地址以查找該特定代幣的錢包餘額。但是,當我部署並執行該功能時,我一直遇到錯誤的交易被探勘但執行錯誤,我不確定這意味著什麼以及如何繼續
如果它們是您的契約的孩子或至少是導入的,您只能呼叫這樣的函式,所以是的,這一行是無效的
uint256 amt = tokenAddress[i].getBalances(walletAddress);
但我認為你走在正確的道路上;你可以使用這個呼叫另一個合約:
//externalContractAddress address contractFoo = 0x12000notFakeAddress00012739 //parameters like tokenId, etc. parameters = bar (bool,data) = address(contractFoo).call("functionSignature",parameters)
IE。我有一個操作員契約,其功能呼叫另一個契約來刻錄 NFT 代幣,如下所示:
function burn (address foo, uint256 id) external { address contractFoo = 0x12000notFakeAddress00012739 (bool burned,) = address(contractFoo).call( abi.encodeWithSignature("burn(address,uint256,uint256)", foo, id, 1) ); require(burned, "Burn Failed"); }
只需將銷毀函式 singature (
"burn(address,uint256,uint256)"
) 替換為從另一個合約中獲取餘額的函式_______新編輯
我對你的程式碼做了一些重構;但是我必須道歉,因為我還找到了另一個實際上比我自己的回答更好的答案,原因是呼叫函式可能會觸發區塊鏈儲存更改,因此 EVM 不允許您將其用作視圖函式,因此呼叫這個函式會觸發一個消耗gas的交易,你可以通過閱讀這裡的文件來推斷
// SPDX-License-Identifier: MIT pragma solidity >=0.4.25 <0.9.0; contract HelloBlockchain { struct token { address token; uint256 balance; } function getBalances(address walletAddress, address[] memory tokenAddress) public returns(token[] memory){ //cant push or pull if the array is not in storage so i make a fixed size array with //the max possible lenght token[] memory res = new token[](tokenAddress.length); for (uint i = 0; i < tokenAddress.length; i++) { (bool success, bytes memory data) = address(tokenAddress[i]).call(abi.encodeWithSignature("balanceOf(address)", walletAddress)); if (success) { uint256 amount = abi.decode(data, (uint256)); res[i]= token(tokenAddress[i], amount); } } return res; } }
有關更多詳細資訊,請查看關於地址成員的solidity 文件,其中詳細說明了這個地址是什麼。呼叫
如果目標是製作自己的代幣
您必須在某處聲明函式 getBalances。通常,我們將繼承集成到 ERC,在本例中為 ERC20。因此,所有平衡都保存在私有映射中。
如果目標是達到特定的令牌。
正如 Carlos 所說,您必須使用其地址呼叫另一個合約。但是出於安全問題,如果被呼叫的智能合約不可信,我會建議避免使用 Call。而是使用介面,和/或檢查他們使用什麼介面以及他們尊重什麼標準。
如果您需要/想要使用 Call,那麼您必須考慮返回的參數:(bool 成功,字節記憶體數據),其中 data 是一個字節包,您將在其中獲得但不僅是從被呼叫函式返回的值。而且在這種情況下最好使用彙程式序。
如果目標是讓所有可能屬於錢包的代幣
那麼,就不可能了,因為錢包不保存任何資訊。餘額保存在合約中的鍵值上(如果它們尊重某些 ERC,則映射):addressWallet -> 金額。