How to initialize an empty byte array in Solidity? - solidity

I need to pass an empty byte array to a function derived from OpenZeppelin:
function mintTo(address to, uint256 tokenId, uint256 amount)
{
bytes memory data;
_mint(to, tokenId, amount, data);
}
However, although this code compiles and works perfectly, Slither is complaining that this is
is a local variable never initialized
I'm curious how to achieve that?

You can shut slither up or just use an empty string:
_mint(to, tokenId, amount, "");

Related

I need help to customize my smart contract lottery project

Things that I need to add as functions:
I want to integrate a management fee of 1% of the total pot. Execution: The management fee (going to contract owner) will be deducted to the total prize before the remaining 99% amount will be sent to the lottery winner. I need to add it to the selectWinner function.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Lottery{
address public manager;
//global dynamic array for participants.
address payable[] public participants;
constructor()
{
//msg.sender is a global variable used to store contract address to manager.
manager=msg.sender;
}
//receive function only creates once in a smart comtract.
//this function help to transfer the ether.
//always use with external keyword and payable.
receive() external payable{
//require is used as a if statement. it check if ether value is 2 then only run below code.
require(msg.value==0.02 ether);
participants.push(payable(msg.sender));
}
function getBalance() public view returns(uint){
//only manager check the total balance.
require(msg.sender==manager);
return address(this).balance;
}
//this random function will genrate random value and from participant array and then return to the winnerFunction.
function random() public view returns(uint)
{
return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, participants.length)));
}
//this function decide the winner randomly.
function selectWinner() public{
require(msg.sender==manager);
require(participants.length>=3);
uint r=random(); //call random function.
uint index=r % participants.length; //for making random function value in array length range.
address payable winner;
winner=participants[index];
winner.transfer(getBalance());
participants=new address payable[](0);
}
}
I need help to do it. Thank you.
I think something like this should work. I don't have time to test the function right now, but will edit this answer later today. Hope it helps you at the moment.
function selectWinner() public {
require(msg.sender==manager);
require(participants.length>=3);
uint r=random(); //call random function.
uint index=r % participants.length; //for making random function value in array length range.
address payable winner;
winner=participants[index];
uint balance = getBalance(); // balance is in wei
uint fee = balance * 0.01 ether; // 1% in wei
uint amountToTransfer = balance - fee;
winner.transfer(amountToTransfer);
_withdrawFee(fee); // transfer fee to manager
participants=new address payable[](0);
}
function _withdrawFee(uint feeAmount) payable private {
msg.sender.transfer(feeAmount);
}

Interaction with Aave V3 contract getUserAccountData

I'm trying to make a normal request to another contract from mine.
function getUserAccountData(address _miskin) internal view returns (AaveUserData memory) {
ILendingPool lendingPool = ILendingPool(aaveLendingPoolAddress);
(uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor) = lendingPool.getUserAccountData(_miskin);
return AaveUserData(totalCollateralETH, totalDebtETH, availableBorrowsETH, currentLiquidationThreshold, ltv, healthFactor);
}
This is pretty basic and on the line lendingPool.getUserAccountData(_miskin); I get an error: function returned an unexpected amount of data.
I don't understand why I have the correct contract address also.
This is my interface
interface ILendingPool {
function getUserAccountData(address user)
external
view
returns (
uint256 totalCollateralETH,
uint256 totalDebtETH,
uint256 availableBorrowsETH,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
}
I someone have any idea what can I do I would love thank you.
A struct is decoded differently than the list of its arguments. In particular it has extra bytes at the beginning.
So your code is expecting a output like (uint256, ..., uint256) but getting a AaveUserData struct. I'm not sure how the output of your internal function getUserAccountData is used, but I guess you're reading it using the Aave ILendingPool interface, which doesn't return a AaveUserData struct.
It's a bit of a dum answer but I forked the wrong network so whe. I tried to call the address with the good polygon address I got an error. So the solution: Fork the good network.

How to swap array elements using destructuring in Solidity?

I want to delete data from an array. But deleting data from a particular array index creates a gap in the array. Hence, I am swapping the array[i] with array[array.length-1] and popping out the array. I tried to do it with a destructuring technique that is supported in Solidity yet it turns out the values do not tend to swap. While swapping using the "temp" variable seems to work perfectly fine but it consumes more gas.
There's a warning that solidity throws which I am not able to understand.
Warning: This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first.
Can anyone help?
Please find the code below:
struct Details{
uint256 id;
address walletAddress;
string fullName;
uint256 phoneNumber;
string residentialAddress;
}
Details [] public userDetails;
function deleteData(uint256 _id) public onlyOwner returns(string memory){
for(uint256 i=0;i<userDetails.length;i++)
{
if (userDetails[i].id==_id){
(userDetails[i],userDetails[userDetails.length-1])=(userDetails[userDetails.length-1],userDetails[i]);
userDetails.pop();
}
}
}
You can just assign the last item to the place of the deleted one (effectively duplicating the last item for the moment), and then delete the last item.
if (userDetails[i].id == _id) {
userDetails[i] = userDetails[userDetails.length-1];
userDetails.pop();
break;
}

Trying to make an array with a variable size in solidity

I am trying to write string to the blockchain using events. This will cost a lot of gas regularly, so I am attempting to compress my strings. They become compressed into a uint8array in js. Here is my solidity script:
pragma solidity ^0.4.18;
contract EthProj {
event Message(uint8[] message, address add, uint256 cost);
event Username(uint8[] name, address add, uint256 cost);
function setMessage(uint8[] _fMessage) public {
uint8[] memory output = new uint8[](_fMessage.length);
output = _fMessage;
emit Message(output, msg.sender, gasleft());
}
function setUsername(uint8[] _userName) public {
emit Username(_userName, msg.sender, gasleft());
}
}
My goal with this is to have the size of the array be dependent on the size of the compressed text, but I get invalid number of arguments error when calling it using this:
message = document.getElementById("MessageBox").value;
compressed = shoco.compress(message);
EthProj.setMessage.sendTransaction(compressed, {from: document.getElementById("add").value});`
Can you not make an array with variable size, and if I can't, than how do I go about achieving my goal? The error is: Invalid number of arguments to solidity function

eth.call on web3 interface returns null value for contract function returning array of bytes32/strings

I am trying to run a bidding smart contract on a private blockchain and my smart contract is working on the Remix IDE and the same works on my private chain except for one function [dataOwnedBy()] which is suposed to return an array of bytes32 but returns all zero values in geth console.
I have compiled and deployed my smart contract using truffle.
The function which is not working is : (along with data declaration snippet and other function prototypes)
struct data{
bytes32 data_id;
address bidder;
uint bid;
}
mapping(bytes32=>data) bidInfo;
mapping(address=>data[]) dataOwned; //data owned by each address
address[] dataOwners; //list of address who own data
function Bid(bytes32 data_id) public payable { ... }
function closeBid(bytes32 data_id) public { ... }
function whoOwns(bytes32 _data_id) constant public returns (address){ ... }
function dataOwnedBy(address _addr) constant public returns (bytes32[10]){
uint length = dataOwned[_addr].length;
bytes32[10] memory _idArray;
for (uint i=0;i<length;i++){
_idArray[i] = (dataOwned[_addr][i].data_id);
}
return _idArray;
}
After closing the bid, when I query the above function with the winner's address, it returns array of size 10 bytes32 values, all equal to zero, where it should be returning the data_ids owned by the address.!
Version Information from console
> web3.version.api
"0.20.1"
truffle(development)> version
Truffle v3.4.11 (core: 3.4.11)
Solidity v0.4.15 (solc-js)
This is the console output :
playbid.whoOwns("data_id1")
"0x7d8eb703bd863313325b784ac35017614484f2e7"
playbid.dataOwnedBy("0x7d8eb703bd863313325b784ac35017614484f2e7")
["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"]
Instead the first value of the array should be the hex of "data_id1".
Don't know what is going wrong here, but it works perfectly fine on Remix IDE.
Thanks in advance !
As your code is working OK in remix, there is no problem with the smart contract code. I experienced same issue when I wanted to return some arrays back to my web3j powered java app. I also tested web3js and encountered the same problem. The returned array was broken the same way.
I ended up in serializing and deserializing arrays to strings with a delimiter, both in inputs and outputs.