Solidity

將數組從松露傳遞給solidity的函式

  • October 30, 2019

從松露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[]

任何幫助將不勝感激!謝謝!

解決方案:

  1. 擺脫pragma experimental ABIEncoderV2;
  2. 將每次出現的替換stringbytes32
  3. 將每次出現的替換bytes32 memorybytes32
  4. 將每次出現的替換"Gator"bytes32("Gator")
  5. 將每次出現的替換"Miami"bytes32("Miami")
  6. 將每次出現的替換"Georgia"bytes32("Georgia")
  7. 將每次出現的替換"Gator vs Miami"bytes32("Gator vs Miami")
  8. 將每次出現的替換"Gator vs Georgia"bytes32("Gator vs Georgia")
  9. 在您的 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

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