Solidity
堅固性:在結構中使用數組
我正在設計/開發一個智能合約,其中我們有兩種類型的對象:移動對象和非移動對象。兩種類型的狀態都會不時更改。前任。在運動物體的情況下,它的位置可以改變,但在非運動物體中,我們沒有位置改變,但也可以。我們有對象的所有者更改。所以,我定義
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; } }
希望能幫助到你。