pragma solidity >=0.4.22 <0.6.0; contract marblesContract { address public contractOwner; //Marble attributes struct Marble { string marbleName; uint uuid; uint marblePrice; string marbleColor; string description; uint indexInArray; bool initialized; } modifier onlyOwner(){ require(msg.sender == contractOwner); _; } //mapping array to map the marbles mapping(uint => Marble) private idToMarbleMap; //mapping to check the ownership mapping(address => mapping(uint => bool)) private addressToIdToIsOwnedMap; //mapping array to save the marbles mapping(address => Marble[]) private marblesOfAddress; //Create events to confirm the transaction event MarbleCreate(address account, uint uuid); //Reject events to tract rejected transaction event RejectCreate(address account, uint uuid, string message); //To track ownership of the marbles event MarbleTransfer(address from, address to, uint uuid); event RejectTransfer(address from, address to, uint uuid, string message); //To track who changed the color event ColorChange(address to,uint uuid,string oldColor, string newColor); //Function to create a marble function createAsset(string name, string description,string color, uint price, uint uuid) public returns(bool){ if(idToMarbleMap[uuid].initialized) { emit RejectCreate(msg.sender, uuid, "Marble with this UUID already exists."); return; } Marble[] storage assetsOfSender = marblesOfAddress[msg.sender]; uint assetIndex = assetsOfSender.length; Marble memory newAsset = Marble(name,uuid,price, color, description,assetIndex, true); assetsOfSender.push(newAsset); idToMarbleMap[uuid] = newAsset; addressToIdToIsOwnedMap[msg.sender][uuid] = true; emit MarbleCreate(msg.sender, uuid); return true; } //function to transfer ownership function transferAsset(address to, uint uuid) public onlyOwner{ //TODO trigger automatically when location changes if(!idToMarbleMap[uuid].initialized) { emit RejectTransfer(msg.sender, to, uuid, "No marble with this UUID exists"); return; } if(!addressToIdToIsOwnedMap[msg.sender][uuid]) { emit RejectTransfer(msg.sender, to, uuid, "Sender does not own this marble."); return; } addressToIdToIsOwnedMap[msg.sender][uuid] = false; addressToIdToIsOwnedMap[to][uuid] = true; Marble[] storage assetsOfSender = marblesOfAddress[msg.sender]; Marble[] storage assetsOfReceiver = marblesOfAddress[to]; Marble storage transferedAsset = idToMarbleMap[uuid]; assetsOfSender[transferedAsset.indexInArray] = assetsOfSender[assetsOfSender.length-1]; //swap last element to fill gap in array assetsOfSender[transferedAsset.indexInArray].indexInArray = transferedAsset.indexInArray; assetsOfSender.length--; transferedAsset.indexInArray = assetsOfReceiver.length; assetsOfReceiver.push(transferedAsset); emit MarbleTransfer(msg.sender, to, uuid); } //function to get marble details for other peers function getAsset(uint id) public view returns (string, string, bool) { Marble storage foundAsset = idToMarbleMap[id]; return (foundAsset.marbleName, foundAsset.marbleColor, foundAsset.initialized); } //function to change marble color function changeMarbleColor(address to,uint uuid,string newColor) public onlyOwner() { Marble[] storage marble = marblesOfAddress[msg.sender]; string oldColor=marble[uuid].marbleColor; marble[uuid].marbleColor = newColor; emit ColorChange(msg.sender, uuid, oldColor,newColor); } //function to marble details for the marble owner function getAssetsOfAddress(address owner) public view returns (uint[]) { Marble[] storage assetsArray = marblesOfAddress[owner]; uint[] memory result = new uint[](assetsArray.length); for (uint i = 0; i < assetsArray.length; i++) { result[i] = assetsArray[i].uuid; } return result; } }
0.4.18