Solidity loop and write data in one function - solidity

Is solidity cannot loop and write data? It must be write one by one?
Here is my smart contract function:
function purchaseItem1(address _to, uint256[] _tokenId) public {
address _from;
for(uint i = 0; i < _tokenId.length; i++){
_from = itemOwner[_tokenId[i]];
itemOwnerCount[_to] = itemOwnerCount[_to]+1;
itemOwnerCount[_from] = itemOwnerCount[_from]-1;
itemOwner[_tokenId[i]] = _to;
items[_tokenId[i]].available = false;
availableCount = availableCount-1;
}
}
In my front end I have a group of checkbox with same name.
After I checked few of it and I will pass the value in array as uint[] tokenId.

Related

Solidity Chainlink keepers with PriceFeeds

I'm trying to integrate Pricefeeds in the chain keepers to automate a sell order when the price goes under certain value.
Separately both work but when adding the Price feed function inside the checkUpkeep() it doesn't trigger the performUpkeep().
Does checkUpkeep() function can call the priceFeed function or is not even praepared for this?
how should I implement it then?
Here is the code:
function checkUpkeep(bytes memory /* checkData */) public view override returns (//,bytes memory value
bool upkeepNeeded,
bytes memory num
){
uint256 EthPrice = 0;
// uint256 i = 2;
EthPrice = getPrice();
num = abi.encodePacked(EthPrice);
if (EthPrice > 0){
upkeepNeeded = true;
}
return (upkeepNeeded, num);//, value
}
function performUpkeep(bytes calldata num) external override {//, bytes calldata value
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Order__UpkeepNotNeeded(
address(this).balance,
s_Wallets.length
);
}
//Byte conversion to uint
uint256 number;
number = abi.decode(num, (uint256));
// for(uint i=0;i<num.length;i++){
// number = number + uint(uint8(num[i]))*(2**(8*(num.length-(i+1))));
// }
s_nombre = number;
}

How to return a struct inside a nested mapping in solidity

I'm working on a smart contract that allows users to subscribe to different Plans.
I have a nested mapping that returns a struct(Subscription). I wanted to create a function that returns all the subscriptions that exist in a specific plan(0,1,2..).
The function that I wrote doesn't return all structs it returns only the first one after that it returns only zeros.
totalSubscriptions increase when a new user creates a new subscription.
address[] allSubcribers contains all the addresses of subscribers.
currentId represents the id of the plan that a subscriber signed up for.
struct Subscription {
address subscriber;
uint start;
uint nextPayment;
}
mapping(address => mapping(uint => Subscription)) public subscriptions;
function getAllsubscriptions() external view returns (Subscription[] memory) {
Subscription[] memory items = new Subscription[](totalLoans);
for(uint256 i = 0; i < totalSubscriptions; i++) {
uint256 currentId = i;
LoanRequest storage currentItem = subscriptions[allSubcribers[currentId]][currentId];
items[currentId] = currentItem;
currentId += 1;
}
return items;
}
What do you think?

Function needs to return array length in solidity, but error occurs

I have a Practice contract in solidity. I was trying to get the length of an array using arrLength function.But, I am getting error like The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
Here, I am trying to any transaction, But getting error like the function should be payable.
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.9.0;
contract Practice {
function arrLength(uint num) public pure returns(uint){
uint[] memory arr = new uint[](num);
for(uint i = 0; i<=num; i++){
arr[i] = 10;
}
return arr.length;
}
}
But I am getting error:
creation of Practice pending...
[vm]from: 0x5B3...eddC4to: Practice.(constructor)value: 0 weidata: 0x608...70033logs: 0hash: 0x029...1dcf6
call to Practice.arrLength
call to Practice.arrLength errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
You Should Try this Code :
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.9.0;
contract Practice {
function arrLength(uint num) public pure returns(uint){
uint[] memory arr = new uint[](num);
for(uint i = 0; i < num; i++){
arr[i] = 10;
}
uint leng= arr.length;
return leng;
}
}
You have error in this line :
for(uint i = 0; i<=num; i++)
change it to for(uint i = 0; i<num; i++)
for example you enter 5 into the input of the function .
now your array size is 5 : arr[0] , arr[1],arr[2],arr[3],arr[4]
when you use this code : for(uint i = 0; i<=num; i++) , it try to add item into arr[5] but it not exsist .

ERC1155 _mintBatch() issue

Trying to create a function to mint a specific set of ERC1155 tokens but for some reason when executing no tokens are minted. Code for mintSingle() works fine. I've tried multiple ways of constructing the dynamic array that's required as an input to the OpenZeppelin ERC1155 contract function _mintBatch(address to, uint256[] ids, uint256[] amounts, bytes data), but nothing is working. What am I doing wrong? Thank you.
contract ExampleProject is ERC1155 {
uint256 public constant ROWA = 0;
uint256 public constant ROWBA = 30;
constructor() public ERC1155("ipfs://Example/metadata/{id}.json") {
}
function mintRowA()
public
{
uint256[] memory a = new uint256[](2);
a[0] = ROWA;
a[1] = ROWBA;
uint256[] memory b = new uint256[](2);
b[0] = 1;
b[1] = 1;
_mintBatch(msg.sender, a, b, "" );
}
function mintSingle()
public
{
_mint(msg.sender, ROWBA, 1, "");
}
}

Solidity ParseError: Expected primary expression

When I am compiling with truffle it is giving me this error
I got this error after adding payable
prior to that it was
winners[j].transfer(betwa*(10000+(LoserBet*10000/WinnerBet))/10000);
I had to add it because I was getting another error
Which was
TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".
My Complete Contract :
pragma solidity ^0.5.16;
contract Betting {
address public owner;
uint256 public minimumBet;
uint256 public totalBetsOne;
uint256 public totalBetsTwo;
address[] public players;
struct Player {
uint256 amountBet;
uint16 teamSelected;
}
// The address of the player and => the user info
mapping(address => Player) public playerInfo;
function() external payable {}
constructor() public {
owner = msg.sender;
minimumBet = 100000000000000;
}
function kill() public {
if(msg.sender == owner) selfdestruct(msg.sender);
}
function checkPlayerExists(address player) public view returns(bool){
for(uint256 i = 0; i < players.length; i++){
if(players[i] == player) return true;
}
return false;
}
function bet(uint8 _teamSelected) public payable {
//The first require is used to check if the player already exist
require(!checkPlayerExists(msg.sender));
//The second one is used to see if the value sended by the player is
//Higher than the minimum value
require(msg.value >= minimumBet);
//We set the player informations : amount of the bet and selected team
playerInfo[msg.sender].amountBet = msg.value;
playerInfo[msg.sender].teamSelected = _teamSelected;
//then we add the address of the player to the players array
players.push(msg.sender);
//at the end, we increment the stakes of the team selected with the player bet
if ( _teamSelected == 1){
totalBetsOne += msg.value;
}
else{
totalBetsTwo += msg.value;
}
}
// Generates a number between 1 and 10 that will be the winner
function distributePrizes(uint16 teamWinner) public {
address[1000] memory winners;
//We have to create a temporary in memory array with fixed size
//Let's choose 1000
uint256 count = 0; // This is the count for the array of winners
uint256 LoserBet = 0; //This will take the value of all losers bet
uint256 WinnerBet = 0; //This will take the value of all winners bet
address playerAddress;
//We loop through the player array to check who selected the winner team
for(uint256 i = 0; i < players.length; i++){
playerAddress = players[i];
//If the player selected the winner team
//We add his address to the winners array
if(playerInfo[playerAddress].teamSelected == teamWinner){
winners[count] = playerAddress;
count++;
}
}
//We define which bet sum is the Loser one and which one is the winner
if ( teamWinner == 1){
LoserBet = totalBetsTwo;
WinnerBet = totalBetsOne;
}
else{
LoserBet = totalBetsOne;
WinnerBet = totalBetsTwo;
}
//We loop through the array of winners, to give ethers to the winners
for(uint256 j = 0; j < count; j++){
// Check that the address in this fixed array is not empty
if(winners[j] != address(0)){
address add = winners[j];
uint256 betwa = playerInfo[add].amountBet;
//Transfer the money to the user
payable(winners[j]).transfer( (betwa*(10000+(LoserBet*10000/WinnerBet)))/10000 );
}
}
delete playerInfo[playerAddress]; // Delete all the players
players.length = 0; // Delete all the players array
LoserBet = 0; //reinitialize the bets
WinnerBet = 0;
totalBetsOne = 0;
totalBetsTwo = 0;
}
function AmountOne() public view returns(uint256){
return totalBetsOne;
}
function AmountTwo() public view returns(uint256){
return totalBetsTwo;
}
}
What I have tried is making the address payable in this function but It is not working I have tried to replace memory with payable but still it isn't working
My versions
Truffle v5.4.18 (core: 5.4.18)
Solidity v0.5.16 (solc-js)
Node v14.15.1
Web3.js v1.5.3
The payable() conversion from address to address payable was introduced in Solidity 0.6.
Source: https://docs.soliditylang.org/en/latest/060-breaking-changes.html#new-features
Since your contract is using (deprecated) version 0.5.16, it doesn't allow this conversion. So you need to define the winners array already as address payable:
// added `payable`
address payable[1000] memory winners;
Then you'll be able to use the .transfer() method of the address payable type:
// `winners[j]` is payable
winners[j].transfer(...);