Error searching in map using array in Solidity - arrays

I want to have a network of clients and servers in this network. To connect to the edge servers, the clients first check the validity of the edge server and then connect to it, and the client also connects to the said edge. . The client calculates the credibility of this edge server. In this code, I want to calculate the reputation of the edge server, so I have mapped the address of the edge server and the client to the reputation and used an identifier to search. I get an error when I run the ComputeReputation function.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "https://github.com/PaulRBerg/prb-math/blob/v1.0.3/contracts/PRBMathSD59x18.sol";
contract Reputationcalculation{
using PRBMathSD59x18 for int256;
struct edgeserver{
bool exists;
uint placed_bids;
uint reputation;
uint deposit;
}
mapping (address => edgeserver) public edgeserver_suppliers;
struct mobileuser{
bool exists;
uint deposit;
//credbility
bool auction_open;
}
mapping (address => mobileuser) public mobileusers;
mapping(address => mapping(address =>mapping (uint=>uint))) public reputation;
mapping(uint => edgeserver) public listedgeservers;
mapping(address => mapping(address => uint)) public reputationid;
//mapping (uint => address) public mobile_user;
//mapping (uint => address) public edge_server;
address payable private owner;
address[] public mobile_user;
address[] public edge_server;
uint SIC;
uint n;
uint u;
uint s;
address client;
address server;
uint reputationSum ;
//uint numRatings;
uint id=0;
uint reputationlength;
uint reputationAverage;
modifier onlyOwner{
require(msg.sender == owner,"Sender not authorized.");
_;
}
modifier onlyClient{
require(mobileusers[msg.sender].exists,"Sender not authorized.");
_;
}
modifier onlySupplier{
require(edgeserver_suppliers[msg.sender].exists,"Sender not authorized.");
_;
}
event edgeserverRegistered(address supplierAddress);
event mobileuserRegistered(address clientAddress);
constructor () public{
owner =payable( msg.sender);
n=0;
SIC=0;
u=0;
s=0;
reputationSum = 0;
//numRatings = 0;
reputationlength=0;
reputationAverage=0;
// client=msg.sender;
}
function addmobileuser() payable public{
require(!mobileusers[msg.sender].exists,"mobileuser already registered");
require(!edgeserver_suppliers[msg.sender].exists,"Address registerd as a edgeserver");
mobileusers[msg.sender]=(mobileuser(true,msg.value,false));
client=msg.sender;
u++;
emit mobileuserRegistered(msg.sender);
}
function addedgeserver(address supplier) onlyOwner public{
require(!mobileusers[supplier].exists,"Address registerd as a mobile user");
edgeserver_suppliers[supplier]=(edgeserver(true,0,0,0));
server=msg.sender;
s++;
emit edgeserverRegistered(supplier);
}
function SetReputation(address mobile, address edge, uint rating) public {
mobile_user.push(mobile);
edge_server.push(edge);
reputation[mobile][edge][id]= rating;
id++;
reputationlength=id;
}
function ComputeReputation(address user )public {
uint numRatings = 0;
address mobile;
address edge;
for(id=0;id<=reputationlength;id++)
{
mobile=mobile_user[id];
edge=edge_server[id];
if(user==mobile){
reputationSum += reputation[mobile][edge][id];
numRatings++;
}
}
}
function getReputation( ) public returns(uint )
{
reputationSum;
}
}
Please help. Thank you
Actually, my problem is searching in the map. I want to calculate the total reputation given to each edge server by a specific client. Also, later, I plan to calculate the total reputation given by each client to a specific server. Please help me.

Related

Timed Advertisements Solidity Contract

Basically, I'm trying to make the smart contract be able to take exactly 0.05 eth ONLY when the cooldown timer is set to 0. The Dapp I'm creating is a first come first serve eth advertising service, where the user can upload an image or gif within the dapp, then pay 0.05 eth to trigger the advertisement to run for x amount of time. When the time runs out, the next user can purchase their ad slot.
The timer seems to work, but I cant get the timer to start upon payment.
I would really appreciate the help, here is what I have so far:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract AdEth {
//This sets up the name of the ad and if it is running, set to false by default
//Variables for start, end, cooldown (cool down can be changed here)
address payable public owner;
uint _start;
uint _end;
uint cooldownTime = 1 minutes;
constructor() {
owner = payable(msg.sender);
}
modifier timerOver {
require(block.timestamp <= _end, "The Cooldown is over");
_;
}
modifier onlyWhileOpen {
require(block.timestamp >= _start && block.timestamp <= _end);
_;
}
function start() public {
_start = block.timestamp;
end(cooldownTime);
}
function end(uint totalTime) public {
_end = totalTime + _start;
}
function getTimeLeft() public view returns(uint) {
return _end - block.timestamp;
}
receive() external payable {
}
function receiveAdPayment() payable public returns (bool) {
require(msg.value == 0.05 ether, "Not enough ether. 0.05 Needed.");
require(cooldownTime == 0, "There is currently an add running. Please wait until the cooldown is finished.");
msg.sender.transfer(0.05 ether);
start();
return true;
}
function withdrawAll(uint _amount) external {
require(msg.sender == owner, "Caller is not the owner.");
payable(msg.sender).transfer(_amount);
}
function getBalance() external view returns (uint) {
return address(this).balance;
}
}
------------EDITS 5.11.21--------------
I have swapped out all of the timestamps for block.number and everything is working as intended. However, I want the smart contract to automatically call the setRunning() function when the cooldownTime expires. Is this possible? or is this the best its going to get?
Appreciate any and all help!
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract AdEth {
//This sets up the name of the ad and if it is running, set to false by default
//Variables for start, end, cooldown (cool down can be changed here)
address payable public owner;
uint _start;
uint _end;
//The number is in BLOCKS (~15 sec each, rinkeby approx ~1 min)
uint cooldownTime = 4;
bool running;
constructor() {
owner = payable(msg.sender);
}
function start() internal {
_start = block.number;
_end = block.number + cooldownTime;
running = true;
}
function getTimeLeft() public view returns(uint) {
return _end - block.number;
}
//This allows the owner to set "running" to false only if the required amount of cooldown blocks is reached.
function setRunning() public {
require(msg.sender == owner, "You are not the owner.");
require(block.number > _end, "Wait for the cooldown to expire before you can reset running to false.");
running = false;
}
function isRunning() public view returns (bool) {
return running;
}
function receiveAdPayment() payable public {
require(msg.value >= 0.05 ether, "At Least 0.05 ETH Needed.");
require(block.number > _end, "There is currently an ad running. Please wait until the cooldown is finished.");
require(running != true, "The ad time may have run out, but has not been reset by Admin.");
start();
}
function withdraw(uint _amount) external {
require(msg.sender == owner, "Caller is not the owner.");
payable(msg.sender).transfer(_amount);
}
function getBalance() external view returns (uint) {
return address(this).balance;
}
}
----EDITS 5.18.22------
Ok here is the final product. Got pushed in a bunch of directions and chose the below code. It is working well in remix.
Thanks everyone!
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '#openzeppelin/contracts/access/Ownable.sol';
contract AdEth is Ownable {
//This sets up the name of the ad and if it is running, set to false by default
//Variables for start, end, cooldown (cool down can be changed here)
uint _start;
uint _end;
uint cooldownTime = 3 minutes;
uint runNumber = 0;
function start() internal {
_start = block.timestamp;
_end = block.timestamp + cooldownTime;
runNumber++;
}
function getTimeLeft() public view returns(uint) {
return _end - block.timestamp;
}
function adRunNumber() public view returns (uint) {
return runNumber;
}
function receiveAdPayment() payable public {
require(msg.value >= 0.05 ether, "At Least 0.05 ETH Needed.");
require(block.timestamp > _end, "There is currently an ad running. Please wait until the cooldown is finished.");
start();
}
function withdraw(uint _amount) external onlyOwner {
payable(msg.sender).transfer(_amount);
}
function getBalance() external view returns (uint) {
return address(this).balance;
}
}
First thing: NEVER use block.timestamp. It's not validated and can be abused. Use the block number as a form of timestamp instead.
Second thing: start() should be internal. Currently, anyone can call this, and this does not seem to be intentional behavior.
Finally, your issue: It appears you have two payable methods. The first one is the one that will be called. Remove the receive() function.

Building React front end for etherum solidity smart contract

I am new to react and solidity however I am doing one project for just learning but I am unable to understand how to create react front end of Solidity project.
pragma solidity^0.5.0;
pragma experimental ABIEncoderV2;
contract I2Chain {
event FileChained(string checksum,
address indexed user,
uint timestamp,
uint fileSize,
uint fileTimestamp,
string fileType,
string fileName);
event FileShared(string checksum,
address indexed user,
address indexed recipient,
uint attributes,
uint tenure,
uint timestamp);
event FileRead(string checksum, address indexed user, uint timestamp);
event FileDeleted(string checksum,
address indexed user,
uint timestamp);
event PubKeyUpdate(address indexed user, string pubKey);
mapping(address => string) public publicKeys;
function PublishFile(string memory _checksum,
uint _fileSize,
uint _fileTimestamp,
string memory _fileType,
string memory _fileName)
public {
emit FileChained(_checksum, msg.sender, now,
_fileSize,_fileTimestamp, _fileType, _fileName);
}
function ShareFile(string memory _checksum, address _recipient,
uint _attributes,
uint _tenure) public {
emit FileShared(_checksum, msg.sender, _recipient, _attributes,
_tenure, now);
}
function ReadFile(string memory _checksum) public {
emit FileRead(_checksum, msg.sender, now);
}
function DeleteFile(string memory _checksum) public {
emit FileDeleted(_checksum, msg.sender, now);
}
function setPublicKey(string memory _pubKey) public {
publicKeys[msg.sender] = _pubKey;
emit PubKeyUpdate(msg.sender, _pubKey);
}
function getPublicKey(address _user)
view public returns(string memory) {
return publicKeys[_user];
}
}
I have deployed the contract into truffle and generate the ABI of contract, however I didn't understand how to create the front-end with this ABI.
Note:p
When I deployed into remix IDE I am getting all function interface(please see the attachement enter image description here
Please suggest and help me how can I create UI for this contracts all function so user can intact with my smart contract and blockchain?
If you're new to both, i think you should follow this tutorial where they use drizzel to connect the blockchain with the frontend.
https://truffleframework.com/tutorials/getting-started-with-drizzle-and-react

Storing variables of GameObjects into Array [Unity]

I have 3 kinds of GameObject, namely blueBook, redBook and greenBook. There are 2 blueBook, 7 redBook and 4 greenBook in the scene.
They are each assigned with the following example script that have 3 properties.
public class blueBook : MonoBehaviour {
public string type = "BlueBook";
public string colour = "Blue";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (700*weightValue+300);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
}
// Update is called once per frame
void Update () {
}
}
In the new class, I want to take all the variables of the GameObject (type, colour, weight) and store them inside an array. How to do this?
After they are all stored inside the array, user will input an weight. Then another class will search through all the info to delete both the array and GameObject(in the scene) with the same amount of weight.
Thank you.
UPDATE
blueBook.cs
public class blueBook: MonoBehaviour {
public string type = "blueBook";
public string colour = "Red";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (500*weightValue+100);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
Debug.Log(weight);
}
// Update is called once per frame
void Update () {
}
}
block.cs
public class block: MonoBehaviour{
public List<GameObject> players;
void Start()
{ Debug.Log(players[1].GetComponent<blueBoook>().weight);
}
// Update is called once per frame
void Update () {
}
The debug.log for block.cs displayed 0 everytime eventho it display otherwise in debug.log of bluebook.cs. It is because it displayed the initial number? I don know wat is wrong
For all blocks in one list you can create a script that has a public list and you drag all your gameobjects into the list in the inspector.
using System.Collections.Generic;
public class ObjectHolder : MonoBehaviour
{
public List<GameObject> theBooks;
// You can remove by weight e.g. like this
public void DeleteByWeight(float inputWeight)
{
for(int i = theBooks.Count - 1; i >= 0; i--)
{
if(theBooks[i].GetComponent<Book>().weight == inputWeight)
Destroy(theBooks[i]);
theBooks.RemoveAt(i);
}
}
}
}
The script on the blocks needs to be renamed to the same name for all (Book in my example). From your code that is no problem since they only differ in the value of the members.

How can i know user is active in winform scenario?

The requirement is that if user hasn't clicked anything on the winform application in the past 60 seconds, it should perfom an auto-logout action. So apart from resetting the counter on each menu, each button, etc, which is overwhelming, is there any simpler method to detect user has been inactive for 60 seconds?
I'm using this code to calculate inactivity time. It work really good, I hope it could help you too.
public struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
[DllImport("User32.dll")]
private static extern Boolean GetLastInputInfo(ref LASTINPUTINFO plii);
/// <summary>
/// Get inactivity time
/// </summary>
/// <returns>Inactivity time in ms</returns>
public static int GetIdleTime()
{
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = (UInt32) System.Runtime.InteropServices.Marshal.SizeOf(lastInputInfo);
if (GetLastInputInfo(ref lastInputInfo))
{
UInt32 lastInputTick = lastInputInfo.dwTime;
if (lastInputTick == 0)
return 0;
return (Environment.TickCount - (Int32)lastInputInfo.dwTime);
}
else
return 0;
}
//In your method :
if (GetIdleTime() >= yourTime)
{
//logout
}

mapreduce fails with message "The request to API call datastore_v3.Put() was too large."

I am running a mapreduce job over 50 million User records.
For each user I read two other Datastore entities and then stream stats for each player to bigquery.
My first dry run (with streaming to bigquery disabled) failed with the following stacktrace.
/_ah/pipeline/handleTask
com.google.appengine.tools.cloudstorage.NonRetriableException: com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large.
at com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:121)
at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:166)
at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:157)
at com.google.appengine.tools.pipeline.impl.backend.AppEngineBackEnd.tryFiveTimes(AppEngineBackEnd.java:196)
at com.google.appengine.tools.pipeline.impl.backend.AppEngineBackEnd.saveWithJobStateCheck(AppEngineBackEnd.java:236)
I have googled this error and the only thing I find is related to that the Mapper is too big to be serialized but our Mapper has no data at all.
/**
* Adds stats for a player via streaming api.
*/
public class PlayerStatsMapper extends Mapper<Entity, Void, Void> {
private static Logger log = Logger.getLogger(PlayerStatsMapper.class.getName());
private static final long serialVersionUID = 1L;
private String dataset;
private String table;
private transient GbqUtils gbq;
public PlayerStatsMapper(String dataset, String table) {
gbq = Davinci.getComponent(GbqUtils.class);
this.dataset = dataset;
this.table = table;
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
log.info("IOC reinitating due to deserialization.");
gbq = Davinci.getComponent(GbqUtils.class);
}
#Override
public void beginShard() {
}
#Override
public void endShard() {
}
#Override
public void map(Entity value) {
if (!value.getKind().equals("User")) {
log.severe("Expected a User but got a " + value.getKind());
return;
}
User user = new User(1, value);
List<Map<String, Object>> rows = new LinkedList<Map<String, Object>>();
List<PlayerStats> playerStats = readPlayerStats(user.getUserId());
addRankings(user.getUserId(), playerStats);
for (PlayerStats ps : playerStats) {
rows.add(ps.asMap());
}
// if (rows.size() > 0)
// gbq.insert(dataset, table, rows);
}
.... private methods only
}
The maprecuce job is started with this code
MapReduceSettings settings = new MapReduceSettings().setWorkerQueueName("mrworker");
settings.setBucketName(gae.getAppName() + "-playerstats");
// #formatter:off <I, K, V, O, R>
MapReduceSpecification<Entity, Void, Void, Void, Void> spec =
MapReduceSpecification.of("Enque player stats",
new DatastoreInput("User", shardCountMappers),
new PlayerStatsMapper(dataset, "playerstats"),
Marshallers.getVoidMarshaller(),
Marshallers.getVoidMarshaller(),
NoReducer.<Void, Void, Void> create(),
NoOutput.<Void, Void> create(1));
// #formatter:on
String jobId = MapReduceJob.start(spec, settings);
Well I solved this by backing to appengine-mapreduce-0.2.jar which was the one we had used before. The one used above was appengine-mapreduce-0.5.jar which actually turned out not to work for us.
When backing to 0.2 the console _ah/pipiline/list started to work again as well!
Anyone else that have encountered similar problem with 0.5?

Resources