Solidity

錯誤:無效的 bytes6 值

  • March 22, 2020

我正在嘗試創建一個 TicketPurchaser 應用程序。這是智能合約的完整程式碼,雖然我認為我要問的問題是類型錯誤,但大部分程式碼並不重要。

pragma solidity ^0.4.0;



/** @title TicketPurchaser
   @dev Let's the user buy ticket for event, which can be validated by gatekeeper at the event.
   @author imestin
*/
contract TicketPurchaser {
   mapping (bytes6 => address) tickets;                        //One address can buy multiple tickets, so the ticket is the key. 
   mapping (bytes6 => bool) expired;                           //True if ticket is already claimed 
   uint TicketPrice;                                           //Ticket price in wei

   //User can buy a ticket using ether
   function BuyTicket() public payable returns (string) {
       //If this condition is not true, program will exit.
       require(msg.value >= TicketPrice);
       if (msg.value > TicketPrice) {
           msg.sender.transfer(msg.value-TicketPrice);
       }

       SaveCode(GenerateSixDigitCode());
   }

   function GenerateSixDigitCode() private view returns (bytes6) {
//        uint8[6] memory AlphaIndex;                     //We add up 2 hex digit, than multiply it by 1.125 (32 to 36 conversion)
//        string memory AlphaNumerics = new string(36);
//        AlphaNumerics = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//        bytes6 SixDigit;

       //This is not really good, "seed" will be sha256 hash, and we want. 6-digit.
//        bytes32 seed = (keccak256(abi.encodePacked(
//            block.timestamp + block.difficulty +
//            ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) +
//            block.gaslimit + 
//            ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)) +
//            block.number
//        )));

       //This is the string that we are getting the index for: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
//        AlphaIndex[0] = ToAlphaIndex(seed[0], seed[1]);
//        AlphaIndex[1] = ToAlphaIndex(seed[0], seed[1]);
//        AlphaIndex[2] = ToAlphaIndex(seed[0], seed[1]);
//        AlphaIndex[3] = ToAlphaIndex(seed[0], seed[1]);
//        AlphaIndex[4] = ToAlphaIndex(seed[0], seed[1]);
//        AlphaIndex[5] = ToAlphaIndex(seed[0], seed[1]);

       //Let's suppose AlphaIndex worked. 
 /*      SixDigit[0] = AlphaNumerics[AlphaIndex[0]];
       SixDigit[1] = AlphaNumerics[AlphaIndex[1]];
       SixDigit[2] = AlphaNumerics[AlphaIndex[2]];
       SixDigit[3] = AlphaNumerics[AlphaIndex[3]];
       SixDigit[4] = AlphaNumerics[AlphaIndex[4]];
       SixDigit[5] = AlphaNumerics[AlphaIndex[5]];*/

       SixDigit = "X4C9BA";
       return SixDigit;
   }

   //The returning value 
   function ToAlphaIndex(bytes1 x, bytes1 y) private pure returns (uint8) {
       return uint8((uint16(x) + uint16(y)) * 9 / 8);
   }

   //we could simple continou coding this and simulating the 6-digit-generation. This way we could have a working contract
   function SaveCode(bytes6 SixDigit) private {
       // will alter tickets mapping
       // should check if 6-digit-code is alpha-numeric, return true or ERR
       //we don't care about this right now
       tickets[SixDigit] = msg.sender;
   }

   //Gatekeeper can validate the ticket of the user
   //This will alter state, because it is invalidating a ticket.
   function RedeemTicket(bytes6 SixDigit) public payable returns (bool) {
       //User will present 6-digit-code (probalby written down in piece of paper.)

       //Gatekeeper prompts the code. It doesn't really matter who owns the code (you can buy tiket for another person). 
       //The thing that matters, that tickets[code] > 0
       require(tickets[SixDigit] > 0);


       //If tickets[code] > 0, we still need to check that the ticket hasn't been already claimed.
       //If this is true, we set expired[code] = true
       if ( !expired[SixDigit] ) {
           expired[SixDigit] = true;
           return true;
           //Green light "Success!"
       } else {
           return false;                   
           //Already claimed!
       }
   }
}

我正在 Remix 中對其進行測試。很明顯,六位數生成不起作用。我現在想解決的是,我正在發送一個修復字元串(“X4C9BA”),它將保存它,我將能夠兌換票。(呼叫 RedeemTicket 將使票證無效。)我認為保存程式碼有效,我檢查了“調試”按鈕,這是在票證映射中:

tickets: mapping(bytes6 => address)

    5834433942410000000000000000000000000000000000000000000000000000: 0xCA35B7D915458EF540ADE6068DFE2F44E8FA733C

我認為這是“X4C9BA”的十六進製表示,但老實說,我並不真正理解 583443394241000000000000000000000000000000000000000000000000000000 是什麼。

但是當我將“X4C9BA”發送到 RedeemTicket 時,它會出錯。

transact to TicketPurchaser.RedeemTicket errored: Error encoding arguments: Error: invalid bytes6 value (arg="", coderType="bytes6", value="X4C9BA", version=4.0.44)

如何修復這種類型的錯誤?謝謝你的幫助!

您需要要傳遞的 6 字節值的十六進製表示。

首先,它應該從開始0x(儘管 Remix 可能沒有它也可以管理)。

但更重要的是,它需要由 12 個十六進製字元組成,因為每個字元代表 4 位,而每個字節儲存 8 位(因此每個字節由 2 個字元表示)。

假設您想要的是字元串 "X4C9BA",您應該找到該字元串中每個字元的 ASCII 碼,然後將此碼轉換為十六進制基數,然後將每個字元替換為相應的結果。

這是一個為您完成所有工作的工具,您似乎應該使用0x885267576665.

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