Solidity

堅固性:在結構中使用數組

  • May 4, 2018

我正在設計/開發一個智能合約,其中我們有兩種類型的對象:移動對象和非移動對象。兩種類型的狀態都會不時更改。前任。在運動物體的情況下,它的位置可以改變,但在非運動物體中,我們沒有位置改變,但也可以。我們有對象的所有者更改。所以,我定義struct如下:

struct Object{
   byte[] nonMoveState;
   byte[] MoveState;
 }
 mapping(address => Object) state;

而且我還定義了一個事件如下,以保留更改歷史以在事務雜湊中顯示它:

event changeAction(address indexed objectAdd, byte actionType, byte actionValue);

現在,我需要記錄所有更改,例如。在移動物體的情況下,它的位置從巴黎更改為倫敦。然後,如果我這樣做如下:

function setAction(address indexed objectAdd, byte actionType, byte actionValue) public returns (bool) {

   state[objectAdd].MoveState[].push("actionValue");
   emit changeAction(address indexed objectAdd, byte actionType, byte actionValue);

   return true;
 }

並呼叫函式:

setAction(0xE07b6e5a2026CC916A4E2Beb03767ae0ED6af773, "change place", "Paris");

setAction(0xE07b6e5a2026CC916A4E2Beb03767ae0ED6af773, "change place", "London");

有什麼不對?

***附加資訊:事實上,在移動物體的情況下,新的“動作”由 RFID/NFC 讀取/寫入,然後新的狀態儲存在區塊鏈中。

您可以使用嵌套在結構中的數組(和mapping和)。struct我不會那樣做。

byte[]是一個單字節數組。一種自然的處理方式是當您想要一次使用或附加一個字節時。對於像“巴黎”這樣的大塊,這不是我的首選。

您提到需要記錄所有更改。你沒有說為誰消費。這很重要,因為基於合約將始終對目前狀態感興趣的假設,有一種廉價且自然的方法可以做到這一點。也就是說,合約不需要訪問歷史,但觀察者需要。為此使用事件。

address如果主題是使用者或契約,則使用for 鍵是很自然的。bytes32我可能會建議在其他情況下使用無意義的。

這是適用於您的範例的通用模式。請參閱Solidity 是否有解決良好且簡單的儲存模式?

pragma solidity 0.4.19; 

contract Object {

   struct ObjectStruct {
       bytes32 location;
       address owner; // caution about using "owner" because it has a de facto meaning in standard contracts. Landlord, titleHolder ... 
       bool isObject;
   }

   mapping(bytes32 => ObjectStruct) public objectStructs;
   bytes32[] public objectList;

   event LogNewObject(address sender, bytes32 uid, bytes32 location, address owner);
   event LogChangeObjectLocation(address sender, bytes32 uid, bytes32 newLocation);
   event LogChangeObjectOwner(address sender, bytes32 uid, address newOwner);

   function isObject(bytes32 _uid) public view returns(bool isIndeed) {
       return objectStructs[_uid].isObject;
   }

   function getObjectCount() public view returns(uint count) {
       return objectList.length;
   }

   function newObject(bytes32 _uid, bytes32 _location, address _owner) public returns(bool success) {
       require(!isObject(_uid));
       objectStructs[_uid].location = _location;
       objectStructs[_uid].owner = _owner;
       objectStructs[_uid].isObject = true;
       objectList.push(_uid);
       LogNewObject(msg.sender, _uid, _location, _owner);
       return true;
   }

   function changeObjectLocation(bytes32 _uid, bytes32 _newLocation) public returns(bool success) {
       require(isObject(_uid));
       objectStructs[_uid].location = _newLocation;
       LogChangeObjectLocation(msg.sender, _uid, _newLocation);
       return true;
   }

   function changeObjectOwner(bytes32 _uid, address _newOwner) public returns(bool success) {
       require(isObject(_uid));
       objectStructs[_uid].owner = _newOwner;
       LogChangeObjectOwner(msg.sender, _uid, _newOwner);
       return true;
   }

}

希望能幫助到你。

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