pragma solidity ^0.4.18; contract Layer2DAPP { struct User { string name; bool exists; uint[] connectedUsers; } struct JointAccount { bool exists; uint balance1; uint balance2; } mapping(uint => User) public users; mapping(bytes32 => JointAccount) private jointAccounts; uint[] public userIds; function createAccountKey(uint user1, uint user2) private pure returns (bytes32) { require(user1 != user2); if(user1 < user2) { return sha256(user1, user2); } else { return sha256(user2, user1); } } function registerUser(uint userId, string userName) public { require(!users[userId].exists); users[userId].name = userName; users[userId].exists = true; userIds.push(userId); } function createAcc(uint user1, uint user2) public { require(users[user1].exists && users[user2].exists); bytes32 accountKey = createAccountKey(user1, user2); require(!jointAccounts[accountKey].exists); jointAccounts[accountKey].exists = true; jointAccounts[accountKey].balance1 = 5; jointAccounts[accountKey].balance2 = 5; users[user1].connectedUsers.push(user2); users[user2].connectedUsers.push(user1); } // Helper function to check if path exists between two users function pathExists(uint start, uint end) private constant returns (bool) { bool[] memory visited = new bool[](100); uint[] memory queue = new uint[](100); uint front = 0; uint rear = 0; queue[rear] = start; rear++; visited[start] = true; while (front < rear) { uint current = queue[front]; front++; if (current == end) { return true; } for (uint i = 0; i < users[current].connectedUsers.length; i++) { uint neighbor = users[current].connectedUsers[i]; if (!visited[neighbor]) { visited[neighbor] = true; queue[rear] = neighbor; rear++; } } } return false; } // Helper function to find next hop in path function findNextHop(uint start, uint end) private constant returns (uint) { bool[] memory visited = new bool[](100); uint[] memory queue = new uint[](100); uint[] memory parent = new uint[](100); uint front = 0; uint rear = 0; queue[rear] = start; rear++; visited[start] = true; while (front < rear) { uint current = queue[front]; front++; if (current == end) { uint temp = current; while (parent[temp] != start) { temp = parent[temp]; } return temp; } for (uint i = 0; i < users[current].connectedUsers.length; i++) { uint neighbor = users[current].connectedUsers[i]; if (!visited[neighbor]) { visited[neighbor] = true; queue[rear] = neighbor; rear++; parent[neighbor] = current; } } } return 0; } function sendAmount(uint sender, uint receiver, uint amount) public returns (bool) { require(users[sender].exists && users[receiver].exists); require(pathExists(sender, receiver)); uint current = sender; uint next; while (current != receiver) { next = findNextHop(current, receiver); require(next != 0); bytes32 accountKey = createAccountKey(current, next); JointAccount storage account = jointAccounts[accountKey]; if (current < next) { require(account.balance1 >= amount); account.balance1 -= amount; account.balance2 += amount; } else { require(account.balance2 >= amount); account.balance2 -= amount; account.balance1 += amount; } current = next; } return true; } function closeAccount(uint user1, uint user2) public { require(users[user1].exists && users[user2].exists); bytes32 accountKey = createAccountKey(user1, user2); require(jointAccounts[accountKey].exists); for (uint i = 0; i < users[user1].connectedUsers.length; i++) { if (users[user1].connectedUsers[i] == user2) { users[user1].connectedUsers[i] = users[user1].connectedUsers[users[user1].connectedUsers.length - 1]; users[user1].connectedUsers.length--; break; } } for (uint j = 0; j < users[user2].connectedUsers.length; j++) { if (users[user2].connectedUsers[j] == user1) { users[user2].connectedUsers[j] = users[user2].connectedUsers[users[user2].connectedUsers.length - 1]; users[user2].connectedUsers.length--; break; } } delete jointAccounts[accountKey]; } function getAccountBalance(uint user1, uint user2) public constant returns (uint, uint) { bytes32 accountKey = createAccountKey(user1, user2); require(jointAccounts[accountKey].exists); return (jointAccounts[accountKey].balance1, jointAccounts[accountKey].balance2); } function getConnectedUsers(uint userId) public constant returns (uint[]) { require(users[userId].exists); return users[userId].connectedUsers; } }
0.4.18