Skip to content

Instantly share code, notes, and snippets.

@dima91
Created June 10, 2018 13:19
Show Gist options
  • Save dima91/1a4ae80acd04c7e94458fe399c7e454f to your computer and use it in GitHub Desktop.
Save dima91/1a4ae80acd04c7e94458fe399c7e454f to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.24+commit.e67f0147.js&optimize=false&gist=
pragma solidity ^0.4.24;
import "./sharedTypes.sol";
import "./catalogSmartContract.sol";
contract BaseContentManagementContract {
// Enum that describe type of access which an user has
enum AccessType {noneAccess, standardAccess, premiumAccess}
// Struct that indentifies a user who was granted to consume current content
struct GrantedUser {
address userAddress;
AccessType accessType;
}
address private authorAddress; // Address of contract's author
address private catalogAddress; // Address of catalog to check if determined functions are called only by catalog
SharedTypes.contentType private typeOfContent; // Tpe of content which this contract contains
bytes32 private contentTitle; // Title which identifies this contract in catalog
bytes32 private content; // Content of resource
uint private numberOfViews; // Number of viwes about content of this contract
mapping (bytes32 => GrantedUser) allowedUsers; // Map of users that are allowed to access this content
constructor (SharedTypes.contentType _conType, bytes32 _conTitle, bytes32 _cnt, address _catalogAddr) public {
typeOfContent = _conType;
authorAddress= msg.sender;
numberOfViews= 0;
contentTitle= _conTitle;
content= _cnt;
catalogAddress= _catalogAddr;
}
// ***** ***** //
// ***** Modifiers ***** //
modifier onlyCatalog () {
require (msg.sender == catalogAddress);
_;
}
modifier onlyAllowedUsers (bytes32 _username) {
require (allowedUsers[_username].accessType == AccessType.standardAccess || allowedUsers[_username].accessType == AccessType.premiumAccess);
_;
}
// ***** ***** //
// ***** Helper private/internal functions ***** //
/* This function allows subContracts of this contract to retrieve content if and only if user
* with addrs _userAddr is into "allowedUsers" map
*/
function retrieveContent (bytes32 _username) internal onlyAllowedUsers(_username) returns (bytes32) {
(CatalogSmartContract (catalogAddress)).notifyNewView (contentTitle, _username);
if (allowedUsers[_username].accessType == AccessType.standardAccess)
numberOfViews++;
allowedUsers[_username].accessType= AccessType.noneAccess;
return content;
}
// ***** ***** //
// ***** Public functions ***** //
// Function used by catalog to check that has the same address of catalogAddress local variable
function getCatalogAddress () public view returns (address) {
return catalogAddress;
}
function getViewsCount () public view returns (uint) {
return numberOfViews;
}
function getTitle () public view returns (bytes32) {
return contentTitle;
}
function getType () public view returns (SharedTypes.contentType) {
return typeOfContent;
}
// This function allows (only to catalog) to grant access to a user with address _userAddr.
function grantAccessToUser (bytes32 _username, address _userAddr, bool isPremium) public onlyCatalog () {
if (isPremium)
allowedUsers[_username].accessType= AccessType.premiumAccess;
else
allowedUsers[_username].accessType= AccessType.standardAccess;
allowedUsers[_username].userAddress= _userAddr;
}
// ***** ***** //
// ***** Abastract functions ***** //
function consumeContent (bytes32 _username) public returns (bytes32);
}
/* *************************************************************************************************************************************** */
/* *************************************************************************************************************************************** */
/* *************************************************************************************************************************************** */
contract SongManagementContract is BaseContentManagementContract {
constructor (bytes32 _title, bytes32 _cnt, address _catAddr)
BaseContentManagementContract(SharedTypes.contentType.song, _title, _cnt, _catAddr) public {
}
function consumeContent (bytes32 _username) public returns (bytes32) {
return retrieveContent (_username);
}
}
/* ********************************************* */
/* ********************************************* */
/* ********************************************* */
contract VideoManagementContract is BaseContentManagementContract {
constructor (bytes32 _title, bytes32 _cnt, address _catAddr)
BaseContentManagementContract(SharedTypes.contentType.video, _title, _cnt, _catAddr) public {
}
function consumeContent (bytes32 _username) public returns (bytes32) {
return retrieveContent (_username);
}
}
/* ********************************************* */
/* ********************************************* */
/* ********************************************* */
contract PhotoManagementContract is BaseContentManagementContract {
constructor (bytes32 _title, bytes32 _cnt, address _catAddr)
BaseContentManagementContract(SharedTypes.contentType.photo, _title, _cnt, _catAddr) public {
}
function consumeContent (bytes32 _username) public returns (bytes32) {
return retrieveContent (_username);
}
}
/* ********************************************* */
/* ********************************************* */
/* ********************************************* */
contract DocumentManagementContract is BaseContentManagementContract {
constructor (bytes32 _title, bytes32 _cnt, address _catAddr)
BaseContentManagementContract(SharedTypes.contentType.document, _title, _cnt, _catAddr) public {
}
function consumeContent (bytes32 _username) public returns (bytes32) {
return retrieveContent (_username);
}
}
pragma solidity ^0.4.24;
contract C {
function bytes32ToString(bytes32 x) constant returns (string) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
function bytes32ArrayToString(bytes32[] data) returns (string) {
bytes memory bytesString = new bytes(data.length * 32);
uint urlLength;
for (uint i=0; i<data.length; i++) {
for (uint j=0; j<32; j++) {
byte char = byte(bytes32(uint(data[i]) * 2 ** (8 * j)));
if (char != 0) {
bytesString[urlLength] = char;
urlLength += 1;
}
}
}
bytes memory bytesStringTrimmed = new bytes(urlLength);
for (i=0; i<urlLength; i++) {
bytesStringTrimmed[i] = bytesString[i];
}
return string(bytesStringTrimmed);
}
}
pragma solidity ^0.4.24;
import "./sharedTypes.sol";
import "./ownable.sol";
import "./baseContentManagementContract.sol";
import "./stringUtils.sol";
contract CatalogSmartContract is Ownable {
// Event list
event NewUser (bytes32 username, address userAddress);
event ContentPublished (bytes32 username, bytes32 contentTitle, address contentAddress);
event GrantedAccess (bytes32 username, address userAddress, bytes32 contentTitle, address contentAddress);
event CatalogDied ();
// TODO REMOVE ME
//event Data (string s, uint i);
// Duration of premium account (in block height)
uint constant PREMIUM_ACCOUNT_DURATION = 256; // ~20 blocks/hour
// Cost of premium account (wei) --> FIXME!!!
uint constant PREMIUM_ACCOUNT_COST= 100 wei;
// Cost of each single content --> FIXME!!
uint constant CONTENT_COST= 10 wei;
// Payout for author for each content access (this value have to be minor than CONTENT_COST) --> FIXME!!
uint constant PAYOUT_FOR_AUTHOR= 5 wei;
// Maximum number of views before sending payment
uint constant MAX_VIEWS_LIMIT= 5;
// Array of users which have are registered to service
bytes32 [] usersArray;
// Number of users
uint usersCount;
// Mapping which contains a User struct for each user that hav published or have requeested a content
mapping (bytes32 => SharedTypes.User) usersMapping;
// Mapping which link address to user: needed for functions like getContent
mapping (address => bytes32) addr2User;
// Mapping which contains, for each author, total number of view of their contents
mapping (bytes32 => uint) viewsPerAuthor;
// Mapping which contains an ExtendedContent struct for each content published on the platform (identified by a string)
mapping (bytes32 => SharedTypes.ExtendedContent) contentsMapping;
// Array containing addresses of contents published on the system (for loop functions)
bytes32 [] contentsArray;
// Number of contents (also index of next content in the array)
uint contentsCount;
constructor () public payable {
contentsCount= 0;
usersCount= 0;
}
// ************************************************************************************************************** //
// ************************************************************************************************************** //
// Modifiers
modifier alreadyPublishedM (bytes32 _contentTitle) {
require (alreadyPublished(_contentTitle) == true);
_;
}
modifier notPublished (bytes32 _contentTitle) {
require (alreadyPublished(_contentTitle) == false);
_;
}
modifier addressNotRegistered (address _address) {
require (addr2User[_address] == ""); // Sembra funzionare
_;
}
modifier userDoesntExist (bytes32 _username) {
require (userExists (_username) == false);
_;
}
modifier userExistsM (bytes32 _username) {
require (userExists(_username) == true);
_;
}
modifier isPremiumM (bytes32 _username) {
require (isPremium(_username) == true);
_;
}
modifier enoughValue (uint _msgValue, uint _lim) {
require (_msgValue == _lim);
_;
}
modifier userAllowed (bytes32 _username, bytes32 _contentTitle) {
require (contentsMapping[_contentTitle].allowedUsers[_username] == true);
_;
}
// ************************************************************************************************************** //
// ************************************************************************************************************** //
// Helper private functions
// Function to check if a user exists or not in usersMapping
function userExists (bytes32 _username) private view returns (bool){
return (usersMapping[_username].exists == true);
}
// Function which returns wether a content is already published on the platform
function alreadyPublished (bytes32 conTitle) private view returns (bool) {
return (contentsMapping[conTitle].exists == true);
}
// Function to register an user to system
function addUser (bytes32 _username, address _userAddr) userDoesntExist(_username) addressNotRegistered(_userAddr) userDoesntExist (_username) private {
addr2User[_userAddr]= _username;
usersMapping[_username].userAddress= _userAddr;
usersMapping[_username].accType= SharedTypes.accountType.standard;
usersMapping[_username].exists= true;
usersMapping[_username].expirationTime= 0;
usersMapping[_username].latestContent = "";
usersCount++;
usersArray.push (_username);
emit NewUser (_username, _userAddr);
}
// Function to add new content with address 'contAddr' registered by user with address 'userAddr'
function addContent (bytes32 _contentTitle, address _contentAddr, bytes32 _username) notPublished(_contentTitle) private {
contentsCount++;
contentsArray.push (_contentTitle);
contentsMapping[_contentTitle].exists= true;
contentsMapping[_contentTitle].author= _username;
contentsMapping[_contentTitle].contractAddress= _contentAddr;
usersMapping[_username].latestContent= _contentTitle;
}
// Return true if current premium account is valid
function isPremiumValid (bytes32 _username, uint _currentBlockNumber) userExistsM(_username) private view returns (bool) {
return (usersMapping[_username].expirationTime > _currentBlockNumber);
}
// ************************************************************************************************************** //
// ************************************************************************************************************** //
// Public functions
function killMe () public onlyOwner() {
// First of all, it distrubutes payments amog authors
uint i=0;
uint sumViews= 0;
for (i=0; i<usersCount; i++) {
if ((viewsPerAuthor[usersArray[i]] % MAX_VIEWS_LIMIT) != 0) {
address userAddr= usersMapping[usersArray[i]].userAddress;
userAddr.transfer ((viewsPerAuthor[usersArray[i]] % MAX_VIEWS_LIMIT) * PAYOUT_FOR_AUTHOR);
}
sumViews += viewsPerAuthor[usersArray[i]];
}
uint unit= address(this).balance / sumViews;
// Second, equally distribute current balance to among authors
for (i=0; i<usersCount; i++) {
uint payment= unit * viewsPerAuthor[usersArray[i]];
address (usersMapping[usersArray[i]].userAddress).transfer (payment);
}
emit CatalogDied ();
selfdestruct (owner);
}
// Function that allows users to registrate themselves into service
function registerMe (bytes32 _username) public userDoesntExist (_username) addressNotRegistered (msg.sender) {
addUser (_username, msg.sender);
}
// Function to link a content with the system
function publishContent (bytes32 _username, bytes32 _contentTitle, address _contentAddr) notPublished (_contentTitle) public {
if (!userExists(_username)) {
// Registering new user
addUser (_username, msg.sender);
}
// Checking wether content's catalogAddress and contentTitle are correct
BaseContentManagementContract remoteContract= BaseContentManagementContract (_contentAddr);
require (remoteContract.getCatalogAddress() == address (this));
require (remoteContract.getTitle() == _contentTitle);
addContent (_contentTitle, _contentAddr, _username);
emit ContentPublished (_username, _contentTitle, _contentAddr);
}
// Function to notify new view from another content manager
function notifyNewView (bytes32 _contentTitle, bytes32 _username) alreadyPublishedM (_contentTitle) userExistsM (_username) userAllowed (_username, _contentTitle) public {
bytes32 author= contentsMapping[_contentTitle].author;
viewsPerAuthor[author]++;
if ((viewsPerAuthor[author] % MAX_VIEWS_LIMIT) == 0) {
address rcvAddr= usersMapping[author].userAddress;
rcvAddr.transfer (MAX_VIEWS_LIMIT * PAYOUT_FOR_AUTHOR);
}
contentsMapping[_contentTitle].allowedUsers[_username]= false;
}
// FIXME DELETE ME!!!!
function getBalance () public view returns (uint) {
return address (this).balance;
}
// ************************************************************************************************************** //
// ************************************************************************************************************** //
// Required functions
// Returns the number of views for each content
function getStatistics () public view returns (uint [], bytes32 []) {
uint [] memory stats= new uint[] (contentsCount);
bytes32 [] memory strs= new bytes32[] (contentsCount);
uint i= 0;
bytes32 tmpCnt;
for (i=0;i<contentsCount; i++) {
tmpCnt= contentsArray[i];
stats[i]= (BaseContentManagementContract (contentsMapping[tmpCnt].contractAddress)).getViewsCount();
strs[i]= tmpCnt;
}
return (stats, strs);
}
// Returns the list of contents without the number of views
function getContentList () public view returns (bytes32 []) {
bytes32 [] memory conList= new bytes32[] (contentsCount);
uint i=0;
for (i=0; i<contentsCount; i++) {
conList[i]= contentsArray[i];
}
return conList;
}
// Returns the list of x newest contents
function getNewContentList (uint _n) public view returns (bytes32 []) {
bytes32 [] memory newest;
uint i= 0;
uint count=0;
if (_n>contentsCount)
count=contentsCount;
else
count=_n;
while (count!=0) {
newest[i]= contentsArray[contentsCount-(++i)];
count--;
}
return newest;
}
// Returns the most recent content with genre x
function getLatestByGenre (SharedTypes.contentType _ct) public view returns (bytes32) {
uint i= contentsCount;
bool found= false;
bytes32 reqStr;
if (contentsCount == 0) {
return "";
}
while (i != 0 && !found ) {
i--;
if ((BaseContentManagementContract(contentsMapping[contentsArray[i]].contractAddress)).getType() == _ct) {
found = true;
reqStr= (BaseContentManagementContract(contentsMapping[contentsArray[i]].contractAddress)).getTitle();
}
}
return reqStr;
}
// Returns the content with genre x, which has received the maximum number of views
function getMostPopularByGenre (SharedTypes.contentType _ct) public view returns (bytes32) {
bytes32 reqStr= "";
uint maximum=0;
uint i= contentsCount;
if (contentsCount == 0) {
return "";
}
while (i != 0) {
i--;
BaseContentManagementContract remoteContract= BaseContentManagementContract(contentsMapping[contentsArray[i]].contractAddress);
if (remoteContract.getType() == _ct) {
if (remoteContract.getViewsCount() > maximum)
reqStr= remoteContract.getTitle();
}
}
return reqStr;
}
// Returns the most recent content of the author x
function getLatestByAuthor (bytes32 _author) userExistsM (_author) public view returns (bytes32) {
bytes32 reqStr;
bool found= false;
uint i= contentsCount;
if (contentsCount == 0) {
return "";
}
while (i != 0 && !found) {
i--;
bytes32 author= contentsMapping[contentsArray[i]].author;
if (author == _author) {
found = true;
reqStr= (BaseContentManagementContract(contentsMapping[contentsArray[i]].contractAddress)).getTitle();
}
}
return reqStr;
}
// Returns the content with most views of the author x
function getMostPopularByAuthor (bytes32 _author) userExistsM (_author) public view returns (bytes32) {
bytes32 reqStr= "";
uint maximum=0;
uint i= contentsCount;
if (contentsCount == 0) {
return "";
}
while (i != 0) {
i--;
BaseContentManagementContract remoteContract= BaseContentManagementContract(contentsMapping[contentsArray[i]].contractAddress);
if (contentsMapping[contentsArray[i]].author == _author) {
if (remoteContract.getViewsCount() > maximum)
reqStr= remoteContract.getTitle();
}
}
return reqStr;
}
// Returns true if x holds a still valid premium account, false otherwise
function isPremium (bytes32 _username) userExistsM (_username) public view returns (bool) {
return (usersMapping[_username].accType == SharedTypes.accountType.premium);
}
// ************************************************************************************************************** //
// ************************************************************************************************************** //
// Pays for access to content x (NOT ACCESS TO CONTENT!)
function getContent (bytes32 _contentTitle) userExistsM(addr2User[msg.sender]) alreadyPublishedM (_contentTitle) enoughValue (msg.value, CONTENT_COST) public payable returns (address) {
// ******* --> Check preconditions (enough value..) + handle payments <-- *******
bytes32 senderUser= addr2User[msg.sender];
(BaseContentManagementContract (contentsMapping[_contentTitle].contractAddress)).grantAccessToUser (senderUser, msg.sender, false);
contentsMapping[_contentTitle].allowedUsers[senderUser]= true;
emit GrantedAccess (senderUser, msg.sender, _contentTitle, contentsMapping[_contentTitle].contractAddress);
return contentsMapping[_contentTitle].contractAddress;
}
// Requests access to content x without paying, premium accounts only
function getContentPremium (bytes32 _contentTitle) isPremiumM (addr2User[msg.sender]) alreadyPublishedM (_contentTitle) public returns (address) {
bytes32 senderUser= addr2User[msg.sender];
if (!isPremiumValid (senderUser, block.number)) {
usersMapping[senderUser].accType= SharedTypes.accountType.standard;
usersMapping[senderUser].expirationTime= 0;
revert ();
}
(BaseContentManagementContract (contentsMapping[_contentTitle].contractAddress)).grantAccessToUser (senderUser, msg.sender, true);
emit GrantedAccess (senderUser, msg.sender, _contentTitle, contentsMapping[_contentTitle].contractAddress);
return contentsMapping[_contentTitle].contractAddress;
}
// Pays for granting access for content x to the user u
function giftContent (bytes32 _contentTitle, bytes32 _receivingUser) userExistsM(_receivingUser) alreadyPublishedM (_contentTitle) enoughValue (msg.value, CONTENT_COST) public payable returns (address) {
// ******* --> Check preconditions (enough value..) + handle payments <-- *******
(BaseContentManagementContract (contentsMapping[_contentTitle].contractAddress)).grantAccessToUser (_receivingUser, usersMapping[_receivingUser].userAddress, false);
contentsMapping[_contentTitle].allowedUsers[_receivingUser]= true;
emit GrantedAccess (_receivingUser, usersMapping[_receivingUser].userAddress, _contentTitle, contentsMapping[_contentTitle].contractAddress);
return contentsMapping[_contentTitle].contractAddress;
}
// Pays for granting a Premium Account to the user u
function giftPremium (bytes32 _receivingUser) userExistsM(_receivingUser) enoughValue (msg.value, PREMIUM_ACCOUNT_COST) public payable {
// ******* --> check preconditions + handle payments <-- *******
usersMapping[_receivingUser].accType= SharedTypes.accountType.premium;
usersMapping[_receivingUser].expirationTime= block.number + PREMIUM_ACCOUNT_DURATION;
}
// Starts a new premium subscription
function buyPremium () userExistsM(addr2User[msg.sender]) enoughValue (msg.value, PREMIUM_ACCOUNT_COST) public payable {
// ******* --> check preconditions + handle payments <-- *******
bytes32 senderUser= addr2User[msg.sender];
usersMapping[senderUser].accType= SharedTypes.accountType.premium;
usersMapping[senderUser].expirationTime= block.number + PREMIUM_ACCOUNT_DURATION;
}
}
pragma solidity ^0.4.24;
import "./baseContentManagementContract.sol";
pragma solidity ^0.4.24;
import "./mortal.sol";
contract Crowdfund {
struct Funder {
address addr;
uint amount;
}
struct Project {
bool created;
bool opened;
string name;
address owner;
mapping (uint => Funder) funders;
uint fundersSize;
uint amount;
uint fundingGoal;
}
event ProjectCreated (string _name, uint _fundingGoal);
event FundTransferred (address _backer, string _project, uint _amount, uint _remainingAmount);
event fundingGoalReached (string project);
address private owner;
mapping (string => Project) private projects;
modifier ProjectNotExists (string _name) {
require (projects[_name].created == false);
_;
}
modifier ProjectExists (string _name) {
require (projects[_name].created == true);
_;
}
constructor () public {
owner= msg.sender;
}
function createProject (string _projectName, uint _amount) public ProjectNotExists (_projectName) {
projects[_projectName]= Project (true, true, _projectName, msg.sender, 0, 0, _amount);
emit ProjectCreated (_projectName, _amount);
}
function sendMoney (string _projectName, uint _sum) public ProjectExists (_projectName) {
Project storage p= projects[_projectName];
p.funders[p.fundersSize]= Funder (msg.sender, _sum);
p.fundersSize++;
p.amount += _sum;
uint remaining= p.fundingGoal - _sum;
emit FundTransferred (msg.sender, _projectName, _sum, remaining);
checkGoalReached (_projectName);
}
function checkGoalReached (string _projectName) private returns (bool) {
Project storage p= projects[_projectName];
if (p.fundingGoal <= p.amount) {
emit fundingGoalReached (_projectName);
p.opened= false;
return true;
}
return false;
}
function getProject (string _projectName) public view returns (bool, address, uint, uint, uint, bool) {
Project storage p= projects[_projectName];
return (p.opened, p.owner, p.fundersSize, p.amount, p.fundingGoal, p.opened);
}
}
pragma solidity ^0.4.24;
contract Mortal {
address owner;
constructor () public {
owner= msg.sender;
}
function kill () public {
if (msg.sender == owner)
selfdestruct (owner);
}
}
pragma solidity ^0.4.24;
contract Ownable {
address owner;
constructor () public {
owner = msg.sender;
}
modifier onlyOwner () {
require (msg.sender == owner);
_;
}
}
pragma solidity ^0.4.24;
library SharedTypes {
// Kind of content
enum contentType {song, video, photo, document}
// Kind of account
enum accountType {standard, premium}
// Type for registered users, both authors or customers. This struct is stored in the catalog
struct User {
address userAddress; // Address of user (key value is the name)
bool exists; // To check if an user exists in the system
accountType accType; // Type of current account (default standard)
uint expirationTime; // Expiration time (calculated in block.size). Valid only for premium account
bytes32 latestContent; // Title of latest content published by current user
}
// Struct to hold togheter BasContentManagementContracts and list of users which payed to view these contents
// Title of content (a string) is the identifier of content
struct ExtendedContent {
bool exists; // To check if a content exists in the system
address contractAddress; // Contract's address associated to current content
bytes32 author; // Name of owner of content
mapping (bytes32 => bool) allowedUsers; // Mapping to store users which are allowed to retreive current content
// Others informations, about views and users which are granted to access to current content, are stored in BaseContentManagementContracts
}
}
pragma solidity ^0.4.24;
library StringUtils {
/// @dev Does a byte-by-byte lexicographical comparison of two strings.
/// @return a negative number if `_a` is smaller, zero if they are equal
/// and a positive numbe if `_b` is smaller.
function compare(string _a, string _b) private pure returns (int) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint minLength = a.length;
if (b.length < minLength) minLength = b.length;
//@todo unroll the loop into increments of 32 and do full 32 byte comparisons
for (uint i = 0; i < minLength; i ++)
if (a[i] < b[i])
return -1;
else if (a[i] > b[i])
return 1;
if (a.length < b.length)
return -1;
else if (a.length > b.length)
return 1;
else
return 0;
}
/// @dev Compares two strings and returns true iff they are equal.
function equal(string _a, string _b) public pure returns (bool) {
return compare(_a, _b) == 0;
}
/// @dev Finds the index of the first occurrence of _needle in _haystack
function indexOf(string _haystack, string _needle) public pure returns (int)
{
bytes memory h = bytes(_haystack);
bytes memory n = bytes(_needle);
if(h.length < 1 || n.length < 1 || (n.length > h.length))
return -1;
else if(h.length > (2**128 -1)) // since we have to be able to return -1 (if the char isn't found or input error), this function must return an "int" type with a max length of (2^128 - 1)
return -1;
else
{
uint subindex = 0;
for (uint i = 0; i < h.length; i ++)
{
if (h[i] == n[0]) // found the first char of b
{
subindex = 1;
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex]) // search until the chars don't match or until we reach the end of a or b
{
subindex++;
}
if(subindex == n.length)
return int(i);
}
}
return -1;
}
}
// Function to convert a bytes32 to a string
function bytes32ToString (bytes32 x) public pure returns (string) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
// Function to convert a string to bytes32
function stringToBytes32(string memory source) public pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 32))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment