Solidity
將數組從松露傳遞給solidity的函式
從松露
ALERT: Transaction Error. Exception thrown in contract code
呼叫函式時,我進入了元遮罩。addBet
當從 remix 呼叫該函式時,該函式可以正常工作。如果我更改程式碼並傳遞單個值而不是數組,該函式也適用於松露。真的可以將數組從松露傳遞給solidity函式嗎?在瀏覽器控制台中,我看到了這個
MetaMask - RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":779020742217,"jsonrpc":"2.0","params":["0xf901ad0c8504a817c800836170d4949d70edd4e3647f2ec9a3b5abce637854b650fe1b80b901440c7bf290000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffce000000000000000000000000000000000000000000000000000000000000001047656f72676961207673204d69616d6900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000747656f726769610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d69616d69000000000000000000000000000000000000000000000000000000822d46a0c2291f4adb451dae0cdfc07076a0af766c061bf9c7ffa56750bb36c7057d10f5a03920df81d72cd6a838664ff8d01eaebb6e51ae07a83b477d74ed03e51905d5cb"],"method":"eth_sendRawTransaction"} [object Object] uncaught exception: Object
投注.sol
pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; contract Betting { struct Bet{ uint betId; string question; BetStatus betStatus; mapping(uint => MoneyLineDatum) moneyLineData; uint lengthMoneyLineData; } struct MoneyLineDatum{ string option; int value; } address public owner = msg.sender; mapping(uint => Bet) public bets; uint public lengthBets; enum BetStatus {Open, Closed} constructor() public{ string[2] memory options = ["Gator", "Miami"]; int[2] memory values = [int(200), -100]; addBet("Gator vs Miami", options, values); options = ["Gator", "Georgia"]; values = [int(200), -150]; addBet("Gator vs Georgia", options, values); } modifier onlyBy(address account){ require(msg.sender == account, "Unauthorised Access"); _; } function addNewEmptyBet() public{ Bet memory bet; bets[lengthBets] = bet; } function addBet(string memory question, string[2] memory options, int[2] memory values) public onlyBy(owner){ addNewEmptyBet(); Bet storage bet = bets[lengthBets]; bet.betId = lengthBets; bet.question = question; bet.betStatus = BetStatus.Open; lengthBets+=1; for(uint i=0; i<options.length; i++){ bet.moneyLineData[i] = MoneyLineDatum(options[i], values[i]); } bet.lengthMoneyLineData+=options.length; } function getLengthMoneyLineData(uint betId) public view returns(uint){ return bets[betId].lengthMoneyLineData; } function getMoneyLineData(uint betId, uint idx) public view returns(string memory, int){ MoneyLineDatum storage moneyLineDatum = bets[betId].moneyLineData[idx]; return (moneyLineDatum.option, moneyLineDatum.value); } }
來自 app.js 的片段
App.contracts.Betting.deployed().then(function(_instance){ return _instance.addBet(question, options, values, {from: App.account}); }).then(function(){ console.log("Bet has been added"); });
options
並且values
是每個大小為 2 的數組,分別具有數據類型string[]
和int[]
任何幫助將不勝感激!謝謝!
解決方案:
- 擺脫
pragma experimental ABIEncoderV2;
- 將每次出現的替換
string
為bytes32
- 將每次出現的替換
bytes32 memory
為bytes32
- 將每次出現的替換
"Gator"
為bytes32("Gator")
- 將每次出現的替換
"Miami"
為bytes32("Miami")
- 將每次出現的替換
"Georgia"
為bytes32("Georgia")
- 將每次出現的替換
"Gator vs Miami"
為bytes32("Gator vs Miami")
- 將每次出現的替換
"Gator vs Georgia"
為bytes32("Gator vs Georgia")
- 在您的 Truffle 測試中,將每個字元串轉換
x
為:
web3.fromAscii(x)
如果您使用的是 Truffle v4.x(依賴於 Web3 v0.x)或更早版本web3.utils.asciiToHex(x)
如果您使用的是 Truffle v5.x(依賴於 Web3 v1.x)或更高版本關於合約程式碼的幾點說明:
- 似乎您的每個映射都像數組一樣使用;所以你可能應該使用數組來代替(為了良好的實踐,以及氣體成本效率)
onlyBy
修飾符不需要作為account
輸入參數;相反,它可以msg.sender
直接將 的值與 的值進行比較owner