From a6cfd2d694461e82cf4751f3189e589058fce626 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Sat, 12 Oct 2019 08:29:35 +0200 Subject: [PATCH] adding an indexing contract: Build sets of tokens indexed by the corresponding events. Allows to build an onchain, trustless, list of token that belong to an event. Needed for auditable/trustless loterry --- eth/contracts/PoapIndex.sol | 65 ++++++++++++++++++++++++++ eth/contracts/Set.sol | 91 +++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 eth/contracts/PoapIndex.sol create mode 100644 eth/contracts/Set.sol diff --git a/eth/contracts/PoapIndex.sol b/eth/contracts/PoapIndex.sol new file mode 100644 index 00000000..dafc0001 --- /dev/null +++ b/eth/contracts/PoapIndex.sol @@ -0,0 +1,65 @@ +/* Copyright 2019 Hadrien Croubois +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +pragma solidity ^0.5.0; + +import "./Poap.sol"; +import "./Set.sol"; + +contract PoapIndex +{ + using Set for Set.set; + + // Poap token address + Poap public poap; + + // event to tokens + mapping(uint256 => Set.set) private m_tokensEvent; + + event TokenAdded(uint256 indexed tokenId, uint256 indexed eventId); + + constructor(Poap _poap) + public + { + poap = _poap; + } + + function addToken(uint256 _tokenId) external + { + _addToken(_tokenId); + } + + function addTokens(uint256[] calldata _tokenIds) external + { + for (uint256 i = 0; i < _tokenIds.length; ++i) + { + _addToken(_tokenIds[i]); + } + } + + function _addToken(uint256 _tokenId) internal + { + uint256 eventId = poap.tokenEvent(_tokenId); + if (eventId != 0 && m_tokensEvent[eventId].add(_tokenId)) + { + emit TokenAdded(_tokenId, eventId); + } + } + + function viewTokens(uint256 _eventId) external view returns (uint256[] memory) + { + return m_tokensEvent[_eventId].content(); + } +} diff --git a/eth/contracts/Set.sol b/eth/contracts/Set.sol new file mode 100644 index 00000000..79ac1e38 --- /dev/null +++ b/eth/contracts/Set.sol @@ -0,0 +1,91 @@ +/* Copyright 2019 Hadrien Croubois +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +pragma solidity ^0.5.0; + +library Set +{ + struct set + { + uint256[] members; + mapping(uint256 => uint256) indexes; + } + + function length(set storage _list) + internal view returns (uint256) + { + return _list.members.length; + } + + function at(set storage _list, uint256 _index) + internal view returns (uint256) + { + return _list.members[_index - 1]; + } + + function indexOf(set storage _list, uint256 _value) + internal view returns (uint256) + { + return _list.indexes[_value]; + } + + function contains(set storage _list, uint256 _value) + internal view returns (bool) + { + return indexOf(_list, _value) != 0; + } + + function content(set storage _list) + internal view returns (uint256[] memory) + { + return _list.members; + } + + function add(set storage _list, uint256 _value) + internal returns (bool) + { + if (contains(_list, _value)) + { + return false; + } + _list.indexes[_value] = _list.members.push(_value); + return true; + } + + function remove(set storage _list, uint256 _value) + internal returns (bool) + { + if (!contains(_list, _value)) + { + return false; + } + + uint256 i = indexOf(_list, _value); + uint256 last = length(_list); + + if (i != last) + { + uint256 swapValue = _list.members[last - 1]; + _list.members[i - 1] = swapValue; + _list.indexes[swapValue] = i; + } + + delete _list.indexes[_value]; + --_list.members.length; + + return true; + } + +}